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
This commit is contained in:
Evan Cheng 2008-08-28 23:48:31 +00:00
parent 37f25d989a
commit 4d46d0af58
5 changed files with 71 additions and 9 deletions

View File

@ -1909,7 +1909,6 @@ SDValue X86TargetLowering::getReturnAddressFrameIndex(SelectionDAG &DAG) {
} }
/// translateX86CC - do a one to one translation of a ISD::CondCode to the X86 /// 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 /// specific condition code. It returns a false if it cannot do a direct
/// translation. X86CC is the translated CondCode. LHS/RHS are modified as /// 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; return true;
} }
} }
}
bool Flip = false;
if (!isFP) {
switch (SetCCOpcode) { switch (SetCCOpcode) {
default: break; default: break;
case ISD::SETEQ: X86CC = X86::COND_E; 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 // 0 | 0 | 1 | X < Y
// 1 | 0 | 0 | X == Y // 1 | 0 | 0 | X == Y
// 1 | 1 | 1 | unordered // 1 | 1 | 1 | unordered
bool Flip = false;
switch (SetCCOpcode) { switch (SetCCOpcode) {
default: break; default: break;
case ISD::SETUEQ: 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::SETUO: X86CC = X86::COND_P; break;
case ISD::SETO: X86CC = X86::COND_NP; 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<X86::CondCode>(X86CC));
std::swap(LHS, RHS);
}
}
return true;
} }
/// hasFPCMov - is there a floating point cmov for the specific X86 condition /// hasFPCMov - is there a floating point cmov for the specific X86 condition

View File

@ -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 { bool X86InstrInfo::isUnpredicatedTerminator(const MachineInstr *MI) const {
const TargetInstrDesc &TID = MI->getDesc(); const TargetInstrDesc &TID = MI->getDesc();
if (!TID.isTerminator()) return false; if (!TID.isTerminator()) return false;
@ -2373,7 +2397,8 @@ bool X86InstrInfo::BlockHasNoFallThrough(MachineBasicBlock &MBB) const {
bool X86InstrInfo:: bool X86InstrInfo::
ReverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const { ReverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const {
assert(Cond.size() == 1 && "Invalid X86 branch condition!"); 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; return false;
} }

View File

@ -54,6 +54,11 @@ namespace X86 {
/// e.g. turning COND_E to COND_NE. /// e.g. turning COND_E to COND_NE.
CondCode GetOppositeBranchCondition(X86::CondCode CC); 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 /// X86II - This namespace holds all of the target specific flags that

18
test/CodeGen/X86/cmp2.ll Normal file
View File

@ -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(...)

View File

@ -2,17 +2,17 @@
; RUN: llvm-as < %s | llc -march=x86 | grep shr | count 1 ; RUN: llvm-as < %s | llc -march=x86 | grep shr | count 1
; RUN: llvm-as < %s | llc -march=x86 | grep xor | 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 %B = icmp slt i64 %x, 0
ret i1 %B ret i1 %B
} }
define i1 @t2(i64 %x) { define i1 @t2(i64 %x) nounwind {
%tmp = icmp ult i64 %x, 4294967296 %tmp = icmp ult i64 %x, 4294967296
ret i1 %tmp ret i1 %tmp
} }
define i1 @t3(i32 %x) { define i1 @t3(i32 %x) nounwind {
%tmp = icmp ugt i32 %x, -1 %tmp = icmp ugt i32 %x, -1
ret i1 %tmp ret i1 %tmp
} }