diff options
author | Martin Sebor <msebor@redhat.com> | 2018-06-11 20:01:40 +0000 |
---|---|---|
committer | Martin Sebor <msebor@gcc.gnu.org> | 2018-06-11 14:01:40 -0600 |
commit | 223c63e62ab44cb36102758dffd5ac8c9ab63bb1 (patch) | |
tree | c2cf4657e86b6d834d4725d513d683dbc6e29638 | |
parent | 87cbbc45a950f382853e2e4cf494cdfab62f0e5b (diff) | |
download | gcc-223c63e62ab44cb36102758dffd5ac8c9ab63bb1.zip gcc-223c63e62ab44cb36102758dffd5ac8c9ab63bb1.tar.gz gcc-223c63e62ab44cb36102758dffd5ac8c9ab63bb1.tar.bz2 |
PR tree-optimization/86083 - handle non-constant assignments in strlen
gcc/ChangeLog:
PR tree-optimization/86083
* tree-ssa-strlen.c (handle_char_store): Use tree_expr_nonzero_p.
gcc/testsuite/ChangeLog:
PR tree-optimization/86083
* gcc.dg/strlenopt-44.c: New test.
From-SVN: r261452
-rw-r--r-- | gcc/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/strlenopt-44.c | 92 | ||||
-rw-r--r-- | gcc/tree-ssa-strlen.c | 4 |
4 files changed, 103 insertions, 3 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 96d953f..655a514 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,8 @@ +2018-06-11 Martin Sebor <msebor@redhat.com> + + * PR tree-optimization/86083 + * tree-ssa-strlen.c (handle_char_store): Use tree_expr_nonzero_p. + 2018-06-11 Zhouyi Zhou <zhouzhouyi@gmail.com> * tree-eh.c (lower_eh_constructs_2): Add a comma to comment. diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index ae6acb3..3ded9ff 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2018-06-11 Martin Sebor <msebor@redhat.com> + + PR tree-optimization/86083 + * gcc.dg/strlenopt-44.c: New test. + 2018-06-11 Janus Weil <janus@gcc.gnu.org> PR fortran/45521 diff --git a/gcc/testsuite/gcc.dg/strlenopt-44.c b/gcc/testsuite/gcc.dg/strlenopt-44.c new file mode 100644 index 0000000..0c01088 --- /dev/null +++ b/gcc/testsuite/gcc.dg/strlenopt-44.c @@ -0,0 +1,92 @@ +/* PR tree-optimization/86083 - handle non-constant assignments in strlen + { dg-do compile } + { dg-options "-O2 -Wall -fdump-tree-optimized" } */ + +#include "range.h" +#include "strlenopt.h" + +#define CAT(x, y) x ## y +#define CONCAT(x, y) CAT (x, y) +#define FAILNAME(name) CONCAT (call_ ## name ##_on_line_, __LINE__) + +#define FAIL(name) do { \ + extern void FAILNAME (name) (void); \ + FAILNAME (name)(); \ + } while (0) + +/* Macro to emit a call to funcation named + call_in_true_branch_not_eliminated_on_line_NNN() + for each call that's expected to be eliminated. The dg-final + scan-tree-dump-time directive at the bottom of the test verifies + that no such call appears in output. */ +#define ASSERT_ELIM(expr) \ + if (!(expr)) FAIL (in_true_branch_not_eliminated); else (void)0 + +/* Macro to emit a call to a function named + call_made_in_{true,false}_branch_on_line_NNN() + for each call that's expected to be retained. The dg-final + scan-tree-dump-time directive at the bottom of the test verifies + that the expected number of both kinds of calls appears in output + (a pair for each line with the invocation of the KEEP() macro. */ +#define ASSERT_KEEP(expr) \ + if (expr) \ + FAIL (made_in_true_branch); \ + else \ + FAIL (made_in_false_branch) + + +#define ELIM(init, i, c, res) \ + do { \ + char a[] = init; \ + a[i] = c; \ + ASSERT_ELIM (strlen (a) == res); \ + } while (0) + +#define KEEP(init, i, c, res) \ + do { \ + char a[] = init; \ + a[i] = c; \ + ASSERT_KEEP (strlen (a) == res); \ + } while (0) + + +void test_elim_range (char c) +{ + ELIM ("1", 0, UR (1, 2), 1); + ELIM ("1", 0, UR (1, 127), 1); + ELIM ("1", 0, UR ('0', '9'), 1); + + ELIM ("12", 0, UR (1, 127), 2); + ELIM ("12", 1, UR (1, 127), 2); + + ELIM ("123", 0, UR (1, 9), 3); + ELIM ("123", 1, UR (10, 99), 3); + ELIM ("123", 2, UR (100, 127), 3); +} + +void test_elim_anti_range (const char *s) +{ + char c = *s++; + ELIM ("123", 0, c ? c : 'x', 3); + + c = *s++; + ELIM ("1234", 1, c ? c : 'y', 4); + + c = *s++; + ELIM ("123", 2, c ? c : 'z', 3); +} + +#line 1000 + +void test_keep (void) +{ + size_t uchar_max = (unsigned char)-1; + + KEEP ("1", 0, UR (1, uchar_max + 1), 1); + KEEP ("1\0\3", 1, UR (1, 2), 1); +} + +/* { dg-final { scan-tree-dump-times "call_in_true_branch_not_eliminated_" 0 "optimized" } } + + { dg-final { scan-tree-dump-times "call_made_in_true_branch_on_line_1\[0-9\]\[0-9\]\[0-9\]" 2 "optimized" } } + { dg-final { scan-tree-dump-times "call_made_in_false_branch_on_line_1\[0-9\]\[0-9\]\[0-9\]" 2 "optimized" } } */ diff --git a/gcc/tree-ssa-strlen.c b/gcc/tree-ssa-strlen.c index 5056214..cc1f5f4 100644 --- a/gcc/tree-ssa-strlen.c +++ b/gcc/tree-ssa-strlen.c @@ -3073,9 +3073,7 @@ handle_char_store (gimple_stmt_iterator *gsi) } bool storing_zero_p = initializer_zerop (rhs); - bool storing_nonzero_p = (!storing_zero_p - && TREE_CODE (rhs) == INTEGER_CST - && integer_nonzerop (rhs)); + bool storing_nonzero_p = !storing_zero_p && tree_expr_nonzero_p (rhs); /* Set to the length of the string being assigned if known. */ HOST_WIDE_INT rhslen; |