Our SSA copy-prop passes do a pretty pathetic job at cleaning up after
themselves when const/copy propagation exposes new trivial copies and
constant initializations.
This can be seen in the code for pr57904 after copyprop2 for bb2
_2 = 344;
ubound.0_3 = _2 & 7;
size.1_4 = ubound.0_3 + 1;
size.1_5 = MAX_EXPR <size.1_4, 0>;
_6 = size.1_5 * 4;
_7 = (character(kind=4)) _6;
_8 = MAX_EXPR <_7, 1>;
sizes_9 = __builtin_malloc (_8);
size.3_10 = MAX_EXPR <ubound.0_3, 0>;
_11 = size.3_10 * 4;
_12 = (character(kind=4)) _11;
_13 = MAX_EXPR <_12, 1>;
strides_14 = __builtin_malloc (_13);
MEM[(integer(kind=4)[0:D.1917] *)sizes_9][0] = 1;
if (ubound.0_3 > 0)
goto <bb 3>;
else
goto <bb 6>;
We discover _2 = 344 and copyprop that to its uses. However, copyprop
does not discover that the RHS of ubound.0_3's assignment will simplify
into a copy until *after* the main copy propagation algorithm is
complete. ie, that isn't discovered until subsitute_and_fold.
Basically anything that doesn't look like a const/copy initialization
when the pass starts is effectively ignored.
During substitute_and_fold, we substitute the value 344 for uses of _2.
But we don't pick up that ubound.0_3 now has a propagatable value.
Worse yet, because we walk backwards through the statements, even if we
recorded that ubound.0_3 has a propagatable value we wouldn't be able to
utilize that information.
For this particular PR, the lack of good optimization early results in
an unreachable loop being left in the IL and that unreachable loop has
undefined behaviour that we warn about.
As it turns out the phi-only-cprop code can handle this quite easily.
First we move all that stuff from tree-ssa-dom.c into tree-ssa-copy.c.
Then we arrange (via callbacks) for tree-ssa-copy.c to get a
notification when substitute_and_fold does something interesting. In
that callback we set an entry in a bitmap for any newly exposed copies
or constant initializations. That bitmap is then fed into the slightly
refactored phi-only-cprop code as an initial state of potential
copies/constant initializations.
The net result is we collapse out all the necessarray code resulting in:
<bb 2>:
sizes_9 = __builtin_malloc (4);
strides_14 = __builtin_malloc (1);
MEM[(integer(kind=4)[0:D.1917] *)sizes_9][0] = 1;
goto <bb 6>;
bb3 (entry into the loop with undefined behaviour) is no longer
reachable and the loop will get removed and we no longer issue the
annoying warning.
You'll note that I tightened the stmt_may_generate_copy code. It was
returning true for any binary RHS where the first operand was an
invariant. Instead we return true for a UNARY/SINGLE rhs that is
invariant (such as a casted ADDR_EXPR).
Bootstrapped and regression tested on x86_64-unknown-linux-gnu. OK for
the trunk?