Commit 6512c0f1 by Martin Sebor Committed by Martin Sebor

PR middle-end/81908 - FAIL: gfortran.dg/alloc_comp_auto_array_2.f90 -O3 -g -m32

gcc/ChangeLog:

	PR middle-end/81908
	* gimple-fold.c (size_must_be_zero_p): New function.
	(gimple_fold_builtin_memory_op): Call it.

gcc/testsuite/ChangeLog:

	PR middle-end/81908
	* gcc.dg/tree-ssa/builtins-folding-gimple-2.c: New test.
	* gcc.dg/tree-ssa/builtins-folding-gimple-3.c: New test.
	* gcc.dg/tree-ssa/pr81908.c: New test.

From-SVN: r251347
parent f9dd01fa
2017-08-24 Martin Sebor <msebor@redhat.com>
PR middle-end/81908
* gimple-fold.c (size_must_be_zero_p): New function.
(gimple_fold_builtin_memory_op): Call it.
2017-08-24 Steven Munroe <munroesj@gcc.gnu.org>
* config/rs6000/mm_malloc.h: New file.
......
......@@ -628,6 +628,36 @@ var_decl_component_p (tree var)
return SSA_VAR_P (inner);
}
/* If the SIZE argument representing the size of an object is in a range
of values of which exactly one is valid (and that is zero), return
true, otherwise false. */
static bool
size_must_be_zero_p (tree size)
{
if (integer_zerop (size))
return true;
if (TREE_CODE (size) != SSA_NAME)
return false;
wide_int min, max;
enum value_range_type rtype = get_range_info (size, &min, &max);
if (rtype != VR_ANTI_RANGE)
return false;
tree type = TREE_TYPE (size);
int prec = TYPE_PRECISION (type);
wide_int wone = wi::one (prec);
/* Compute the value of SSIZE_MAX, the largest positive value that
can be stored in ssize_t, the signed counterpart of size_t. */
wide_int ssize_max = wi::lshift (wi::one (prec), prec - 1) - 1;
return wi::eq_p (min, wone) && wi::geu_p (max, ssize_max);
}
/* Fold function call to builtin mem{{,p}cpy,move}. Return
false if no simplification can be made.
If ENDP is 0, return DEST (like memcpy).
......@@ -646,8 +676,9 @@ gimple_fold_builtin_memory_op (gimple_stmt_iterator *gsi,
tree destvar, srcvar;
location_t loc = gimple_location (stmt);
/* If the LEN parameter is zero, return DEST. */
if (integer_zerop (len))
/* If the LEN parameter is a constant zero or in range where
the only valid value is zero, return DEST. */
if (size_must_be_zero_p (len))
{
gimple *repl;
if (gimple_call_lhs (stmt))
......
2017-08-24 Martin Sebor <msebor@redhat.com>
PR middle-end/81908
* gcc.dg/tree-ssa/builtins-folding-gimple-2.c: New test.
* gcc.dg/tree-ssa/builtins-folding-gimple-3.c: New test.
* gcc.dg/tree-ssa/pr81908.c: New test.
2017-08-24 Steven Munroe <munroesj@gcc.gnu.org>
* gcc.target/powerpc/mmx-packuswb-1.c [NO_WARN_X86_INTRINSICS]:
......
/* PR 81908 - FAIL: gfortran.dg/alloc_comp_auto_array_2.f90 -O3 -g -m32
Test to verify that calls to memcpy et al. where the size is in a range
with just one valid value -- zero -- are eliminated.
{ dg-do compile }
{ dg-options "-O2 -Wall -fdump-tree-optimized" } */
#define INT_MAX __INT_MAX__
#define SHRT_MAX __SHRT_MAX__
#define SIZE_MAX __SIZE_MAX__
#define SSIZE_MAX (SIZE_MAX / 2)
typedef __PTRDIFF_TYPE__ ssize_t;
typedef __SIZE_TYPE__ size_t;
#define UNIQUE_FUNCNAME(func, line) test_ ## func ## _ ## line
#define FUNCNAME(func, line) UNIQUE_FUNCNAME (func, line)
#define AR(func, type, min, max, val) \
void __attribute__ ((noclone, noinline)) \
FUNCNAME (func, __LINE__) (char *d, const char *s, type n) \
{ \
if ((type)min <= n && n <= (type)max) \
n = val; \
__builtin_ ## func (d, s, n); \
} typedef void DummyType
AR (memcpy, short, 1, SHRT_MAX, 0);
AR (memcpy, int, 1, INT_MAX, 0);
AR (memcpy, size_t, 1, SSIZE_MAX, 0);
AR (memcpy, ssize_t, 1, SSIZE_MAX, 0);
AR (memmove, short, 1, SHRT_MAX, 0);
AR (memmove, int, 1, INT_MAX, 0);
AR (memmove, ssize_t, 1, SSIZE_MAX, 0);
AR (memmove, ssize_t, 1, SSIZE_MAX, 0);
AR (mempcpy, short, 1, SHRT_MAX, 0);
AR (mempcpy, int, 1, INT_MAX, 0);
AR (mempcpy, size_t, 1, SSIZE_MAX, 0);
AR (mempcpy, ssize_t, 1, SSIZE_MAX, 0);
/* { dg-final { scan-tree-dump-not "builtin_memcpy" "optimized" } }
{ dg-final { scan-tree-dump-not "builtin_memmove" "optimized" } }
{ dg-final { scan-tree-dump-not "builtin_mempcpy" "optimized" } } */
/* PR 81908 - FAIL: gfortran.dg/alloc_comp_auto_array_2.f90 -O3 -g -m32
Test to verify that calls to memcpy et al. where the size is in a range
with more than one valid value are not eliminated (this test complements
builtins-folding-gimple-2.c).
{ dg-do compile }
{ dg-options "-O2 -Wall -fdump-tree-optimized" } */
#define SHRT_MAX __SHRT_MAX__
#define SHRT_MIN (-SHRT_MAX - 1)
#define INT_MAX __INT_MAX__
#define INT_MIN (-INT_MAX - 1)
#define UNIQUE_FUNCNAME(func, line) test_ ## func ## _ ## line
#define FUNCNAME(func, line) UNIQUE_FUNCNAME (func, line)
#define AR(func, type, min, max, val) \
void __attribute__ ((noclone, noinline)) \
FUNCNAME (func, __LINE__) (char *d, const char *s, type n) \
{ \
if ((type)min <= n && n <= (type)max) \
n = val; \
__builtin_ ## func (d, s, n); \
} typedef void DummyType
AR (memcpy, short, SHRT_MIN, 0, 1);
AR (memcpy, short, SHRT_MIN, 1, 2);
AR (memcpy, short, 2, SHRT_MAX, 1);
AR (memcpy, int, INT_MIN, 0, 1);
AR (memcpy, int, INT_MIN, 1, 2);
AR (memcpy, int, INT_MIN, 2, 3);
AR (memcpy, int, 2, INT_MAX, 1);
AR (memcpy, int, 2, INT_MAX, 1);
AR (memmove, short, 2, SHRT_MAX, 1);
AR (memmove, int, 2, INT_MAX, 1);
AR (mempcpy, short, 2, SHRT_MAX, 1);
AR (mempcpy, int, 2, INT_MAX, 1);
/* { dg-final { scan-tree-dump-times "builtin_memcpy" 8 "optimized" } }
{ dg-final { scan-tree-dump-times "builtin_memmove" 2 "optimized" } }
{ dg-final { scan-tree-dump-times "builtin_mempcpy" 2 "optimized" } } */
/* PR 81908 - FAIL: gfortran.dg/alloc_comp_auto_array_2.f90 -O3 -g -m32
{ dg-do compile }
{ dg-options "-O2 -Wall" } */
#define SIZE_MAX __SIZE_MAX__
typedef __SIZE_TYPE__ size_t;
void f0 (char *d, const char *s, size_t n)
{
if (n > 0 && n <= SIZE_MAX / 2 - 1)
n = 0;
__builtin_memcpy (d, s, n);
}
void f1 (char *d, const char *s, size_t n)
{
if (n > 0 && n <= SIZE_MAX / 2)
n = 0;
__builtin_memcpy (d, s, n); /* { dg-bogus "\\\[-Wstringop-overflow=]" } */
}
void f2 (char *d, const char *s, size_t n)
{
if (n > 0 && n <= SIZE_MAX / 2 + 1)
n = 0;
__builtin_memcpy (d, s, n);
}
void f3 (char *d, const char *s, size_t n)
{
if (n > 0 && n <= SIZE_MAX - 1)
n = 0;
__builtin_memcpy (d, s, n); /* { dg-bogus "\\\[-Wstringop-overflow=]" } */
}
void f4 (char *d, const char *s, size_t n)
{
if (n > 0 && n <= SIZE_MAX)
n = 0;
__builtin_memcpy (d, s, n);
}
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