[llvm] [KnownFPClass] Propagate non-`sNaN` for `fadd`/`fsub`, `fmul`, `fdiv`, and `fma` (PR #221876)
via llvm-commits
llvm-commits at lists.llvm.org
Thu Sep 10 21:54:46 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-llvm-support
@llvm/pr-subscribers-llvm-transforms
Author: Eric Ross (ZERICO2005)
<details>
<summary>Changes</summary>
`fadd`, `fsub`, `fmul`, `fdiv`, and `fma` can only return `sNaN` if at least one of their inputs are `sNaN`. This means that we can rule out `sNaN` from the result if all of the arguments are known to never be `sNaN`.
`sNaN` propagation for `frem` is handled in this PR: https://github.com/llvm/llvm-project/pull/219303
---
Patch is 218.57 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/221876.diff
8 Files Affected:
- (modified) llvm/lib/Support/KnownFPClass.cpp (+18-3)
- (added) llvm/test/Transforms/Attributor/nofpclass-fadd-fsub.ll (+1296)
- (modified) llvm/test/Transforms/Attributor/nofpclass-fdiv.ll (+51-11)
- (modified) llvm/test/Transforms/Attributor/nofpclass-fma.ll (+159-15)
- (modified) llvm/test/Transforms/Attributor/nofpclass-fmul.ll (+44-4)
- (modified) llvm/test/Transforms/Attributor/nofpclass-nan-fmul.ll (+12-12)
- (modified) llvm/test/Transforms/Attributor/nofpclass.ll (+142-1339)
- (modified) llvm/unittests/Analysis/ValueTrackingTest.cpp (+7-7)
``````````diff
diff --git a/llvm/lib/Support/KnownFPClass.cpp b/llvm/lib/Support/KnownFPClass.cpp
index 1f596edd74100..0d47986415b5b 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/nofpclass-fadd-fsub.ll b/llvm/test/Transforms/Attributor/nofpclass-fadd-fsub.ll
new file mode 100644
index 0000000000000..05a4da5e5878d
--- /dev/null
+++ b/llvm/test/Transforms/Attributor/nofpclass-fadd-fsub.ll
@@ -0,0 +1,1296 @@
+; 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]] {
+; CHECK-NEXT: [[ADD:%.*]] = fadd float [[ARG0]], 0.000000e+00
+; CHECK-NEXT: ret float [[ADD]]
+;
+ %add = fadd float %arg0, 0.0
+ ret float %add
+}
+
+define float @fadd_n0(float %arg0) {
+; CHECK-LABEL: define float @fadd_n0(
+; CHECK-SAME: float [[ARG0:%.*]]) #[[ATTR0]] {
+; CHECK-NEXT: [[ADD:%.*]] = fadd float [[ARG0]], -0.000000e+00
+; CHECK-NEXT: ret float [[ADD]]
+;
+ %add = fadd float %arg0, -0.0
+ ret float %add
+}
+
+define float @fsub_p0(float %arg0) {
+; CHECK-LABEL: define float @fsub_p0(
+; CHECK-SAME: float [[ARG0:%.*]]) #[[ATTR0]] {
+; CHECK-NEXT: [[SUB:%.*]] = fsub float [[ARG0]], 0.000000e+00
+; CHECK-NEXT: ret float [[SUB]]
+;
+ %sub = fsub float %arg0, 0.0
+ ret float %sub
+}
+
+define float @fsub_n0(float %arg0) {
+; CHECK-LABEL: define nofpclass(nzero) float @fsub_n0(
+; CHECK-SAME: float [[ARG0:%.*]]) #[[ATTR0]] {
+; CHECK-NEXT: [[SUB:%.*]] = fsub float [[ARG0]], -0.000000e+00
+; CHECK-NEXT: ret float [[SUB]]
+;
+ %sub = fsub float %arg0, -0.0
+ ret float %sub
+}
+
+define float @fsub_p0_commute(float %arg0) {
+; CHECK-LABEL: define nofpclass(nzero) float @fsub_p0_commute(
+; CHECK-SAME: float [[ARG0:%.*]]) #[[ATTR0]] {
+; CHECK-NEXT: [[SUB:%.*]] = fsub float 0.000000e+00, [[ARG0]]
+; CHECK-NEXT: ret float [[SUB]]
+;
+ %sub = fsub float 0.0, %arg0
+ ret float %sub
+}
+
+define float @fsub_n0_commute(float %arg0) {
+; CHECK-LABEL: define float @fsub_n0_commute(
+; CHECK-SAME: float [[ARG0:%.*]]) #[[ATTR0]] {
+; CHECK-NEXT: [[SUB:%.*]] = fsub float -0.000000e+00, [[ARG0]]
+; CHECK-NEXT: ret float [[SUB]]
+;
+ %sub = fsub float -0.0, %arg0
+ ret float %sub
+}
+
+define float @fadd_p0_ftz_daz(float %arg0) #0 {
+; CHECK-LABEL: define float @fadd_p0_ftz_daz(
+; CHECK-SAME: float [[ARG0:%.*]]) #[[ATTR1:[0-9]+]] {
+; CHECK-NEXT: [[ADD:%.*]] = fadd float [[ARG0]], 0.000000e+00
+; CHECK-NEXT: ret float [[ADD]]
+;
+ %add = fadd float %arg0, 0.0
+ ret float %add
+}
+
+define float @fadd_p0_ftpz_dapz(float %arg0) #3 {
+; CHECK-LABEL: define nofpclass(nzero) float @fadd_p0_ftpz_dapz(
+; CHECK-SAME: float [[ARG0:%.*]]) #[[ATTR2:[0-9]+]] {
+; CHECK-NEXT: [[ADD:%.*]] = fadd float [[ARG0]], 0.000000e+00
+; CHECK-NEXT: ret float [[ADD]]
+;
+ %add = fadd float %arg0, 0.0
+ ret float %add
+}
+
+define float @fadd_p0_dynamic_dynamic(float %arg0) #6 {
+; CHECK-LABEL: define float @fadd_p0_dynamic_dynamic(
+; CHECK-SAME: float [[ARG0:%.*]]) #[[ATTR3:[0-9]+]] {
+; CHECK-NEXT: [[ADD:%.*]] = fadd float [[ARG0]], 0.000000e+00
+; CHECK-NEXT: ret float [[ADD]]
+;
+ %add = fadd float %arg0, 0.0
+ ret float %add
+}
+
+define float @fadd_n0_ftz_daz(float %arg0) #0 {
+; CHECK-LABEL: define float @fadd_n0_ftz_daz(
+; CHECK-SAME: float [[ARG0:%.*]]) #[[ATTR1]] {
+; CHECK-NEXT: [[ADD:%.*]] = fadd float [[ARG0]], -0.000000e+00
+; CHECK-NEXT: ret float [[ADD]]
+;
+ %add = fadd float %arg0, -0.0
+ ret float %add
+}
+
+define float @fsub_p0_ftz_daz(float %arg0) #0 {
+; CHECK-LABEL: define float @fsub_p0_ftz_daz(
+; CHECK-SAME: float [[ARG0:%.*]]) #[[ATTR1]] {
+; CHECK-NEXT: [[SUB:%.*]] = fsub float [[ARG0]], 0.000000e+00
+; CHECK-NEXT: ret float [[SUB]]
+;
+ %sub = fsub float %arg0, 0.0
+ ret float %sub
+}
+
+define float @fsub_n0_ftz_daz(float %arg0) #0 {
+; CHECK-LABEL: define float @fsub_n0_ftz_daz(
+; CHECK-SAME: float [[ARG0:%.*]]) #[[ATTR1]] {
+; CHECK-NEXT: [[SUB:%.*]] = fsub float [[ARG0]], -0.000000e+00
+; CHECK-NEXT: ret float [[SUB]]
+;
+ %sub = fsub float %arg0, -0.0
+ ret float %sub
+}
+
+define float @fsub_p0_commute_ftz_daz(float %arg0) #0 {
+; CHECK-LABEL: define float @fsub_p0_commute_ftz_daz(
+; CHECK-SAME: float [[ARG0:%.*]]) #[[ATTR1]] {
+; CHECK-NEXT: [[SUB:%.*]] = fsub float 0.000000e+00, [[ARG0]]
+; CHECK-NEXT: ret float [[SUB]]
+;
+ %sub = fsub float 0.0, %arg0
+ ret float %sub
+}
+
+define float @fsub_n0_commute_ftz_daz(float %arg0) #0 {
+; CHECK-LABEL: define float @fsub_n0_commute_ftz_daz(
+; CHECK-SAME: float [[ARG0:%.*]]) #[[ATTR1]] {
+; CHECK-NEXT: [[SUB:%.*]] = fsub float -0.000000e+00, [[ARG0]]
+; CHECK-NEXT: ret float [[SUB]]
+;
+ %sub = fsub float -0.0, %arg0
+ ret float %sub
+}
+
+define float @fadd_p0_ieee_daz(float %arg0) #2 {
+; CHECK-LABEL: define nofpclass(nzero) float @fadd_p0_ieee_daz(
+; CHECK-SAME: float [[ARG0:%.*]]) #[[ATTR4:[0-9]+]] {
+; CHECK-NEXT: [[ADD:%.*]] = fadd float [[ARG0]], 0.000000e+00
+; CHECK-NEXT: ret float [[ADD]]
+;
+ %add = fadd float %arg0, 0.0
+ ret float %add
+}
+
+define float @fadd_p0_dapz_ieee(float %arg0) #4 {
+; CHECK-LABEL: define nofpclass(nzero) float @fadd_p0_dapz_ieee(
+; CHECK-SAME: float [[ARG0:%.*]]) #[[ATTR5:[0-9]+]] {
+; CHECK-NEXT: [[ADD:%.*]] = fadd float [[ARG0]], 0.000000e+00
+; CHECK-NEXT: ret float [[ADD]]
+;
+ %add = fadd float %arg0, 0.0
+ ret float %add
+}
+
+define float @fadd_n0_ieee_daz(float %arg0) #2 {
+; CHECK-LABEL: define float @fadd_n0_ieee_daz(
+; CHECK-SAME: float [[ARG0:%.*]]) #[[ATTR4]] {
+; CHECK-NEXT: [[ADD:%.*]] = fadd float [[ARG0]], -0.000000e+00
+; CHECK-NEXT: ret float [[ADD]]
+;
+ %add = fadd float %arg0, -0.0
+ ret float %add
+}
+
+define float @fsub_p0_ieee_daz(float %arg0) #2 {
+; CHECK-LABEL: define float @fsub_p0_ieee_daz(
+; CHECK-SAME: float [[ARG0:%.*]]) #[[ATTR4]] {
+; CHECK-NEXT: [[SUB:%.*]] = fsub float [[ARG0]], 0.000000e+00
+; CHECK-NEXT: ret float [[SUB]]
+;
+ %sub = fsub float %arg0, 0.0
+ ret float %sub
+}
+
+define float @fsub_n0_ieee_daz(float %arg0) #2 {
+; CHECK-LABEL: define nofpclass(nzero) float @fsub_n0_ieee_daz(
+; CHECK-SAME: float [[ARG0:%.*]]) #[[ATTR4]] {
+; CHECK-NEXT: [[SUB:%.*]] = fsub float [[ARG0]], -0.000000e+00
+; CHECK-NEXT: ret float [[SUB]]
+;
+ %sub = fsub float %arg0, -0.0
+ ret float %sub
+}
+
+define float @fsub_p0_commute_ieee_daz(float %arg0) #2 {
+; CHECK-LABEL: define nofpclass(nzero) float @fsub_p0_commute_ieee_daz(
+; CHECK-SAME: float [[ARG0:%.*]]) #[[ATTR4]] {
+; CHECK-NEXT: [[SUB:%.*]] = fsub float 0.000000e+00, [[ARG0]]
+; CHECK-NEXT: ret float [[SUB]]
+;
+ %sub = fsub float 0.0, %arg0
+ ret float %sub
+}
+
+define float @fsub_n0_commute_ieee_daz(float %arg0) #1 {
+; CHECK-LABEL: define float @fsub_n0_commute_ieee_daz(
+; CHECK-SAME: float [[ARG0:%.*]]) #[[ATTR6:[0-9]+]] {
+; CHECK-NEXT: [[SUB:%.*]] = fsub float -0.000000e+00, [[ARG0]]
+; CHECK-NEXT: ret float [[SUB]]
+;
+ %sub = fsub float -0.0, %arg0
+ ret float %sub
+}
+
+define float @fadd_never_negzero_or_negsub(float nofpclass(nzero nsub) %a, float nofpclass(nzero nsub) %b) {
+; CHECK-LABEL: define nofpclass(nzero) float @fadd_never_negzero_or_negsub(
+; CHECK-SAME: float nofpclass(nzero nsub) [[A:%.*]], float nofpclass(nzero nsub) [[B:%.*]]) #[[ATTR0]] {
+; CHECK-NEXT: [[ADD:%.*]] = fadd float [[A]], [[B]]
+; CHECK-NEXT: ret float [[ADD]]
+;
+ %add = fadd float %a, %b
+ ret float %add
+}
+
+define float @fadd_never_negzero_or_ftz_daz(float nofpclass(nzero nsub) %a, float nofpclass(nzero nsub) %b) #0 {
+; CHECK-LABEL: define float @fadd_never_negzero_or_ftz_daz(
+; CHECK-SAME: float nofpclass(nzero nsub) [[A:%.*]], float nofpclass(nzero nsub) [[B:%.*]]) #[[ATTR1]] {
+; CHECK-NEXT: [[ADD:%.*]] = fadd float [[A]], [[B]]
+; CHECK-NEXT: ret float [[ADD]]
+;
+ %add = fadd float %a, %b
+ ret float %add
+}
+
+define float @fadd_never_negzero_or_negsub_daz(float nofpclass(nzero nsub) %a, float nofpclass(nzero nsub) %b) #2 {
+; CHECK-LABEL: define nofpclass(nzero) float @fadd_never_negzero_or_negsub_daz(
+; CHECK-SAME: float nofpclass(nzero nsub) [[A:%.*]], float nofpclass(nzero nsub) [[B:%.*]]) #[[ATTR4]] {
+; CHECK-NEXT: [[ADD:%.*]] = fadd float [[A]], [[B]]
+; CHECK-NEXT: ret float [[ADD]]
+;
+ %add = fadd float %a, %b
+ ret float %add
+}
+
+define float @fadd_never_negzero_or_negsub_dapz(float nofpclass(nzero nsub) %a, float nofpclass(nzero nsub) %b) #5 {
+; CHECK-LABEL: define nofpclass(nzero) float @fadd_never_negzero_or_negsub_dapz(
+; CHECK-SAME: float nofpclass(nzero nsub) [[A:%.*]], float nofpclass(nzero nsub) [[B:%.*]]) #[[ATTR7:[0-9]+]] {
+; CHECK-NEXT: [[ADD:%.*]] = fadd float [[A]], [[B]]
+; CHECK-NEXT: ret float [[ADD]]
+;
+ %add = fadd float %a, %b
+ ret float %add
+}
+
+define float @fadd_never_negzero_or_possub(float nofpclass(nzero psub) %a, float nofpclass(nzero psub) %b) {
+; CHECK-LABEL: define nofpclass(nzero) float @fadd_never_negzero_or_possub(
+; CHECK-SAME: float nofpclass(nzero psub) [[A:%.*]], float nofpclass(nzero psub) [[B:%.*]]) #[[ATTR0]] {
+; CHECK-NEXT: [[ADD:%.*]] = fadd float [[A]], [[B]]
+; CHECK-NEXT: ret float [[ADD]]
+;
+ %add = fadd float %a, %b
+ ret float %add
+}
+
+define float @fadd_never_negzero_or_possub_daz(float nofpclass(nzero psub) %a, float nofpclass(nzero psub) %b) #2 {
+; CHECK-LABEL: define float @fadd_never_negzero_or_possub_daz(
+; CHECK-SAME: float nofpclass(nzero psub) [[A:%.*]], float nofpclass(nzero psub) [[B:%.*]]) #[[ATTR4]] {
+; CHECK-NEXT: [[ADD:%.*]] = fadd float [[A]], [[B]]
+; CHECK-NEXT: ret float [[ADD]]
+;
+ %add = fadd float %a, %b
+ ret float %add
+}
+
+define float @fadd_never_negzero_or_possub_dapz(float nofpclass(nzero psub) %a, float nofpclass(nzero psub) %b) #5 {
+; CHECK-LABEL: define nofpclass(nzero) float @fadd_never_negzero_or_possub_dapz(
+; CHECK-SAME: float nofpclass(nzero psub) [[A:%.*]], float nofpclass(nzero psub) [[B:%.*]]) #[[ATTR7]] {
+; CHECK-NEXT: [[ADD:%.*]] = fadd float [[A]], [[B]]
+; CHECK-NEXT: ret float [[ADD]]
+;
+ %add = fadd float %a, %b
+ ret float %add
+}
+
+define float @fadd_never_negzero_or_sub_daz(float nofpclass(nzero sub) %a, float nofpclass(nzero sub) %b) #2 {
+; CHECK-LABEL: define nofpclass(nzero) float @fadd_never_negzero_or_sub_daz(
+; CHECK-SAME: float nofpclass(nzero sub) [[A:%.*]], float nofpclass(nzero sub) [[B:%.*]]) #[[ATTR4]] {
+; CHECK-NEXT: [[ADD:%.*]] = fadd float [[A]], [[B]]
+; CHECK-NEXT: ret float [[ADD]]
+;
+ %add = fadd float %a, %b
+ ret float %add
+}
+
+define float @fadd_never_negzero_or_sub_dapz(float nofpclass(nzero sub) %a, float nofpclass(nzero sub) %b) #5 {
+; CHECK-LABEL: define nofpclass(nzero) float @fadd_never_negzero_or_sub_dapz(
+; CHECK-SAME: float nofpclass(nzero sub) [[A:%.*]], float nofpclass(nzero sub) [[B:%.*]]) #[[ATTR7]] {
+; CHECK-NEXT: [[ADD:%.*]] = fadd float [[A]], [[B]]
+; CHECK-NEXT: ret float [[ADD]]
+;
+ %add = fadd float %a, %b
+ ret float %add
+}
+
+define float @fadd_known_positive_lhs(float nofpclass(ninf nsub nnorm) %arg0, float %arg1) {
+; CHECK-LABEL: define float @fadd_known_positive_lhs(
+; CHECK-SAME: float nofpclass(ninf nsub nnorm) [[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_known_positive_rhs(float %arg0, float nofpclass(ninf nsub nnorm) %arg1) {
+; CHECK-LABEL: define float @fadd_known_positive_rhs(
+; CHECK-SAME: float [[ARG0:%.*]], float nofpclass(ninf nsub nnorm) [[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_known_positive(float nofpclass(ninf nsub nnorm) %arg0, float nofpclass(ninf nsub nnorm) %arg1) {
+; CHECK-LABEL: define nofpclass(ninf nsub nnorm) float @fadd_known_positive(
+; CHECK-SAME: float nofpclass(ninf nsub nnorm) [[ARG0:%.*]], float nofpclass(ninf nsub nnorm) [[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_known_positive_daz(float nofpclass(ninf nsub nnorm) %arg0, float nofpclass(ninf nsub nnorm) %arg1) #0 {
+; CHECK-LABEL: define nofpclass(ninf nsub nnorm) float @fadd_known_positive_daz(
+; CHECK-SAME: float nofpclass(ninf nsub nnorm) [[ARG0:%.*]], float nofpclass(ninf nsub nnorm) [[ARG1:%.*]]) #[[ATTR1]] {
+; CHECK-NEXT: [[ADD:%.*]] = fadd float [[ARG0]], [[ARG1]]
+; CHECK-NEXT: ...
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/221876
More information about the llvm-commits
mailing list