aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-ssa-strlen.c
diff options
context:
space:
mode:
authorMartin Sebor <msebor@redhat.com>2019-10-28 23:46:09 +0000
committerMartin Sebor <msebor@gcc.gnu.org>2019-10-28 17:46:09 -0600
commit02c4de7631a177ea44149332aa1294a60ed9adad (patch)
tree42ae1d041a7a04aa7f3c1fe8003efd45ff7da865 /gcc/tree-ssa-strlen.c
parentad1539d5555a161cf6851de8995641d6dfe792d9 (diff)
downloadgcc-02c4de7631a177ea44149332aa1294a60ed9adad.zip
gcc-02c4de7631a177ea44149332aa1294a60ed9adad.tar.gz
gcc-02c4de7631a177ea44149332aa1294a60ed9adad.tar.bz2
PR tree-optimization/92226 - live nul char store to array eliminated
gcc/testsuite/ChangeLog: PR tree-optimization/92226 * gcc.dg/strlenopt-88.c: New test. gcc/ChangeLog: PR tree-optimization/92226 * tree-ssa-strlen.c (compare_nonzero_chars): Return -1 also when the offset is in the open range outlined by SI's length. From-SVN: r277545
Diffstat (limited to 'gcc/tree-ssa-strlen.c')
-rw-r--r--gcc/tree-ssa-strlen.c19
1 files changed, 14 insertions, 5 deletions
diff --git a/gcc/tree-ssa-strlen.c b/gcc/tree-ssa-strlen.c
index 4381458..476bcf6 100644
--- a/gcc/tree-ssa-strlen.c
+++ b/gcc/tree-ssa-strlen.c
@@ -193,10 +193,11 @@ static void handle_builtin_stxncpy (built_in_function, gimple_stmt_iterator *);
* +1 if SI is known to start with more than OFF nonzero characters.
- * 0 if SI is known to start with OFF nonzero characters,
- but is not known to start with more.
+ * 0 if SI is known to start with exactly OFF nonzero characters.
- * -1 if SI might not start with OFF nonzero characters. */
+ * -1 if SI either does not start with OFF nonzero characters
+ or the relationship between the number of leading nonzero
+ characters in SI and OFF is unknown. */
static inline int
compare_nonzero_chars (strinfo *si, unsigned HOST_WIDE_INT off)
@@ -221,7 +222,7 @@ compare_nonzero_chars (strinfo *si, unsigned HOST_WIDE_INT off,
if (TREE_CODE (si->nonzero_chars) == INTEGER_CST)
return compare_tree_int (si->nonzero_chars, off);
- if (TREE_CODE (si->nonzero_chars) != SSA_NAME)
+ if (!rvals || TREE_CODE (si->nonzero_chars) != SSA_NAME)
return -1;
const value_range *vr
@@ -232,7 +233,15 @@ compare_nonzero_chars (strinfo *si, unsigned HOST_WIDE_INT off,
if (rng != VR_RANGE || !range_int_cst_p (vr))
return -1;
- return compare_tree_int (vr->min (), off);
+ /* If the offset is less than the minimum length or if the bounds
+ of the length range are equal return the result of the comparison
+ same as in the constant case. Otherwise return a conservative
+ result. */
+ int cmpmin = compare_tree_int (vr->min (), off);
+ if (cmpmin > 0 || tree_int_cst_equal (vr->min (), vr->max ()))
+ return cmpmin;
+
+ return -1;
}
/* Return true if SI is known to be a zero-length string. */