[llvm] [SLP] Fix reduction cost crash for reduced values replaced by extractelement (PR #204847)
via llvm-commits
llvm-commits at lists.llvm.org
Fri Jun 19 08:54:30 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-llvm-transforms
Author: Alexey Bataev (alexey-bataev)
<details>
<summary>Changes</summary>
A reduced value may be replaced by an extractelement while vectorizing a
previous subvector, so it is no longer a key in ReducedValsToOps.
Look through replaced values to the reduction operation among their users.
Fixes #<!-- -->204814
---
Full diff: https://github.com/llvm/llvm-project/pull/204847.diff
2 Files Affected:
- (modified) llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp (+15-2)
- (added) llvm/test/Transforms/SLPVectorizer/X86/reduced-value-replace-extractelement-cost.ll (+61)
``````````diff
diff --git a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
index 68c11dc372ad7..9b7d154598c40 100644
--- a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
+++ b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
@@ -30551,6 +30551,19 @@ class HorizontalReduction {
// If all of the reduced values are constant, the vector cost is 0, since
// the reduction value can be calculated at the compile time.
bool AllConsts = allConstant(ReducedVals);
+ // A reduced value may have been replaced by an extractelement while
+ // vectorizing a previous subvector of the reduction. Such tracked values
+ // are not present in ReducedValsToOps, so look through them to the
+ // reduction operation that uses the replaced value.
+ auto GetReductionOp = [&](Value *RdxVal) -> Instruction * {
+ auto It = ReducedValsToOps.find(RdxVal);
+ if (It != ReducedValsToOps.end())
+ return It->second.front();
+ for (User *U : RdxVal->users())
+ if (getRdxKind(U) == RdxKind)
+ return cast<Instruction>(U);
+ return cast<Instruction>(RdxVal);
+ };
auto EvaluateScalarCost =
[&](function_ref<InstructionCost(Instruction *)> GenCostFn) {
InstructionCost Cost = 0;
@@ -30559,7 +30572,7 @@ class HorizontalReduction {
for (auto [Idx, RdxVal] : enumerate(ReducedVals)) {
if (!isa<Instruction>(RdxVal))
continue;
- Instruction *RdxOp = ReducedValsToOps[ReducedVals[Idx]].front();
+ Instruction *RdxOp = GetReductionOp(RdxVal);
if (Cnt == 1) {
unsigned SameValueCount = SameValuesCounter.lookup(RdxVal);
Cost +=
@@ -30639,7 +30652,7 @@ class HorizontalReduction {
RdxOpcode, VecTy, CostKind,
TTI::getOperandInfo(ReducedVals[I]),
TTI::getOperandInfo(ReducedVals[I + 1]), {},
- ReducedValsToOps[ReducedVals[I]].front());
+ GetReductionOp(ReducedVals[I]));
}
} else {
Type *RedTy = VectorTy->getElementType();
diff --git a/llvm/test/Transforms/SLPVectorizer/X86/reduced-value-replace-extractelement-cost.ll b/llvm/test/Transforms/SLPVectorizer/X86/reduced-value-replace-extractelement-cost.ll
new file mode 100644
index 0000000000000..3089a72ef5f79
--- /dev/null
+++ b/llvm/test/Transforms/SLPVectorizer/X86/reduced-value-replace-extractelement-cost.ll
@@ -0,0 +1,61 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6
+; RUN: opt -S --passes=slp-vectorizer < %s -mtriple=x86_64-unknown-linux-gnu | FileCheck %s
+
+define i32 @test(i32 %arg) {
+; CHECK-LABEL: define i32 @test(
+; CHECK-SAME: i32 [[ARG:%.*]]) {
+; CHECK-NEXT: [[ENTRY:.*:]]
+; CHECK-NEXT: [[TMP0:%.*]] = insertelement <4 x i32> <i32 0, i32 poison, i32 0, i32 0>, i32 [[ARG]], i32 1
+; CHECK-NEXT: [[TMP1:%.*]] = srem <4 x i32> [[TMP0]], splat (i32 46337)
+; CHECK-NEXT: [[TMP2:%.*]] = icmp slt <4 x i32> [[TMP1]], zeroinitializer
+; CHECK-NEXT: [[TMP3:%.*]] = select <4 x i1> [[TMP2]], <4 x i32> zeroinitializer, <4 x i32> zeroinitializer
+; CHECK-NEXT: [[TMP4:%.*]] = mul <4 x i32> [[TMP3]], zeroinitializer
+; CHECK-NEXT: [[TMP5:%.*]] = urem <4 x i32> [[TMP4]], splat (i32 46337)
+; CHECK-NEXT: [[TMP6:%.*]] = icmp ult <4 x i32> [[TMP5]], zeroinitializer
+; CHECK-NEXT: [[TMP7:%.*]] = select <4 x i1> [[TMP6]], <4 x i32> zeroinitializer, <4 x i32> zeroinitializer
+; CHECK-NEXT: [[TMP8:%.*]] = shufflevector <4 x i32> [[TMP1]], <4 x i32> <i32 0, i32 0, i32 0, i32 poison>, <4 x i32> <i32 4, i32 5, i32 6, i32 1>
+; CHECK-NEXT: [[TMP9:%.*]] = sub <4 x i32> [[TMP8]], zeroinitializer
+; CHECK-NEXT: [[RDX_OP:%.*]] = add <4 x i32> [[TMP7]], [[TMP9]]
+; CHECK-NEXT: [[TMP10:%.*]] = call i32 @llvm.vector.reduce.add.v4i32(<4 x i32> [[RDX_OP]])
+; CHECK-NEXT: ret i32 [[TMP10]]
+;
+entry:
+ %rem943.i = srem i32 0, 46337
+ %rem945.cmp.i = icmp slt i32 %rem943.i, 0
+ %rem945.i = select i1 %rem945.cmp.i, i32 0, i32 0
+ %mul946.i = mul i32 %rem945.i, 0
+ %rem947.i = urem i32 %mul946.i, 46337
+ %rem943.i.1 = srem i32 %arg, 46337
+ %rem945.cmp.i.1 = icmp slt i32 %rem943.i.1, 0
+ %rem945.i.1 = select i1 %rem945.cmp.i.1, i32 0, i32 0
+ %mul946.i.1 = mul i32 %rem945.i.1, 0
+ %rem947.i.1 = urem i32 %mul946.i.1, 46337
+ %rem956.cmp.i.1 = icmp ult i32 %rem947.i.1, 0
+ %rem956.v.i.1 = select i1 %rem956.cmp.i.1, i32 0, i32 0
+ %.neg = sub i32 0, 0
+ %rem956.cmp.i = icmp ult i32 %rem947.i, 0
+ %rem956.v.i = select i1 %rem956.cmp.i, i32 0, i32 0
+ %0 = add i32 %.neg, %rem956.v.i
+ %rem943.i.2 = srem i32 0, 46337
+ %rem945.cmp.i.2 = icmp slt i32 %rem943.i.2, 0
+ %rem945.i.2 = select i1 %rem945.cmp.i.2, i32 0, i32 0
+ %mul946.i.2 = mul i32 %rem945.i.2, 0
+ %rem947.i.2 = urem i32 %mul946.i.2, 46337
+ %rem956.cmp.i.2 = icmp ult i32 %rem947.i.2, 0
+ %rem956.v.i.2 = select i1 %rem956.cmp.i.2, i32 0, i32 0
+ %1 = add i32 %rem956.v.i.1, %0
+ %2 = add i32 %rem943.i.1, %1
+ %3 = add i32 %rem956.v.i.2, %2
+ %rem943.i.3 = srem i32 0, 46337
+ %rem945.cmp.i.3 = icmp slt i32 %rem943.i.3, 0
+ %rem945.i.3 = select i1 %rem945.cmp.i.3, i32 0, i32 0
+ %mul946.i.3 = mul i32 %rem945.i.3, 0
+ %rem947.i.3 = urem i32 %mul946.i.3, 46337
+ %rem956.cmp.i.3 = icmp ult i32 %rem947.i.3, 0
+ %rem956.v.i.3 = select i1 %rem956.cmp.i.3, i32 0, i32 0
+ %.neg38 = sub i32 0, 0
+ %4 = add i32 %3, 0
+ %5 = add i32 %.neg38, %4
+ %6 = add i32 %rem956.v.i.3, %5
+ ret i32 %6
+}
``````````
</details>
https://github.com/llvm/llvm-project/pull/204847
More information about the llvm-commits
mailing list