[llvm] InstCombine: Infer nnan and ninf flags on exp intrinsics (PR #177766)
Matt Arsenault via llvm-commits
llvm-commits at lists.llvm.org
Sat Jan 24 06:21:00 PST 2026
https://github.com/arsenm created https://github.com/llvm/llvm-project/pull/177766
Use the new common utility function to try fold to constant
or introduce flags.
>From eab6bd534549fb442f4abf1bdc653d2017c48d16 Mon Sep 17 00:00:00 2001
From: Matt Arsenault <Matthew.Arsenault at amd.com>
Date: Sat, 24 Jan 2026 13:34:26 +0100
Subject: [PATCH] InstCombine: Infer nnan and ninf flags on exp intrinsics
Use the new common utility function to try fold to constant
or introduce flags.
---
.../InstCombineSimplifyDemanded.cpp | 4 ++--
.../simplify-demanded-fpclass-exp.ll | 22 +++++++++----------
.../InstCombine/simplify-demanded-fpclass.ll | 6 ++---
3 files changed, 16 insertions(+), 16 deletions(-)
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp b/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
index 6846f13dced66..2c6b585a13251 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
@@ -2920,8 +2920,8 @@ Value *InstCombinerImpl::SimplifyDemandedUseFPClass(Instruction *I,
Known = KnownFPClass::exp(KnownSrc);
Known.knownNot(~DemandedMask);
- return getFPClassConstant(VTy, Known.KnownFPClasses,
- /*IsCanonicalizing=*/true);
+ return simplifyDemandedFPClassResult(CI, FMF, DemandedMask, Known,
+ KnownSrc);
}
case Intrinsic::log:
case Intrinsic::log2:
diff --git a/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-exp.ll b/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-exp.ll
index ef68699c73166..e026aab18df5b 100644
--- a/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-exp.ll
+++ b/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-exp.ll
@@ -42,7 +42,7 @@ define nofpclass(nan) float @ret_nofpclass_nan__exp2_select_maybe_inf_or_not_nan
; CHECK-LABEL: define nofpclass(nan) float @ret_nofpclass_nan__exp2_select_maybe_inf_or_not_nan(
; CHECK-SAME: i1 [[COND:%.*]], float [[MAYBE_NAN:%.*]], float nofpclass(nan) [[NOT_NAN:%.*]]) {
; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[COND]], float [[MAYBE_NAN]], float [[NOT_NAN]]
-; CHECK-NEXT: [[EXP:%.*]] = call float @llvm.exp2.f32(float [[SELECT]])
+; CHECK-NEXT: [[EXP:%.*]] = call nnan float @llvm.exp2.f32(float [[SELECT]])
; CHECK-NEXT: ret float [[EXP]]
;
%select = select i1 %cond, float %maybe.nan, float %not.nan
@@ -54,7 +54,7 @@ define nofpclass(nan) float @ret_nofpclass_nan__exp2_select_maybe_inf_or_not_nan
define nofpclass(nan) float @ret_nofpclass_nan__exp2_select_maybe_inf_or_nan(i1 %cond, float %maybe.nan, float nofpclass(inf zero sub norm) %only.nan) {
; CHECK-LABEL: define nofpclass(nan) float @ret_nofpclass_nan__exp2_select_maybe_inf_or_nan(
; CHECK-SAME: i1 [[COND:%.*]], float [[MAYBE_NAN:%.*]], float nofpclass(inf zero sub norm) [[ONLY_NAN:%.*]]) {
-; CHECK-NEXT: [[EXP:%.*]] = call float @llvm.exp2.f32(float [[MAYBE_NAN]])
+; CHECK-NEXT: [[EXP:%.*]] = call nnan float @llvm.exp2.f32(float [[MAYBE_NAN]])
; CHECK-NEXT: ret float [[EXP]]
;
%select = select i1 %cond, float %maybe.nan, float %only.nan
@@ -128,7 +128,7 @@ define nofpclass(pinf psub pnorm) float @ret_nofpclass_no_positives_except_0__ex
define nofpclass(nan) float @handle_exp(i1 %cond, float %maybe.nan, float nofpclass(inf zero sub norm) %only.nan) {
; CHECK-LABEL: define nofpclass(nan) float @handle_exp(
; CHECK-SAME: i1 [[COND:%.*]], float [[MAYBE_NAN:%.*]], float nofpclass(inf zero sub norm) [[ONLY_NAN:%.*]]) {
-; CHECK-NEXT: [[EXP:%.*]] = call float @llvm.exp.f32(float [[MAYBE_NAN]])
+; CHECK-NEXT: [[EXP:%.*]] = call nnan float @llvm.exp.f32(float [[MAYBE_NAN]])
; CHECK-NEXT: ret float [[EXP]]
;
%select = select i1 %cond, float %maybe.nan, float %only.nan
@@ -140,7 +140,7 @@ define nofpclass(nan) float @handle_exp(i1 %cond, float %maybe.nan, float nofpcl
define nofpclass(nan) float @handle_exp10(i1 %cond, float %maybe.nan, float nofpclass(inf zero sub norm) %only.nan) {
; CHECK-LABEL: define nofpclass(nan) float @handle_exp10(
; CHECK-SAME: i1 [[COND:%.*]], float [[MAYBE_NAN:%.*]], float nofpclass(inf zero sub norm) [[ONLY_NAN:%.*]]) {
-; CHECK-NEXT: [[EXP:%.*]] = call float @llvm.exp10.f32(float [[MAYBE_NAN]])
+; CHECK-NEXT: [[EXP:%.*]] = call nnan float @llvm.exp10.f32(float [[MAYBE_NAN]])
; CHECK-NEXT: ret float [[EXP]]
;
%select = select i1 %cond, float %maybe.nan, float %only.nan
@@ -154,7 +154,7 @@ define nofpclass(inf norm nan) float @ret_nofpclass_only_subzero__exp2_select_un
; CHECK-LABEL: define nofpclass(nan inf norm) float @ret_nofpclass_only_subzero__exp2_select_unknown_or_not_norm(
; CHECK-SAME: i1 [[COND:%.*]], float [[UNKNOWN:%.*]], float nofpclass(norm) [[NOT_NORM:%.*]]) {
; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[COND]], float [[UNKNOWN]], float 0xFFF0000000000000
-; CHECK-NEXT: [[EXP:%.*]] = call float @llvm.exp2.f32(float [[SELECT]])
+; CHECK-NEXT: [[EXP:%.*]] = call nnan float @llvm.exp2.f32(float [[SELECT]])
; CHECK-NEXT: ret float [[EXP]]
;
%select = select i1 %cond, float %unknown, float %not.norm
@@ -165,7 +165,7 @@ define nofpclass(inf norm nan) float @ret_nofpclass_only_subzero__exp2_select_un
define nofpclass(inf norm nan zero) float @ret_nofpclass_only_sub__exp2_select_unknown_or_not_norm(i1 %cond, float %unknown, float nofpclass(norm) %not.norm) {
; CHECK-LABEL: define nofpclass(nan inf zero norm) float @ret_nofpclass_only_sub__exp2_select_unknown_or_not_norm(
; CHECK-SAME: i1 [[COND:%.*]], float [[UNKNOWN:%.*]], float nofpclass(norm) [[NOT_NORM:%.*]]) {
-; CHECK-NEXT: [[EXP:%.*]] = call float @llvm.exp2.f32(float [[UNKNOWN]])
+; CHECK-NEXT: [[EXP:%.*]] = call nnan ninf float @llvm.exp2.f32(float [[UNKNOWN]])
; CHECK-NEXT: ret float [[EXP]]
;
%select = select i1 %cond, float %unknown, float %not.norm
@@ -256,7 +256,7 @@ define nofpclass(inf norm nan sub) float @zero_result_implies_nsub_source_valid_
define nofpclass(inf norm nan zero) float @sub_result_implies_nnorm_source_valid(float nofpclass(pnorm sub nan) %maybe.nnorm) {
; CHECK-LABEL: define nofpclass(nan inf zero norm) float @sub_result_implies_nnorm_source_valid(
; CHECK-SAME: float nofpclass(nan sub pnorm) [[MAYBE_NNORM:%.*]]) {
-; CHECK-NEXT: [[EXP:%.*]] = call float @llvm.exp2.f32(float [[MAYBE_NNORM]])
+; CHECK-NEXT: [[EXP:%.*]] = call nnan ninf float @llvm.exp2.f32(float [[MAYBE_NNORM]])
; CHECK-NEXT: ret float [[EXP]]
;
%exp = call float @llvm.exp2.f32(float %maybe.nnorm)
@@ -294,7 +294,7 @@ define nofpclass(inf norm nan sub) float @zero_result_implies_pnorm_source_valid
define nofpclass(inf norm nan zero) float @sub_result_implies_pnorm_source_valid(float nofpclass(pnorm sub nan) %maybe.pnorm) {
; CHECK-LABEL: define nofpclass(nan inf zero norm) float @sub_result_implies_pnorm_source_valid(
; CHECK-SAME: float nofpclass(nan sub pnorm) [[MAYBE_PNORM:%.*]]) {
-; CHECK-NEXT: [[EXP:%.*]] = call float @llvm.exp2.f32(float [[MAYBE_PNORM]])
+; CHECK-NEXT: [[EXP:%.*]] = call nnan ninf float @llvm.exp2.f32(float [[MAYBE_PNORM]])
; CHECK-NEXT: ret float [[EXP]]
;
%exp = call float @llvm.exp2.f32(float %maybe.pnorm)
@@ -304,7 +304,7 @@ define nofpclass(inf norm nan zero) float @sub_result_implies_pnorm_source_valid
define nofpclass(inf nnorm nan zero) float @pnorm_result_implies_possible_0_source(float nofpclass(pnorm sub) %maybe.zero.or.nan) {
; CHECK-LABEL: define nofpclass(nan inf zero nnorm) float @pnorm_result_implies_possible_0_source(
; CHECK-SAME: float nofpclass(sub pnorm) [[MAYBE_ZERO_OR_NAN:%.*]]) {
-; CHECK-NEXT: [[EXP:%.*]] = call float @llvm.exp2.f32(float [[MAYBE_ZERO_OR_NAN]])
+; CHECK-NEXT: [[EXP:%.*]] = call nnan ninf float @llvm.exp2.f32(float [[MAYBE_ZERO_OR_NAN]])
; CHECK-NEXT: ret float [[EXP]]
;
%exp = call float @llvm.exp2.f32(float %maybe.zero.or.nan)
@@ -323,7 +323,7 @@ define nofpclass(inf nnorm nan zero sub) float @pnorm_result_implies_possible_0_
define nofpclass(inf nnorm nan zero sub) float @pnorm_result_implies_possible_sub_source(float nofpclass(inf norm zero) %maybe.sub.or.nan) {
; CHECK-LABEL: define nofpclass(nan inf zero sub nnorm) float @pnorm_result_implies_possible_sub_source(
; CHECK-SAME: float nofpclass(inf zero norm) [[MAYBE_SUB_OR_NAN:%.*]]) {
-; CHECK-NEXT: [[EXP:%.*]] = call float @llvm.exp2.f32(float [[MAYBE_SUB_OR_NAN]])
+; CHECK-NEXT: [[EXP:%.*]] = call nnan ninf float @llvm.exp2.f32(float [[MAYBE_SUB_OR_NAN]])
; CHECK-NEXT: ret float [[EXP]]
;
%exp = call float @llvm.exp2.f32(float %maybe.sub.or.nan)
@@ -510,7 +510,7 @@ define nofpclass(nan inf nnorm sub zero) float @posnormal_result_demands_negnorm
; CHECK-LABEL: define nofpclass(nan inf zero sub nnorm) float @posnormal_result_demands_negnormal_source(
; CHECK-SAME: i1 [[COND:%.*]], float nofpclass(nan inf zero sub pnorm) [[NEG_NORMAL:%.*]], float [[UNKNOWN:%.*]]) {
; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[COND]], float [[UNKNOWN]], float [[NEG_NORMAL]]
-; CHECK-NEXT: [[EXP:%.*]] = call float @llvm.exp2.f32(float [[SELECT]])
+; CHECK-NEXT: [[EXP:%.*]] = call nnan ninf float @llvm.exp2.f32(float [[SELECT]])
; CHECK-NEXT: ret float [[EXP]]
;
%select = select i1 %cond, float %unknown, float %neg.normal
diff --git a/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass.ll b/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass.ll
index 545a5f895ab6f..7164d251ce0b7 100644
--- a/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass.ll
+++ b/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass.ll
@@ -1232,7 +1232,7 @@ define nofpclass(nan inf nzero nsub nnorm) float @powr_issue64870(float nofpclas
; CHECK-NEXT: [[I:%.*]] = tail call float @llvm.fabs.f32(float [[X]])
; CHECK-NEXT: [[I1:%.*]] = tail call float @llvm.log2.f32(float [[I]])
; CHECK-NEXT: [[I2:%.*]] = fmul nnan float [[I1]], [[Y]]
-; CHECK-NEXT: [[I3:%.*]] = tail call nofpclass(ninf nzero nsub nnorm) float @llvm.exp2.f32(float [[I2]])
+; CHECK-NEXT: [[I3:%.*]] = tail call nnan nofpclass(ninf nzero nsub nnorm) float @llvm.exp2.f32(float [[I2]])
; CHECK-NEXT: [[I6:%.*]] = fcmp oeq float [[X]], 0.000000e+00
; CHECK-NEXT: [[I7:%.*]] = select i1 [[I6]], float 0.000000e+00, float [[I3]]
; CHECK-NEXT: [[I8:%.*]] = fcmp oeq float [[Y]], 0.000000e+00
@@ -1267,7 +1267,7 @@ define nofpclass(nan inf nzero nsub nnorm) float @test_powr_issue64870_2(float n
; CHECK-NEXT: bb:
; CHECK-NEXT: [[I3:%.*]] = tail call float @llvm.log2.f32(float noundef [[ARG]])
; CHECK-NEXT: [[I5:%.*]] = fmul nnan float [[ARG1]], [[I3]]
-; CHECK-NEXT: [[I6:%.*]] = tail call noundef nofpclass(ninf nzero nsub nnorm) float @llvm.exp2.f32(float noundef [[I5]])
+; CHECK-NEXT: [[I6:%.*]] = tail call nnan nofpclass(ninf nzero nsub nnorm) float @llvm.exp2.f32(float [[I5]])
; CHECK-NEXT: [[TMP0:%.*]] = fcmp oeq float [[ARG]], 0.000000e+00
; CHECK-NEXT: [[I12:%.*]] = select i1 [[TMP0]], float 0.000000e+00, float [[I6]]
; CHECK-NEXT: ret float [[I12]]
@@ -1296,7 +1296,7 @@ define nofpclass(nan inf) float @pow_f32(float nofpclass(nan inf) %arg, float no
; CHECK-NEXT: [[I:%.*]] = tail call nofpclass(ninf nzero nsub nnorm) float @llvm.fabs.f32(float noundef [[ARG]])
; CHECK-NEXT: [[I2:%.*]] = tail call float @llvm.log2.f32(float noundef [[I]])
; CHECK-NEXT: [[I3:%.*]] = fmul nnan float [[I2]], [[ARG1]]
-; CHECK-NEXT: [[I4:%.*]] = tail call noundef float @llvm.exp2.f32(float noundef [[I3]])
+; CHECK-NEXT: [[I4:%.*]] = tail call nnan float @llvm.exp2.f32(float [[I3]])
; CHECK-NEXT: [[I5:%.*]] = tail call nofpclass(ninf nzero nsub nnorm) float @llvm.fabs.f32(float noundef [[ARG1]])
; CHECK-NEXT: [[I6:%.*]] = tail call float @llvm.trunc.f32(float noundef [[I5]])
; CHECK-NEXT: [[I7:%.*]] = fcmp oeq float [[I6]], [[I5]]
More information about the llvm-commits
mailing list