================
@@ -2018,9 +2018,38 @@ bool GVNPass::performLoopLoadPRE(LoadInst *Load,
if (LoadPtr->canBeFreed())
return false;
- // TODO: Support critical edge splitting if blocker has more than 1
successor.
+ // The reload is inserted at the end of the chosen in-loop block so its value
+ // reaches the header along the path back to the latch. If that block has
+ // multiple successors, inserting there would also run the load on paths that
+ // leave the loop. Split the critical edge to the unique in-loop successor so
+ // the reload only runs on the path that feeds the header.
+ BasicBlock *InsertBlock = LoopBlock;
+ if (LoopBlock->getTerminator()->getNumSuccessors() != 1) {
+ BasicBlock *InLoopSucc = nullptr;
+ for (BasicBlock *Succ : successors(LoopBlock)) {
+ if (!L->contains(Succ))
+ continue;
+ // Bail if there is more than one in-loop successor: it is then unclear
+ // which edge carries the value back to the header.
+ if (InLoopSucc)
----------------
antoniofrighetto wrote:
I'm not sure this is framing correctly enough why we would be bailing out. At
least in the suggested test (`test_load_on_cold_path_multi_inloop_succ`), I
think we may be able to perform PRE since both `cold_succ_a` and `cold_succ_b`
jump to the dominating block `backedge` (the first load would be hoisted out of
the loop, the reload would be placed after the side effect call, and `backedge`
would be merging the load from `hot_path`, and the two cold successors). Since
it would be harder in the general case, I may suggest something as follows:
```suggestion
// Split the edge only when one of the two successors is the
// backedge.
if (InLoopSucc)
```
https://github.com/llvm/llvm-project/pull/206694
_______________________________________________
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits