summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHans Wennborg <hans@hanshq.net>2017-09-01 16:28:52 +0000
committerHans Wennborg <hans@hanshq.net>2017-09-01 16:28:52 +0000
commit657c31173ea30090583e40c7a9204561d9c2d8c4 (patch)
treeb9e33478611fc841f0b4828198b6f306019498ff
parenta3b2103ffc378bb6c82a05e720163f448149cd75 (diff)
Merging r312285:
------------------------------------------------------------------------ r312285 | ctopper | 2017-08-31 14:39:23 -0700 (Thu, 31 Aug 2017) | 11 lines [X86] Don't pull carry through X86ISD::ADD carryin, -1 if we can't guranteed we're really using the carry flag from the add. Prior to this patch we had a DAG combine that tried to bypass an X86ISD::ADD with -1 being added to the carry flag of some previous operation. We would then pass the carry flag directly to user. But this is only safe if the user is looking for the carry flag and not the zero flag. So we need to only do this combine in a context where we know what flag the consumer is using. Fixes PR34381. Differential Revision: https://reviews.llvm.org/D37317 ------------------------------------------------------------------------ git-svn-id: https://llvm.org/svn/llvm-project/llvm/branches/release_50@312333 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Target/X86/X86ISelLowering.cpp67
1 files changed, 45 insertions, 22 deletions
diff --git a/lib/Target/X86/X86ISelLowering.cpp b/lib/Target/X86/X86ISelLowering.cpp
index 193ee8de6192..957b46c40a6e 100644
--- a/lib/Target/X86/X86ISelLowering.cpp
+++ b/lib/Target/X86/X86ISelLowering.cpp
@@ -30942,11 +30942,40 @@ static bool checkBoolTestAndOrSetCCCombine(SDValue Cond, X86::CondCode &CC0,
return true;
}
+// When legalizing carry, we create carries via add X, -1
+// If that comes from an actual carry, via setcc, we use the
+// carry directly.
+static SDValue combineCarryThroughADD(SDValue EFLAGS) {
+ if (EFLAGS.getOpcode() == X86ISD::ADD) {
+ if (isAllOnesConstant(EFLAGS.getOperand(1))) {
+ SDValue Carry = EFLAGS.getOperand(0);
+ while (Carry.getOpcode() == ISD::TRUNCATE ||
+ Carry.getOpcode() == ISD::ZERO_EXTEND ||
+ Carry.getOpcode() == ISD::SIGN_EXTEND ||
+ Carry.getOpcode() == ISD::ANY_EXTEND ||
+ (Carry.getOpcode() == ISD::AND &&
+ isOneConstant(Carry.getOperand(1))))
+ Carry = Carry.getOperand(0);
+ if (Carry.getOpcode() == X86ISD::SETCC ||
+ Carry.getOpcode() == X86ISD::SETCC_CARRY) {
+ if (Carry.getConstantOperandVal(0) == X86::COND_B)
+ return Carry.getOperand(1);
+ }
+ }
+ }
+
+ return SDValue();
+}
+
/// Optimize an EFLAGS definition used according to the condition code \p CC
/// into a simpler EFLAGS value, potentially returning a new \p CC and replacing
/// uses of chain values.
static SDValue combineSetCCEFLAGS(SDValue EFLAGS, X86::CondCode &CC,
SelectionDAG &DAG) {
+ if (CC == X86::COND_B)
+ if (SDValue Flags = combineCarryThroughADD(EFLAGS))
+ return Flags;
+
if (SDValue R = checkBoolTestSetCCCombine(EFLAGS, CC))
return R;
return combineSetCCAtomicArith(EFLAGS, CC, DAG);
@@ -34989,27 +35018,13 @@ static SDValue combineSIntToFP(SDNode *N, SelectionDAG &DAG,
return SDValue();
}
-// Optimize RES, EFLAGS = X86ISD::ADD LHS, RHS
-static SDValue combineX86ADD(SDNode *N, SelectionDAG &DAG,
- X86TargetLowering::DAGCombinerInfo &DCI) {
- // When legalizing carry, we create carries via add X, -1
- // If that comes from an actual carry, via setcc, we use the
- // carry directly.
- if (isAllOnesConstant(N->getOperand(1)) && N->hasAnyUseOfValue(1)) {
- SDValue Carry = N->getOperand(0);
- while (Carry.getOpcode() == ISD::TRUNCATE ||
- Carry.getOpcode() == ISD::ZERO_EXTEND ||
- Carry.getOpcode() == ISD::SIGN_EXTEND ||
- Carry.getOpcode() == ISD::ANY_EXTEND ||
- (Carry.getOpcode() == ISD::AND &&
- isOneConstant(Carry.getOperand(1))))
- Carry = Carry.getOperand(0);
-
- if (Carry.getOpcode() == X86ISD::SETCC ||
- Carry.getOpcode() == X86ISD::SETCC_CARRY) {
- if (Carry.getConstantOperandVal(0) == X86::COND_B)
- return DCI.CombineTo(N, SDValue(N, 0), Carry.getOperand(1));
- }
+static SDValue combineSBB(SDNode *N, SelectionDAG &DAG) {
+ if (SDValue Flags = combineCarryThroughADD(N->getOperand(2))) {
+ MVT VT = N->getSimpleValueType(0);
+ SDVTList VTs = DAG.getVTList(VT, MVT::i32);
+ return DAG.getNode(X86ISD::SBB, SDLoc(N), VTs,
+ N->getOperand(0), N->getOperand(1),
+ Flags);
}
return SDValue();
@@ -35038,6 +35053,14 @@ static SDValue combineADC(SDNode *N, SelectionDAG &DAG,
return DCI.CombineTo(N, Res1, CarryOut);
}
+ if (SDValue Flags = combineCarryThroughADD(N->getOperand(2))) {
+ MVT VT = N->getSimpleValueType(0);
+ SDVTList VTs = DAG.getVTList(VT, MVT::i32);
+ return DAG.getNode(X86ISD::ADC, SDLoc(N), VTs,
+ N->getOperand(0), N->getOperand(1),
+ Flags);
+ }
+
return SDValue();
}
@@ -35677,7 +35700,7 @@ SDValue X86TargetLowering::PerformDAGCombine(SDNode *N,
case X86ISD::CMOV: return combineCMov(N, DAG, DCI, Subtarget);
case ISD::ADD: return combineAdd(N, DAG, Subtarget);
case ISD::SUB: return combineSub(N, DAG, Subtarget);
- case X86ISD::ADD: return combineX86ADD(N, DAG, DCI);
+ case X86ISD::SBB: return combineSBB(N, DAG);
case X86ISD::ADC: return combineADC(N, DAG, DCI);
case ISD::MUL: return combineMul(N, DAG, DCI, Subtarget);
case ISD::SHL: