aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexey Bataev <a.bataev@outlook.com>2022-11-17 16:46:51 -0800
committerAlexey Bataev <a.bataev@outlook.com>2022-11-17 17:23:48 -0800
commit07015e12f0a96e2c9484240b319c4d63b78be5e2 (patch)
tree619c7cc52566b491e7b85738c0f3e0ca7272ad61
parent6b852ffa9973015fb5deb6d859d980692387dcc7 (diff)
downloadllvm-07015e12f0a96e2c9484240b319c4d63b78be5e2.zip
llvm-07015e12f0a96e2c9484240b319c4d63b78be5e2.tar.gz
llvm-07015e12f0a96e2c9484240b319c4d63b78be5e2.tar.bz2
[SLP]Fix PR59053: trying to erase instruction with users.
Need to count the reduced values, vectorized in the tree but not in the top node. Such scalars still must be extracted out of the vector node instead of the original scalar.
-rw-r--r--llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp33
-rw-r--r--llvm/test/Transforms/SLPVectorizer/X86/reduction-value-in-tree.ll58
2 files changed, 81 insertions, 10 deletions
diff --git a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
index ef63fbb..dc67c9e 100644
--- a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
+++ b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
@@ -11873,23 +11873,36 @@ public:
Value *V = Candidates[Cnt];
++NumUses.try_emplace(V, 0).first->getSecond();
}
+ SmallPtrSet<Value *, 4> VLScalars(VL.begin(), VL.end());
// Gather externally used values.
SmallPtrSet<Value *, 4> Visited;
for (unsigned Cnt = 0; Cnt < Pos; ++Cnt) {
- Value *V = Candidates[Cnt];
- if (!Visited.insert(V).second)
+ Value *RdxVal = Candidates[Cnt];
+ if (!Visited.insert(RdxVal).second)
+ continue;
+ // Check if the scalar was vectorized as part of the vectorization
+ // tree but not the top node.
+ if (!VLScalars.contains(RdxVal) && V.isVectorized(RdxVal)) {
+ LocalExternallyUsedValues[RdxVal];
continue;
- unsigned NumOps = VectorizedVals.lookup(V) + NumUses[V];
- if (NumOps != ReducedValsToOps.find(V)->second.size())
- LocalExternallyUsedValues[V];
+ }
+ unsigned NumOps = VectorizedVals.lookup(RdxVal) + NumUses[RdxVal];
+ if (NumOps != ReducedValsToOps.find(RdxVal)->second.size())
+ LocalExternallyUsedValues[RdxVal];
}
for (unsigned Cnt = Pos + ReduxWidth; Cnt < NumReducedVals; ++Cnt) {
- Value *V = Candidates[Cnt];
- if (!Visited.insert(V).second)
+ Value *RdxVal = Candidates[Cnt];
+ if (!Visited.insert(RdxVal).second)
+ continue;
+ // Check if the scalar was vectorized as part of the vectorization
+ // tree but not the top node.
+ if (!VLScalars.contains(RdxVal) && V.isVectorized(RdxVal)) {
+ LocalExternallyUsedValues[RdxVal];
continue;
- unsigned NumOps = VectorizedVals.lookup(V) + NumUses[V];
- if (NumOps != ReducedValsToOps.find(V)->second.size())
- LocalExternallyUsedValues[V];
+ }
+ unsigned NumOps = VectorizedVals.lookup(RdxVal) + NumUses[RdxVal];
+ if (NumOps != ReducedValsToOps.find(RdxVal)->second.size())
+ LocalExternallyUsedValues[RdxVal];
}
for (Value *RdxVal : VL)
if (RequiredExtract.contains(RdxVal))
diff --git a/llvm/test/Transforms/SLPVectorizer/X86/reduction-value-in-tree.ll b/llvm/test/Transforms/SLPVectorizer/X86/reduction-value-in-tree.ll
new file mode 100644
index 0000000..b349c3a
--- /dev/null
+++ b/llvm/test/Transforms/SLPVectorizer/X86/reduction-value-in-tree.ll
@@ -0,0 +1,58 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
+; RUN: opt -S -passes=slp-vectorizer -mtriple=x86_64-unknown-linux < %s | FileCheck %s
+define void @test() {
+; CHECK-LABEL: @test(
+; CHECK-NEXT: bb:
+; CHECK-NEXT: br i1 false, label [[PH:%.*]], label [[EXIT:%.*]]
+; CHECK: ph:
+; CHECK-NEXT: [[TMP0:%.*]] = call i8 @llvm.vector.reduce.and.v8i8(<8 x i8> zeroinitializer)
+; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.vector.reduce.and.v4i8(<4 x i8> zeroinitializer)
+; CHECK-NEXT: [[OP_RDX:%.*]] = and i8 [[TMP0]], [[TMP1]]
+; CHECK-NEXT: [[TMP2:%.*]] = call i8 @llvm.vector.reduce.and.v8i8(<8 x i8> zeroinitializer)
+; CHECK-NEXT: [[OP_RDX1:%.*]] = and i8 [[OP_RDX]], [[TMP2]]
+; CHECK-NEXT: [[OP_RDX2:%.*]] = and i8 [[OP_RDX1]], 0
+; CHECK-NEXT: br label [[EXIT]]
+; CHECK: exit:
+; CHECK-NEXT: [[PHI:%.*]] = phi i8 [ [[OP_RDX2]], [[PH]] ], [ 0, [[BB:%.*]] ]
+; CHECK-NEXT: ret void
+;
+bb:
+ br i1 false, label %ph, label %exit
+
+ph:
+ %add1 = add i8 0, 0
+ %add2 = add i8 %add1, 0
+ %add3 = add i8 %add1, 0
+ %add4 = add i8 %add1, 0
+ %add5 = add i8 %add1, 0
+ %add6 = add i8 %add1, 0
+ %add7 = add i8 %add1, 0
+ %add8 = add i8 %add1, 0
+ %add9 = add i8 0, 0
+ %add10 = add i8 0, %add9
+ %0 = and i8 %add10, %add3
+ %1 = and i8 %0, %add2
+ %2 = and i8 %1, %add4
+ %3 = and i8 %2, 0
+ %4 = and i8 %3, %add5
+ %5 = and i8 %4, %add6
+ %6 = and i8 %5, 0
+ %7 = and i8 %6, 0
+ %8 = and i8 %7, 0
+ %9 = and i8 %8, 0
+ %10 = and i8 %9, 0
+ %11 = and i8 %10, 0
+ %12 = and i8 %11, 0
+ %13 = and i8 %12, %add7
+ %14 = and i8 %13, %add8
+ %15 = and i8 %14, 0
+ %16 = and i8 %15, 0
+ %17 = and i8 %16, 0
+ %18 = and i8 %17, 0
+ %and = and i8 %18, %add1
+ br label %exit
+
+exit:
+ %phi = phi i8 [ %and, %ph ], [ 0, %bb ]
+ ret void
+}