Commit 5689294c by H.J. Lu Committed by H.J. Lu

Don't use mode wider than Pmode for size in movmem/setmem

gcc/

	PR middle-end/58981
	* doc/md.texi (@code{movmem@var{m}}): Specify Pmode as mode of
	pattern, instead of word_mode.

	* expr.c (emit_block_move_via_movmem): Don't use mode wider than
	Pmode for size.
	(set_storage_via_setmem): Likewise.

gcc/testsuite/

	PR middle-end/58981
	* gcc.dg/pr58981.c: New test.

From-SVN: r204394
parent c8d97db2
2013-11-05 H.J. Lu <hongjiu.lu@intel.com>
PR middle-end/58981
* doc/md.texi (@code{movmem@var{m}}): Specify Pmode as mode of
pattern, instead of word_mode.
* expr.c (emit_block_move_via_movmem): Don't use mode wider than
Pmode for size.
(set_storage_via_setmem): Likewise.
2013-11-05 Andrew MacLeod <amacleod@redhat.com> 2013-11-05 Andrew MacLeod <amacleod@redhat.com>
* tree-outof-ssa.c (queue_phi_copy_p): Combine phi_ssa_name_p from * tree-outof-ssa.c (queue_phi_copy_p): Combine phi_ssa_name_p from
...@@ -5291,12 +5291,13 @@ are the first two operands, and both are @code{mem:BLK}s with an ...@@ -5291,12 +5291,13 @@ are the first two operands, and both are @code{mem:BLK}s with an
address in mode @code{Pmode}. address in mode @code{Pmode}.
The number of bytes to move is the third operand, in mode @var{m}. The number of bytes to move is the third operand, in mode @var{m}.
Usually, you specify @code{word_mode} for @var{m}. However, if you can Usually, you specify @code{Pmode} for @var{m}. However, if you can
generate better code knowing the range of valid lengths is smaller than generate better code knowing the range of valid lengths is smaller than
those representable in a full word, you should provide a pattern with a those representable in a full Pmode pointer, you should provide
a pattern with a
mode corresponding to the range of values you can handle efficiently mode corresponding to the range of values you can handle efficiently
(e.g., @code{QImode} for values in the range 0--127; note we avoid numbers (e.g., @code{QImode} for values in the range 0--127; note we avoid numbers
that appear negative) and also a pattern with @code{word_mode}. that appear negative) and also a pattern with @code{Pmode}.
The fourth operand is the known shared alignment of the source and The fourth operand is the known shared alignment of the source and
destination, in the form of a @code{const_int} rtx. Thus, if the destination, in the form of a @code{const_int} rtx. Thus, if the
......
...@@ -1297,11 +1297,12 @@ emit_block_move_via_movmem (rtx x, rtx y, rtx size, unsigned int align, ...@@ -1297,11 +1297,12 @@ emit_block_move_via_movmem (rtx x, rtx y, rtx size, unsigned int align,
/* We don't need MODE to be narrower than BITS_PER_HOST_WIDE_INT /* We don't need MODE to be narrower than BITS_PER_HOST_WIDE_INT
here because if SIZE is less than the mode mask, as it is here because if SIZE is less than the mode mask, as it is
returned by the macro, it will definitely be less than the returned by the macro, it will definitely be less than the
actual mode mask. */ actual mode mask. Since SIZE is within the Pmode address
space, we limit MODE to Pmode. */
&& ((CONST_INT_P (size) && ((CONST_INT_P (size)
&& ((unsigned HOST_WIDE_INT) INTVAL (size) && ((unsigned HOST_WIDE_INT) INTVAL (size)
<= (GET_MODE_MASK (mode) >> 1))) <= (GET_MODE_MASK (mode) >> 1)))
|| GET_MODE_BITSIZE (mode) >= BITS_PER_WORD)) || GET_MODE_BITSIZE (mode) >= GET_MODE_BITSIZE (Pmode)))
{ {
struct expand_operand ops[6]; struct expand_operand ops[6];
unsigned int nops; unsigned int nops;
...@@ -2879,14 +2880,15 @@ set_storage_via_setmem (rtx object, rtx size, rtx val, unsigned int align, ...@@ -2879,14 +2880,15 @@ set_storage_via_setmem (rtx object, rtx size, rtx val, unsigned int align,
enum insn_code code = direct_optab_handler (setmem_optab, mode); enum insn_code code = direct_optab_handler (setmem_optab, mode);
if (code != CODE_FOR_nothing if (code != CODE_FOR_nothing
/* We don't need MODE to be narrower than /* We don't need MODE to be narrower than BITS_PER_HOST_WIDE_INT
BITS_PER_HOST_WIDE_INT here because if SIZE is less than here because if SIZE is less than the mode mask, as it is
the mode mask, as it is returned by the macro, it will returned by the macro, it will definitely be less than the
definitely be less than the actual mode mask. */ actual mode mask. Since SIZE is within the Pmode address
space, we limit MODE to Pmode. */
&& ((CONST_INT_P (size) && ((CONST_INT_P (size)
&& ((unsigned HOST_WIDE_INT) INTVAL (size) && ((unsigned HOST_WIDE_INT) INTVAL (size)
<= (GET_MODE_MASK (mode) >> 1))) <= (GET_MODE_MASK (mode) >> 1)))
|| GET_MODE_BITSIZE (mode) >= BITS_PER_WORD)) || GET_MODE_BITSIZE (mode) >= GET_MODE_BITSIZE (Pmode)))
{ {
struct expand_operand ops[6]; struct expand_operand ops[6];
unsigned int nops; unsigned int nops;
......
2013-11-05 H.J. Lu <hongjiu.lu@intel.com>
PR middle-end/58981
* gcc.dg/pr58981.c: New test.
2013-11-05 Richard Biener <rguenther@suse.de> 2013-11-05 Richard Biener <rguenther@suse.de>
PR middle-end/58941 PR middle-end/58941
......
/* { dg-do run } */
/* { dg-options "-O2" } */
/* { dg-additional-options "-minline-all-stringops" { target { i?86-*-* x86_64-*-* } } } */
extern void abort (void);
#define MAX_OFFSET (sizeof (long long))
#define MAX_COPY (8 * sizeof (long long))
#define MAX_EXTRA (sizeof (long long))
#define MAX_LENGTH (MAX_OFFSET + MAX_COPY + MAX_EXTRA)
static union {
char buf[MAX_LENGTH];
long long align_int;
long double align_fp;
} u;
char A[MAX_LENGTH];
int
main ()
{
int off, len, i;
char *p, *q;
for (i = 0; i < MAX_LENGTH; i++)
A[i] = 'A';
for (off = 0; off < MAX_OFFSET; off++)
for (len = 1; len < MAX_COPY; len++)
{
for (i = 0; i < MAX_LENGTH; i++)
u.buf[i] = 'a';
p = __builtin_memcpy (u.buf + off, A, len);
if (p != u.buf + off)
abort ();
q = u.buf;
for (i = 0; i < off; i++, q++)
if (*q != 'a')
abort ();
for (i = 0; i < len; i++, q++)
if (*q != 'A')
abort ();
for (i = 0; i < MAX_EXTRA; i++, q++)
if (*q != 'a')
abort ();
}
return 0;
}
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