[llvm] [LoopVectorize] Refine runtime memory check costs when there is an outer loop (PR #76034)

Florian Hahn via llvm-commits llvm-commits at lists.llvm.org
Thu Jan 25 13:46:58 PST 2024


================
@@ -2076,16 +2081,62 @@ class GeneratedRTChecks {
         LLVM_DEBUG(dbgs() << "  " << C << "  for " << I << "\n");
         RTCheckCost += C;
       }
-    if (MemCheckBlock)
+    if (MemCheckBlock) {
+      InstructionCost MemCheckCost = 0;
       for (Instruction &I : *MemCheckBlock) {
         if (MemCheckBlock->getTerminator() == &I)
           continue;
         InstructionCost C =
             TTI->getInstructionCost(&I, TTI::TCK_RecipThroughput);
         LLVM_DEBUG(dbgs() << "  " << C << "  for " << I << "\n");
-        RTCheckCost += C;
+        MemCheckCost += C;
       }
 
+      // If the runtime memory checks are being created inside an outer loop
+      // we should find out if these checks are outer loop invariant. If so,
+      // the checks will likely be hoisted out and so the effective cost will
+      // reduce according to the outer loop trip count.
+      if (OuterLoop) {
+        ScalarEvolution *SE = MemCheckExp.getSE();
+        // TODO: We could refine this further by analysing every individual
+        // memory check, since there could be a mixture of loop variant and
+        // invariant checks that mean the final condition is variant. However,
+        // I think it would need further analysis to prove this is beneficial.
+        const SCEV *Cond = SE->getSCEV(MemRuntimeCheckCond);
+        if (SE->isLoopInvariant(Cond, OuterLoop)) {
+          // It seems reasonable to assume that we can reduce the effective
+          // cost of the checks even when we know nothing about the trip
+          // count. Here I've assumed that the outer loop executes at least
----------------
fhahn wrote:

nit: still refers to `I`, better to rephrase or use more general `we`

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


More information about the llvm-commits mailing list