Skip to content

Conversation

@afonso360
Copy link
Contributor

👋 Hey,

This PR fixes the RISC-V issues that #6850 exposed. It does a bit of a refactor in our constant emission infrastructure, and also moves some of it into ISLE.

The issues that that PR exposed are that we sometimes would match or not match a particular constant generation strategy based on the upper bits that shouldn't really matter. The main fix is to sign extend constants before trying to match them.

Moving the constant emission into ISLE also means that we have a bunch of neutral regalloc changes. There are a few cases where we have actual changes in the instructions emitted.

This PR contains a lot of stuff, and I would recommend reviewing it commit by commit.

This better fits the existing naming convention of constructors being `x_to_y` and extractors being `y_from_x`

See `u64_to_uimm5` or `uimm5_from_u8` as examples.
Instead of taking a closure, return an Option with the split values
This moves the constant emission rules into isle and cleans
up some of the existing constant emission code.

Further work is still required
@afonso360 afonso360 added the cranelift:area:riscv64 Issues related to the RISC-V 64 backend. label Aug 26, 2023
@afonso360 afonso360 requested a review from a team as a code owner August 26, 2023 16:55
@afonso360 afonso360 requested review from elliottt and removed request for a team August 26, 2023 16:55
@github-actions github-actions bot added cranelift Issues related to the Cranelift code generator cranelift:area:machinst Issues related to instruction selection and the new MachInst backend. isle Related to the ISLE domain-specific language labels Aug 26, 2023
@github-actions
Copy link

Subscribe to Label Action

cc @cfallin, @fitzgen

Details This issue or pull request has been labeled: "cranelift", "cranelift:area:machinst", "cranelift:area:riscv64", "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.

Copy link
Contributor

@jameysharp jameysharp left a comment

Choose a reason for hiding this comment

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

This looks great, for the most part! I feel much better about this infrastructure with these changes.

I think Imm20::maybe_from_u64 is incorrect and also unused, although I'd suggest using it from generate_imm so I think it's worth fixing it. However if you want to just delete it in this PR and maybe add a corrected version in a later PR, that's fine with me.

(rv_vwadd_vx x y (unmasked) (vstate_mf2 (ty_half_lanes in_ty))))

(rule 14 (lower (has_type (ty_vec_fits_in_register _) (iadd (splat (sextend x @ (value_type sext_ty)))
(rule 15 (lower (has_type (ty_vec_fits_in_register _) (iadd (splat (sextend x @ (value_type sext_ty)))
Copy link
Contributor

Choose a reason for hiding this comment

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

I can't see from the diff of the "Sign extend replicated_imm5 immediates" commit why these rules needed a higher priority; I don't see another rule at priority 14 that these rules could conflict with.

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 don't know why that overlap showed up either. But it does show up when I switch the definition of replicated_imm5. The overlaps that ISLE reports are:

  src/isa/riscv64/lower.isle:139:7: (rule 14 (lower (has_type (ty_vec_fits_in_register ty) (iadd (replicated_imm5 x) y)))
  src/isa/riscv64/lower.isle:204:7: (rule 14 (lower (has_type (ty_vec_fits_in_register _) (iadd (splat (uextend x @ (value_type uext_ty)))
  src/isa/riscv64/lower.isle:159:7: (rule 14 (lower (has_type (ty_vec_fits_in_register _) (iadd (splat (sextend x @ (value_type sext_ty)))
  src/isa/riscv64/lower.isle:182:7: (rule 14 (lower (has_type (ty_vec_fits_in_register _) (iadd (splat (sextend x @ (value_type sext_ty)))
  src/isa/riscv64/lower.isle:227:7: (rule 14 (lower (has_type (ty_vec_fits_in_register _) (iadd (splat (uextend y @ (value_type uext_ty)))

Copy link
Contributor

Choose a reason for hiding this comment

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

Ah, now I understand. Previously replicated_imm5 matched iconst and ISLE could tell that's a different enum variant than splat. Now it matches an external constructor, which ISLE has to assume could match splat, even though we know it doesn't. I don't see a reasonable way to rewrite that to give ISLE more information, so changing the priorities like you've done here is the only option.

Some((
Imm20::from_bits(imm20 as i32),
Imm12::from_bits(imm12 as i16),
))
Copy link
Contributor

Choose a reason for hiding this comment

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

I appreciate that this is a pretty minimal change, but looking at the original function I kind of really want to rewrite the whole thing. Something along these lines:

    // sign-extend the low 12 bits: this is the value we can represent with an `addi` immediate operand
    const SIGN_BITS: u8 = 64 - 12;
    let imm12 = (value as i64) << SIGN_BITS >> SIGN_BITS;
    // compute the inverse of `addi` to see what part we need to use `lui` for;
    // note that by construction the low 12 bits are always 0 so it's safe to shift them out
    let imm20 = value.wrapping_sub(imm12 as u64) >> 12;
    // check that the imm20 part fits; note that by construction the imm12 always fits
    Imm20::maybe_from_u64(imm20).map(|imm20| (imm20, Imm12::from_bits(imm12 as i16)))

I think that should correctly replace everything, including the check for imm_min/imm_max and the check for whether an imm12 is enough.

Copy link
Contributor Author

@afonso360 afonso360 Aug 29, 2023

Choose a reason for hiding this comment

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

Yeah, I was trying to avoid changing that function since it ends up being slightly complicated to write. And that version is a lot cleaner.

I think it might be failing in a couple edge cases since some tests stop working with it, and I don't really feel like looking into it now, but I'm going to file an issue to follow up on it later (#6922).

@jameysharp jameysharp removed the request for review from elliottt August 28, 2023 20:50
@afonso360 afonso360 added this pull request to the merge queue Aug 29, 2023
Merged via the queue into bytecodealliance:main with commit 4e52d95 Aug 29, 2023
@afonso360 afonso360 deleted the riscv-fix-imm branch August 29, 2023 18:52
eduardomourar pushed a commit to eduardomourar/wasmtime that referenced this pull request Sep 6, 2023
* riscv64: Sign extend imm12 values

* riscv64: Rename `imm5_to_i8` constructor

This better fits the existing naming convention of constructors being `x_to_y` and extractors being `y_from_x`

See `u64_to_uimm5` or `uimm5_from_u8` as examples.

* riscv64: Sign extend `replicated_imm5` immediates

* riscv64: Delete `neg_imm12` helper

* riscv64: Delete `construct_imm_sub_rs`

It is no longer used.

* riscv64: Refactor `Inst::generate_imm`

Instead of taking a closure, return an Option with the split values

* riscv64: Rework constant emission

This moves the constant emission rules into isle and cleans
up some of the existing constant emission code.

Further work is still required

* riscv64: Fix imm matching for `insertlane`

* riscv64: Misc cleanups

* riscv64: Refactor uses of `Imm12::maybe_from_u64`

Use `Imm12::maybe_from_i64` where it is more ergonomic

* riscv64: Delete `Imm20::maybe_from_u64`
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

cranelift:area:machinst Issues related to instruction selection and the new MachInst backend. cranelift:area:riscv64 Issues related to the RISC-V 64 backend. 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.

2 participants