>>+/* Return a value rtx in MODE for memset from MEMSET_VALS. */
>>+
>>+static rtx
>>+ix86_expand_memset_val (rtx *memset_vals, machine_mode mode)
>
>Where is "an odd blank line"?
Nevermind.
>+/* Return a value rtx in MODE for memset from MEMSET_VALS. */
>+
>+static rtx
>+ix86_expand_memset_val (rtx *memset_vals, machine_mode mode)
>+{
>+ rtx val;
>+ if (mode == QImode)
>+ val = memset_vals[memset_val_byte];
>+ else if (mode == word_mode)
>+ val = memset_vals[memset_val_word];
>+ else if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT)
>+ {
>+ if (GET_MODE (memset_vals[memset_val_vector]) == mode)
>+ val = memset_vals[memset_val_vector];
>+ else
>+ {
>+ machine_mode vmode = GET_MODE (memset_vals[memset_val_vector]);
>+ if (memset_vals[memset_val_vector] == CONST0_RTX (vmode))
>+ val = CONST0_RTX (mode);
>+ else if (memset_vals[memset_val_vector] == CONSTM1_RTX (vmode))
>+ val = CONSTM1_RTX (mode);
>+ else
...
>+ if (memset_vals[memset_val_word] == const0_rtx
>+ || memset_vals[memset_val_word] == constm1_rtx)
>+ val = memset_vals[memset_val_word];
const0_rtx or constm1_rtx in memset_vals[memset_val_word] or
memset_vals[memset_val_vector] is propagated from
memset_vals[memset_val_byte] in ix86_expand_movmem, so we can be
simply rewrite ix86_expand_memset_val as below
static rtx
ix86_expand_memset_val (rtx *memset_vals, machine_mode mode)
{
rtx byte_val = memset_vals[memset_val_byte];
if (mode == QImode)
return byte_val;
if (mode == word_mode)
return memset_vals[memset_val_word];
/* All-zero / all-ones is a property of the original byte value, so
detect it once here rather than re-deriving it from each slot. */
if (byte_val == const0_rtx)
return CONST0_RTX (mode);
if (byte_val == constm1_rtx)
return CONSTM1_RTX (mode);
if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT)
{
if (GET_MODE (memset_vals[memset_val_vector]) == mode)
return memset_vals[memset_val_vector];
return gen_rtx_SUBREG (mode, memset_vals[memset_val_vector], 0);
}
gcc_assert (mode == HImode || mode == SImode);
return gen_rtx_SUBREG (mode, memset_vals[memset_val_word], 0);
}
>+ /* Expand memcpy and memset like memmove only for bounded size. */
>+ if ((iscpymem || issetmem)
>+ && (count != 0 /* Fixed size. */
>+ || max_size == 0 /* Unbounded size. */
>+ || max_size == HOST_WIDE_INT_M1U)) /* Unbounded size. */
For x32, unbounded max_size could be 0xffff(size_t) instead of
HOST_WIDE_INT_M1U
So maybe
if (iscpymem || issetmem)
{
unsigned HOST_WIDE_INT unbounded
= GET_MODE_MASK (counter_mode (count_exp));
if (count != 0 /* Fixed size. */
|| max_size == 0 /* Unbounded size. */
|| max_size == unbounded) /* Unbounded size. */
return false;
}
>+ machine_mode vector_mode;
> if (between_32_63_label)
> {
> emit_label (between_32_63_label);
>- ix86_expand_n_overlapping_move_movmem (dst, src, destreg, srcreg,
>- count_exp, OImode, 2);
>+ vector_mode = memset_vals ? V32QImode : OImode;
>+ ix86_expand_n_overlapping_move_set_or_movmem (dst, src,
>+ memset_vals,
>+ destreg, srcreg,
>+ count_exp,
>+ vector_mode, 2);
> emit_jump_insn (gen_jump (done_label));
> emit_barrier ();
> }
>@@ -10428,8 +10548,12 @@ ix86_expand_less_move_movmem (rtx dst, rtx src, rtx
>destreg,
> if (between_16_31_label)
> {
> emit_label (between_16_31_label);
>- ix86_expand_n_overlapping_move_movmem (dst, src, destreg, srcreg,
>- count_exp, TImode, 2);
>+ vector_mode = memset_vals ? V16QImode : TImode;
>+ ix86_expand_n_overlapping_move_set_or_movmem (dst, src,
>+ memset_vals,
>+ destreg, srcreg,
>+ count_exp,
>+ vector_mode, 2);
Can we refactor those if(***_label) branches into
/* For each size band, memset uses a QI-vector mode above a word so it
can broadcast the fill value, while memmove uses the same-size scalar
integer mode; at and below a word both use the scalar integer mode. */
struct {
rtx_code_label *label;
machine_mode set_mode;
machine_mode move_mode;
} bands[] = {
{ between_32_63_label, V32QImode, OImode },
{ between_16_31_label, V16QImode, TImode },
{ between_8_15_label, DImode, DImode },
{ between_4_7_label, SImode, SImode },
{ between_2_3_label, HImode, HImode },
};
for (auto &band : bands)
if (band.label)
{
emit_label (band.label);
machine_mode bmode = memset_vals ? band.set_mode : band.move_mode;
ix86_expand_n_overlapping_move_set_or_movmem (dst, src, memset_vals,
destreg, srcreg,
count_exp, bmode, 2);
emit_jump_insn (gen_jump (done_label));
emit_barrier ();
}