https://github.com/arsenm created https://github.com/llvm/llvm-project/pull/173429
This is already handled, but misses opportunities. Test cases where the input is known positive or negative. >From d8af1dc910fac987e8c49c921a906dc089e6d1a1 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
