[clang] [llvm] [mlir] [LLVM][Constants] Store "splat (float 0.0)" as ConstantFP rather than ConstantAggregateZero. (PR #195284)

via cfe-commits cfe-commits at lists.llvm.org
Fri May 1 09:02:11 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-llvm-ir

Author: Paul Walker (paulwalker-arm)

<details>
<summary>Changes</summary>

The original split is awkward because, not unreasonably, some code paths expect constant folding of ConstantFP operands to yield a ConstantFP result.

I'd like to follow up and investigated why the scalar and vector output takes different forms, but for now I wanted to fix the assertion failure.

NOTE: The change to ConstantFoldInsertElementInstruction is required to maintain existing test output.

Fixes https://github.com/llvm/llvm-project/issues/194590

---
Full diff: https://github.com/llvm/llvm-project/pull/195284.diff


4 Files Affected:

- (modified) llvm/lib/IR/AsmWriter.cpp (+5) 
- (modified) llvm/lib/IR/ConstantFold.cpp (+1-1) 
- (modified) llvm/lib/IR/Constants.cpp (+8-6) 
- (modified) llvm/test/Transforms/Reassociate/fast-ReassociateVector.ll (+45) 


``````````diff
diff --git a/llvm/lib/IR/AsmWriter.cpp b/llvm/lib/IR/AsmWriter.cpp
index 29e253e7c5f97..3cdb51826f2e3 100644
--- a/llvm/lib/IR/AsmWriter.cpp
+++ b/llvm/lib/IR/AsmWriter.cpp
@@ -1672,6 +1672,11 @@ static void writeConstantInternal(raw_ostream &Out, const Constant *CV,
     Type *Ty = CFP->getType();
 
     if (Ty->isVectorTy()) {
+      if (CFP->isNullValue()) {
+        Out << "zeroinitializer";
+        return;
+      }
+
       Out << "splat (";
       WriterCtx.TypePrinter->print(Ty->getScalarType(), Out);
       Out << " ";
diff --git a/llvm/lib/IR/ConstantFold.cpp b/llvm/lib/IR/ConstantFold.cpp
index ef87b1037beb6..f8abd576f93c4 100644
--- a/llvm/lib/IR/ConstantFold.cpp
+++ b/llvm/lib/IR/ConstantFold.cpp
@@ -442,7 +442,7 @@ Constant *llvm::ConstantFoldInsertElementInstruction(Constant *Val,
 
   // Inserting null into all zeros is still all zeros.
   // TODO: This is true for undef and poison splats too.
-  if (isa<ConstantAggregateZero>(Val) && Elt->isNullValue())
+  if (Val->isNullValue() && Elt->isNullValue())
     return Val;
 
   ConstantInt *CIdx = dyn_cast<ConstantInt>(Idx);
diff --git a/llvm/lib/IR/Constants.cpp b/llvm/lib/IR/Constants.cpp
index f07ce527c1240..d71f854aa6c7f 100644
--- a/llvm/lib/IR/Constants.cpp
+++ b/llvm/lib/IR/Constants.cpp
@@ -1637,11 +1637,12 @@ Constant *ConstantVector::getSplat(ElementCount EC, Constant *V) {
       if (isa<ConstantByte>(V))
         return ConstantByte::get(V->getContext(), EC,
                                  cast<ConstantByte>(V)->getValue());
-      if (UseConstantFPForFixedLengthSplat && isa<ConstantFP>(V))
-        return ConstantFP::get(V->getContext(), EC,
-                               cast<ConstantFP>(V)->getValue());
     }
 
+    if (UseConstantFPForFixedLengthSplat && isa<ConstantFP>(V))
+      return ConstantFP::get(V->getContext(), EC,
+                             cast<ConstantFP>(V)->getValue());
+
     // If this splat is compatible with ConstantDataVector, use it instead of
     // ConstantVector.
     if ((isa<ConstantFP>(V) || isa<ConstantInt>(V) || isa<ConstantByte>(V)) &&
@@ -1660,11 +1661,12 @@ Constant *ConstantVector::getSplat(ElementCount EC, Constant *V) {
     if (isa<ConstantByte>(V))
       return ConstantByte::get(V->getContext(), EC,
                                cast<ConstantByte>(V)->getValue());
-    if (UseConstantFPForScalableSplat && isa<ConstantFP>(V))
-      return ConstantFP::get(V->getContext(), EC,
-                             cast<ConstantFP>(V)->getValue());
   }
 
+  if (UseConstantFPForScalableSplat && isa<ConstantFP>(V))
+    return ConstantFP::get(V->getContext(), EC,
+                           cast<ConstantFP>(V)->getValue());
+
   Type *VTy = VectorType::get(V->getType(), EC);
 
   if (V->isNullValue())
diff --git a/llvm/test/Transforms/Reassociate/fast-ReassociateVector.ll b/llvm/test/Transforms/Reassociate/fast-ReassociateVector.ll
index 1a18526c3b6df..3e81d581b5ef6 100644
--- a/llvm/test/Transforms/Reassociate/fast-ReassociateVector.ll
+++ b/llvm/test/Transforms/Reassociate/fast-ReassociateVector.ll
@@ -458,3 +458,48 @@ define <2 x i32> @test18(<2 x i32> %x, <2 x i32> %y) {
   %tmp5 = xor <2 x i32> %tmp4, %tmp3
   ret <2 x i32> %tmp5
 }
+
+define float @test19_scalar(float %x, float %y) {
+; CHECK-LABEL: @test19_scalar(
+; CHECK-NEXT:    [[NEG:%.*]] = fneg reassoc nsz float [[Y:%.*]]
+; CHECK-NEXT:    [[REASS_ADD:%.*]] = fadd reassoc nsz float [[NEG]], [[X:%.*]]
+; CHECK-NEXT:    [[REASS_MUL:%.*]] = fmul reassoc nsz float [[REASS_ADD]], 0.000000e+00
+; CHECK-NEXT:    [[TMP4:%.*]] = fadd reassoc nsz float [[REASS_MUL]], 0.000000e+00
+; CHECK-NEXT:    ret float [[TMP4]]
+;
+  %tmp1 = fmul reassoc nsz float %x, zeroinitializer
+  %tmp2 = fadd reassoc nsz float zeroinitializer, %tmp1
+  %tmp3 = fmul reassoc nsz float %y, zeroinitializer
+  %tmp4 = fsub reassoc nsz float %tmp2, %tmp3
+  ret float %tmp4
+}
+
+define <4 x float> @test19_vector(<4 x float> %x, <4 x float> %y) {
+; CHECK-LABEL: @test19_vector(
+; CHECK-NEXT:    [[TMP1:%.*]] = fmul reassoc nsz <4 x float> [[X:%.*]], zeroinitializer
+; CHECK-NEXT:    [[TMP2:%.*]] = fadd reassoc nsz <4 x float> [[TMP1]], zeroinitializer
+; CHECK-NEXT:    [[TMP3_NEG:%.*]] = fmul reassoc nsz <4 x float> [[Y:%.*]], splat (float -0.000000e+00)
+; CHECK-NEXT:    [[TMP4:%.*]] = fadd reassoc nsz <4 x float> [[TMP2]], [[TMP3_NEG]]
+; CHECK-NEXT:    ret <4 x float> [[TMP4]]
+;
+  %tmp1 = fmul reassoc nsz <4 x float> %x, zeroinitializer
+  %tmp2 = fadd reassoc nsz <4 x float> zeroinitializer, %tmp1
+  %tmp3 = fmul reassoc nsz <4 x float> %y, zeroinitializer
+  %tmp4 = fsub reassoc nsz <4 x float> %tmp2, %tmp3
+  ret <4 x float> %tmp4
+}
+
+define <vscale x 4 x float> @test19_scalable_vector(<vscale x 4 x float> %x, <vscale x 4 x float> %y) {
+; CHECK-LABEL: @test19_scalable_vector(
+; CHECK-NEXT:    [[TMP1:%.*]] = fmul reassoc nsz <vscale x 4 x float> [[X:%.*]], zeroinitializer
+; CHECK-NEXT:    [[TMP2:%.*]] = fadd reassoc nsz <vscale x 4 x float> [[TMP1]], zeroinitializer
+; CHECK-NEXT:    [[TMP3_NEG:%.*]] = fmul reassoc nsz <vscale x 4 x float> [[Y:%.*]], splat (float -0.000000e+00)
+; CHECK-NEXT:    [[TMP4:%.*]] = fadd reassoc nsz <vscale x 4 x float> [[TMP2]], [[TMP3_NEG]]
+; CHECK-NEXT:    ret <vscale x 4 x float> [[TMP4]]
+;
+  %tmp1 = fmul reassoc nsz <vscale x 4 x float> %x, zeroinitializer
+  %tmp2 = fadd reassoc nsz <vscale x 4 x float> zeroinitializer, %tmp1
+  %tmp3 = fmul reassoc nsz <vscale x 4 x float> %y, zeroinitializer
+  %tmp4 = fsub reassoc nsz <vscale x 4 x float> %tmp2, %tmp3
+  ret <vscale x 4 x float> %tmp4
+}

``````````

</details>


https://github.com/llvm/llvm-project/pull/195284


More information about the cfe-commits mailing list