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

cranelift: Validate iconst ranges #6850

Merged

Conversation

timjrd
Copy link
Contributor

@timjrd timjrd commented Aug 16, 2023

Add the following checks:

  • iconst.i8 immediate must be within 0 .. 2^8-1
  • iconst.i16 immediate must be within 0 .. 2^16-1
  • iconst.i32 immediate must be within 0 .. 2^32-1

Resolves #3059

Explain why this change is needed:

As mentioned in #3059, iconst currently allows any immediate within the range of an i64, even for iconst.i8, iconst.i16 or iconst.i32.

This breaks some tests!

Running cargo test in /cranelift/codegen returns successfully. I also added a few tests concerning the new checks.

Running cargo test in /cranelift returns some failures. For example:

1: - inst1 (v1 = iconst.i8 -1): constant immediate is out of bounds
[...]
failures:
    bugpoint::tests::test_reduce
    run::test::nop

Which is expected if we forbid negative immediates, @jameysharp could you please confirm?

Running cargo test at the root of this repo returns a lot of failures, possibly related to negative immediates.

This is my first contribution so this patch is probably broken.

@timjrd timjrd changed the title [draft] cranelift: Validate iconst ranges cranelift: Validate iconst ranges Aug 16, 2023
@github-actions github-actions bot added the cranelift Issues related to the Cranelift code generator label Aug 16, 2023
@jameysharp
Copy link
Contributor

I think it's a good sign that the verifier is rejecting those tests. It's nice to confirm that it's detecting the problem that it was supposed to check for!

That said, I think the way we should fix these tests is by changing the parser for the textual CLIF representation, in cranelift/reader/src/parser.rs.

The first thing to note is that I believe parse_inst_operands should only be called for an InstructionFormat::UnaryImm if explicit_control_type is not None; I think iconst requires that a type always be provided, and it's the only instruction which uses that instruction format.

So when parsing operands for that format, we can report a syntax error if that argument is None, and otherwise match on the type to decide whether to call self.match_imm8/16/32. Those return signed types like i8, which needs to be converted to unsigned so it's zero-extended. So something like Imm64::from(self.match_imm8(...) as u8) should check that it fits in range for the appropriate type.

Does that make sense? Feel free to do that in this PR, or make a separate PR for that change which we'll merge first, either way.

@timjrd
Copy link
Contributor Author

timjrd commented Aug 20, 2023

After looking at the CLIF parser, it does make total sense. Thanks for the detailed explanation. 🙂

I have a somewhat working patch, I need to fix a few things and it should be good!

@timjrd
Copy link
Contributor Author

timjrd commented Aug 22, 2023

Hi @jameysharp 👋 please see the message of my last commit: I'm facing some test breakage, I fixed a few ones, but many others seem to be related to the conversion from signed to unsigned integers. Maybe I should adapt the ranges in the verifier to allow both signed and unsigned use (-128 .. 255 instead of 0 .. 255 for i8) as initially proposed by @afonso360? 🙂

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.

I still don't think that we want to allow sign-extended values in iconst instructions, and I don't think we need to.

Most of the remaining test failures are in the precise-output tests for the riscv64 backend, so I hope @afonso360 has time to take a look. There is one similar failure in each of x64 and s390x, and none in aarch64.

In all the failing precise-output tests, I think the backend is emitting constants where the upper bits are subsequently ignored so it doesn't matter what value they have, and this has changed only those upper bits. We need to verify that though. And it looks like riscv64 is missing an opportunity to use shorter sequences of instructions when those high bits don't matter.

Comment on lines 383 to 395
UnaryImm { imm, .. } => write!(w, " {}", imm),
UnaryImm { imm, .. } => write!(
w,
" {}",
Imm64::new(match dfg.ctrl_typevar(inst) {
types::I8 => imm.bits() as i8 as i64,
types::I16 => imm.bits() as i16 as i64,
types::I32 => imm.bits() as i32 as i64,
types::I64 => imm.bits(),
_ => unreachable!(),
})
),
Copy link
Contributor

Choose a reason for hiding this comment

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

