-
Notifications
You must be signed in to change notification settings - Fork 15.5k
ValueTracking: Improve accuracy of 0 handling with PreserveSign #173165
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: users/arsenm/valuetracking/add-more-canonicalize-knownfpclass-tests
Are you sure you want to change the base?
Conversation
If the source value is known not subnormal and not zero with the same sign, we can infer the result is also not zero with the same sign.
|
Warning This pull request is not mergeable via GitHub because a downstack PR is open. Once all requirements are satisfied, merge this PR as a stack on Graphite.
This stack of pull requests is managed by Graphite. Learn more about stacking. |
|
@llvm/pr-subscribers-llvm-analysis @llvm/pr-subscribers-llvm-transforms Author: Matt Arsenault (arsenm) ChangesIf the source value is known not subnormal and not zero with the Full diff: https://github.com/llvm/llvm-project/pull/173165.diff 2 Files Affected:
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index d3d2a3db66ddc..0321c08f55776 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -5308,6 +5308,14 @@ void computeKnownFPClass(const Value *V, const APInt &DemandedElts,
if (DenormMode.inputsAreZero() || DenormMode.outputsAreZero())
Known.knownNot(fcSubnormal);
+ if (DenormMode == DenormalMode::getPreserveSign()) {
+ if (KnownSrc.isKnownNever(fcPosZero | fcPosSubnormal))
+ Known.knownNot(fcPosZero);
+ if (KnownSrc.isKnownNever(fcNegZero | fcNegSubnormal))
+ Known.knownNot(fcNegZero);
+ break;
+ }
+
if (DenormMode.Input == DenormalMode::PositiveZero ||
(DenormMode.Output == DenormalMode::PositiveZero &&
DenormMode.Input == DenormalMode::IEEE))
diff --git a/llvm/test/Transforms/Attributor/nofpclass-canonicalize.ll b/llvm/test/Transforms/Attributor/nofpclass-canonicalize.ll
index 8a31bef83b68e..d1879cbb9add9 100644
--- a/llvm/test/Transforms/Attributor/nofpclass-canonicalize.ll
+++ b/llvm/test/Transforms/Attributor/nofpclass-canonicalize.ll
@@ -204,9 +204,9 @@ define float @ret_canonicalize_ieee_constant_snan() "denormal-fp-math"="ieee,iee
}
define float @ret_canonicalize_daz_constant_pos_denormal() "denormal-fp-math"="preserve-sign,preserve-sign" {
-; CHECK-LABEL: define noundef nofpclass(nan inf sub norm) float @ret_canonicalize_daz_constant_pos_denormal
+; CHECK-LABEL: define noundef nofpclass(nan inf nzero sub norm) float @ret_canonicalize_daz_constant_pos_denormal
; CHECK-SAME: () #[[ATTR10:[0-9]+]] {
-; CHECK-NEXT: [[CALL:%.*]] = call noundef nofpclass(nan inf sub norm) float @llvm.canonicalize.f32(float noundef 0x36A0000000000000) #[[ATTR12]]
+; CHECK-NEXT: [[CALL:%.*]] = call noundef nofpclass(nan inf nzero sub norm) float @llvm.canonicalize.f32(float noundef 0x36A0000000000000) #[[ATTR12]]
; CHECK-NEXT: ret float [[CALL]]
;
%call = call float @llvm.canonicalize.f32(float 0x36A0000000000000)
@@ -214,9 +214,9 @@ define float @ret_canonicalize_daz_constant_pos_denormal() "denormal-fp-math"="p
}
define float @ret_canonicalize_daz_constant_neg_denormal() "denormal-fp-math"="preserve-sign,preserve-sign" {
-; CHECK-LABEL: define noundef nofpclass(nan inf sub norm) float @ret_canonicalize_daz_constant_neg_denormal
+; CHECK-LABEL: define noundef nofpclass(nan inf pzero sub norm) float @ret_canonicalize_daz_constant_neg_denormal
; CHECK-SAME: () #[[ATTR10]] {
-; CHECK-NEXT: [[CALL:%.*]] = call noundef nofpclass(nan inf sub norm) float @llvm.canonicalize.f32(float noundef 0xB6A0000000000000) #[[ATTR12]]
+; CHECK-NEXT: [[CALL:%.*]] = call noundef nofpclass(nan inf pzero sub norm) float @llvm.canonicalize.f32(float noundef 0xB6A0000000000000) #[[ATTR12]]
; CHECK-NEXT: ret float [[CALL]]
;
%call = call float @llvm.canonicalize.f32(float 0xb6A0000000000000)
@@ -224,9 +224,9 @@ define float @ret_canonicalize_daz_constant_neg_denormal() "denormal-fp-math"="p
}
define float @ret_canonicalize_daz_constant_pos_zero() "denormal-fp-math"="preserve-sign,preserve-sign" {
-; CHECK-LABEL: define noundef nofpclass(nan inf sub norm) float @ret_canonicalize_daz_constant_pos_zero
+; CHECK-LABEL: define noundef nofpclass(nan inf nzero sub norm) float @ret_canonicalize_daz_constant_pos_zero
; CHECK-SAME: () #[[ATTR10]] {
-; CHECK-NEXT: [[CALL:%.*]] = call noundef nofpclass(nan inf sub norm) float @llvm.canonicalize.f32(float noundef 0.000000e+00) #[[ATTR12]]
+; CHECK-NEXT: [[CALL:%.*]] = call noundef nofpclass(nan inf nzero sub norm) float @llvm.canonicalize.f32(float noundef 0.000000e+00) #[[ATTR12]]
; CHECK-NEXT: ret float [[CALL]]
;
%call = call float @llvm.canonicalize.f32(float 0.0)
@@ -234,9 +234,9 @@ define float @ret_canonicalize_daz_constant_pos_zero() "denormal-fp-math"="prese
}
define float @ret_canonicalize_daz_constant_neg_zero() "denormal-fp-math"="preserve-sign,preserve-sign" {
-; CHECK-LABEL: define noundef nofpclass(nan inf sub norm) float @ret_canonicalize_daz_constant_neg_zero
+; CHECK-LABEL: define noundef nofpclass(nan inf pzero sub norm) float @ret_canonicalize_daz_constant_neg_zero
; CHECK-SAME: () #[[ATTR10]] {
-; CHECK-NEXT: [[CALL:%.*]] = call noundef nofpclass(nan inf sub norm) float @llvm.canonicalize.f32(float noundef -0.000000e+00) #[[ATTR12]]
+; CHECK-NEXT: [[CALL:%.*]] = call noundef nofpclass(nan inf pzero sub norm) float @llvm.canonicalize.f32(float noundef -0.000000e+00) #[[ATTR12]]
; CHECK-NEXT: ret float [[CALL]]
;
%call = call float @llvm.canonicalize.f32(float -0.0)
@@ -244,9 +244,9 @@ define float @ret_canonicalize_daz_constant_neg_zero() "denormal-fp-math"="prese
}
define float @ret_canonicalize_daz_constant_pos_normal() "denormal-fp-math"="preserve-sign,preserve-sign" {
-; CHECK-LABEL: define noundef nofpclass(nan inf sub nnorm) float @ret_canonicalize_daz_constant_pos_normal
+; CHECK-LABEL: define noundef nofpclass(nan inf zero sub nnorm) float @ret_canonicalize_daz_constant_pos_normal
; CHECK-SAME: () #[[ATTR10]] {
-; CHECK-NEXT: [[CALL:%.*]] = call noundef nofpclass(nan inf sub nnorm) float @llvm.canonicalize.f32(float noundef 8.000000e+00) #[[ATTR12]]
+; CHECK-NEXT: [[CALL:%.*]] = call noundef nofpclass(nan inf zero sub nnorm) float @llvm.canonicalize.f32(float noundef 8.000000e+00) #[[ATTR12]]
; CHECK-NEXT: ret float [[CALL]]
;
%call = call float @llvm.canonicalize.f32(float 8.0)
@@ -254,9 +254,9 @@ define float @ret_canonicalize_daz_constant_pos_normal() "denormal-fp-math"="pre
}
define float @ret_canonicalize_daz_constant_neg_normal() "denormal-fp-math"="preserve-sign,preserve-sign" {
-; CHECK-LABEL: define noundef nofpclass(nan inf sub pnorm) float @ret_canonicalize_daz_constant_neg_normal
+; CHECK-LABEL: define noundef nofpclass(nan inf zero sub pnorm) float @ret_canonicalize_daz_constant_neg_normal
; CHECK-SAME: () #[[ATTR10]] {
-; CHECK-NEXT: [[CALL:%.*]] = call noundef nofpclass(nan inf sub pnorm) float @llvm.canonicalize.f32(float noundef -8.000000e+00) #[[ATTR12]]
+; CHECK-NEXT: [[CALL:%.*]] = call noundef nofpclass(nan inf zero sub pnorm) float @llvm.canonicalize.f32(float noundef -8.000000e+00) #[[ATTR12]]
; CHECK-NEXT: ret float [[CALL]]
;
%call = call float @llvm.canonicalize.f32(float -8.0)
@@ -264,9 +264,9 @@ define float @ret_canonicalize_daz_constant_neg_normal() "denormal-fp-math"="pre
}
define float @ret_canonicalize_daz_constant_pos_inf() "denormal-fp-math"="preserve-sign,preserve-sign" {
-; CHECK-LABEL: define noundef nofpclass(nan ninf sub norm) float @ret_canonicalize_daz_constant_pos_inf
+; CHECK-LABEL: define noundef nofpclass(nan ninf zero sub norm) float @ret_canonicalize_daz_constant_pos_inf
; CHECK-SAME: () #[[ATTR10]] {
-; CHECK-NEXT: [[CALL:%.*]] = call noundef nofpclass(nan ninf sub norm) float @llvm.canonicalize.f32(float noundef 0x7FF0000000000000) #[[ATTR12]]
+; CHECK-NEXT: [[CALL:%.*]] = call noundef nofpclass(nan ninf zero sub norm) float @llvm.canonicalize.f32(float noundef 0x7FF0000000000000) #[[ATTR12]]
; CHECK-NEXT: ret float [[CALL]]
;
%call = call float @llvm.canonicalize.f32(float 0x7FF0000000000000)
@@ -274,9 +274,9 @@ define float @ret_canonicalize_daz_constant_pos_inf() "denormal-fp-math"="preser
}
define float @ret_canonicalize_daz_constant_neg_inf() "denormal-fp-math"="preserve-sign,preserve-sign" {
-; CHECK-LABEL: define noundef nofpclass(nan pinf sub norm) float @ret_canonicalize_daz_constant_neg_inf
+; CHECK-LABEL: define noundef nofpclass(nan pinf zero sub norm) float @ret_canonicalize_daz_constant_neg_inf
; CHECK-SAME: () #[[ATTR10]] {
-; CHECK-NEXT: [[CALL:%.*]] = call noundef nofpclass(nan pinf sub norm) float @llvm.canonicalize.f32(float noundef 0xFFF0000000000000) #[[ATTR12]]
+; CHECK-NEXT: [[CALL:%.*]] = call noundef nofpclass(nan pinf zero sub norm) float @llvm.canonicalize.f32(float noundef 0xFFF0000000000000) #[[ATTR12]]
; CHECK-NEXT: ret float [[CALL]]
;
%call = call float @llvm.canonicalize.f32(float 0xFFF0000000000000)
@@ -284,9 +284,9 @@ define float @ret_canonicalize_daz_constant_neg_inf() "denormal-fp-math"="preser
}
define float @ret_canonicalize_daz_constant_qnan() "denormal-fp-math"="preserve-sign,preserve-sign" {
-; CHECK-LABEL: define noundef nofpclass(snan inf sub norm) float @ret_canonicalize_daz_constant_qnan
+; CHECK-LABEL: define noundef nofpclass(snan inf zero sub norm) float @ret_canonicalize_daz_constant_qnan
; CHECK-SAME: () #[[ATTR10]] {
-; CHECK-NEXT: [[CALL:%.*]] = call noundef nofpclass(snan inf sub norm) float @llvm.canonicalize.f32(float noundef 0x7FF8000000000000) #[[ATTR12]]
+; CHECK-NEXT: [[CALL:%.*]] = call noundef nofpclass(snan inf zero sub norm) float @llvm.canonicalize.f32(float noundef 0x7FF8000000000000) #[[ATTR12]]
; CHECK-NEXT: ret float [[CALL]]
;
%call = call float @llvm.canonicalize.f32(float 0x7FF8000000000000)
@@ -294,9 +294,9 @@ define float @ret_canonicalize_daz_constant_qnan() "denormal-fp-math"="preserve-
}
define float @ret_canonicalize_daz_constant_snan() "denormal-fp-math"="preserve-sign,preserve-sign" {
-; CHECK-LABEL: define noundef nofpclass(snan inf sub norm) float @ret_canonicalize_daz_constant_snan
+; CHECK-LABEL: define noundef nofpclass(snan inf zero sub norm) float @ret_canonicalize_daz_constant_snan
; CHECK-SAME: () #[[ATTR10]] {
-; CHECK-NEXT: [[CALL:%.*]] = call noundef nofpclass(snan inf sub norm) float @llvm.canonicalize.f32(float noundef 0x7FF1000000000000) #[[ATTR12]]
+; CHECK-NEXT: [[CALL:%.*]] = call noundef nofpclass(snan inf zero sub norm) float @llvm.canonicalize.f32(float noundef 0x7FF1000000000000) #[[ATTR12]]
; CHECK-NEXT: ret float [[CALL]]
;
%call = call float @llvm.canonicalize.f32(float 0x7FF1000000000000)
@@ -504,9 +504,9 @@ define float @ret_canonicalize_dynamic_constant_snan() "denormal-fp-math"="dynam
}
define float @ret_canonicalize_daz_not_nzero_not_nsub(float nofpclass(nzero nsub) %x) "denormal-fp-math"="preserve-sign,preserve-sign" {
-; CHECK-LABEL: define nofpclass(snan sub) float @ret_canonicalize_daz_not_nzero_not_nsub
+; CHECK-LABEL: define nofpclass(snan nzero sub) float @ret_canonicalize_daz_not_nzero_not_nsub
; CHECK-SAME: (float nofpclass(nzero nsub) [[X:%.*]]) #[[ATTR10]] {
-; CHECK-NEXT: [[CALL:%.*]] = call nofpclass(snan sub) float @llvm.canonicalize.f32(float nofpclass(nzero nsub) [[X]]) #[[ATTR12]]
+; CHECK-NEXT: [[CALL:%.*]] = call nofpclass(snan nzero sub) float @llvm.canonicalize.f32(float nofpclass(nzero nsub) [[X]]) #[[ATTR12]]
; CHECK-NEXT: ret float [[CALL]]
;
%call = call float @llvm.canonicalize.f32(float %x)
@@ -534,9 +534,9 @@ define float @ret_canonicalize_daz_not_nzero(float nofpclass(nzero) %x) "denorma
}
define float @ret_canonicalize_daz_not_pzero_not_psub(float nofpclass(pzero psub) %x) "denormal-fp-math"="preserve-sign,preserve-sign" {
-; CHECK-LABEL: define nofpclass(snan sub) float @ret_canonicalize_daz_not_pzero_not_psub
+; CHECK-LABEL: define nofpclass(snan pzero sub) float @ret_canonicalize_daz_not_pzero_not_psub
; CHECK-SAME: (float nofpclass(pzero psub) [[X:%.*]]) #[[ATTR10]] {
-; CHECK-NEXT: [[CALL:%.*]] = call nofpclass(snan sub) float @llvm.canonicalize.f32(float nofpclass(pzero psub) [[X]]) #[[ATTR12]]
+; CHECK-NEXT: [[CALL:%.*]] = call nofpclass(snan pzero sub) float @llvm.canonicalize.f32(float nofpclass(pzero psub) [[X]]) #[[ATTR12]]
; CHECK-NEXT: ret float [[CALL]]
;
%call = call float @llvm.canonicalize.f32(float %x)
@@ -584,9 +584,9 @@ define float @ret_canonicalize_daz_not_sub(float nofpclass(sub) %x) "denormal-fp
}
define float @ret_canonicalize_daz_not_sub_not_nzero(float nofpclass(sub nzero) %x) "denormal-fp-math"="preserve-sign,preserve-sign" {
-; CHECK-LABEL: define nofpclass(snan sub) float @ret_canonicalize_daz_not_sub_not_nzero
+; CHECK-LABEL: define nofpclass(snan nzero sub) float @ret_canonicalize_daz_not_sub_not_nzero
; CHECK-SAME: (float nofpclass(nzero sub) [[X:%.*]]) #[[ATTR10]] {
-; CHECK-NEXT: [[CALL:%.*]] = call nofpclass(snan sub) float @llvm.canonicalize.f32(float nofpclass(nzero sub) [[X]]) #[[ATTR12]]
+; CHECK-NEXT: [[CALL:%.*]] = call nofpclass(snan nzero sub) float @llvm.canonicalize.f32(float nofpclass(nzero sub) [[X]]) #[[ATTR12]]
; CHECK-NEXT: ret float [[CALL]]
;
%call = call float @llvm.canonicalize.f32(float %x)
|

If the source value is known not subnormal and not zero with the
same sign, we can infer the result is also not zero with the same
sign.