[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