Commit d86d8b35 by Martin Sebor Committed by Martin Sebor

PR tree-optimization/92683 - strncmp incorrect result with equal substrings and non-const bound

gcc/testsuite/ChangeLog:

	PR tree-optimization/92683
	* gcc.dg/strcmpopt_8.c: New test.
	* gcc.dg/strcmpopt_9.c: New test.

gcc/ChangeLog:

	PR tree-optimization/92683
	* gimple-fold.c (gimple_fold_builtin_string_compare): Restore a test
	inadvertently removed in a previous change.  Rename local variable
	for clarity.

From-SVN: r278742
parent e4c935cb
2019-11-26 Martin Sebor <msebor@redhat.com>
PR tree-optimization/92683
* gimple-fold.c (gimple_fold_builtin_string_compare): Restore a test
inadvertently removed in a previous change. Rename local variable
for clarity.
2019-11-26 Richard Biener <rguenther@suse.de> 2019-11-26 Richard Biener <rguenther@suse.de>
PR middle-end/92669 PR middle-end/92669
...@@ -2346,18 +2346,19 @@ gimple_fold_builtin_string_compare (gimple_stmt_iterator *gsi) ...@@ -2346,18 +2346,19 @@ gimple_fold_builtin_string_compare (gimple_stmt_iterator *gsi)
tree str1 = gimple_call_arg (stmt, 0); tree str1 = gimple_call_arg (stmt, 0);
tree str2 = gimple_call_arg (stmt, 1); tree str2 = gimple_call_arg (stmt, 1);
tree lhs = gimple_call_lhs (stmt); tree lhs = gimple_call_lhs (stmt);
tree len = NULL_TREE;
tree bound_node = NULL_TREE;
unsigned HOST_WIDE_INT bound = HOST_WIDE_INT_M1U; unsigned HOST_WIDE_INT bound = HOST_WIDE_INT_M1U;
/* Handle strncmp and strncasecmp functions. */ /* Handle strncmp and strncasecmp functions. */
if (gimple_call_num_args (stmt) == 3) if (gimple_call_num_args (stmt) == 3)
{ {
len = gimple_call_arg (stmt, 2); bound_node = gimple_call_arg (stmt, 2);
if (tree_fits_uhwi_p (len)) if (tree_fits_uhwi_p (bound_node))
bound = tree_to_uhwi (len); bound = tree_to_uhwi (bound_node);
} }
/* If the LEN parameter is zero, return zero. */ /* If the BOUND parameter is zero, return zero. */
if (bound == 0) if (bound == 0)
{ {
replace_call_with_value (gsi, integer_zero_node); replace_call_with_value (gsi, integer_zero_node);
...@@ -2418,6 +2419,9 @@ gimple_fold_builtin_string_compare (gimple_stmt_iterator *gsi) ...@@ -2418,6 +2419,9 @@ gimple_fold_builtin_string_compare (gimple_stmt_iterator *gsi)
case BUILT_IN_STRNCMP: case BUILT_IN_STRNCMP:
case BUILT_IN_STRNCMP_EQ: case BUILT_IN_STRNCMP_EQ:
{ {
if (bound == HOST_WIDE_INT_M1U)
break;
/* Reduce the bound to be no more than the length /* Reduce the bound to be no more than the length
of the shorter of the two strings, or the sizes of the shorter of the two strings, or the sizes
of the unterminated arrays. */ of the unterminated arrays. */
......
2019-11-26 Martin Sebor <msebor@redhat.com>
PR tree-optimization/92683
* gcc.dg/strcmpopt_8.c: New test.
* gcc.dg/strcmpopt_9.c: New test.
2019-11-26 Joel Hutton <Joel.Hutton@arm.com> 2019-11-26 Joel Hutton <Joel.Hutton@arm.com>
PR testsuite/92391 PR testsuite/92391
......
/* PR tree-optimization/92683 - strncmp incorrect result with equal substrings
and nonconst bound
{ dg-do compile }
{ dg-options "-O1 -Wall -fdump-tree-forwprop1" } */
#define SIZE_MAX __SIZE_MAX__
#define S123 "123"
#define S1234 "1234"
typedef __SIZE_TYPE__ size_t;
#ifndef ident
# define ident(n) n
#endif
extern void failure_on_line (int);
/* Verify that the test in 'if (EQL strncmp (S, T, N))' is folded. */
#define T(eql, s, t, n) do { \
max = ident (n); \
if (!(eql __builtin_strncmp (s, t, max))) \
failure_on_line (__LINE__); \
} while (0)
void test_literal (void)
{
size_t max;
T (0 ==, S123, S1234, 0);
T (0 ==, S123, S1234, 1);
T (0 ==, S123, S1234, 2);
T (0 ==, S123, S1234, 3);
T (0 >, S123, S1234, 4);
T (0 >, S123, S1234, 5);
T (0 >, S123, S1234, SIZE_MAX - 2);
T (0 >, S123, S1234, SIZE_MAX - 1);
T (0 >, S123, S1234, SIZE_MAX);
T (0 ==, S123 + 1, S1234, 0);
T (0 <, S123 + 1, S1234, 1);
T (0 <, S123 + 1, S1234, 2);
T (0 <, S123 + 1, S1234, 3);
T (0 <, S123 + 1, S1234, 4);
T (0 <, S123 + 1, S1234, SIZE_MAX - 2);
T (0 <, S123 + 1, S1234, SIZE_MAX - 1);
T (0 <, S123 + 1, S1234, SIZE_MAX);
T (0 ==, S123 + 1, S1234 + 1, 0);
T (0 ==, S123 + 1, S1234 + 1, 1);
T (0 ==, S123 + 1, S1234 + 1, 2);
T (0 >, S123 + 1, S1234 + 1, 3);
T (0 >, S123 + 1, S1234 + 1, SIZE_MAX - 1);
T (0 >, S123 + 1, S1234 + 1, SIZE_MAX);
T (0 ==, S123 + 3, S1234 + 1, 0);
T (0 >, S123 + 3, S1234 + 1, 1);
T (0 >, S123 + 3, S1234 + 1, 2);
T (0 >, S123 + 3, S1234 + 1, 3);
T (0 >, S123 + 3, S1234 + 1, SIZE_MAX - 1);
T (0 >, S123 + 3, S1234 + 1, SIZE_MAX);
int zero = 0;
T (zero ==, S123, S1234, 0);
T (zero ==, S123, S1234, 1);
T (zero ==, S123, S1234, 2);
T (zero ==, S123, S1234, 3);
T (zero >, S123, S1234, 4);
T (zero >, S123, S1234, 5);
T (zero >, S123, S1234, SIZE_MAX - 2);
T (zero >, S123, S1234, SIZE_MAX - 1);
T (zero >, S123, S1234, SIZE_MAX);
T (zero ==, S123 + 1, S1234, 0);
T (zero <, S123 + 1, S1234, 1);
T (zero <, S123 + 1, S1234, 2);
T (zero <, S123 + 1, S1234, 3);
T (zero <, S123 + 1, S1234, 4);
T (zero <, S123 + 1, S1234, SIZE_MAX - 2);
T (zero <, S123 + 1, S1234, SIZE_MAX - 1);
T (zero <, S123 + 1, S1234, SIZE_MAX);
T (zero ==, S123 + 1, S1234 + 1, 0);
T (zero ==, S123 + 1, S1234 + 1, 1);
T (zero ==, S123 + 1, S1234 + 1, 2);
T (zero >, S123 + 1, S1234 + 1, 3);
T (zero >, S123 + 1, S1234 + 1, SIZE_MAX - 1);
T (zero >, S123 + 1, S1234 + 1, SIZE_MAX);
T (zero ==, S123 + 3, S1234 + 1, 0);
T (zero >, S123 + 3, S1234 + 1, 1);
T (zero >, S123 + 3, S1234 + 1, 2);
T (zero >, S123 + 3, S1234 + 1, 3);
T (zero >, S123 + 3, S1234 + 1, SIZE_MAX - 1);
T (zero >, S123 + 3, S1234 + 1, SIZE_MAX);
}
const char s123[] = S123;
const char s1234[] = S1234;
void test_cst_array (void)
{
size_t max;
T (0 ==, s123, s1234, 0);
T (0 ==, s123, s1234, 1);
T (0 ==, s123, s1234, 2);
T (0 ==, s123, s1234, 3);
T (0 >, s123, s1234, 4);
T (0 >, s123, s1234, 5);
T (0 >, s123, s1234, SIZE_MAX - 2);
T (0 >, s123, s1234, SIZE_MAX - 1);
T (0 >, s123, s1234, SIZE_MAX);
T (0 ==, s123 + 1, s1234, 0);
T (0 <, s123 + 1, s1234, 1);
T (0 <, s123 + 1, s1234, 2);
T (0 <, s123 + 1, s1234, 3);
T (0 <, s123 + 1, s1234, 4);
T (0 <, s123 + 1, s1234, SIZE_MAX - 2);
T (0 <, s123 + 1, s1234, SIZE_MAX - 1);
T (0 <, s123 + 1, s1234, SIZE_MAX);
T (0 ==, s123 + 1, s1234 + 1, 0);
T (0 ==, s123 + 1, s1234 + 1, 1);
T (0 ==, s123 + 1, s1234 + 1, 2);
T (0 >, s123 + 1, s1234 + 1, 3);
T (0 >, s123 + 1, s1234 + 1, SIZE_MAX - 1);
T (0 >, s123 + 1, s1234 + 1, SIZE_MAX);
T (0 ==, s123 + 3, s1234 + 1, 0);
T (0 >, s123 + 3, s1234 + 1, 1);
T (0 >, s123 + 3, s1234 + 1, 2);
T (0 >, s123 + 3, s1234 + 1, 3);
T (0 >, s123 + 3, s1234 + 1, SIZE_MAX - 1);
T (0 >, s123 + 3, s1234 + 1, SIZE_MAX);
int zero = 0;
T (zero ==, s123, s1234, 0);
T (zero ==, s123, s1234, 1);
T (zero ==, s123, s1234, 2);
T (zero ==, s123, s1234, 3);
T (zero >, s123, s1234, 4);
T (zero >, s123, s1234, 5);
T (zero >, s123, s1234, SIZE_MAX - 2);
T (zero >, s123, s1234, SIZE_MAX - 1);
T (zero >, s123, s1234, SIZE_MAX);
T (zero ==, s123 + 1, s1234, 0);
T (zero <, s123 + 1, s1234, 1);
T (zero <, s123 + 1, s1234, 2);
T (zero <, s123 + 1, s1234, 3);
T (zero <, s123 + 1, s1234, 4);
T (zero <, s123 + 1, s1234, SIZE_MAX - 2);
T (zero <, s123 + 1, s1234, SIZE_MAX - 1);
T (zero <, s123 + 1, s1234, SIZE_MAX);
T (zero ==, s123 + 1, s1234 + 1, 0);
T (zero ==, s123 + 1, s1234 + 1, 1);
T (zero ==, s123 + 1, s1234 + 1, 2);
T (zero >, s123 + 1, s1234 + 1, 3);
T (zero >, s123 + 1, s1234 + 1, SIZE_MAX - 1);
T (zero >, s123 + 1, s1234 + 1, SIZE_MAX);
T (zero ==, s123 + 3, s1234 + 1, 0);
T (zero >, s123 + 3, s1234 + 1, 1);
T (zero >, s123 + 3, s1234 + 1, 2);
T (zero >, s123 + 3, s1234 + 1, 3);
T (zero >, s123 + 3, s1234 + 1, SIZE_MAX - 1);
T (zero >, s123 + 3, s1234 + 1, SIZE_MAX);
}
/* { dg-final { scan-tree-dump-not "strcmp" "forwprop1" } }
{ dg-final { scan-tree-dump-not "strncmp" "forwprop1" } }
{ dg-final { scan-tree-dump-not "failure_on_line_" "forwprop1" } } */
/* PR tree-optimization/92683 - strncmp incorrect result with equal substrings
and nonconst bound
{ dg-do run }
{ dg-options "-O2 -Wall" } */
#include "strlenopt.h"
#define ident(n) ident (n)
__attribute__ ((noclone, noinline, noipa)) size_t
ident (size_t x)
{
return x;
}
int nfails;
__attribute__ ((noclone, noinline, noipa)) void
failure_on_line (int line)
{
__builtin_printf ("failure on line %i\n", line);
++nfails;
}
#include "strcmpopt_8.c"
int main (void)
{
test_literal ();
test_cst_array ();
if (nfails)
__builtin_abort ();
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment