summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKrzysztof Parzyszek <kparzysz@quicinc.com>2019-07-01 15:50:09 +0000
committerKrzysztof Parzyszek <kparzysz@quicinc.com>2019-07-01 15:50:09 +0000
commit5abf80cdfa347c8b6306157011e7f85212994428 (patch)
tree97094d8a04596b407ccb419d8391a568339ec801
parentcda82f0bb6fd0577b9f2f8185f3b6be20ea96e58 (diff)
downloadbcm5719-llvm-5abf80cdfa347c8b6306157011e7f85212994428.tar.gz
bcm5719-llvm-5abf80cdfa347c8b6306157011e7f85212994428.zip
[Hexagon] Custom-lower UADDO(x, 1) and USUBO(x, 1)
llvm-svn: 364790
-rw-r--r--llvm/lib/Target/Hexagon/HexagonISelLowering.cpp43
-rw-r--r--llvm/lib/Target/Hexagon/HexagonISelLowering.h1
-rw-r--r--llvm/test/CodeGen/Hexagon/isel-uaddo-1.ll37
3 files changed, 79 insertions, 2 deletions
diff --git a/llvm/lib/Target/Hexagon/HexagonISelLowering.cpp b/llvm/lib/Target/Hexagon/HexagonISelLowering.cpp
index b72498777ed..fef5a98cdb0 100644
--- a/llvm/lib/Target/Hexagon/HexagonISelLowering.cpp
+++ b/llvm/lib/Target/Hexagon/HexagonISelLowering.cpp
@@ -1334,8 +1334,8 @@ HexagonTargetLowering::HexagonTargetLowering(const TargetMachine &TM,
// Hexagon has A4_addp_c and A4_subp_c that take and generate a carry bit,
// but they only operate on i64.
for (MVT VT : MVT::integer_valuetypes()) {
- setOperationAction(ISD::UADDO, VT, Expand);
- setOperationAction(ISD::USUBO, VT, Expand);
+ setOperationAction(ISD::UADDO, VT, Custom);
+ setOperationAction(ISD::USUBO, VT, Custom);
setOperationAction(ISD::SADDO, VT, Expand);
setOperationAction(ISD::SSUBO, VT, Expand);
setOperationAction(ISD::ADDCARRY, VT, Expand);
@@ -2692,6 +2692,43 @@ HexagonTargetLowering::LowerUnalignedLoad(SDValue Op, SelectionDAG &DAG)
}
SDValue
+HexagonTargetLowering::LowerUAddSubO(SDValue Op, SelectionDAG &DAG) const {
+ SDValue X = Op.getOperand(0), Y = Op.getOperand(1);
+ auto *CY = dyn_cast<ConstantSDNode>(Y);
+ if (!CY)
+ return SDValue();
+
+ const SDLoc &dl(Op);
+ SDVTList VTs = Op.getNode()->getVTList();
+ assert(VTs.NumVTs == 2);
+ assert(VTs.VTs[1] == MVT::i1);
+ unsigned Opc = Op.getOpcode();
+
+ if (CY) {
+ uint32_t VY = CY->getZExtValue();
+ assert(VY != 0 && "This should have been folded");
+ // X +/- 1
+ if (VY != 1)
+ return SDValue();
+
+ if (Opc == ISD::UADDO) {
+ SDValue Op = DAG.getNode(ISD::ADD, dl, VTs.VTs[0], {X, Y});
+ SDValue Ov = DAG.getSetCC(dl, MVT::i1, Op, getZero(dl, ty(Op), DAG),
+ ISD::SETEQ);
+ return DAG.getMergeValues({Op, Ov}, dl);
+ }
+ if (Opc == ISD::USUBO) {
+ SDValue Op = DAG.getNode(ISD::SUB, dl, VTs.VTs[0], {X, Y});
+ SDValue Ov = DAG.getSetCC(dl, MVT::i1, Op,
+ DAG.getConstant(-1, dl, ty(Op)), ISD::SETEQ);
+ return DAG.getMergeValues({Op, Ov}, dl);
+ }
+ }
+
+ return SDValue();
+}
+
+SDValue
HexagonTargetLowering::LowerAddSubCarry(SDValue Op, SelectionDAG &DAG) const {
const SDLoc &dl(Op);
unsigned Opc = Op.getOpcode();
@@ -2768,6 +2805,8 @@ HexagonTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const {
case ISD::BITCAST: return LowerBITCAST(Op, DAG);
case ISD::LOAD: return LowerLoad(Op, DAG);
case ISD::STORE: return LowerStore(Op, DAG);
+ case ISD::UADDO:
+ case ISD::USUBO: return LowerUAddSubO(Op, DAG);
case ISD::ADDCARRY:
case ISD::SUBCARRY: return LowerAddSubCarry(Op, DAG);
case ISD::SRA:
diff --git a/llvm/lib/Target/Hexagon/HexagonISelLowering.h b/llvm/lib/Target/Hexagon/HexagonISelLowering.h
index 7c86bbf62a3..4e467cb2272 100644
--- a/llvm/lib/Target/Hexagon/HexagonISelLowering.h
+++ b/llvm/lib/Target/Hexagon/HexagonISelLowering.h
@@ -167,6 +167,7 @@ namespace HexagonISD {
SDValue LowerLoad(SDValue Op, SelectionDAG &DAG) const;
SDValue LowerStore(SDValue Op, SelectionDAG &DAG) const;
SDValue LowerUnalignedLoad(SDValue Op, SelectionDAG &DAG) const;
+ SDValue LowerUAddSubO(SDValue Op, SelectionDAG &DAG) const;
SDValue LowerAddSubCarry(SDValue Op, SelectionDAG &DAG) const;
SDValue LowerDYNAMIC_STACKALLOC(SDValue Op, SelectionDAG &DAG) const;
diff --git a/llvm/test/CodeGen/Hexagon/isel-uaddo-1.ll b/llvm/test/CodeGen/Hexagon/isel-uaddo-1.ll
new file mode 100644
index 00000000000..092fb60e041
--- /dev/null
+++ b/llvm/test/CodeGen/Hexagon/isel-uaddo-1.ll
@@ -0,0 +1,37 @@
+; RUN: llc -march=hexagon < %s | FileCheck %s
+
+; Check that a hardware loop is generated.
+; CHECK: loop0
+
+target triple = "hexagon"
+
+; Function Attrs: norecurse nounwind
+define dso_local void @f0(i32* nocapture readonly %a0, i32* nocapture %a1) local_unnamed_addr #0 {
+b0:
+ br label %b1
+
+b1: ; preds = %b1, %b0
+ %v0 = phi i32 [ %v3, %b1 ], [ 100, %b0 ]
+ %v1 = phi i32* [ %v6, %b1 ], [ %a1, %b0 ]
+ %v2 = phi i32* [ %v4, %b1 ], [ %a0, %b0 ]
+ %v3 = add nsw i32 %v0, -1
+ %v4 = getelementptr inbounds i32, i32* %v2, i32 1
+ %v5 = load i32, i32* %v2, align 4, !tbaa !1
+ %v6 = getelementptr inbounds i32, i32* %v1, i32 1
+ store i32 %v5, i32* %v1, align 4, !tbaa !1
+ %v7 = icmp eq i32 %v3, 0
+ br i1 %v7, label %b2, label %b1
+
+b2: ; preds = %b1
+ ret void
+}
+
+attributes #0 = { norecurse nounwind "target-cpu"="hexagonv62" }
+
+!llvm.module.flags = !{!0}
+
+!0 = !{i32 1, !"wchar_size", i32 4}
+!1 = !{!2, !2, i64 0}
+!2 = !{!"int", !3, i64 0}
+!3 = !{!"omnipotent char", !4, i64 0}
+!4 = !{!"Simple C/C++ TBAA"}
OpenPOWER on IntegriCloud