From 253174bf50c932abaa680f465e2888c0e5272267 Mon Sep 17 00:00:00 2001 From: Bill Wendling Date: Sat, 22 Nov 2008 07:24:01 +0000 Subject: [PATCH] Cleanup of the [SU]ADDO type legalization code. Patch by Duncan! "It simplifies the type legalization part a bit, and produces better code by teaching SelectionDAG about the extra bits in an i8 SADDO/UADDO node. In essence, I spontaneously decided that on x86 this i8 boolean result would be either 0 or 1, and on other platforms 0/1 or 0/-1, depending on whether the platform likes it's boolean zero extended or sign extended." git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@59864 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/CodeGen/SelectionDAGNodes.h | 13 ++++---- .../SelectionDAG/LegalizeIntegerTypes.cpp | 30 ++++++++----------- lib/CodeGen/SelectionDAG/LegalizeTypes.h | 4 +-- lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 12 +++++++- 4 files changed, 31 insertions(+), 28 deletions(-) diff --git a/include/llvm/CodeGen/SelectionDAGNodes.h b/include/llvm/CodeGen/SelectionDAGNodes.h index 2698233fe9e..5b55df9601a 100644 --- a/include/llvm/CodeGen/SelectionDAGNodes.h +++ b/include/llvm/CodeGen/SelectionDAGNodes.h @@ -250,12 +250,13 @@ namespace ISD { // values. ADDE, SUBE, - // RESULT, BOOL = [SU]ADDO(LHS, RHS) - Overflow-aware nodes for arithmetic - // operations. These nodes takes two operands: the normal lhs and rhs to the - // add. They produce two results: the normal result of the add, and a - // boolean to indicate if an overflow occured (*not* a flag, because it may - // be stored to memory, etc.). These nodes is generated from the - // llvm.[su]add.with.overflow intrinsics. + // RESULT, BOOL = [SU]ADDO(LHS, RHS) - Overflow-aware nodes for addition. + // These nodes take two operands: the normal LHS and RHS to the add. They + // produce two results: the normal result of the add, and a boolean that + // indicates if an overflow occured (*not* a flag, because it may be stored + // to memory, etc.). If the type of the boolean is not i1 then the high + // bits conform to getSetCCResultContents. + // These nodes are generated from the llvm.[su]add.with.overflow intrinsics. SADDO, UADDO, // Simple binary floating point operators. diff --git a/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp b/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp index cd4524ef489..179329b5903 100644 --- a/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp +++ b/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp @@ -99,8 +99,8 @@ void DAGTypeLegalizer::PromoteIntegerResult(SDNode *N, unsigned ResNo) { case ISD::UDIV: case ISD::UREM: Result = PromoteIntRes_UDIV(N); break; - case ISD::SADDO: Result = PromoteIntRes_SADDO(N, ResNo); break; - case ISD::UADDO: Result = PromoteIntRes_UADDO(N, ResNo); break; + case ISD::SADDO: + case ISD::UADDO: Result = PromoteIntRes_XADDO(N, ResNo); break; case ISD::ATOMIC_LOAD_ADD_8: case ISD::ATOMIC_LOAD_SUB_8: @@ -518,26 +518,20 @@ SDValue DAGTypeLegalizer::PromoteIntRes_UDIV(SDNode *N) { return DAG.getNode(N->getOpcode(), LHS.getValueType(), LHS, RHS); } -SDValue DAGTypeLegalizer::PromoteIntRes_XADDO(SDNode *N, unsigned ResNo, - ISD::NodeType NTy) { - MVT NewVT = TLI.getTypeToTransformTo(SDValue(N, ResNo).getValueType()); - assert(isTypeLegal(NewVT) && "Illegal XADDO type!"); +SDValue DAGTypeLegalizer::PromoteIntRes_XADDO(SDNode *N, unsigned ResNo) { + assert(ResNo == 1 && "Only boolean result promotion currently supported!"); - MVT ValueVTs[] = { N->getOperand(0).getValueType(), NewVT }; + // Simply change the return type of the boolean result. + MVT NVT = TLI.getTypeToTransformTo(N->getValueType(1)); + MVT ValueVTs[] = { N->getValueType(0), NVT }; SDValue Ops[] = { N->getOperand(0), N->getOperand(1) }; + SDValue Res = DAG.getNode(N->getOpcode(), DAG.getVTList(ValueVTs, 2), Ops, 2); - SDValue Res = DAG.getNode(NTy, DAG.getVTList(&ValueVTs[0], 2), &Ops[0], 2); - ReplaceValueWith(SDValue(N, 0), SDValue(Res.getNode(), 0)); - ReplaceValueWith(SDValue(N, 1), SDValue(Res.getNode(), 1)); - return Res; -} - -SDValue DAGTypeLegalizer::PromoteIntRes_SADDO(SDNode *N, unsigned ResNo) { - return PromoteIntRes_XADDO(N, ResNo, ISD::SADDO); -} + // Modified the sum result - switch anything that used the old sum to use + // the new one. + ReplaceValueWith(SDValue(N, 0), Res); -SDValue DAGTypeLegalizer::PromoteIntRes_UADDO(SDNode *N, unsigned ResNo) { - return PromoteIntRes_XADDO(N, ResNo, ISD::UADDO); + return SDValue(Res.getNode(), 1); } SDValue DAGTypeLegalizer::PromoteIntRes_UNDEF(SDNode *N) { diff --git a/lib/CodeGen/SelectionDAG/LegalizeTypes.h b/lib/CodeGen/SelectionDAG/LegalizeTypes.h index e9af5f53477..f75fa778ed2 100644 --- a/lib/CodeGen/SelectionDAG/LegalizeTypes.h +++ b/lib/CodeGen/SelectionDAG/LegalizeTypes.h @@ -268,11 +268,9 @@ private: SDValue PromoteIntRes_SRL(SDNode *N); SDValue PromoteIntRes_TRUNCATE(SDNode *N); SDValue PromoteIntRes_UDIV(SDNode *N); - SDValue PromoteIntRes_XADDO(SDNode *N, unsigned ResNo, ISD::NodeType NTy); - SDValue PromoteIntRes_SADDO(SDNode *N, unsigned ResNo); - SDValue PromoteIntRes_UADDO(SDNode *N, unsigned ResNo); SDValue PromoteIntRes_UNDEF(SDNode *N); SDValue PromoteIntRes_VAARG(SDNode *N); + SDValue PromoteIntRes_XADDO(SDNode *N, unsigned ResNo); // Integer Operand Promotion. bool PromoteIntegerOperand(SDNode *N, unsigned OperandNo); diff --git a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp index 02159de0c75..7d64b2441d9 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -1491,6 +1491,11 @@ void SelectionDAG::ComputeMaskedBits(SDValue Op, const APInt &Mask, KnownOne &= KnownOne2; KnownZero &= KnownZero2; return; + case ISD::SADDO: + case ISD::UADDO: + if (Op.getResNo() != 1) + return; + // The boolean result conforms to getSetCCResultContents. Fall through. case ISD::SETCC: // If we know the result of a setcc has the top bits zero, use this info. if (TLI.getSetCCResultContents() == TargetLowering::ZeroOrOneSetCCResult && @@ -1893,7 +1898,12 @@ unsigned SelectionDAG::ComputeNumSignBits(SDValue Op, unsigned Depth) const{ if (Tmp == 1) return 1; // Early out. Tmp2 = ComputeNumSignBits(Op.getOperand(2), Depth+1); return std::min(Tmp, Tmp2); - + + case ISD::SADDO: + case ISD::UADDO: + if (Op.getResNo() != 1) + break; + // The boolean result conforms to getSetCCResultContents. Fall through. case ISD::SETCC: // If setcc returns 0/-1, all bits are sign bits. if (TLI.getSetCCResultContents() == -- 2.34.1