The handful of test failures on your branch that are in filetests/filetests/egraph/ are because of this change: constants which were narrower than 64 bits were previously printed as unsigned, and are now printed as signed, but these tests expect the printed text to match what's in the test.

This change is harmless and I kind of like having these values printed the way you've done it, so you can fix the egraph tests by updating them to match the new format.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

OK! 🙂 The change in write.rs was needed to fix a test case, but ended up breaking some others, as you said. I'll update those outputs.

@jameysharp
Copy link
Contributor

One more thought: The fact that these backends produce different code based on the supposedly-ignored high bits of iconst instructions is potentially a sign of bugs in the backends. Hopefully these cases are all harmless but it's hard to tell at a glance. So these test failures are a good sign! They indicate that this PR will help us ensure that there aren't any surprising ways to affect codegen from a Cranelift frontend.

@afonso360
Copy link
Contributor

Hey, Just wanted to say that this is awesome work! Thanks for working on it. I'm going to look into the RISC-V failures, but It might take a bit.

@bjorn3
Copy link
Contributor

bjorn3 commented Aug 23, 2023

Would it make sense to store Uimm64 instead of Imm64 in iconst given that sign extending is no longer allowed?

@jameysharp
Copy link
Contributor

Would it make sense to store Uimm64 instead of Imm64 in iconst given that sign extending is no longer allowed?

Yes, I think so—but I think that's a much bigger change and we shouldn't try to do it in this PR.

@timjrd
Copy link
Contributor Author

timjrd commented Aug 23, 2023

Alright! I'm waiting for a greenlight (or a fix) before updating the outputs of the tests, since I'm a total ISAs / assembly / compiler noob.

After this PR is merged, I would be happy to work on replacing Imm64 by Uimm64, if the task is suitable for a compiler beginner with limited time resource. It's a related change, so at least I know where to start. 🙂

@jameysharp
Copy link
Contributor

Now that #6915 is merged (thanks @afonso360!), hopefully most of the test failures will disappear in this PR. Are you comfortable rebasing on main and taking another look at which tests fail now?

@timjrd timjrd force-pushed the cranelift_validate_iconst_ranges branch 2 times, most recently from f1d2996 to 78a91bc Compare August 29, 2023 23:10
@timjrd
Copy link
Contributor Author

timjrd commented Aug 29, 2023

I updated the egraphs file-tests. There are 2 remaining failures:

FAIL filetests/filetests/isa/x64/simd-lane-access-compile.clif: compile
line 185

    --- expected
    +++ actual
    @@ -2,7 +2,7 @@
       pushq   %rbp
       movq    %rsp, %rbp
     block0:
    -  movl    $-1, %ecx
    +  movl    $65535, %ecx
       movd    %ecx, %xmm1
       pshuflw $0, %xmm1, %xmm3
       pshufd  $0, %xmm3, %xmm0
    @@ -15,7 +15,7 @@
       pushq %rbp
       movq %rsp, %rbp
     block1: ; offset 0x4
    -  movl $0xffffffff, %ecx
    +  movl $0xffff, %ecx
       movd %ecx, %xmm1
       pshuflw $0, %xmm1, %xmm3
       pshufd $0, %xmm3, %xmm0

FAIL filetests/filetests/isa/s390x/constants.clif: compile
line 4

    --- expected
    +++ actual
    @@ -1,9 +1,9 @@
     VCode:
     block0:
    -  lhi %r2, -1
    +  lhi %r2, 255
       br %r14
     
     Disassembled:
     block0: ; offset 0x0
    -  lhi %r2, -1
    +  lhi %r2, 0xff
       br %r14

@timjrd timjrd requested a review from jameysharp August 29, 2023 23:29
@@ -206,7 +206,7 @@ block0(v0: i32):

