[PATCH] D37460: [GVN] Prevent LoadPRE from hoisting through guards
Daniel Berlin via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Fri Sep 8 12:55:46 PDT 2017
dberlin added inline comments.
================
Comment at: lib/Transforms/Scalar/GVN.cpp:2042
+ auto *II = dyn_cast<IntrinsicInst>(&I);
+ return II && II->getIntrinsicID() == Intrinsic::experimental_guard;
+ };
----------------
efriedma wrote:
> Why does this specifically apply to guards, as opposed to anything where isGuaranteedToTransferExecutionToSuccessor() is false?
Yeah, it looks like GVN presumes that if it's a straight line non-infinite loop, they have the same "guaranteed to execute" properties.
As you correctly point out, since LLVM has implicit control flow, this is not always true.
I suspect GVN's PRE is quite broken here in that respect in theory.
However, most of the effect of isGuaranteed is on memory instructions, and those almost certainly get corrected by memdep (IE it ends up respecting the same things that isGuaranteed* is respecting).
Going through the rest:
```
if (const auto *CRI = dyn_cast<CleanupReturnInst>(I))
return !CRI->unwindsToCaller();
if (const auto *CatchSwitch = dyn_cast<CatchSwitchInst>(I))
return !CatchSwitch->unwindsToCaller();
if (isa<ResumeInst>(I))
return false;
if (isa<ReturnInst>(I))
return false;
if (isa<UnreachableInst>(I))
return false;
```
None of these will have successors, so there shouldn't be a predecessor we hit to check anyway.
You can hoist above them, just not sink below them.
So those should be fine.
The callsite checking, except for throwing, is probably also handled by memdep's insertion of memory dependencies.
So I suspect you may be able to rig up a testcase where memdep and isGuaranteed* end up disagreeing in a way that causes this to break. But i also suspect it's hard.
Thoughts?
https://reviews.llvm.org/D37460
More information about the llvm-commits
mailing list