summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatt Arsenault <Matthew.Arsenault@amd.com>2018-08-17 21:19:22 +0000
committerMatt Arsenault <Matthew.Arsenault@amd.com>2018-08-17 21:19:22 +0000
commit25e51540e1c59206b7620973e48a38ac93f15eb4 (patch)
tree4b6f9277e64e59dd1d22b3042c89ab48f7ecdd08
parentd5f56c5979d697f1c9eabf0bdfd882baac55f402 (diff)
downloadbcm5719-llvm-25e51540e1c59206b7620973e48a38ac93f15eb4.tar.gz
bcm5719-llvm-25e51540e1c59206b7620973e48a38ac93f15eb4.zip
DAG: Fix isKnownNeverNaN for basic non-sNaN cases
fadd/fsub/fmul need to worry about infinities as well as fdiv. llvm-svn: 340085
-rw-r--r--llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp19
-rw-r--r--llvm/test/CodeGen/AArch64/known-never-nan.ll50
2 files changed, 57 insertions, 12 deletions
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
index dc167a20253..f93a2af4f3f 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
@@ -3641,11 +3641,15 @@ bool SelectionDAG::isKnownNeverNaN(SDValue Op, bool SNaN, unsigned Depth) const
switch (Opcode) {
case ISD::FADD:
case ISD::FSUB:
- case ISD::FMUL: {
+ case ISD::FMUL:
+ case ISD::FDIV:
+ case ISD::FREM:
+ case ISD::FSIN:
+ case ISD::FCOS: {
if (SNaN)
return true;
- return isKnownNeverNaN(Op.getOperand(0), SNaN, Depth + 1) &&
- isKnownNeverNaN(Op.getOperand(1), SNaN, Depth + 1);
+ // TODO: Need isKnownNeverInfinity
+ return false;
}
case ISD::FCANONICALIZE:
case ISD::FEXP:
@@ -3668,15 +3672,6 @@ bool SelectionDAG::isKnownNeverNaN(SDValue Op, bool SNaN, unsigned Depth) const
case ISD::SELECT:
return isKnownNeverNaN(Op.getOperand(1), SNaN, Depth + 1) &&
isKnownNeverNaN(Op.getOperand(2), SNaN, Depth + 1);
- case ISD::FDIV:
- case ISD::FREM:
- case ISD::FSIN:
- case ISD::FCOS: {
- if (SNaN)
- return true;
- // TODO: Need isKnownNeverInfinity
- return false;
- }
case ISD::FP_EXTEND:
case ISD::FP_ROUND: {
if (SNaN)
diff --git a/llvm/test/CodeGen/AArch64/known-never-nan.ll b/llvm/test/CodeGen/AArch64/known-never-nan.ll
new file mode 100644
index 00000000000..1ffbb9bda44
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/known-never-nan.ll
@@ -0,0 +1,50 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc -mtriple=aarch64 < %s | FileCheck %s
+
+; This should codegen to fmaxnm with no-signed-zeros.
+define float @fmaxnm(i32 %i1, i32 %i2) #0 {
+; CHECK-LABEL: fmaxnm:
+; CHECK: // %bb.0:
+; CHECK-NEXT: ucvtf s0, w0
+; CHECK-NEXT: fmov s1, #11.00000000
+; CHECK-NEXT: ucvtf s2, w1
+; CHECK-NEXT: fmov s3, #17.00000000
+; CHECK-NEXT: fadd s0, s0, s1
+; CHECK-NEXT: fadd s1, s2, s3
+; CHECK-NEXT: fcmp s0, s1
+; CHECK-NEXT: fcsel s0, s0, s1, pl
+; CHECK-NEXT: ret
+ %f1 = uitofp i32 %i1 to float
+ %fadd1 = fadd float %f1, 11.0
+ %f2 = uitofp i32 %i2 to float
+ %fadd2 = fadd float %f2, 17.0
+ %cmp = fcmp uge float %fadd1, %fadd2
+ %val = select i1 %cmp, float %fadd1, float %fadd2
+ ret float %val
+}
+
+; If f1 is 0, fmul is NaN because 0.0 * -INF = NaN
+; Therefore, this is not fmaxnm.
+define float @not_fmaxnm_maybe_nan(i32 %i1, i32 %i2) #0 {
+; CHECK-LABEL: not_fmaxnm_maybe_nan:
+; CHECK: // %bb.0:
+; CHECK-NEXT: adrp x8, .LCPI1_0
+; CHECK-NEXT: ldr s0, [x8, :lo12:.LCPI1_0]
+; CHECK-NEXT: ucvtf s1, w0
+; CHECK-NEXT: ucvtf s2, w1
+; CHECK-NEXT: fmov s3, #17.00000000
+; CHECK-NEXT: fmul s0, s1, s0
+; CHECK-NEXT: fadd s1, s2, s3
+; CHECK-NEXT: fcmp s0, s1
+; CHECK-NEXT: fcsel s0, s0, s1, pl
+; CHECK-NEXT: ret
+ %f1 = uitofp i32 %i1 to float
+ %fmul = fmul float %f1, 0xfff0000000000000 ; -INFINITY as 64-bit hex
+ %f2 = uitofp i32 %i2 to float
+ %fadd2 = fadd float %f2, 17.0
+ %cmp = fcmp uge float %fmul, %fadd2
+ %val = select i1 %cmp, float %fmul, float %fadd2
+ ret float %val
+}
+
+attributes #0 = { "no-signed-zeros-fp-math"="true" }
OpenPOWER on IntegriCloud