This patch modifies the current conditions for loop fusion by ensuring that
either both fusion candidates have a guard, or neither have a guard. This
prevents us from inadvertantly attempting to fuse a guarded loop with a
non-guarded loop.
Details
- Reviewers
Meinersbur Whitney
Diff Detail
- Repository
- rG LLVM Github Monorepo
- Build Status
Buildable 42603 Build 43128: arc lint + arc unit
Event Timeline
| llvm/test/Transforms/LoopFusion/cannot_fuse.ll | ||
|---|---|---|
| 421 | optional: | |
| llvm/lib/Transforms/Scalar/LoopFuse.cpp | ||
|---|---|---|
| 1070 | haveIdenticalGuards() is not called with both candidates unguarded, so (!FC0.GuardBranch && !FC1.GuardBranch) is impossible. | |
LGTM. @Whitney?
I know that @kbarton is working on a patch which allow guarded loops fuse with unguarded loops as long as they are control flow equivalent.
I think that's a better solution. And with that, this patch is no longer needed.
However, I don't mind having this patch committed in the meantime.
I wonder if this issue still exists in llvm trunk.
// Ensure that FC0 and FC1 have identical guards.
// If one (or both) are not guarded, this check is not necessary.
if (FC0->GuardBranch && FC1->GuardBranch &&
!haveIdenticalGuards(*FC0, *FC1) && !TCDifference) {
LLVM_DEBUG(dbgs() << "Fusion candidates do not have identical "
"guards. Not Fusing.\n");
reportLoopFusion<OptimizationRemarkMissed>(*FC0, *FC1,
NonIdenticalGuards);
continue;
}
if (!isSafeToMoveBefore(*FC1->Preheader,
*FC0->Preheader->getTerminator(), DT, &PDT,
&DI)) {
LLVM_DEBUG(dbgs() << "Fusion candidate contains unsafe "
"instructions in preheader. Not fusing.\n");
reportLoopFusion<OptimizationRemarkMissed>(*FC0, *FC1,
NonEmptyPreheader);
continue;
}
if (FC0->GuardBranch) {
assert(FC1->GuardBranch && "Expecting valid FC1 guard branch");It seems we still need add checks to make sure both loops are guarded or neither are guarded. I enabled loop fusion in our compiler for Xtensa at Cadence, and encountered this issue (our llvm base is 10.0.1 at the moment).
[style] (FC0->GuardBranch || FC1->GuardBranch) && !haveIdenticalGuards(*FC0, *FC1)