Stream: git-wasmtime

Topic: wasmtime / issue #3003 Cranelift: bint produces different...


view this post on Zulip Wasmtime GitHub notifications bot (Jun 19 2021 at 21:29):

afonso360 opened issue #3003:

Hey,

While working on #2978, i found that we are lowering constants inconsistently between backends. x64 always lowers as -1 (i.e. all bits 1) while aarch64 lowers as 1.

I don't know which one is correct, but they should agree with each other. According to this comment I think the behavior on x64 is wrong.

It looks like cg_clif depends on this behavior.

.clif Test Case

test run
target aarch64
target x86_64 machinst

function %bint_b8_i16() -> i16 {
block0:
  v0 = bconst.b8 true
  v1 = bint.i16 v0
  return v1
}
; Passes on x86, fails on aarch64
; run: %bint_b8_i16() == 0xFF

; Passes on aarch64, fails on x86
; run: %bint_b8_i16() == 1


function %bint_b16_i16() -> i16 {
block0:
  v0 = bconst.b16 true
  v1 = bint.i16 v0
  return v1
}
; Passes on x86, fails on aarch64
; run: %bint_b16_i16() == 0xFFFF

; Passes on aarch64, fails on x86
; run: %bint_b16_i16() == 1

Steps to Reproduce

Run the above test

Expected Results

The aarch64 and x64 backends should produce identical results

Actual Results

Bools are lowered as either 1 or -1 depending on the backend.

Versions and Environment

Cranelift version or commit: current main branch
Operating system: Windows 10
Architecture: x64 / aarch64

view this post on Zulip Wasmtime GitHub notifications bot (Jun 19 2021 at 21:29):

afonso360 labeled issue #3003:

Hey,

While working on #2978, i found that we are lowering constants inconsistently between backends. x64 always lowers as -1 (i.e. all bits 1) while aarch64 lowers as 1.

I don't know which one is correct, but they should agree with each other. According to this comment I think the behavior on x64 is wrong.

It looks like cg_clif depends on this behavior.

.clif Test Case

test run
target aarch64
target x86_64 machinst

function %bint_b8_i16() -> i16 {
block0:
  v0 = bconst.b8 true
  v1 = bint.i16 v0
  return v1
}
; Passes on x86, fails on aarch64
; run: %bint_b8_i16() == 0xFF

; Passes on aarch64, fails on x86
; run: %bint_b8_i16() == 1


function %bint_b16_i16() -> i16 {
block0:
  v0 = bconst.b16 true
  v1 = bint.i16 v0
  return v1
}
; Passes on x86, fails on aarch64
; run: %bint_b16_i16() == 0xFFFF

; Passes on aarch64, fails on x86
; run: %bint_b16_i16() == 1

Steps to Reproduce

Run the above test

Expected Results

The aarch64 and x64 backends should produce identical results

Actual Results

Bools are lowered as either 1 or -1 depending on the backend.

Versions and Environment

Cranelift version or commit: current main branch
Operating system: Windows 10
Architecture: x64 / aarch64

view this post on Zulip Wasmtime GitHub notifications bot (Jun 19 2021 at 21:29):

afonso360 labeled issue #3003:

Hey,

While working on #2978, i found that we are lowering constants inconsistently between backends. x64 always lowers as -1 (i.e. all bits 1) while aarch64 lowers as 1.

I don't know which one is correct, but they should agree with each other. According to this comment I think the behavior on x64 is wrong.

It looks like cg_clif depends on this behavior.

.clif Test Case

test run
target aarch64
target x86_64 machinst

function %bint_b8_i16() -> i16 {
block0:
  v0 = bconst.b8 true
  v1 = bint.i16 v0
  return v1
}
; Passes on x86, fails on aarch64
; run: %bint_b8_i16() == 0xFF

; Passes on aarch64, fails on x86
; run: %bint_b8_i16() == 1


function %bint_b16_i16() -> i16 {
block0:
  v0 = bconst.b16 true
  v1 = bint.i16 v0
  return v1
}
; Passes on x86, fails on aarch64
; run: %bint_b16_i16() == 0xFFFF

; Passes on aarch64, fails on x86
; run: %bint_b16_i16() == 1

Steps to Reproduce

Run the above test

Expected Results

The aarch64 and x64 backends should produce identical results

Actual Results

Bools are lowered as either 1 or -1 depending on the backend.

Versions and Environment

Cranelift version or commit: current main branch
Operating system: Windows 10
Architecture: x64 / aarch64

view this post on Zulip Wasmtime GitHub notifications bot (Jun 19 2021 at 21:50):

bjorn3 commented on issue #3003:

-1 is the expected behavior for bmask I think, not for bint.

view this post on Zulip Wasmtime GitHub notifications bot (Jun 21 2021 at 14:11):

akirilov-arm commented on issue #3003:

The bint documentation states that either 0 or 1 is the expected result. As for bconst, both backends seem to behave identically.

view this post on Zulip Wasmtime GitHub notifications bot (Jun 21 2021 at 17:22):

cfallin commented on issue #3003:

Thanks for finding this!

I did a bit of archaeology just now to try to work out what's going on here, as I recalled we had had some discussions about this already. It turns out that we have, also #2058.

The bconst is indeed correct, as per above -- it generates all-ones into the register (this is so that it can be used as a mask). The issue is that I think the bint implementation on x64 does not properly mask this down to 0 or 1. It appears that I had added the masking in aarch64 when I made the change in #2058 above but the x64 backend wasn't updated at the same time. I'll do a quick PR to rectify this!

view this post on Zulip Wasmtime GitHub notifications bot (Jun 22 2021 at 18:26):

cfallin closed issue #3003:

Hey,

While working on #2978, i found that we are lowering constants inconsistently between backends. x64 always lowers as -1 (i.e. all bits 1) while aarch64 lowers as 1.

I don't know which one is correct, but they should agree with each other. According to this comment I think the behavior on x64 is wrong.

It looks like cg_clif depends on this behavior.

.clif Test Case

test run
target aarch64
target x86_64 machinst

function %bint_b8_i16() -> i16 {
block0:
  v0 = bconst.b8 true
  v1 = bint.i16 v0
  return v1
}
; Passes on x86, fails on aarch64
; run: %bint_b8_i16() == 0xFF

; Passes on aarch64, fails on x86
; run: %bint_b8_i16() == 1


function %bint_b16_i16() -> i16 {
block0:
  v0 = bconst.b16 true
  v1 = bint.i16 v0
  return v1
}
; Passes on x86, fails on aarch64
; run: %bint_b16_i16() == 0xFFFF

; Passes on aarch64, fails on x86
; run: %bint_b16_i16() == 1

Steps to Reproduce

Run the above test

Expected Results

The aarch64 and x64 backends should produce identical results

Actual Results

Bools are lowered as either 1 or -1 depending on the backend.

Versions and Environment

Cranelift version or commit: current main branch
Operating system: Windows 10
Architecture: x64 / aarch64


Last updated: Dec 23 2024 at 12:05 UTC