[llvm] InstCombine: Fix defining undef constant vector elts in SimplifyDemandedFPClass (PR #174074)

Matt Arsenault via llvm-commits llvm-commits at lists.llvm.org
Thu Jan 1 02:57:29 PST 2026


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

>From 78c49c590b8bf4ca27190b1b54278440977eb490 Mon Sep 17 00:00:00 2001
From: Matt Arsenault <Matthew.Arsenault at amd.com>
Date: Wed, 31 Dec 2025 09:46:25 +0100
Subject: [PATCH] InstCombine: Fix defining undef constant vector elts in
 SimplifyDemandedFPClass

Fold constants of known single class to the original constant instead of
a new constant. This avoids overdefining vector elements that were originally
undefined with the splat constant.
---
 .../InstCombineSimplifyDemanded.cpp           | 14 +++++++--
 .../InstCombine/simplify-demanded-fpclass.ll  | 29 +++++++++++++++++++
 2 files changed, 41 insertions(+), 2 deletions(-)

diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp b/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
index 554c5d82c3085..4c4ae4a6316d6 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
@@ -2048,8 +2048,18 @@ Value *InstCombinerImpl::SimplifyDemandedUseFPClass(Value *V,
   if (!I) {
     // Handle constants and arguments
     Known = computeKnownFPClass(V, fcAllFlags, CxtI, Depth + 1);
-    Value *FoldedToConst =
-        getFPClassConstant(VTy, DemandedMask & Known.KnownFPClasses);
+
+    FPClassTest ValidResults = DemandedMask & Known.KnownFPClasses;
+    if (ValidResults == fcNone)
+      return isa<UndefValue>(V) ? nullptr : PoisonValue::get(VTy);
+
+    // Do not try to replace values which are already constants (unless we are
+    // folding to poison). Doing so could promote poison elements to non-poison
+    // constants.
+    if (isa<Constant>(V))
+      return nullptr;
+
+    Value *FoldedToConst = getFPClassConstant(VTy, ValidResults);
     return FoldedToConst == V ? nullptr : FoldedToConst;
   }
 
diff --git a/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass.ll b/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass.ll
index c28b5967303c8..6d4674c8c9b54 100644
--- a/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass.ll
+++ b/llvm/test/Transforms/InstCombine/simplify-demanded-fpclass.ll
@@ -1357,3 +1357,32 @@ define nofpclass(nan) float @known_class_multiple_uses(i1 %cond0, i1 %cond1, i1
   %select2 = select i1 %cond2, float %select0, float %select1
   ret float %select2
 }
+
+; Do not overdefine the poison element to inf.
+define nofpclass(ninf) <2 x float> @single_class_constant_partially_poison_pinf() {
+; CHECK-LABEL: define nofpclass(ninf) <2 x float> @single_class_constant_partially_poison_pinf() {
+; CHECK-NEXT:    ret <2 x float> <float 0x7FF0000000000000, float poison>
+;
+  ret <2 x float> <float 0x7FF0000000000000, float poison>
+}
+
+define nofpclass(ninf) <2 x float> @single_class_constant_partially_undef_pinf() {
+; CHECK-LABEL: define nofpclass(ninf) <2 x float> @single_class_constant_partially_undef_pinf() {
+; CHECK-NEXT:    ret <2 x float> <float 0x7FF0000000000000, float undef>
+;
+  ret <2 x float> <float 0x7FF0000000000000, float undef>
+}
+
+define nofpclass(zero) <3 x float> @mixed_sign_zero_splat_to_poison() {
+; CHECK-LABEL: define nofpclass(zero) <3 x float> @mixed_sign_zero_splat_to_poison() {
+; CHECK-NEXT:    ret <3 x float> poison
+;
+  ret <3 x float> <float 0.0, float -0.0, float poison>
+}
+
+define nofpclass(zero) <3 x float> @partially_defined_0_splat_to_poison() {
+; CHECK-LABEL: define nofpclass(zero) <3 x float> @partially_defined_0_splat_to_poison() {
+; CHECK-NEXT:    ret <3 x float> poison
+;
+  ret <3 x float> <float 0.0, float 0.0, float poison>
+}



More information about the llvm-commits mailing list