forked from OSchip/llvm-project
[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
This commit is contained in:
parent
70af85b0ac
commit
2c7a9476e0
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
//
|
||||
|
|
Loading…
Reference in New Issue