[llvm] d71ad41 - [SLP]Fix insertpoint of the extractellements instructions to avoid reshuffle crash.

Alexey Bataev via llvm-commits llvm-commits at lists.llvm.org
Wed Oct 12 08:19:30 PDT 2022


Author: Alexey Bataev
Date: 2022-10-12T08:18:30-07:00
New Revision: d71ad4108056d685f48407447095d8d92fd7685d

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

LOG: [SLP]Fix insertpoint of the extractellements instructions to avoid reshuffle crash.

Need to set the insertpoint for extractelement to point to the first
instruction in the node to avoid possible crash during external uses
combine  process. Without it we may endup with the incorrect
transformation.

Differential Revision: https://reviews.llvm.org/D135591

Added: 
    llvm/test/Transforms/SLPVectorizer/X86/extractelement-insertpoint.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 10d9293d928e..865578f7c4f0 100644
--- a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
+++ b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
@@ -7693,13 +7693,34 @@ Instruction &BoUpSLP::getLastInstructionInBundle(const TreeEntry *E) {
     return LastInst;
   };
 
-  auto &&FindFirstInst = [E, Front]() {
+  auto &&FindFirstInst = [E, Front, this]() {
     Instruction *FirstInst = Front;
     for (Value *V : E->Scalars) {
       auto *I = dyn_cast<Instruction>(V);
       if (!I)
         continue;
-      if (I->comesBefore(FirstInst))
+      if (FirstInst->getParent() == I->getParent()) {
+        if (I->comesBefore(FirstInst))
+          FirstInst = I;
+        continue;
+      }
+      assert(isVectorLikeInstWithConstOps(FirstInst) &&
+             isVectorLikeInstWithConstOps(I) &&
+             "Expected vector-like insts only.");
+      if (!DT->isReachableFromEntry(FirstInst->getParent())) {
+        FirstInst = I;
+        continue;
+      }
+      if (!DT->isReachableFromEntry(I->getParent()))
+        continue;
+      auto *NodeA = DT->getNode(FirstInst->getParent());
+      auto *NodeB = DT->getNode(I->getParent());
+      assert(NodeA && "Should only process reachable instructions");
+      assert(NodeB && "Should only process reachable instructions");
+      assert((NodeA == NodeB) ==
+                 (NodeA->getDFSNumIn() == NodeB->getDFSNumIn()) &&
+             "Different nodes should have 
diff erent DFS numbers");
+      if (NodeA->getDFSNumIn() > NodeB->getDFSNumIn())
         FirstInst = I;
     }
     return FirstInst;
@@ -7708,9 +7729,12 @@ Instruction &BoUpSLP::getLastInstructionInBundle(const TreeEntry *E) {
   // Set the insert point to the beginning of the basic block if the entry
   // should not be scheduled.
   if (E->State != TreeEntry::NeedToGather &&
-      doesNotNeedToSchedule(E->Scalars)) {
+      (doesNotNeedToSchedule(E->Scalars) ||
+       all_of(E->Scalars, isVectorLikeInstWithConstOps))) {
     Instruction *InsertInst;
-    if (all_of(E->Scalars, isUsedOutsideBlock))
+    if (all_of(E->Scalars, [](Value *V) {
+          return !isVectorLikeInstWithConstOps(V) && isUsedOutsideBlock(V);
+        }))
       InsertInst = FindLastInst();
     else
       InsertInst = FindFirstInst();
@@ -8135,7 +8159,7 @@ Value *BoUpSLP::vectorizeTree(TreeEntry *E) {
 
     case Instruction::ExtractElement: {
       Value *V = E->getSingleOperand(0);
-      Builder.SetInsertPoint(VL0);
+      setInsertPointAfterBundle(E);
       ShuffleBuilder.addInversedMask(E->ReorderIndices);
       ShuffleBuilder.addMask(E->ReuseShuffleIndices);
       V = ShuffleBuilder.finalize(V);

diff  --git a/llvm/test/Transforms/SLPVectorizer/X86/extractelement-insertpoint.ll b/llvm/test/Transforms/SLPVectorizer/X86/extractelement-insertpoint.ll
new file mode 100644
index 000000000000..0d53121c9dee
--- /dev/null
+++ b/llvm/test/Transforms/SLPVectorizer/X86/extractelement-insertpoint.ll
@@ -0,0 +1,31 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
+; RUN: opt -S -slp-vectorizer -mtriple=x86_64-grtev4-linux-gnu -o - < %s | FileCheck %s
+
+define i32 @crash() {
+; CHECK-LABEL: @crash(
+; CHECK-NEXT:  label:
+; CHECK-NEXT:    [[ADD:%.*]] = fadd <2 x double> zeroinitializer, zeroinitializer
+; CHECK-NEXT:    [[SHUFFLE:%.*]] = shufflevector <2 x double> [[ADD]], <2 x double> poison, <2 x i32> <i32 1, i32 0>
+; CHECK-NEXT:    [[TMP0:%.*]] = shufflevector <2 x double> zeroinitializer, <2 x double> [[SHUFFLE]], <2 x i32> <i32 2, i32 1>
+; CHECK-NEXT:    [[TMP1:%.*]] = fmul <2 x double> [[SHUFFLE]], zeroinitializer
+; CHECK-NEXT:    [[TMP2:%.*]] = extractelement <2 x double> [[TMP1]], i32 0
+; CHECK-NEXT:    [[TMP3:%.*]] = extractelement <2 x double> [[TMP1]], i32 1
+; CHECK-NEXT:    [[ADD1:%.*]] = fadd double [[TMP2]], [[TMP3]]
+; CHECK-NEXT:    [[MUL1:%.*]] = fmul double [[ADD1]], 0.000000e+00
+; CHECK-NEXT:    store double [[MUL1]], double* null, align 16
+; CHECK-NEXT:    ret i32 0
+;
+label:
+  %0 = extractelement <2 x double> zeroinitializer, i64 1
+  %1 = extractelement <2 x double> zeroinitializer, i64 0
+  %add = fadd <2 x double> zeroinitializer, zeroinitializer
+  %extract1 = extractelement <2 x double> %add, i64 1
+  %2 = fmul double %extract1, %1
+  %insert = insertelement <2 x double> zeroinitializer, double %extract1, i64 0
+  %extract0 = extractelement <2 x double> %add, i64 0
+  %mul = fmul double %extract0, %0
+  %add1 = fadd double %2, %mul
+  %mul1 = fmul double %add1, 0.000000e+00
+  store double %mul1, double* null, align 16
+  ret i32 0
+}


        


More information about the llvm-commits mailing list