; function %icmp_eq_smin(i32) -> i8 fast {
; block0(v0: i32):
; v1 = iconst.i32 0x8000_0000
; v1 = iconst.i32 0xffff_ffff_8000_0000
Copy link
Contributor Author

Choose a reason for hiding this comment

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

@jameysharp this is not super clean, the parser could not re-parse this output, I don't know if it's a big deal

Copy link
Contributor

Choose a reason for hiding this comment

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

Yeah, something's a little off about these tests, which appear to be sign-extending 32-bit constants to 64-bit when printing them. I think there's a bug in the writer but I haven't looked closely at it to figure out what that might be.

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 didn't check but most probably the Display instance for Imm64 is falling back to hex representation for big values. This particular example is a valid negative i32 value, but a big one, so maybe the Display implementation is falling back to unsigned 64-bit hexadecimal as it can't know it's a 32-bit value. We could add range checks in this Display instance and emit the right amount of hex digits; or I could remove my changes in the CLIF writer altogether and figure out another way of fixing the tests it solved.

Copy link
Contributor

Choose a reason for hiding this comment

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

I see now. Before this PR, for constants narrower than 64 bits we were preserving whether the input was written as a negative number or not based on whether the Imm64 was sign-extended or zero-extended. So some of the egraph tests used small negative numbers on input and got negative numbers in the test expectations output; others used large enough positive numbers to have the high bit set, which were printed as positive hex numbers before but get sign-extended by your change to the writer now.

I think we should revert your change to the writer so it doesn't try to sign-extend constants, and then we'll probably just need to update the test expectations to reflect that some negative constants are printed as large positive hex values now.

@jameysharp
Copy link
Contributor

This feels very close!

@abrown and @uweigand, could you take a look at the test failures happening on this PR and check my reasoning about them? The diffs in the precise-output compile tests are in a comment above.


For s390x, the failing test is:

function %f() -> i8 {
block0:
v0 = iconst.i8 -1
return v0
}
; VCode:
; block0:
; lhi %r2, -1
; br %r14
;
; Disassembled:
; block0: ; offset 0x0
; lhi %r2, -1
; br %r14

I think the lowering rule in question is this one:

;; 16-bit (or smaller) result type, any value
(rule 7 (imm (fits_in_16 ty) n)
(let ((dst WritableReg (temp_writable_reg ty))
(_ Unit (emit (MInst.Mov32SImm16 dst (u64_as_i16 n)))))
dst))

I'm guessing that callers are expected to ignore all but the least-significant 8 bits of %r2 if a function returns an I8, so it wouldn't matter that in this case the constant has been sign-extended past 8 bits. It also doesn't matter to Wasmtime, I think, since we don't use 8-bit constants and for anything wider there are type-specific lowering rules. But I think it's hard to prove that there aren't any other situations where a sign-extended 8-bit constant could cause other instructions to produce incorrect results.

That said, my guess is that we can just update this test expectation from "-1" to "255"/"0xff" and everything else will be good enough as-is.


For x64, this is the failing test:

function %splat_i16() -> i16x8 {
block0:
v0 = iconst.i16 -1
v1 = splat.i16x8 v0
return v1
}
; VCode:
; pushq %rbp
; movq %rsp, %rbp
; block0:
; movl $-1, %ecx
; movd %ecx, %xmm1
; pshuflw $0, %xmm1, %xmm3
; pshufd $0, %xmm3, %xmm0
; movq %rbp, %rsp
; popq %rbp
; ret
;
; Disassembled:
; block0: ; offset 0x0
; pushq %rbp
; movq %rsp, %rbp
; block1: ; offset 0x4
; movl $0xffffffff, %ecx
; movd %ecx, %xmm1
; pshuflw $0, %xmm1, %xmm3
; pshufd $0, %xmm3, %xmm0
; movq %rbp, %rsp
; popq %rbp
; retq

When the x64 backend lowers (splat (iconst x)) where x is an i16, it emits a 32-bit constant, which I think is because the matching lowering rule invokes bitcast_gpr_to_xmm $I32. As a result, it includes bits in the constant which are supposed to be ignored.

(rule 0 (lower (has_type $I16X8 (splat src)))
(x64_pshufd (x64_pshuflw (bitcast_gpr_to_xmm $I32 src) 0) 0))

I believe this is harmless because the value is used by pshuflw which is told to read only the lowest 16 bits, overwriting the uninitialized bits. If so, we can safely update the test expectation in this PR because only unused bits change. But I wonder if we should change the generated code further for this case? For example, does movw $-1, %cx have a shorter encoding than movl $-1, %ecx, or weird costs? Would it be worth matching on splat of iconst.i16 and precomputing the result of pshuflw as a 32-bit constant, if we have to emit a 32-bit constant anyway? etc.

@uweigand
Copy link
Member

I'm guessing that callers are expected to ignore all but the least-significant 8 bits of %r2 if a function returns an I8, so it wouldn't matter that in this case the constant has been sign-extended past 8 bits. It also doesn't matter to Wasmtime, I think, since we don't use 8-bit constants and for anything wider there are type-specific lowering rules. But I think it's hard to prove that there aren't any other situations where a sign-extended 8-bit constant could cause other instructions to produce incorrect results.

The general assumption in the s390x back-end is that when holding an i8 in a register, the upper bits are undefined and don't-care. (For example, i8 addition uses a 32-bit addition ISA instruction, which will change upper bits.) From that perspective, using lhi .., -1 and lhi .., 255 should be equivalent when loading an i8 value. (Also note that lhi only modifies the low 32 bits of the 64-bit register in the first place, the high bits are left unmodified. So either way this doesn't deterministically set all bits in the full register.)

