Add configurable per-class trap policy for non-zero vstart#1703
Conversation
|
I haven’t checked the vector crypto instructions yet, but I suspect this is already handled. |
|
My understanding of Software can't safely write arbitrary values of
When executing an instruction you must start from
Since the current model only produces The obvious fix is that we require Then in future we can allow other values but also change the loops from So I reckon for now just change your Note also that the behaviour for when
Btw the thing I mentioned in the meeting about being able to repeat elements was not actually about vstart - I was thinking of this which isn't a problem for us at the moment. |
|
Tim Hutt (@Timmmm) Thanks that, this makes sense!
I was wondering whether it would make sense to start adding support for vstart != 0 for LOAD/STORE RVV instructions soon. I can imagine this is actually something people would like to test and that it could provide some value, especially for load/store operations that cross page boundaries. I also think it should not be too hard to support. We would probably just need to modify the handful of load/store instructions and start looping from vstart instead of 0 and write vstart when we return an error. So maybe we do as you suggested for now and require that all instructions trap on vstart != 0, but then later I could create a follow-up PR implementing what I described above, where we would allow vstart != 0 for load/store operations. Thoughts? |
|
Isn't |
|
Prashanth Mundkur (@pmundkur) Ahh yeah, you are right! I took another look at vext_mem_insts.sail, and we already support vstart != 0 for LOAD/STORE instructions. |
efa6ecb to
a8ab6e1
Compare
|
Ok so I removed the config option for ALU instructions and now always trap if vstart is non-zero. Other then that I am still not so sure about the naming of the enum values (VS_ALU). Does someone have a better idea? :D |
|
Perhaps |
|
With regards to act4 testing, we would like to use sail as the reference model to test all our possible test cases. While trapping on vstart != 0 I agree makes a lot of sense from an implementation's perspective, however there are a small subset of normative statements of the spec we would like to exercise that this behaviour would not allow us to. One example is:
As normally we can run with vstart=0 to satisfy the vstart >= vl condition. support vstart != 0 for loads addresses most situations but not whole register moves:
|
3a6a41f to
2b71c16
Compare
|
jacassidy (@jacassidy) I looked into this and actually started adding it, but I felt it was beginning to balloon the PR and would have made it more complicated to review. Instead, I added back the configuration option for vector arithmetic instructions. With this new configuration option and a follow-up PR, you should be able to test what you're looking for. Besides that, please let me know if this PR looks good and whether it addresses some of the ATC4 needs. |
I needed to add some checks for Zvbb and Zvbc |
Prashanth Mundkur (pmundkur)
left a comment
There was a problem hiding this comment.
Some initial comments after a quick look; I'll take a closer look later after reading the spec.
|
Nadime Barhoumi (@nadime15) Understood, thank you for the attempt. Ryan Wolk (@fourth-bit) will be taking over vector, he is currently running this pr against our test suite to confirm it solves any discrepencies and will likely weigh in shortly |
|
It looks like this is giving us the configuration options to match spike and qemu for the arithmetic instructions. But, spike is trapping on scalar move instructions with nonzero vstart. According to riscv/riscv-isa-manual#2564 (comment) this behavior is permitted and not defined as independent of vstart, so it would be nice to also have a configuration option for the behavior of |
I'm having a hard time squaring this with these parts of the spec
Perhaps I'm misunderstanding something? |
|
We were discussing the part of the spec and had some deliberation. I understand it to be saying that these two instructions either do or dont have additional constraints on vstart, not that their implementation is independent of them. Therefore it would be a legal implication to trap on a vstart that the instruction itself cannot produce. It may be worth opening an issue, or it may be obvious that my interpretation is wrong. |
|
I put up the follow-up Right now get_start_element only bounds vstart against a single register's worth of elements, which is too narrow once LMUL > 1, and the follow-up replaces that with the real per instruction element count and moves the validation up front into illegal_vstart. So this PR gives us the configurable trap policy, and the follow-up closes the bounds-checking side, together they should cover what we need once both land. I kept them separate just to keep each PR focused and easier to review. |
I added a new config option (not pushed yet), I just need to double check that the spec really allows it (need to read your linked comment carefully as well as check the spec again). |
1b4e1c4 to
42385ce
Compare
|
So, reading Andrew's comment again, it seems that we can actually trap when vstart != 0 simply because these instructions (SCALAR_MOVE) can never produce a non-zero vstart themselves (and implementation are permitted to trap). As he pointed out, a vstart!=0 makes no sense because for vmv.x.s/vfmv.f.s it is ignored by definition anyway, while for vmv.s.x/vfmv.s.f the operation would be masked off when vstart != 0, effectively making it a no-op. |
Prashanth Mundkur (pmundkur)
left a comment
There was a problem hiding this comment.
Generally LGTM. I haven't looked at your follow-up branch yet.
Adds a `vstart_class` enum and `illegal_vstart()` helper classifying
each vector instruction's vstart trap policy:
- `VSTART_ARITH` — trap on non-zero vstart, configurable via
`extensions.V.vstart.zero_required.arith`
(default `true`)
- `VSTART_LOAD_STORE` — never traps (vstart needed for trap resumption)
- `VSTART_SCALAR_MOVE` — trap on non-zero vstart, configurable via
`extensions.V.vstart.zero_required.scalar_move`
(default `true`)
- `VSTART_MANDATORY` — always traps on non-zero vstart (spec-required:
reductions, vcompress, vcpop/vfirst/vmsbf/
vmsif/vmsof/viota.m)
The model only produces a non-zero vstart on load/store faults, so the
specification permits arithmetic and scalar-move instructions to trap on
any non-zero vstart. By default, arithmetic and scalar-move instructions
trap on a non-zero vstart. The arithmetic and scalar-move defaults introduce
a backward-incompatible change. Both defaults can be configured to match the
behaviour of a different implementation.
The element-wise vector crypto instructions (Zvbb, Zvbc) and the Zvabd
and bfloat16 vector instructions share the arithmetic policy. Element-group
vector crypto keeps its own EGS-alignment rules.
The previous inline `assert_vstart(0)` checks in reduction helpers and
mandatory-trap instructions are replaced with `illegal_vstart(VSTART_MANDATORY)`.
Partially addresses riscv#1104 (stricter vstart bounds checking remains a
follow-up).
94f7d60 to
d694c8f
Compare
|
Let's merge this soon so that we can get the out-of-bounds check in as well. |
Adds a
vstart_classenum andillegal_vstart()helper classifyingeach vector instruction's vstart trap policy:
VSTART_ARITH— trap on non-zero vstart, configurable viaextensions.V.vstart.zero_required.arith(defaulttrue)VSTART_LOAD_STORE— never traps (vstart needed for trap resumption)VSTART_SCALAR_MOVE— trap on non-zero vstart, configurable viaextensions.V.vstart.zero_required.scalar_move(defaulttrue)VSTART_MANDATORY— always traps on non-zero vstart (spec-required: reductions, vcompress, vcpop/vfirst/vmsbf/vmsif/vmsof/viota.m)The model only produces a non-zero vstart on load/store faults, so the specification permits arithmetic and scalar-move instructions to trap on any non-zero vstart. By default, arithmetic and scalar-move instructions
trap on a non-zero vstart. The arithmetic and scalar-move defaults introduce a backward-incompatible change. Both defaults can be configured to match the behaviour of a different implementation.
The element-wise vector crypto instructions (Zvbb, Zvbc) and the Zvabd and bfloat16 vector instructions share the arithmetic policy. Element-group vector crypto keeps its own EGS-alignment rules.
The previous inline
assert_vstart(0)checks in reduction helpers and mandatory-trap instructions are replaced withillegal_vstart(VSTART_MANDATORY).Partially addresses #1104 (stricter vstart bounds checking remains a
follow-up).