Stream: git-wasmtime

Topic: wasmtime / issue #3060 Cranelift: s390x has different ove...


view this post on Zulip Wasmtime GitHub notifications bot (Jul 04 2021 at 12:47):

afonso360 labeled issue #3060:

Hey!

While fixing br_icmp handling on the interpreter I developed the following test case, in which the s390x backend disagrees with both x86_64 and aarch64.

.clif Test Case

test run
target aarch64
target s390x
target x86_64 machinst

function %bricmp_of_i64(i64, i64) -> b1 {
block0(v0: i64, v1: i64):
    br_icmp.i64 of v0, v1, block2
    jump block1

block1:
    v2 = bconst.b1 false
    return v2

block2:
    v3 = bconst.b1 true
    return v3
}

; All three agree on these tests
; run: %bricmp_of_i64(0, 0) == false
; run: %bricmp_of_i64(0, 1) == false
; run: %bricmp_of_i64(1, 0) == false
; run: %bricmp_of_i64(0, -1) == false
; run: %bricmp_of_i64(0x80000000_00000000, 0x80000000_00000000) == false
; run: %bricmp_of_i64(0x7FFFFFFF_FFFFFFFF, 1) == false
; run: %bricmp_of_i64(0x7FFFFFFF_FFFFFFFF, 0x7FFFFFFF_FFFFFFFF) == false
; run: %bricmp_of_i64(0xFFFFFFFF_FFFFFFFF, 1) == false


; aarch64 & x86_64 report all of the following as true
; s390x reports them as false

; run: %bricmp_of_i64(0x80000000_00000000, 1) == ?
; run: %bricmp_of_i64(0x7FFFFFFF_FFFFFFFF, 0x80000000_00000000) == ?
; run: %bricmp_of_i64(0x80000000_00000000, 0x7FFFFFFF_FFFFFFFF) == ?

Steps to Reproduce

Run the above testcase with clif-util test ./of.clif

Expected Results

All backends should agree on the same set of results.

I don't really understand the behaviour of the overflow flag very well, so I don't know which ones are correct.
To me 0x7F + 1 should be an overflow, but all three backends disagree with me.

Actual Results

s390x disagrees with both x86_64 and aarch64 for some results.

Versions and Environment

Cranelift version or commit: main as of writing
Operating system: Windows 10 / Linux
Architecture: aarch64 / s390x / x86_64

Note: I only tested aarch64 and s390x in qemu. So it is possible that that plays a part in this as well.

view this post on Zulip Wasmtime GitHub notifications bot (Jul 04 2021 at 12:47):

afonso360 opened issue #3060:

Hey!

While fixing br_icmp handling on the interpreter I developed the following test case, in which the s390x backend disagrees with both x86_64 and aarch64.

.clif Test Case

test run
target aarch64
target s390x
target x86_64 machinst

function %bricmp_of_i64(i64, i64) -> b1 {
block0(v0: i64, v1: i64):
    br_icmp.i64 of v0, v1, block2
    jump block1

block1:
    v2 = bconst.b1 false
    return v2

block2:
    v3 = bconst.b1 true
    return v3
}

; All three agree on these tests
; run: %bricmp_of_i64(0, 0) == false
; run: %bricmp_of_i64(0, 1) == false
; run: %bricmp_of_i64(1, 0) == false
; run: %bricmp_of_i64(0, -1) == false
; run: %bricmp_of_i64(0x80000000_00000000, 0x80000000_00000000) == false
; run: %bricmp_of_i64(0x7FFFFFFF_FFFFFFFF, 1) == false
; run: %bricmp_of_i64(0x7FFFFFFF_FFFFFFFF, 0x7FFFFFFF_FFFFFFFF) == false
; run: %bricmp_of_i64(0xFFFFFFFF_FFFFFFFF, 1) == false


; aarch64 & x86_64 report all of the following as true
; s390x reports them as false

; run: %bricmp_of_i64(0x80000000_00000000, 1) == ?
; run: %bricmp_of_i64(0x7FFFFFFF_FFFFFFFF, 0x80000000_00000000) == ?
; run: %bricmp_of_i64(0x80000000_00000000, 0x7FFFFFFF_FFFFFFFF) == ?

Steps to Reproduce

