Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

riscv64: Initial support for the ZiCond Extension #8695

Merged
merged 9 commits into from
May 30, 2024

Conversation

afonso360
Copy link
Contributor

👋 Hey,

This PR adds support for the ZiCond: Integer Conditional Operations (Chapter 12 of the Unprivileged RISC-V ISA Manual).

This extension adds two instructions that either zero a register, or move one of the arguments, depending on a condition register.

  • czero.eqz rd, rs1, rs2 - Moves zero to a register rd, if the condition rs2 is equal to zero, otherwise moves rs1 to rd.
  • czero.nez rd, rs1, rs2 - Moves zero to a register rd, if the condition rs2 is nonzero, otherwise moves rs1 to rd

It doesn't include a full conditional move of two registers, but that is implemented by combining both of the instructions above.

The ISA manual also suggests some interesting instruction sequences for conditional add/sub/and/or/etc... that only contain two instructions.

This PR only implements the base cases. The direct lowerings of the instructions, as well as the full conditional move of two registers. I'm planning on implementing the other sequences at a later date.

@afonso360 afonso360 added the cranelift:area:riscv64 Issues related to the RISC-V 64 backend. label May 27, 2024
@afonso360 afonso360 requested review from a team as code owners May 27, 2024 11:09
@afonso360 afonso360 requested review from fitzgen and removed request for a team May 27, 2024 11:09
@afonso360 afonso360 changed the title riscv64: Initial support for ZiCond Extension riscv64: Initial support for the ZiCond Extension May 27, 2024
@github-actions github-actions bot added cranelift Issues related to the Cranelift code generator cranelift:meta Everything related to the meta-language. isle Related to the ISLE domain-specific language labels May 27, 2024
Copy link

Subscribe to Label Action

cc @cfallin, @fitzgen

This issue or pull request has been labeled: "cranelift", "cranelift:area:riscv64", "cranelift:meta", "isle"

Thus the following users have been cc'd because of the following labels:

  • cfallin: isle
  • fitzgen: isle

To subscribe or unsubscribe from this label, edit the .github/subscribe-to-label.json configuration file.

Learn more.

Additionally add some checks to prevent a stack overflow in the zero
swap rules
cranelift/codegen/src/isa/riscv64/inst.isle Outdated Show resolved Hide resolved
Comment on lines +1830 to +1833
;; Manually matching (iconst 0) here is a bit of a hack. We can't do that as part
;; of the iconst rule because that runs into regalloc issues. gen_select_xreg
;; has some optimizations based on the use of the zero register so we have to
;; manually match it here.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I remember running into this historically as well, you wouldn't happen to know off-hand if there's an issue for this or if you've bottomed it out before perhaps? This isn't the first time that it's been useful to pattern-match on (zero_reg) and generating the zero register directly I think also results in better codegen in situations as well (as it avoids a move-of-zero into a register)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've definitely run into it in the past. And IIRC it was something to do with regalloc, but I don't remember what exactly. I tried to search around the existing issues / PR's and I couldn't find a direct reference to any of it, but I'm fairly sure we've talked about it.

I'll create an issue and then we can have that centralized in a single place.

Copy link
Contributor Author

@afonso360 afonso360 May 28, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I found it! #7162 It looks like there's a pretty big incompatibility with RA2.

I wonder if we could just check all of the register uses when collecting the operands, and using Operand::fixed_nonallocatable() instead of the normal reg_use if we do find the zero register. Might be worth trying.

Edit: Re-reading that thread again, it looks like this still wouldn't work

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unfortunately yeah the issue is that we don't do rematerialization, and so we need to distinguish between "zero for this operand that can accept a special reg" and "zero in an arbitrary lowered-from-SSA reg" which fundamentally needs participation from the lowering logic; operand kinds can't patch the hole.

(Remat would be great to have! It's also a giant lift in complexity...)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nothing like routinely forgetting PRs I myself made...

In any case thanks for digging that up! In the meantime I would definitely agree that the implemented solution in this PR, pattern matching iconst 0, is the way to go.

cranelift/codegen/src/isa/riscv64/inst.isle Outdated Show resolved Hide resolved
alexcrichton added a commit to alexcrichton/wasmtime that referenced this pull request May 28, 2024
This commit is inspired by discussion on bytecodealliance#8695 which made me remember
the discussion around bytecodealliance#7162 historically. In lieu of a deeper fix for
the issue of "why can't `iconst 0` use `(zero_reg)`" it's still possible
to add special-cases to rules throughout the backend so this commit does
that for generating zero-value floats.
@afonso360
Copy link
Contributor Author

It looks like one of the CI jobs was canceled part way through. I wonder if this is also related to the issues in #8701

@alexcrichton alexcrichton added this pull request to the merge queue May 30, 2024
Merged via the queue into bytecodealliance:main with commit 700f43c May 30, 2024
66 checks passed
github-merge-queue bot pushed a commit that referenced this pull request May 30, 2024
* riscv64: Special-case `f32const 0` and `f64const 0`

This commit is inspired by discussion on #8695 which made me remember
the discussion around #7162 historically. In lieu of a deeper fix for
the issue of "why can't `iconst 0` use `(zero_reg)`" it's still possible
to add special-cases to rules throughout the backend so this commit does
that for generating zero-value floats.

* Fix tests

* Run all tests on CI

prtest:full
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
cranelift:area:riscv64 Issues related to the RISC-V 64 backend. cranelift:meta Everything related to the meta-language. cranelift Issues related to the Cranelift code generator isle Related to the ISLE domain-specific language
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants