[llvm] 07015e1 - [SLP]Fix PR59053: trying to erase instruction with users.

Alexey Bataev via llvm-commits llvm-commits at lists.llvm.org
Thu Nov 17 17:24:38 PST 2022


Author: Alexey Bataev
Date: 2022-11-17T17:23:48-08:00
New Revision: 07015e12f0a96e2c9484240b319c4d63b78be5e2

URL: https://github.com/llvm/llvm-project/commit/07015e12f0a96e2c9484240b319c4d63b78be5e2
DIFF: https://github.com/llvm/llvm-project/commit/07015e12f0a96e2c9484240b319c4d63b78be5e2.diff

LOG: [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.

Added: 
    llvm/test/Transforms/SLPVectorizer/X86/reduction-value-in-tree.ll

Modified: 
    llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
index ef63fbb4086b5..dc67c9e42e309 100644
--- a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
+++ b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
@@ -11873,23 +11873,36 @@ class HorizontalReduction {
           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 0000000000000..b349c3ac86319
--- /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
+}


        


More information about the llvm-commits mailing list