Run the above testcase with clif-util test ./of.clif

Expected Results

All backends should agree on the same set of results.

I don't really understand the behaviour of the overflow flag very well, so I don't know which ones are correct.
To me 0x7F + 1 should be an overflow, but all three backends disagree with me.

Actual Results

s390x disagrees with both x86_64 and aarch64 for some results.

Versions and Environment

Cranelift version or commit: main as of writing
Operating system: Windows 10 / Linux
Architecture: aarch64 / s390x / x86_64

Note: I only tested aarch64 and s390x in qemu. So it is possible that that plays a part in this as well.

view this post on Zulip Wasmtime GitHub notifications bot (Jul 04 2021 at 12:47):

afonso360 labeled issue #3060:

Hey!

While fixing br_icmp handling on the interpreter I developed the following test case, in which the s390x backend disagrees with both x86_64 and aarch64.

.clif Test Case

test run
target aarch64
target s390x
target x86_64 machinst

function %bricmp_of_i64(i64, i64) -> b1 {
block0(v0: i64, v1: i64):
    br_icmp.i64 of v0, v1, block2
    jump block1

block1:
    v2 = bconst.b1 false
    return v2

block2:
    v3 = bconst.b1 true
    return v3
}

; All three agree on these tests
; run: %bricmp_of_i64(0, 0) == false
; run: %bricmp_of_i64(0, 1) == false
; run: %bricmp_of_i64(1, 0) == false
; run: %bricmp_of_i64(0, -1) == false
; run: %bricmp_of_i64(0x80000000_00000000, 0x80000000_00000000) == false
; run: %bricmp_of_i64(0x7FFFFFFF_FFFFFFFF, 1) == false
; run: %bricmp_of_i64(0x7FFFFFFF_FFFFFFFF, 0x7FFFFFFF_FFFFFFFF) == false
; run: %bricmp_of_i64(0xFFFFFFFF_FFFFFFFF, 1) == false


; aarch64 & x86_64 report all of the following as true
; s390x reports them as false

; run: %bricmp_of_i64(0x80000000_00000000, 1) == ?
; run: %bricmp_of_i64(0x7FFFFFFF_FFFFFFFF, 0x80000000_00000000) == ?
; run: %bricmp_of_i64(0x80000000_00000000, 0x7FFFFFFF_FFFFFFFF) == ?

Steps to Reproduce

Run the above testcase with clif-util test ./of.clif

Expected Results

All backends should agree on the same set of results.

I don't really understand the behaviour of the overflow flag very well, so I don't know which ones are correct.
To me 0x7F + 1 should be an overflow, but all three backends disagree with me.

Actual Results

s390x disagrees with both x86_64 and aarch64 for some results.

Versions and Environment

Cranelift version or commit: main as of writing
Operating system: Windows 10 / Linux
Architecture: aarch64 / s390x / x86_64

Note: I only tested aarch64 and s390x in qemu. So it is possible that that plays a part in this as well.

view this post on Zulip Wasmtime GitHub notifications bot (Jul 04 2021 at 12:47):

afonso360 edited issue #3060:

Hey!

While fixing br_icmp handling on the interpreter I developed the following test case, in which the s390x backend disagrees with both x86_64 and aarch64.

.clif Test Case

test run
target aarch64
target s390x
target x86_64 machinst

function %bricmp_of_i64(i64, i64) -> b1 {
block0(v0: i64, v1: i64):
    br_icmp.i64 of v0, v1, block2
    jump block1

block1:
    v2 = bconst.b1 false
    return v2

block2:
    v3 = bconst.b1 true
    return v3
}

; All three agree on these tests
; run: %bricmp_of_i64(0, 0) == false
; run: %bricmp_of_i64(0, 1) == false
; run: %bricmp_of_i64(1, 0) == false
; run: %bricmp_of_i64(0, -1) == false
; run: %bricmp_of_i64(0x80000000_00000000, 0x80000000_00000000) == false
; run: %bricmp_of_i64(0x7FFFFFFF_FFFFFFFF, 1) == false
; run: %bricmp_of_i64(0x7FFFFFFF_FFFFFFFF, 0x7FFFFFFF_FFFFFFFF) == false
; run: %bricmp_of_i64(0xFFFFFFFF_FFFFFFFF, 1) == false


