From 4d46d0af583b95a5d4f7d490f542c4fb65b9e824 Mon Sep 17 00:00:00 2001 From: Evan Cheng Date: Thu, 28 Aug 2008 23:48:31 +0000 Subject: [PATCH] Swap fp comparison operands and change predicate to allow load folding. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@55521 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/X86/X86ISelLowering.cpp | 24 +++++++++++++++++++----- lib/Target/X86/X86InstrInfo.cpp | 27 ++++++++++++++++++++++++++- lib/Target/X86/X86InstrInfo.h | 5 +++++ test/CodeGen/X86/cmp2.ll | 18 ++++++++++++++++++ test/CodeGen/X86/long-setcc.ll | 6 +++--- 5 files changed, 71 insertions(+), 9 deletions(-) create mode 100644 test/CodeGen/X86/cmp2.ll diff --git a/lib/Target/X86/X86ISelLowering.cpp b/lib/Target/X86/X86ISelLowering.cpp index 8f7b668ca0b..26c9cd76a1c 100644 --- a/lib/Target/X86/X86ISelLowering.cpp +++ b/lib/Target/X86/X86ISelLowering.cpp @@ -1909,7 +1909,6 @@ SDValue X86TargetLowering::getReturnAddressFrameIndex(SelectionDAG &DAG) { } - /// translateX86CC - do a one to one translation of a ISD::CondCode to the X86 /// specific condition code. It returns a false if it cannot do a direct /// translation. X86CC is the translated CondCode. LHS/RHS are modified as @@ -1936,7 +1935,10 @@ static bool translateX86CC(ISD::CondCode SetCCOpcode, bool isFP, return true; } } + } + bool Flip = false; + if (!isFP) { switch (SetCCOpcode) { default: break; case ISD::SETEQ: X86CC = X86::COND_E; break; @@ -1957,7 +1959,6 @@ static bool translateX86CC(ISD::CondCode SetCCOpcode, bool isFP, // 0 | 0 | 1 | X < Y // 1 | 0 | 0 | X == Y // 1 | 1 | 1 | unordered - bool Flip = false; switch (SetCCOpcode) { default: break; case ISD::SETUEQ: @@ -1979,11 +1980,24 @@ static bool translateX86CC(ISD::CondCode SetCCOpcode, bool isFP, case ISD::SETUO: X86CC = X86::COND_P; break; case ISD::SETO: X86CC = X86::COND_NP; break; } - if (Flip) - std::swap(LHS, RHS); } - return X86CC != X86::COND_INVALID; + if (X86CC == X86::COND_INVALID) + return false; + + if (Flip) + std::swap(LHS, RHS); + + if (isFP) { + bool LHSCanFold = ISD::isNON_EXTLoad(LHS.getNode()) && LHS.hasOneUse(); + bool RHSCanFold = ISD::isNON_EXTLoad(RHS.getNode()) && RHS.hasOneUse(); + if (LHSCanFold && !RHSCanFold) { + X86CC = X86::GetSwappedBranchCondition(static_cast(X86CC)); + std::swap(LHS, RHS); + } + } + + return true; } /// hasFPCMov - is there a floating point cmov for the specific X86 condition diff --git a/lib/Target/X86/X86InstrInfo.cpp b/lib/Target/X86/X86InstrInfo.cpp index bcbebcd45df..6066e5cf66f 100644 --- a/lib/Target/X86/X86InstrInfo.cpp +++ b/lib/Target/X86/X86InstrInfo.cpp @@ -1433,6 +1433,30 @@ X86::CondCode X86::GetOppositeBranchCondition(X86::CondCode CC) { } } +/// GetSwappedBranchCondition - Return the branch condition that would be +/// the result of exchanging the two operands of a comparison without +/// changing the result produced. +/// e.g. COND_E to COND_E, COND_G -> COND_L +X86::CondCode X86::GetSwappedBranchCondition(X86::CondCode CC) { + switch (CC) { + default: assert(0 && "Illegal condition code!"); + case X86::COND_E: return X86::COND_E; + case X86::COND_NE: return X86::COND_NE; + case X86::COND_L: return X86::COND_G; + case X86::COND_LE: return X86::COND_GE; + case X86::COND_G: return X86::COND_L; + case X86::COND_GE: return X86::COND_LE; + case X86::COND_B: return X86::COND_A; + case X86::COND_BE: return X86::COND_AE; + case X86::COND_A: return X86::COND_B; + case X86::COND_AE: return X86::COND_BE; + case X86::COND_P: return X86::COND_P; + case X86::COND_NP: return X86::COND_NP; + case X86::COND_O: return X86::COND_O; + case X86::COND_NO: return X86::COND_NO; + } +} + bool X86InstrInfo::isUnpredicatedTerminator(const MachineInstr *MI) const { const TargetInstrDesc &TID = MI->getDesc(); if (!TID.isTerminator()) return false; @@ -2373,7 +2397,8 @@ bool X86InstrInfo::BlockHasNoFallThrough(MachineBasicBlock &MBB) const { bool X86InstrInfo:: ReverseBranchCondition(SmallVectorImpl &Cond) const { assert(Cond.size() == 1 && "Invalid X86 branch condition!"); - Cond[0].setImm(GetOppositeBranchCondition((X86::CondCode)Cond[0].getImm())); + X86::CondCode CC = static_cast(Cond[0].getImm()); + Cond[0].setImm(GetOppositeBranchCondition(CC)); return false; } diff --git a/lib/Target/X86/X86InstrInfo.h b/lib/Target/X86/X86InstrInfo.h index 2b089f31189..6d0eebe2b15 100644 --- a/lib/Target/X86/X86InstrInfo.h +++ b/lib/Target/X86/X86InstrInfo.h @@ -54,6 +54,11 @@ namespace X86 { /// e.g. turning COND_E to COND_NE. CondCode GetOppositeBranchCondition(X86::CondCode CC); + /// GetSwappedBranchCondition - Return the branch condition that would be + /// the result of exchanging the two operands of a comparison without + /// changing the result produced. + /// e.g. COND_E to COND_E, COND_G -> COND_L + CondCode GetSwappedBranchCondition(X86::CondCode CC); } /// X86II - This namespace holds all of the target specific flags that diff --git a/test/CodeGen/X86/cmp2.ll b/test/CodeGen/X86/cmp2.ll new file mode 100644 index 00000000000..cc4027eb1b6 --- /dev/null +++ b/test/CodeGen/X86/cmp2.ll @@ -0,0 +1,18 @@ +; RUN: llvm-as < %s | llc -march=x86 -mattr=+sse2 | grep ucomisd | grep CPI | count 2 + +define i32 @test(double %A) nounwind { + entry: + %tmp2 = fcmp ogt double %A, 1.500000e+02; [#uses=1] + %tmp5 = fcmp olt double %A, 7.500000e+01; [#uses=1] + %bothcond = or i1 %tmp2, %tmp5; [#uses=1] + br i1 %bothcond, label %bb8, label %bb12 + + bb8:; preds = %entry + %tmp9 = tail call i32 (...)* @foo( ) nounwind ; [#uses=1] + ret i32 %tmp9 + + bb12:; preds = %entry + ret i32 32 +} + +declare i32 @foo(...) diff --git a/test/CodeGen/X86/long-setcc.ll b/test/CodeGen/X86/long-setcc.ll index 55e7c86891a..8d9ebfb276f 100644 --- a/test/CodeGen/X86/long-setcc.ll +++ b/test/CodeGen/X86/long-setcc.ll @@ -2,17 +2,17 @@ ; RUN: llvm-as < %s | llc -march=x86 | grep shr | count 1 ; RUN: llvm-as < %s | llc -march=x86 | grep xor | count 1 -define i1 @t1(i64 %x) { +define i1 @t1(i64 %x) nounwind { %B = icmp slt i64 %x, 0 ret i1 %B } -define i1 @t2(i64 %x) { +define i1 @t2(i64 %x) nounwind { %tmp = icmp ult i64 %x, 4294967296 ret i1 %tmp } -define i1 @t3(i32 %x) { +define i1 @t3(i32 %x) nounwind { %tmp = icmp ugt i32 %x, -1 ret i1 %tmp }