diff options
author | Craig Topper <craig.topper@intel.com> | 2018-12-06 22:26:59 +0000 |
---|---|---|
committer | Craig Topper <craig.topper@intel.com> | 2018-12-06 22:26:59 +0000 |
commit | 2c7a9476e0b8068518d83d1afced9b4fdca4961c (patch) | |
tree | 8085303d1dcbde208ae017cf3d8856c209431466 /llvm/lib | |
parent | 70af85b0accbe887604120776ad2e9a62340a64a (diff) | |
download | bcm5719-llvm-2c7a9476e0b8068518d83d1afced9b4fdca4961c.tar.gz bcm5719-llvm-2c7a9476e0b8068518d83d1afced9b4fdca4961c.zip |
[X86] Directly create ADC/SBB nodes instead of using ADD/SUB with (and SETCC_CARRY, 1)
This addresses a FIXME and avoids depending on an isel pattern match I think. I've remove the isel patterns too since he have no lit tests left that cover them. Hopefully that really means they are unused.
I'm trying to decide if we need SETCC_CARRY. This removes one of its usages.
Differential Revision: https://reviews.llvm.org/D55355
llvm-svn: 348536
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/Target/X86/X86ISelLowering.cpp | 31 | ||||
-rw-r--r-- | llvm/lib/Target/X86/X86InstrCompiler.td | 24 |
2 files changed, 8 insertions, 47 deletions
diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp index d725fbd6f41..4590980aa1a 100644 --- a/llvm/lib/Target/X86/X86ISelLowering.cpp +++ b/llvm/lib/Target/X86/X86ISelLowering.cpp @@ -39995,18 +39995,6 @@ static SDValue combineADC(SDNode *N, SelectionDAG &DAG, return SDValue(); } -/// Materialize "setb reg" as "sbb reg,reg", since it produces an all-ones bit -/// which is more useful than 0/1 in some cases. -static SDValue materializeSBB(SDNode *N, SDValue EFLAGS, SelectionDAG &DAG) { - SDLoc DL(N); - // "Condition code B" is also known as "the carry flag" (CF). - SDValue CF = DAG.getConstant(X86::COND_B, DL, MVT::i8); - SDValue SBB = DAG.getNode(X86ISD::SETCC_CARRY, DL, MVT::i8, CF, EFLAGS); - MVT VT = N->getSimpleValueType(0); - assert(VT == MVT::i8 && "Unexpected type for SETCC node"); - return DAG.getNode(ISD::AND, DL, VT, SBB, DAG.getConstant(1, DL, VT)); -} - /// If this is an add or subtract where one operand is produced by a cmp+setcc, /// then try to convert it to an ADC or SBB. This replaces TEST+SET+{ADD/SUB} /// with CMP+{ADC, SBB}. @@ -40077,13 +40065,11 @@ static SDValue combineAddOrSubToADCOrSBB(SDNode *N, SelectionDAG &DAG) { } if (CC == X86::COND_B) { - // X + SETB Z --> X + (mask SBB Z, Z) - // X - SETB Z --> X - (mask SBB Z, Z) - // TODO: Produce ADC/SBB here directly and avoid SETCC_CARRY? - SDValue SBB = materializeSBB(Y.getNode(), Y.getOperand(1), DAG); - if (SBB.getValueSizeInBits() != VT.getSizeInBits()) - SBB = DAG.getZExtOrTrunc(SBB, DL, VT); - return DAG.getNode(IsSub ? ISD::SUB : ISD::ADD, DL, VT, X, SBB); + // X + SETB Z --> adc X, 0 + // X - SETB Z --> sbb X, 0 + return DAG.getNode(IsSub ? X86ISD::SBB : X86ISD::ADC, DL, + DAG.getVTList(VT, MVT::i32), X, + DAG.getConstant(0, DL, VT), Y.getOperand(1)); } if (CC == X86::COND_A) { @@ -40101,10 +40087,9 @@ static SDValue combineAddOrSubToADCOrSBB(SDNode *N, SelectionDAG &DAG) { EFLAGS.getNode()->getVTList(), EFLAGS.getOperand(1), EFLAGS.getOperand(0)); SDValue NewEFLAGS = SDValue(NewSub.getNode(), EFLAGS.getResNo()); - SDValue SBB = materializeSBB(Y.getNode(), NewEFLAGS, DAG); - if (SBB.getValueSizeInBits() != VT.getSizeInBits()) - SBB = DAG.getZExtOrTrunc(SBB, DL, VT); - return DAG.getNode(IsSub ? ISD::SUB : ISD::ADD, DL, VT, X, SBB); + return DAG.getNode(IsSub ? X86ISD::SBB : X86ISD::ADC, DL, + DAG.getVTList(VT, MVT::i32), X, + DAG.getConstant(0, DL, VT), NewEFLAGS); } } diff --git a/llvm/lib/Target/X86/X86InstrCompiler.td b/llvm/lib/Target/X86/X86InstrCompiler.td index df4e37927ab..8ba6ecf78b6 100644 --- a/llvm/lib/Target/X86/X86InstrCompiler.td +++ b/llvm/lib/Target/X86/X86InstrCompiler.td @@ -362,30 +362,6 @@ def : Pat<(i64 (sext (i8 (X86setcc_c X86_COND_B, EFLAGS)))), def : Pat<(and (i8 (X86setcc_c X86_COND_B, EFLAGS)), 1), (SETBr)>; -// (add OP, SETB) -> (adc OP, 0) -def : Pat<(add (and (i8 (X86setcc_c X86_COND_B, EFLAGS)), 1), GR8:$op), - (ADC8ri GR8:$op, 0)>; -def : Pat<(add (and (i32 (X86setcc_c X86_COND_B, EFLAGS)), 1), GR32:$op), - (ADC32ri8 GR32:$op, 0)>; -def : Pat<(add (and (i64 (X86setcc_c X86_COND_B, EFLAGS)), 1), GR64:$op), - (ADC64ri8 GR64:$op, 0)>; - -// (sub OP, SETB) -> (sbb OP, 0) -def : Pat<(sub GR8:$op, (and (i8 (X86setcc_c X86_COND_B, EFLAGS)), 1)), - (SBB8ri GR8:$op, 0)>; -def : Pat<(sub GR32:$op, (and (i32 (X86setcc_c X86_COND_B, EFLAGS)), 1)), - (SBB32ri8 GR32:$op, 0)>; -def : Pat<(sub GR64:$op, (and (i64 (X86setcc_c X86_COND_B, EFLAGS)), 1)), - (SBB64ri8 GR64:$op, 0)>; - -// (sub OP, SETCC_CARRY) -> (adc OP, 0) -def : Pat<(sub GR8:$op, (i8 (X86setcc_c X86_COND_B, EFLAGS))), - (ADC8ri GR8:$op, 0)>; -def : Pat<(sub GR32:$op, (i32 (X86setcc_c X86_COND_B, EFLAGS))), - (ADC32ri8 GR32:$op, 0)>; -def : Pat<(sub GR64:$op, (i64 (X86setcc_c X86_COND_B, EFLAGS))), - (ADC64ri8 GR64:$op, 0)>; - //===----------------------------------------------------------------------===// // String Pseudo Instructions // |