[llvm] r265559 - Revert r265450 "[X86] Reuse EFLAGS and form LOCKed ops when only user is SETCC."
Hans Wennborg via llvm-commits
llvm-commits at lists.llvm.org
Wed Apr 6 09:44:38 PDT 2016
Author: hans
Date: Wed Apr 6 11:44:38 2016
New Revision: 265559
URL: http://llvm.org/viewvc/llvm-project?rev=265559&view=rev
Log:
Revert r265450 "[X86] Reuse EFLAGS and form LOCKed ops when only user is SETCC."
It caused ASan 32-bit tests to hang (PR27245).
Modified:
llvm/trunk/lib/Target/X86/X86ISelLowering.cpp
llvm/trunk/test/CodeGen/X86/atomic-eflags-reuse.ll
Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.cpp?rev=265559&r1=265558&r2=265559&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86ISelLowering.cpp (original)
+++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Wed Apr 6 11:44:38 2016
@@ -26135,56 +26135,6 @@ static SDValue combineSelect(SDNode *N,
return SDValue();
}
-/// Combine:
-/// (brcond/cmov/setcc .., (cmp (atomic_load_op ..), 0), cc)
-/// to:
-/// (brcond/cmov/setcc .., (LOCKed op ..), cc)
-/// i.e., reusing the EFLAGS produced by the LOCKed instruction.
-/// Note that this is only legal for some op/cc combinations.
-static SDValue combineSetCCAtomicArith(SDValue Cmp, X86::CondCode CC,
- SelectionDAG &DAG) {
- // This combine only operates on CMP-like nodes.
- if (!(Cmp.getOpcode() == X86ISD::CMP ||
- (Cmp.getOpcode() == X86ISD::SUB && !Cmp->hasAnyUseOfValue(0))))
- return SDValue();
-
- SDValue LHS = Cmp.getOperand(0);
- SDValue RHS = Cmp.getOperand(1);
-
- if (!LHS.hasOneUse())
- return SDValue();
-
- // FIXME: We can do this for XOR/OR/AND as well, but only if they survive
- // AtomicExpand. Currently, we choose to expand them to cmpxchg if they
- // have any users. Could we relax that to ignore (icmp x,0) users?
- switch (LHS->getOpcode()) {
- case ISD::ATOMIC_LOAD_ADD:
- case ISD::ATOMIC_LOAD_SUB:
- break;
- default:
- return SDValue();
- }
-
- auto *C = dyn_cast<ConstantSDNode>(RHS);
- if (!C || C->getZExtValue() != 0)
- return SDValue();
-
- // Don't do this for all condition codes, as OF/CF are cleared by (CMP x,0)
- // but might be set by arithmetic. Furthermore, we might later select INC/DEC,
- // which don't modify CF (though CCs using CF should have been optimized out).
- // SF/ZF are safe as they are set the same way.
- // Note that in theory, the transformation is also valid for P/NP.
- if (CC != X86::COND_E && CC != X86::COND_NE && CC != X86::COND_S &&
- CC != X86::COND_NS)
- return SDValue();
-
- SDValue LockOp = lowerAtomicArithWithLOCK(LHS, DAG);
- DAG.ReplaceAllUsesOfValueWith(LHS.getValue(0),
- DAG.getUNDEF(LHS.getValueType()));
- DAG.ReplaceAllUsesOfValueWith(LHS.getValue(1), LockOp.getValue(1));
- return LockOp;
-}
-
// Check whether a boolean test is testing a boolean value generated by
// X86ISD::SETCC. If so, return the operand of that SETCC and proper condition
// code.
@@ -26356,16 +26306,6 @@ static bool checkBoolTestAndOrSetCCCombi
return true;
}
-/// 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 (SDValue R = checkBoolTestSetCCCombine(EFLAGS, CC))
- return R;
- return combineSetCCAtomicArith(EFLAGS, CC, DAG);
-}
-
/// Optimize X86ISD::CMOV [LHS, RHS, CONDCODE (e.g. X86::COND_NE), CONDVAL]
static SDValue combineCMov(SDNode *N, SelectionDAG &DAG,
TargetLowering::DAGCombinerInfo &DCI,
@@ -26392,14 +26332,15 @@ static SDValue combineCMov(SDNode *N, Se
}
}
- // Try to simplify the EFLAGS and condition code operands.
- // We can't always do this as FCMOV only supports a subset of X86 cond.
- if (SDValue Flags = combineSetCCEFLAGS(Cond, CC, DAG)) {
- if (FalseOp.getValueType() != MVT::f80 || hasFPCMov(CC)) {
- SDValue Ops[] = {FalseOp, TrueOp, DAG.getConstant(CC, DL, MVT::i8),
- Flags};
- return DAG.getNode(X86ISD::CMOV, DL, N->getVTList(), Ops);
- }
+ SDValue Flags;
+
+ Flags = checkBoolTestSetCCCombine(Cond, CC);
+ if (Flags.getNode() &&
+ // Extra check as FCMOV only supports a subset of X86 cond.
+ (FalseOp.getValueType() != MVT::f80 || hasFPCMov(CC))) {
+ SDValue Ops[] = { FalseOp, TrueOp,
+ DAG.getConstant(CC, DL, MVT::i8), Flags };
+ return DAG.getNode(X86ISD::CMOV, DL, N->getVTList(), Ops);
}
// If this is a select between two integer constants, try to do some
@@ -29325,8 +29266,7 @@ static SDValue combineX86SetCC(SDNode *N
if (CC == X86::COND_B)
return MaterializeSETB(DL, EFLAGS, DAG, N->getSimpleValueType(0));
- // Try to simplify the EFLAGS and condition code operands.
- if (SDValue Flags = combineSetCCEFLAGS(EFLAGS, CC, DAG)) {
+ if (SDValue Flags = checkBoolTestSetCCCombine(EFLAGS, CC)) {
SDValue Cond = DAG.getConstant(CC, DL, MVT::i8);
return DAG.getNode(X86ISD::SETCC, DL, N->getVTList(), Cond, Flags);
}
@@ -29339,16 +29279,15 @@ static SDValue combineBrCond(SDNode *N,
TargetLowering::DAGCombinerInfo &DCI,
const X86Subtarget &Subtarget) {
SDLoc DL(N);
+ SDValue Chain = N->getOperand(0);
+ SDValue Dest = N->getOperand(1);
SDValue EFLAGS = N->getOperand(3);
X86::CondCode CC = X86::CondCode(N->getConstantOperandVal(2));
- // Try to simplify the EFLAGS and condition code operands.
- // Make sure to not keep references to operands, as combineSetCCEFLAGS can
- // RAUW them under us.
- if (SDValue Flags = combineSetCCEFLAGS(EFLAGS, CC, DAG)) {
+ if (SDValue Flags = checkBoolTestSetCCCombine(EFLAGS, CC)) {
SDValue Cond = DAG.getConstant(CC, DL, MVT::i8);
- return DAG.getNode(X86ISD::BRCOND, DL, N->getVTList(), N->getOperand(0),
- N->getOperand(1), Cond, Flags);
+ return DAG.getNode(X86ISD::BRCOND, DL, N->getVTList(), Chain, Dest, Cond,
+ Flags);
}
return SDValue();
Modified: llvm/trunk/test/CodeGen/X86/atomic-eflags-reuse.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/atomic-eflags-reuse.ll?rev=265559&r1=265558&r2=265559&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/X86/atomic-eflags-reuse.ll (original)
+++ llvm/trunk/test/CodeGen/X86/atomic-eflags-reuse.ll Wed Apr 6 11:44:38 2016
@@ -4,7 +4,9 @@
define i8 @test_add_1_setcc_ne(i64* %p) #0 {
; CHECK-LABEL: test_add_1_setcc_ne:
; CHECK: # BB#0: # %entry
-; CHECK-NEXT: lock incq (%rdi)
+; CHECK-NEXT: movl $1, %eax
+; CHECK-NEXT: lock xaddq %rax, (%rdi)
+; CHECK-NEXT: testq %rax, %rax
; CHECK-NEXT: setne %al
; CHECK-NEXT: retq
entry:
@@ -17,7 +19,9 @@ entry:
define i8 @test_sub_1_setcc_eq(i64* %p) #0 {
; CHECK-LABEL: test_sub_1_setcc_eq:
; CHECK: # BB#0: # %entry
-; CHECK-NEXT: lock decq (%rdi)
+; CHECK-NEXT: movq $-1, %rax
+; CHECK-NEXT: lock xaddq %rax, (%rdi)
+; CHECK-NEXT: testq %rax, %rax
; CHECK-NEXT: sete %al
; CHECK-NEXT: retq
entry:
@@ -45,7 +49,9 @@ entry:
define i8 @test_sub_10_setcc_sge(i64* %p) #0 {
; CHECK-LABEL: test_sub_10_setcc_sge:
; CHECK: # BB#0: # %entry
-; CHECK-NEXT: lock addq $-10, (%rdi)
+; CHECK-NEXT: movq $-10, %rax
+; CHECK-NEXT: lock xaddq %rax, (%rdi)
+; CHECK-NEXT: testq %rax, %rax
; CHECK-NEXT: setns %al
; CHECK-NEXT: retq
entry:
@@ -60,7 +66,9 @@ entry:
define i32 @test_add_10_brcond_sge(i64* %p, i32 %a0, i32 %a1) #0 {
; CHECK-LABEL: test_add_10_brcond_sge:
; CHECK: # BB#0: # %entry
-; CHECK-NEXT: lock addq $10, (%rdi)
+; CHECK-NEXT: movl $10, %eax
+; CHECK-NEXT: lock xaddq %rax, (%rdi)
+; CHECK-NEXT: testq %rax, %rax
; CHECK-NEXT: js .LBB4_2
; CHECK-NEXT: # BB#1: # %t
; CHECK-NEXT: movl %esi, %eax
@@ -81,7 +89,9 @@ f:
define i32 @test_sub_1_cmov_slt(i64* %p, i32 %a0, i32 %a1) #0 {
; CHECK-LABEL: test_sub_1_cmov_slt:
; CHECK: # BB#0: # %entry
-; CHECK-NEXT: lock decq (%rdi)
+; CHECK-NEXT: movq $-1, %rax
+; CHECK-NEXT: lock xaddq %rax, (%rdi)
+; CHECK-NEXT: testq %rax, %rax
; CHECK-NEXT: cmovnsl %edx, %esi
; CHECK-NEXT: movl %esi, %eax
; CHECK-NEXT: retq
More information about the llvm-commits
mailing list