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