At 2026/6/12 12:45, Jeffrey Law wrote:
On 6/11/2026 1:54 AM, Jiawei wrote:
Add RTL patterns for the Zvdota and Zvbdota dot-product
instructions. The patterns model the destructive accumulator operand
and use explicit altfmt operands where the runtime vtype.altfmt state
selects the VS1 interpretation. Zvbdota patterns also take a scaled
ci immediate operand.
gcc/ChangeLog:
* config/riscv/predicates.md (zvbdota_ci_operand): New operand.
* config/riscv/riscv-protos.h (enum mask_policy): Update altfmt
comment.
* config/riscv/riscv.md: Include vector-dot.md.
* config/riscv/vector-iterators.md: Add UNSPEC and iterator
definitions for Zvdota and Zvbdota.
* config/riscv/vector-dot.md: New file.
---
gcc/config/riscv/predicates.md | 5 +
gcc/config/riscv/riscv-protos.h | 5 +-
gcc/config/riscv/riscv.md | 1 +
gcc/config/riscv/vector-dot.md | 246 +++++++++++++++++++++++++++
gcc/config/riscv/vector-iterators.md | 207 ++++++++++++++++++++++
5 files changed, 461 insertions(+), 3 deletions(-)
create mode 100644 gcc/config/riscv/vector-dot.md
diff --git a/gcc/config/riscv/riscv-protos.h
b/gcc/config/riscv/riscv-protos.h
index fa360157570..a8a40f5dda9 100644
--- a/gcc/config/riscv/riscv-protos.h
+++ b/gcc/config/riscv/riscv-protos.h
@@ -663,9 +663,8 @@ enum mask_policy
/* Values for the VTYPE altfmt field. Instructions that do not
care about
altfmt leave the "altfmt" insn attribute at its default
(INVALID_ATTRIBUTE);
- FP8 instructions select between standard (ALTFMT_NONE, E4M3) and the
- alternate format (ALTFMT_ALT, E5M2) by setting the attribute via an
- operand. */
+ Some dot-product instructions select their vs1 interpretation by
setting
+ the attribute via an operand. */
Why drop the FP8 parts of this comment?
That was not intentional. I generalized the comment too much when adding
the dot-product altfmt use case. I will restore the FP8 part and extend
the comment instead of replacing it, e.g. something along the lines of:
FP8 instructions select between the standard and alternate formats by
setting the altfmt attribute, and some dot-product instructions also use
altfmt to select the VS1 interpretation.
/* Values for the VTYPE altfmt field. Instructions that do not care about
altfmt leave the "altfmt" insn attribute at its default (INVALID_ATTRIBUTE);
FP8 instructions select between standard (ALTFMT_NONE, E4M3) and the
alternate format (ALTFMT_ALT, E5M2) by setting the attribute via an
operand. Some dot-product instructions also use altfmt to select the VS1
interpretation. */
+
+(define_insn "@pred_<zvqwdot>_vv_zvdota<mode>"
+ [(set (match_operand:<ZVQWDOTI_ACC> 0
"register_operand" "=&vr")
+ (if_then_else:<ZVQWDOTI_ACC>
+ (unspec:<VM>
+ [(match_operand:<VM> 1 "vector_mask_operand"
"vmWc1")
+ (match_operand 5 "vector_length_operand"
" rvl")
+ (match_operand 6 "const_int_operand"
" i")
+ (match_operand 7 "const_int_operand"
" i")
+ (match_operand 8 "const_int_operand"
" i")
+ (reg:SI VL_REGNUM)
+ (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
+ (unspec:<ZVQWDOTI_ACC>
+ [(match_operand:ZVQWDOTI_SRCMODE 3 "register_operand"
" vr")
+ (match_operand:ZVQWDOTI_SRCMODE 4 "register_operand"
" vr")
+ (match_operand:<ZVQWDOTI_ACC> 2 "register_operand"
" 0")
+ (match_operand 9 "const_int_operand"
" i")]
+ ZVQWDOT)
+ (match_dup 2)))]
+ "TARGET_VECTOR"
Don't we need a stronger condition here? These are only available
when the SDOT extensions are enabled, so we should be testing for
that. Similarly for other new patterns/expanders.
The mode iterators already carry per-extension predicates, so the generated
patterns should only be available for modes whose corresponding extension
is enabled. But I agree that relying on the iterator predicates is not
obvious from the define_insn condition itself.
I will make this more explicit in the next revision, either by adding
extension predicates to the define_insn conditions or by factoring the
per-extension conditions into mode attributes used by the pattern
conditions. I will also double-check the builtin expanders; the public
intrinsics are already guarded by their required extension sets, but the
RTL patterns should be clearly guarded as well.
+
+(define_insn "@pred_vfwdota_vv_zvdota<mode>"
+ [(set (match_operand:<ZVFWDOTBF_ACC> 0
"register_operand" "=&vr")
+ (if_then_else:<ZVFWDOTBF_ACC>
+ (unspec:<VM>
+ [(match_operand:<VM> 1 "vector_mask_operand"
"vmWc1")
+ (match_operand 5 "vector_length_operand"
" rvl")
+ (match_operand 6 "const_int_operand"
" i")
+ (match_operand 7 "const_int_operand"
" i")
+ (match_operand 8 "const_int_operand"
" i")
+ (reg:SI VL_REGNUM)
+ (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
+ (unspec:<ZVFWDOTBF_ACC>
+ [(match_operand:ZVFWDOTBF_SRCMODE 3 "register_operand"
" vr")
+ (match_operand:ZVFWDOTBF_SRCMODE 4 "register_operand"
" vr")
+ (match_operand:<ZVFWDOTBF_ACC> 2 "register_operand"
" 0")]
+ UNSPEC_VFWDOTA)
+ (match_dup 2)))]
I haven't looked at this extension closely, but presumably with the
widening nature we have to avoid certain overlaps? Robin is looking
at a better solution for that problem that should give us more
flexibility in the register allocation phase. GIven all the new
iterators, I'd like Robin to take a looksie as well.
Yes. The patterns currently model this conservatively by tying the
accumulator input to the output operand and using an earlyclobber output
constraint. The intention is to allow the destructive accumulator operand
while preventing the destination register group from overlapping the source
register groups. Hoping we have a better solve here.
I forgot to ask, have these extensions reached a frozen state yet?
Jeff
They are not ratified yet. My understanding from RVS-3925 is that the
Zvdota/Zvbdota work is on the ratification track and is scheduled to reach
Frozen status on June 22.
https://riscv.atlassian.net/browse/RVS-3925
So this series is not intended for immediate merge. It is sent for early
design feedback.
Thanks,
Jiawei