As to the caller's expectations, the platform ABI does indeed require all scalar integer types to be zero- or sign-extended to the full register width when passed in registers. However, this is implemented at the cranelift IR level by using i8 uext or i8 sext as argument or return type, not a plain i8. (The latter is only used in rare cases like when passing a single-byte struct by value. In those cases the ABI does indeed state that the upper bits are undefined, so i8 correctly represents that semantics.)

That said, my guess is that we can just update this test expectation from "-1" to "255"/"0xff" and everything else will be good enough as-is.

Agreed.

@abrown
Copy link
Collaborator

abrown commented Aug 30, 2023

I believe this is harmless because the value is used by pshuflw which is told to read only the lowest 16 bits, overwriting the uninitialized bits. If so, we can safely update the test expectation in this PR because only unused bits change. But I wonder if we should change the generated code further for this case? For example, does movw $-1, %cx have a shorter encoding than movl $-1, %ecx, or weird costs? Would it be worth matching on splat of iconst.i16 and precomputing the result of pshuflw as a 32-bit constant, if we have to emit a 32-bit constant anyway? etc.

@jameysharp:

  • Your assumption is correct: pshuflw reads only the low 16 bits; you could just change the test
  • I don't think you're going to get smaller code with a word-mov; it's the same single byte opcode as a doubleword (32 bits in x86)
  • I like your idea of changing the codegen: I would just double up the 16-bit constant in the 32-bit mov and then use a single pshufd: for constant a, movl <a>:<a>, %ecx; movd %ecx, %xmm1; pshufd $0, %xmm1, %xmm1. (Another option would be to use a pshufb but then you have to setup a separate xmm register for the mask).

@jameysharp
Copy link
Contributor

Awesome: besides sorting out the writer change that's affecting the egraph tests, the last step for this PR is to update these two test expectations to match what the new parser implementation does.


I don't think you're going to get smaller code with a word-mov; it's the same single byte opcode as a doubleword (32 bits in x86)

I see it's the same opcode, but the immediate operand is only two bytes instead of four, right? Looking more carefully, I'm confused by the use of operand_size_of_type_32_64 in the imm constructor used by iconst. Why doesn't it use smaller move-from-immediate instructions for smaller types? Is this just to ensure that the upper bits in the register are initialized, or perhaps because nothing else needed smaller operand sizes?

(rule 1 (imm (fits_in_64 ty) (u64_nonzero simm64))
(let ((dst WritableGpr (temp_writable_gpr))
(size OperandSize (operand_size_of_type_32_64 ty))
(_ Unit (emit (MInst.Imm size simm64 dst))))
dst))

Add the following checks:

`iconst.i8`  immediate must be within 0 .. 2^8-1
`iconst.i16` immediate must be within 0 .. 2^16-1
`iconst.i32` immediate must be within 0 .. 2^32-1

Resolves bytecodealliance#3059
Modifies the parser for textual CLIF so that V in `iconst.T V` is
parsed according to T.

