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 Casetest 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 me0x7F + 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_64Note: I only tested aarch64 and s390x in qemu. So it is possible that that plays a part in this as well.
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 Casetest 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 me0x7F + 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_64Note: I only tested aarch64 and s390x in qemu. So it is possible that that plays a part in this as well.
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 Casetest 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 me0x7F + 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_64Note: I only tested aarch64 and s390x in qemu. So it is possible that that plays a part in this as well.
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 Casetest 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 me0x7F + 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_64Note: I only tested aarch64 and s390x in qemu. So it is possible that that plays a part in this as well.
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 Casetest 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 me0x7F + 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_64Note: I only tested s390x in qemu. So it is possible that that plays a part in this as well.
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 Casetest 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 me0x7F + 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_64Note: I only tested s390x in qemu. So it is possible that that plays a part in this as well.
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 Casetest 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_64Note: I only tested s390x in qemu. So it is possible that that plays a part in this as well.
akirilov-arm commented on issue #3060:
cc @uweigand
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.)
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
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 ...
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 Casetest 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_64Note: 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