From 62f55d37a8d000caf3fe0c1ae59317ab30ade6d0 Mon Sep 17 00:00:00 2001 From: Jimmy Brisson Date: Thu, 9 Apr 2026 13:51:28 -0500 Subject: [PATCH 1/2] s390x-z17: Fix ordering bug & runtest veval lowerings The vec eval bug was created by generating all of the masks with a script, and then updating the masks in place without reordering the arguments to these 2 cases. Reported-by: Shun Kashiwa @shumbo --- cranelift/codegen/src/isa/s390x/lower.isle | 4 +- .../isa/s390x/vec-bitwise-arch15.clif | 8 +- .../filetests/runtests/s390x-veval.clif | 495 ++++++++++++++++++ 3 files changed, 501 insertions(+), 6 deletions(-) create mode 100644 cranelift/filetests/filetests/runtests/s390x-veval.clif diff --git a/cranelift/codegen/src/isa/s390x/lower.isle b/cranelift/codegen/src/isa/s390x/lower.isle index 7ad613c3f2a9..08e263abf521 100644 --- a/cranelift/codegen/src/isa/s390x/lower.isle +++ b/cranelift/codegen/src/isa/s390x/lower.isle @@ -1167,9 +1167,9 @@ (rule 17 (lower (has_type (and (vxrs_ext3_enabled) (vr128_ty ty)) (band _ x (band _ y (bnot _ z))))) (vec_eval ty 0b00000010 x y z)) (rule 18 (lower (has_type (and (vxrs_ext3_enabled) (vr128_ty ty)) (band _ (band _ x (bnot _ y)) z))) - (vec_eval ty 0b00000100 y x z)) + (vec_eval ty 0b00000100 x y z)) (rule 19 (lower (has_type (and (vxrs_ext3_enabled) (vr128_ty ty)) (band _ x (band _ (bnot _ y) z)))) - (vec_eval ty 0b00000100 z x y)) + (vec_eval ty 0b00000100 x y z)) ;; Not-and three vector registers (rule 20 (lower (has_type (and (vxrs_ext3_enabled) (vr128_ty ty)) (bnot _ (band _ (band _ x y) z)))) diff --git a/cranelift/filetests/filetests/isa/s390x/vec-bitwise-arch15.clif b/cranelift/filetests/filetests/isa/s390x/vec-bitwise-arch15.clif index 1c91bb392755..77854465e12f 100644 --- a/cranelift/filetests/filetests/isa/s390x/vec-bitwise-arch15.clif +++ b/cranelift/filetests/filetests/isa/s390x/vec-bitwise-arch15.clif @@ -67,14 +67,14 @@ block0(v0: i64x2, v1: i64x2, v2: i64x2): ; VCode: ; block0: -; veval %v24, %v25, %v24, %v26, 4 +; veval %v24, %v24, %v25, %v26, 4 ; br %r14 ; ; Disassembled: ; block0: ; offset 0x0 -; .byte 0xe7, 0x89 -; .byte 0x80, 0x04 -; mc 0x7fe, 0x88 +; .byte 0xe7, 0x88 +; stm %r0, %r4, 0xf88(%r10) +; br %r14 function %band_band_notc_i64x2(i64x2, i64x2, i64x2) -> i64x2 { block0(v0: i64x2, v1: i64x2, v2: i64x2): diff --git a/cranelift/filetests/filetests/runtests/s390x-veval.clif b/cranelift/filetests/filetests/runtests/s390x-veval.clif new file mode 100644 index 000000000000..5a51586bbb55 --- /dev/null +++ b/cranelift/filetests/filetests/runtests/s390x-veval.clif @@ -0,0 +1,495 @@ +test interpret +test run +target pulley64 +target s390x arch15 + +function %band_band_i64x2(i64x2, i64x2, i64x2) -> i64x2 { +block0(v0: i64x2, v1: i64x2, v2: i64x2): + v3 = band.i64x2 v0, v1 + v4 = band.i64x2 v3, v2 + return v4 +} + +; run: %band_band_i64x2([0x55 0], [0x33 0], [0x0f 0]) == 0x01 + +function %band_band_rev_i64x2(i64x2, i64x2, i64x2) -> i64x2 { +block0(v0: i64x2, v1: i64x2, v2: i64x2): + v3 = band.i64x2 v0, v1 + v4 = band.i64x2 v2, v3 + return v4 +} + +; run: %band_band_rev_i64x2([0x55 0], [0x33 0], [0x0f 0]) == 0x01 + +function %band_band_nota_i64x2(i64x2, i64x2, i64x2) -> i64x2 { +block0(v0: i64x2, v1: i64x2, v2: i64x2): + v3 = bnot v0 + v4 = band.i64x2 v3, v1 + v5 = band.i64x2 v4, v2 + return v5 +} + +; run: %band_band_nota_i64x2([0x55 0], [0x33 0], [0x0f 0]) == 0x02 + +function %band_band_notb_i64x2(i64x2, i64x2, i64x2) -> i64x2 { +block0(v0: i64x2, v1: i64x2, v2: i64x2): + v3 = bnot v1 + v4 = band.i64x2 v0, v3 + v5 = band.i64x2 v4, v2 + return v5 +} + +; run: %band_band_notb_i64x2([0x55 0], [0x33 0], [0x0f 0]) == 0x04 + +function %band_band_notc_i64x2(i64x2, i64x2, i64x2) -> i64x2 { +block0(v0: i64x2, v1: i64x2, v2: i64x2): + v3 = bnot v2 + v4 = band.i64x2 v0, v1 + v5 = band.i64x2 v4, v3 + return v5 +} + +; run: %band_band_notc_i64x2([0x55 0], [0x33 0], [0x0f 0]) == 0x10 + +function %band_bnandab_i64x2(i64x2, i64x2, i64x2) -> i64x2 { +block0(v0: i64x2, v1: i64x2, v2: i64x2): + v3 = band.i64x2 v0, v1 + v4 = bnot v3 + v5 = band.i64x2 v4, v2 + return v5 +} + +; run: %band_bnandab_i64x2([0x55 0], [0x33 0], [0x0f 0]) == 0x0e + +function %band_bnandbc_i64x2(i64x2, i64x2, i64x2) -> i64x2 { +block0(v0: i64x2, v1: i64x2, v2: i64x2): + v3 = band.i64x2 v1, v2 + v4 = bnot v3 + v5 = band.i64x2 v0, v4 + return v5 +} + +; run: %band_bnandbc_i64x2([0x55 0], [0x33 0], [0x0f 0]) == 0x54 + +function %band_borab_i64x2(i64x2, i64x2, i64x2) -> i64x2 { +block0(v0: i64x2, v1: i64x2, v2: i64x2): + v3 = bor.i64x2 v0, v1 + v4 = band.i64x2 v3, v2 + return v4 +} + +; run: %band_borab_i64x2([0x55 0], [0x33 0], [0x0f 0]) == 0x07 + +function %band_borbc_i64x2(i64x2, i64x2, i64x2) -> i64x2 { +block0(v0: i64x2, v1: i64x2, v2: i64x2): + v3 = bor.i64x2 v1, v2 + v4 = band.i64x2 v0, v3 + return v4 +} + +; run: %band_borbc_i64x2([0x55 0], [0x33 0], [0x0f 0]) == 0x15 + +function %band_bnorab_i64x2(i64x2, i64x2, i64x2) -> i64x2 { +block0(v0: i64x2, v1: i64x2, v2: i64x2): + v3 = bor.i64x2 v0, v1 + v4 = bnot.i64x2 v3 + v5 = band.i64x2 v4, v2 + return v5 +} + +; run: %band_bnorab_i64x2([0x55 0], [0x33 0], [0x0f 0]) == 0x08 + +function %band_bnorbc_i64x2(i64x2, i64x2, i64x2) -> i64x2 { +block0(v0: i64x2, v1: i64x2, v2: i64x2): + v3 = bor.i64x2 v1, v2 + v4 = bnot.i64x2 v3 + v5 = band.i64x2 v0, v4 + return v5 +} + +; run: %band_bnorbc_i64x2([0x55 0], [0x33 0], [0x0f 0]) == 0x40 + +function %band_bxorab_i64x2(i64x2, i64x2, i64x2) -> i64x2 { +block0(v0: i64x2, v1: i64x2, v2: i64x2): + v3 = bxor.i64x2 v0, v1 + v4 = band.i64x2 v3, v2 + return v4 +} + +; run: %band_bxorab_i64x2([0x55 0], [0x33 0], [0x0f 0]) == 0x06 + +function %band_bxorbc_i64x2(i64x2, i64x2, i64x2) -> i64x2 { +block0(v0: i64x2, v1: i64x2, v2: i64x2): + v3 = bxor.i64x2 v1, v2 + v4 = band.i64x2 v0, v3 + return v4 +} + +; run: %band_bxorbc_i64x2([0x55 0], [0x33 0], [0x0f 0]) == 0x14 + +function %band_bnxorab_i64x2(i64x2, i64x2, i64x2) -> i64x2 { +block0(v0: i64x2, v1: i64x2, v2: i64x2): + v3 = bxor.i64x2 v0, v1 + v4 = bnot.i64x2 v3 + v5 = band.i64x2 v4, v2 + return v5 +} + +; run: %band_bnxorab_i64x2([0x55 0], [0x33 0], [0x0f 0]) == 0x09 + +function %band_bnxorbc_i64x2(i64x2, i64x2, i64x2) -> i64x2 { +block0(v0: i64x2, v1: i64x2, v2: i64x2): + v3 = bxor.i64x2 v1, v2 + v4 = bnot.i64x2 v3 + v5 = band.i64x2 v0, v4 + return v5 +} + +; run: %band_bnxorbc_i64x2([0x55 0], [0x33 0], [0x0f 0]) == 0x41 + +function %bor_bor_i64x2(i64x2, i64x2, i64x2) -> i64x2 { +block0(v0: i64x2, v1: i64x2, v2: i64x2): + v3 = bor v0, v1 + v4 = bor v3, v2 + return v4 +} + +; run: %bor_bor_i64x2([0x55 0], [0x33 0], [0x0f 0]) == 0x7f + +function %bor_bor_rev_i64x2(i64x2, i64x2, i64x2) -> i64x2 { +block0(v0: i64x2, v1: i64x2, v2: i64x2): + v3 = bor v0, v1 + v4 = bor v2, v3 + return v4 +} + +; run: %bor_bor_rev_i64x2([0x55 0], [0x33 0], [0x0f 0]) == 0x7f + +function %bor_bor_nota_i64x2(i64x2, i64x2, i64x2) -> i64x2 { +block0(v0: i64x2, v1: i64x2, v2: i64x2): + v3 = bnot v0 + v4 = bor v3, v1 + v5 = bor v4, v2 + return v5 +} + +; run: %bor_bor_nota_i64x2([0x55 0], [0x33 0], [0x0f 0]) == 0xffffffffffffffffffffffffffffffbf + +function %bor_bor_notb_i64x2(i64x2, i64x2, i64x2) -> i64x2 { +block0(v0: i64x2, v1: i64x2, v2: i64x2): + v3 = bnot v1 + v4 = bor v0, v3 + v5 = bor v4, v2 + return v5 +} + +; run: %bor_bor_notb_i64x2([0x55 0], [0x33 0], [0x0f 0]) == 0xffffffffffffffffffffffffffffffdf + +function %bor_bor_notc_i64x2(i64x2, i64x2, i64x2) -> i64x2 { +block0(v0: i64x2, v1: i64x2, v2: i64x2): + v3 = bnot v2 + v4 = bor.i64x2 v0, v1 + v5 = bor.i64x2 v4, v3 + return v5 +} + +; run: %bor_bor_notc_i64x2([0x55 0], [0x33 0], [0x0f 0]) == 0xfffffffffffffffffffffffffffffff7 + +function %bor_bnandab_i64x2(i64x2, i64x2, i64x2) -> i64x2 { +block0(v0: i64x2, v1: i64x2, v2: i64x2): + v3 = band v0, v1 + v4 = bnot v3 + v5 = bor v4, v2 + return v5 +} + +; run: %bor_bnandab_i64x2([0x55 0], [0x33 0], [0x0f 0]) == 0xffffffffffffffffffffffffffffffef + +function %bor_bnandbc_i64x2(i64x2, i64x2, i64x2) -> i64x2 { +block0(v0: i64x2, v1: i64x2, v2: i64x2): + v3 = band v1, v2 + v4 = bnot v3 + v5 = bor v0, v4 + return v5 +} + +; run: %bor_bnandbc_i64x2([0x55 0], [0x33 0], [0x0f 0]) == 0xfffffffffffffffffffffffffffffffd + +function %bor_borab_i64x2(i64x2, i64x2, i64x2) -> i64x2 { +block0(v0: i64x2, v1: i64x2, v2: i64x2): + v3 = bor v0, v1 + v4 = bor v3, v2 + return v4 +} + +; run: %bor_borab_i64x2([0x55 0], [0x33 0], [0x0f 0]) == 0x7f + +function %bor_borbc_i64x2(i64x2, i64x2, i64x2) -> i64x2 { +block0(v0: i64x2, v1: i64x2, v2: i64x2): + v3 = bor v1, v2 + v4 = bor v0, v3 + return v4 +} + +; run: %bor_borbc_i64x2([0x55 0], [0x33 0], [0x0f 0]) == 0x7f + +function %bor_bnorab_i64x2(i64x2, i64x2, i64x2) -> i64x2 { +block0(v0: i64x2, v1: i64x2, v2: i64x2): + v3 = bor v0, v1 + v4 = bnot v3 + v5 = bor v4, v2 + return v5 +} + +; run: %bor_bnorab_i64x2([0x55 0], [0x33 0], [0x0f 0]) == 0xffffffffffffffffffffffffffffff8f + +function %bor_bnorbc_i64x2(i64x2, i64x2, i64x2) -> i64x2 { +block0(v0: i64x2, v1: i64x2, v2: i64x2): + v3 = bor v1, v2 + v4 = bnot v3 + v5 = bor v0, v4 + return v5 +} + +; run: %bor_bnorbc_i64x2([0x55 0], [0x33 0], [0x0f 0]) == 0xffffffffffffffffffffffffffffffd5 + +function %bor_bxorab_i64x2(i64x2, i64x2, i64x2) -> i64x2 { +block0(v0: i64x2, v1: i64x2, v2: i64x2): + v3 = bxor v0, v1 + v4 = bor v3, v2 + return v4 +} + +; run: %bor_bxorab_i64x2([0x55 0], [0x33 0], [0x0f 0]) == 0x6f + +function %bor_bxorbc_i64x2(i64x2, i64x2, i64x2) -> i64x2 { +block0(v0: i64x2, v1: i64x2, v2: i64x2): + v3 = bxor v1, v2 + v4 = bor v0, v3 + return v4 +} + +; run: %bor_bxorbc_i64x2([0x55 0], [0x33 0], [0x0f 0]) == 0x7d + +function %bor_bnxorab_i64x2(i64x2, i64x2, i64x2) -> i64x2 { +block0(v0: i64x2, v1: i64x2, v2: i64x2): + v3 = bxor v0, v1 + v4 = bnot v3 + v5 = bor v4, v2 + return v5 +} + +; run: %bor_bnxorab_i64x2([0x55 0], [0x33 0], [0x0f 0]) == 0xffffffffffffffffffffffffffffff9f + +function %bor_bnxorbc_i64x2(i64x2, i64x2, i64x2) -> i64x2 { +block0(v0: i64x2, v1: i64x2, v2: i64x2): + v3 = bxor v1, v2 + v4 = bnot v3 + v5 = bor v0, v4 + return v5 +} + +; run: %bor_bnxorbc_i64x2([0x55 0], [0x33 0], [0x0f 0]) == 0xffffffffffffffffffffffffffffffd7 + +function %bxor_bxor_i64x2(i64x2, i64x2, i64x2) -> i64x2 { +block0(v0: i64x2, v1: i64x2, v2: i64x2): + v3 = bxor v0, v1 + v4 = bxor v3, v2 + return v4 +} + +; run: %bxor_bxor_i64x2([0x55 0], [0x33 0], [0x0f 0]) == 0x69 + +function %bxor_bxor_rev_i64x2(i64x2, i64x2, i64x2) -> i64x2 { +block0(v0: i64x2, v1: i64x2, v2: i64x2): + v3 = bxor v0, v1 + v4 = bxor v2, v3 + return v4 +} + +; run: %bxor_bxor_rev_i64x2([0x55 0], [0x33 0], [0x0f 0]) == 0x69 + +function %bxor_bnandab_i64x2(i64x2, i64x2, i64x2) -> i64x2 { +block0(v0: i64x2, v1: i64x2, v2: i64x2): + v3 = band v0, v1 + v4 = bnot v3 + v5 = bxor v4, v2 + return v5 +} + +; run: %bxor_bnandab_i64x2([0x55 0], [0x33 0], [0x0f 0]) == 0xffffffffffffffffffffffffffffffe1 + +function %bxor_bnandbc_i64x2(i64x2, i64x2, i64x2) -> i64x2 { +block0(v0: i64x2, v1: i64x2, v2: i64x2): + v3 = band v1, v2 + v4 = bnot v3 + v5 = bxor v0, v4 + return v5 +} + +; run: %bxor_bnandbc_i64x2([0x55 0], [0x33 0], [0x0f 0]) == 0xffffffffffffffffffffffffffffffa9 + +function %bxor_borab_i64x2(i64x2, i64x2, i64x2) -> i64x2 { +block0(v0: i64x2, v1: i64x2, v2: i64x2): + v3 = bor v0, v1 + v4 = bxor v3, v2 + return v4 +} + +; run: %bxor_borab_i64x2([0x55 0], [0x33 0], [0x0f 0]) == 0x78 + +function %bxor_borbc_i64x2(i64x2, i64x2, i64x2) -> i64x2 { +block0(v0: i64x2, v1: i64x2, v2: i64x2): + v3 = bor v1, v2 + v4 = bxor v0, v3 + return v4 +} + +; run: %bxor_borbc_i64x2([0x55 0], [0x33 0], [0x0f 0]) == 0x6a + +function %bxor_bnorab_i64x2(i64x2, i64x2, i64x2) -> i64x2 { +block0(v0: i64x2, v1: i64x2, v2: i64x2): + v3 = bor v0, v1 + v4 = bnot v3 + v5 = bxor v4, v2 + return v5 +} + +; run: %bxor_bnorab_i64x2([0x55 0], [0x33 0], [0x0f 0]) == 0xffffffffffffffffffffffffffffff87 + +function %bxor_bnorbc_i64x2(i64x2, i64x2, i64x2) -> i64x2 { +block0(v0: i64x2, v1: i64x2, v2: i64x2): + v3 = bor v1, v2 + v4 = bnot v3 + v5 = bxor v0, v4 + return v5 +} + +; run: %bxor_bnorbc_i64x2([0x55 0], [0x33 0], [0x0f 0]) == 0xffffffffffffffffffffffffffffff95 + +function %bxor_bnxorab_i64x2(i64x2, i64x2, i64x2) -> i64x2 { +block0(v0: i64x2, v1: i64x2, v2: i64x2): + v3 = bxor v0, v1 + v4 = bnot v3 + v5 = bxor v4, v2 + return v5 +} + +; run: %bxor_bnxorab_i64x2([0x55 0], [0x33 0], [0x0f 0]) == 0xffffffffffffffffffffffffffffff96 + +function %bxor_bnxorbc_i64x2(i64x2, i64x2, i64x2) -> i64x2 { +block0(v0: i64x2, v1: i64x2, v2: i64x2): + v3 = bxor v1, v2 + v4 = bnot v3 + v5 = bxor v0, v4 + return v5 +} + +; run: %bxor_bnxorbc_i64x2([0x55 0], [0x33 0], [0x0f 0]) == 0xffffffffffffffffffffffffffffff96 + +function %bnxor_bxor_i64x2(i64x2, i64x2, i64x2) -> i64x2 { +block0(v0: i64x2, v1: i64x2, v2: i64x2): + v3 = bxor v0, v1 + v4 = bxor v3, v2 + v5 = bnot v4 + return v5 +} + +; run: %bnxor_bxor_i64x2([0x55 0], [0x33 0], [0x0f 0]) == 0xffffffffffffffffffffffffffffff96 + +function %bnxor_bxor_rev_i64x2(i64x2, i64x2, i64x2) -> i64x2 { +block0(v0: i64x2, v1: i64x2, v2: i64x2): + v3 = bxor v0, v1 + v4 = bxor v2, v3 + v5 = bnot v4 + return v5 +} + +; run: %bnxor_bxor_rev_i64x2([0x55 0], [0x33 0], [0x0f 0]) == 0xffffffffffffffffffffffffffffff96 + +function %bnxor_bnandab_i64x2(i64x2, i64x2, i64x2) -> i64x2 { +block0(v0: i64x2, v1: i64x2, v2: i64x2): + v3 = band v0, v1 + v4 = bnot v3 + v5 = bxor v4, v2 + v6 = bnot v5 + return v6 +} + +; run: %bnxor_bnandab_i64x2([0x55 0], [0x33 0], [0x0f 0]) == 0x1e + +function %bnxor_bnandbc_i64x2(i64x2, i64x2, i64x2) -> i64x2 { +block0(v0: i64x2, v1: i64x2, v2: i64x2): + v3 = band v1, v2 + v4 = bnot v3 + v5 = bxor v0, v4 + v6 = bnot v5 + return v6 +} + +; run: %bnxor_bnandbc_i64x2([0x55 0], [0x33 0], [0x0f 0]) == 0x56 + +function %bnxor_borab_i64x2(i64x2, i64x2, i64x2) -> i64x2 { +block0(v0: i64x2, v1: i64x2, v2: i64x2): + v3 = bor v0, v1 + v4 = bxor v3, v2 + v5 = bnot v4 + return v5 +} + +; run: %bnxor_borab_i64x2([0x55 0], [0x33 0], [0x0f 0]) == 0xffffffffffffffffffffffffffffff87 + +function %bnxor_borbc_i64x2(i64x2, i64x2, i64x2) -> i64x2 { +block0(v0: i64x2, v1: i64x2, v2: i64x2): + v3 = bor v1, v2 + v4 = bxor v0, v3 + v5 = bnot v4 + return v5 +} + +; run: %bnxor_borbc_i64x2([0x55 0], [0x33 0], [0x0f 0]) == 0xffffffffffffffffffffffffffffff95 + +function %bnxor_bnorab_i64x2(i64x2, i64x2, i64x2) -> i64x2 { +block0(v0: i64x2, v1: i64x2, v2: i64x2): + v3 = bor v0, v1 + v4 = bnot v3 + v5 = bxor v4, v2 + v6 = bnot v5 + return v6 +} + +; run: %bnxor_bnorab_i64x2([0x55 0], [0x33 0], [0x0f 0]) == 0x78 + +function %bnxor_bnorbc_i64x2(i64x2, i64x2, i64x2) -> i64x2 { +block0(v0: i64x2, v1: i64x2, v2: i64x2): + v3 = bor v1, v2 + v4 = bnot v3 + v5 = bxor v0, v4 + v6 = bnot v5 + return v6 +} + +; run: %bnxor_bnorbc_i64x2([0x55 0], [0x33 0], [0x0f 0]) == 0x6a + +function %bnxor_bnxorab_i64x2(i64x2, i64x2, i64x2) -> i64x2 { +block0(v0: i64x2, v1: i64x2, v2: i64x2): + v3 = bxor v0, v1 + v4 = bnot v3 + v5 = bxor v4, v2 + v6 = bnot v5 + return v6 +} + +; run: %bnxor_bnxorab_i64x2([0x55 0], [0x33 0], [0x0f 0]) == 0x69 + +function %bnxor_bnxorbc_i64x2(i64x2, i64x2, i64x2) -> i64x2 { +block0(v0: i64x2, v1: i64x2, v2: i64x2): + v3 = bxor v1, v2 + v4 = bnot v3 + v5 = bxor v0, v4 + v6 = bnot v5 + return v6 +} + +; run: %bnxor_bnxorbc_i64x2([0x55 0], [0x33 0], [0x0f 0]) == 0x69 + From 222853abd22d63750fed431c334042af10aaa420 Mon Sep 17 00:00:00 2001 From: Jimmy Brisson Date: Thu, 9 Apr 2026 14:46:43 -0500 Subject: [PATCH 2/2] s390x-z17: fix sdiv_overflow trap bug This bug was inruduced by mistakenly swapping the divisor and dividend in the overflow check included in sdiv.i128. Reported-by: Shun Kashiwa @shumbo --- cranelift/codegen/src/isa/s390x/lower.isle | 16 ++++++++-------- .../filetests/isa/s390x/arithmetic-arch15.clif | 10 +++++----- .../filetests/filetests/runtests/sdiv-i128.clif | 12 ++++++++++++ 3 files changed, 25 insertions(+), 13 deletions(-) create mode 100644 cranelift/filetests/filetests/runtests/sdiv-i128.clif diff --git a/cranelift/codegen/src/isa/s390x/lower.isle b/cranelift/codegen/src/isa/s390x/lower.isle index 08e263abf521..05036ba9808b 100644 --- a/cranelift/codegen/src/isa/s390x/lower.isle +++ b/cranelift/codegen/src/isa/s390x/lower.isle @@ -721,14 +721,14 @@ (trap_code_integer_overflow)))) (rule 1 (maybe_trap_if_sdiv_overflow true $I128 $I128 x y) (let ( - ;; We need to trap when y == INT_MIN && x == -1 - ;; y == INT_MIN is implemented as y == -y, as -INT_MIN == INT_MIN. - ;; This checks that y == -y, by using Not-Xor for bitwise - ;; equality, producing all 0b1's (-1u128) when y == -y. - ;; Then it uses band to include the x == -1 check as well. - ;; using (band x (bnot (bxor y neg_division))) variant of vec eval - (neg_divisor Reg (vec_neg $I128 y)) - (reg Reg (vec_eval $I128 0b00001001 x y neg_divisor)) + ;; We need to trap when x == INT_MIN && y == -1 + ;; y == INT_MIN is implemented as x == -x, as -INT_MIN == INT_MIN. + ;; This checks that x == -x, by using Not-Xor for bitwise + ;; equality, producing all 0b1's (-1u128) when x == -x. + ;; Then it uses band to include the y == -1 check as well. + ;; using (band y (bnot (bxor x neg_division))) variant of vec eval + (neg_dividend Reg (vec_neg $I128 x)) + (reg Reg (vec_eval $I128 0b00001001 y x neg_dividend)) ;; finally, we check that the combination of x & y == -y is -1 (flags ProducesFlags (vec_elt_icmps reg (vec_imm $I128 -1)))) (trap_if flags diff --git a/cranelift/filetests/filetests/isa/s390x/arithmetic-arch15.clif b/cranelift/filetests/filetests/isa/s390x/arithmetic-arch15.clif index 499e9c20a79f..59478e0494d3 100644 --- a/cranelift/filetests/filetests/isa/s390x/arithmetic-arch15.clif +++ b/cranelift/filetests/filetests/isa/s390x/arithmetic-arch15.clif @@ -86,8 +86,8 @@ block0(v0: i128, v1: i128): ; block0: ; vl %v1, 0(%r3) ; vl %v3, 0(%r4) -; vlcq %v6, %v3 -; veval %v16, %v1, %v3, %v6, 9 +; vlcq %v6, %v1 +; veval %v16, %v3, %v1, %v6, 9 ; vrepib %v17, 255 ; vecq %v16, %v17 ; jge .+2 # trap=int_ovf @@ -99,9 +99,9 @@ block0(v0: i128, v1: i128): ; block0: ; offset 0x0 ; vl %v1, 0(%r3) ; vl %v3, 0(%r4) -; vlc %v6, %v3, 4 -; .byte 0xe7, 0x01 -; lper %f0, %f9 +; vlc %v6, %v1, 4 +; .byte 0xe7, 0x03 +; lpr %r0, %r9 ; ld %f8, 0x710(%r8, %r14) ; .byte 0x00, 0xff ; .byte 0x08, 0x45 diff --git a/cranelift/filetests/filetests/runtests/sdiv-i128.clif b/cranelift/filetests/filetests/runtests/sdiv-i128.clif new file mode 100644 index 000000000000..e6ff11941f0b --- /dev/null +++ b/cranelift/filetests/filetests/runtests/sdiv-i128.clif @@ -0,0 +1,12 @@ +test run +set enable_multi_ret_implicit_sret +target s390x arch15 + +function %sdiv_i128(i128, i128) -> i128 { +block0(v0: i128, v1: i128): + v2 = sdiv.i128 v0, v1 + return v2 +} +; run: %sdiv_i128(100, 10) == 10 +; run: %sdiv_i128(-100, 10) == 0xFFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFF6 +; run: %sdiv_i128(0xFFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFF, 0x80000000_00000000_00000000_00000000) == 0