aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Sebor <msebor@redhat.com>2018-06-11 20:01:40 +0000
committerMartin Sebor <msebor@gcc.gnu.org>2018-06-11 14:01:40 -0600
commit223c63e62ab44cb36102758dffd5ac8c9ab63bb1 (patch)
treec2cf4657e86b6d834d4725d513d683dbc6e29638
parent87cbbc45a950f382853e2e4cf494cdfab62f0e5b (diff)
downloadgcc-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/ChangeLog5
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.dg/strlenopt-44.c92
-rw-r--r--gcc/tree-ssa-strlen.c4
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;