; aarch64 & x86_64 report all of the following as true
; s390x reports them as false

; run: %bricmp_of_i64(0x80000000_00000000, 1) == ?
; run: %bricmp_of_i64(0x7FFFFFFF_FFFFFFFF, 0x80000000_00000000) == ?
; run: %bricmp_of_i64(0x80000000_00000000, 0x7FFFFFFF_FFFFFFFF) == ?

Steps to Reproduce

Run the above testcase with clif-util test ./of.clif

Expected Results

All backends should agree on the same set of results.

I don't really understand the behaviour of the overflow flag very well, so I don't know which ones are correct.
To me 0x7F + 1 should be an overflow, but all three backends disagree with me.

Actual Results

s390x disagrees with both x86_64 and aarch64 for some results.

Versions and Environment

Cranelift version or commit: main as of writing
Operating system: Windows 10 / Linux
Architecture: aarch64 / s390x / x86_64

Note: I only tested aarch64 and s390x in qemu. So it is possible that that plays a part in this as well.

view this post on Zulip Wasmtime GitHub notifications bot (Jul 04 2021 at 13:20):

afonso360 edited issue #3060:

Hey!

While fixing br_icmp handling on the interpreter I developed the following test case, in which the s390x backend disagrees with both x86_64 and aarch64.

.clif Test Case

test run
target aarch64
target s390x
target x86_64 machinst

function %bricmp_of_i64(i64, i64) -> b1 {
block0(v0: i64, v1: i64):
    br_icmp.i64 of v0, v1, block2
    jump block1

block1:
    v2 = bconst.b1 false
    return v2

block2:
    v3 = bconst.b1 true
    return v3
}

; All three agree on these tests
; run: %bricmp_of_i64(0, 0) == false
; run: %bricmp_of_i64(0, 1) == false
; run: %bricmp_of_i64(1, 0) == false
; run: %bricmp_of_i64(0, -1) == false
; run: %bricmp_of_i64(0x80000000_00000000, 0x80000000_00000000) == false
; run: %bricmp_of_i64(0x7FFFFFFF_FFFFFFFF, 1) == false
; run: %bricmp_of_i64(0x7FFFFFFF_FFFFFFFF, 0x7FFFFFFF_FFFFFFFF) == false
; run: %bricmp_of_i64(0xFFFFFFFF_FFFFFFFF, 1) == false


; aarch64 & x86_64 report all of the following as true
; s390x reports them as false

; run: %bricmp_of_i64(0x80000000_00000000, 1) == ?
; run: %bricmp_of_i64(0x7FFFFFFF_FFFFFFFF, 0x80000000_00000000) == ?
; run: %bricmp_of_i64(0x80000000_00000000, 0x7FFFFFFF_FFFFFFFF) == ?

Steps to Reproduce

Run the above testcase with clif-util test ./of.clif

Expected Results

All backends should agree on the same set of results.

I don't really understand the behaviour of the overflow flag very well, so I don't know which ones are correct.
To me 0x7F + 1 should be an overflow, but all three backends disagree with me.

Actual Results

s390x disagrees with both x86_64 and aarch64 for some results.

Versions and Environment

Cranelift version or commit: main as of writing
Operating system: Windows 10 / Linux
Architecture: aarch64 / s390x / x86_64

Note: I only tested s390x in qemu. So it is possible that that plays a part in this as well.

view this post on Zulip Wasmtime GitHub notifications bot (Jul 04 2021 at 14:53):

afonso360 edited issue #3060:

Hey!

While fixing br_icmp handling on the interpreter I developed the following test case, in which the s390x backend disagrees with both x86_64 and aarch64.

.clif Test Case

test run
target aarch64
target s390x
target x86_64 machinst

function %bricmp_of_i64(i64, i64) -> b1 {
block0(v0: i64, v1: i64):
    br_icmp.i64 of v0, v1, block2
    jump block1

block1:
    v2 = bconst.b1 false
    return v2

block2:
    v3 = bconst.b1 true
    return v3
}

