Fold comparisons against a constant nan, and optimize ORD/UNORD

comparisons with a constant.  This allows us to compile isnan to:

_foo:
	fcmpu cr7, f1, f1
	mfcr r2
	rlwinm r3, r2, 0, 31, 31
	blr 

instead of:

LCPI1_0:					;  float
	.space	4
_foo:
	lis r2, ha16(LCPI1_0)
	lfs f0, lo16(LCPI1_0)(r2)
	fcmpu cr7, f1, f0
	mfcr r2
	rlwinm r3, r2, 0, 31, 31
	blr 



git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@45405 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Chris Lattner 2007-12-29 08:37:08 +00:00
parent 69bfbdfaee
commit 63079f0757
3 changed files with 33 additions and 17 deletions

View File

@ -1280,6 +1280,28 @@ TargetLowering::SimplifySetCC(MVT::ValueType VT, SDOperand N0, SDOperand N1,
// Constant fold or commute setcc. // Constant fold or commute setcc.
SDOperand O = DAG.FoldSetCC(VT, N0, N1, Cond); SDOperand O = DAG.FoldSetCC(VT, N0, N1, Cond);
if (O.Val) return O; if (O.Val) return O;
} else if (ConstantFPSDNode *CFP = dyn_cast<ConstantFPSDNode>(N1.Val)) {
// If the RHS of an FP comparison is a constant, simplify it away in
// some cases.
if (CFP->getValueAPF().isNaN()) {
// If an operand is known to be a nan, we can fold it.
switch (ISD::getUnorderedFlavor(Cond)) {
default: assert(0 && "Unknown flavor!");
case 0: // Known false.
return DAG.getConstant(0, VT);
case 1: // Known true.
return DAG.getConstant(1, VT);
case 2: // undefind.
return DAG.getNode(ISD::UNDEF, VT);
}
}
// Otherwise, we know the RHS is not a NaN. Simplify the node to drop the
// constant if knowing that the operand is non-nan is enough. We prefer to
// have SETO(x,x) instead of SETO(x, 0.0) because this avoids having to
// materialize 0.0.
if (Cond == ISD::SETO || Cond == ISD::SETUO)
return DAG.getSetCC(VT, N0, N0, Cond);
} }
if (N0 == N1) { if (N0 == N1) {

View File

@ -816,23 +816,6 @@ _add_zf:
//===---------------------------------------------------------------------===// //===---------------------------------------------------------------------===//
This:
#include <math.h>
int foo(double X) { return isnan(X); }
compiles to (-m64):
_foo:
pxor %xmm1, %xmm1
ucomisd %xmm1, %xmm0
setp %al
movzbl %al, %eax
ret
the pxor is not needed, we could compare the value against itself.
//===---------------------------------------------------------------------===//
These two functions have identical effects: These two functions have identical effects:
unsigned int f(unsigned int i, unsigned int n) {++i; if (i == n) ++i; return i;} unsigned int f(unsigned int i, unsigned int n) {++i; if (i == n) ++i; return i;}

11
test/CodeGen/X86/isnan.ll Normal file
View File

@ -0,0 +1,11 @@
; RUN: llvm-as < %s | llc -march=x86 -mcpu=yonah | not grep pxor
; This should not need to materialize 0.0 to evaluate the condition.
define i32 @test(double %X) nounwind {
entry:
%tmp6 = fcmp uno double %X, 0.000000e+00 ; <i1> [#uses=1]
%tmp67 = zext i1 %tmp6 to i32 ; <i32> [#uses=1]
ret i32 %tmp67
}