https://gcc.gnu.org/bugzilla/show_bug.cgi?id=128246

            Bug ID: 128246
           Summary: Masked broadcast can turn into unmasked broadcast on
                    RISC-V
           Product: gcc
           Version: 17.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: target
          Assignee: unassigned at gcc dot gnu.org
          Reporter: law at gcc dot gnu.org
  Target Milestone: ---

We have a define_insn_and_split  (pred_strided_broadcast<mode>_zvfhmin) which
when split will in effect make the broadcast unmasked.

LLM inspection showed the mask/merge operands are never used in the split-rtl
code generation which raised concerns.  After chewing for a while the LLM came
up with this testcase.  Note the spacemit tuning is needed to force the split.

/* { dg-do run { target { riscv_v && rv64 } } } */
/* { dg-options "-O2 -march=rv64gcv_zvfhmin -mabi=lp64d -mtune=spacemit-x60" }
*/
#include "riscv_vector.h"

/* Masked, tail- and mask-undisturbed broadcast of *p into merge.  */
vfloat16m1_t __RTL (startwith ("split1"))
foo (vbool16_t m, _Float16 *p, size_t vl, vfloat16m1_t merge)
{
(function "foo"
  (param "m"
    (DECL_RTL (reg/v:RVVMF16BI <1> [ m ]))
    (DECL_RTL_INCOMING (reg:RVVMF16BI v0 [ m ])))
  (param "p"
    (DECL_RTL (reg/v:DI <2> [ p ]))
    (DECL_RTL_INCOMING (reg:DI a0 [ p ])))
  (param "vl"
    (DECL_RTL (reg/v:DI <3> [ vl ]))
    (DECL_RTL_INCOMING (reg:DI a1 [ vl ])))
  (param "merge"
    (DECL_RTL (reg/v:RVVM1HF <5> [ merge ]))
    (DECL_RTL_INCOMING (reg:RVVM1HF v8 [ merge ])))
  (insn-chain
    (block 2
      (edge-from entry (flags "FALLTHRU"))
      (cnote 8 [bb 2] NOTE_INSN_BASIC_BLOCK)
      (cinsn 2 (set (reg/v:RVVMF16BI <1> [ m ])
                    (reg:RVVMF16BI v0 [ m ])))
      (cinsn 3 (set (reg/v:DI <2> [ p ])
                    (reg:DI a0 [ p ])))
      (cinsn 4 (set (reg/v:DI <3> [ vl ])
                    (reg:DI a1 [ vl ])))
      (cinsn 5 (set (reg/v:RVVM1HF <5> [ merge ])
                    (reg:RVVM1HF v8 [ merge ])))
      (cnote 6 NOTE_INSN_FUNCTION_BEG)
      (cinsn 10 (set (reg:RVVM1HF <5>)
        (if_then_else:RVVM1HF (unspec:RVVMF16BI [
                    (reg/v:RVVMF16BI <1> [ m ])
                    (reg/v:DI <3> [ vl ])
                    (const_int 0)
                    (const_int 0)
                    (const_int 0)
                    (reg:SI vl)
                    (reg:SI vtype)
                ] UNSPEC_VPREDICATE)
            (vec_duplicate:RVVM1HF (mem:HF (reg/v:DI <2> [ p ]) [1 *p+0 S2
A16]))
            (reg/v:RVVM1HF <5> [ merge ]))))
      (cinsn 11 (set (reg:RVVM1HF v8)
                     (reg:RVVM1HF <5>)))
      (cinsn 12 (use (reg:RVVM1HF v8)))
      (edge-to exit (flags "FALLTHRU"))
    ) ;; block 2
  ) ;; insn-chain
) ;; function
}

unsigned short Src = 0x2222, Init[8], Out[8];
unsigned char Bits = 0x05;      /* lanes 0 and 2 active */

int
main (void)
{
  for (int i = 0; i < 8; i++)
    Init[i] = 0x1111;
  vbool16_t m = __riscv_vlm_v_b16 (&Bits, 8);
  vfloat16m1_t merge
    = __riscv_vreinterpret_v_u16m1_f16m1 (__riscv_vle16_v_u16m1 (Init, 8));
  vfloat16m1_t r = foo (m, (_Float16 *) &Src, 8, merge);
  __riscv_vse16_v_u16m1 (Out, __riscv_vreinterpret_v_f16m1_u16m1 (r), 8);
  for (int i = 0; i < 8; i++)
    if (Out[i] != ((i == 0 || i == 2) ? 0x2222 : 0x1111))
      __builtin_abort ();
  __builtin_exit (0);
}

Reply via email to