https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86389
--- Comment #10 from Richard Biener <rguenth at gcc dot gnu.org> ---
-fdisable-tree-dom2 fixes it, DOM2 does
--- a/vector_subscript_1.f90.127t.dom2 2021-08-24 15:41:19.245450872 +0200
+++ b/vector_subscript_1.f90.127t.dom2 2021-08-24 15:41:23.421513299 +0200
@@ -383,11 +383,11 @@
<bb 9> [local count: 292809384]:
# S.29_149 = PHI <S.29_112(9), 0(8)>
_14 = S.29_149 * -2;
- _110 = MEM <integer(kind=4)D.8[0:]> [(integer(kind=4)D.8[0:] *)&idxD.4029 +
36B][_14];
- _15 = (integer(kind=8)D.9) _110;
- _16 = _15 + -1;
- _17 = FRAME.39D.4164.bD.4167[_16];
- FRAME.39D.4164.aD.4165[_16] = _17;
+ _110 = _84;
+ _15 = _9;
+ _16 = _10;
+ _17 = FRAME.39D.4164.bD.4167[_10];
+ FRAME.39D.4164.aD.4165[_10] = _17;
S.29_112 = S.29_149 + 1;
if (S.29_112 > 2)
goto <bb 10>; [25.00%]
but that's odd, _84 is defined inside another loop
<bb 7> [local count: 292809384]:
# S.24_148 = PHI <S.24_86(7), 0(6)>
_7 = S.24_148 * 3;
_83 = MEM <integer(kind=4)D.8[0:]> [(integer(kind=4)D.8[0:]
*)&idxD.4029][_7];
_8 = S.24_148 * -2;
_84 = MEM <integer(kind=4)D.8[0:]> [(integer(kind=4)D.8[0:] *)&idxD.4029 +
36B][_8];
_9 = (integer(kind=8)D.9) _84;
_10 = _9 + -1;
_11 = (integer(kind=8)D.9) _83;
_12 = _11 + -1;
_13 = FRAME.39D.4164.bD.4167[_10];
FRAME.39D.4164.aD.4165[_12] = _13;
S.24_86 = S.24_148 + 1;
if (S.24_86 > 2)
goto <bb 8>; [25.00%]
else
goto <bb 7>; [75.00%]
there's a call inbetween
test (&parm.25D.4099, &parm.26D.4105); [static-chain: &FRAME.39D.4164]
and IPA PTA is likely required to disambiguate against that.
The second loop looks like (pre DOM):
<bb 9> [local count: 292809384]:
# S.29_149 = PHI <S.29_112(9), 0(8)>
_14 = S.29_149 * -2;
_110 = MEM <integer(kind=4)D.8[0:]> [(integer(kind=4)D.8[0:] *)&idxD.4029 +
36B][_14];
_15 = (integer(kind=8)D.9) _110;
_16 = _15 + -1;
_17 = FRAME.39D.4164.bD.4167[_16];
FRAME.39D.4164.aD.4165[_16] = _17;
S.29_112 = S.29_149 + 1;
if (S.29_112 > 2)
goto <bb 10>; [25.00%]
else
goto <bb 9>; [75.00%]
but sth as simple as the following does not reproduce DOMs behavior.
int a[1024], b[1024], idx[1024];
void foo ()
{
int i = 0;
do
{
int tem = (idx + 2)[-i];
a[tem] = b[tem];
}
while (++i <= 2);
i = 0;
do
{
int tem = (idx + 2)[-i];
a[tem] = b[tem];
}
while (++i <= 2);
}
So I guess it must be sth to do with
MEM <integer(kind=4)[0:]> [(integer(kind=4)[0:] *)&idx + 36B][_14];
and equal_mem_array_ref_p which uses get_ref_base_and_extent somehow
arrives at the conclusion that the referenced array has a single element
and is not trailing... indeed we have 'int idx[10];' here but _14
is negative and the domain is [0:..] which means the access is outside
of the domain of the array. Which means this is likely a frontend issue.
When the frontend lowers idx (10:6:-2) it generates
parm.22D.4083.dimD.4082[0].lboundD.3942 = 1;
parm.22D.4083.dimD.4082[0].uboundD.3943 = 3;
parm.22D.4083.dimD.4082[0].strideD.3941 = -2;
parm.22D.4083.dataD.4078 = (voidD.27 *) &idxD.4029[9];
...
D.4091 = (*(integer(kind=4)D.8[0:] *)
parm.22D.4083.dataD.4078)[parm.22D.4083.dimD.4082[0].strideD.3941 *
NON_LVALUE_EXPR <S.24D.4090>];
and that looks clearly wrong to me.