Before this commit, something like `iconst.i32 0xffff_ffff_ffff` was
valid because all `iconst` were parsed the same as an
`iconst.i64`. Now the above example will throw an error.

Also, a negative immediate as in `iconst.iN -X` is now converted to
`2^N - X`.

This commit also fixes some broken tests.
@timjrd timjrd force-pushed the cranelift_validate_iconst_ranges branch from 78a91bc to 3b5d25c Compare August 31, 2023 21:47
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.

Looks great to me! Let's see if this all passes CI and go ahead and merge it if so. Nice work!

@jameysharp
Copy link
Contributor

Oh, though you still have it marked as a draft PR. Do you feel it's ready to merge? You should click the "Ready for review" button if so.

@@ -189,11 +189,11 @@ block0:

; VCode:
; block0:
; lhi %r2, -1
; iilf %r2, 4294967295
Copy link
Contributor Author

Choose a reason for hiding this comment

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

The instructions are different. Is this expected?

; br %r14
;
; Disassembled:
; block0: ; offset 0x0
; lhi %r2, -1
; iilf %r2, 0xffffffff
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Same as above.

@timjrd
Copy link
Contributor Author

timjrd commented Aug 31, 2023

@jameysharp I think it's OK except for the 2 comments I made above. 🙂

@timjrd timjrd marked this pull request as ready for review August 31, 2023 22:39
@timjrd timjrd requested a review from a team as a code owner August 31, 2023 22:39
@jameysharp
Copy link
Contributor

Those two diffs are the same s390x instruction printed by two different disassemblers, so it's actually only one change. I looked at it before approving the PR earlier and decided that, although I don't know what the iilf instruction does, it's clearly emitting a 32-bit immediate constant and the instruction it came from is an iconst.i32, so it's probably fine. It's possible that @uweigand may want to change codegen based on this, if lhi is a more efficient instruction encoding or something, but I think that can safely land after this PR if it's worth doing at all.

@jameysharp jameysharp added this pull request to the merge queue Aug 31, 2023
Merged via the queue into bytecodealliance:main with commit cd33a1b Aug 31, 2023
18 checks passed
@timjrd
Copy link
Contributor Author

timjrd commented Sep 1, 2023

Nice to see this PR merged! Thanks for all your detailed explanations and guidance. This project is definitely beginner-friendly! 🚀

uweigand added a commit to uweigand/wasmtime that referenced this pull request Sep 1, 2023
After bytecodealliance#6850 was merged,
the s390x back-end now always uses iilf instead of lhi to load negative
constants, which is a small code size regression.

Fix the isle predicate to get back lhi whenever possible.
pchickey pushed a commit that referenced this pull request Sep 1, 2023
…6950)

