aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEvan Cheng <evan.cheng@apple.com>2008-08-28 23:48:31 +0000
committerEvan Cheng <evan.cheng@apple.com>2008-08-28 23:48:31 +0000
commit4d46d0af583b95a5d4f7d490f542c4fb65b9e824 (patch)
tree0384768491997c341ecb57a52b9e1cf7a299f65b
parent37f25d989a3054b4742f6c92af94a312c26ffb2b (diff)
downloadexternal_llvm-4d46d0af583b95a5d4f7d490f542c4fb65b9e824.tar.gz
external_llvm-4d46d0af583b95a5d4f7d490f542c4fb65b9e824.tar.bz2
external_llvm-4d46d0af583b95a5d4f7d490f542c4fb65b9e824.zip
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
-rw-r--r--lib/Target/X86/X86ISelLowering.cpp22
-rw-r--r--lib/Target/X86/X86InstrInfo.cpp27
-rw-r--r--lib/Target/X86/X86InstrInfo.h5
-rw-r--r--test/CodeGen/X86/cmp2.ll18
-rw-r--r--test/CodeGen/X86/long-setcc.ll6
5 files changed, 70 insertions, 8 deletions
diff --git a/lib/Target/X86/X86ISelLowering.cpp b/lib/Target/X86/X86ISelLowering.cpp
index 8f7b668ca0..26c9cd76a1 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)
+ }
+
+ 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<X86::CondCode>(X86CC));
std::swap(LHS, RHS);
+ }
}
- return X86CC != X86::COND_INVALID;
+ 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 bcbebcd45d..6066e5cf66 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<MachineOperand> &Cond) const {
assert(Cond.size() == 1 && "Invalid X86 branch condition!");
- Cond[0].setImm(GetOppositeBranchCondition((X86::CondCode)Cond[0].getImm()));
+ X86::CondCode CC = static_cast<X86::CondCode>(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 2b089f3118..6d0eebe2b1 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 0000000000..cc4027eb1b
--- /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; <i1> [#uses=1]
+ %tmp5 = fcmp olt double %A, 7.500000e+01; <i1> [#uses=1]
+ %bothcond = or i1 %tmp2, %tmp5; <i1> [#uses=1]
+ br i1 %bothcond, label %bb8, label %bb12
+
+ bb8:; preds = %entry
+ %tmp9 = tail call i32 (...)* @foo( ) nounwind ; <i32> [#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 55e7c86891..8d9ebfb276 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
}