[llvm-commits] [llvm] r45405 - in /llvm/trunk: lib/CodeGen/SelectionDAG/TargetLowering.cpp lib/Target/X86/README.txt test/CodeGen/X86/isnan.ll
Chris Lattner
sabre at nondot.org
Sat Dec 29 00:37:08 PST 2007
Author: lattner
Date: Sat Dec 29 02:37:08 2007
New Revision: 45405
URL: http://llvm.org/viewvc/llvm-project?rev=45405&view=rev
Log:
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
Added:
llvm/trunk/test/CodeGen/X86/isnan.ll
Modified:
llvm/trunk/lib/CodeGen/SelectionDAG/TargetLowering.cpp
llvm/trunk/lib/Target/X86/README.txt
Modified: llvm/trunk/lib/CodeGen/SelectionDAG/TargetLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/TargetLowering.cpp?rev=45405&r1=45404&r2=45405&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/TargetLowering.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/TargetLowering.cpp Sat Dec 29 02:37:08 2007
@@ -1280,6 +1280,28 @@
// Constant fold or commute setcc.
SDOperand O = DAG.FoldSetCC(VT, N0, N1, Cond);
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) {
Modified: llvm/trunk/lib/Target/X86/README.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/README.txt?rev=45405&r1=45404&r2=45405&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/README.txt (original)
+++ llvm/trunk/lib/Target/X86/README.txt Sat Dec 29 02:37:08 2007
@@ -816,23 +816,6 @@
//===---------------------------------------------------------------------===//
-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:
unsigned int f(unsigned int i, unsigned int n) {++i; if (i == n) ++i; return i;}
Added: llvm/trunk/test/CodeGen/X86/isnan.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/isnan.ll?rev=45405&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/X86/isnan.ll (added)
+++ llvm/trunk/test/CodeGen/X86/isnan.ll Sat Dec 29 02:37:08 2007
@@ -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
+}
+
More information about the llvm-commits
mailing list