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.
|
||||
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) {
|
||||
|
@ -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;}
|
||||
|
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