Files
wasmtime/cranelift/filetests/filetests/runtests/bint.clif
Chris Fallin efe3930215 Fix bint on x64, and make bextend consistent with bool representation.
There has been occasional confusion with the representation that we use
for bool-typed values in registers, at least when these are wider than
one bit. Does a `b8` store `true` as 1, or as all-ones (`0xff`)?

We've settled on the latter because of some use-cases where the wide
bool becomes a mask -- see #2058 for more on this.

This is fine, and transparent, to most operations within CLIF, because
the bool-typed value still has only two semantically-visible states,
namely `true` and `false`.

However, we have to be careful with bool-to-int conversions. `bint` on
aarch64 correctly masked the all-ones value down to 0 or 1, as required
by the instruction specification, but on x64 it did not. This PR fixes
that bug and makes x64 consistent with aarch64.

While staring at this code I realized that `bextend` was also not
consistent with the all-ones invariant: it should do a sign-extend, not
a zero-extend as it previously did. This is also rectified and tested.
(Aarch64 also already had this case implemented correctly.)

Fixes #3003.
2021-06-22 10:56:56 -07:00

38 lines
597 B
Plaintext

test run
target aarch64
target x86_64 machinst
function %bint_b8_i16_true() -> i16 {
block0:
v0 = bconst.b8 true
v1 = bint.i16 v0
return v1
}
; run: %bint_b8_i16_true() == 1
function %bint_b16_i16_true() -> i16 {
block0:
v0 = bconst.b16 true
v1 = bint.i16 v0
return v1
}
; run: %bint_b16_i16_true() == 1
function %bint_b8_i16_false() -> i16 {
block0:
v0 = bconst.b8 false
v1 = bint.i16 v0
return v1
}
; run: %bint_b8_i16_false() == 0
function %bint_b16_i16_false() -> i16 {
block0:
v0 = bconst.b16 false
v1 = bint.i16 v0
return v1
}
; run: %bint_b16_i16_false() == 0