[llvm] LoopLoadElim: don't version single-iteration loops (PR #97599)

Florian Hahn via llvm-commits llvm-commits at lists.llvm.org
Wed Aug 28 12:41:42 PDT 2024


================
@@ -598,10 +598,11 @@ class LoadEliminationForLoop {
       }
 
       // Point of no-return, start the transformation.  First, version the loop
-      // if necessary.
-
-      LoopVersioning LV(LAI, Checks, L, LI, DT, PSE.getSE());
-      LV.versionLoop();
+      // if it's not a single-iteration loop.
+      if (!PSE.getBackedgeTakenCount()->isOne()) {
----------------
fhahn wrote:

That's an interesting point, thanks! One thing to note is that BTC == 1 means that the backed I taken once, i.e. the loop body executes twice IIUC (e.g. see https://llvm.godbolt.org/z/E385vqb4M for `@single_iteration_unknown_stride`, which has BTC = 0)

Taking a step back, `@lver.check.unnecessary` from https://github.com/llvm/llvm-project/issues/96656 should be handled by checking for BTC == 0?

For BTC == 0, it should indeed not be a correctness issue, as we only execute a single iteration. But then the transform isn't needed, so it would still be better to bail out.

> Here's the Alive2 proof for the transformation in the test: https://alive2.llvm.org/ce/z/fKWdPi.

Thanks for sharing. Unfortunately Alive2's reasoning about loops can be a bit surprising. I am not able to summarize the way the reasoning works at the moment, but IIUC it only reasons about the straight-line paths in the CFG, so for the link you shared only about the first loop iteration.

To work around the limitation, there are the `-src-unroll` and `-tgt-unroll` options. E.g. when unrolling by 2, verification fails because now we verify both the first and second iteration. (Apologies, my explanation here may not be completely precise)

https://alive2.llvm.org/ce/z/7g7sg-

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


More information about the llvm-commits mailing list