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.

Bootstrapped and tested on x86_64-unknown-linux-gnu and
aarch64-suse-linux-gnu.

I'll push this part once 1/2 is approved and also plan to backport
to the 16 branch.

        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.
---
 gcc/testsuite/gcc.dg/torture/pr125730.c | 40 +++++++++++++++++++++++++
 gcc/tree-ssa-loop-ivopts.cc             |  8 ++---
 2 files changed, 43 insertions(+), 5 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/torture/pr125730.c

diff --git a/gcc/testsuite/gcc.dg/torture/pr125730.c 
b/gcc/testsuite/gcc.dg/torture/pr125730.c
new file mode 100644
index 00000000000..ef698e4f513
--- /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 4ca55325188..bbd3cfaab24 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);
-- 
2.51.0

Reply via email to