[llvm] ValueTracking: Fix handling of fadd with mixed denormal modes (PR #175454)
via llvm-commits
llvm-commits at lists.llvm.org
Sun Jan 11 12:19:32 PST 2026
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-llvm-analysis
Author: Matt Arsenault (arsenm)
<details>
<summary>Changes</summary>
Fix case where the input mode is IEEE, the output flushes, and the
input could be subnormal. Also improves accuracy with positive zero
case.
---
Full diff: https://github.com/llvm/llvm-project/pull/175454.diff
2 Files Affected:
- (modified) llvm/lib/Analysis/ValueTracking.cpp (+4-1)
- (modified) llvm/test/Transforms/Attributor/nofpclass.ll (+45-1)
``````````diff
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index dbb44c8828545..5340d41dd3683 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -5560,7 +5560,10 @@ void computeKnownFPClass(const Value *V, const APInt &DemandedElts,
// Doubling 0 will give the same 0.
if (SelfAdd && KnownRHS.isKnownNeverLogicalPosZero(Mode) &&
(Mode.Output == DenormalMode::IEEE ||
- Mode.Output == DenormalMode::PreserveSign))
+ (Mode.Output == DenormalMode::PreserveSign &&
+ KnownRHS.isKnownNeverPosSubnormal()) ||
+ (Mode.Output == DenormalMode::PositiveZero &&
+ KnownRHS.isKnownNeverSubnormal())))
Known.knownNot(fcPosZero);
// (fadd x, 0.0) is guaranteed to return +0.0, not -0.0.
diff --git a/llvm/test/Transforms/Attributor/nofpclass.ll b/llvm/test/Transforms/Attributor/nofpclass.ll
index bb0b1930ffe58..4260c4ff1115a 100644
--- a/llvm/test/Transforms/Attributor/nofpclass.ll
+++ b/llvm/test/Transforms/Attributor/nofpclass.ll
@@ -3607,7 +3607,7 @@ define float @fadd_double_no_pzero_maybe_undef(float nofpclass(pzero) %arg) {
; still be flushed.
define float @fadd_double_no_zero__output_only_is_ftz(float noundef nofpclass(zero) %arg) #7 {
; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
-; CHECK-LABEL: define noundef nofpclass(pzero) float @fadd_double_no_zero__output_only_is_ftz
+; CHECK-LABEL: define noundef float @fadd_double_no_zero__output_only_is_ftz
; CHECK-SAME: (float noundef nofpclass(zero) [[ARG:%.*]]) #[[ATTR13]] {
; CHECK-NEXT: [[ADD:%.*]] = fadd float [[ARG]], [[ARG]]
; CHECK-NEXT: ret float [[ADD]]
@@ -3675,6 +3675,50 @@ define float @assume_returned_arg(float %arg) {
ret float %arg
}
+define float @fadd_double_no_zero__output_only_is_ftpz(float noundef nofpclass(zero) %arg) #4 {
+; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
+; CHECK-LABEL: define noundef nofpclass(nzero) float @fadd_double_no_zero__output_only_is_ftpz
+; CHECK-SAME: (float noundef nofpclass(zero) [[ARG:%.*]]) #[[ATTR12]] {
+; CHECK-NEXT: [[ADD:%.*]] = fadd float [[ARG]], [[ARG]]
+; CHECK-NEXT: ret float [[ADD]]
+;
+ %add = fadd float %arg, %arg
+ ret float %add
+}
+
+define float @fadd_double_no_zero_or_nsub__output_only_is_ftpz(float noundef nofpclass(zero nsub) %arg) #4 {
+; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
+; CHECK-LABEL: define noundef nofpclass(nzero) float @fadd_double_no_zero_or_nsub__output_only_is_ftpz
+; CHECK-SAME: (float noundef nofpclass(zero nsub) [[ARG:%.*]]) #[[ATTR12]] {
+; CHECK-NEXT: [[ADD:%.*]] = fadd float [[ARG]], [[ARG]]
+; CHECK-NEXT: ret float [[ADD]]
+;
+ %add = fadd float %arg, %arg
+ ret float %add
+}
+
+define float @fadd_double_no_zero_or_psub__output_only_is_ftpz(float noundef nofpclass(zero psub) %arg) #4 {
+; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
+; CHECK-LABEL: define noundef nofpclass(nzero) float @fadd_double_no_zero_or_psub__output_only_is_ftpz
+; CHECK-SAME: (float noundef nofpclass(zero psub) [[ARG:%.*]]) #[[ATTR12]] {
+; CHECK-NEXT: [[ADD:%.*]] = fadd float [[ARG]], [[ARG]]
+; CHECK-NEXT: ret float [[ADD]]
+;
+ %add = fadd float %arg, %arg
+ ret float %add
+}
+
+define float @fadd_double_no_zero_or_sub__output_only_is_ftpz(float noundef nofpclass(zero sub) %arg) #4 {
+; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
+; CHECK-LABEL: define noundef nofpclass(zero) float @fadd_double_no_zero_or_sub__output_only_is_ftpz
+; CHECK-SAME: (float noundef nofpclass(zero sub) [[ARG:%.*]]) #[[ATTR12]] {
+; CHECK-NEXT: [[ADD:%.*]] = fadd float [[ARG]], [[ARG]]
+; CHECK-NEXT: ret float [[ADD]]
+;
+ %add = fadd float %arg, %arg
+ ret float %add
+}
+
declare i64 @_Z13get_global_idj(i32 noundef)
attributes #0 = { "denormal-fp-math"="preserve-sign,preserve-sign" }
``````````
</details>
https://github.com/llvm/llvm-project/pull/175454
More information about the llvm-commits
mailing list