[llvm] [KnownFPClass] Propagate non-`sNaN` for `fadd`/`fsub`, `fmul`, `fdiv`, and `fma` (PR #221876)
Eric Ross via llvm-commits
llvm-commits at lists.llvm.org
Fri Sep 11 12:56:41 PDT 2026
https://github.com/ZERICO2005 updated https://github.com/llvm/llvm-project/pull/221876
>From c4f38f2fb533f6da9c6e287a8f5efc9acec0e21d Mon Sep 17 00:00:00 2001
From: zerico <zerico2005 at gmail.com>
Date: Mon, 7 Sep 2026 22:32:20 -0600
Subject: [PATCH] [KnownFPClass] Propagate non-sNaN for fadd/fsub, fmul, fdiv,
and fma
---
llvm/lib/Support/KnownFPClass.cpp | 21 ++-
.../AMDGPU/nofpclass-amdgcn-trig-preop.ll | 4 +-
.../Attributor/nofpclass-fadd-fsub.ll | 148 ++++++++++++++-
.../Transforms/Attributor/nofpclass-fdiv.ll | 62 +++++--
.../Transforms/Attributor/nofpclass-fma.ll | 174 ++++++++++++++++--
.../Transforms/Attributor/nofpclass-fmul.ll | 48 ++++-
.../Attributor/nofpclass-nan-fmul.ll | 24 +--
llvm/unittests/Analysis/ValueTrackingTest.cpp | 14 +-
8 files changed, 437 insertions(+), 58 deletions(-)
diff --git a/llvm/lib/Support/KnownFPClass.cpp b/llvm/lib/Support/KnownFPClass.cpp
index 75636ffc73361..e544980742fbc 100644
--- a/llvm/lib/Support/KnownFPClass.cpp
+++ b/llvm/lib/Support/KnownFPClass.cpp
@@ -377,6 +377,8 @@ KnownFPClass KnownFPClass::fadd(const KnownFPClass &KnownLHS,
Mode.Output == DenormalMode::PositiveZero))
Known.knownNot(fcNegZero);
+ Known.propagateNonSNaN(KnownLHS, KnownRHS);
+
return Known;
}
@@ -407,6 +409,8 @@ KnownFPClass KnownFPClass::fmul(const KnownFPClass &KnownLHS,
DenormalMode Mode) {
KnownFPClass Known;
+ Known.propagateNonSNaN(KnownLHS, KnownRHS);
+
// +X * +Y or -X * -Y => +Q
// +X * -Y or -X * +Y => -Q
Known.propagateXorSign(KnownLHS, KnownRHS);
@@ -468,6 +472,8 @@ KnownFPClass KnownFPClass::fdiv(const KnownFPClass &KnownLHS,
DenormalMode Mode) {
KnownFPClass Known;
+ Known.propagateNonSNaN(KnownLHS, KnownRHS);
+
// Only 0/0, Inf/Inf produce NaN.
if (KnownLHS.isKnownNeverNaN() && KnownRHS.isKnownNeverNaN() &&
(KnownLHS.isKnownNeverInfinity() || KnownRHS.isKnownNeverInfinity()) &&
@@ -509,10 +515,10 @@ KnownFPClass KnownFPClass::fdiv_self(const KnownFPClass &KnownSrc,
// X / X is always exactly 1.0 or a NaN.
KnownFPClass Known(fcNan | fcPosNormal);
+ Known.propagateNonSNaN(KnownSrc);
+
if (KnownSrc.isKnownNeverInfOrNaN() && KnownSrc.isKnownNeverLogicalZero(Mode))
Known.knownNot(fcNan);
- else if (KnownSrc.isKnownNever(fcSNan))
- Known.knownNot(fcSNan);
return Known;
}
@@ -570,7 +576,14 @@ KnownFPClass KnownFPClass::fma(const KnownFPClass &KnownLHS,
//
// If the multiply is a -0 due to rounding, the final -0 + 0 will be -0,
// unlike for a separate fadd.
- return fadd_impl(Mul, KnownAddend, Mode);
+ KnownFPClass Known = fadd_impl(Mul, KnownAddend, Mode);
+
+ // propagateNonSNaN for 3 arguments.
+ if (KnownLHS.isKnownNever(fcSNan) && KnownRHS.isKnownNever(fcSNan) &&
+ KnownAddend.isKnownNever(fcSNan))
+ Known.knownNot(fcSNan);
+
+ return Known;
}
KnownFPClass KnownFPClass::fma_square(const KnownFPClass &KnownSquared,
@@ -588,6 +601,8 @@ KnownFPClass KnownFPClass::fma_square(const KnownFPClass &KnownSquared,
if (KnownAddend.isKnownNever(fcNegInf | fcNan) && Squared.isKnownNever(fcNan))
Known.knownNot(fcNan);
+ Known.propagateNonSNaN(KnownSquared, KnownAddend);
+
return Known;
}
diff --git a/llvm/test/Transforms/Attributor/AMDGPU/nofpclass-amdgcn-trig-preop.ll b/llvm/test/Transforms/Attributor/AMDGPU/nofpclass-amdgcn-trig-preop.ll
index 292dc05756d2f..6ee4548cb635c 100644
--- a/llvm/test/Transforms/Attributor/AMDGPU/nofpclass-amdgcn-trig-preop.ll
+++ b/llvm/test/Transforms/Attributor/AMDGPU/nofpclass-amdgcn-trig-preop.ll
@@ -36,7 +36,7 @@ define double @ret_trig_preop__fmul__not_inf(double nofpclass(inf) %not.inf, dou
}
define double @ret_not_nan__fmul__trig_preop(double nofpclass(nan) %not.nan, double %x, i32 %n) {
-; CHECK-LABEL: define double @ret_not_nan__fmul__trig_preop(
+; CHECK-LABEL: define nofpclass(snan) double @ret_not_nan__fmul__trig_preop(
; CHECK-SAME: double nofpclass(nan) [[NOT_NAN:%.*]], double [[X:%.*]], i32 [[N:%.*]]) #[[ATTR0]] {
; CHECK-NEXT: [[TRIG_PREOP:%.*]] = call double @llvm.amdgcn.trig.preop.f64(double [[X]], i32 [[N]]) #[[ATTR2]]
; CHECK-NEXT: [[MUL:%.*]] = fmul double [[NOT_NAN]], [[TRIG_PREOP]]
@@ -48,7 +48,7 @@ define double @ret_not_nan__fmul__trig_preop(double nofpclass(nan) %not.nan, dou
}
define double @ret_trig_preop__fmul__not_nan(double nofpclass(nan) %not.nan, double %x, i32 %n) {
-; CHECK-LABEL: define double @ret_trig_preop__fmul__not_nan(
+; CHECK-LABEL: define nofpclass(snan) double @ret_trig_preop__fmul__not_nan(
; CHECK-SAME: double nofpclass(nan) [[NOT_NAN:%.*]], double [[X:%.*]], i32 [[N:%.*]]) #[[ATTR0]] {
; CHECK-NEXT: [[TRIG_PREOP:%.*]] = call double @llvm.amdgcn.trig.preop.f64(double [[X]], i32 [[N]]) #[[ATTR2]]
; CHECK-NEXT: [[MUL:%.*]] = fmul double [[TRIG_PREOP]], [[NOT_NAN]]
diff --git a/llvm/test/Transforms/Attributor/nofpclass-fadd-fsub.ll b/llvm/test/Transforms/Attributor/nofpclass-fadd-fsub.ll
index 7c4823fe24740..05a4da5e5878d 100644
--- a/llvm/test/Transforms/Attributor/nofpclass-fadd-fsub.ll
+++ b/llvm/test/Transforms/Attributor/nofpclass-fadd-fsub.ll
@@ -1,9 +1,149 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6
; RUN: opt -S -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal < %s | FileCheck %s
+define float @fadd_no_nan(float nofpclass(nan) %arg0, float nofpclass(nan) %arg1) {
+; CHECK-LABEL: define nofpclass(snan) float @fadd_no_nan(
+; CHECK-SAME: float nofpclass(nan) [[ARG0:%.*]], float nofpclass(nan) [[ARG1:%.*]]) #[[ATTR0:[0-9]+]] {
+; CHECK-NEXT: [[ADD:%.*]] = fadd float [[ARG0]], [[ARG1]]
+; CHECK-NEXT: ret float [[ADD]]
+;
+ %add = fadd float %arg0, %arg1
+ ret float %add
+}
+
+define float @fadd_no_snan(float nofpclass(snan) %arg0, float nofpclass(snan) %arg1) {
+; CHECK-LABEL: define nofpclass(snan) float @fadd_no_snan(
+; CHECK-SAME: float nofpclass(snan) [[ARG0:%.*]], float nofpclass(snan) [[ARG1:%.*]]) #[[ATTR0]] {
+; CHECK-NEXT: [[ADD:%.*]] = fadd float [[ARG0]], [[ARG1]]
+; CHECK-NEXT: ret float [[ADD]]
+;
+ %add = fadd float %arg0, %arg1
+ ret float %add
+}
+
+define float @fadd_lhs_no_snan(float nofpclass(snan) %arg0, float %arg1) {
+; CHECK-LABEL: define float @fadd_lhs_no_snan(
+; CHECK-SAME: float nofpclass(snan) [[ARG0:%.*]], float [[ARG1:%.*]]) #[[ATTR0]] {
+; CHECK-NEXT: [[ADD:%.*]] = fadd float [[ARG0]], [[ARG1]]
+; CHECK-NEXT: ret float [[ADD]]
+;
+ %add = fadd float %arg0, %arg1
+ ret float %add
+}
+
+define float @fadd_rhs_no_snan(float %arg0, float nofpclass(snan) %arg1) {
+; CHECK-LABEL: define float @fadd_rhs_no_snan(
+; CHECK-SAME: float [[ARG0:%.*]], float nofpclass(snan) [[ARG1:%.*]]) #[[ATTR0]] {
+; CHECK-NEXT: [[ADD:%.*]] = fadd float [[ARG0]], [[ARG1]]
+; CHECK-NEXT: ret float [[ADD]]
+;
+ %add = fadd float %arg0, %arg1
+ ret float %add
+}
+
+define float @fadd_self_no_nan(float noundef nofpclass(nan) %arg0) {
+; CHECK-LABEL: define noundef nofpclass(snan) float @fadd_self_no_nan(
+; CHECK-SAME: float noundef nofpclass(nan) [[ARG0:%.*]]) #[[ATTR0]] {
+; CHECK-NEXT: [[ADD:%.*]] = fadd float [[ARG0]], [[ARG0]]
+; CHECK-NEXT: ret float [[ADD]]
+;
+ %add = fadd float %arg0, %arg0
+ ret float %add
+}
+
+define float @fadd_self_no_snan(float noundef nofpclass(snan) %arg0) {
+; CHECK-LABEL: define noundef nofpclass(snan) float @fadd_self_no_snan(
+; CHECK-SAME: float noundef nofpclass(snan) [[ARG0:%.*]]) #[[ATTR0]] {
+; CHECK-NEXT: [[ADD:%.*]] = fadd float [[ARG0]], [[ARG0]]
+; CHECK-NEXT: ret float [[ADD]]
+;
+ %add = fadd float %arg0, %arg0
+ ret float %add
+}
+
+define float @fadd_self_no_qnan(float noundef nofpclass(qnan) %arg0) {
+; CHECK-LABEL: define noundef float @fadd_self_no_qnan(
+; CHECK-SAME: float noundef nofpclass(qnan) [[ARG0:%.*]]) #[[ATTR0]] {
+; CHECK-NEXT: [[ADD:%.*]] = fadd float [[ARG0]], [[ARG0]]
+; CHECK-NEXT: ret float [[ADD]]
+;
+ %add = fadd float %arg0, %arg0
+ ret float %add
+}
+
+define float @fsub_no_nan(float nofpclass(nan) %arg0, float nofpclass(nan) %arg1) {
+; CHECK-LABEL: define nofpclass(snan) float @fsub_no_nan(
+; CHECK-SAME: float nofpclass(nan) [[ARG0:%.*]], float nofpclass(nan) [[ARG1:%.*]]) #[[ATTR0]] {
+; CHECK-NEXT: [[SUB:%.*]] = fsub float [[ARG0]], [[ARG1]]
+; CHECK-NEXT: ret float [[SUB]]
+;
+ %sub = fsub float %arg0, %arg1
+ ret float %sub
+}
+
+define float @fsub_no_snan(float nofpclass(snan) %arg0, float nofpclass(snan) %arg1) {
+; CHECK-LABEL: define nofpclass(snan) float @fsub_no_snan(
+; CHECK-SAME: float nofpclass(snan) [[ARG0:%.*]], float nofpclass(snan) [[ARG1:%.*]]) #[[ATTR0]] {
+; CHECK-NEXT: [[SUB:%.*]] = fsub float [[ARG0]], [[ARG1]]
+; CHECK-NEXT: ret float [[SUB]]
+;
+ %sub = fsub float %arg0, %arg1
+ ret float %sub
+}
+
+define float @fsub_lhs_no_snan(float nofpclass(snan) %arg0, float %arg1) {
+; CHECK-LABEL: define float @fsub_lhs_no_snan(
+; CHECK-SAME: float nofpclass(snan) [[ARG0:%.*]], float [[ARG1:%.*]]) #[[ATTR0]] {
+; CHECK-NEXT: [[SUB:%.*]] = fsub float [[ARG0]], [[ARG1]]
+; CHECK-NEXT: ret float [[SUB]]
+;
+ %sub = fsub float %arg0, %arg1
+ ret float %sub
+}
+
+define float @fsub_rhs_no_snan(float %arg0, float nofpclass(snan) %arg1) {
+; CHECK-LABEL: define float @fsub_rhs_no_snan(
+; CHECK-SAME: float [[ARG0:%.*]], float nofpclass(snan) [[ARG1:%.*]]) #[[ATTR0]] {
+; CHECK-NEXT: [[SUB:%.*]] = fsub float [[ARG0]], [[ARG1]]
+; CHECK-NEXT: ret float [[SUB]]
+;
+ %sub = fsub float %arg0, %arg1
+ ret float %sub
+}
+
+define float @fsub_self_no_nan(float noundef nofpclass(nan) %arg0) {
+; CHECK-LABEL: define noundef nofpclass(snan) float @fsub_self_no_nan(
+; CHECK-SAME: float noundef nofpclass(nan) [[ARG0:%.*]]) #[[ATTR0]] {
+; CHECK-NEXT: [[SUB:%.*]] = fsub float [[ARG0]], [[ARG0]]
+; CHECK-NEXT: ret float [[SUB]]
+;
+ %sub = fsub float %arg0, %arg0
+ ret float %sub
+}
+
+define float @fsub_self_no_snan(float noundef nofpclass(snan) %arg0) {
+; CHECK-LABEL: define noundef nofpclass(snan) float @fsub_self_no_snan(
+; CHECK-SAME: float noundef nofpclass(snan) [[ARG0:%.*]]) #[[ATTR0]] {
+; CHECK-NEXT: [[SUB:%.*]] = fsub float [[ARG0]], [[ARG0]]
+; CHECK-NEXT: ret float [[SUB]]
+;
+ %sub = fsub float %arg0, %arg0
+ ret float %sub
+}
+
+define float @fsub_self_no_qnan(float noundef nofpclass(qnan) %arg0) {
+; CHECK-LABEL: define noundef float @fsub_self_no_qnan(
+; CHECK-SAME: float noundef nofpclass(qnan) [[ARG0:%.*]]) #[[ATTR0]] {
+; CHECK-NEXT: [[SUB:%.*]] = fsub float [[ARG0]], [[ARG0]]
+; CHECK-NEXT: ret float [[SUB]]
+;
+ %sub = fsub float %arg0, %arg0
+ ret float %sub
+}
+
define float @fadd_p0(float %arg0) {
; CHECK-LABEL: define nofpclass(nzero) float @fadd_p0(
-; CHECK-SAME: float [[ARG0:%.*]]) #[[ATTR0:[0-9]+]] {
+; CHECK-SAME: float [[ARG0:%.*]]) #[[ATTR0]] {
; CHECK-NEXT: [[ADD:%.*]] = fadd float [[ARG0]], 0.000000e+00
; CHECK-NEXT: ret float [[ADD]]
;
@@ -362,7 +502,7 @@ define float @test_fadd_no_nan_from_no_pinf(float nofpclass(nan pinf) %arg0, flo
}
define float @test_fadd_may_nan_from_no_pinf_no_ninf(float nofpclass(nan pinf) %arg0, float nofpclass(nan ninf) %arg1) {
-; CHECK-LABEL: define float @test_fadd_may_nan_from_no_pinf_no_ninf(
+; CHECK-LABEL: define nofpclass(snan) float @test_fadd_may_nan_from_no_pinf_no_ninf(
; CHECK-SAME: float nofpclass(nan pinf) [[ARG0:%.*]], float nofpclass(nan ninf) [[ARG1:%.*]]) #[[ATTR0]] {
; CHECK-NEXT: [[ADD:%.*]] = fadd float [[ARG0]], [[ARG1]]
; CHECK-NEXT: ret float [[ADD]]
@@ -372,7 +512,7 @@ define float @test_fadd_may_nan_from_no_pinf_no_ninf(float nofpclass(nan pinf) %
}
define float @test_fadd_may_nan_from_no_ninf_no_pinf(float nofpclass(nan ninf) %arg0, float nofpclass(nan pinf) %arg1) {
-; CHECK-LABEL: define float @test_fadd_may_nan_from_no_ninf_no_pinf(
+; CHECK-LABEL: define nofpclass(snan) float @test_fadd_may_nan_from_no_ninf_no_pinf(
; CHECK-SAME: float nofpclass(nan ninf) [[ARG0:%.*]], float nofpclass(nan pinf) [[ARG1:%.*]]) #[[ATTR0]] {
; CHECK-NEXT: [[ADD:%.*]] = fadd float [[ARG0]], [[ARG1]]
; CHECK-NEXT: ret float [[ADD]]
@@ -494,7 +634,7 @@ define float @fadd_double(float noundef %arg) {
}
define float @fadd_double_nnan(float noundef nofpclass(nan) %arg) {
-; CHECK-LABEL: define noundef float @fadd_double_nnan(
+; CHECK-LABEL: define noundef nofpclass(snan) float @fadd_double_nnan(
; CHECK-SAME: float noundef nofpclass(nan) [[ARG:%.*]]) #[[ATTR0]] {
; CHECK-NEXT: [[ADD:%.*]] = fadd float [[ARG]], [[ARG]]
; CHECK-NEXT: ret float [[ADD]]
diff --git a/llvm/test/Transforms/Attributor/nofpclass-fdiv.ll b/llvm/test/Transforms/Attributor/nofpclass-fdiv.ll
index f49b13d7b3f78..f2d2a5ddd86ed 100644
--- a/llvm/test/Transforms/Attributor/nofpclass-fdiv.ll
+++ b/llvm/test/Transforms/Attributor/nofpclass-fdiv.ll
@@ -92,7 +92,7 @@ define float @ret_fdiv_ieee_nonan_noinf__nonan_nozero(float nofpclass(nan inf) %
}
define float @ret_fdiv_daz_nonan_nozero__nonan_noinf(float nofpclass(nan zero) %arg0, float nofpclass(nan inf) %arg1) #1 {
-; CHECK-LABEL: define float @ret_fdiv_daz_nonan_nozero__nonan_noinf
+; CHECK-LABEL: define nofpclass(snan) float @ret_fdiv_daz_nonan_nozero__nonan_noinf
; CHECK-SAME: (float nofpclass(nan zero) [[ARG0:%.*]], float nofpclass(nan inf) [[ARG1:%.*]]) #[[ATTR1]] {
; CHECK-NEXT: [[FDIV:%.*]] = fdiv float [[ARG0]], [[ARG1]]
; CHECK-NEXT: ret float [[FDIV]]
@@ -102,7 +102,7 @@ define float @ret_fdiv_daz_nonan_nozero__nonan_noinf(float nofpclass(nan zero) %
}
define float @ret_fdiv_daz_nonan_noinf__nonan_nozero(float nofpclass(nan inf) %arg0, float nofpclass(nan zero) %arg1) #1 {
-; CHECK-LABEL: define float @ret_fdiv_daz_nonan_noinf__nonan_nozero
+; CHECK-LABEL: define nofpclass(snan) float @ret_fdiv_daz_nonan_noinf__nonan_nozero
; CHECK-SAME: (float nofpclass(nan inf) [[ARG0:%.*]], float nofpclass(nan zero) [[ARG1:%.*]]) #[[ATTR1]] {
; CHECK-NEXT: [[FDIV:%.*]] = fdiv float [[ARG0]], [[ARG1]]
; CHECK-NEXT: ret float [[FDIV]]
@@ -132,7 +132,7 @@ define float @ret_fdiv_daz_nonan_noinf__nonan_nozero_nosub(float nofpclass(nan i
}
define float @ret_fdiv_ieee_nonan_noinf__nonan_noinf(float nofpclass(nan) %arg0, float nofpclass(nan) %arg1) #0 {
-; CHECK-LABEL: define float @ret_fdiv_ieee_nonan_noinf__nonan_noinf
+; CHECK-LABEL: define nofpclass(snan) float @ret_fdiv_ieee_nonan_noinf__nonan_noinf
; CHECK-SAME: (float nofpclass(nan) [[ARG0:%.*]], float nofpclass(nan) [[ARG1:%.*]]) #[[ATTR0]] {
; CHECK-NEXT: [[FDIV:%.*]] = fdiv float [[ARG0]], [[ARG1]]
; CHECK-NEXT: ret float [[FDIV]]
@@ -152,7 +152,7 @@ define float @ret_fdiv_ieee_nonan_noinf_nozero__nonan_noinf_nozero(float nofpcla
}
define float @ret_fdiv_daz_nonan_noinf_nozero__nonan_noinf_nozero(float nofpclass(nan inf zero) %arg0, float nofpclass(nan inf zero) %arg1) #1 {
-; CHECK-LABEL: define float @ret_fdiv_daz_nonan_noinf_nozero__nonan_noinf_nozero
+; CHECK-LABEL: define nofpclass(snan) float @ret_fdiv_daz_nonan_noinf_nozero__nonan_noinf_nozero
; CHECK-SAME: (float nofpclass(nan inf zero) [[ARG0:%.*]], float nofpclass(nan inf zero) [[ARG1:%.*]]) #[[ATTR1]] {
; CHECK-NEXT: [[FDIV:%.*]] = fdiv float [[ARG0]], [[ARG1]]
; CHECK-NEXT: ret float [[FDIV]]
@@ -162,7 +162,7 @@ define float @ret_fdiv_daz_nonan_noinf_nozero__nonan_noinf_nozero(float nofpclas
}
define float @ret_fdiv_dapz_nonan_noinf_nozero__nonan_noinf_nozero(float nofpclass(nan inf zero) %arg0, float nofpclass(nan inf zero) %arg1) #2 {
-; CHECK-LABEL: define float @ret_fdiv_dapz_nonan_noinf_nozero__nonan_noinf_nozero
+; CHECK-LABEL: define nofpclass(snan) float @ret_fdiv_dapz_nonan_noinf_nozero__nonan_noinf_nozero
; CHECK-SAME: (float nofpclass(nan inf zero) [[ARG0:%.*]], float nofpclass(nan inf zero) [[ARG1:%.*]]) #[[ATTR2:[0-9]+]] {
; CHECK-NEXT: [[FDIV:%.*]] = fdiv float [[ARG0]], [[ARG1]]
; CHECK-NEXT: ret float [[FDIV]]
@@ -172,7 +172,7 @@ define float @ret_fdiv_dapz_nonan_noinf_nozero__nonan_noinf_nozero(float nofpcla
}
define float @ret_fdiv_dynamic_nonan_noinf_nozero__nonan_noinf_nozero(float nofpclass(nan inf zero) %arg0, float nofpclass(nan inf zero) %arg1) #3 {
-; CHECK-LABEL: define float @ret_fdiv_dynamic_nonan_noinf_nozero__nonan_noinf_nozero
+; CHECK-LABEL: define nofpclass(snan) float @ret_fdiv_dynamic_nonan_noinf_nozero__nonan_noinf_nozero
; CHECK-SAME: (float nofpclass(nan inf zero) [[ARG0:%.*]], float nofpclass(nan inf zero) [[ARG1:%.*]]) #[[ATTR3:[0-9]+]] {
; CHECK-NEXT: [[FDIV:%.*]] = fdiv float [[ARG0]], [[ARG1]]
; CHECK-NEXT: ret float [[FDIV]]
@@ -182,7 +182,7 @@ define float @ret_fdiv_dynamic_nonan_noinf_nozero__nonan_noinf_nozero(float nofp
}
define float @ret_fdiv_ieee_nonan_noinf_noinf__nonan_noinf_noinf(float nofpclass(nan inf) %arg0, float nofpclass(nan inf) %arg1) #0 {
-; CHECK-LABEL: define float @ret_fdiv_ieee_nonan_noinf_noinf__nonan_noinf_noinf
+; CHECK-LABEL: define nofpclass(snan) float @ret_fdiv_ieee_nonan_noinf_noinf__nonan_noinf_noinf
; CHECK-SAME: (float nofpclass(nan inf) [[ARG0:%.*]], float nofpclass(nan inf) [[ARG1:%.*]]) #[[ATTR0]] {
; CHECK-NEXT: [[FDIV:%.*]] = fdiv float [[ARG0]], [[ARG1]]
; CHECK-NEXT: ret float [[FDIV]]
@@ -212,7 +212,7 @@ define float @ret_fdiv_ieee_nonan_noinf_noinf__nonan_noinf_nozero(float nofpclas
}
define float @ret_fdiv_ieee_nonan_noinf_noinf__nonan_noinf_noposzero(float nofpclass(nan inf) %arg0, float nofpclass(nan pzero) %arg1) #0 {
-; CHECK-LABEL: define float @ret_fdiv_ieee_nonan_noinf_noinf__nonan_noinf_noposzero
+; CHECK-LABEL: define nofpclass(snan) float @ret_fdiv_ieee_nonan_noinf_noinf__nonan_noinf_noposzero
; CHECK-SAME: (float nofpclass(nan inf) [[ARG0:%.*]], float nofpclass(nan pzero) [[ARG1:%.*]]) #[[ATTR0]] {
; CHECK-NEXT: [[FDIV:%.*]] = fdiv float [[ARG0]], [[ARG1]]
; CHECK-NEXT: ret float [[FDIV]]
@@ -222,7 +222,7 @@ define float @ret_fdiv_ieee_nonan_noinf_noinf__nonan_noinf_noposzero(float nofpc
}
define float @ret_fdiv_ieee_nonan_noinf_noposzero__nonan_noinf_noinf(float nofpclass(nan pzero) %arg0, float nofpclass(nan inf) %arg1) #0 {
-; CHECK-LABEL: define float @ret_fdiv_ieee_nonan_noinf_noposzero__nonan_noinf_noinf
+; CHECK-LABEL: define nofpclass(snan) float @ret_fdiv_ieee_nonan_noinf_noposzero__nonan_noinf_noinf
; CHECK-SAME: (float nofpclass(nan pzero) [[ARG0:%.*]], float nofpclass(nan inf) [[ARG1:%.*]]) #[[ATTR0]] {
; CHECK-NEXT: [[FDIV:%.*]] = fdiv float [[ARG0]], [[ARG1]]
; CHECK-NEXT: ret float [[FDIV]]
@@ -962,7 +962,7 @@ define float @ret_fdiv_rhs_negative_lhs_positive(float %lhs, float %rhs) {
; Could be inf of either sign
define float @ret_known_inf_fdiv_known_inf(float nofpclass(norm sub zero nan) %arg0, float nofpclass(norm sub zero nan) %arg1) {
-; CHECK-LABEL: define nofpclass(sub norm) float @ret_known_inf_fdiv_known_inf
+; CHECK-LABEL: define nofpclass(snan sub norm) float @ret_known_inf_fdiv_known_inf
; CHECK-SAME: (float nofpclass(nan zero sub norm) [[ARG0:%.*]], float nofpclass(nan zero sub norm) [[ARG1:%.*]]) #[[ATTR4]] {
; CHECK-NEXT: [[FDIV:%.*]] = fdiv float [[ARG0]], [[ARG1]]
; CHECK-NEXT: ret float [[FDIV]]
@@ -995,7 +995,7 @@ define float @ret_known_inf_or_nan_fdiv_known_inf(float nofpclass(norm sub zero)
; Could be zero of either sign
define float @ret_known_zero_fdiv_known_zero(float nofpclass(inf norm sub nan) %arg0, float nofpclass(inf norm sub nan) %arg1) {
-; CHECK-LABEL: define nofpclass(inf zero sub norm) float @ret_known_zero_fdiv_known_zero
+; CHECK-LABEL: define nofpclass(snan inf zero sub norm) float @ret_known_zero_fdiv_known_zero
; CHECK-SAME: (float nofpclass(nan inf sub norm) [[ARG0:%.*]], float nofpclass(nan inf sub norm) [[ARG1:%.*]]) #[[ATTR4]] {
; CHECK-NEXT: [[FDIV:%.*]] = fdiv float [[ARG0]], [[ARG1]]
; CHECK-NEXT: ret float [[FDIV]]
@@ -1056,6 +1056,46 @@ define float @ret_known_inf_or_nan_fdiv_known_inf_or_nan(float nofpclass(norm su
ret float %fdiv
}
+define float @fdiv_no_nan(float nofpclass(nan) %arg0, float nofpclass(nan) %arg1) {
+; CHECK-LABEL: define nofpclass(snan) float @fdiv_no_nan
+; CHECK-SAME: (float nofpclass(nan) [[ARG0:%.*]], float nofpclass(nan) [[ARG1:%.*]]) #[[ATTR4]] {
+; CHECK-NEXT: [[FDIV:%.*]] = fdiv float [[ARG0]], [[ARG1]]
+; CHECK-NEXT: ret float [[FDIV]]
+;
+ %fdiv = fdiv float %arg0, %arg1
+ ret float %fdiv
+}
+
+define float @fdiv_no_snan(float nofpclass(snan) %arg0, float nofpclass(snan) %arg1) {
+; CHECK-LABEL: define float @fdiv_no_snan
+; CHECK-SAME: (float nofpclass(snan) [[ARG0:%.*]], float nofpclass(snan) [[ARG1:%.*]]) #[[ATTR4]] {
+; CHECK-NEXT: [[FDIV:%.*]] = fdiv float [[ARG0]], [[ARG1]]
+; CHECK-NEXT: ret float [[FDIV]]
+;
+ %fdiv = fdiv float %arg0, %arg1
+ ret float %fdiv
+}
+
+define float @fdiv_lhs_no_snan(float nofpclass(snan) %arg0, float %arg1) {
+; CHECK-LABEL: define float @fdiv_lhs_no_snan
+; CHECK-SAME: (float nofpclass(snan) [[ARG0:%.*]], float [[ARG1:%.*]]) #[[ATTR4]] {
+; CHECK-NEXT: [[FDIV:%.*]] = fdiv float [[ARG0]], [[ARG1]]
+; CHECK-NEXT: ret float [[FDIV]]
+;
+ %fdiv = fdiv float %arg0, %arg1
+ ret float %fdiv
+}
+
+define float @fdiv_rhs_no_snan(float %arg0, float nofpclass(snan) %arg1) {
+; CHECK-LABEL: define float @fdiv_rhs_no_snan
+; CHECK-SAME: (float [[ARG0:%.*]], float nofpclass(snan) [[ARG1:%.*]]) #[[ATTR4]] {
+; CHECK-NEXT: [[FDIV:%.*]] = fdiv float [[ARG0]], [[ARG1]]
+; CHECK-NEXT: ret float [[FDIV]]
+;
+ %fdiv = fdiv float %arg0, %arg1
+ ret float %fdiv
+}
+
attributes #0 = { denormal_fpenv(ieee|ieee) }
attributes #1 = { denormal_fpenv(ieee|preservesign) }
attributes #2 = { denormal_fpenv(ieee|positivezero) }
diff --git a/llvm/test/Transforms/Attributor/nofpclass-fma.ll b/llvm/test/Transforms/Attributor/nofpclass-fma.ll
index 0284b97181177..de20233afc7e2 100644
--- a/llvm/test/Transforms/Attributor/nofpclass-fma.ll
+++ b/llvm/test/Transforms/Attributor/nofpclass-fma.ll
@@ -325,9 +325,9 @@ define half @ret_fmuladd__pos01_pos01__pos2() {
; all no-nan inputs does not imply no-nan output
define half @ret_fma__no_nan__no_nan__no_nan(half nofpclass(nan) %arg0, half nofpclass(nan) %arg1, half nofpclass(nan) %arg2) {
-; CHECK-LABEL: define half @ret_fma__no_nan__no_nan__no_nan
+; CHECK-LABEL: define nofpclass(snan) half @ret_fma__no_nan__no_nan__no_nan
; CHECK-SAME: (half nofpclass(nan) [[ARG0:%.*]], half nofpclass(nan) [[ARG1:%.*]], half nofpclass(nan) [[ARG2:%.*]]) #[[ATTR1]] {
-; CHECK-NEXT: [[RESULT:%.*]] = call half @llvm.fma.f16(half nofpclass(nan) [[ARG0]], half nofpclass(nan) [[ARG1]], half nofpclass(nan) [[ARG2]]) #[[ATTR2]]
+; CHECK-NEXT: [[RESULT:%.*]] = call nofpclass(snan) half @llvm.fma.f16(half nofpclass(nan) [[ARG0]], half nofpclass(nan) [[ARG1]], half nofpclass(nan) [[ARG2]]) #[[ATTR2]]
; CHECK-NEXT: ret half [[RESULT]]
;
%result = call half @llvm.fma.f16(half %arg0, half %arg1, half %arg2)
@@ -335,9 +335,9 @@ define half @ret_fma__no_nan__no_nan__no_nan(half nofpclass(nan) %arg0, half nof
}
define half @ret_fma__no_nan__no_nan__no_nan_zero(half nofpclass(nan) %arg0, half nofpclass(nan) %arg1, half nofpclass(nan zero) %arg2) {
-; CHECK-LABEL: define half @ret_fma__no_nan__no_nan__no_nan_zero
+; CHECK-LABEL: define nofpclass(snan) half @ret_fma__no_nan__no_nan__no_nan_zero
; CHECK-SAME: (half nofpclass(nan) [[ARG0:%.*]], half nofpclass(nan) [[ARG1:%.*]], half nofpclass(nan zero) [[ARG2:%.*]]) #[[ATTR1]] {
-; CHECK-NEXT: [[RESULT:%.*]] = call half @llvm.fma.f16(half nofpclass(nan) [[ARG0]], half nofpclass(nan) [[ARG1]], half nofpclass(nan zero) [[ARG2]]) #[[ATTR2]]
+; CHECK-NEXT: [[RESULT:%.*]] = call nofpclass(snan) half @llvm.fma.f16(half nofpclass(nan) [[ARG0]], half nofpclass(nan) [[ARG1]], half nofpclass(nan zero) [[ARG2]]) #[[ATTR2]]
; CHECK-NEXT: ret half [[RESULT]]
;
%result = call half @llvm.fma.f16(half %arg0, half %arg1, half %arg2)
@@ -345,9 +345,9 @@ define half @ret_fma__no_nan__no_nan__no_nan_zero(half nofpclass(nan) %arg0, hal
}
define half @ret_fma__no_nan__no_nan__no_nan_inf(half nofpclass(nan) %arg0, half nofpclass(nan) %arg1, half nofpclass(nan zero inf) %arg2) {
-; CHECK-LABEL: define half @ret_fma__no_nan__no_nan__no_nan_inf
+; CHECK-LABEL: define nofpclass(snan) half @ret_fma__no_nan__no_nan__no_nan_inf
; CHECK-SAME: (half nofpclass(nan) [[ARG0:%.*]], half nofpclass(nan) [[ARG1:%.*]], half nofpclass(nan inf zero) [[ARG2:%.*]]) #[[ATTR1]] {
-; CHECK-NEXT: [[RESULT:%.*]] = call half @llvm.fma.f16(half nofpclass(nan) [[ARG0]], half nofpclass(nan) [[ARG1]], half nofpclass(nan inf zero) [[ARG2]]) #[[ATTR2]]
+; CHECK-NEXT: [[RESULT:%.*]] = call nofpclass(snan) half @llvm.fma.f16(half nofpclass(nan) [[ARG0]], half nofpclass(nan) [[ARG1]], half nofpclass(nan inf zero) [[ARG2]]) #[[ATTR2]]
; CHECK-NEXT: ret half [[RESULT]]
;
%result = call half @llvm.fma.f16(half %arg0, half %arg1, half %arg2)
@@ -388,9 +388,9 @@ define half @ret_fma__no_nan_ninf_zero__no_nan_ninf_zero__no_nan_inf(half nofpcl
; Cannot infer nnan output
define half @ret_fma_square__no_nan__no_nan(half noundef nofpclass(nan) %arg0, half nofpclass(nan) %arg1) {
-; CHECK-LABEL: define half @ret_fma_square__no_nan__no_nan
+; CHECK-LABEL: define nofpclass(snan) half @ret_fma_square__no_nan__no_nan
; CHECK-SAME: (half noundef nofpclass(nan) [[ARG0:%.*]], half nofpclass(nan) [[ARG1:%.*]]) #[[ATTR1]] {
-; CHECK-NEXT: [[CALL:%.*]] = call half @llvm.fma.f16(half noundef nofpclass(nan) [[ARG0]], half noundef nofpclass(nan) [[ARG0]], half nofpclass(nan) [[ARG1]]) #[[ATTR2]]
+; CHECK-NEXT: [[CALL:%.*]] = call nofpclass(snan) half @llvm.fma.f16(half noundef nofpclass(nan) [[ARG0]], half noundef nofpclass(nan) [[ARG0]], half nofpclass(nan) [[ARG1]]) #[[ATTR2]]
; CHECK-NEXT: ret half [[CALL]]
;
%call = call half @llvm.fma.f16(half %arg0, half %arg0, half %arg1)
@@ -398,9 +398,9 @@ define half @ret_fma_square__no_nan__no_nan(half noundef nofpclass(nan) %arg0, h
}
define half @ret_fma_square__no_nan__no_nan_zero(half noundef nofpclass(nan) %arg0, half nofpclass(nan zero) %arg1) {
-; CHECK-LABEL: define half @ret_fma_square__no_nan__no_nan_zero
+; CHECK-LABEL: define nofpclass(snan) half @ret_fma_square__no_nan__no_nan_zero
; CHECK-SAME: (half noundef nofpclass(nan) [[ARG0:%.*]], half nofpclass(nan zero) [[ARG1:%.*]]) #[[ATTR1]] {
-; CHECK-NEXT: [[CALL:%.*]] = call half @llvm.fma.f16(half noundef nofpclass(nan) [[ARG0]], half noundef nofpclass(nan) [[ARG0]], half nofpclass(nan zero) [[ARG1]]) #[[ATTR2]]
+; CHECK-NEXT: [[CALL:%.*]] = call nofpclass(snan) half @llvm.fma.f16(half noundef nofpclass(nan) [[ARG0]], half noundef nofpclass(nan) [[ARG0]], half nofpclass(nan zero) [[ARG1]]) #[[ATTR2]]
; CHECK-NEXT: ret half [[CALL]]
;
%call = call half @llvm.fma.f16(half %arg0, half %arg0, half %arg1)
@@ -458,9 +458,9 @@ define half @ret_fma_square__no_nan_no_inf__no_nan_no_inf(half noundef nofpclass
}
define half @ret_fma_square__no_nan_no_inf__no_nan_no_pinf(half noundef nofpclass(nan inf) %arg0, half nofpclass(nan pinf) %arg1) {
-; CHECK-LABEL: define half @ret_fma_square__no_nan_no_inf__no_nan_no_pinf
+; CHECK-LABEL: define nofpclass(snan) half @ret_fma_square__no_nan_no_inf__no_nan_no_pinf
; CHECK-SAME: (half noundef nofpclass(nan inf) [[ARG0:%.*]], half nofpclass(nan pinf) [[ARG1:%.*]]) #[[ATTR1]] {
-; CHECK-NEXT: [[CALL:%.*]] = call half @llvm.fma.f16(half noundef nofpclass(nan inf) [[ARG0]], half noundef nofpclass(nan inf) [[ARG0]], half nofpclass(nan pinf) [[ARG1]]) #[[ATTR2]]
+; CHECK-NEXT: [[CALL:%.*]] = call nofpclass(snan) half @llvm.fma.f16(half noundef nofpclass(nan inf) [[ARG0]], half noundef nofpclass(nan inf) [[ARG0]], half nofpclass(nan pinf) [[ARG1]]) #[[ATTR2]]
; CHECK-NEXT: ret half [[CALL]]
;
%call = call half @llvm.fma.f16(half %arg0, half %arg0, half %arg1)
@@ -498,9 +498,9 @@ define half @ret_fma_ninf_square__no_nan__no_nan(half noundef nofpclass(nan) %ar
}
define nofpclass(inf) half @ret_noinf_fma_square__no_nan__no_nan(half noundef nofpclass(nan) %arg0, half nofpclass(nan) %arg1) {
-; CHECK-LABEL: define nofpclass(inf) half @ret_noinf_fma_square__no_nan__no_nan
+; CHECK-LABEL: define nofpclass(snan inf) half @ret_noinf_fma_square__no_nan__no_nan
; CHECK-SAME: (half noundef nofpclass(nan) [[ARG0:%.*]], half nofpclass(nan) [[ARG1:%.*]]) #[[ATTR1]] {
-; CHECK-NEXT: [[CALL:%.*]] = call half @llvm.fma.f16(half noundef nofpclass(nan) [[ARG0]], half noundef nofpclass(nan) [[ARG0]], half nofpclass(nan) [[ARG1]]) #[[ATTR2]]
+; CHECK-NEXT: [[CALL:%.*]] = call nofpclass(snan) half @llvm.fma.f16(half noundef nofpclass(nan) [[ARG0]], half noundef nofpclass(nan) [[ARG0]], half nofpclass(nan) [[ARG1]]) #[[ATTR2]]
; CHECK-NEXT: ret half [[CALL]]
;
%call = call half @llvm.fma.f16(half %arg0, half %arg0, half %arg1)
@@ -510,7 +510,7 @@ define nofpclass(inf) half @ret_noinf_fma_square__no_nan__no_nan(half noundef no
define nofpclass(nan) half @ret_nonan_fma_square__no_nan__no_nan(half noundef nofpclass(nan) %arg0, half nofpclass(nan) %arg1) {
; CHECK-LABEL: define nofpclass(nan) half @ret_nonan_fma_square__no_nan__no_nan
; CHECK-SAME: (half noundef nofpclass(nan) [[ARG0:%.*]], half nofpclass(nan) [[ARG1:%.*]]) #[[ATTR1]] {
-; CHECK-NEXT: [[CALL:%.*]] = call half @llvm.fma.f16(half noundef nofpclass(nan) [[ARG0]], half noundef nofpclass(nan) [[ARG0]], half nofpclass(nan) [[ARG1]]) #[[ATTR2]]
+; CHECK-NEXT: [[CALL:%.*]] = call nofpclass(snan) half @llvm.fma.f16(half noundef nofpclass(nan) [[ARG0]], half noundef nofpclass(nan) [[ARG0]], half nofpclass(nan) [[ARG1]]) #[[ATTR2]]
; CHECK-NEXT: ret half [[CALL]]
;
%call = call half @llvm.fma.f16(half %arg0, half %arg0, half %arg1)
@@ -527,5 +527,149 @@ define half @ret_fma_ninf__no_nan_inputs(half nofpclass(nan) %arg0, half nofpcla
ret half %call
}
+;---------------------------------------------------------------------
+; Rule out sNaN if and only if all arguments are not sNaN.
+;---------------------------------------------------------------------
+
+define float @ret_fma__any__any__any(float %arg0, float %arg1, float %arg2) {
+; CHECK-LABEL: define float @ret_fma__any__any__any
+; CHECK-SAME: (float [[ARG0:%.*]], float [[ARG1:%.*]], float [[ARG2:%.*]]) #[[ATTR1]] {
+; CHECK-NEXT: [[CALL:%.*]] = call float @llvm.fma.f32(float [[ARG0]], float [[ARG1]], float [[ARG2]]) #[[ATTR2]]
+; CHECK-NEXT: ret float [[CALL]]
+;
+ %call = call float @llvm.fma.f32(float %arg0, float %arg1, float %arg2)
+ ret float %call
+}
+
+define float @ret_fma__any__any__no_snan(float %arg0, float %arg1, float nofpclass(snan) %arg2) {
+; CHECK-LABEL: define float @ret_fma__any__any__no_snan
+; CHECK-SAME: (float [[ARG0:%.*]], float [[ARG1:%.*]], float nofpclass(snan) [[ARG2:%.*]]) #[[ATTR1]] {
+; CHECK-NEXT: [[CALL:%.*]] = call float @llvm.fma.f32(float [[ARG0]], float [[ARG1]], float nofpclass(snan) [[ARG2]]) #[[ATTR2]]
+; CHECK-NEXT: ret float [[CALL]]
+;
+ %call = call float @llvm.fma.f32(float %arg0, float %arg1, float %arg2)
+ ret float %call
+}
+
+define float @ret_fma__any__no_snan__any(float %arg0, float nofpclass(snan) %arg1, float %arg2) {
+; CHECK-LABEL: define float @ret_fma__any__no_snan__any
+; CHECK-SAME: (float [[ARG0:%.*]], float nofpclass(snan) [[ARG1:%.*]], float [[ARG2:%.*]]) #[[ATTR1]] {
+; CHECK-NEXT: [[CALL:%.*]] = call float @llvm.fma.f32(float [[ARG0]], float nofpclass(snan) [[ARG1]], float [[ARG2]]) #[[ATTR2]]
+; CHECK-NEXT: ret float [[CALL]]
+;
+ %call = call float @llvm.fma.f32(float %arg0, float %arg1, float %arg2)
+ ret float %call
+}
+
+define float @ret_fma__any__no_snan__no_snan(float %arg0, float nofpclass(snan) %arg1, float nofpclass(snan) %arg2) {
+; CHECK-LABEL: define float @ret_fma__any__no_snan__no_snan
+; CHECK-SAME: (float [[ARG0:%.*]], float nofpclass(snan) [[ARG1:%.*]], float nofpclass(snan) [[ARG2:%.*]]) #[[ATTR1]] {
+; CHECK-NEXT: [[CALL:%.*]] = call float @llvm.fma.f32(float [[ARG0]], float nofpclass(snan) [[ARG1]], float nofpclass(snan) [[ARG2]]) #[[ATTR2]]
+; CHECK-NEXT: ret float [[CALL]]
+;
+ %call = call float @llvm.fma.f32(float %arg0, float %arg1, float %arg2)
+ ret float %call
+}
+
+define float @ret_fma__no_snan__any__any(float nofpclass(snan) %arg0, float %arg1, float %arg2) {
+; CHECK-LABEL: define float @ret_fma__no_snan__any__any
+; CHECK-SAME: (float nofpclass(snan) [[ARG0:%.*]], float [[ARG1:%.*]], float [[ARG2:%.*]]) #[[ATTR1]] {
+; CHECK-NEXT: [[CALL:%.*]] = call float @llvm.fma.f32(float nofpclass(snan) [[ARG0]], float [[ARG1]], float [[ARG2]]) #[[ATTR2]]
+; CHECK-NEXT: ret float [[CALL]]
+;
+ %call = call float @llvm.fma.f32(float %arg0, float %arg1, float %arg2)
+ ret float %call
+}
+
+define float @ret_fma__no_snan__any__no_snan(float nofpclass(snan) %arg0, float %arg1, float nofpclass(snan) %arg2) {
+; CHECK-LABEL: define float @ret_fma__no_snan__any__no_snan
+; CHECK-SAME: (float nofpclass(snan) [[ARG0:%.*]], float [[ARG1:%.*]], float nofpclass(snan) [[ARG2:%.*]]) #[[ATTR1]] {
+; CHECK-NEXT: [[CALL:%.*]] = call float @llvm.fma.f32(float nofpclass(snan) [[ARG0]], float [[ARG1]], float nofpclass(snan) [[ARG2]]) #[[ATTR2]]
+; CHECK-NEXT: ret float [[CALL]]
+;
+ %call = call float @llvm.fma.f32(float %arg0, float %arg1, float %arg2)
+ ret float %call
+}
+
+define float @ret_fma__no_snan__no_snan__any(float nofpclass(snan) %arg0, float nofpclass(snan) %arg1, float %arg2) {
+; CHECK-LABEL: define float @ret_fma__no_snan__no_snan__any
+; CHECK-SAME: (float nofpclass(snan) [[ARG0:%.*]], float nofpclass(snan) [[ARG1:%.*]], float [[ARG2:%.*]]) #[[ATTR1]] {
+; CHECK-NEXT: [[CALL:%.*]] = call float @llvm.fma.f32(float nofpclass(snan) [[ARG0]], float nofpclass(snan) [[ARG1]], float [[ARG2]]) #[[ATTR2]]
+; CHECK-NEXT: ret float [[CALL]]
+;
+ %call = call float @llvm.fma.f32(float %arg0, float %arg1, float %arg2)
+ ret float %call
+}
+
+define float @ret_fma__no_snan__no_snan__no_snan(float nofpclass(snan) %arg0, float nofpclass(snan) %arg1, float nofpclass(snan) %arg2) {
+; CHECK-LABEL: define nofpclass(snan) float @ret_fma__no_snan__no_snan__no_snan
+; CHECK-SAME: (float nofpclass(snan) [[ARG0:%.*]], float nofpclass(snan) [[ARG1:%.*]], float nofpclass(snan) [[ARG2:%.*]]) #[[ATTR1]] {
+; CHECK-NEXT: [[CALL:%.*]] = call nofpclass(snan) float @llvm.fma.f32(float nofpclass(snan) [[ARG0]], float nofpclass(snan) [[ARG1]], float nofpclass(snan) [[ARG2]]) #[[ATTR2]]
+; CHECK-NEXT: ret float [[CALL]]
+;
+ %call = call float @llvm.fma.f32(float %arg0, float %arg1, float %arg2)
+ ret float %call
+}
+
+define float @ret_fma_square__any__any(float noundef %arg0, float %arg1) {
+; CHECK-LABEL: define float @ret_fma_square__any__any
+; CHECK-SAME: (float noundef [[ARG0:%.*]], float [[ARG1:%.*]]) #[[ATTR1]] {
+; CHECK-NEXT: [[CALL:%.*]] = call float @llvm.fma.f32(float noundef [[ARG0]], float noundef [[ARG0]], float [[ARG1]]) #[[ATTR2]]
+; CHECK-NEXT: ret float [[CALL]]
+;
+ %call = call float @llvm.fma.f32(float %arg0, float %arg0, float %arg1)
+ ret float %call
+}
+
+define float @ret_fma_square__any__no_snan(float noundef %arg0, float nofpclass(snan) %arg1) {
+; CHECK-LABEL: define float @ret_fma_square__any__no_snan
+; CHECK-SAME: (float noundef [[ARG0:%.*]], float nofpclass(snan) [[ARG1:%.*]]) #[[ATTR1]] {
+; CHECK-NEXT: [[CALL:%.*]] = call float @llvm.fma.f32(float noundef [[ARG0]], float noundef [[ARG0]], float nofpclass(snan) [[ARG1]]) #[[ATTR2]]
+; CHECK-NEXT: ret float [[CALL]]
+;
+ %call = call float @llvm.fma.f32(float %arg0, float %arg0, float %arg1)
+ ret float %call
+}
+
+define float @ret_fma_square__no_snan__any(float noundef nofpclass(snan) %arg0, float %arg1) {
+; CHECK-LABEL: define float @ret_fma_square__no_snan__any
+; CHECK-SAME: (float noundef nofpclass(snan) [[ARG0:%.*]], float [[ARG1:%.*]]) #[[ATTR1]] {
+; CHECK-NEXT: [[CALL:%.*]] = call float @llvm.fma.f32(float noundef nofpclass(snan) [[ARG0]], float noundef nofpclass(snan) [[ARG0]], float [[ARG1]]) #[[ATTR2]]
+; CHECK-NEXT: ret float [[CALL]]
+;
+ %call = call float @llvm.fma.f32(float %arg0, float %arg0, float %arg1)
+ ret float %call
+}
+
+define float @ret_fma_square__no_snan__no_snan(float noundef nofpclass(snan) %arg0, float nofpclass(snan) %arg1) {
+; CHECK-LABEL: define nofpclass(snan) float @ret_fma_square__no_snan__no_snan
+; CHECK-SAME: (float noundef nofpclass(snan) [[ARG0:%.*]], float nofpclass(snan) [[ARG1:%.*]]) #[[ATTR1]] {
+; CHECK-NEXT: [[CALL:%.*]] = call nofpclass(snan) float @llvm.fma.f32(float noundef nofpclass(snan) [[ARG0]], float noundef nofpclass(snan) [[ARG0]], float nofpclass(snan) [[ARG1]]) #[[ATTR2]]
+; CHECK-NEXT: ret float [[CALL]]
+;
+ %call = call float @llvm.fma.f32(float %arg0, float %arg0, float %arg1)
+ ret float %call
+}
+
+define float @ret_fma_same_arg__any(float noundef %arg0) {
+; CHECK-LABEL: define noundef float @ret_fma_same_arg__any
+; CHECK-SAME: (float noundef [[ARG0:%.*]]) #[[ATTR1]] {
+; CHECK-NEXT: [[CALL:%.*]] = call noundef float @llvm.fma.f32(float noundef [[ARG0]], float noundef [[ARG0]], float noundef [[ARG0]]) #[[ATTR2]]
+; CHECK-NEXT: ret float [[CALL]]
+;
+ %call = call float @llvm.fma.f32(float %arg0, float %arg0, float %arg0)
+ ret float %call
+}
+
+define float @ret_fma_same_arg__no_snan(float noundef nofpclass(snan) %arg0) {
+; CHECK-LABEL: define noundef nofpclass(snan) float @ret_fma_same_arg__no_snan
+; CHECK-SAME: (float noundef nofpclass(snan) [[ARG0:%.*]]) #[[ATTR1]] {
+; CHECK-NEXT: [[CALL:%.*]] = call noundef nofpclass(snan) float @llvm.fma.f32(float noundef nofpclass(snan) [[ARG0]], float noundef nofpclass(snan) [[ARG0]], float noundef nofpclass(snan) [[ARG0]]) #[[ATTR2]]
+; CHECK-NEXT: ret float [[CALL]]
+;
+ %call = call float @llvm.fma.f32(float %arg0, float %arg0, float %arg0)
+ ret float %call
+}
+
;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line:
; TUNIT: {{.*}}
diff --git a/llvm/test/Transforms/Attributor/nofpclass-fmul.ll b/llvm/test/Transforms/Attributor/nofpclass-fmul.ll
index aa7b7a7a8395e..2adc39385a988 100644
--- a/llvm/test/Transforms/Attributor/nofpclass-fmul.ll
+++ b/llvm/test/Transforms/Attributor/nofpclass-fmul.ll
@@ -44,6 +44,46 @@ define float @ret_mul_exponent_f32_22(float %arg0) {
ret float %call
}
+define float @fmul_no_nan(float nofpclass(nan) %arg0, float nofpclass(nan) %arg1) {
+; CHECK-LABEL: define nofpclass(snan) float @fmul_no_nan(
+; CHECK-SAME: float nofpclass(nan) [[ARG0:%.*]], float nofpclass(nan) [[ARG1:%.*]]) #[[ATTR0]] {
+; CHECK-NEXT: [[MUL:%.*]] = fmul float [[ARG0]], [[ARG1]]
+; CHECK-NEXT: ret float [[MUL]]
+;
+ %fmul = fmul float %arg0, %arg1
+ ret float %fmul
+}
+
+define float @fmul_no_snan(float nofpclass(snan) %arg0, float nofpclass(snan) %arg1) {
+; CHECK-LABEL: define nofpclass(snan) float @fmul_no_snan(
+; CHECK-SAME: float nofpclass(snan) [[ARG0:%.*]], float nofpclass(snan) [[ARG1:%.*]]) #[[ATTR0]] {
+; CHECK-NEXT: [[MUL:%.*]] = fmul float [[ARG0]], [[ARG1]]
+; CHECK-NEXT: ret float [[MUL]]
+;
+ %fmul = fmul float %arg0, %arg1
+ ret float %fmul
+}
+
+define float @fmul_lhs_no_snan(float nofpclass(snan) %arg0, float %arg1) {
+; CHECK-LABEL: define float @fmul_lhs_no_snan(
+; CHECK-SAME: float nofpclass(snan) [[ARG0:%.*]], float [[ARG1:%.*]]) #[[ATTR0]] {
+; CHECK-NEXT: [[MUL:%.*]] = fmul float [[ARG0]], [[ARG1]]
+; CHECK-NEXT: ret float [[MUL]]
+;
+ %fmul = fmul float %arg0, %arg1
+ ret float %fmul
+}
+
+define float @fmul_rhs_no_snan(float %arg0, float nofpclass(snan) %arg1) {
+; CHECK-LABEL: define float @fmul_rhs_no_snan(
+; CHECK-SAME: float [[ARG0:%.*]], float nofpclass(snan) [[ARG1:%.*]]) #[[ATTR0]] {
+; CHECK-NEXT: [[MUL:%.*]] = fmul float [[ARG0]], [[ARG1]]
+; CHECK-NEXT: ret float [[MUL]]
+;
+ %fmul = fmul float %arg0, %arg1
+ ret float %fmul
+}
+
define float @ret_fmul_square_f32_src_no_nan(float noundef nofpclass(nan) %arg) {
; CHECK-LABEL: define noundef nofpclass(nan ninf nzero nsub nnorm) float @ret_fmul_square_f32_src_no_nan(
; CHECK-SAME: float noundef nofpclass(nan) [[ARG:%.*]]) #[[ATTR0]] {
@@ -528,7 +568,7 @@ define float @ret_fmul_f32_known_ninf_or_nan_rhs(float %arg0, float nofpclass(pi
; -> nan
define float @ret_known_inf_mul_known_zero(float nofpclass(nan norm sub zero) %arg0, float nofpclass(nan inf norm sub) %arg1) {
-; CHECK-LABEL: define nofpclass(inf zero sub norm) float @ret_known_inf_mul_known_zero(
+; CHECK-LABEL: define nofpclass(snan inf zero sub norm) float @ret_known_inf_mul_known_zero(
; CHECK-SAME: float nofpclass(nan zero sub norm) [[ARG0:%.*]], float nofpclass(nan inf sub norm) [[ARG1:%.*]]) #[[ATTR0]] {
; CHECK-NEXT: [[FMUL:%.*]] = fmul float [[ARG0]], [[ARG1]]
; CHECK-NEXT: ret float [[FMUL]]
@@ -561,7 +601,7 @@ define float @ret_known_inf_mul_known_zero_or_nan(float nofpclass(nan norm sub z
; -> nan
define float @ret_known_ninf_mul_known_zero(float nofpclass(nan pinf norm sub zero) %arg0, float nofpclass(nan inf norm sub) %arg1) {
-; CHECK-LABEL: define nofpclass(inf zero sub norm) float @ret_known_ninf_mul_known_zero(
+; CHECK-LABEL: define nofpclass(snan inf zero sub norm) float @ret_known_ninf_mul_known_zero(
; CHECK-SAME: float nofpclass(nan pinf zero sub norm) [[ARG0:%.*]], float nofpclass(nan inf sub norm) [[ARG1:%.*]]) #[[ATTR0]] {
; CHECK-NEXT: [[FMUL:%.*]] = fmul float [[ARG0]], [[ARG1]]
; CHECK-NEXT: ret float [[FMUL]]
@@ -572,7 +612,7 @@ define float @ret_known_ninf_mul_known_zero(float nofpclass(nan pinf norm sub ze
; -> nan
define float @ret_known_pinf_mul_known_zero(float nofpclass(nan ninf norm sub zero) %arg0, float nofpclass(nan inf norm sub) %arg1) {
-; CHECK-LABEL: define nofpclass(inf zero sub norm) float @ret_known_pinf_mul_known_zero(
+; CHECK-LABEL: define nofpclass(snan inf zero sub norm) float @ret_known_pinf_mul_known_zero(
; CHECK-SAME: float nofpclass(nan ninf zero sub norm) [[ARG0:%.*]], float nofpclass(nan inf sub norm) [[ARG1:%.*]]) #[[ATTR0]] {
; CHECK-NEXT: [[FMUL:%.*]] = fmul float [[ARG0]], [[ARG1]]
; CHECK-NEXT: ret float [[FMUL]]
@@ -583,7 +623,7 @@ define float @ret_known_pinf_mul_known_zero(float nofpclass(nan ninf norm sub ze
; -> nan
define float @ret_known_zero_mul_known_inf(float nofpclass(nan inf norm sub) %arg0, float nofpclass(nan norm sub zero) %arg1) {
-; CHECK-LABEL: define nofpclass(inf zero sub norm) float @ret_known_zero_mul_known_inf(
+; CHECK-LABEL: define nofpclass(snan inf zero sub norm) float @ret_known_zero_mul_known_inf(
; CHECK-SAME: float nofpclass(nan inf sub norm) [[ARG0:%.*]], float nofpclass(nan zero sub norm) [[ARG1:%.*]]) #[[ATTR0]] {
; CHECK-NEXT: [[FMUL:%.*]] = fmul float [[ARG0]], [[ARG1]]
; CHECK-NEXT: ret float [[FMUL]]
diff --git a/llvm/test/Transforms/Attributor/nofpclass-nan-fmul.ll b/llvm/test/Transforms/Attributor/nofpclass-nan-fmul.ll
index f67ced498a29f..61eeac03f42ac 100644
--- a/llvm/test/Transforms/Attributor/nofpclass-nan-fmul.ll
+++ b/llvm/test/Transforms/Attributor/nofpclass-nan-fmul.ll
@@ -2,7 +2,7 @@
; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -S < %s | FileCheck %s --check-prefixes=CHECK,TUNIT
define float @ret_fmul_ieee_nonan__nonan(float nofpclass(nan) %arg0, float nofpclass(nan) %arg1) #0 {
-; CHECK-LABEL: define float @ret_fmul_ieee_nonan__nonan
+; CHECK-LABEL: define nofpclass(snan) float @ret_fmul_ieee_nonan__nonan
; CHECK-SAME: (float nofpclass(nan) [[ARG0:%.*]], float nofpclass(nan) [[ARG1:%.*]]) #[[ATTR0:[0-9]+]] {
; CHECK-NEXT: [[FMUL:%.*]] = fmul float [[ARG0]], [[ARG1]]
; CHECK-NEXT: ret float [[FMUL]]
@@ -22,7 +22,7 @@ define float @ret_fmul_ieee_nonan_nozero__nonan_nozero(float nofpclass(nan zero)
}
define float @ret_fmul_daz_nonan_nozero__nonan_nozero(float nofpclass(nan zero) %arg0, float nofpclass(nan zero) %arg1) #1 {
-; CHECK-LABEL: define float @ret_fmul_daz_nonan_nozero__nonan_nozero
+; CHECK-LABEL: define nofpclass(snan) float @ret_fmul_daz_nonan_nozero__nonan_nozero
; CHECK-SAME: (float nofpclass(nan zero) [[ARG0:%.*]], float nofpclass(nan zero) [[ARG1:%.*]]) #[[ATTR1:[0-9]+]] {
; CHECK-NEXT: [[FMUL:%.*]] = fmul float [[ARG0]], [[ARG1]]
; CHECK-NEXT: ret float [[FMUL]]
@@ -32,7 +32,7 @@ define float @ret_fmul_daz_nonan_nozero__nonan_nozero(float nofpclass(nan zero)
}
define float @ret_fmul_dapz_nonan_nozero__nonan_nozero(float nofpclass(nan zero) %arg0, float nofpclass(nan zero) %arg1) #2 {
-; CHECK-LABEL: define float @ret_fmul_dapz_nonan_nozero__nonan_nozero
+; CHECK-LABEL: define nofpclass(snan) float @ret_fmul_dapz_nonan_nozero__nonan_nozero
; CHECK-SAME: (float nofpclass(nan zero) [[ARG0:%.*]], float nofpclass(nan zero) [[ARG1:%.*]]) #[[ATTR2:[0-9]+]] {
; CHECK-NEXT: [[FMUL:%.*]] = fmul float [[ARG0]], [[ARG1]]
; CHECK-NEXT: ret float [[FMUL]]
@@ -42,7 +42,7 @@ define float @ret_fmul_dapz_nonan_nozero__nonan_nozero(float nofpclass(nan zero)
}
define float @ret_fmul_dynamic_nonan_nozero__nonan_nozero(float nofpclass(nan zero) %arg0, float nofpclass(nan zero) %arg1) #3 {
-; CHECK-LABEL: define float @ret_fmul_dynamic_nonan_nozero__nonan_nozero
+; CHECK-LABEL: define nofpclass(snan) float @ret_fmul_dynamic_nonan_nozero__nonan_nozero
; CHECK-SAME: (float nofpclass(nan zero) [[ARG0:%.*]], float nofpclass(nan zero) [[ARG1:%.*]]) #[[ATTR3:[0-9]+]] {
; CHECK-NEXT: [[FMUL:%.*]] = fmul float [[ARG0]], [[ARG1]]
; CHECK-NEXT: ret float [[FMUL]]
@@ -62,7 +62,7 @@ define float @ret_fmul_ieee_nonan_noinf__nonan_noinf(float nofpclass(nan inf) %a
}
define float @ret_fmul_ieee_nonan_nozero__nonan_noinf(float nofpclass(nan zero) %arg0, float nofpclass(nan inf) %arg1) #0 {
-; CHECK-LABEL: define float @ret_fmul_ieee_nonan_nozero__nonan_noinf
+; CHECK-LABEL: define nofpclass(snan) float @ret_fmul_ieee_nonan_nozero__nonan_noinf
; CHECK-SAME: (float nofpclass(nan zero) [[ARG0:%.*]], float nofpclass(nan inf) [[ARG1:%.*]]) #[[ATTR0]] {
; CHECK-NEXT: [[FMUL:%.*]] = fmul float [[ARG0]], [[ARG1]]
; CHECK-NEXT: ret float [[FMUL]]
@@ -72,7 +72,7 @@ define float @ret_fmul_ieee_nonan_nozero__nonan_noinf(float nofpclass(nan zero)
}
define float @ret_fmul_ieee_nonan_noinf__nonan_nozero(float nofpclass(nan inf) %arg0, float nofpclass(nan zero) %arg1) #0 {
-; CHECK-LABEL: define float @ret_fmul_ieee_nonan_noinf__nonan_nozero
+; CHECK-LABEL: define nofpclass(snan) float @ret_fmul_ieee_nonan_noinf__nonan_nozero
; CHECK-SAME: (float nofpclass(nan inf) [[ARG0:%.*]], float nofpclass(nan zero) [[ARG1:%.*]]) #[[ATTR0]] {
; CHECK-NEXT: [[FMUL:%.*]] = fmul float [[ARG0]], [[ARG1]]
; CHECK-NEXT: ret float [[FMUL]]
@@ -82,7 +82,7 @@ define float @ret_fmul_ieee_nonan_noinf__nonan_nozero(float nofpclass(nan inf) %
}
define float @ret_fmul_ieee_nonan_noinf__nonan_noposzero(float nofpclass(nan inf) %arg0, float nofpclass(nan pzero) %arg1) #0 {
-; CHECK-LABEL: define float @ret_fmul_ieee_nonan_noinf__nonan_noposzero
+; CHECK-LABEL: define nofpclass(snan) float @ret_fmul_ieee_nonan_noinf__nonan_noposzero
; CHECK-SAME: (float nofpclass(nan inf) [[ARG0:%.*]], float nofpclass(nan pzero) [[ARG1:%.*]]) #[[ATTR0]] {
; CHECK-NEXT: [[FMUL:%.*]] = fmul float [[ARG0]], [[ARG1]]
; CHECK-NEXT: ret float [[FMUL]]
@@ -92,7 +92,7 @@ define float @ret_fmul_ieee_nonan_noinf__nonan_noposzero(float nofpclass(nan inf
}
define float @ret_fmul_ieee_nonan_noposzero__nonan_noinf(float nofpclass(nan pzero) %arg0, float nofpclass(nan inf) %arg1) #0 {
-; CHECK-LABEL: define float @ret_fmul_ieee_nonan_noposzero__nonan_noinf
+; CHECK-LABEL: define nofpclass(snan) float @ret_fmul_ieee_nonan_noposzero__nonan_noinf
; CHECK-SAME: (float nofpclass(nan pzero) [[ARG0:%.*]], float nofpclass(nan inf) [[ARG1:%.*]]) #[[ATTR0]] {
; CHECK-NEXT: [[FMUL:%.*]] = fmul float [[ARG0]], [[ARG1]]
; CHECK-NEXT: ret float [[FMUL]]
@@ -144,7 +144,7 @@ define float @ret_fmul_dynamic_nonan_nozero_nosub__nonan_nozero_nosub(float nofp
; Missing no-subnormal on lhs
define float @ret_fmul_daz_nonan_nozero__nonan_nozero_nosub(float nofpclass(nan zero) %arg0, float nofpclass(nan zero sub) %arg1) #1 {
-; CHECK-LABEL: define float @ret_fmul_daz_nonan_nozero__nonan_nozero_nosub
+; CHECK-LABEL: define nofpclass(snan) float @ret_fmul_daz_nonan_nozero__nonan_nozero_nosub
; CHECK-SAME: (float nofpclass(nan zero) [[ARG0:%.*]], float nofpclass(nan zero sub) [[ARG1:%.*]]) #[[ATTR1]] {
; CHECK-NEXT: [[FMUL:%.*]] = fmul float [[ARG0]], [[ARG1]]
; CHECK-NEXT: ret float [[FMUL]]
@@ -155,7 +155,7 @@ define float @ret_fmul_daz_nonan_nozero__nonan_nozero_nosub(float nofpclass(nan
; Missing no-subnormal on lhs
define float @ret_fmul_daz_nonan_nozero_nosub__nonan_nozero(float nofpclass(nan zero sub) %arg0, float nofpclass(nan zero) %arg1) #1 {
-; CHECK-LABEL: define float @ret_fmul_daz_nonan_nozero_nosub__nonan_nozero
+; CHECK-LABEL: define nofpclass(snan) float @ret_fmul_daz_nonan_nozero_nosub__nonan_nozero
; CHECK-SAME: (float nofpclass(nan zero sub) [[ARG0:%.*]], float nofpclass(nan zero) [[ARG1:%.*]]) #[[ATTR1]] {
; CHECK-NEXT: [[FMUL:%.*]] = fmul float [[ARG0]], [[ARG1]]
; CHECK-NEXT: ret float [[FMUL]]
@@ -285,7 +285,7 @@ define float @ret_fmul_ieee_noinf_nonan__nozero(float nofpclass(inf nan) %arg0,
}
define float @ret_fmul_ieee_nozero_nonan__noinf_nonan(float nofpclass(zero nan) %arg0, float nofpclass(inf nan) %arg1) {
-; CHECK-LABEL: define float @ret_fmul_ieee_nozero_nonan__noinf_nonan
+; CHECK-LABEL: define nofpclass(snan) float @ret_fmul_ieee_nozero_nonan__noinf_nonan
; CHECK-SAME: (float nofpclass(nan zero) [[ARG0:%.*]], float nofpclass(nan inf) [[ARG1:%.*]]) #[[ATTR4]] {
; CHECK-NEXT: [[FMUL:%.*]] = fmul float [[ARG0]], [[ARG1]]
; CHECK-NEXT: ret float [[FMUL]]
@@ -295,7 +295,7 @@ define float @ret_fmul_ieee_nozero_nonan__noinf_nonan(float nofpclass(zero nan)
}
define float @ret_fmul_ieee_noinf_nonan__nozero_nonan(float nofpclass(inf nan) %arg0, float nofpclass(zero nan) %arg1) {
-; CHECK-LABEL: define float @ret_fmul_ieee_noinf_nonan__nozero_nonan
+; CHECK-LABEL: define nofpclass(snan) float @ret_fmul_ieee_noinf_nonan__nozero_nonan
; CHECK-SAME: (float nofpclass(nan inf) [[ARG0:%.*]], float nofpclass(nan zero) [[ARG1:%.*]]) #[[ATTR4]] {
; CHECK-NEXT: [[FMUL:%.*]] = fmul float [[ARG0]], [[ARG1]]
; CHECK-NEXT: ret float [[FMUL]]
diff --git a/llvm/unittests/Analysis/ValueTrackingTest.cpp b/llvm/unittests/Analysis/ValueTrackingTest.cpp
index 0634f43f3e79c..04749b89663c9 100644
--- a/llvm/unittests/Analysis/ValueTrackingTest.cpp
+++ b/llvm/unittests/Analysis/ValueTrackingTest.cpp
@@ -1794,7 +1794,7 @@ TEST_F(ComputeKnownFPClassTest, FAdd) {
expectKnownFPClass(fcFinite | fcInf, std::nullopt, A2);
expectKnownFPClass(fcAllFlags, std::nullopt, A3);
expectKnownFPClass(fcAllFlags, std::nullopt, A4);
- expectKnownFPClass(fcAllFlags, std::nullopt, A5);
+ expectKnownFPClass(~fcSNan, std::nullopt, A5);
}
TEST_F(ComputeKnownFPClassTest, FSub) {
@@ -1811,7 +1811,7 @@ TEST_F(ComputeKnownFPClassTest, FSub) {
expectKnownFPClass(fcFinite | fcInf, std::nullopt, A2);
expectKnownFPClass(fcAllFlags, std::nullopt, A3);
expectKnownFPClass(fcAllFlags, std::nullopt, A4);
- expectKnownFPClass(fcAllFlags, std::nullopt, A5);
+ expectKnownFPClass(~fcSNan, std::nullopt, A5);
}
TEST_F(ComputeKnownFPClassTest, FMul) {
@@ -1825,8 +1825,8 @@ TEST_F(ComputeKnownFPClassTest, FMul) {
" ret float %A\n"
"}\n");
expectKnownFPClass(fcFinite | fcInf, std::nullopt, A);
- expectKnownFPClass(fcAllFlags, std::nullopt, A2);
- expectKnownFPClass(fcAllFlags, std::nullopt, A3);
+ expectKnownFPClass(~fcSNan, std::nullopt, A2);
+ expectKnownFPClass(~fcSNan, std::nullopt, A3);
expectKnownFPClass(fcAllFlags, std::nullopt, A4);
expectKnownFPClass(fcPositive, false, A5);
}
@@ -1845,11 +1845,11 @@ TEST_F(ComputeKnownFPClassTest, FMulNoZero) {
"}\n");
expectKnownFPClass(fcFinite | fcInf, std::nullopt, A);
expectKnownFPClass(fcPositive | fcNan, std::nullopt, A2);
- expectKnownFPClass(fcAllFlags, std::nullopt, A3);
+ expectKnownFPClass(~fcSNan, std::nullopt, A3);
expectKnownFPClass(fcAllFlags, std::nullopt, A4);
expectKnownFPClass(fcAllFlags, std::nullopt, A5);
- expectKnownFPClass(fcAllFlags, std::nullopt, A6);
- expectKnownFPClass(fcAllFlags, std::nullopt, A7);
+ expectKnownFPClass(~fcSNan, std::nullopt, A6);
+ expectKnownFPClass(~fcSNan, std::nullopt, A7);
}
TEST_F(ComputeKnownFPClassTest, MinimumNumSignBit) {
More information about the llvm-commits
mailing list