[llvm] r333751 - [SelectionDAG] Expand UADDO/USUBO into ADD/SUBCARRY if legal for target
Krzysztof Parzyszek via llvm-commits
llvm-commits at lists.llvm.org
Fri Jun 1 07:00:32 PDT 2018
Author: kparzysz
Date: Fri Jun 1 07:00:32 2018
New Revision: 333751
URL: http://llvm.org/viewvc/llvm-project?rev=333751&view=rev
Log:
[SelectionDAG] Expand UADDO/USUBO into ADD/SUBCARRY if legal for target
Additionally, implement handling of ADD/SUBCARRY on Hexagon, utilizing
the UADDO/USUBO expansion.
Differential Revision: https://reviews.llvm.org/D47559
Added:
llvm/trunk/test/CodeGen/Hexagon/addsubcarry.ll
Removed:
llvm/trunk/test/CodeGen/Hexagon/adde.ll
llvm/trunk/test/CodeGen/Hexagon/sube.ll
Modified:
llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
llvm/trunk/lib/Target/Hexagon/HexagonISelDAGToDAG.cpp
llvm/trunk/lib/Target/Hexagon/HexagonISelDAGToDAG.h
llvm/trunk/lib/Target/Hexagon/HexagonISelLowering.cpp
llvm/trunk/lib/Target/Hexagon/HexagonISelLowering.h
Modified: llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp?rev=333751&r1=333750&r2=333751&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Fri Jun 1 07:00:32 2018
@@ -2283,8 +2283,11 @@ SDValue DAGCombiner::visitADDCARRY(SDNod
return DAG.getNode(ISD::ADDCARRY, DL, N->getVTList(), N1, N0, CarryIn);
// fold (addcarry x, y, false) -> (uaddo x, y)
- if (isNullConstant(CarryIn))
- return DAG.getNode(ISD::UADDO, DL, N->getVTList(), N0, N1);
+ if (isNullConstant(CarryIn)) {
+ if (!LegalOperations ||
+ TLI.isOperationLegalOrCustom(ISD::UADDO, N->getValueType(0)))
+ return DAG.getNode(ISD::UADDO, DL, N->getVTList(), N0, N1);
+ }
// fold (addcarry 0, 0, X) -> (and (ext/trunc X), 1) and no carry.
if (isNullConstant(N0) && isNullConstant(N1)) {
@@ -2592,8 +2595,11 @@ SDValue DAGCombiner::visitSUBCARRY(SDNod
SDValue CarryIn = N->getOperand(2);
// fold (subcarry x, y, false) -> (usubo x, y)
- if (isNullConstant(CarryIn))
- return DAG.getNode(ISD::USUBO, SDLoc(N), N->getVTList(), N0, N1);
+ if (isNullConstant(CarryIn)) {
+ if (!LegalOperations ||
+ TLI.isOperationLegalOrCustom(ISD::USUBO, N->getValueType(0)))
+ return DAG.getNode(ISD::USUBO, SDLoc(N), N->getVTList(), N0, N1);
+ }
return SDValue();
}
Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp?rev=333751&r1=333750&r2=333751&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Fri Jun 1 07:00:32 2018
@@ -3499,15 +3499,25 @@ bool SelectionDAGLegalize::ExpandNode(SD
case ISD::USUBO: {
SDValue LHS = Node->getOperand(0);
SDValue RHS = Node->getOperand(1);
- SDValue Sum = DAG.getNode(Node->getOpcode() == ISD::UADDO ?
- ISD::ADD : ISD::SUB, dl, LHS.getValueType(),
- LHS, RHS);
+ bool IsAdd = Node->getOpcode() == ISD::UADDO;
+ // If ADD/SUBCARRY is legal, use that instead.
+ unsigned OpcCarry = IsAdd ? ISD::ADDCARRY : ISD::SUBCARRY;
+ if (TLI.isOperationLegalOrCustom(OpcCarry, Node->getValueType(0))) {
+ SDValue CarryIn = DAG.getConstant(0, dl, Node->getValueType(1));
+ SDValue NodeCarry = DAG.getNode(OpcCarry, dl, Node->getVTList(),
+ { LHS, RHS, CarryIn });
+ Results.push_back(SDValue(NodeCarry.getNode(), 0));
+ Results.push_back(SDValue(NodeCarry.getNode(), 1));
+ break;
+ }
+
+ SDValue Sum = DAG.getNode(IsAdd ? ISD::ADD : ISD::SUB, dl,
+ LHS.getValueType(), LHS, RHS);
Results.push_back(Sum);
EVT ResultType = Node->getValueType(1);
EVT SetCCType = getSetCCResultType(Node->getValueType(0));
- ISD::CondCode CC
- = Node->getOpcode() == ISD::UADDO ? ISD::SETULT : ISD::SETUGT;
+ ISD::CondCode CC = IsAdd ? ISD::SETULT : ISD::SETUGT;
SDValue SetCC = DAG.getSetCC(dl, SetCCType, Sum, LHS, CC);
Results.push_back(DAG.getBoolExtOrTrunc(SetCC, dl, ResultType, ResultType));
Modified: llvm/trunk/lib/Target/Hexagon/HexagonISelDAGToDAG.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Hexagon/HexagonISelDAGToDAG.cpp?rev=333751&r1=333750&r2=333751&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Hexagon/HexagonISelDAGToDAG.cpp (original)
+++ llvm/trunk/lib/Target/Hexagon/HexagonISelDAGToDAG.cpp Fri Jun 1 07:00:32 2018
@@ -762,6 +762,15 @@ void HexagonDAGToDAGISel::SelectFrameInd
ReplaceNode(N, R);
}
+void HexagonDAGToDAGISel::SelectAddSubCarry(SDNode *N) {
+ unsigned OpcCarry = N->getOpcode() == HexagonISD::ADDC ? Hexagon::A4_addp_c
+ : Hexagon::A4_subp_c;
+ SDNode *C = CurDAG->getMachineNode(OpcCarry, SDLoc(N), N->getVTList(),
+ { N->getOperand(0), N->getOperand(1),
+ N->getOperand(2) });
+ ReplaceNode(N, C);
+}
+
void HexagonDAGToDAGISel::SelectVAlign(SDNode *N) {
MVT ResTy = N->getValueType(0).getSimpleVT();
if (HST->isHVXVectorType(ResTy, true))
@@ -875,6 +884,9 @@ void HexagonDAGToDAGISel::Select(SDNode
case ISD::STORE: return SelectStore(N);
case ISD::INTRINSIC_W_CHAIN: return SelectIntrinsicWChain(N);
case ISD::INTRINSIC_WO_CHAIN: return SelectIntrinsicWOChain(N);
+
+ case HexagonISD::ADDC:
+ case HexagonISD::SUBC: return SelectAddSubCarry(N);
case HexagonISD::VALIGN: return SelectVAlign(N);
case HexagonISD::VALIGNADDR: return SelectVAlignAddr(N);
case HexagonISD::TYPECAST: return SelectTypecast(N);
Modified: llvm/trunk/lib/Target/Hexagon/HexagonISelDAGToDAG.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Hexagon/HexagonISelDAGToDAG.h?rev=333751&r1=333750&r2=333751&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Hexagon/HexagonISelDAGToDAG.h (original)
+++ llvm/trunk/lib/Target/Hexagon/HexagonISelDAGToDAG.h Fri Jun 1 07:00:32 2018
@@ -105,6 +105,7 @@ public:
void SelectV65Gather(SDNode *N);
void SelectV65GatherPred(SDNode *N);
void SelectHVXDualOutput(SDNode *N);
+ void SelectAddSubCarry(SDNode *N);
void SelectVAlign(SDNode *N);
void SelectVAlignAddr(SDNode *N);
void SelectTypecast(SDNode *N);
Modified: llvm/trunk/lib/Target/Hexagon/HexagonISelLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Hexagon/HexagonISelLowering.cpp?rev=333751&r1=333750&r2=333751&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Hexagon/HexagonISelLowering.cpp (original)
+++ llvm/trunk/lib/Target/Hexagon/HexagonISelLowering.cpp Fri Jun 1 07:00:32 2018
@@ -1327,13 +1327,18 @@ HexagonTargetLowering::HexagonTargetLowe
setMinimumJumpTableEntries(std::numeric_limits<int>::max());
setOperationAction(ISD::BR_JT, MVT::Other, Expand);
- // Only add and sub that detect overflow are the saturating ones.
+ // 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::SADDO, VT, Expand);
- setOperationAction(ISD::USUBO, VT, Expand);
- setOperationAction(ISD::SSUBO, VT, Expand);
+ setOperationAction(ISD::UADDO, VT, Expand);
+ setOperationAction(ISD::USUBO, VT, Expand);
+ setOperationAction(ISD::SADDO, VT, Expand);
+ setOperationAction(ISD::SSUBO, VT, Expand);
+ setOperationAction(ISD::ADDCARRY, VT, Expand);
+ setOperationAction(ISD::SUBCARRY, VT, Expand);
}
+ setOperationAction(ISD::ADDCARRY, MVT::i64, Custom);
+ setOperationAction(ISD::SUBCARRY, MVT::i64, Custom);
setOperationAction(ISD::CTLZ, MVT::i8, Promote);
setOperationAction(ISD::CTLZ, MVT::i16, Promote);
@@ -1681,6 +1686,8 @@ HexagonTargetLowering::HexagonTargetLowe
const char* HexagonTargetLowering::getTargetNodeName(unsigned Opcode) const {
switch ((HexagonISD::NodeType)Opcode) {
+ case HexagonISD::ADDC: return "HexagonISD::ADDC";
+ case HexagonISD::SUBC: return "HexagonISD::SUBC";
case HexagonISD::ALLOCA: return "HexagonISD::ALLOCA";
case HexagonISD::AT_GOT: return "HexagonISD::AT_GOT";
case HexagonISD::AT_PCREL: return "HexagonISD::AT_PCREL";
@@ -2706,6 +2713,24 @@ HexagonTargetLowering::LowerUnalignedLoa
}
SDValue
+HexagonTargetLowering::LowerAddSubCarry(SDValue Op, SelectionDAG &DAG) const {
+ const SDLoc &dl(Op);
+ unsigned Opc = Op.getOpcode();
+ SDValue X = Op.getOperand(0), Y = Op.getOperand(1), C = Op.getOperand(2);
+
+ if (Opc == ISD::ADDCARRY)
+ return DAG.getNode(HexagonISD::ADDC, dl, Op.getNode()->getVTList(),
+ { X, Y, C });
+
+ EVT CarryTy = C.getValueType();
+ SDValue SubC = DAG.getNode(HexagonISD::SUBC, dl, Op.getNode()->getVTList(),
+ { X, Y, DAG.getLogicalNOT(dl, C, CarryTy) });
+ SDValue Out[] = { SubC.getValue(0),
+ DAG.getLogicalNOT(dl, SubC.getValue(1), CarryTy) };
+ return DAG.getMergeValues(Out, dl);
+}
+
+SDValue
HexagonTargetLowering::LowerEH_RETURN(SDValue Op, SelectionDAG &DAG) const {
SDValue Chain = Op.getOperand(0);
SDValue Offset = Op.getOperand(1);
@@ -2763,6 +2788,8 @@ HexagonTargetLowering::LowerOperation(SD
case ISD::VECTOR_SHUFFLE: return LowerVECTOR_SHUFFLE(Op, DAG);
case ISD::BITCAST: return LowerBITCAST(Op, DAG);
case ISD::LOAD: return LowerUnalignedLoad(Op, DAG);
+ case ISD::ADDCARRY:
+ case ISD::SUBCARRY: return LowerAddSubCarry(Op, DAG);
case ISD::SRA:
case ISD::SHL:
case ISD::SRL: return LowerVECTOR_SHIFT(Op, DAG);
Modified: llvm/trunk/lib/Target/Hexagon/HexagonISelLowering.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Hexagon/HexagonISelLowering.h?rev=333751&r1=333750&r2=333751&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Hexagon/HexagonISelLowering.h (original)
+++ llvm/trunk/lib/Target/Hexagon/HexagonISelLowering.h Fri Jun 1 07:00:32 2018
@@ -36,6 +36,8 @@ namespace HexagonISD {
CONST32 = OP_BEGIN,
CONST32_GP, // For marking data present in GP.
+ ADDC, // Add with carry: (X, Y, Cin) -> (X+Y, Cout).
+ SUBC, // Sub with carry: (X, Y, Cin) -> (X+~Y+Cin, Cout).
ALLOCA,
AT_GOT, // Index in GOT.
@@ -162,6 +164,7 @@ namespace HexagonISD {
SDValue LowerSIGN_EXTEND(SDValue Op, SelectionDAG &DAG) const;
SDValue LowerZERO_EXTEND(SDValue Op, SelectionDAG &DAG) const;
SDValue LowerUnalignedLoad(SDValue Op, SelectionDAG &DAG) const;
+ SDValue LowerAddSubCarry(SDValue Op, SelectionDAG &DAG) const;
SDValue LowerDYNAMIC_STACKALLOC(SDValue Op, SelectionDAG &DAG) const;
SDValue LowerINLINEASM(SDValue Op, SelectionDAG &DAG) const;
Removed: llvm/trunk/test/CodeGen/Hexagon/adde.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/Hexagon/adde.ll?rev=333750&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/Hexagon/adde.ll (original)
+++ llvm/trunk/test/CodeGen/Hexagon/adde.ll (removed)
@@ -1,27 +0,0 @@
-; RUN: llc -march=hexagon -hexagon-expand-condsets=0 < %s | FileCheck %s
-
-; CHECK-DAG: r{{[0-9]+:[0-9]+}} = add(r{{[0-9]+:[0-9]+}},r{{[0-9]+:[0-9]+}})
-; CHECK-DAG: r{{[0-9]+:[0-9]+}} = add(r{{[0-9]+:[0-9]+}},r{{[0-9]+:[0-9]+}})
-; CHECK-DAG: p{{[0-9]+}} = cmp.gtu(r{{[0-9]+:[0-9]+}},r{{[0-9]+:[0-9]+}})
-; CHECK-DAG: p{{[0-9]+}} = cmp.gtu(r{{[0-9]+:[0-9]+}},r{{[0-9]+:[0-9]+}})
-; CHECK-DAG: r{{[0-9]+}} = mux(p{{[0-9]+}},r{{[0-9]+}},r{{[0-9]+}})
-; CHECK-DAG: r{{[0-9]+}} = mux(p{{[0-9]+}},r{{[0-9]+}},r{{[0-9]+}})
-
-define void @check_adde_addc(i64 %a0, i64 %a1, i64 %a2, i64 %a3, i64* %a4, i64* %a5) {
-b6:
- %v7 = zext i64 %a0 to i128
- %v8 = zext i64 %a1 to i128
- %v9 = shl i128 %v8, 64
- %v10 = or i128 %v7, %v9
- %v11 = zext i64 %a2 to i128
- %v12 = zext i64 %a3 to i128
- %v13 = shl i128 %v12, 64
- %v14 = or i128 %v11, %v13
- %v15 = add i128 %v10, %v14
- %v16 = lshr i128 %v15, 64
- %v17 = trunc i128 %v15 to i64
- %v18 = trunc i128 %v16 to i64
- store i64 %v17, i64* %a4
- store i64 %v18, i64* %a5
- ret void
-}
Added: llvm/trunk/test/CodeGen/Hexagon/addsubcarry.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/Hexagon/addsubcarry.ll?rev=333751&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/Hexagon/addsubcarry.ll (added)
+++ llvm/trunk/test/CodeGen/Hexagon/addsubcarry.ll Fri Jun 1 07:00:32 2018
@@ -0,0 +1,25 @@
+; RUN: llc -march=hexagon < %s | FileCheck %s
+
+ at g = global i128 zeroinitializer, align 8
+
+; CHECK-LABEL: addc:
+; CHECK: p[[P0:[0-3]]] = and(p[[P1:[0-9]]],!p[[P1]])
+; CHECK: add({{.*}},{{.*}},p[[P0]]):carry
+; CHECK: add({{.*}},{{.*}},p[[P0]]):carry
+define void @addc(i128 %a0, i128 %a1) #0 {
+ %v0 = add i128 %a0, %a1
+ store i128 %v0, i128* @g, align 8
+ ret void
+}
+
+; CHECK-LABEL: subc:
+; CHECK: p[[P0:[0-3]]] = or(p[[P1:[0-9]]],!p[[P1]])
+; CHECK: sub({{.*}},{{.*}},p[[P0]]):carry
+; CHECK: sub({{.*}},{{.*}},p[[P0]]):carry
+define void @subc(i128 %a0, i128 %a1) #0 {
+ %v0 = sub i128 %a0, %a1
+ store i128 %v0, i128* @g, align 8
+ ret void
+}
+
+
Removed: llvm/trunk/test/CodeGen/Hexagon/sube.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/Hexagon/sube.ll?rev=333750&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/Hexagon/sube.ll (original)
+++ llvm/trunk/test/CodeGen/Hexagon/sube.ll (removed)
@@ -1,26 +0,0 @@
-; RUN: llc -march=hexagon -hexagon-expand-condsets=0 < %s | FileCheck %s
-
-; CHECK-DAG: r{{[0-9]+:[0-9]+}} = sub(r{{[0-9]+:[0-9]+}},r{{[0-9]+:[0-9]+}})
-; CHECK-DAG: r{{[0-9]+:[0-9]+}} = sub(r{{[0-9]+:[0-9]+}},r{{[0-9]+:[0-9]+}})
-; CHECK-DAG: p{{[0-9]+}} = cmp.gtu(r{{[0-9]+:[0-9]+}},r{{[0-9]+:[0-9]+}})
-; CHECK-DAG: r{{[0-9]+}} = mux(p{{[0-9]+}},r{{[0-9]+}},r{{[0-9]+}})
-; CHECK-DAG: r{{[0-9]+}} = mux(p{{[0-9]+}},r{{[0-9]+}},r{{[0-9]+}})
-
-define void @check_sube_subc(i64 %a0, i64 %a1, i64 %a2, i64 %a3, i64* %a4, i64* %a5) {
-b6:
- %v7 = zext i64 %a0 to i128
- %v8 = zext i64 %a1 to i128
- %v9 = shl i128 %v8, 64
- %v10 = or i128 %v7, %v9
- %v11 = zext i64 %a2 to i128
- %v12 = zext i64 %a3 to i128
- %v13 = shl i128 %v12, 64
- %v14 = or i128 %v11, %v13
- %v15 = sub i128 %v10, %v14
- %v16 = lshr i128 %v15, 64
- %v17 = trunc i128 %v15 to i64
- %v18 = trunc i128 %v16 to i64
- store i64 %v17, i64* %a4
- store i64 %v18, i64* %a5
- ret void
-}
More information about the llvm-commits
mailing list