In rG6a076fa9539e, a problem with updating the old/narrow phi nodes after IV widening was introduced. If after widening of the IV the transformation is *not* applied, the narrow phi node was incorrectly modified, which should only happen if flattening happens. This can be seen in the added test widen-iv2.ll, which incorrectly had 1 incoming value, but should have its original 2 incoming values, which is now restored.
Details
Diff Detail
- Repository
- rG LLVM Github Monorepo
Event Timeline
llvm/lib/Transforms/Scalar/LoopFlatten.cpp | ||
---|---|---|
725 | Deleted is now unused? |
llvm/lib/Transforms/Scalar/LoopFlatten.cpp | ||
---|---|---|
725 | Thanks for taking a look at this. Function CreateWideIV takes and sets a bool if the phi node was trivially deleted. Above, on line 720, we pass FI.IsTriviallyDeletedPhi. We want to record this state for the inner induction phi, because it's the inner loop that gets removed. But here, for the outer loop, we don't really care about this. So it's not really used, and we pass in a dummy Deleted boolean. |
Can we add the inner phi that was not deleted to InnerPHIsToTransform? That would allow us to hold less state, hopefully simplifying things a little.
llvm/lib/Transforms/Scalar/LoopFlatten.cpp | ||
---|---|---|
104 | Other places add to InnerInductionPHI. Is it always safe (now and in the future) to assume they are all narrow induction phis? |
Reverting to previous revision: don't conflate narrow and phis that will be transformed in InnerInductionPHI.
@dmgreen : I propose to keep this revision. The extra bit of state for NarrowInnerInductionPHI and NarrowOuterInductionPHI is needed anyway, to checks on the phi nodes (and skip these ones). That's why e.g. just this is not enough:
diff --git a/llvm/lib/Transforms/Scalar/LoopFlatten.cpp b/llvm/lib/Transforms/Scalar/LoopFlatten.cpp index 931bcc2aada6..f81eb07b5425 100644 --- a/llvm/lib/Transforms/Scalar/LoopFlatten.cpp +++ b/llvm/lib/Transforms/Scalar/LoopFlatten.cpp @@ -711,7 +711,7 @@ static bool CanWidenIV(FlattenInfo &FI, DominatorTree *DT, LoopInfo *LI, // If the inner Phi node cannot be trivially deleted, we need to at least // bring it in a consistent state. if (!Deleted) - FI.InnerInductionPHI->removeIncomingValue(FI.InnerLoop->getLoopLatch()); + FI.InnerPHIsToTransform.insert(FI.InnerInductionPHI); if (!CreateWideIV({FI.OuterInductionPHI, MaxLegalType, false }, Deleted)) return false;
And I think it is clearer to keep these narrow phi separate from InnerPHIsToTransform. Let me know what you think.
Ok, think I got what you meant. This gets rid of the extra state IsTriviallyDeletedPhi and adds to InnerPHIsToTransform so that the phi will be adjusted (and we don't need to add extra code for that).
Other places add to InnerInductionPHI. Is it always safe (now and in the future) to assume they are all narrow induction phis?