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);

Reply via email to