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 +} + _______________________________________________ llvm-commits mailing list llvm-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits