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);
}