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.
12 lines
199 B
Plaintext
12 lines
199 B
Plaintext
test run
|
|
target x86_64 machinst
|
|
|
|
function %bint_b8_i128() -> i64, i64 {
|
|
block0:
|
|
v0 = bconst.b8 true
|
|
v1 = bint.i128 v0
|
|
v2, v3 = isplit.i128 v1
|
|
return v2, v3
|
|
}
|
|
; run: %bint_b8_i128() == [1, 0]
|