[llvm] InstCombine: Negative normal exp results imply possible positive normal inputs (PR #174273)

Matt Arsenault via llvm-commits llvm-commits at lists.llvm.org
Sat Jan 3 02:50:25 PST 2026


https://github.com/arsenm created https://github.com/llvm/llvm-project/pull/174273

Fix mishandling exp where the result is known to only be a negative normal.

>From 796296c24155c1b61e25d8f9621d556aef22929b Mon Sep 17 00:00:00 2001
From: Matt Arsenault <Matthew.Arsenault at amd.com>
Date: Sat, 3 Jan 2026 11:35:07 +0100
Subject: [PATCH] InstCombine: Negative normal exp results imply possible
 positive normal inputs

Fix mishandling exp where the result is known to only be a negative normal.
---
 .../InstCombine/InstCombineSimplifyDemanded.cpp     |  3 ++-
 .../InstCombine/simplify-demanded-fpclass-exp.ll    | 13 +++++++++++++
 2 files changed, 15 insertions(+), 1 deletion(-)

diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp b/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
index 3ad1caa6baa63..7bc1070613acd 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
@@ -2159,7 +2159,8 @@ Value *InstCombinerImpl::SimplifyDemandedUseFPClass(Value *V,
         // exp(+/- smallest_normal) = 1
         // exp(+/- largest_denormal) = 1
         // exp(+/- smallest_denormal) = 1
-        SrcDemandedMask |= fcPosNormal | fcSubnormal | fcZero;
+        // exp(-1) = pos normal
+        SrcDemandedMask |= fcNormal | fcSubnormal | fcZero;
       }
 
       // exp(inf), exp(largest_normal) = inf
diff --git a/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-exp.ll b/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-exp.ll
index 1f042868ea879..8a2ad8ba31d32 100644
--- a/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-exp.ll
+++ b/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass-exp.ll
@@ -509,6 +509,19 @@ define nofpclass(pzero nan) float @source_is_known_zero_or_nan__nnan_result(floa
   ret float %exp
 }
 
+; Cannot eliminate the select
+define nofpclass(nan inf nnorm sub zero) float @posnormal_result_demands_negnormal_source(i1 %cond, float nofpclass(inf nan pnorm sub zero) %neg.normal, float %unknown) {
+; 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:    ret float [[EXP]]
+;
+  %select = select i1 %cond, float %unknown, float %neg.normal
+  %exp = call float @llvm.exp2.f32(float %select)
+  ret float %exp
+}
+
 !0 = !{!"function_entry_count", i64 1000}
 ;.
 ; CHECK: attributes #[[ATTR0:[0-9]+]] = { nocallback nocreateundeforpoison nofree nosync nounwind speculatable willreturn memory(none) }



More information about the llvm-commits mailing list