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.