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
This commit is contained in:
parent
c8d97db2cc
commit
5689294cd9
@ -1,3 +1,13 @@
|
||||
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>
|
||||
|
||||
* 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
|
||||
address in mode @code{Pmode}.
|
||||
|
||||
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
|
||||
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
|
||||
(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
|
||||
destination, in the form of a @code{const_int} rtx. Thus, if the
|
||||
|
16
gcc/expr.c
16
gcc/expr.c
@ -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
|
||||
here because if SIZE is less than the mode mask, as it is
|
||||
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)
|
||||
&& ((unsigned HOST_WIDE_INT) INTVAL (size)
|
||||
<= (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];
|
||||
unsigned int nops;
|
||||
@ -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);
|
||||
|
||||
if (code != CODE_FOR_nothing
|
||||
/* 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 returned by the macro, it will
|
||||
definitely be less than the actual mode mask. */
|
||||
/* 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
|
||||
returned by the macro, it will definitely be less than the
|
||||
actual mode mask. Since SIZE is within the Pmode address
|
||||
space, we limit MODE to Pmode. */
|
||||
&& ((CONST_INT_P (size)
|
||||
&& ((unsigned HOST_WIDE_INT) INTVAL (size)
|
||||
<= (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];
|
||||
unsigned int nops;
|
||||
|
@ -1,3 +1,8 @@
|
||||
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>
|
||||
|
||||
PR middle-end/58941
|
||||
|
55
gcc/testsuite/gcc.dg/pr58981.c
Normal file
55
gcc/testsuite/gcc.dg/pr58981.c
Normal file
@ -0,0 +1,55 @@
|
||||
/* { 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;
|
||||
}
|
Loading…
Reference in New Issue
Block a user