; All three agree on these tests
; run: %bricmp_of_i64(0, 0) == false
; run: %bricmp_of_i64(0, 1) == false
; run: %bricmp_of_i64(1, 0) == false
; run: %bricmp_of_i64(0, -1) == false
; run: %bricmp_of_i64(0x80000000_00000000, 0x80000000_00000000) == false
; run: %bricmp_of_i64(0x7FFFFFFF_FFFFFFFF, 1) == false
; run: %bricmp_of_i64(0x7FFFFFFF_FFFFFFFF, 0x7FFFFFFF_FFFFFFFF) == false
; run: %bricmp_of_i64(0xFFFFFFFF_FFFFFFFF, 1) == false


; aarch64 & x86_64 report all of the following as true
; s390x reports them as false

; run: %bricmp_of_i64(0x80000000_00000000, 1) == ?
; run: %bricmp_of_i64(0x7FFFFFFF_FFFFFFFF, 0x80000000_00000000) == ?
; run: %bricmp_of_i64(0x80000000_00000000, 0x7FFFFFFF_FFFFFFFF) == ?
; run: %bricmp_of_i64(0x7FFFFFFF_FFFFFFFF, 0xFFFFFFFF_FFFFFFFF) == ?

Steps to Reproduce

Run the above testcase with clif-util test ./of.clif

Expected Results

All backends should agree on the same set of results.

I don't really understand the behaviour of the overflow flag very well, so I don't know which ones are correct.
To me 0x7F + 1 should be an overflow, but all three backends disagree with me.

Actual Results

s390x disagrees with both x86_64 and aarch64 for some results.

Versions and Environment

Cranelift version or commit: main as of writing
Operating system: Windows 10 / Linux
Architecture: aarch64 / s390x / x86_64

Note: I only tested s390x in qemu. So it is possible that that plays a part in this as well.

view this post on Zulip Wasmtime GitHub notifications bot (Jul 05 2021 at 08:29):

afonso360 edited issue #3060:

Hey!

While fixing br_icmp handling on the interpreter I developed the following test case, in which the s390x backend disagrees with both x86_64 and aarch64.

.clif Test Case

test run
target aarch64
target s390x
target x86_64 machinst

function %bricmp_of_i64(i64, i64) -> b1 {
block0(v0: i64, v1: i64):
    br_icmp.i64 of v0, v1, block2
    jump block1

block1:
    v2 = bconst.b1 false
    return v2

block2:
    v3 = bconst.b1 true
    return v3
}

; All three agree on these tests
; run: %bricmp_of_i64(0, 0) == false
; run: %bricmp_of_i64(0, 1) == false
; run: %bricmp_of_i64(1, 0) == false
; run: %bricmp_of_i64(0, -1) == false
; run: %bricmp_of_i64(0x80000000_00000000, 0x80000000_00000000) == false
; run: %bricmp_of_i64(0x7FFFFFFF_FFFFFFFF, 1) == false
; run: %bricmp_of_i64(0x7FFFFFFF_FFFFFFFF, 0x7FFFFFFF_FFFFFFFF) == false
; run: %bricmp_of_i64(0xFFFFFFFF_FFFFFFFF, 1) == false


; aarch64 & x86_64 report all of the following as true
; s390x reports them as false

; run: %bricmp_of_i64(0x80000000_00000000, 1) == ?
; run: %bricmp_of_i64(0x7FFFFFFF_FFFFFFFF, 0x80000000_00000000) == ?
; run: %bricmp_of_i64(0x80000000_00000000, 0x7FFFFFFF_FFFFFFFF) == ?
; run: %bricmp_of_i64(0x7FFFFFFF_FFFFFFFF, 0xFFFFFFFF_FFFFFFFF) == ?

Steps to Reproduce

Run the above testcase with clif-util test ./of.clif

Expected Results

All backends should agree on the same set of results.

I think both x86 and aarch64 are correct here, and we are probably just missing the overflow implementation in the s390x backend.

Actual Results

s390x disagrees with both x86_64 and aarch64 for some results.

Versions and Environment

Cranelift version or commit: main as of writing
Operating system: Windows 10 / Linux
Architecture: aarch64 / s390x / x86_64

Note: I only tested s390x in qemu. So it is possible that that plays a part in this as well.

view this post on Zulip Wasmtime GitHub notifications bot (Oct 01 2021 at 20:54):