* Enhance `async` configuration of `bindgen!` macro (#6942)

This commit takes a leaf out of `wiggle`'s book to enable bindings
generation for async host functions where only some host functions are
async instead of all of them. This enhances the `async` key with a few
more options:

    async: {
        except_imports: ["foo"],
        only_imports: ["bar"],
    }

This is beyond what `wiggle` supports where either an allow-list or
deny-list can be specified (although only one can be specified). This
can be useful if either the list of sync imports or the list of async
imports is small.

* cranelift-interpreter: Fix SIMD shifts and rotates (#6939)

* cranelift-interpreter: Fix SIMD `ishl`/`{s,u}`shr

* fuzzgen: Enable a few more ops

* cranelift: Fix tests for {u,s}shr

* fuzzgen: Change pattern matching arms for shifts

Co-Authored-By: Jamey Sharp <jsharp@fastly.com>

---------

Co-authored-by: Jamey Sharp <jsharp@fastly.com>

* Partially revert CLI argument changes from #6737 (#6944)

* Partially revert CLI argument changes from #6737

This commit is a partial revert of #6737. That change was reverted
in #6830 for the 12.0.0 release of Wasmtime and otherwise it's currently
slated to get released with the 13.0.0 release of Wasmtime. Discussion
at today's Wasmtime meeting concluded that it's best to couple this
change with #6925 as a single release rather than spread out across
multiple releases. This commit is thus the revert of #6737, although
it's a partial revert in that I've kept many of the new tests added to
showcase the differences before/after when the change lands.

This means that Wasmtime 13.0.0 will exhibit the same CLI behavior as
12.0.0 and all prior releases. The 14.0.0 release will have both a new
CLI and new argument passing semantics. I'll revert this revert (aka
re-land #6737) once the 13.0.0 release branch is created and `main`
becomes 14.0.0.

* Update release notes

* riscv64: Use `PCRelLo12I` relocation on Loads (#6938)

* riscv64: Use `PCRelLo12I` relocation on Loads

* riscv64: Strenghten pattern matching when emitting Load's

* riscv64: Clarify some of the load address logic

* riscv64: Even stronger matching

* Update Rust in CI to 1.72.0, clarify Wasmtime's MSRV (#6900)

* Update Rust in CI to 1.72.0

* Update CI, tooling, and docs for MSRV

This commit codifies an MSRV policy for Wasmtime at "stable minus two"
meaning that the latest three releases of Rust will be supported. This
is enforced on CI with a full test suite job running on Linux x86_64
with the minimum supported Rust version. The full test suite will use
the latest stable version. A downside of this approach is that new
changes may break MSRV support on non-Linux or non-x86_64 platforms and
we won't know about it, but that's deemed a minor enough risk at this
time.

A minor fix is applied to Wasmtime's `Cargo.toml` to support Rust 1.70.0
instead of requiring Rust 1.71.0

* Fix installation of rust

* Scrape MSRV from Cargo.toml

* Cranelift is the same as Wasmtime's MSRV now, more words too

* Fix a typo

* aarch64: Use `RegScaled*` addressing modes (#6945)

This commit adds a few cases to `amode` construction on AArch64 for
using the `RegScaled*` variants of `AMode`. This won't affect wasm due
to this only matching the sign-extension happening before the shift, but
it should otherwise help non-wasm Cranelift use cases.

Closes #6742

* cranelift: Validate `iconst` ranges (#6850)

* cranelift: Validate `iconst` ranges

Add the following checks:

`iconst.i8`  immediate must be within 0 .. 2^8-1
`iconst.i16` immediate must be within 0 .. 2^16-1
`iconst.i32` immediate must be within 0 .. 2^32-1

Resolves #3059

* cranelift: Parse `iconst` according to its type

Modifies the parser for textual CLIF so that V in `iconst.T V` is
parsed according to T.

Before this commit, something like `iconst.i32 0xffff_ffff_ffff` was
valid because all `iconst` were parsed the same as an
`iconst.i64`. Now the above example will throw an error.

Also, a negative immediate as in `iconst.iN -X` is now converted to
`2^N - X`.

This commit also fixes some broken tests.

* cranelift: Update tests to match new CLIF parser

* Some minor fixes and features for WASI and sockets (#6948)

* Use `command::add_to_linker` in tests to reduce the number of times
  all the `add_to_linker` are listed.
* Add all `wasi:sockets` interfaces currently implemented to both the
  sync and async `command` functions (this enables all the interfaces in
  the CLI for example).
* Use `tokio::net::TcpStream::try_io` whenever I/O is performed on a
  socket, ensuring that readable/writable flags are set/cleared
  appropriately (otherwise once readable a socket is infinitely readable).
* Add a `with_ambient_tokio_runtime` helper function to use when
  creating a `tokio::net::TcpStream` since otherwise it panics due to a
  lack of active runtime in a synchronous context.
* Add `WouldBlock` handling to return a 0-length read.
* Add an `--inherit-network` CLI flag to enable basic usage of sockets
  in the CLI.

This will conflict a small amount with #6877 but should be easy to
resolve, and otherwise this targets different usability points/issues
than that PR.

---------

Co-authored-by: Afonso Bordado <afonso360@users.noreply.github.com>
Co-authored-by: Jamey Sharp <jsharp@fastly.com>
Co-authored-by: Timothée Jourde <timjrd@netc.fr>
@uweigand
Copy link
Member

uweigand commented Sep 1, 2023

Those two diffs are the same s390x instruction printed by two different disassemblers, so it's actually only one change. I looked at it before approving the PR earlier and decided that, although I don't know what the iilf instruction does, it's clearly emitting a 32-bit immediate constant and the instruction it came from is an iconst.i32, so it's probably fine. It's possible that @uweigand may want to change codegen based on this, if lhi is a more efficient instruction encoding or something, but I think that can safely land after this PR if it's worth doing at all.

This is now #6952

github-merge-queue bot pushed a commit that referenced this pull request Sep 2, 2023
After #6850 was merged,
the s390x back-end now always uses iilf instead of lhi to load negative
constants, which is a small code size regression.

Fix the isle predicate to get back lhi whenever possible.
afonso360 added a commit to afonso360/wasmtime that referenced this pull request Sep 5, 2023
timjrd added a commit to timjrd/wasmtime that referenced this pull request Sep 5, 2023
Resolves bytecodealliance#6965
Linked to bytecodealliance#3059 bytecodealliance#6850 bytecodealliance#6958

Co-authored-by: Afonso Bordado <afonso360@users.noreply.github.com>
github-merge-queue bot pushed a commit that referenced this pull request Sep 5, 2023
Resolves #6965
Linked to #3059 #6850 #6958

Co-authored-by: Afonso Bordado <afonso360@users.noreply.github.com>
eduardomourar pushed a commit to eduardomourar/wasmtime that referenced this pull request Sep 6, 2023
* cranelift: Validate `iconst` ranges

Add the following checks:

`iconst.i8`  immediate must be within 0 .. 2^8-1
`iconst.i16` immediate must be within 0 .. 2^16-1
`iconst.i32` immediate must be within 0 .. 2^32-1

Resolves bytecodealliance#3059

* cranelift: Parse `iconst` according to its type

Modifies the parser for textual CLIF so that V in `iconst.T V` is
parsed according to T.

Before this commit, something like `iconst.i32 0xffff_ffff_ffff` was
valid because all `iconst` were parsed the same as an
`iconst.i64`. Now the above example will throw an error.

Also, a negative immediate as in `iconst.iN -X` is now converted to
`2^N - X`.

This commit also fixes some broken tests.

* cranelift: Update tests to match new CLIF parser
eduardomourar pushed a commit to eduardomourar/wasmtime that referenced this pull request Sep 6, 2023
…6952)

After bytecodealliance#6850 was merged,
the s390x back-end now always uses iilf instead of lhi to load negative
constants, which is a small code size regression.

Fix the isle predicate to get back lhi whenever possible.
eduardomourar pushed a commit to eduardomourar/wasmtime that referenced this pull request Sep 6, 2023
jameysharp added a commit to jameysharp/wasmtime that referenced this pull request Apr 4, 2024
Since bytecodealliance#6850, we've been able to rely on `iconst` instructions having
their immediate operands' high bits zeroed before lowering.

So a couple of places in `x64/lower.rs` can be expressed more simply now
as a result.

Out of an abundance of caution, I added a debug-assertion when constants
are looked up during lowering, to check that earlier phases really did
ensure the high bits are zero.

I also got rid of an `expect` where a simple pattern-match will do.
jameysharp added a commit to jameysharp/wasmtime that referenced this pull request Apr 4, 2024
Since bytecodealliance#6850, we've been able to rely on `iconst` instructions having
their immediate operands' high bits zeroed before lowering.

So a couple of places in `x64/lower.rs` can be expressed more simply now
as a result.

Out of an abundance of caution, I added a debug-assertion when constants
are looked up during lowering, to check that earlier phases really did
ensure the high bits are zero.

I also got rid of an `expect` where a simple pattern-match will do.
github-merge-queue bot pushed a commit that referenced this pull request Apr 4, 2024
Since #6850, we've been able to rely on `iconst` instructions having
their immediate operands' high bits zeroed before lowering.

So a couple of places in `x64/lower.rs` can be expressed more simply now
as a result.

Out of an abundance of caution, I added a debug-assertion when constants
are looked up during lowering, to check that earlier phases really did
ensure the high bits are zero.

I also got rid of an `expect` where a simple pattern-match will do.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
cranelift:wasm cranelift Issues related to the Cranelift code generator
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Validate const value ranges in CLIF Validator
6 participants