https://gcc.gnu.org/g:57efa2046671372c1e17cec6100e23716af688b9
commit r16-9266-g57efa2046671372c1e17cec6100e23716af688b9 Author: Richard Biener <[email protected]> Date: Thu Jun 11 15:51:02 2026 +0200 tree-optimization/125730 - avoid losing track of base in IVOPTs The PR highlights several places where IVOPTs gets lost in tracking an appropriate base to use for a TARGET_MEM_REF. The following addresses the initial place, enough to fix the bug, but already showing difficulties in avoiding fallout. The first place is alloc_iv where we convert the nice pointer IV to an unsigned integer before applying affine canonicalization. Removing that resolves the PR and with the fold_plusminus_mult_expr change tests without regressions on x86_64. PR tree-optimization/125730 * tree-ssa-loop-ivopts.cc (alloc_iv): Do not convert pointer IVs to unsigned before canonicalizing. * gcc.dg/torture/pr125730.c: New testcase. (cherry picked from commit c36539e6fd0dfa6bd1ebb891df68da9a5bd96163) Diff: --- gcc/testsuite/gcc.dg/torture/pr125730.c | 40 +++++++++++++++++++++++++++++++++ gcc/tree-ssa-loop-ivopts.cc | 8 +++---- 2 files changed, 43 insertions(+), 5 deletions(-) diff --git a/gcc/testsuite/gcc.dg/torture/pr125730.c b/gcc/testsuite/gcc.dg/torture/pr125730.c new file mode 100644 index 000000000000..ef698e4f5137 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr125730.c @@ -0,0 +1,40 @@ +/* { dg-do run } */ + +char *key; +char *value; +char **name_regex = &key; + +__attribute__ ((noipa)) void +dict_get_item_ref (char ***result) +{ + *result = &value; +} + +__attribute__ ((noinline)) static void +parse_keyword_dict (char ***argnames, char ***values, + int num_posargs, int num_kwargs) +{ + char ***first_kw_arg = argnames + num_posargs; + char ***name = first_kw_arg; + + while (*name && num_kwargs > 0) + { + char **fetched_value; + dict_get_item_ref (&fetched_value); + values[name - argnames] = fetched_value; + name++; + } +} + +int +main () +{ + char **fetched_values[] = { 0 }; + char **argnames[] = { name_regex, 0 }; + parse_keyword_dict (argnames, fetched_values, 0, 1); + + if (fetched_values[0] != &value) + __builtin_abort (); + + return 0; +} diff --git a/gcc/tree-ssa-loop-ivopts.cc b/gcc/tree-ssa-loop-ivopts.cc index 6ecf5bef7b4f..36d47ff0369f 100644 --- a/gcc/tree-ssa-loop-ivopts.cc +++ b/gcc/tree-ssa-loop-ivopts.cc @@ -1162,8 +1162,8 @@ alloc_iv (struct ivopts_data *data, tree base, tree step, sizeof (struct iv)); gcc_assert (step != NULL_TREE); - /* Canonicalize the address expression in base if it were an unsigned - computation. That leads to more equalities being detected and results in: + /* Canonicalize the address expression in base. + That leads to more equalities being detected and results in: 1) More accurate cost can be computed for address expressions; 2) Duplicate candidates won't be created for bases in different @@ -1171,10 +1171,8 @@ alloc_iv (struct ivopts_data *data, tree base, tree step, 3) Duplicate candidates won't be created for IV expressions that differ only in their sign. */ aff_tree comb; - STRIP_NOPS (expr); - expr = fold_convert (unsigned_type_for (TREE_TYPE (expr)), expr); tree_to_aff_combination (expr, TREE_TYPE (expr), &comb); - base = fold_convert (TREE_TYPE (base), aff_combination_to_tree (&comb)); + base = aff_combination_to_tree (&comb); iv->base = base; iv->base_object = determine_base_object (data, base);
