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.
Details
Diff Detail
- Repository
- rG LLVM Github Monorepo
Event Timeline
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). |
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? |
llvm/lib/Transforms/Scalar/SROA.cpp | ||
---|---|---|
3527 | Yes. For example, https://godbolt.org/z/6b86Ts . |
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!
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>, |
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.. |
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. |
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. |
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. |
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).