>>+/* 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 ();
      }

Reply via email to