aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Transforms/Utils/LoopUnrollRuntime.cpp
diff options
context:
space:
mode:
authorNikita Popov <npopov@redhat.com>2022-05-18 17:09:36 +0200
committerNikita Popov <npopov@redhat.com>2022-05-24 09:42:39 +0200
commit81c648a3d909cf0c1c1c635309f35b93d07307d1 (patch)
tree898571b5b8aa178e91b0114e66f87365d3e749dd /llvm/lib/Transforms/Utils/LoopUnrollRuntime.cpp
parentbe84f91f87a787ebfa8a346e936a5c88bc87b047 (diff)
downloadllvm-81c648a3d909cf0c1c1c635309f35b93d07307d1.zip
llvm-81c648a3d909cf0c1c1c635309f35b93d07307d1.tar.gz
llvm-81c648a3d909cf0c1c1c635309f35b93d07307d1.tar.bz2
[LoopUnroll] Freeze tripcount rather than condition
This is a followup to D125754. We introduce two branches, one before the unrolled loop and one before the epilogue (and similar for the prologue case). The previous patch only froze the condition on the first branch. Rather than independently freezing the second condition, this patch instead freezes TripCount and bases BECount on it. These are the two quantities involved in the conditions, and this ensures that both work on a consistent, non-poisonous trip count. Differential Revision: https://reviews.llvm.org/D125896
Diffstat (limited to 'llvm/lib/Transforms/Utils/LoopUnrollRuntime.cpp')
-rw-r--r--llvm/lib/Transforms/Utils/LoopUnrollRuntime.cpp28
1 files changed, 20 insertions, 8 deletions
diff --git a/llvm/lib/Transforms/Utils/LoopUnrollRuntime.cpp b/llvm/lib/Transforms/Utils/LoopUnrollRuntime.cpp
index 71c15f9..37a013c 100644
--- a/llvm/lib/Transforms/Utils/LoopUnrollRuntime.cpp
+++ b/llvm/lib/Transforms/Utils/LoopUnrollRuntime.cpp
@@ -738,11 +738,28 @@ bool llvm::UnrollRuntimeLoopRemainder(
// Compute the number of extra iterations required, which is:
// extra iterations = run-time trip count % loop unroll factor
PreHeaderBR = cast<BranchInst>(PreHeader->getTerminator());
+ IRBuilder<> B(PreHeaderBR);
Value *TripCount = Expander.expandCodeFor(TripCountSC, TripCountSC->getType(),
PreHeaderBR);
- Value *BECount = Expander.expandCodeFor(BECountSC, BECountSC->getType(),
- PreHeaderBR);
- IRBuilder<> B(PreHeaderBR);
+ Value *BECount;
+ // If there are other exits before the latch, that may cause the latch exit
+ // branch to never be executed, and the latch exit count may be poison.
+ // In this case, freeze the TripCount and base BECount on the frozen
+ // TripCount. We will introduce two branches using these values, and it's
+ // important that they see a consistent value (which would not be guaranteed
+ // if were frozen independently.)
+ if ((!OtherExits.empty() || !SE->loopHasNoAbnormalExits(L)) &&
+ !isGuaranteedNotToBeUndefOrPoison(TripCount, AC, PreHeaderBR, DT)) {
+ TripCount = B.CreateFreeze(TripCount);
+ BECount =
+ B.CreateAdd(TripCount, ConstantInt::get(TripCount->getType(), -1));
+ } else {
+ // If we don't need to freeze, use SCEVExpander for BECount as well, to
+ // allow slightly better value reuse.
+ BECount =
+ Expander.expandCodeFor(BECountSC, BECountSC->getType(), PreHeaderBR);
+ }
+
Value * const ModVal = CreateTripRemainder(B, BECount, TripCount, Count);
Value *BranchVal =
@@ -752,11 +769,6 @@ bool llvm::UnrollRuntimeLoopRemainder(
B.CreateIsNotNull(ModVal, "lcmp.mod");
BasicBlock *RemainderLoop = UseEpilogRemainder ? NewExit : PrologPreHeader;
BasicBlock *UnrollingLoop = UseEpilogRemainder ? NewPreHeader : PrologExit;
- // Freeze the condition if there are other exits before the latch that may
- // cause the latch exit branch to never be executed.
- if ((!OtherExits.empty() || !SE->loopHasNoAbnormalExits(L)) &&
- !isGuaranteedNotToBeUndefOrPoison(BranchVal, AC, PreHeaderBR, DT))
- BranchVal = B.CreateFreeze(BranchVal);
// Branch to either remainder (extra iterations) loop or unrolling loop.
B.CreateCondBr(BranchVal, RemainderLoop, UnrollingLoop);
PreHeaderBR->eraseFromParent();