[llvm] [VPlan] Hoist predicated loads with complementary masks. (PR #168373)

Ramkumar Ramachandra via llvm-commits llvm-commits at lists.llvm.org
Fri Nov 21 03:36:28 PST 2025


================
@@ -3974,6 +3974,152 @@ void VPlanTransforms::hoistInvariantLoads(VPlan &Plan) {
   }
 }
 
+// Returns the intersection of metadata from a group of loads.
+static VPIRMetadata getCommonLoadMetadata(ArrayRef<VPReplicateRecipe *> Loads) {
+  VPIRMetadata CommonMetadata = *Loads.front();
+  for (VPReplicateRecipe *Load : drop_begin(Loads))
+    CommonMetadata.intersect(*Load);
+  return CommonMetadata;
+}
+
+// Check if a load can be hoisted by verifying it doesn't alias with any stores
+// in blocks between FirstBB and LastBB using scoped noalias metadata.
+static bool canHoistLoadWithNoAliasCheck(VPReplicateRecipe *Load,
+                                         VPBasicBlock *FirstBB,
+                                         VPBasicBlock *LastBB) {
+  // Get the load's memory location and check if it aliases with any stores
+  // using scoped noalias metadata.
+  auto LoadLoc = vputils::getMemoryLocation(*Load);
+  if (!LoadLoc || !LoadLoc->AATags.Scope)
+    return false;
+
+  const AAMDNodes &LoadAA = LoadLoc->AATags;
+  for (VPBlockBase *Block = FirstBB; Block;
+       Block = Block->getSingleSuccessor()) {
+    // This function assumes a simple linear chain of blocks. If there are
+    // multiple successors, we would need more complex analysis.
+    assert(Block->getNumSuccessors() <= 1 &&
+           "Expected at most one successor in block chain");
+    auto *VPBB = cast<VPBasicBlock>(Block);
+    for (VPRecipeBase &R : *VPBB) {
+      if (R.mayWriteToMemory()) {
+        auto Loc = vputils::getMemoryLocation(R);
+        // Bail out if we can't get the location or if the scoped noalias
+        // metadata indicates potential aliasing.
+        if (!Loc || ScopedNoAliasAAResult::mayAliasInScopes(
+                        LoadAA.Scope, Loc->AATags.NoAlias))
+          return false;
+      }
+    }
+
+    if (Block == LastBB)
+      break;
----------------
artagnon wrote:

```suggestion
  for (VPBlockBase *Block = FirstBB; Block && Block != LastBB;
       Block = Block->getSingleSuccessor()) {
    // This function assumes a simple linear chain of blocks. If there are
    // multiple successors, we would need more complex analysis.
    assert(Block->getNumSuccessors() <= 1 &&
           "Expected at most one successor in block chain");
    auto *VPBB = cast<VPBasicBlock>(Block);
    for (VPRecipeBase &R : *VPBB) {
      if (R.mayWriteToMemory()) {
        auto Loc = vputils::getMemoryLocation(R);
        // Bail out if we can't get the location or if the scoped noalias
        // metadata indicates potential aliasing.
        if (!Loc || ScopedNoAliasAAResult::mayAliasInScopes(
                        LoadAA.Scope, Loc->AATags.NoAlias))
          return false;
      }
    }
```

https://github.com/llvm/llvm-project/pull/168373


More information about the llvm-commits mailing list