Hi,
Given the amount of boilerplate in our target code as well as some missed
optimizations, I have been thinking about introducing a generic vector
mask/predicate expression. My thinking was something similar to what we
already have for RVV, but with a well-defined predicate:
(define_insn "*addv4si"
[(set (match_operand:V4SI 0 "register_operand" ...)
(if_then_else:V4BI
(vec_predicate
("register_or_immediate" # mask)
("register_or_immediate" # length)
(... # bias?)
( # "mask_policy")
( # "tail_policy"))
(plus:V4SI
(match_operand 1)
(match_operand 2))
(match_operand 3) # merge/inactive elements operand
...))])
For riscv mask_policy and tail_policy would be variable while all other
targets have fixed policies. The policy determines how inactive elements
are handled by the hardware (either unchanged or overwritten with -1 for
riscv, unchanged or overwritten with 0 for all others AFAIK).
I don't think the tail policy is important for code-gen as we don't care about
tail elements anyway in length-controlled loops. It helps riscv to include it,
though ;) and would keep things orthogonal.
That way, simplify-rtx and friends could reason about the predicate, identify
dead statements, and possibly merge predicates. On top, combine, fwprop, and
others are already prepared to handle if_then_else so changes there would
hopefully be minimal.
Another option would be to re-use vec_merge and enhance its predicate/mask but
I don't think vec_merge handling is as pervasive as if_then_else. Besides, I
don't like its operand order :)
In general, things could be changed incrementally without breaking existing
code. But I didn't want to start implementing a half-baked solution that
others don't agree with.
Comments, suggestions?
We could also nest two predicates for riscv and keep it simpler for other
targets?
--
Regards
Robin