diff options
author | Nikita Popov <npopov@redhat.com> | 2022-05-17 11:26:14 +0200 |
---|---|---|
committer | Nikita Popov <npopov@redhat.com> | 2022-05-18 09:51:22 +0200 |
commit | 323514de58aba8c073faa37335345338ae57173c (patch) | |
tree | f2b68ae0c932850d73f7a558d96bf5187a9d1219 /llvm/lib/Transforms/Utils/LoopUnrollRuntime.cpp | |
parent | c4c01e4e4e388a1e3cefc9e3982ac15fb94d4f40 (diff) | |
download | llvm-323514de58aba8c073faa37335345338ae57173c.zip llvm-323514de58aba8c073faa37335345338ae57173c.tar.gz llvm-323514de58aba8c073faa37335345338ae57173c.tar.bz2 |
[LoopUnroll] Avoid branch on poison for runtime unroll with multiple exits
When performing runtime unrolling with multiple exits, one of the
earlier (non-latch) exits may exit the loop on the first iteration,
such that we never branch on the latch exit condition. As such, we
need to freeze the condition of the new branch that is introduced
before the loop, as it now executes unconditionally.
Differential Revision: https://reviews.llvm.org/D125754
Diffstat (limited to 'llvm/lib/Transforms/Utils/LoopUnrollRuntime.cpp')
-rw-r--r-- | llvm/lib/Transforms/Utils/LoopUnrollRuntime.cpp | 6 |
1 files changed, 6 insertions, 0 deletions
diff --git a/llvm/lib/Transforms/Utils/LoopUnrollRuntime.cpp b/llvm/lib/Transforms/Utils/LoopUnrollRuntime.cpp index 0fa6f02..71c15f9 100644 --- a/llvm/lib/Transforms/Utils/LoopUnrollRuntime.cpp +++ b/llvm/lib/Transforms/Utils/LoopUnrollRuntime.cpp @@ -25,6 +25,7 @@ #include "llvm/Analysis/InstructionSimplify.h" #include "llvm/Analysis/LoopIterator.h" #include "llvm/Analysis/ScalarEvolution.h" +#include "llvm/Analysis/ValueTracking.h" #include "llvm/IR/BasicBlock.h" #include "llvm/IR/Dominators.h" #include "llvm/IR/MDBuilder.h" @@ -751,6 +752,11 @@ 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(); |