https://gcc.gnu.org/g:ee30e2586a3142e63daaf301a561984f1d22d38d
commit r15-7665-gee30e2586a3142e63daaf301a561984f1d22d38d Author: Richard Biener <rguent...@suse.de> Date: Fri Feb 21 09:58:04 2025 +0100 tree-optimization/118954 - avoid UB on ref created by predcom When predicitive commoning moves an invariant ref it makes sure to not build a MEM_REF with a base that is negatively offsetted from an object. But in trying to preserve some transforms it does not consider association of a constant offset with the address computation in DR_BASE_ADDRESS leading to exactly this problem again. This is arguably a problem in data-ref analysis producing such an out-of-bound DR_BASE_ADDRESS, but this looks quite involved to fix, so the following avoids the association in one more case. This fixes the testcase while preserving the desired transform in gcc.dg/tree-ssa/predcom-1.c. PR tree-optimization/118954 * tree-predcom.cc (ref_at_iteration): Make sure to not associate the constant offset with DR_BASE_ADDRESS when that is an offsetted pointer. * gcc.dg/torture/pr118954.c: New testcase. Diff: --- gcc/testsuite/gcc.dg/torture/pr118954.c | 22 ++++++++++++++++++++++ gcc/tree-predcom.cc | 3 ++- 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/gcc/testsuite/gcc.dg/torture/pr118954.c b/gcc/testsuite/gcc.dg/torture/pr118954.c new file mode 100644 index 000000000000..6b95e0b8c46f --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr118954.c @@ -0,0 +1,22 @@ +/* { dg-do run } */ +/* { dg-additional-options "-fpredictive-commoning" } */ + +int a, b, c, d; +void e(int f) +{ + int g[] = {5, 8}; + int *h = g; + while (c < f) { + d = 0; + for (; d < f; d++) + c = h[d]; + } +} +int main() +{ + int i = (0 == a + 1) - 1; + e(i + 3); + if (b != 0) + __builtin_abort (); + return 0; +} diff --git a/gcc/tree-predcom.cc b/gcc/tree-predcom.cc index ade8fbf0b5c3..d45aa3857b9f 100644 --- a/gcc/tree-predcom.cc +++ b/gcc/tree-predcom.cc @@ -1807,7 +1807,8 @@ ref_at_iteration (data_reference_p dr, int iter, then. But for some cases we can retain that to allow tree_could_trap_p to return false - see gcc.dg/tree-ssa/predcom-1.c */ tree addr, alias_ptr; - if (integer_zerop (off)) + if (integer_zerop (off) + && TREE_CODE (DR_BASE_ADDRESS (dr)) != POINTER_PLUS_EXPR) { alias_ptr = fold_convert (reference_alias_ptr_type (ref), coff); addr = DR_BASE_ADDRESS (dr);