From efbf7d1ceb55d891afb39842be75014807c7042f Mon Sep 17 00:00:00 2001 From: Tim Northover Date: Tue, 10 Jun 2014 10:50:11 +0000 Subject: [PATCH] Revert "X86: elide comparisons after cmpxchg instructions." This reverts commit r210523. It was committed prematurely without waiting for review. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@210524 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/X86/X86ISelLowering.cpp | 156 ++++++++++------------------- lib/Target/X86/X86ISelLowering.h | 7 +- test/CodeGen/X86/cmpxchg-i1.ll | 82 --------------- 3 files changed, 57 insertions(+), 188 deletions(-) delete mode 100644 test/CodeGen/X86/cmpxchg-i1.ll diff --git a/lib/Target/X86/X86ISelLowering.cpp b/lib/Target/X86/X86ISelLowering.cpp index 171f832a44d..ecf718f639f 100644 --- a/lib/Target/X86/X86ISelLowering.cpp +++ b/lib/Target/X86/X86ISelLowering.cpp @@ -3504,24 +3504,6 @@ static bool isX86CCUnsigned(unsigned X86CC) { llvm_unreachable("covered switch fell through?!"); } -/// Convert an integer condition code to an x86 one in the most straightforward -/// way possible, with no optimisation attempt. -static unsigned getSimpleX86IntCC(ISD::CondCode SetCCOpcode) { - switch (SetCCOpcode) { - default: llvm_unreachable("Invalid integer condition!"); - case ISD::SETEQ: return X86::COND_E; - case ISD::SETGT: return X86::COND_G; - case ISD::SETGE: return X86::COND_GE; - case ISD::SETLT: return X86::COND_L; - case ISD::SETLE: return X86::COND_LE; - case ISD::SETNE: return X86::COND_NE; - case ISD::SETULT: return X86::COND_B; - case ISD::SETUGT: return X86::COND_A; - case ISD::SETULE: return X86::COND_BE; - case ISD::SETUGE: return X86::COND_AE; - } -} - /// TranslateX86CC - do a one to one translation of a ISD::CondCode to the X86 /// specific condition code, returning the condition code and the LHS/RHS of the /// comparison to make. @@ -3545,7 +3527,19 @@ static unsigned TranslateX86CC(ISD::CondCode SetCCOpcode, bool isFP, } } - return getSimpleX86IntCC(SetCCOpcode); + switch (SetCCOpcode) { + default: llvm_unreachable("Invalid integer condition!"); + case ISD::SETEQ: return X86::COND_E; + case ISD::SETGT: return X86::COND_G; + case ISD::SETGE: return X86::COND_GE; + case ISD::SETLT: return X86::COND_L; + case ISD::SETLE: return X86::COND_LE; + case ISD::SETNE: return X86::COND_NE; + case ISD::SETULT: return X86::COND_B; + case ISD::SETUGT: return X86::COND_A; + case ISD::SETULE: return X86::COND_BE; + case ISD::SETUGE: return X86::COND_AE; + } } // First determine if it is required or is profitable to flip the operands. @@ -10380,77 +10374,10 @@ SDValue X86TargetLowering::EmitTest(SDValue Op, unsigned X86CC, SDLoc dl, return SDValue(New.getNode(), 1); } -static SDValue LowerCMP_SWAP(SDValue Op, const X86Subtarget *Subtarget, - SelectionDAG &DAG) { - MVT T = Op.getSimpleValueType(); - SDLoc DL(Op); - unsigned Reg = 0; - unsigned size = 0; - switch(T.SimpleTy) { - default: llvm_unreachable("Invalid value type!"); - case MVT::i8: Reg = X86::AL; size = 1; break; - case MVT::i16: Reg = X86::AX; size = 2; break; - case MVT::i32: Reg = X86::EAX; size = 4; break; - case MVT::i64: - assert(Subtarget->is64Bit() && "Node not type legal!"); - Reg = X86::RAX; size = 8; - break; - } - SDValue cpIn = DAG.getCopyToReg(Op.getOperand(0), DL, Reg, - Op.getOperand(2), SDValue()); - SDValue Ops[] = { cpIn.getValue(0), - Op.getOperand(1), - Op.getOperand(3), - DAG.getTargetConstant(size, MVT::i8), - cpIn.getValue(1) }; - SDVTList Tys = DAG.getVTList(MVT::Other, MVT::Glue); - MachineMemOperand *MMO = cast(Op)->getMemOperand(); - SDValue Result = DAG.getMemIntrinsicNode(X86ISD::LCMPXCHG_DAG, DL, Tys, - Ops, T, MMO); - SDValue cpOut = - DAG.getCopyFromReg(Result.getValue(0), DL, Reg, T, Result.getValue(1)); - return cpOut; -} - - -/// Emit nodes that will be selected as "cmp Op0,Op1", or something equivalent -/// and set X86CC to the needed condition code to make use of the -/// comparison. This may not be the obvious equivalent to CC if the comparison -/// can be achieved more efficiently using a different method. -SDValue X86TargetLowering::EmitCmp(SDValue Op0, SDValue Op1, ISD::CondCode CC, - SDLoc dl, SelectionDAG &DAG, - unsigned &X86CC) const { - // A cmpxchg instruction will actually perform the comparison - if ((Op0.getOpcode() == ISD::ATOMIC_CMP_SWAP && Op0.getOperand(2) == Op1) || - (Op1.getOpcode() == ISD::ATOMIC_CMP_SWAP && Op1.getOperand(2) == Op0)) { - SDValue CmpSwap; - if (Op0.getOpcode() == ISD::ATOMIC_CMP_SWAP) { - // x86's cmpxchg instruction performs the equivalent of "cmp desired, - // loaded". - CmpSwap = Op0; - CC = getSetCCSwappedOperands(CC); - } else - CmpSwap = Op1; - - // Lowering the CmpSwap node gives us a getCopyFromReg SDValue representing - // the value loaded. I.e. the ATOMIC_CMP_SWAP - X86CC = getSimpleX86IntCC(CC); - SDValue EFLAGS = LowerCMP_SWAP(CmpSwap, Subtarget, DAG); - DAG.ReplaceAllUsesOfValueWith(CmpSwap.getValue(0), EFLAGS); - - // Glue on a copy from EFLAGS to be used in place of the required Cmp. - EFLAGS = DAG.getCopyFromReg(EFLAGS.getValue(1), dl, X86::EFLAGS, - MVT::i32, EFLAGS.getValue(2)); - DAG.ReplaceAllUsesOfValueWith(CmpSwap.getValue(1), EFLAGS.getValue(1)); - - return EFLAGS; - } - - bool IsFP = Op1.getSimpleValueType().isFloatingPoint(); - X86CC = TranslateX86CC(CC, IsFP, Op0, Op1, DAG); - if (X86CC == X86::COND_INVALID) - return SDValue(); - +/// Emit nodes that will be selected as "cmp Op0,Op1", or something +/// equivalent. +SDValue X86TargetLowering::EmitCmp(SDValue Op0, SDValue Op1, unsigned X86CC, + SDLoc dl, SelectionDAG &DAG) const { if (ConstantSDNode *C = dyn_cast(Op1)) { if (C->getAPIntValue() == 0) return EmitTest(Op0, X86CC, dl, DAG); @@ -10458,7 +10385,7 @@ SDValue X86TargetLowering::EmitCmp(SDValue Op0, SDValue Op1, ISD::CondCode CC, if (Op0.getValueType() == MVT::i1) llvm_unreachable("Unexpected comparison operation for MVT::i1 operands"); } - + if ((Op0.getValueType() == MVT::i8 || Op0.getValueType() == MVT::i16 || Op0.getValueType() == MVT::i32 || Op0.getValueType() == MVT::i64)) { // Do the comparison at i32 if it's smaller, besides the Atom case. @@ -11024,11 +10951,12 @@ SDValue X86TargetLowering::LowerSETCC(SDValue Op, SelectionDAG &DAG) const { return DAG.getSetCC(dl, VT, Op0, DAG.getConstant(0, MVT::i1), NewCC); } - unsigned X86CC; - SDValue EFLAGS = EmitCmp(Op0, Op1, CC, dl, DAG, X86CC); - if (!EFLAGS.getNode()) + bool isFP = Op1.getSimpleValueType().isFloatingPoint(); + unsigned X86CC = TranslateX86CC(CC, isFP, Op0, Op1, DAG); + if (X86CC == X86::COND_INVALID) return SDValue(); + SDValue EFLAGS = EmitCmp(Op0, Op1, X86CC, dl, DAG); EFLAGS = ConvertCmpIfNecessary(EFLAGS, DAG); SDValue SetCC = DAG.getNode(X86ISD::SETCC, dl, MVT::i8, DAG.getConstant(X86CC, MVT::i8), EFLAGS); @@ -11456,14 +11384,6 @@ SDValue X86TargetLowering::LowerBRCOND(SDValue Op, SelectionDAG &DAG) const { if (isX86LogicalCmp(Cmp) || Opc == X86ISD::BT) { Cond = Cmp; addTest = false; - } else if (Opc == ISD::CopyFromReg && - Cmp->getOperand(0)->getOpcode() == ISD::CopyFromReg && - Cmp->getOperand(0)->getOperand(0)->getOpcode() == - X86ISD::LCMPXCHG_DAG) { - assert(cast(Cmp->getOperand(1))->getReg() == X86::EFLAGS); - Chain = Cmp.getValue(1); - Cond = Cmp; - addTest = false; } else { switch (cast(CC)->getZExtValue()) { default: break; @@ -14443,6 +14363,38 @@ static SDValue LowerATOMIC_FENCE(SDValue Op, const X86Subtarget *Subtarget, return DAG.getNode(X86ISD::MEMBARRIER, dl, MVT::Other, Op.getOperand(0)); } +static SDValue LowerCMP_SWAP(SDValue Op, const X86Subtarget *Subtarget, + SelectionDAG &DAG) { + MVT T = Op.getSimpleValueType(); + SDLoc DL(Op); + unsigned Reg = 0; + unsigned size = 0; + switch(T.SimpleTy) { + default: llvm_unreachable("Invalid value type!"); + case MVT::i8: Reg = X86::AL; size = 1; break; + case MVT::i16: Reg = X86::AX; size = 2; break; + case MVT::i32: Reg = X86::EAX; size = 4; break; + case MVT::i64: + assert(Subtarget->is64Bit() && "Node not type legal!"); + Reg = X86::RAX; size = 8; + break; + } + SDValue cpIn = DAG.getCopyToReg(Op.getOperand(0), DL, Reg, + Op.getOperand(2), SDValue()); + SDValue Ops[] = { cpIn.getValue(0), + Op.getOperand(1), + Op.getOperand(3), + DAG.getTargetConstant(size, MVT::i8), + cpIn.getValue(1) }; + SDVTList Tys = DAG.getVTList(MVT::Other, MVT::Glue); + MachineMemOperand *MMO = cast(Op)->getMemOperand(); + SDValue Result = DAG.getMemIntrinsicNode(X86ISD::LCMPXCHG_DAG, DL, Tys, + Ops, T, MMO); + SDValue cpOut = + DAG.getCopyFromReg(Result.getValue(0), DL, Reg, T, Result.getValue(1)); + return cpOut; +} + static SDValue LowerBITCAST(SDValue Op, const X86Subtarget *Subtarget, SelectionDAG &DAG) { MVT SrcVT = Op.getOperand(0).getSimpleValueType(); diff --git a/lib/Target/X86/X86ISelLowering.h b/lib/Target/X86/X86ISelLowering.h index 25214464902..af2e4344e5b 100644 --- a/lib/Target/X86/X86ISelLowering.h +++ b/lib/Target/X86/X86ISelLowering.h @@ -1006,10 +1006,9 @@ namespace llvm { SelectionDAG &DAG) const; /// Emit nodes that will be selected as "cmp Op0,Op1", or something - /// equivalent, possibly adjusting the condition code to a more appropriate - /// x86 form. - SDValue EmitCmp(SDValue Op0, SDValue Op1, ISD::CondCode CC, SDLoc dl, - SelectionDAG &DAG, unsigned &X86CC) const; + /// equivalent, for use with the given x86 condition code. + SDValue EmitCmp(SDValue Op0, SDValue Op1, unsigned X86CC, SDLoc dl, + SelectionDAG &DAG) const; /// Convert a comparison if required by the subtarget. SDValue ConvertCmpIfNecessary(SDValue Cmp, SelectionDAG &DAG) const; diff --git a/test/CodeGen/X86/cmpxchg-i1.ll b/test/CodeGen/X86/cmpxchg-i1.ll deleted file mode 100644 index 53cf3e300fd..00000000000 --- a/test/CodeGen/X86/cmpxchg-i1.ll +++ /dev/null @@ -1,82 +0,0 @@ -; RUN: llc -mtriple=x86_64 -o - %s | FileCheck %s - -define i1 @try_cmpxchg(i32* %addr, i32 %desired, i32 %new) { -; CHECK-LABEL: try_cmpxchg: -; CHECK: cmpxchgl -; CHECK-NOT: cmp -; CHECK: sete %al -; CHECK: retq - %old = cmpxchg i32* %addr, i32 %desired, i32 %new seq_cst seq_cst - %success = icmp eq i32 %old, %desired - ret i1 %success -} - -define void @cmpxchg_flow(i64* %addr, i64 %desired, i64 %new) { -; CHECK-LABEL: cmpxchg_flow: -; CHECK: cmpxchgq -; CHECK-NOT: cmp -; CHECK-NOT: set -; CHECK: {{jne|jeq}} - %old = cmpxchg i64* %addr, i64 %desired, i64 %new seq_cst seq_cst - %success = icmp eq i64 %old, %desired - br i1 %success, label %true, label %false - -true: - call void @foo() - ret void - -false: - call void @bar() - ret void -} - -define i1 @cmpxchg_arithcmp(i16* %addr, i16 %desired, i16 %new) { -; CHECK-LABEL: cmpxchg_arithcmp: -; CHECK: cmpxchgw -; CHECK-NOT: cmp -; CHECK: setbe %al -; CHECK: retq - %old = cmpxchg i16* %addr, i16 %desired, i16 %new seq_cst seq_cst - %success = icmp uge i16 %old, %desired - ret i1 %success -} - -define i1 @cmpxchg_arithcmp_swapped(i8* %addr, i8 %desired, i8 %new) { -; CHECK-LABEL: cmpxchg_arithcmp_swapped: -; CHECK: cmpxchgb -; CHECK-NOT: cmp -; CHECK: setge %al -; CHECK: retq - %old = cmpxchg i8* %addr, i8 %desired, i8 %new seq_cst seq_cst - %success = icmp sge i8 %desired, %old - ret i1 %success -} - -define i64 @cmpxchg_sext(i32* %addr, i32 %desired, i32 %new) { -; CHECK-LABEL: cmpxchg_sext: -; CHECK-DAG: cmpxchgl -; CHECK-DAG: movq $-1, %rax -; CHECK-DAG: xorl %e[[ZERO:[a-z0-9]+]], %e[[ZERO]] -; CHECK-NOT: cmpl -; CHECK: cmovneq %r[[ZERO]], %rax -; CHECK: retq - %old = cmpxchg i32* %addr, i32 %desired, i32 %new seq_cst seq_cst - %success = icmp eq i32 %old, %desired - %mask = sext i1 %success to i64 - ret i64 %mask -} - -define i32 @cmpxchg_zext(i32* %addr, i32 %desired, i32 %new) { -; CHECK-LABEL: cmpxchg_zext: -; CHECK: cmpxchgl -; CHECK-NOT: cmp -; CHECK: sete [[BYTE:%[a-z0-9]+]] -; CHECK: movzbl [[BYTE]], %eax - %old = cmpxchg i32* %addr, i32 %desired, i32 %new seq_cst seq_cst - %success = icmp eq i32 %old, %desired - %mask = zext i1 %success to i32 - ret i32 %mask -} - -declare void @foo() -declare void @bar()