[llvm] [KnownFPClass] Fix fadd/fsub input handling and improve fadd_self (PR #225605)
Eric Ross via llvm-commits
llvm-commits at lists.llvm.org
Tue Sep 22 23:19:50 PDT 2026
https://github.com/ZERICO2005 created https://github.com/llvm/llvm-project/pull/225605
Fixes https://github.com/llvm/llvm-project/issues/225587
I rewrote `KnownFPClass::fadd_self` from scratch.
>From 323a44120b8a93f8afb7bddb5a9c782b637565b7 Mon Sep 17 00:00:00 2001
From: zerico <zerico2005 at gmail.com>
Date: Tue, 22 Sep 2026 19:53:28 -0600
Subject: [PATCH 1/2] [KnownFPClass] Add output/input denormal helpers
---
llvm/include/llvm/Support/KnownFPClass.h | 10 +++
llvm/lib/Support/KnownFPClass.cpp | 110 +++++++++++++----------
2 files changed, 71 insertions(+), 49 deletions(-)
diff --git a/llvm/include/llvm/Support/KnownFPClass.h b/llvm/include/llvm/Support/KnownFPClass.h
index 22097a70a361be..33a115b679ad0d 100644
--- a/llvm/include/llvm/Support/KnownFPClass.h
+++ b/llvm/include/llvm/Support/KnownFPClass.h
@@ -160,6 +160,16 @@ struct KnownFPClass {
return isKnownNever(fcPositive) && isKnownNeverLogicalNegZero(Mode);
}
+ /// Return the known classes of \p Src after passing through an input that
+ /// may flush subnormals to zero according to \p Mode.
+ LLVM_ABI static KnownFPClass applyInputDenormalMode(const KnownFPClass &Src,
+ DenormalMode Mode);
+
+ /// Return the known classes of \p Src after producing an output that may
+ /// flush subnormals to zero according to \p Mode.
+ LLVM_ABI static KnownFPClass applyOutputDenormalMode(const KnownFPClass &Src,
+ DenormalMode Mode);
+
KnownFPClass intersectWith(const KnownFPClass &RHS) const {
return KnownFPClass(getKnownFPClasses() | RHS.getKnownFPClasses(),
getSignBit() == RHS.getSignBit() ? getSignBit()
diff --git a/llvm/lib/Support/KnownFPClass.cpp b/llvm/lib/Support/KnownFPClass.cpp
index 48867ce3a6a6fb..c7ba90ed3ac742 100644
--- a/llvm/lib/Support/KnownFPClass.cpp
+++ b/llvm/lib/Support/KnownFPClass.cpp
@@ -23,48 +23,70 @@ KnownFPClass::KnownFPClass(const APFloat &C)
setSignBit(C.isNegative());
}
-/// Return true if it's possible to assume IEEE treatment of input denormals in
-/// \p F for \p Val.
-static bool inputDenormalIsIEEE(DenormalMode Mode) {
- return Mode.Input == DenormalMode::IEEE;
+KnownFPClass KnownFPClass::applyInputDenormalMode(const KnownFPClass &KnownSrc,
+ DenormalMode Mode) {
+ KnownFPClass Known = KnownSrc;
+ switch (Mode.Input) {
+ case DenormalMode::IEEE:
+ return Known;
+ case DenormalMode::PreserveSign:
+ if (KnownSrc.getKnownFPClasses() & fcPosSubnormal)
+ Known.setKnownFPClasses(Known.getKnownFPClasses() | fcPosZero);
+ if (KnownSrc.getKnownFPClasses() & fcNegSubnormal)
+ Known.setKnownFPClasses(Known.getKnownFPClasses() | fcNegZero);
+ return Known;
+ case DenormalMode::PositiveZero:
+ if (KnownSrc.getKnownFPClasses() & fcSubnormal)
+ Known.setKnownFPClasses(Known.getKnownFPClasses() | fcPosZero);
+ return Known;
+ default:
+ if (KnownSrc.getKnownFPClasses() & fcSubnormal)
+ Known.setKnownFPClasses(Known.getKnownFPClasses() | fcPosZero);
+ if (KnownSrc.getKnownFPClasses() & fcNegSubnormal)
+ Known.setKnownFPClasses(Known.getKnownFPClasses() | fcNegZero);
+ return Known;
+ }
+
+ llvm_unreachable("covered switch over denormal mode");
}
-static bool inputDenormalIsIEEEOrPosZero(DenormalMode Mode) {
- return Mode.Input == DenormalMode::IEEE ||
- Mode.Input == DenormalMode::PositiveZero;
+KnownFPClass KnownFPClass::applyOutputDenormalMode(const KnownFPClass &KnownSrc,
+ DenormalMode Mode) {
+ KnownFPClass Known = KnownSrc;
+ switch (Mode.Output) {
+ case DenormalMode::IEEE:
+ return Known;
+ case DenormalMode::PreserveSign:
+ if (KnownSrc.getKnownFPClasses() & fcPosSubnormal)
+ Known.setKnownFPClasses(Known.getKnownFPClasses() | fcPosZero);
+ if (KnownSrc.getKnownFPClasses() & fcNegSubnormal)
+ Known.setKnownFPClasses(Known.getKnownFPClasses() | fcNegZero);
+ return Known;
+ case DenormalMode::PositiveZero:
+ if (KnownSrc.getKnownFPClasses() & fcSubnormal)
+ Known.setKnownFPClasses(Known.getKnownFPClasses() | fcPosZero);
+ return Known;
+ default:
+ if (KnownSrc.getKnownFPClasses() & fcSubnormal)
+ Known.setKnownFPClasses(Known.getKnownFPClasses() | fcPosZero);
+ if (KnownSrc.getKnownFPClasses() & fcNegSubnormal)
+ Known.setKnownFPClasses(Known.getKnownFPClasses() | fcNegZero);
+ return Known;
+ }
+
+ llvm_unreachable("covered switch over denormal mode");
}
bool KnownFPClass::isKnownNeverLogicalZero(DenormalMode Mode) const {
- return isKnownNeverZero() &&
- (isKnownNeverSubnormal() || inputDenormalIsIEEE(Mode));
+ return applyInputDenormalMode(*this, Mode).isKnownNeverZero();
}
bool KnownFPClass::isKnownNeverLogicalNegZero(DenormalMode Mode) const {
- return isKnownNeverNegZero() &&
- (isKnownNeverNegSubnormal() || inputDenormalIsIEEEOrPosZero(Mode));
+ return applyInputDenormalMode(*this, Mode).isKnownNeverNegZero();
}
bool KnownFPClass::isKnownNeverLogicalPosZero(DenormalMode Mode) const {
- if (!isKnownNeverPosZero())
- return false;
-
- // If we know there are no denormals, nothing can be flushed to zero.
- if (isKnownNeverSubnormal())
- return true;
-
- switch (Mode.Input) {
- case DenormalMode::IEEE:
- return true;
- case DenormalMode::PreserveSign:
- // Negative subnormal won't flush to +0
- return isKnownNeverPosSubnormal();
- case DenormalMode::PositiveZero:
- default:
- // Both positive and negative subnormal could flush to +0
- return false;
- }
-
- llvm_unreachable("covered switch over denormal mode");
+ return applyInputDenormalMode(*this, Mode).isKnownNeverPosZero();
}
void KnownFPClass::propagateDenormal(const KnownFPClass &Src,
@@ -831,9 +853,11 @@ KnownFPClass KnownFPClass::atan(const KnownFPClass &KnownSrc) {
return Known;
}
-KnownFPClass KnownFPClass::atan2(const KnownFPClass &KnownY,
- const KnownFPClass &KnownX,
+KnownFPClass KnownFPClass::atan2(const KnownFPClass &KnownY_,
+ const KnownFPClass &KnownX_,
DenormalMode Mode) {
+ KnownFPClass KnownY = applyInputDenormalMode(KnownY_, Mode);
+ KnownFPClass KnownX = applyInputDenormalMode(KnownX_, Mode);
KnownFPClass Known;
// Even though these deductions are correct, we are ignoring the following
@@ -846,14 +870,8 @@ KnownFPClass KnownFPClass::atan2(const KnownFPClass &KnownY,
Known.propagateNonNaN(KnownY, KnownX);
- // Negative subnormals could be treated like positive zero.
- const bool XCannotHavePositiveInput = KnownX.isKnownNever(fcPositive) &&
- KnownX.isKnownNeverLogicalPosZero(Mode);
- const bool YCannotHavePositiveInput = KnownY.isKnownNever(fcPositive) &&
- KnownY.isKnownNeverLogicalPosZero(Mode);
-
// If x <= -0.0, then |atan2(y, x)| >= pi/2
- if (XCannotHavePositiveInput)
+ if (KnownX.isKnownNever(fcPositive))
Known.knownNot(fcZero | fcSubnormal);
// If y >= +0.0, then atan2(y, x) >= +0.0
@@ -861,16 +879,10 @@ KnownFPClass KnownFPClass::atan2(const KnownFPClass &KnownY,
Known.knownNot(fcNegative);
// If y <= -0.0, then atan2(y, x) <= -0.0
- // We do this deduction last in case we were able to rule out a negative
- // subnormal result earlier.
- if (YCannotHavePositiveInput) {
- Known.knownNot(fcPosSubnormal | fcPosNormal | fcPosInf);
- // Negative subnormal results can flush to +0.0.
- if (Known.isKnownNever(fcNegSubnormal) || !Mode.outputsMayBePositiveZero())
- Known.knownNot(fcPosZero);
- }
+ if (KnownY.isKnownNever(fcPositive))
+ Known.knownNot(fcPositive);
- return Known;
+ return applyOutputDenormalMode(Known, Mode);
}
KnownFPClass KnownFPClass::fpext(const KnownFPClass &KnownSrc,
>From 8d69cfa2da49e812b76f51d4e38402d051429e9c Mon Sep 17 00:00:00 2001
From: zerico <zerico2005 at gmail.com>
Date: Wed, 23 Sep 2026 00:12:59 -0600
Subject: [PATCH 2/2] [KnownFPClass] Fix fadd/fsub input handling and improve
fadd_self
---
llvm/lib/Support/KnownFPClass.cpp | 87 +++++++++-----
.../Attributor/nofpclass-fadd-fsub.ll | 107 ++++++++++++++----
.../simplify-demanded-fpclass-fadd.ll | 57 ++++------
3 files changed, 163 insertions(+), 88 deletions(-)
diff --git a/llvm/lib/Support/KnownFPClass.cpp b/llvm/lib/Support/KnownFPClass.cpp
index c7ba90ed3ac742..d13245a096a307 100644
--- a/llvm/lib/Support/KnownFPClass.cpp
+++ b/llvm/lib/Support/KnownFPClass.cpp
@@ -385,9 +385,9 @@ KnownBits KnownFPClass::toKnownBits(const fltSemantics &FltSemantics) const {
return Known;
}
-// Handle known sign bit and nan cases for fadd.
-static KnownFPClass fadd_impl(const KnownFPClass &KnownLHS,
- const KnownFPClass &KnownRHS, DenormalMode Mode) {
+// Handle known sign bit and nan cases for fadd, fsub, and fma.
+static KnownFPClass fadd_fsub_fma_common(const KnownFPClass &KnownLHS,
+ const KnownFPClass &KnownRHS) {
KnownFPClass Known;
// Adding positive and negative infinity produces NaN, but only if both
@@ -420,17 +420,13 @@ static KnownFPClass fadd_impl(const KnownFPClass &KnownLHS,
return Known;
}
-KnownFPClass KnownFPClass::fadd(const KnownFPClass &KnownLHS,
- const KnownFPClass &KnownRHS,
- DenormalMode Mode) {
- KnownFPClass Known = fadd_impl(KnownLHS, KnownRHS, Mode);
-
- // (fadd x, 0.0) is guaranteed to return +0.0, not -0.0.
- if ((KnownLHS.isKnownNeverLogicalNegZero(Mode) ||
- KnownRHS.isKnownNeverLogicalNegZero(Mode)) &&
- // Make sure output negative denormal can't flush to -0
- (Mode.Output == DenormalMode::IEEE ||
- Mode.Output == DenormalMode::PositiveZero))
+static KnownFPClass fadd_fsub_common(const KnownFPClass &KnownLHS,
+ const KnownFPClass &KnownRHS) {
+ KnownFPClass Known = fadd_fsub_fma_common(KnownLHS, KnownRHS);
+
+ // fadd(x, +0.0) is guaranteed to return +0.0, not -0.0.
+ // TODO: fadd(+0.0, -0.0) returns -0.0 if rounding towards negative infinity.
+ if (KnownLHS.isKnownNeverNegZero() || KnownRHS.isKnownNeverNegZero())
Known.knownNot(fcNegZero);
Known.propagateNonSNaN(KnownLHS, KnownRHS);
@@ -438,26 +434,57 @@ KnownFPClass KnownFPClass::fadd(const KnownFPClass &KnownLHS,
return Known;
}
-KnownFPClass KnownFPClass::fadd_self(const KnownFPClass &KnownSrc,
+KnownFPClass KnownFPClass::fadd(const KnownFPClass &KnownLHS_,
+ const KnownFPClass &KnownRHS_,
+ DenormalMode Mode) {
+ KnownFPClass KnownLHS = applyInputDenormalMode(KnownLHS_, Mode);
+ KnownFPClass KnownRHS = applyInputDenormalMode(KnownRHS_, Mode);
+
+ KnownFPClass Known = fadd_fsub_common(KnownLHS, KnownRHS);
+
+ return applyOutputDenormalMode(Known, Mode);
+}
+
+KnownFPClass KnownFPClass::fadd_self(const KnownFPClass &KnownSrc_,
DenormalMode Mode) {
- KnownFPClass Known = fadd(KnownSrc, KnownSrc, Mode);
-
- // Doubling 0 will give the same 0.
- if (KnownSrc.isKnownNeverLogicalPosZero(Mode) &&
- (Mode.Output == DenormalMode::IEEE ||
- (Mode.Output == DenormalMode::PreserveSign &&
- KnownSrc.isKnownNeverPosSubnormal()) ||
- (Mode.Output == DenormalMode::PositiveZero &&
- KnownSrc.isKnownNeverSubnormal())))
+ KnownFPClass KnownSrc = applyInputDenormalMode(KnownSrc_, Mode);
+
+ KnownFPClass Known;
+
+ Known.propagateNonNaN(KnownSrc);
+
+ if (KnownSrc.isKnownNever(fcPosNormal | fcPosInf))
+ Known.knownNot(fcPosInf);
+ if (KnownSrc.isKnownNever(fcNegNormal | fcNegInf))
+ Known.knownNot(fcNegInf);
+
+ if (KnownSrc.isKnownNever(fcPosSubnormal | fcPosNormal))
+ Known.knownNot(fcPosNormal);
+ if (KnownSrc.isKnownNever(fcNegSubnormal | fcNegNormal))
+ Known.knownNot(fcNegNormal);
+
+ if (KnownSrc.isKnownNever(fcPosSubnormal))
+ Known.knownNot(fcPosSubnormal);
+ if (KnownSrc.isKnownNever(fcNegSubnormal))
+ Known.knownNot(fcNegSubnormal);
+
+ if (KnownSrc.isKnownNever(fcPosZero))
Known.knownNot(fcPosZero);
+ if (KnownSrc.isKnownNever(fcNegZero))
+ Known.knownNot(fcNegZero);
- return Known;
+ return applyOutputDenormalMode(Known, Mode);
}
-KnownFPClass KnownFPClass::fsub(const KnownFPClass &KnownLHS,
- const KnownFPClass &KnownRHS,
+KnownFPClass KnownFPClass::fsub(const KnownFPClass &KnownLHS_,
+ const KnownFPClass &KnownRHS_,
DenormalMode Mode) {
- return fadd(KnownLHS, fneg(KnownRHS), Mode);
+ KnownFPClass KnownLHS = applyInputDenormalMode(KnownLHS_, Mode);
+ KnownFPClass KnownRHS = applyInputDenormalMode(KnownRHS_, Mode);
+
+ KnownFPClass Known = fadd_fsub_common(KnownLHS, fneg(KnownRHS));
+
+ return applyOutputDenormalMode(Known, Mode);
}
KnownFPClass KnownFPClass::fmul(const KnownFPClass &KnownLHS,
@@ -632,7 +659,7 @@ 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.
- KnownFPClass Known = fadd_impl(Mul, KnownAddend, Mode);
+ KnownFPClass Known = fadd_fsub_fma_common(Mul, KnownAddend);
// propagateNonSNaN for 3 arguments.
if (KnownLHS.isKnownNever(fcSNan) && KnownRHS.isKnownNever(fcSNan) &&
@@ -646,7 +673,7 @@ KnownFPClass KnownFPClass::fma_square(const KnownFPClass &KnownSquared,
const KnownFPClass &KnownAddend,
DenormalMode Mode) {
KnownFPClass Squared = square(KnownSquared, Mode);
- KnownFPClass Known = fadd_impl(Squared, KnownAddend, Mode);
+ KnownFPClass Known = fadd_fsub_fma_common(Squared, KnownAddend);
// Since we know the squared input must be positive, the add of opposite sign
// infinities nan hazard only applies for negative inf.
diff --git a/llvm/test/Transforms/Attributor/nofpclass-fadd-fsub.ll b/llvm/test/Transforms/Attributor/nofpclass-fadd-fsub.ll
index 05a4da5e5878dd..203f86a76bd74c 100644
--- a/llvm/test/Transforms/Attributor/nofpclass-fadd-fsub.ll
+++ b/llvm/test/Transforms/Attributor/nofpclass-fadd-fsub.ll
@@ -42,7 +42,7 @@ define float @fadd_rhs_no_snan(float %arg0, float nofpclass(snan) %arg1) {
}
define float @fadd_self_no_nan(float noundef nofpclass(nan) %arg0) {
-; CHECK-LABEL: define noundef nofpclass(snan) float @fadd_self_no_nan(
+; CHECK-LABEL: define noundef nofpclass(nan) 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]]
@@ -552,7 +552,7 @@ define float @fadd_known_positive_nzero(float nofpclass(ninf nsub nnorm nzero) %
}
define float @fadd_known_positive_nzero_ftz_daz(float nofpclass(ninf nsub nnorm nzero) %arg0, float nofpclass(ninf nsub nnorm nzero) %arg1) #0 {
-; CHECK-LABEL: define nofpclass(ninf nsub nnorm) float @fadd_known_positive_nzero_ftz_daz(
+; CHECK-LABEL: define nofpclass(ninf nzero nsub nnorm) float @fadd_known_positive_nzero_ftz_daz(
; CHECK-SAME: float nofpclass(ninf nzero nsub nnorm) [[ARG0:%.*]], float nofpclass(ninf nzero nsub nnorm) [[ARG1:%.*]]) #[[ATTR1]] {
; CHECK-NEXT: [[ADD:%.*]] = fadd float [[ARG0]], [[ARG1]]
; CHECK-NEXT: ret float [[ADD]]
@@ -562,7 +562,7 @@ define float @fadd_known_positive_nzero_ftz_daz(float nofpclass(ninf nsub nnorm
}
define float @fadd_known_positive_nzero_ftz(float nofpclass(ninf nsub nnorm nzero) %arg0, float nofpclass(ninf nsub nnorm nzero) %arg1) #1 {
-; CHECK-LABEL: define nofpclass(ninf nsub nnorm) float @fadd_known_positive_nzero_ftz(
+; CHECK-LABEL: define nofpclass(ninf nzero nsub nnorm) float @fadd_known_positive_nzero_ftz(
; CHECK-SAME: float nofpclass(ninf nzero nsub nnorm) [[ARG0:%.*]], float nofpclass(ninf nzero nsub nnorm) [[ARG1:%.*]]) #[[ATTR6]] {
; CHECK-NEXT: [[ADD:%.*]] = fadd float [[ARG0]], [[ARG1]]
; CHECK-NEXT: ret float [[ADD]]
@@ -634,7 +634,7 @@ define float @fadd_double(float noundef %arg) {
}
define float @fadd_double_nnan(float noundef nofpclass(nan) %arg) {
-; CHECK-LABEL: define noundef nofpclass(snan) float @fadd_double_nnan(
+; CHECK-LABEL: define noundef nofpclass(nan) float @fadd_double_nnan(
; CHECK-SAME: float noundef nofpclass(nan) [[ARG:%.*]]) #[[ATTR0]] {
; CHECK-NEXT: [[ADD:%.*]] = fadd float [[ARG]], [[ARG]]
; CHECK-NEXT: ret float [[ADD]]
@@ -744,7 +744,7 @@ define float @fadd_double_known_negative_non0(float noundef nofpclass(pinf pnorm
}
define float @fadd_double_no_nopinf_pnorm(float noundef nofpclass(pinf pnorm) %arg) {
-; CHECK-LABEL: define noundef float @fadd_double_no_nopinf_pnorm(
+; CHECK-LABEL: define noundef nofpclass(pinf) float @fadd_double_no_nopinf_pnorm(
; CHECK-SAME: float noundef nofpclass(pinf pnorm) [[ARG:%.*]]) #[[ATTR0]] {
; CHECK-NEXT: [[ADD:%.*]] = fadd float [[ARG]], [[ARG]]
; CHECK-NEXT: ret float [[ADD]]
@@ -754,7 +754,7 @@ define float @fadd_double_no_nopinf_pnorm(float noundef nofpclass(pinf pnorm) %a
}
define float @fadd_double_no_noninf_nnorm(float noundef nofpclass(ninf nnorm) %arg) {
-; CHECK-LABEL: define noundef float @fadd_double_no_noninf_nnorm(
+; CHECK-LABEL: define noundef nofpclass(ninf) float @fadd_double_no_noninf_nnorm(
; CHECK-SAME: float noundef nofpclass(ninf nnorm) [[ARG:%.*]]) #[[ATTR0]] {
; CHECK-NEXT: [[ADD:%.*]] = fadd float [[ARG]], [[ARG]]
; CHECK-NEXT: ret float [[ADD]]
@@ -764,7 +764,7 @@ define float @fadd_double_no_noninf_nnorm(float noundef nofpclass(ninf nnorm) %a
}
define float @fadd_double_no_pnorm_psub(float noundef nofpclass(pnorm psub) %arg) {
-; CHECK-LABEL: define noundef float @fadd_double_no_pnorm_psub(
+; CHECK-LABEL: define noundef nofpclass(psub pnorm) float @fadd_double_no_pnorm_psub(
; CHECK-SAME: float noundef nofpclass(psub pnorm) [[ARG:%.*]]) #[[ATTR0]] {
; CHECK-NEXT: [[ADD:%.*]] = fadd float [[ARG]], [[ARG]]
; CHECK-NEXT: ret float [[ADD]]
@@ -774,7 +774,7 @@ define float @fadd_double_no_pnorm_psub(float noundef nofpclass(pnorm psub) %arg
}
define float @fadd_double_no_nnorm_nsub(float noundef nofpclass(nnorm nsub) %arg) {
-; CHECK-LABEL: define noundef float @fadd_double_no_nnorm_nsub(
+; CHECK-LABEL: define noundef nofpclass(nsub nnorm) float @fadd_double_no_nnorm_nsub(
; CHECK-SAME: float noundef nofpclass(nsub nnorm) [[ARG:%.*]]) #[[ATTR0]] {
; CHECK-NEXT: [[ADD:%.*]] = fadd float [[ARG]], [[ARG]]
; CHECK-NEXT: ret float [[ADD]]
@@ -784,7 +784,7 @@ define float @fadd_double_no_nnorm_nsub(float noundef nofpclass(nnorm nsub) %arg
}
define float @fadd_double_no_nopsub_pzero(float noundef nofpclass(psub pzero) %arg) {
-; CHECK-LABEL: define noundef nofpclass(pzero) float @fadd_double_no_nopsub_pzero(
+; CHECK-LABEL: define noundef nofpclass(pzero psub) float @fadd_double_no_nopsub_pzero(
; CHECK-SAME: float noundef nofpclass(pzero psub) [[ARG:%.*]]) #[[ATTR0]] {
; CHECK-NEXT: [[ADD:%.*]] = fadd float [[ARG]], [[ARG]]
; CHECK-NEXT: ret float [[ADD]]
@@ -794,7 +794,7 @@ define float @fadd_double_no_nopsub_pzero(float noundef nofpclass(psub pzero) %a
}
define float @fadd_double_no_nonsub_nzero(float noundef nofpclass(nsub nzero) %arg) {
-; CHECK-LABEL: define noundef nofpclass(nzero) float @fadd_double_no_nonsub_nzero(
+; CHECK-LABEL: define noundef nofpclass(nzero nsub) float @fadd_double_no_nonsub_nzero(
; CHECK-SAME: float noundef nofpclass(nzero nsub) [[ARG:%.*]]) #[[ATTR0]] {
; CHECK-NEXT: [[ADD:%.*]] = fadd float [[ARG]], [[ARG]]
; CHECK-NEXT: ret float [[ADD]]
@@ -804,7 +804,7 @@ define float @fadd_double_no_nonsub_nzero(float noundef nofpclass(nsub nzero) %a
}
define float @fadd_double_no_nopsub_pzero__ieee_daz(float noundef nofpclass(psub pzero) %arg) #2 {
-; CHECK-LABEL: define noundef nofpclass(pzero) float @fadd_double_no_nopsub_pzero__ieee_daz(
+; CHECK-LABEL: define noundef nofpclass(pzero psub) float @fadd_double_no_nopsub_pzero__ieee_daz(
; CHECK-SAME: float noundef nofpclass(pzero psub) [[ARG:%.*]]) #[[ATTR4]] {
; CHECK-NEXT: [[ADD:%.*]] = fadd float [[ARG]], [[ARG]]
; CHECK-NEXT: ret float [[ADD]]
@@ -814,7 +814,7 @@ define float @fadd_double_no_nopsub_pzero__ieee_daz(float noundef nofpclass(psub
}
define float @fadd_double_no_nopsub_pzero__ftz_daz(float noundef nofpclass(psub pzero) %arg) #0 {
-; CHECK-LABEL: define noundef nofpclass(pzero) float @fadd_double_no_nopsub_pzero__ftz_daz(
+; CHECK-LABEL: define noundef nofpclass(pzero psub) float @fadd_double_no_nopsub_pzero__ftz_daz(
; CHECK-SAME: float noundef nofpclass(pzero psub) [[ARG:%.*]]) #[[ATTR1]] {
; CHECK-NEXT: [[ADD:%.*]] = fadd float [[ARG]], [[ARG]]
; CHECK-NEXT: ret float [[ADD]]
@@ -824,7 +824,7 @@ define float @fadd_double_no_nopsub_pzero__ftz_daz(float noundef nofpclass(psub
}
define float @fadd_double_no_nonsub_nzero__ieee_daz(float noundef nofpclass(nsub nzero) %arg) #2 {
-; CHECK-LABEL: define noundef nofpclass(nzero) float @fadd_double_no_nonsub_nzero__ieee_daz(
+; CHECK-LABEL: define noundef nofpclass(nzero nsub) float @fadd_double_no_nonsub_nzero__ieee_daz(
; CHECK-SAME: float noundef nofpclass(nzero nsub) [[ARG:%.*]]) #[[ATTR4]] {
; CHECK-NEXT: [[ADD:%.*]] = fadd float [[ARG]], [[ARG]]
; CHECK-NEXT: ret float [[ADD]]
@@ -834,7 +834,7 @@ define float @fadd_double_no_nonsub_nzero__ieee_daz(float noundef nofpclass(nsub
}
define float @fadd_double_no_nonsub_nzero__ftz_daz(float noundef nofpclass(nsub nzero) %arg) #0 {
-; CHECK-LABEL: define noundef float @fadd_double_no_nonsub_nzero__ftz_daz(
+; CHECK-LABEL: define noundef nofpclass(nzero nsub) float @fadd_double_no_nonsub_nzero__ftz_daz(
; CHECK-SAME: float noundef nofpclass(nzero nsub) [[ARG:%.*]]) #[[ATTR1]] {
; CHECK-NEXT: [[ADD:%.*]] = fadd float [[ARG]], [[ARG]]
; CHECK-NEXT: ret float [[ADD]]
@@ -844,7 +844,7 @@ define float @fadd_double_no_nonsub_nzero__ftz_daz(float noundef nofpclass(nsub
}
define float @fadd_double_no_nopsub_pzero__ieee_dynamic(float noundef nofpclass(psub pzero) %arg) #9 {
-; CHECK-LABEL: define noundef float @fadd_double_no_nopsub_pzero__ieee_dynamic(
+; CHECK-LABEL: define noundef nofpclass(psub) float @fadd_double_no_nopsub_pzero__ieee_dynamic(
; CHECK-SAME: float noundef nofpclass(pzero psub) [[ARG:%.*]]) #[[ATTR8:[0-9]+]] {
; CHECK-NEXT: [[ADD:%.*]] = fadd float [[ARG]], [[ARG]]
; CHECK-NEXT: ret float [[ADD]]
@@ -854,7 +854,7 @@ define float @fadd_double_no_nopsub_pzero__ieee_dynamic(float noundef nofpclass(
}
define float @fadd_double_no_nonsub_nzero__ieee_dynamic(float noundef nofpclass(nsub nzero) %arg) #9 {
-; CHECK-LABEL: define noundef nofpclass(nzero) float @fadd_double_no_nonsub_nzero__ieee_dynamic(
+; CHECK-LABEL: define noundef nofpclass(nzero nsub) float @fadd_double_no_nonsub_nzero__ieee_dynamic(
; CHECK-SAME: float noundef nofpclass(nzero nsub) [[ARG:%.*]]) #[[ATTR8]] {
; CHECK-NEXT: [[ADD:%.*]] = fadd float [[ARG]], [[ARG]]
; CHECK-NEXT: ret float [[ADD]]
@@ -1135,8 +1135,8 @@ define float @fadd_double_no_nzero(float noundef nofpclass(nzero) %arg) {
}
define float @fadd_double_no_nzero_dapz_dapz(float noundef nofpclass(nzero) %arg) #10 {
-; CHECK-LABEL: define noundef nofpclass(nzero) float @fadd_double_no_nzero_dapz_dapz(
-; CHECK-SAME: float noundef nofpclass(nzero) [[ARG:%.*]]) #[[ATTR0]] {
+; CHECK-LABEL: define noundef float @fadd_double_no_nzero_dapz_dapz(
+; CHECK-SAME: float noundef nofpclass(nzero) [[ARG:%.*]]) #[[ATTR9:[0-9]+]] {
; CHECK-NEXT: [[ADD:%.*]] = fadd float [[ARG]], [[ARG]]
; CHECK-NEXT: ret float [[ADD]]
;
@@ -1190,7 +1190,7 @@ define float @fadd_double_no_zero__output_only_is_ftz(float noundef nofpclass(ze
; still be flushed.
define float @fadd_double_no_zero__output_only_is_dynamic(float noundef nofpclass(zero) %arg) #8 {
; CHECK-LABEL: define noundef float @fadd_double_no_zero__output_only_is_dynamic(
-; CHECK-SAME: float noundef nofpclass(zero) [[ARG:%.*]]) #[[ATTR9:[0-9]+]] {
+; CHECK-SAME: float noundef nofpclass(zero) [[ARG:%.*]]) #[[ATTR10:[0-9]+]] {
; CHECK-NEXT: [[ADD:%.*]] = fadd float [[ARG]], [[ARG]]
; CHECK-NEXT: ret float [[ADD]]
;
@@ -1211,7 +1211,7 @@ define float @fadd_double_no_zero__output_only_is_ftpz(float noundef nofpclass(z
}
define float @fadd_double_no_zero_or_nsub__output_only_is_ftpz(float noundef nofpclass(zero nsub) %arg) #4 {
-; CHECK-LABEL: define noundef nofpclass(nzero) float @fadd_double_no_zero_or_nsub__output_only_is_ftpz(
+; CHECK-LABEL: define noundef nofpclass(nzero nsub) float @fadd_double_no_zero_or_nsub__output_only_is_ftpz(
; CHECK-SAME: float noundef nofpclass(zero nsub) [[ARG:%.*]]) #[[ATTR5]] {
; CHECK-NEXT: [[ADD:%.*]] = fadd float [[ARG]], [[ARG]]
; CHECK-NEXT: ret float [[ADD]]
@@ -1221,7 +1221,7 @@ define float @fadd_double_no_zero_or_nsub__output_only_is_ftpz(float noundef nof
}
define float @fadd_double_no_zero_or_psub__output_only_is_ftpz(float noundef nofpclass(zero psub) %arg) #4 {
-; CHECK-LABEL: define noundef nofpclass(nzero) float @fadd_double_no_zero_or_psub__output_only_is_ftpz(
+; CHECK-LABEL: define noundef nofpclass(nzero psub) float @fadd_double_no_zero_or_psub__output_only_is_ftpz(
; CHECK-SAME: float noundef nofpclass(zero psub) [[ARG:%.*]]) #[[ATTR5]] {
; CHECK-NEXT: [[ADD:%.*]] = fadd float [[ARG]], [[ARG]]
; CHECK-NEXT: ret float [[ADD]]
@@ -1231,7 +1231,7 @@ define float @fadd_double_no_zero_or_psub__output_only_is_ftpz(float noundef nof
}
define float @fadd_double_no_zero_or_sub__output_only_is_ftpz(float noundef nofpclass(zero sub) %arg) #4 {
-; CHECK-LABEL: define noundef nofpclass(zero) float @fadd_double_no_zero_or_sub__output_only_is_ftpz(
+; CHECK-LABEL: define noundef nofpclass(zero sub) float @fadd_double_no_zero_or_sub__output_only_is_ftpz(
; CHECK-SAME: float noundef nofpclass(zero sub) [[ARG:%.*]]) #[[ATTR5]] {
; CHECK-NEXT: [[ADD:%.*]] = fadd float [[ARG]], [[ARG]]
; CHECK-NEXT: ret float [[ADD]]
@@ -1284,6 +1284,68 @@ define half @known_negative_normal_or_inf__fadd__known_negative_or_nan(half nofp
ret half %add
}
+define float @fsub__lhs_nzero__rhs_psub(float nofpclass(nan inf pzero sub norm) %lhs, float nofpclass(nan inf zero nsub norm) %rhs) {
+; CHECK-LABEL: define nofpclass(nan pinf nzero psub pnorm) float @fsub__lhs_nzero__rhs_psub(
+; CHECK-SAME: float nofpclass(nan inf pzero sub norm) [[LHS:%.*]], float nofpclass(nan inf zero nsub norm) [[RHS:%.*]]) #[[ATTR0]] {
+; CHECK-NEXT: [[SUB:%.*]] = fsub float [[LHS]], [[RHS]]
+; CHECK-NEXT: ret float [[SUB]]
+;
+ %sub = fsub float %lhs, %rhs
+ ret float %sub
+}
+
+; We shall not rule out negative zero: -0.0 - dapz(psub) == -0.0 - +0.0 == -0.0
+define float @fsub__lhs_nzero__rhs_psub__mode_ieee_dapz(float nofpclass(nan inf pzero sub norm) %lhs, float nofpclass(nan inf zero nsub norm) %rhs) #5 {
+; CHECK-LABEL: define nofpclass(nan pinf psub pnorm) float @fsub__lhs_nzero__rhs_psub__mode_ieee_dapz(
+; CHECK-SAME: float nofpclass(nan inf pzero sub norm) [[LHS:%.*]], float nofpclass(nan inf zero nsub norm) [[RHS:%.*]]) #[[ATTR7]] {
+; CHECK-NEXT: [[SUB:%.*]] = fsub float [[LHS]], [[RHS]]
+; CHECK-NEXT: ret float [[SUB]]
+;
+ %sub = fsub float %lhs, %rhs
+ ret float %sub
+}
+
+; We shall not rule out negative zero: -0.0 - daz(psub) == -0.0 - +0.0 == -0.0
+define float @fsub__lhs_nzero__rhs_psub__mode_ieee_daz(float nofpclass(nan inf pzero sub norm) %lhs, float nofpclass(nan inf zero nsub norm) %rhs) #2 {
+; CHECK-LABEL: define nofpclass(nan pinf psub pnorm) float @fsub__lhs_nzero__rhs_psub__mode_ieee_daz(
+; CHECK-SAME: float nofpclass(nan inf pzero sub norm) [[LHS:%.*]], float nofpclass(nan inf zero nsub norm) [[RHS:%.*]]) #[[ATTR4]] {
+; CHECK-NEXT: [[SUB:%.*]] = fsub float [[LHS]], [[RHS]]
+; CHECK-NEXT: ret float [[SUB]]
+;
+ %sub = fsub float %lhs, %rhs
+ ret float %sub
+}
+
+define float @fsub__lhs_nzero__rhs_psub__mode_ftpz_dapz(float nofpclass(nan inf pzero sub norm) %lhs, float nofpclass(nan inf zero nsub norm) %rhs) #3 {
+; CHECK-LABEL: define nofpclass(nan pinf psub pnorm) float @fsub__lhs_nzero__rhs_psub__mode_ftpz_dapz(
+; CHECK-SAME: float nofpclass(nan inf pzero sub norm) [[LHS:%.*]], float nofpclass(nan inf zero nsub norm) [[RHS:%.*]]) #[[ATTR2]] {
+; CHECK-NEXT: [[SUB:%.*]] = fsub float [[LHS]], [[RHS]]
+; CHECK-NEXT: ret float [[SUB]]
+;
+ %sub = fsub float %lhs, %rhs
+ ret float %sub
+}
+
+define float @fsub__lhs_nzero__rhs_psub__mode_dynamic_dapz(float nofpclass(nan inf pzero sub norm) %lhs, float nofpclass(nan inf zero nsub norm) %rhs) #10 {
+; CHECK-LABEL: define nofpclass(nan pinf psub pnorm) float @fsub__lhs_nzero__rhs_psub__mode_dynamic_dapz(
+; CHECK-SAME: float nofpclass(nan inf pzero sub norm) [[LHS:%.*]], float nofpclass(nan inf zero nsub norm) [[RHS:%.*]]) #[[ATTR9]] {
+; CHECK-NEXT: [[SUB:%.*]] = fsub float [[LHS]], [[RHS]]
+; CHECK-NEXT: ret float [[SUB]]
+;
+ %sub = fsub float %lhs, %rhs
+ ret float %sub
+}
+
+define float @fsub__lhs_nzero__rhs_psub__mode_dynamic_dynamic(float nofpclass(nan inf pzero sub norm) %lhs, float nofpclass(nan inf zero nsub norm) %rhs) #6 {
+; CHECK-LABEL: define nofpclass(nan pinf psub pnorm) float @fsub__lhs_nzero__rhs_psub__mode_dynamic_dynamic(
+; CHECK-SAME: float nofpclass(nan inf pzero sub norm) [[LHS:%.*]], float nofpclass(nan inf zero nsub norm) [[RHS:%.*]]) #[[ATTR3]] {
+; CHECK-NEXT: [[SUB:%.*]] = fsub float [[LHS]], [[RHS]]
+; CHECK-NEXT: ret float [[SUB]]
+;
+ %sub = fsub float %lhs, %rhs
+ ret float %sub
+}
+
attributes #0 = { denormal_fpenv(preservesign) }
attributes #1 = { denormal_fpenv(preservesign|ieee) }
attributes #2 = { denormal_fpenv(ieee|preservesign) }
@@ -1294,3 +1356,4 @@ attributes #6 = { denormal_fpenv(dynamic) }
attributes #7 = { denormal_fpenv(preservesign|ieee) }
attributes #8 = { denormal_fpenv(dynamic|ieee) }
attributes #9 = { denormal_fpenv(ieee|dynamic) }
+attributes #10 = { denormal_fpenv(dynamic|positivezero) }
diff --git a/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-fadd.ll b/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-fadd.ll
index 12bc61ef4ce390..0cd5f337218bcd 100644
--- a/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-fadd.ll
+++ b/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-fadd.ll
@@ -1638,7 +1638,7 @@ define nofpclass(norm sub) half @demand_zero_select_sub_source__fadd_self__ftz_d
; CHECK-LABEL: define nofpclass(sub norm) half @demand_zero_select_sub_source__fadd_self__ftz_daz(
; CHECK-SAME: i1 [[COND:%.*]], half noundef [[UNKNOWN:%.*]]) #[[ATTR0]] {
; CHECK-NEXT: [[SUB:%.*]] = call noundef half @returns_sub()
-; CHECK-NEXT: [[RESULT:%.*]] = fadd nnan half [[SUB]], [[SUB]]
+; CHECK-NEXT: [[RESULT:%.*]] = fadd nnan ninf half [[SUB]], [[SUB]]
; CHECK-NEXT: ret half [[RESULT]]
;
%sub = call noundef half @returns_sub()
@@ -1651,8 +1651,7 @@ define nofpclass(norm sub pzero) half @demand_nzero_select_nsub_source__fadd_sel
; CHECK-LABEL: define nofpclass(pzero sub norm) half @demand_nzero_select_nsub_source__fadd_self__ftz_daz(
; CHECK-SAME: i1 [[COND:%.*]], half noundef [[UNKNOWN:%.*]]) #[[ATTR0]] {
; CHECK-NEXT: [[NSUB:%.*]] = call noundef half @returns_nsub()
-; CHECK-NEXT: [[RESULT:%.*]] = fadd nnan half [[NSUB]], [[NSUB]]
-; CHECK-NEXT: ret half [[RESULT]]
+; CHECK-NEXT: ret half -0.000000e+00
;
%nsub = call noundef half @returns_nsub()
%select = select i1 %cond, half %unknown, half %nsub
@@ -1676,8 +1675,7 @@ define nofpclass(norm sub nzero) half @demand_pzero_select_psub_source__fadd_sel
; CHECK-LABEL: define nofpclass(nzero sub norm) half @demand_pzero_select_psub_source__fadd_self__ftz_daz(
; CHECK-SAME: i1 [[COND:%.*]], half noundef [[UNKNOWN:%.*]]) #[[ATTR0]] {
; CHECK-NEXT: [[PSUB:%.*]] = call noundef half @returns_psub()
-; CHECK-NEXT: [[RESULT:%.*]] = fadd nnan half [[PSUB]], [[PSUB]]
-; CHECK-NEXT: ret half [[RESULT]]
+; CHECK-NEXT: ret half 0.000000e+00
;
%psub = call noundef half @returns_psub()
%select = select i1 %cond, half %unknown, half %psub
@@ -1702,7 +1700,7 @@ define nofpclass(norm sub) half @demand_zero_select_sub_source__fadd_self__ieee_
; CHECK-LABEL: define nofpclass(sub norm) half @demand_zero_select_sub_source__fadd_self__ieee_daz(
; CHECK-SAME: i1 [[COND:%.*]], half noundef [[UNKNOWN:%.*]]) #[[ATTR2:[0-9]+]] {
; CHECK-NEXT: [[SUB:%.*]] = call noundef half @returns_sub()
-; CHECK-NEXT: [[RESULT:%.*]] = fadd nnan half [[SUB]], [[SUB]]
+; CHECK-NEXT: [[RESULT:%.*]] = fadd nnan ninf half [[SUB]], [[SUB]]
; CHECK-NEXT: ret half [[RESULT]]
;
%sub = call noundef half @returns_sub()
@@ -1715,8 +1713,7 @@ define nofpclass(norm sub pzero) half @demand_nzero_select_nsub_source__fadd_sel
; CHECK-LABEL: define nofpclass(pzero sub norm) half @demand_nzero_select_nsub_source__fadd_self__ieee_daz(
; CHECK-SAME: i1 [[COND:%.*]], half noundef [[UNKNOWN:%.*]]) #[[ATTR2]] {
; CHECK-NEXT: [[NSUB:%.*]] = call noundef half @returns_nsub()
-; CHECK-NEXT: [[RESULT:%.*]] = fadd nnan half [[NSUB]], [[NSUB]]
-; CHECK-NEXT: ret half [[RESULT]]
+; CHECK-NEXT: ret half -0.000000e+00
;
%nsub = call noundef half @returns_nsub()
%select = select i1 %cond, half %unknown, half %nsub
@@ -1740,8 +1737,7 @@ define nofpclass(norm sub nzero) half @demand_pzero_select_psub_source__fadd_sel
; CHECK-LABEL: define nofpclass(nzero sub norm) half @demand_pzero_select_psub_source__fadd_self__ieee_daz(
; CHECK-SAME: i1 [[COND:%.*]], half noundef [[UNKNOWN:%.*]]) #[[ATTR2]] {
; CHECK-NEXT: [[PSUB:%.*]] = call noundef half @returns_psub()
-; CHECK-NEXT: [[RESULT:%.*]] = fadd nnan half [[PSUB]], [[PSUB]]
-; CHECK-NEXT: ret half [[RESULT]]
+; CHECK-NEXT: ret half 0.000000e+00
;
%psub = call noundef half @returns_psub()
%select = select i1 %cond, half %unknown, half %psub
@@ -1766,7 +1762,7 @@ define nofpclass(norm sub) half @demand_zero_select_sub_source__fadd_self__ftz_i
; CHECK-LABEL: define nofpclass(sub norm) half @demand_zero_select_sub_source__fadd_self__ftz_ieee(
; CHECK-SAME: i1 [[COND:%.*]], half noundef [[UNKNOWN:%.*]]) #[[ATTR3:[0-9]+]] {
; CHECK-NEXT: [[SUB:%.*]] = call noundef half @returns_sub()
-; CHECK-NEXT: [[RESULT:%.*]] = fadd nnan half [[SUB]], [[SUB]]
+; CHECK-NEXT: [[RESULT:%.*]] = fadd nnan ninf half [[SUB]], [[SUB]]
; CHECK-NEXT: ret half [[RESULT]]
;
%sub = call noundef half @returns_sub()
@@ -1779,8 +1775,7 @@ define nofpclass(norm sub pzero) half @demand_nzero_select_nsub_source__fadd_sel
; CHECK-LABEL: define nofpclass(pzero sub norm) half @demand_nzero_select_nsub_source__fadd_self__ftz_ieee(
; CHECK-SAME: i1 [[COND:%.*]], half noundef [[UNKNOWN:%.*]]) #[[ATTR3]] {
; CHECK-NEXT: [[NSUB:%.*]] = call noundef half @returns_nsub()
-; CHECK-NEXT: [[RESULT:%.*]] = fadd nnan half [[NSUB]], [[NSUB]]
-; CHECK-NEXT: ret half [[RESULT]]
+; CHECK-NEXT: ret half -0.000000e+00
;
%nsub = call noundef half @returns_nsub()
%select = select i1 %cond, half %unknown, half %nsub
@@ -1804,8 +1799,7 @@ define nofpclass(norm sub nzero) half @demand_pzero_select_psub_source__fadd_sel
; CHECK-LABEL: define nofpclass(nzero sub norm) half @demand_pzero_select_psub_source__fadd_self__ftz_ieee(
; CHECK-SAME: i1 [[COND:%.*]], half noundef [[UNKNOWN:%.*]]) #[[ATTR3]] {
; CHECK-NEXT: [[PSUB:%.*]] = call noundef half @returns_psub()
-; CHECK-NEXT: [[RESULT:%.*]] = fadd nnan half [[PSUB]], [[PSUB]]
-; CHECK-NEXT: ret half [[RESULT]]
+; CHECK-NEXT: ret half 0.000000e+00
;
%psub = call noundef half @returns_psub()
%select = select i1 %cond, half %unknown, half %psub
@@ -1830,7 +1824,7 @@ define nofpclass(norm sub) half @demand_zero_select_sub_source__fadd_self__dynam
; CHECK-LABEL: define nofpclass(sub norm) half @demand_zero_select_sub_source__fadd_self__dynamic_dynamic(
; CHECK-SAME: i1 [[COND:%.*]], half noundef [[UNKNOWN:%.*]]) #[[ATTR1]] {
; CHECK-NEXT: [[SUB:%.*]] = call noundef half @returns_sub()
-; CHECK-NEXT: [[RESULT:%.*]] = fadd nnan half [[SUB]], [[SUB]]
+; CHECK-NEXT: [[RESULT:%.*]] = fadd nnan ninf half [[SUB]], [[SUB]]
; CHECK-NEXT: ret half [[RESULT]]
;
%sub = call noundef half @returns_sub()
@@ -1843,8 +1837,7 @@ define nofpclass(norm sub pzero) half @demand_nzero_select_nsub_source__fadd_sel
; CHECK-LABEL: define nofpclass(pzero sub norm) half @demand_nzero_select_nsub_source__fadd_self__dynamic_dynamic(
; CHECK-SAME: i1 [[COND:%.*]], half noundef [[UNKNOWN:%.*]]) #[[ATTR1]] {
; CHECK-NEXT: [[NSUB:%.*]] = call noundef half @returns_nsub()
-; CHECK-NEXT: [[RESULT:%.*]] = fadd nnan half [[NSUB]], [[NSUB]]
-; CHECK-NEXT: ret half [[RESULT]]
+; CHECK-NEXT: ret half -0.000000e+00
;
%nsub = call noundef half @returns_nsub()
%select = select i1 %cond, half %unknown, half %nsub
@@ -1868,8 +1861,7 @@ define nofpclass(norm sub nzero) half @demand_pzero_select_psub_source__fadd_sel
; CHECK-LABEL: define nofpclass(nzero sub norm) half @demand_pzero_select_psub_source__fadd_self__dynamic_dynamic(
; CHECK-SAME: i1 [[COND:%.*]], half noundef [[UNKNOWN:%.*]]) #[[ATTR1]] {
; CHECK-NEXT: [[PSUB:%.*]] = call noundef half @returns_psub()
-; CHECK-NEXT: [[RESULT:%.*]] = fadd nnan half [[PSUB]], [[PSUB]]
-; CHECK-NEXT: ret half [[RESULT]]
+; CHECK-NEXT: ret half 0.000000e+00
;
%psub = call noundef half @returns_psub()
%select = select i1 %cond, half %unknown, half %psub
@@ -1881,8 +1873,7 @@ define nofpclass(norm sub nzero) half @demand_pzero_select_nsub_source__fadd_sel
; CHECK-LABEL: define nofpclass(nzero sub norm) half @demand_pzero_select_nsub_source__fadd_self__dynamic_dynamic(
; CHECK-SAME: i1 [[COND:%.*]], half noundef [[UNKNOWN:%.*]]) #[[ATTR1]] {
; CHECK-NEXT: [[NSUB:%.*]] = call noundef half @returns_nsub()
-; CHECK-NEXT: [[RESULT:%.*]] = fadd nnan half [[NSUB]], [[NSUB]]
-; CHECK-NEXT: ret half [[RESULT]]
+; CHECK-NEXT: ret half 0.000000e+00
;
%nsub = call noundef half @returns_nsub()
%select = select i1 %cond, half %unknown, half %nsub
@@ -1895,8 +1886,7 @@ define nofpclass(norm sub) half @demand_zero_select_sub_source__fadd_self__ieee_
; CHECK-LABEL: define nofpclass(sub norm) half @demand_zero_select_sub_source__fadd_self__ieee_dapz(
; CHECK-SAME: i1 [[COND:%.*]], half noundef [[UNKNOWN:%.*]]) #[[ATTR4:[0-9]+]] {
; CHECK-NEXT: [[SUB:%.*]] = call noundef half @returns_sub()
-; CHECK-NEXT: [[RESULT:%.*]] = fadd nnan half [[SUB]], [[SUB]]
-; CHECK-NEXT: ret half [[RESULT]]
+; CHECK-NEXT: ret half 0.000000e+00
;
%sub = call noundef half @returns_sub()
%select = select i1 %cond, half %unknown, half %sub
@@ -1908,7 +1898,7 @@ define nofpclass(norm sub pzero) half @demand_nzero_select_nsub_source__fadd_sel
; CHECK-LABEL: define nofpclass(pzero sub norm) half @demand_nzero_select_nsub_source__fadd_self__ieee_dapz(
; CHECK-SAME: i1 [[COND:%.*]], half noundef [[UNKNOWN:%.*]]) #[[ATTR4]] {
; CHECK-NEXT: [[NSUB:%.*]] = call noundef half @returns_nsub()
-; CHECK-NEXT: ret half -inf
+; CHECK-NEXT: ret half poison
;
%nsub = call noundef half @returns_nsub()
%select = select i1 %cond, half %unknown, half %nsub
@@ -1932,8 +1922,7 @@ define nofpclass(norm sub nzero) half @demand_pzero_select_psub_source__fadd_sel
; CHECK-LABEL: define nofpclass(nzero sub norm) half @demand_pzero_select_psub_source__fadd_self__ieee_dapz(
; CHECK-SAME: i1 [[COND:%.*]], half noundef [[UNKNOWN:%.*]]) #[[ATTR4]] {
; CHECK-NEXT: [[PSUB:%.*]] = call noundef half @returns_psub()
-; CHECK-NEXT: [[RESULT:%.*]] = fadd nnan half [[PSUB]], [[PSUB]]
-; CHECK-NEXT: ret half [[RESULT]]
+; CHECK-NEXT: ret half 0.000000e+00
;
%psub = call noundef half @returns_psub()
%select = select i1 %cond, half %unknown, half %psub
@@ -1946,8 +1935,7 @@ define nofpclass(norm sub nzero) half @demand_pzero_select_nsub_source__fadd_sel
; CHECK-LABEL: define nofpclass(nzero sub norm) half @demand_pzero_select_nsub_source__fadd_self__ieee_dapz(
; CHECK-SAME: i1 [[COND:%.*]], half noundef [[UNKNOWN:%.*]]) #[[ATTR4]] {
; CHECK-NEXT: [[NSUB:%.*]] = call noundef half @returns_nsub()
-; CHECK-NEXT: [[RESULT:%.*]] = fadd nnan half [[NSUB]], [[NSUB]]
-; CHECK-NEXT: ret half [[RESULT]]
+; CHECK-NEXT: ret half 0.000000e+00
;
%nsub = call noundef half @returns_nsub()
%select = select i1 %cond, half %unknown, half %nsub
@@ -1960,8 +1948,7 @@ define nofpclass(norm sub) half @demand_zero_select_sub_source__fadd_self__ftpz_
; CHECK-LABEL: define nofpclass(sub norm) half @demand_zero_select_sub_source__fadd_self__ftpz_ieee(
; CHECK-SAME: i1 [[COND:%.*]], half noundef [[UNKNOWN:%.*]]) #[[ATTR5:[0-9]+]] {
; CHECK-NEXT: [[SUB:%.*]] = call noundef half @returns_sub()
-; CHECK-NEXT: [[RESULT:%.*]] = fadd nnan half [[SUB]], [[SUB]]
-; CHECK-NEXT: ret half [[RESULT]]
+; CHECK-NEXT: ret half 0.000000e+00
;
%sub = call noundef half @returns_sub()
%select = select i1 %cond, half %unknown, half %sub
@@ -1973,7 +1960,7 @@ define nofpclass(norm sub pzero) half @demand_nzero_select_nsub_source__fadd_sel
; CHECK-LABEL: define nofpclass(pzero sub norm) half @demand_nzero_select_nsub_source__fadd_self__ftpz_ieee(
; CHECK-SAME: i1 [[COND:%.*]], half noundef [[UNKNOWN:%.*]]) #[[ATTR5]] {
; CHECK-NEXT: [[NSUB:%.*]] = call noundef half @returns_nsub()
-; CHECK-NEXT: ret half -inf
+; CHECK-NEXT: ret half poison
;
%nsub = call noundef half @returns_nsub()
%select = select i1 %cond, half %unknown, half %nsub
@@ -1997,8 +1984,7 @@ define nofpclass(norm sub nzero) half @demand_pzero_select_psub_source__fadd_sel
; CHECK-LABEL: define nofpclass(nzero sub norm) half @demand_pzero_select_psub_source__fadd_self__ftpz_ieee(
; CHECK-SAME: i1 [[COND:%.*]], half noundef [[UNKNOWN:%.*]]) #[[ATTR5]] {
; CHECK-NEXT: [[PSUB:%.*]] = call noundef half @returns_psub()
-; CHECK-NEXT: [[RESULT:%.*]] = fadd nnan half [[PSUB]], [[PSUB]]
-; CHECK-NEXT: ret half [[RESULT]]
+; CHECK-NEXT: ret half 0.000000e+00
;
%psub = call noundef half @returns_psub()
%select = select i1 %cond, half %unknown, half %psub
@@ -2011,8 +1997,7 @@ define nofpclass(norm sub nzero) half @demand_pzero_select_nsub_source__fadd_sel
; CHECK-LABEL: define nofpclass(nzero sub norm) half @demand_pzero_select_nsub_source__fadd_self__ftpz_ieee(
; CHECK-SAME: i1 [[COND:%.*]], half noundef [[UNKNOWN:%.*]]) #[[ATTR5]] {
; CHECK-NEXT: [[NSUB:%.*]] = call noundef half @returns_nsub()
-; CHECK-NEXT: [[RESULT:%.*]] = fadd nnan half [[NSUB]], [[NSUB]]
-; CHECK-NEXT: ret half [[RESULT]]
+; CHECK-NEXT: ret half 0.000000e+00
;
%nsub = call noundef half @returns_nsub()
%select = select i1 %cond, half %unknown, half %nsub
More information about the llvm-commits
mailing list