-
Notifications
You must be signed in to change notification settings - Fork 15.5k
ValueTracking: Handle amdgcn_exp2 in computeKnownFPClass #172495
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/baseline-amdgcn-exp-nofpclass-test
Are you sure you want to change the base?
Conversation
The base exp handling looks pretty incomplete.
|
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-backend-amdgpu Author: Matt Arsenault (arsenm) ChangesThe base exp handling looks pretty incomplete. Full diff: https://github.com/llvm/llvm-project/pull/172495.diff 2 Files Affected:
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index 045cbab221ac3..0b57e27c92331 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -5374,7 +5374,8 @@ void computeKnownFPClass(const Value *V, const APInt &DemandedElts,
}
case Intrinsic::exp:
case Intrinsic::exp2:
- case Intrinsic::exp10: {
+ case Intrinsic::exp10:
+ case Intrinsic::amdgcn_exp2: {
Known.knownNot(fcNegative);
if ((InterestedClasses & fcNan) == fcNone)
break;
@@ -5387,6 +5388,10 @@ void computeKnownFPClass(const Value *V, const APInt &DemandedElts,
Known.signBitMustBeZero();
}
+ Type *EltTy = II->getType()->getScalarType();
+ if (IID == Intrinsic::amdgcn_exp2 && EltTy->isFloatTy())
+ Known.knownNot(fcSubnormal);
+
break;
}
case Intrinsic::fptrunc_round: {
diff --git a/llvm/test/Transforms/Attributor/AMDGPU/nofpclass-amdgcn-exp.ll b/llvm/test/Transforms/Attributor/AMDGPU/nofpclass-amdgcn-exp.ll
index babd1c68f161d..e7c41e9be7e33 100644
--- a/llvm/test/Transforms/Attributor/AMDGPU/nofpclass-amdgcn-exp.ll
+++ b/llvm/test/Transforms/Attributor/AMDGPU/nofpclass-amdgcn-exp.ll
@@ -4,9 +4,9 @@
declare float @llvm.amdgcn.exp2.f32(float)
define half @ret_exp_f16(half %arg0) {
-; CHECK-LABEL: define half @ret_exp_f16(
+; CHECK-LABEL: define nofpclass(ninf nzero nsub nnorm) half @ret_exp_f16(
; CHECK-SAME: half [[ARG0:%.*]]) #[[ATTR1:[0-9]+]] {
-; CHECK-NEXT: [[CALL:%.*]] = call half @llvm.amdgcn.exp2.f16(half [[ARG0]]) #[[ATTR2:[0-9]+]]
+; CHECK-NEXT: [[CALL:%.*]] = call nofpclass(ninf nzero nsub nnorm) half @llvm.amdgcn.exp2.f16(half [[ARG0]]) #[[ATTR2:[0-9]+]]
; CHECK-NEXT: ret half [[CALL]]
;
%call = call half @llvm.amdgcn.exp2.f16(half %arg0)
@@ -14,9 +14,9 @@ define half @ret_exp_f16(half %arg0) {
}
define float @ret_exp_f32(float %arg0) {
-; CHECK-LABEL: define float @ret_exp_f32(
+; CHECK-LABEL: define nofpclass(ninf nzero sub nnorm) float @ret_exp_f32(
; CHECK-SAME: float [[ARG0:%.*]]) #[[ATTR1]] {
-; CHECK-NEXT: [[CALL:%.*]] = call float @llvm.amdgcn.exp2.f32(float [[ARG0]]) #[[ATTR2]]
+; CHECK-NEXT: [[CALL:%.*]] = call nofpclass(ninf nzero sub nnorm) float @llvm.amdgcn.exp2.f32(float [[ARG0]]) #[[ATTR2]]
; CHECK-NEXT: ret float [[CALL]]
;
%call = call float @llvm.amdgcn.exp2.f32(float %arg0)
@@ -24,9 +24,9 @@ define float @ret_exp_f32(float %arg0) {
}
define float @ret_exp_noinf(float nofpclass(inf) %arg0) {
-; CHECK-LABEL: define float @ret_exp_noinf(
+; CHECK-LABEL: define nofpclass(ninf nzero sub nnorm) float @ret_exp_noinf(
; CHECK-SAME: float nofpclass(inf) [[ARG0:%.*]]) #[[ATTR1]] {
-; CHECK-NEXT: [[CALL:%.*]] = call float @llvm.amdgcn.exp2.f32(float nofpclass(inf) [[ARG0]]) #[[ATTR2]]
+; CHECK-NEXT: [[CALL:%.*]] = call nofpclass(ninf nzero sub nnorm) float @llvm.amdgcn.exp2.f32(float nofpclass(inf) [[ARG0]]) #[[ATTR2]]
; CHECK-NEXT: ret float [[CALL]]
;
%call = call float @llvm.amdgcn.exp2.f32(float %arg0)
@@ -34,9 +34,9 @@ define float @ret_exp_noinf(float nofpclass(inf) %arg0) {
}
define float @ret_exp_nopinf(float nofpclass(pinf) %arg0) {
-; CHECK-LABEL: define float @ret_exp_nopinf(
+; CHECK-LABEL: define nofpclass(ninf nzero sub nnorm) float @ret_exp_nopinf(
; CHECK-SAME: float nofpclass(pinf) [[ARG0:%.*]]) #[[ATTR1]] {
-; CHECK-NEXT: [[CALL:%.*]] = call float @llvm.amdgcn.exp2.f32(float nofpclass(pinf) [[ARG0]]) #[[ATTR2]]
+; CHECK-NEXT: [[CALL:%.*]] = call nofpclass(ninf nzero sub nnorm) float @llvm.amdgcn.exp2.f32(float nofpclass(pinf) [[ARG0]]) #[[ATTR2]]
; CHECK-NEXT: ret float [[CALL]]
;
%call = call float @llvm.amdgcn.exp2.f32(float %arg0)
@@ -44,9 +44,9 @@ define float @ret_exp_nopinf(float nofpclass(pinf) %arg0) {
}
define float @ret_exp_noninf(float nofpclass(ninf) %arg0) {
-; CHECK-LABEL: define float @ret_exp_noninf(
+; CHECK-LABEL: define nofpclass(ninf nzero sub nnorm) float @ret_exp_noninf(
; CHECK-SAME: float nofpclass(ninf) [[ARG0:%.*]]) #[[ATTR1]] {
-; CHECK-NEXT: [[CALL:%.*]] = call float @llvm.amdgcn.exp2.f32(float nofpclass(ninf) [[ARG0]]) #[[ATTR2]]
+; CHECK-NEXT: [[CALL:%.*]] = call nofpclass(ninf nzero sub nnorm) float @llvm.amdgcn.exp2.f32(float nofpclass(ninf) [[ARG0]]) #[[ATTR2]]
; CHECK-NEXT: ret float [[CALL]]
;
%call = call float @llvm.amdgcn.exp2.f32(float %arg0)
@@ -54,9 +54,9 @@ define float @ret_exp_noninf(float nofpclass(ninf) %arg0) {
}
define float @ret_exp_nonan(float nofpclass(nan) %arg0) {
-; CHECK-LABEL: define float @ret_exp_nonan(
+; CHECK-LABEL: define nofpclass(nan ninf nzero sub nnorm) float @ret_exp_nonan(
; CHECK-SAME: float nofpclass(nan) [[ARG0:%.*]]) #[[ATTR1]] {
-; CHECK-NEXT: [[CALL:%.*]] = call float @llvm.amdgcn.exp2.f32(float nofpclass(nan) [[ARG0]]) #[[ATTR2]]
+; CHECK-NEXT: [[CALL:%.*]] = call nofpclass(nan ninf nzero sub nnorm) float @llvm.amdgcn.exp2.f32(float nofpclass(nan) [[ARG0]]) #[[ATTR2]]
; CHECK-NEXT: ret float [[CALL]]
;
%call = call float @llvm.amdgcn.exp2.f32(float %arg0)
@@ -64,9 +64,9 @@ define float @ret_exp_nonan(float nofpclass(nan) %arg0) {
}
define float @ret_exp_nonan_noinf(float nofpclass(nan inf) %arg0) {
-; CHECK-LABEL: define float @ret_exp_nonan_noinf(
+; CHECK-LABEL: define nofpclass(nan ninf nzero sub nnorm) float @ret_exp_nonan_noinf(
; CHECK-SAME: float nofpclass(nan inf) [[ARG0:%.*]]) #[[ATTR1]] {
-; CHECK-NEXT: [[CALL:%.*]] = call float @llvm.amdgcn.exp2.f32(float nofpclass(nan inf) [[ARG0]]) #[[ATTR2]]
+; CHECK-NEXT: [[CALL:%.*]] = call nofpclass(nan ninf nzero sub nnorm) float @llvm.amdgcn.exp2.f32(float nofpclass(nan inf) [[ARG0]]) #[[ATTR2]]
; CHECK-NEXT: ret float [[CALL]]
;
%call = call float @llvm.amdgcn.exp2.f32(float %arg0)
@@ -74,9 +74,9 @@ define float @ret_exp_nonan_noinf(float nofpclass(nan inf) %arg0) {
}
define float @ret_exp_nonan_noinf_nozero(float nofpclass(nan inf zero) %arg0) {
-; CHECK-LABEL: define float @ret_exp_nonan_noinf_nozero(
+; CHECK-LABEL: define nofpclass(nan ninf nzero sub nnorm) float @ret_exp_nonan_noinf_nozero(
; CHECK-SAME: float nofpclass(nan inf zero) [[ARG0:%.*]]) #[[ATTR1]] {
-; CHECK-NEXT: [[CALL:%.*]] = call float @llvm.amdgcn.exp2.f32(float nofpclass(nan inf zero) [[ARG0]]) #[[ATTR2]]
+; CHECK-NEXT: [[CALL:%.*]] = call nofpclass(nan ninf nzero sub nnorm) float @llvm.amdgcn.exp2.f32(float nofpclass(nan inf zero) [[ARG0]]) #[[ATTR2]]
; CHECK-NEXT: ret float [[CALL]]
;
%call = call float @llvm.amdgcn.exp2.f32(float %arg0)
@@ -84,9 +84,9 @@ define float @ret_exp_nonan_noinf_nozero(float nofpclass(nan inf zero) %arg0) {
}
define float @ret_exp_noinf_nozero(float nofpclass(inf zero) %arg0) {
-; CHECK-LABEL: define float @ret_exp_noinf_nozero(
+; CHECK-LABEL: define nofpclass(ninf nzero sub nnorm) float @ret_exp_noinf_nozero(
; CHECK-SAME: float nofpclass(inf zero) [[ARG0:%.*]]) #[[ATTR1]] {
-; CHECK-NEXT: [[CALL:%.*]] = call float @llvm.amdgcn.exp2.f32(float nofpclass(inf zero) [[ARG0]]) #[[ATTR2]]
+; CHECK-NEXT: [[CALL:%.*]] = call nofpclass(ninf nzero sub nnorm) float @llvm.amdgcn.exp2.f32(float nofpclass(inf zero) [[ARG0]]) #[[ATTR2]]
; CHECK-NEXT: ret float [[CALL]]
;
%call = call float @llvm.amdgcn.exp2.f32(float %arg0)
@@ -94,9 +94,9 @@ define float @ret_exp_noinf_nozero(float nofpclass(inf zero) %arg0) {
}
define float @ret_exp_noinf_nonegzero(float nofpclass(inf nzero) %arg0) {
-; CHECK-LABEL: define float @ret_exp_noinf_nonegzero(
+; CHECK-LABEL: define nofpclass(ninf nzero sub nnorm) float @ret_exp_noinf_nonegzero(
; CHECK-SAME: float nofpclass(inf nzero) [[ARG0:%.*]]) #[[ATTR1]] {
-; CHECK-NEXT: [[CALL:%.*]] = call float @llvm.amdgcn.exp2.f32(float nofpclass(inf nzero) [[ARG0]]) #[[ATTR2]]
+; CHECK-NEXT: [[CALL:%.*]] = call nofpclass(ninf nzero sub nnorm) float @llvm.amdgcn.exp2.f32(float nofpclass(inf nzero) [[ARG0]]) #[[ATTR2]]
; CHECK-NEXT: ret float [[CALL]]
;
%call = call float @llvm.amdgcn.exp2.f32(float %arg0)
@@ -104,10 +104,10 @@ define float @ret_exp_noinf_nonegzero(float nofpclass(inf nzero) %arg0) {
}
define float @ret_exp_positive_source(i32 %arg) {
-; CHECK-LABEL: define float @ret_exp_positive_source(
+; CHECK-LABEL: define nofpclass(nan ninf nzero sub nnorm) float @ret_exp_positive_source(
; CHECK-SAME: i32 [[ARG:%.*]]) #[[ATTR1]] {
; CHECK-NEXT: [[UITOFP:%.*]] = uitofp i32 [[ARG]] to float
-; CHECK-NEXT: [[CALL:%.*]] = call float @llvm.amdgcn.exp2.f32(float [[UITOFP]]) #[[ATTR2]]
+; CHECK-NEXT: [[CALL:%.*]] = call nofpclass(nan ninf nzero sub nnorm) float @llvm.amdgcn.exp2.f32(float [[UITOFP]]) #[[ATTR2]]
; CHECK-NEXT: ret float [[CALL]]
;
%uitofp = uitofp i32 %arg to float
@@ -117,10 +117,10 @@ define float @ret_exp_positive_source(i32 %arg) {
; Could produce a nan because we don't know if the multiply is negative.
define float @ret_exp_unknown_sign(float nofpclass(nan) %arg0, float nofpclass(nan) %arg1) {
-; CHECK-LABEL: define float @ret_exp_unknown_sign(
+; CHECK-LABEL: define nofpclass(nan ninf nzero sub nnorm) float @ret_exp_unknown_sign(
; CHECK-SAME: float nofpclass(nan) [[ARG0:%.*]], float nofpclass(nan) [[ARG1:%.*]]) #[[ATTR1]] {
; CHECK-NEXT: [[UNKNOWN_SIGN_NOT_NAN:%.*]] = fmul nnan float [[ARG0]], [[ARG1]]
-; CHECK-NEXT: [[CALL:%.*]] = call float @llvm.amdgcn.exp2.f32(float [[UNKNOWN_SIGN_NOT_NAN]]) #[[ATTR2]]
+; CHECK-NEXT: [[CALL:%.*]] = call nofpclass(nan ninf nzero sub nnorm) float @llvm.amdgcn.exp2.f32(float [[UNKNOWN_SIGN_NOT_NAN]]) #[[ATTR2]]
; CHECK-NEXT: ret float [[CALL]]
;
%unknown.sign.not.nan = fmul nnan float %arg0, %arg1
|
| case Intrinsic::exp10: | ||
| case Intrinsic::amdgcn_exp2: { | ||
| Known.knownNot(fcNegative); | ||
| if ((InterestedClasses & fcNan) == fcNone) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| if ((InterestedClasses & fcNan) == fcNone) | |
| if ((InterestedClasses & (fcNan | fcSubnormal)) == fcNone) |

The base exp handling looks pretty incomplete.