summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2007-12-29 08:37:08 +0000
committerChris Lattner <sabre@nondot.org>2007-12-29 08:37:08 +0000
commit63079f0757785c5c461bafdd3101ee40aeb717fe (patch)
tree37d7b2cfa774bb40277cbba69dda31a00ea2d3bd /lib
parent69bfbdfaeebf366b70a1aa3ba650685493da9e8c (diff)
downloadexternal_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.cpp22
-rw-r--r--lib/Target/X86/README.txt17
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;}