Fix ice in insert_access
authorJan Hubicka <hubicka@ucw.cz>
Fri, 5 Nov 2021 22:32:55 +0000 (23:32 +0100)
committerJan Hubicka <hubicka@ucw.cz>
Fri, 5 Nov 2021 22:32:55 +0000 (23:32 +0100)
gcc/ChangeLog:

PR ipa/103073
* ipa-modref-tree.h (modref_tree::insert): Do nothing for
paradoxical and zero sized accesses.

gcc/testsuite/ChangeLog:

PR ipa/103073
* g++.dg/torture/pr103073.C: New test.
* gcc.dg/tree-ssa/modref-11.c: New test.

gcc/ipa-modref-tree.h
gcc/testsuite/g++.dg/torture/pr103073.C [new file with mode: 0644]
gcc/testsuite/gcc.dg/tree-ssa/modref-11.c [new file with mode: 0644]

index bc428d1..54ae9e1 100644 (file)
@@ -818,6 +818,36 @@ struct GTY((user)) modref_tree
 
     bool changed = false;
 
+    /* We may end up with max_size being less than size for accesses past the
+       end of array.  Those are undefined and safe to ignore.  */
+    if (a.range_info_useful_p ()
+       && known_size_p (a.size) && known_size_p (a.max_size)
+       && known_lt (a.max_size, a.size))
+      {
+       if (dump_file)
+         fprintf (dump_file,
+                  "   - Paradoxical range. Ignoring\n");
+       return false;
+      }
+    if (known_size_p (a.size)
+       && known_eq (a.size, 0))
+      {
+       if (dump_file)
+         fprintf (dump_file,
+                  "   - Zero size. Ignoring\n");
+       return false;
+      }
+    if (known_size_p (a.max_size)
+       && known_eq (a.max_size, 0))
+      {
+       if (dump_file)
+         fprintf (dump_file,
+                  "   - Zero max_size. Ignoring\n");
+       return false;
+      }
+    gcc_checking_assert (!known_size_p (a.max_size)
+                        || !known_le (a.max_size, 0));
+
     /* No useful information tracked; collapse everything.  */
     if (!base && !ref && !a.useful_p ())
       {
diff --git a/gcc/testsuite/g++.dg/torture/pr103073.C b/gcc/testsuite/g++.dg/torture/pr103073.C
new file mode 100644 (file)
index 0000000..02b1eee
--- /dev/null
@@ -0,0 +1,8 @@
+// { dg-do compile }
+int a;
+void b(bool c[], char d[], bool g[][55][21]) {
+  for (signed e = 0; e < 11; e += 3)
+    for (unsigned f = c[0] + 1; f < d[0]; f += 3)
+      a = g[0][e][f + 2];
+}
+
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/modref-11.c b/gcc/testsuite/gcc.dg/tree-ssa/modref-11.c
new file mode 100644 (file)
index 0000000..de9ad16
--- /dev/null
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-modref1"  } */
+struct linkedlist {
+  struct linkedlist *next;
+};
+struct linkedlist *
+find_last (struct linkedlist *l)
+{
+  while (l->next)
+   l = l->next;
+  return l;
+}
+/* { dg-final { scan-tree-dump "noclobber noescape nodirectescape" "modref1"} } */