mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-02-07 14:33:15 +00:00
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:
parent
69bfbdfaee
commit
63079f0757
@ -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) {
|
||||||
|
@ -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
11
test/CodeGen/X86/isnan.ll
Normal 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
|
||||||
|
}
|
||||||
|
|
Loading…
x
Reference in New Issue
Block a user