https://github.com/arsenm updated 
https://github.com/llvm/llvm-project/pull/173429

>From 9632f325bf27413b3fca7eb088b0e16f0f32a673 Mon Sep 17 00:00:00 2001
From: Matt Arsenault <[email protected]>
Date: Sat, 20 Dec 2025 23:52:22 +0100
Subject: [PATCH] ValueTracking: Add baseline tests for computeKnownFPClass exp

This is already handled, but misses opportunities. Test cases
where the input is known positive or negative.
---
 .../Transforms/Attributor/nofpclass-exp.ll    | 101 ++++++++++++++++++
 1 file changed, 101 insertions(+)

diff --git a/llvm/test/Transforms/Attributor/nofpclass-exp.ll 
b/llvm/test/Transforms/Attributor/nofpclass-exp.ll
index 490d3da5505eb..ea5c26d101186 100644
--- a/llvm/test/Transforms/Attributor/nofpclass-exp.ll
+++ b/llvm/test/Transforms/Attributor/nofpclass-exp.ll
@@ -349,5 +349,106 @@ define float @ret_exp10_unknown_sign(float nofpclass(nan) 
%arg0, float nofpclass
   %call = call float @llvm.exp10.f32(float %unknown.sign.not.nan)
   ret float %call
 }
+
+; Can infer this doesn't return any inf
+define float @ret_exp_src_known_negative_or_zero_or_nan(float nofpclass(pinf 
psub pnorm) %arg0) {
+; CHECK-LABEL: define nofpclass(ninf nzero nsub nnorm) float 
@ret_exp_src_known_negative_or_zero_or_nan
+; CHECK-SAME: (float nofpclass(pinf psub pnorm) [[ARG0:%.*]]) #[[ATTR1]] {
+; CHECK-NEXT:    [[CALL:%.*]] = call nofpclass(ninf nzero nsub nnorm) float 
@llvm.exp.f32(float nofpclass(pinf psub pnorm) [[ARG0]]) #[[ATTR2]]
+; CHECK-NEXT:    ret float [[CALL]]
+;
+  %call = call float @llvm.exp.f32(float %arg0)
+  ret float %call
+}
+
+; Can infer this doesn't return any inf
+define float @ret_exp_src_known_negative_nonzero_or_nan(float nofpclass(pinf 
psub pnorm zero) %arg0) {
+; CHECK-LABEL: define nofpclass(ninf nzero nsub nnorm) float 
@ret_exp_src_known_negative_nonzero_or_nan
+; CHECK-SAME: (float nofpclass(pinf zero psub pnorm) [[ARG0:%.*]]) #[[ATTR1]] {
+; CHECK-NEXT:    [[CALL:%.*]] = call nofpclass(ninf nzero nsub nnorm) float 
@llvm.exp.f32(float nofpclass(pinf zero psub pnorm) [[ARG0]]) #[[ATTR2]]
+; CHECK-NEXT:    ret float [[CALL]]
+;
+  %call = call float @llvm.exp.f32(float %arg0)
+  ret float %call
+}
+
+define float @ret_exp_src_known_positive_or_zero_or_nan(float nofpclass(ninf 
nsub nnorm) %arg0) {
+; CHECK-LABEL: define nofpclass(ninf nzero nsub nnorm) float 
@ret_exp_src_known_positive_or_zero_or_nan
+; CHECK-SAME: (float nofpclass(ninf nsub nnorm) [[ARG0:%.*]]) #[[ATTR1]] {
+; CHECK-NEXT:    [[CALL:%.*]] = call nofpclass(ninf nzero nsub nnorm) float 
@llvm.exp.f32(float nofpclass(ninf nsub nnorm) [[ARG0]]) #[[ATTR2]]
+; CHECK-NEXT:    ret float [[CALL]]
+;
+  %call = call float @llvm.exp.f32(float %arg0)
+  ret float %call
+}
+
+define float @ret_exp_src_known_positive_non0_or_nan(float nofpclass(ninf nsub 
nnorm zero) %arg0) {
+; CHECK-LABEL: define nofpclass(ninf nzero nsub nnorm) float 
@ret_exp_src_known_positive_non0_or_nan
+; CHECK-SAME: (float nofpclass(ninf zero nsub nnorm) [[ARG0:%.*]]) #[[ATTR1]] {
+; CHECK-NEXT:    [[CALL:%.*]] = call nofpclass(ninf nzero nsub nnorm) float 
@llvm.exp.f32(float nofpclass(ninf zero nsub nnorm) [[ARG0]]) #[[ATTR2]]
+; CHECK-NEXT:    ret float [[CALL]]
+;
+  %call = call float @llvm.exp.f32(float %arg0)
+  ret float %call
+}
+
+; Can't underflow to 0, can't be denormal.
+define float @ret_exp_src_known_positive_non0_nonsub_or_nan(float 
nofpclass(ninf sub nnorm zero) %arg0) {
+; CHECK-LABEL: define nofpclass(ninf nzero nsub nnorm) float 
@ret_exp_src_known_positive_non0_nonsub_or_nan
+; CHECK-SAME: (float nofpclass(ninf zero sub nnorm) [[ARG0:%.*]]) #[[ATTR1]] {
+; CHECK-NEXT:    [[CALL:%.*]] = call nofpclass(ninf nzero nsub nnorm) float 
@llvm.exp.f32(float nofpclass(ninf zero sub nnorm) [[ARG0]]) #[[ATTR2]]
+; CHECK-NEXT:    ret float [[CALL]]
+;
+  %call = call float @llvm.exp.f32(float %arg0)
+  ret float %call
+}
+
+; Can't underflow to denormal, but can have an input denormal stay denormal.
+define float @ret_exp_src_known_positive_or_nan(float nofpclass(ninf nsub 
nnorm) %arg0) {
+; CHECK-LABEL: define nofpclass(ninf nzero nsub nnorm) float 
@ret_exp_src_known_positive_or_nan
+; CHECK-SAME: (float nofpclass(ninf nsub nnorm) [[ARG0:%.*]]) #[[ATTR1]] {
+; CHECK-NEXT:    [[CALL:%.*]] = call nofpclass(ninf nzero nsub nnorm) float 
@llvm.exp.f32(float nofpclass(ninf nsub nnorm) [[ARG0]]) #[[ATTR2]]
+; CHECK-NEXT:    ret float [[CALL]]
+;
+  %call = call float @llvm.exp.f32(float %arg0)
+  ret float %call
+}
+
+define float @ret_exp_src_known_positive_nonsub_or_nan(float nofpclass(ninf 
sub nnorm) %arg0) {
+; CHECK-LABEL: define nofpclass(ninf nzero nsub nnorm) float 
@ret_exp_src_known_positive_nonsub_or_nan
+; CHECK-SAME: (float nofpclass(ninf sub nnorm) [[ARG0:%.*]]) #[[ATTR1]] {
+; CHECK-NEXT:    [[CALL:%.*]] = call nofpclass(ninf nzero nsub nnorm) float 
@llvm.exp.f32(float nofpclass(ninf sub nnorm) [[ARG0]]) #[[ATTR2]]
+; CHECK-NEXT:    ret float [[CALL]]
+;
+  %call = call float @llvm.exp.f32(float %arg0)
+  ret float %call
+}
+
+define float @ret_exp_fabs(float %arg) {
+; CHECK-LABEL: define nofpclass(ninf nzero nsub nnorm) float @ret_exp_fabs
+; CHECK-SAME: (float [[ARG:%.*]]) #[[ATTR1]] {
+; CHECK-NEXT:    [[ARG_FABS:%.*]] = call float @llvm.fabs.f32(float [[ARG]]) 
#[[ATTR2]]
+; CHECK-NEXT:    [[CALL:%.*]] = call nofpclass(ninf nzero nsub nnorm) float 
@llvm.exp.f32(float [[ARG_FABS]]) #[[ATTR2]]
+; CHECK-NEXT:    ret float [[CALL]]
+;
+  %arg.fabs = call float @llvm.fabs.f32(float %arg)
+  %call = call float @llvm.exp.f32(float %arg.fabs)
+  ret float %call
+}
+
+define float @ret_exp_fneg_fabs(float %arg) {
+; CHECK-LABEL: define nofpclass(ninf nzero nsub nnorm) float @ret_exp_fneg_fabs
+; CHECK-SAME: (float [[ARG:%.*]]) #[[ATTR1]] {
+; CHECK-NEXT:    [[ARG_FABS:%.*]] = call float @llvm.fabs.f32(float [[ARG]]) 
#[[ATTR2]]
+; CHECK-NEXT:    [[ARG_NEG_FABS:%.*]] = fneg float [[ARG_FABS]]
+; CHECK-NEXT:    [[CALL:%.*]] = call nofpclass(ninf nzero nsub nnorm) float 
@llvm.exp.f32(float [[ARG_NEG_FABS]]) #[[ATTR2]]
+; CHECK-NEXT:    ret float [[CALL]]
+;
+  %arg.fabs = call float @llvm.fabs.f32(float %arg)
+  %arg.neg.fabs = fneg float %arg.fabs
+  %call = call float @llvm.exp.f32(float %arg.neg.fabs)
+  ret float %call
+}
+
 ;; NOTE: These prefixes are unused and the list is autogenerated. Do not add 
tests below this line:
 ; TUNIT: {{.*}}

_______________________________________________
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits

Reply via email to