aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Sandiford <richard.sandiford@linaro.org>2017-07-04 11:48:44 +0000
committerRichard Sandiford <rsandifo@gcc.gnu.org>2017-07-04 11:48:44 +0000
commit1aad71067c3ed227a9fce0e50c1818250eef6f92 (patch)
tree12020e076b3b67d0a74a4361ec63a0c71c1b88e3
parent7c819e8ae28435601df531215419957814990cd5 (diff)
downloadgcc-1aad71067c3ed227a9fce0e50c1818250eef6f92.zip
gcc-1aad71067c3ed227a9fce0e50c1818250eef6f92.tar.gz
gcc-1aad71067c3ed227a9fce0e50c1818250eef6f92.tar.bz2
PR 81292: ICE on related strlens after r249880
r249880 installed the result of a strlen in a strinfo if the strinfo wasn't previously a full string. But as Jakub says in the PR comments, we can't just do that in isolation, because there are no vdefs on the call that would invalidate any related strinfos. This patch updates the related strinfos if the adjustment is simple and invalidates them otherwise. As elsewhere, we treat adjustments of the form strlen +/- INTEGER_CST as simple but anything else as too complex. 2017-07-04 Richard Sandiford <richard.sandiford@linaro.org> gcc/ PR tree-optimization/81292 * tree-ssa-strlen.c (handle_builtin_strlen): When setting full_string_p, also call adjust_related_strinfos if the adjustment is simple, otherwise invalidate related strinfos. gcc/testsuite/ PR tree-optimization/81292 * gcc.dg/pr81292-1.c: New test. * gcc.dg/pr81292-2.c: Likewise. From-SVN: r249961
-rw-r--r--gcc/ChangeLog7
-rw-r--r--gcc/testsuite/ChangeLog6
-rw-r--r--gcc/testsuite/gcc.dg/pr81292-1.c35
-rw-r--r--gcc/testsuite/gcc.dg/pr81292-2.c35
-rw-r--r--gcc/tree-ssa-strlen.c15
5 files changed, 98 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index dda6ea4..b262a64 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,10 @@
+2017-07-04 Richard Sandiford <richard.sandiford@linaro.org>
+
+ PR tree-optimization/81292
+ * tree-ssa-strlen.c (handle_builtin_strlen): When setting
+ full_string_p, also call adjust_related_strinfos if the adjustment
+ is simple, otherwise invalidate related strinfos.
+
2017-07-04 Martin Liska <mliska@suse.cz>
PR sanitizer/81040
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 7a2e2ae..74f9ee6 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,9 @@
+2017-07-04 Richard Sandiford <richard.sandiford@linaro.org>
+
+ PR tree-optimization/81292
+ * gcc.dg/pr81292-1.c: New test.
+ * gcc.dg/pr81292-2.c: Likewise.
+
2017-07-04 Martin Liska <mliska@suse.cz>
PR sanitizer/81040
diff --git a/gcc/testsuite/gcc.dg/pr81292-1.c b/gcc/testsuite/gcc.dg/pr81292-1.c
new file mode 100644
index 0000000..931e4c3
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr81292-1.c
@@ -0,0 +1,35 @@
+/* { dg-do run } */
+/* { dg-options "-O2 -fdump-tree-strlen" } */
+
+#include "strlenopt.h"
+
+char a[10];
+
+int __attribute__ ((noinline, noclone))
+f1 (int n)
+{
+ a[0] = '1';
+ a[1] = '2';
+ return strlen (a + 1) < n ? strlen (a) : 100;
+}
+
+int __attribute__ ((noinline, noclone))
+f2 (char *a, int n)
+{
+ a[0] = '1';
+ a[1] = '2';
+ return strlen (a + 1) < n ? strlen (a) : 100;
+}
+
+int
+main (void)
+{
+ char b[10];
+ strcpy (a + 2, "345");
+ strcpy (b + 2, "34567");
+ if (f1 (100) != 5 || f2 (b, 100) != 7)
+ __builtin_abort ();
+ return 0;
+}
+
+/* { dg-final { scan-tree-dump-times "strlen \\(" 2 "strlen" } } */
diff --git a/gcc/testsuite/gcc.dg/pr81292-2.c b/gcc/testsuite/gcc.dg/pr81292-2.c
new file mode 100644
index 0000000..c1c507f
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr81292-2.c
@@ -0,0 +1,35 @@
+/* { dg-do run } */
+/* { dg-options "-O2 -fdump-tree-strlen" } */
+
+#include "strlenopt.h"
+
+char a[] = { 0, 'a', 0, 'b', 'c', 0, 'd', 'e', 'f', 0 };
+
+int __attribute__ ((noinline, noclone))
+f1 (void)
+{
+ a[0] = '1';
+ a[strlen (a)] = '2';
+ a[strlen (a)] = '3';
+ return strlen (a);
+}
+
+int __attribute__ ((noinline, noclone))
+f2 (char *a)
+{
+ a[0] = '1';
+ a[strlen (a)] = '2';
+ a[strlen (a)] = '3';
+ return strlen (a);
+}
+
+int
+main (void)
+{
+ char b[] = { 0, 0, 'a', 'b', 0, 0 };
+ if (f1 () != 9 || f2 (b) != 5)
+ __builtin_abort ();
+ return 0;
+}
+
+/* { dg-final { scan-tree-dump-times "strlen \\(" 6 "strlen" } } */
diff --git a/gcc/tree-ssa-strlen.c b/gcc/tree-ssa-strlen.c
index 5118460..b0563fe 100644
--- a/gcc/tree-ssa-strlen.c
+++ b/gcc/tree-ssa-strlen.c
@@ -1214,8 +1214,23 @@ handle_builtin_strlen (gimple_stmt_iterator *gsi)
/* Until now we only had a lower bound on the string length.
Install LHS as the actual length. */
si = unshare_strinfo (si);
+ tree old = si->nonzero_chars;
si->nonzero_chars = lhs;
si->full_string_p = true;
+ if (TREE_CODE (old) == INTEGER_CST)
+ {
+ location_t loc = gimple_location (stmt);
+ old = fold_convert_loc (loc, TREE_TYPE (lhs), old);
+ tree adj = fold_build2_loc (loc, MINUS_EXPR,
+ TREE_TYPE (lhs), lhs, old);
+ adjust_related_strinfos (loc, si, adj);
+ }
+ else
+ {
+ si->first = 0;
+ si->prev = 0;
+ si->next = 0;
+ }
}
return;
}