diff options
author | Matt Arsenault <Matthew.Arsenault@amd.com> | 2018-08-17 21:19:22 +0000 |
---|---|---|
committer | Matt Arsenault <Matthew.Arsenault@amd.com> | 2018-08-17 21:19:22 +0000 |
commit | 25e51540e1c59206b7620973e48a38ac93f15eb4 (patch) | |
tree | 4b6f9277e64e59dd1d22b3042c89ab48f7ecdd08 | |
parent | d5f56c5979d697f1c9eabf0bdfd882baac55f402 (diff) | |
download | bcm5719-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.cpp | 19 | ||||
-rw-r--r-- | llvm/test/CodeGen/AArch64/known-never-nan.ll | 50 |
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" } |