[llvm] a16308c - [SLP] Explicit track required stacksave/alloca dependency (try 3)

Philip Reames via llvm-commits llvm-commits at lists.llvm.org
Fri Mar 25 10:04:49 PDT 2022


Author: Philip Reames
Date: 2022-03-25T10:04:10-07:00
New Revision: a16308c2823b37721f786a911323f55b313f6d77

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

LOG: [SLP] Explicit track required stacksave/alloca dependency (try 3)

This is an extension of commit b7806c to handle one last case noticed in test changes for D118538.  Again, this is thought to be a latent bug in the existing code, though this time I have not managed to reduce tests for the original algoritthm.

The prior attempt had failed to account for this case:
  %a = alloca i8
  stacksave
  stackrestore
  store i8 0, i8* %a

If we allow '%a' to reorder into the stacksave/restore region, then the alloca will be deallocated before the use.  We will have taken a well defined program, and introduced a use-after-free bug.

There's also an inverse case where the alloca originally follows the stackrestore, and we need to prevent the reordering it above the restore.

Compile time wise, we potentially do an extra scan of the block for each alloca seen in a bundle.  This is significantly more expensive than the stacksave rooted version and is why I'd tried to avoid this in the initial patch.  There is room to optimize this (by essentially caching a "has stacksave" bit per block), but I'm leaving that to future work if it actually shows up in practice.  Since allocas in bundles should be rare in practice, I suspect we can defer the complexity for a long while.

Added: 
    

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 e8daa02958ae1..7296dba13aaac 100644
--- a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
+++ b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
@@ -8100,11 +8100,14 @@ void BoUpSLP::BlockScheduling::calculateDependencies(ScheduleData *SD,
       }
 
       // If we have an inalloc alloca instruction, it needs to be scheduled
-      // after any preceeding stacksave.
-      if (match(BundleMember->Inst, m_Intrinsic<Intrinsic::stacksave>())) {
+      // after any preceeding stacksave.  We also need to prevent any alloca
+      // from reordering above a preceeding stackrestore.
+      if (match(BundleMember->Inst, m_Intrinsic<Intrinsic::stacksave>()) ||
+          match(BundleMember->Inst, m_Intrinsic<Intrinsic::stackrestore>())) {
         for (Instruction *I = BundleMember->Inst->getNextNode();
              I != ScheduleEnd; I = I->getNextNode()) {
-          if (match(I, m_Intrinsic<Intrinsic::stacksave>()))
+          if (match(I, m_Intrinsic<Intrinsic::stacksave>()) ||
+              match(I, m_Intrinsic<Intrinsic::stackrestore>()))
             // Any allocas past here must be control dependent on I, and I
             // must be memory dependend on BundleMember->Inst.
             break;
@@ -8117,6 +8120,21 @@ void BoUpSLP::BlockScheduling::calculateDependencies(ScheduleData *SD,
         }
       }
 
+      // In addition to the cases handle just above, we need to prevent
+      // allocas from moving below a stacksave.  The stackrestore case
+      // is currently thought to be conservatism.
+      if (isa<AllocaInst>(BundleMember->Inst)) {
+        for (Instruction *I = BundleMember->Inst->getNextNode();
+             I != ScheduleEnd; I = I->getNextNode()) {
+          if (!match(I, m_Intrinsic<Intrinsic::stacksave>()) &&
+              !match(I, m_Intrinsic<Intrinsic::stackrestore>()))
+            continue;
+
+          // Add the dependency
+          makeControlDependent(I);
+          break;
+        }
+      }
 
       // Handle the memory dependencies (if any).
       ScheduleData *DepDest = BundleMember->NextLoadStore;


        


More information about the llvm-commits mailing list