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)