From: Richard Sandiford Date: Tue, 4 Jul 2017 11:48:44 +0000 (+0000) Subject: PR 81292: ICE on related strlens after r249880 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=1aad71067c3ed227a9fce0e50c1818250eef6f92;p=gcc.git 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 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 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index dda6ea47ea5..b262a646aec 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2017-07-04 Richard Sandiford + + 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 PR sanitizer/81040 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 7a2e2ae3a6f..74f9ee6ab97 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2017-07-04 Richard Sandiford + + PR tree-optimization/81292 + * gcc.dg/pr81292-1.c: New test. + * gcc.dg/pr81292-2.c: Likewise. + 2017-07-04 Martin Liska 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 00000000000..931e4c37c17 --- /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 00000000000..c1c507f982e --- /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 51184602a3f..b0563fe7c32 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; }