diff options
author | Chris Lattner <sabre@nondot.org> | 2007-12-29 08:37:08 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2007-12-29 08:37:08 +0000 |
commit | 63079f0757785c5c461bafdd3101ee40aeb717fe (patch) | |
tree | 37d7b2cfa774bb40277cbba69dda31a00ea2d3bd /lib | |
parent | 69bfbdfaeebf366b70a1aa3ba650685493da9e8c (diff) | |
download | external_llvm-63079f0757785c5c461bafdd3101ee40aeb717fe.zip external_llvm-63079f0757785c5c461bafdd3101ee40aeb717fe.tar.gz external_llvm-63079f0757785c5c461bafdd3101ee40aeb717fe.tar.bz2 |
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
Diffstat (limited to 'lib')
-rw-r--r-- | lib/CodeGen/SelectionDAG/TargetLowering.cpp | 22 | ||||
-rw-r--r-- | lib/Target/X86/README.txt | 17 |
2 files changed, 22 insertions, 17 deletions
diff --git a/lib/CodeGen/SelectionDAG/TargetLowering.cpp b/lib/CodeGen/SelectionDAG/TargetLowering.cpp index eb08bba..ad33273 100644 --- a/lib/CodeGen/SelectionDAG/TargetLowering.cpp +++ b/lib/CodeGen/SelectionDAG/TargetLowering.cpp @@ -1280,6 +1280,28 @@ TargetLowering::SimplifySetCC(MVT::ValueType VT, SDOperand N0, SDOperand N1, // 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) { diff --git a/lib/Target/X86/README.txt b/lib/Target/X86/README.txt index 08b5875..759c7ac 100644 --- a/lib/Target/X86/README.txt +++ b/lib/Target/X86/README.txt @@ -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: unsigned int f(unsigned int i, unsigned int n) {++i; if (i == n) ++i; return i;} |