This is an archive of the discontinued LLVM Phabricator instance.

[SLPVectorizer] Fix extractelement insertion point
AbandonedPublic

Authored by anna on May 31 2022, 11:42 AM.

Details

Summary

7d8060bc1 / D111574 exposed an assertion failure in setInsertPointAfterBundle,
when the extractelement instruction is not in the same basic block as
the rest of the instructions in the bundle.

Updated the insertion point to avoid the assertion failure.
Fixes https://github.com/llvm/llvm-project/issues/55796 and added
testcase.

Diff Detail

Event Timeline

anna created this revision.May 31 2022, 11:42 AM
Herald added a project: Restricted Project. · View Herald TranscriptMay 31 2022, 11:42 AM
anna requested review of this revision.May 31 2022, 11:42 AM
Herald added a project: Restricted Project. · View Herald TranscriptMay 31 2022, 11:42 AM
anna edited the summary of this revision. (Show Details)
anna edited the summary of this revision. (Show Details)

JFI: It also requires updating a lot of tests, around 25 in X86 with CHECK lines updated since the insertion point changed. I have not tested the other targets, but there would be others as well.

Thanks for the patch.

  1. Would be good to check if it affects the vectorization of the SPECs.
  2. I think the test can be reduced more.

The original patch is not the cause of the issue, it just reveals it. This patch also does not fix the issue, it just hides it.

anna added a comment.EditedMay 31 2022, 1:31 PM

Thanks for the patch.

  1. Would be good to check if it affects the vectorization of the SPECs.

Could you pls elaborate? Unfortunately, I don't know what needs to be done here and I think irrespective of any vectorization "performance issue", we would need to fix the *functional problem*.

  1. I think the test can be reduced more.

Will do.

The original patch is not the cause of the issue, it just reveals it. This patch also does not fix the issue, it just hides it.

yes, it exposed the issue and I do not know what the actual issue is. However, we don't have any forward path downstream (with applications failing with this assertion failure) and I believe the ideal solution is to revert the exposing patch, fix the issue correctly and then land it again, if the actual fix is more involved.

As you can see there are a whole bunch of tests that need to be fixed as well for this (at least the X86 ones were CHECK updates) and if this is not the correct fix, I think it best to revert the change to allow unblocking failing issues. I will go ahead with the update for the test case here as requested.

What do you think?

Could you try this patch:

diff --git a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
index db8f97271db6..1f33ad604d11 100644
--- a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
+++ b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
@@ -7237,18 +7237,41 @@ void BoUpSLP::setInsertPointAfterBundle(const TreeEntry *E) {
   auto *BB = Front->getParent();
   assert(llvm::all_of(E->Scalars, [=](Value *V) -> bool {
     auto *I = cast<Instruction>(V);
-    return !E->isOpcodeOrAlt(I) || I->getParent() == BB;
+    return !E->isOpcodeOrAlt(I) || I->getParent() == BB ||
+           isVectorLikeInstWithConstOps(I);
   }));

-  auto &&FindLastInst = [E, Front]() {
+  auto &&FindLastInst = [E, Front, this, &BB]() {
     Instruction *LastInst = Front;
     for (Value *V : E->Scalars) {
       auto *I = dyn_cast<Instruction>(V);
       if (!I)
         continue;
-      if (LastInst->comesBefore(I))
+      if (LastInst->getParent() == I->getParent()) {
+        if (LastInst->comesBefore(I))
+          LastInst = I;
+        continue;
+      }
+      assert(isVectorLikeInstWithConstOps(LastInst) &&
+             isVectorLikeInstWithConstOps(I) &&
+             "Expected vector-like insts only.");
+      if (!DT->isReachableFromEntry(LastInst->getParent())) {
+        LastInst = I;
+        continue;
+      }
+      if (!DT->isReachableFromEntry(I->getParent()))
+        continue;
+      auto *NodeA = DT->getNode(LastInst->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 different DFS numbers");
+      if (NodeA->getDFSNumIn() < NodeB->getDFSNumIn())
         LastInst = I;
     }
+    BB = LastInst->getParent();
     return LastInst;
   };
anna updated this revision to Diff 433195.May 31 2022, 2:34 PM

simplified test case

anna abandoned this revision.Jun 1 2022, 7:49 AM

Abandoned in favour of D126777.