akirilov-arm commented on issue #3060:

cc @uweigand

view this post on Zulip Wasmtime GitHub notifications bot (Oct 04 2021 at 12:02):

uweigand commented on issue #3060:

So my first question would be, what is the supposed behavior for a "icmp of", and is this really useful?

From what I can see, the behavior on Intel is the "icmp of A, B" means - "would a subtraction A - B cause a signed overflow"? We don't have an instruction to do that directly on s390x, other than actually performing a subtraction and ignoring the result (and even that only for i64 and i32 -- for i16 and i8 this would have to be emulated by a longer sequence).

If necessary, I guess we could do that, but I'm wondering when this is ever actually useful for anything. (Note that checking for overflow after an operation you've already performed does make sense - but the "icmp of" seems strange.)

view this post on Zulip Wasmtime GitHub notifications bot (Oct 05 2021 at 08:44):

afonso360 commented on issue #3060:

From what I can see, the behavior on Intel is the "icmp of A, B" means - "would a subtraction A - B cause a signed overflow"?

As far as i understand, yes that is exactly what this operation does.

is this really useful?

Not too sure, I haven't seen this operation a lot. It was added in 43a891dfa23d1ed838a7eebef601a38120d53ac5

view this post on Zulip Wasmtime GitHub notifications bot (Oct 05 2021 at 09:21):

uweigand commented on issue #3060:

From what I can see, the behavior on Intel is the "icmp of A, B" means - "would a subtraction A - B cause a signed overflow"?

As far as i understand, yes that is exactly what this operation does.

is this really useful?

Not too sure, I haven't seen this operation a lot. It was added in 43a891d

That commit introduces uses of "trapif of", which I do agree is useful. It's the "icmp of" that I'm sceptical about ...

view this post on Zulip Wasmtime GitHub notifications bot (Sep 07 2022 at 15:38):

jameysharp closed issue #3060:

Hey!

While fixing br_icmp handling on the interpreter I developed the following test case, in which the s390x backend disagrees with both x86_64 and aarch64.

.clif Test Case

test run
target aarch64
target s390x
target x86_64 machinst

function %bricmp_of_i64(i64, i64) -> b1 {
block0(v0: i64, v1: i64):
    br_icmp.i64 of v0, v1, block2
    jump block1

block1:
    v2 = bconst.b1 false
    return v2

block2:
    v3 = bconst.b1 true
    return v3
}

; All three agree on these tests
; run: %bricmp_of_i64(0, 0) == false
; run: %bricmp_of_i64(0, 1) == false
; run: %bricmp_of_i64(1, 0) == false
; run: %bricmp_of_i64(0, -1) == false
; run: %bricmp_of_i64(0x80000000_00000000, 0x80000000_00000000) == false
; run: %bricmp_of_i64(0x7FFFFFFF_FFFFFFFF, 1) == false
; run: %bricmp_of_i64(0x7FFFFFFF_FFFFFFFF, 0x7FFFFFFF_FFFFFFFF) == false
; run: %bricmp_of_i64(0xFFFFFFFF_FFFFFFFF, 1) == false


; aarch64 & x86_64 report all of the following as true
; s390x reports them as false

; run: %bricmp_of_i64(0x80000000_00000000, 1) == ?
; run: %bricmp_of_i64(0x7FFFFFFF_FFFFFFFF, 0x80000000_00000000) == ?
; run: %bricmp_of_i64(0x80000000_00000000, 0x7FFFFFFF_FFFFFFFF) == ?
; run: %bricmp_of_i64(0x7FFFFFFF_FFFFFFFF, 0xFFFFFFFF_FFFFFFFF) == ?

Steps to Reproduce

Run the above testcase with clif-util test ./of.clif

Expected Results

All backends should agree on the same set of results.

I think both x86 and aarch64 are correct here, and we are probably just missing the overflow implementation in the s390x backend.

Actual Results

s390x disagrees with both x86_64 and aarch64 for some results.

Versions and Environment

Cranelift version or commit: main as of writing
Operating system: Windows 10 / Linux
Architecture: aarch64 / s390x / x86_64

Note: I only tested s390x in qemu. So it is possible that that plays a part in this as well.


Last updated: Dec 23 2024 at 12:05 UTC