This is an archive of the discontinued LLVM Phabricator instance.

[RLEV] Pick a correct insert point when incoming instruction is itself a phi node
ClosedPublic

Authored by reames on Aug 24 2022, 9:45 AM.

Details

Summary

This fixes https://github.com/llvm/llvm-project/issues/57336. It was exposed by a recent SCEV change, but appears to have been a long standing issue.

Note that the whole insert into the loop instead of a split exit edge is slightly contrived to begin with; it's there solely because IndVarSimplify preserves the CFG.

Diff Detail

Event Timeline

reames created this revision.Aug 24 2022, 9:45 AM
reames requested review of this revision.Aug 24 2022, 9:45 AM
Herald added a project: Restricted Project. · View Herald TranscriptAug 24 2022, 9:45 AM

Thanks, I've verified that this solves the problem I saw in
https://github.com/llvm/llvm-project/issues/57336
as well as my original unreduced reproducer.

nikic added inline comments.Aug 29 2022, 7:50 AM
llvm/lib/Transforms/Utils/LoopUtils.cpp
1400

Any reason we don't just use PN->getIncomingBlock(i)->getTerminator() as the insertion point? That seems like a more obvious place to materialize an edge value.

llvm/test/Transforms/IndVarSimplify/rewrite-loop-exit-value.ll
188

Can you please return the value from the function? The problem is a bit hard to understand if the RLEV results gets optimized away.

reames updated this revision to Diff 456411.Aug 29 2022, 11:05 AM

Address review comment.

llvm/lib/Transforms/Utils/LoopUtils.cpp
1400

I'd been trying for a minimal fix. Do you mind if we land this, and then do a follow up change as you suggest? It'll cause significant test diffs which I think obscure the (rather narrow) impact of the fix.

nikic accepted this revision.Aug 29 2022, 11:33 AM

LG

llvm/lib/Transforms/Utils/LoopUtils.cpp
1400

Sure

This revision is now accepted and ready to land.Aug 29 2022, 11:33 AM
This revision was landed with ongoing or failed builds.Aug 29 2022, 11:46 AM
This revision was automatically updated to reflect the committed changes.
reames added inline comments.Aug 29 2022, 11:56 AM
llvm/lib/Transforms/Utils/LoopUtils.cpp
1400

Went to do this in a follow up, and realized it's more complicated than it sounds.

Since a loop can have multiple exiting blocks which share a single exit block, there is no single source for the exiting edge. Instead, we'd have to either a) duplicate the expansion or b) find a common dominating point. The current code effectively does the later, and leaves the decision on whether to duplicate in order to sink to later code.

(Remember: SCEV expander reuses expressions, so expanding the same expression at the same point multiple times only results in one expansion.)

It's not entirely clear to me we *should* do running RLEV when we can't sink, but it's definitely not a straight forward NFC any more.

Unless you feel strongly about this, I'm not going to follow up further.

nikic added inline comments.Aug 29 2022, 12:10 PM
llvm/lib/Transforms/Utils/LoopUtils.cpp
1400

Oh, that makes sense. It's fine to leave it as is then.

What we should be able to do is require that the loop has dedicated exits (which is part of loop simplify, and as such a prerequisite for indvars anyway), in which case placing the expansion in the exit and replacing the lcssa phi node should be fine (right?)

nikic added inline comments.Aug 29 2022, 12:12 PM
llvm/lib/Transforms/Utils/LoopUtils.cpp
1400

Eh, ignore my last comment, that's just wrong. Dedicated exits don't forbid having multiple incoming edges from the same loop.

reames added inline comments.Aug 29 2022, 12:13 PM
llvm/lib/Transforms/Utils/LoopUtils.cpp
1400

I think this should work. That would imply the multiple entry phi handling in this code is redundant and could be simplified away as well.

reames added inline comments.Aug 29 2022, 12:14 PM
llvm/lib/Transforms/Utils/LoopUtils.cpp
1400

Amusingly, I made the same mistake in my response.

yrouban added a subscriber: yrouban.Sep 1 2022, 5:24 AM
yrouban added inline comments.Sep 1 2022, 5:29 AM
llvm/lib/Transforms/Utils/LoopUtils.cpp
1398–1400

Would it be better to fix SCEVExpander::expandCodeForImpl(const SCEV *SH, Type *Ty, Instruction *IP, bool Root) so it fixed IP in the same way? It would fix all its users.

reames added inline comments.Sep 1 2022, 8:03 AM
llvm/lib/Transforms/Utils/LoopUtils.cpp
1398–1400

No. any routine given an insertion point should use it. It might make sense to add an *assert* that the insertion point is sane, but mutating the insertion point explicitly would be quite confusing.

yrouban added inline comments.Sep 1 2022, 9:02 AM
llvm/lib/Transforms/Utils/LoopUtils.cpp
1398–1400

Ok, but in this particular case the insertion point can be adjusted by hoisting in SCEVExpander::expand(). In other words the insertion point passed as argument is not final.