mirror of git://gcc.gnu.org/git/gcc.git
x86: Handle small OP size in setmem_epilogue_gen_val
Since OP size passed to setmem_epilogue_gen_val may be smaller than the required vector size, duplicate it first before setting vector. gcc/ PR target/122150 * config/i386/i386-expand.cc (setmem_epilogue_gen_val): Duplicate OP if its size is smaller than MODE size. gcc/testsuite/ PR target/122150 * gcc.target/i386/pr122150.c: New test. Signed-off-by: H.J. Lu <hjl.tools@gmail.com>
This commit is contained in:
parent
eb5a29677e
commit
a3727eb5e8
|
@ -8443,9 +8443,28 @@ setmem_epilogue_gen_val (void *op_p, void *prev_p, HOST_WIDE_INT,
|
||||||
|
|
||||||
unsigned int op_size = GET_MODE_SIZE (op_mode);
|
unsigned int op_size = GET_MODE_SIZE (op_mode);
|
||||||
unsigned int size = GET_MODE_SIZE (mode);
|
unsigned int size = GET_MODE_SIZE (mode);
|
||||||
unsigned int nunits = op_size / GET_MODE_SIZE (QImode);
|
unsigned int nunits;
|
||||||
machine_mode vec_mode
|
machine_mode vec_mode;
|
||||||
= mode_for_vector (QImode, nunits).require ();
|
if (op_size < size)
|
||||||
|
{
|
||||||
|
/* If OP size is smaller than MODE size, duplicate it. */
|
||||||
|
nunits = size / GET_MODE_SIZE (QImode);
|
||||||
|
vec_mode = mode_for_vector (QImode, nunits).require ();
|
||||||
|
nunits = size / op_size;
|
||||||
|
gcc_assert (SCALAR_INT_MODE_P (op_mode));
|
||||||
|
machine_mode dup_mode
|
||||||
|
= mode_for_vector (as_a <scalar_mode> (op_mode),
|
||||||
|
nunits).require ();
|
||||||
|
target = gen_reg_rtx (vec_mode);
|
||||||
|
op = gen_vec_duplicate (dup_mode, op);
|
||||||
|
rtx dup_op = gen_reg_rtx (dup_mode);
|
||||||
|
emit_move_insn (dup_op, op);
|
||||||
|
op = gen_rtx_SUBREG (vec_mode, dup_op, 0);
|
||||||
|
emit_move_insn (target, op);
|
||||||
|
return target;
|
||||||
|
}
|
||||||
|
nunits = op_size / GET_MODE_SIZE (QImode);
|
||||||
|
vec_mode = mode_for_vector (QImode, nunits).require ();
|
||||||
target = gen_reg_rtx (vec_mode);
|
target = gen_reg_rtx (vec_mode);
|
||||||
op = gen_rtx_SUBREG (vec_mode, op, 0);
|
op = gen_rtx_SUBREG (vec_mode, op, 0);
|
||||||
emit_move_insn (target, op);
|
emit_move_insn (target, op);
|
||||||
|
|
|
@ -0,0 +1,21 @@
|
||||||
|
/* { dg-do run } */
|
||||||
|
/* { dg-options "-mstringop-strategy=unrolled_loop" } */
|
||||||
|
|
||||||
|
char c[2841];
|
||||||
|
|
||||||
|
__attribute__((noipa))
|
||||||
|
void
|
||||||
|
foo (void)
|
||||||
|
{
|
||||||
|
__builtin_memset (&c, 1, 2841);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
main (void)
|
||||||
|
{
|
||||||
|
foo ();
|
||||||
|
for (unsigned i = 0; i < sizeof (c); i++)
|
||||||
|
if (c[i] != 1)
|
||||||
|
__builtin_abort();
|
||||||
|
return 0;
|
||||||
|
}
|
Loading…
Reference in New Issue