From: H.J. Lu Date: Fri, 3 Oct 2025 23:02:20 +0000 (+0800) Subject: x86: Handle small OP size in setmem_epilogue_gen_val X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=a3727eb5e821d6a1916805029aeaed092e5e739d;p=thirdparty%2Fgcc.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 --- diff --git a/gcc/config/i386/i386-expand.cc b/gcc/config/i386/i386-expand.cc index c6f42275a3e..0115af4d359 100644 --- a/gcc/config/i386/i386-expand.cc +++ b/gcc/config/i386/i386-expand.cc @@ -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 size = GET_MODE_SIZE (mode); - unsigned int nunits = op_size / GET_MODE_SIZE (QImode); - machine_mode vec_mode - = mode_for_vector (QImode, nunits).require (); + unsigned int nunits; + machine_mode vec_mode; + 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 (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); op = gen_rtx_SUBREG (vec_mode, op, 0); emit_move_insn (target, op); diff --git a/gcc/testsuite/gcc.target/i386/pr122150.c b/gcc/testsuite/gcc.target/i386/pr122150.c new file mode 100644 index 00000000000..973c34d180e --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr122150.c @@ -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; +}