This is an archive of the discontinued LLVM Phabricator instance.

Fix SROA with a PHI mergig values from a same block
ClosedPublic

Authored by rampitec on Oct 22 2020, 11:25 AM.

Details

Summary

This fixes the bug 47945. It is legal to have a PHI with values
from from the same block, but values must stay the same. In this
case it is illegal to merge different values.

Diff Detail

Event Timeline

rampitec created this revision.Oct 22 2020, 11:25 AM
Herald added a project: Restricted Project. · View Herald TranscriptOct 22 2020, 11:25 AM
Herald added a subscriber: hiraditya. · View Herald Transcript
rampitec requested review of this revision.Oct 22 2020, 11:25 AM
efriedma added inline comments.
llvm/lib/Transforms/Scalar/SROA.cpp
3527

I don't think that's what you want to check. In particular, it doesn't handle the case where a block has multiple predecessors containing a construct like br i1 undef, label %cond.end.i, label %cond.end.i (or more commonly, a switch).

rampitec added inline comments.Oct 22 2020, 4:56 PM
llvm/lib/Transforms/Scalar/SROA.cpp
3527

Do you mean it is legal to have several incoming values from a same block and then some from another?

efriedma added inline comments.Oct 22 2020, 5:19 PM
llvm/lib/Transforms/Scalar/SROA.cpp
3527

Yes. For example, https://godbolt.org/z/6b86Ts .

rampitec updated this revision to Diff 300174.Oct 22 2020, 11:35 PM
rampitec marked 2 inline comments as done.
rampitec retitled this revision from Fix SROA with a constant value PHI to Fix SROA with a PHI mergig values from a same block.

Changed check to only allow unique blocks.

I don't know what the best fix is, but I've verified that this patch solves the problem I saw and I haven't seen anything weird pop up with the patch in some limited testing I've done with it.
Thanks!

lebedev.ri added a subscriber: lebedev.ri.
lebedev.ri added inline comments.
llvm/lib/Transforms/Scalar/SROA.cpp
3534–3536

Am i correctly reading that this is preventing the fold if PHI has the same incoming BB more than once?

3541–3561

Can't you instead simply cache GEP's, i.e. have a map<basicblock, NewVal>,
and perform this GEP creation only if there is no previous gep for that incoming bb in the map?

rampitec added inline comments.Oct 26 2020, 8:32 AM
llvm/lib/Transforms/Scalar/SROA.cpp
3534–3536

Right.

3541–3561

I thought about it. but it seems to miss the target. It will not help SROA to eliminate an alloca as far as I understand, so there seems to be no reason to do it.

lebedev.ri added inline comments.Oct 26 2020, 8:35 AM
llvm/lib/Transforms/Scalar/SROA.cpp
3541–3561

I'm not sure why it would matter to SROA, that sounds like an unrelated bug that should be fixed..
I think it would be more future-proof fix.

rampitec updated this revision to Diff 300765.Oct 26 2020, 12:52 PM
rampitec marked 2 inline comments as done.

Reuse a value for the same block instead of bailing.

llvm/lib/Transforms/Scalar/SROA.cpp
3541–3561

Looks like it actually works as expected.

lebedev.ri accepted this revision.Oct 26 2020, 12:54 PM

LGTM, thank you!

This revision is now accepted and ready to land.Oct 26 2020, 12:54 PM
This revision was automatically updated to reflect the committed changes.
efriedma added inline comments.Oct 27 2020, 11:47 AM
llvm/lib/Transforms/Scalar/SROA.cpp
3550

getBasicBlockIndex is linear in the number of operands, so this is overall O(N^2) in the number of PHI operands. Unlikely to matter in most cases, but maybe we should bail out if there are too many operands.

rampitec added inline comments.Oct 27 2020, 12:00 PM
llvm/lib/Transforms/Scalar/SROA.cpp
3550

I think we can if we ever see such a PHI. Then alloca will remain, so overall it may be slower to work on a non-optimized code.