cranelift: Fix urem/srem in interpreter (#4532)
This commit is contained in:
@@ -1,18 +1,18 @@
|
||||
test run
|
||||
set avoid_div_traps=false
|
||||
target aarch64
|
||||
target s390x
|
||||
set avoid_div_traps=false
|
||||
target x86_64
|
||||
|
||||
; Tests that the `avoid_div_traps` flag prevents a trap when {s,u}rem is called
|
||||
; with INT_MIN % -1.
|
||||
|
||||
function %i8(i8, i8) -> i8 {
|
||||
block0(v0: i8, v1: i8):
|
||||
v2 = srem.i8 v0, v1
|
||||
return v2
|
||||
}
|
||||
; run: %i8(0, 1) == 0
|
||||
; run: %i8(1, -1) == 0
|
||||
; run: %i8(0x80, 0xff) == 0
|
||||
; run: %i8(0x2, 0x7) == 0x2
|
||||
|
||||
function %i8_const(i8) -> i8 {
|
||||
block0(v0: i8):
|
||||
@@ -20,19 +20,13 @@ block0(v0: i8):
|
||||
v2 = srem.i8 v0, v1
|
||||
return v2
|
||||
}
|
||||
; run: %i8_const(0) == 0
|
||||
; run: %i8_const(1) == 0
|
||||
; run: %i8_const(0x80) == 0
|
||||
; run: %i8_const(0x2) == 0
|
||||
|
||||
function %i16(i16, i16) -> i16 {
|
||||
block0(v0: i16, v1: i16):
|
||||
v2 = srem.i16 v0, v1
|
||||
return v2
|
||||
}
|
||||
; run: %i16(0, 42) == 0
|
||||
; run: %i16(4, -2) == 0
|
||||
; run: %i16(13, 5) == 3
|
||||
; run: %i16(0x8000, 0xffff) == 0
|
||||
|
||||
function %i16_const(i16) -> i16 {
|
||||
@@ -41,9 +35,6 @@ block0(v0: i16):
|
||||
v2 = srem.i16 v0, v1
|
||||
return v2
|
||||
}
|
||||
; run: %i16_const(0) == 0
|
||||
; run: %i16_const(4) == 0
|
||||
; run: %i16_const(13) == 0
|
||||
; run: %i16_const(0x8000) == 0
|
||||
|
||||
function %i32(i32, i32) -> i32 {
|
||||
@@ -51,9 +42,6 @@ block0(v0: i32, v1: i32):
|
||||
v2 = srem.i32 v0, v1
|
||||
return v2
|
||||
}
|
||||
; run: %i32(0, 13) == 0
|
||||
; run: %i32(1048576, 8192) == 0
|
||||
; run: %i32(-1024, 255) == -4
|
||||
; run: %i32(0x80000000, 0xffffffff) == 0
|
||||
|
||||
function %i32_const(i32) -> i32 {
|
||||
@@ -62,9 +50,6 @@ block0(v0: i32):
|
||||
v2 = srem.i32 v0, v1
|
||||
return v2
|
||||
}
|
||||
; run: %i32_const(0) == 0
|
||||
; run: %i32_const(1057) == 0
|
||||
; run: %i32_const(-42) == 0
|
||||
; run: %i32_const(0x80000000) == 0
|
||||
|
||||
function %i64(i64, i64) -> i64 {
|
||||
@@ -72,9 +57,6 @@ block0(v0: i64, v1: i64):
|
||||
v2 = srem.i64 v0, v1
|
||||
return v2
|
||||
}
|
||||
; run: %i64(0, 104857600000) == 0
|
||||
; run: %i64(104857600000, 511) == 398
|
||||
; run: %i64(-57, -5) == -2
|
||||
; run: %i64(0x800000000000000, 0xffffffffffffffff) == 0
|
||||
|
||||
function %i64_const(i64) -> i64 {
|
||||
@@ -83,9 +65,6 @@ block0(v0: i64):
|
||||
v2 = srem.i64 v0, v1
|
||||
return v2
|
||||
}
|
||||
; run: %i64_const(0) == 0
|
||||
; run: %i64_const(104857600000) == 0
|
||||
; run: %i64_const(-57) == 0
|
||||
; run: %i64_const(0x800000000000000) == 0
|
||||
|
||||
function %i8_u(i8, i8) -> i8 {
|
||||
@@ -93,10 +72,6 @@ block0(v0: i8,v1: i8):
|
||||
v2 = urem v0, v1
|
||||
return v2
|
||||
}
|
||||
; run: %i8_u(0, 1) == 0
|
||||
; run: %i8_u(2, 2) == 0
|
||||
; run: %i8_u(1, -1) == 1
|
||||
; run: %i8_u(3, 2) == 1
|
||||
; run: %i8_u(0x80, 0xff) == 0x80
|
||||
|
||||
function %i8_u_const(i8) -> i8 {
|
||||
@@ -105,8 +80,6 @@ block0(v0: i8):
|
||||
v2 = urem v0, v1
|
||||
return v2
|
||||
}
|
||||
; run: %i8_u_const(0) == 0
|
||||
; run: %i8_u_const(3) == 3
|
||||
; run: %i8_u_const(0x80) == 0x80
|
||||
|
||||
function %i16_u(i16, i16) -> i16 {
|
||||
@@ -114,9 +87,6 @@ block0(v0: i16, v1: i16):
|
||||
v2 = urem.i16 v0, v1
|
||||
return v2
|
||||
}
|
||||
; run: %i16_u(0, 42) == 0
|
||||
; run: %i16_u(4, -2) == 4
|
||||
; run: %i16_u(13, 5) == 3
|
||||
; run: %i16_u(0x8000, 0xffff) == 0x8000
|
||||
|
||||
function %i16_u_const(i16) -> i16 {
|
||||
@@ -125,8 +95,6 @@ block0(v0: i16):
|
||||
v2 = urem.i16 v0, v1
|
||||
return v2
|
||||
}
|
||||
; run: %i16_u_const(0) == 0
|
||||
; run: %i16_u_const(4) == 4
|
||||
; run: %i16_u_const(0x8000) == 0x8000
|
||||
|
||||
function %i32_u(i32, i32) -> i32 {
|
||||
@@ -134,9 +102,6 @@ block0(v0: i32, v1: i32):
|
||||
v2 = urem.i32 v0, v1
|
||||
return v2
|
||||
}
|
||||
; run: %i32_u(0, 13) == 0
|
||||
; run: %i32_u(1048576, 8192) == 0
|
||||
; run: %i32_u(-1024, 255) == 252
|
||||
; run: %i32_u(0x80000000, 0xffffffff) == 0x80000000
|
||||
|
||||
function %i32_u_const(i32) -> i32 {
|
||||
@@ -145,9 +110,6 @@ block0(v0: i32):
|
||||
v2 = urem.i32 v0, v1
|
||||
return v2
|
||||
}
|
||||
; run: %i32_u_const(0) == 0
|
||||
; run: %i32_u_const(1057) == 1057
|
||||
; run: %i32_u_const(-42) == -42
|
||||
; run: %i32_u_const(0x80000000) == 0x80000000
|
||||
|
||||
function %i64_u(i64, i64) -> i64 {
|
||||
@@ -155,9 +117,6 @@ block0(v0: i64, v1: i64):
|
||||
v2 = urem.i64 v0, v1
|
||||
return v2
|
||||
}
|
||||
; run: %i64_u(0, 104857600000) == 0
|
||||
; run: %i64_u(104857600000, 511) == 398
|
||||
; run: %i64_u(-57, -5) == -57
|
||||
; run: %i64_u(0x800000000000000, 0xffffffffffffffff) == 0x800000000000000
|
||||
|
||||
function %i64_u_const(i64) -> i64 {
|
||||
@@ -166,7 +125,4 @@ block0(v0: i64):
|
||||
v2 = urem.i64 v0, v1
|
||||
return v2
|
||||
}
|
||||
; run: %i64_u_const(0) == 0
|
||||
; run: %i64_u_const(104857600000) == 104857600000
|
||||
; run: %i64_u_const(-57) == -57
|
||||
; run: %i64_u_const(0x800000000000000) == 0x800000000000000
|
||||
|
||||
32
cranelift/filetests/filetests/runtests/i128-srem.clif
Normal file
32
cranelift/filetests/filetests/runtests/i128-srem.clif
Normal file
@@ -0,0 +1,32 @@
|
||||
test interpret
|
||||
|
||||
function %srem_i128(i128, i128) -> i128 {
|
||||
block0(v0: i128,v1: i128):
|
||||
v2 = srem v0, v1
|
||||
return v2
|
||||
}
|
||||
; run: %srem_i128(0, 1) == 0
|
||||
; run: %srem_i128(2, 2) == 0
|
||||
; run: %srem_i128(1, -1) == 0
|
||||
; run: %srem_i128(3, 2) == 1
|
||||
; run: %srem_i128(19, 7) == 5
|
||||
; run: %srem_i128(3, -2) == 1
|
||||
; run: %srem_i128(-19, 7) == -5
|
||||
; run: %srem_i128(0xC0FFEEEE_DECAFFFF_C0FFEEEE_DECAFFFF, 8) == -1
|
||||
; run: %srem_i128(0xC0FFEEEE_DECAFFFF_C0FFEEEE_DECAFFFF, -8) == -1
|
||||
; run: %srem_i128(0x80000000_00000000_00000000_00000000, -2) == 0
|
||||
|
||||
|
||||
function %srem_imm_i128(i128) -> i128 {
|
||||
block0(v0: i128):
|
||||
v1 = srem_imm v0, 3
|
||||
return v1
|
||||
}
|
||||
; run: %srem_imm_i128(0) == 0
|
||||
; run: %srem_imm_i128(1) == 1
|
||||
; run: %srem_imm_i128(2) == 2
|
||||
; run: %srem_imm_i128(3) == 0
|
||||
; run: %srem_imm_i128(19) == 1
|
||||
; run: %srem_imm_i128(-19) == -1
|
||||
; run: %srem_imm_i128(0xC0FFEEEE_DECAFFFF_C0FFEEEE_DECAFFFF) == -1
|
||||
; run: %srem_imm_i128(0x80000000_00000000_00000000_00000000) == -2
|
||||
32
cranelift/filetests/filetests/runtests/i128-urem.clif
Normal file
32
cranelift/filetests/filetests/runtests/i128-urem.clif
Normal file
@@ -0,0 +1,32 @@
|
||||
test interpret
|
||||
|
||||
function %urem_i128(i128, i128) -> i128 {
|
||||
block0(v0: i128,v1: i128):
|
||||
v2 = urem v0, v1
|
||||
return v2
|
||||
}
|
||||
; run: %urem_i128(0, 1) == 0
|
||||
; run: %urem_i128(2, 2) == 0
|
||||
; run: %urem_i128(1, -1) == 1
|
||||
; run: %urem_i128(3, 2) == 1
|
||||
; run: %urem_i128(19, 7) == 5
|
||||
; run: %urem_i128(3, -2) == 3
|
||||
; run: %urem_i128(-19, 7) == 6
|
||||
; run: %urem_i128(0xC0FFEEEE_DECAFFFF_C0FFEEEE_DECAFFFF, 8) == 7
|
||||
; run: %urem_i128(0xC0FFEEEE_DECAFFFF_C0FFEEEE_DECAFFFF, -8) == 0xC0FFEEEE_DECAFFFF_C0FFEEEE_DECAFFFF
|
||||
; run: %urem_i128(0x80000000_00000000_00000000_00000000, -2) == 0x80000000_00000000_00000000_00000000
|
||||
|
||||
|
||||
function %urem_imm_i128(i128) -> i128 {
|
||||
block0(v0: i128):
|
||||
v1 = urem_imm v0, 3
|
||||
return v1
|
||||
}
|
||||
; run: %urem_imm_i128(0) == 0
|
||||
; run: %urem_imm_i128(1) == 1
|
||||
; run: %urem_imm_i128(2) == 2
|
||||
; run: %urem_imm_i128(3) == 0
|
||||
; run: %urem_imm_i128(19) == 1
|
||||
; run: %urem_imm_i128(-19) == 0
|
||||
; run: %urem_imm_i128(0xC0FFEEEE_DECAFFFF_C0FFEEEE_DECAFFFF) == 0
|
||||
; run: %urem_imm_i128(0x80000000_00000000_00000000_00000000) == 2
|
||||
146
cranelift/filetests/filetests/runtests/srem.clif
Normal file
146
cranelift/filetests/filetests/runtests/srem.clif
Normal file
@@ -0,0 +1,146 @@
|
||||
test interpret
|
||||
test run
|
||||
target aarch64
|
||||
target s390x
|
||||
target x86_64
|
||||
; Test these inputs without div traps, it shouldn't affect normal inputs
|
||||
set avoid_div_traps
|
||||
target aarch64
|
||||
target s390x
|
||||
target x86_64
|
||||
|
||||
function %srem_i64(i64, i64) -> i64 {
|
||||
block0(v0: i64,v1: i64):
|
||||
v2 = srem v0, v1
|
||||
return v2
|
||||
}
|
||||
; run: %srem_i64(0, 1) == 0
|
||||
; run: %srem_i64(2, 2) == 0
|
||||
; run: %srem_i64(1, -1) == 0
|
||||
; run: %srem_i64(3, 2) == 1
|
||||
; run: %srem_i64(19, 7) == 5
|
||||
; run: %srem_i64(3, -2) == 1
|
||||
; run: %srem_i64(-19, 7) == -5
|
||||
; run: %srem_i64(-57, -5) == -2
|
||||
; run: %srem_i64(0, 104857600000) == 0
|
||||
; run: %srem_i64(104857600000, 511) == 398
|
||||
; run: %srem_i64(0xC0FFEEEE_DECAFFFF, 8) == -1
|
||||
; run: %srem_i64(0xC0FFEEEE_DECAFFFF, -8) == -1
|
||||
; run: %srem_i64(0x80000000_00000000, -2) == 0
|
||||
|
||||
function %srem_i32(i32, i32) -> i32 {
|
||||
block0(v0: i32,v1: i32):
|
||||
v2 = srem v0, v1
|
||||
return v2
|
||||
}
|
||||
; run: %srem_i32(0, 1) == 0
|
||||
; run: %srem_i32(2, 2) == 0
|
||||
; run: %srem_i32(1, -1) == 0
|
||||
; run: %srem_i32(3, 2) == 1
|
||||
; run: %srem_i32(19, 7) == 5
|
||||
; run: %srem_i32(3, -2) == 1
|
||||
; run: %srem_i32(-19, 7) == -5
|
||||
; run: %srem_i32(0, 13) == 0
|
||||
; run: %srem_i32(1048576, 8192) == 0
|
||||
; run: %srem_i32(-1024, 255) == -4
|
||||
; run: %srem_i32(0xC0FFEEEE, 8) == -2
|
||||
; run: %srem_i32(0xC0FFEEEE, -8) == -2
|
||||
; run: %srem_i32(0x80000000, -2) == 0
|
||||
|
||||
function %srem_i16(i16, i16) -> i16 {
|
||||
block0(v0: i16,v1: i16):
|
||||
v2 = srem v0, v1
|
||||
return v2
|
||||
}
|
||||
; run: %srem_i16(0, 1) == 0
|
||||
; run: %srem_i16(2, 2) == 0
|
||||
; run: %srem_i16(1, -1) == 0
|
||||
; run: %srem_i16(3, 2) == 1
|
||||
; run: %srem_i16(19, 7) == 5
|
||||
; run: %srem_i16(3, -2) == 1
|
||||
; run: %srem_i16(13, 5) == 3
|
||||
; run: %srem_i16(0, 42) == 0
|
||||
; run: %srem_i16(4, -2) == 0
|
||||
; run: %srem_i16(-19, 7) == -5
|
||||
; run: %srem_i16(0xC0FF, 8) == -1
|
||||
; run: %srem_i16(0xC0FF, -8) == -1
|
||||
; run: %srem_i16(0x8000, -2) == 0
|
||||
|
||||
function %srem_i8(i8, i8) -> i8 {
|
||||
block0(v0: i8,v1: i8):
|
||||
v2 = srem v0, v1
|
||||
return v2
|
||||
}
|
||||
; run: %srem_i8(0, 1) == 0
|
||||
; run: %srem_i8(2, 2) == 0
|
||||
; run: %srem_i8(1, -1) == 0
|
||||
; run: %srem_i8(2, 7) == 2
|
||||
; run: %srem_i8(3, 2) == 1
|
||||
; run: %srem_i8(19, 7) == 5
|
||||
; run: %srem_i8(3, -2) == 1
|
||||
; run: %srem_i8(-19, 7) == -5
|
||||
; run: %srem_i8(0xC0, 8) == 0
|
||||
; run: %srem_i8(0xC0, -8) == 0
|
||||
; run: %srem_i8(0x80, -2) == 0
|
||||
|
||||
|
||||
function %srem_imm_i64(i64) -> i64 {
|
||||
block0(v0: i64):
|
||||
v1 = srem_imm v0, 3
|
||||
return v1
|
||||
}
|
||||
; run: %srem_imm_i64(0) == 0
|
||||
; run: %srem_imm_i64(1) == 1
|
||||
; run: %srem_imm_i64(2) == 2
|
||||
; run: %srem_imm_i64(3) == 0
|
||||
; run: %srem_imm_i64(19) == 1
|
||||
; run: %srem_imm_i64(-19) == -1
|
||||
; run: %srem_imm_i64(-57) == 0
|
||||
; run: %srem_imm_i64(104857600000) == 1
|
||||
; run: %srem_imm_i64(0xC0FFEEEE_DECAFFFF) == -1
|
||||
; run: %srem_imm_i64(0x80000000_00000000) == -2
|
||||
|
||||
function %srem_imm_i32(i32) -> i32 {
|
||||
block0(v0: i32):
|
||||
v1 = srem_imm v0, 3
|
||||
return v1
|
||||
}
|
||||
; run: %srem_imm_i32(0) == 0
|
||||
; run: %srem_imm_i32(1) == 1
|
||||
; run: %srem_imm_i32(2) == 2
|
||||
; run: %srem_imm_i32(3) == 0
|
||||
; run: %srem_imm_i32(4) == 1
|
||||
; run: %srem_imm_i32(19) == 1
|
||||
; run: %srem_imm_i32(-19) == -1
|
||||
; run: %srem_imm_i32(-42) == 0
|
||||
; run: %srem_imm_i32(1057) == 1
|
||||
; run: %srem_imm_i32(0xC0FFEEEE) == -2
|
||||
|
||||
function %srem_imm_i16(i16) -> i16 {
|
||||
block0(v0: i16):
|
||||
v1 = srem_imm v0, 3
|
||||
return v1
|
||||
}
|
||||
; run: %srem_imm_i16(0) == 0
|
||||
; run: %srem_imm_i16(1) == 1
|
||||
; run: %srem_imm_i16(2) == 2
|
||||
; run: %srem_imm_i16(3) == 0
|
||||
; run: %srem_imm_i16(4) == 1
|
||||
; run: %srem_imm_i16(19) == 1
|
||||
; run: %srem_imm_i16(-19) == -1
|
||||
; run: %srem_imm_i16(0xC0FF) == -1
|
||||
; run: %srem_imm_i16(0x8000) == -2
|
||||
|
||||
function %srem_imm_i8(i8) -> i8 {
|
||||
block0(v0: i8):
|
||||
v1 = srem_imm v0, 3
|
||||
return v1
|
||||
}
|
||||
; run: %srem_imm_i8(0) == 0
|
||||
; run: %srem_imm_i8(1) == 1
|
||||
; run: %srem_imm_i8(2) == 2
|
||||
; run: %srem_imm_i8(3) == 0
|
||||
; run: %srem_imm_i8(19) == 1
|
||||
; run: %srem_imm_i8(-19) == -1
|
||||
; run: %srem_imm_i8(0xC0) == -1
|
||||
; run: %srem_imm_i8(0x80) == -2
|
||||
140
cranelift/filetests/filetests/runtests/urem.clif
Normal file
140
cranelift/filetests/filetests/runtests/urem.clif
Normal file
@@ -0,0 +1,140 @@
|
||||
test interpret
|
||||
test run
|
||||
target aarch64
|
||||
target s390x
|
||||
target x86_64
|
||||
; Test these inputs without div traps, it shouldn't affect normal inputs
|
||||
set avoid_div_traps
|
||||
target aarch64
|
||||
target s390x
|
||||
target x86_64
|
||||
|
||||
function %urem_i64(i64, i64) -> i64 {
|
||||
block0(v0: i64,v1: i64):
|
||||
v2 = urem v0, v1
|
||||
return v2
|
||||
}
|
||||
; run: %urem_i64(0, 1) == 0
|
||||
; run: %urem_i64(2, 2) == 0
|
||||
; run: %urem_i64(1, -1) == 1
|
||||
; run: %urem_i64(3, 2) == 1
|
||||
; run: %urem_i64(19, 7) == 5
|
||||
; run: %urem_i64(3, -2) == 3
|
||||
; run: %urem_i64(-19, 7) == 4
|
||||
; run: %urem_i64(-57, -5) == -57
|
||||
; run: %urem_i64(0, 104857600000) == 0
|
||||
; run: %urem_i64(104857600000, 511) == 398
|
||||
; run: %urem_i64(0xC0FFEEEE_DECAFFFF, 8) == 7
|
||||
; run: %urem_i64(0xC0FFEEEE_DECAFFFF, -8) == 0xC0FFEEEE_DECAFFFF
|
||||
; run: %urem_i64(0x80000000_00000000, -2) == 0x80000000_00000000
|
||||
|
||||
function %urem_i32(i32, i32) -> i32 {
|
||||
block0(v0: i32,v1: i32):
|
||||
v2 = urem v0, v1
|
||||
return v2
|
||||
}
|
||||
; run: %urem_i32(0, 1) == 0
|
||||
; run: %urem_i32(2, 2) == 0
|
||||
; run: %urem_i32(1, -1) == 1
|
||||
; run: %urem_i32(3, 2) == 1
|
||||
; run: %urem_i32(19, 7) == 5
|
||||
; run: %urem_i32(3, -2) == 3
|
||||
; run: %urem_i32(-19, 7) == 6
|
||||
; run: %urem_i32(0, 13) == 0
|
||||
; run: %urem_i32(1048576, 8192) == 0
|
||||
; run: %urem_i32(-1024, 255) == 252
|
||||
; run: %urem_i32(0xC0FFEEEE, 8) == 6
|
||||
; run: %urem_i32(0xC0FFEEEE, -8) == 0xC0FFEEEE
|
||||
; run: %urem_i32(0x80000000, -2) == 0x80000000
|
||||
|
||||
function %urem_i16(i16, i16) -> i16 {
|
||||
block0(v0: i16,v1: i16):
|
||||
v2 = urem v0, v1
|
||||
return v2
|
||||
}
|
||||
; run: %urem_i16(0, 1) == 0
|
||||
; run: %urem_i16(2, 2) == 0
|
||||
; run: %urem_i16(1, -1) == 1
|
||||
; run: %urem_i16(3, 2) == 1
|
||||
; run: %urem_i16(19, 7) == 5
|
||||
; run: %urem_i16(3, -2) == 3
|
||||
; run: %urem_i16(-19, 7) == 4
|
||||
; run: %urem_i16(0, 42) == 0
|
||||
; run: %urem_i16(4, -2) == 4
|
||||
; run: %urem_i16(13, 5) == 3
|
||||
; run: %urem_i16(0xC0FF, 8) == 7
|
||||
; run: %urem_i16(0xC0FF, -8) == 0xC0FF
|
||||
; run: %urem_i16(0x8000, -2) == 0x8000
|
||||
|
||||
function %urem_i8(i8, i8) -> i8 {
|
||||
block0(v0: i8,v1: i8):
|
||||
v2 = urem v0, v1
|
||||
return v2
|
||||
}
|
||||
; run: %urem_i8(0, 1) == 0
|
||||
; run: %urem_i8(2, 2) == 0
|
||||
; run: %urem_i8(1, -1) == 1
|
||||
; run: %urem_i8(3, 2) == 1
|
||||
; run: %urem_i8(19, 7) == 5
|
||||
; run: %urem_i8(3, -2) == 3
|
||||
; run: %urem_i8(-19, 7) == 6
|
||||
; run: %urem_i8(0xC0, 8) == 0
|
||||
; run: %urem_i8(0xC0, -8) == 0xC0
|
||||
; run: %urem_i8(0x80, -2) == 0x80
|
||||
|
||||
|
||||
function %urem_imm_i64(i64) -> i64 {
|
||||
block0(v0: i64):
|
||||
v1 = urem_imm v0, 3
|
||||
return v1
|
||||
}
|
||||
; run: %urem_imm_i64(0) == 0
|
||||
; run: %urem_imm_i64(1) == 1
|
||||
; run: %urem_imm_i64(2) == 2
|
||||
; run: %urem_imm_i64(3) == 0
|
||||
; run: %urem_imm_i64(19) == 1
|
||||
; run: %urem_imm_i64(-19) == 0
|
||||
; run: %urem_imm_i64(0xC0FFEEEE_DECAFFFF) == 0
|
||||
; run: %urem_imm_i64(0x80000000_00000000) == 2
|
||||
|
||||
function %urem_imm_i32(i32) -> i32 {
|
||||
block0(v0: i32):
|
||||
v1 = urem_imm v0, 3
|
||||
return v1
|
||||
}
|
||||
; run: %urem_imm_i32(0) == 0
|
||||
; run: %urem_imm_i32(1) == 1
|
||||
; run: %urem_imm_i32(2) == 2
|
||||
; run: %urem_imm_i32(3) == 0
|
||||
; run: %urem_imm_i32(19) == 1
|
||||
; run: %urem_imm_i32(-19) == 0
|
||||
; run: %urem_imm_i32(0xC0FFEEEE) == 2
|
||||
; run: %urem_imm_i32(0x80000000) == 2
|
||||
|
||||
function %urem_imm_i16(i16) -> i16 {
|
||||
block0(v0: i16):
|
||||
v1 = urem_imm v0, 3
|
||||
return v1
|
||||
}
|
||||
; run: %urem_imm_i16(0) == 0
|
||||
; run: %urem_imm_i16(1) == 1
|
||||
; run: %urem_imm_i16(2) == 2
|
||||
; run: %urem_imm_i16(3) == 0
|
||||
; run: %urem_imm_i16(19) == 1
|
||||
; run: %urem_imm_i16(-19) == 0
|
||||
; run: %urem_imm_i16(0xC0FF) == 0
|
||||
; run: %urem_imm_i16(0x8000) == 2
|
||||
|
||||
function %urem_imm_i8(i8) -> i8 {
|
||||
block0(v0: i8):
|
||||
v1 = urem_imm v0, 3
|
||||
return v1
|
||||
}
|
||||
; run: %urem_imm_i8(0) == 0
|
||||
; run: %urem_imm_i8(1) == 1
|
||||
; run: %urem_imm_i8(2) == 2
|
||||
; run: %urem_imm_i8(3) == 0
|
||||
; run: %urem_imm_i8(19) == 1
|
||||
; run: %urem_imm_i8(-19) == 0
|
||||
; run: %urem_imm_i8(0xC0) == 0
|
||||
; run: %urem_imm_i8(0x80) == 2
|
||||
@@ -1013,4 +1013,26 @@ mod tests {
|
||||
|
||||
assert_eq!(result, vec![DataValue::B(true)])
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn srem_trap() {
|
||||
let code = "function %test() -> i64 {
|
||||
block0:
|
||||
v0 = iconst.i64 0x8000_0000_0000_0000
|
||||
v1 = iconst.i64 -1
|
||||
v2 = srem.i64 v0, v1
|
||||
return v2
|
||||
}";
|
||||
|
||||
let func = parse_functions(code).unwrap().into_iter().next().unwrap();
|
||||
let mut env = FunctionStore::default();
|
||||
env.add(func.name.to_string(), &func);
|
||||
let state = InterpreterState::default().with_function_store(env);
|
||||
let trap = Interpreter::new(state)
|
||||
.call_by_name("%test", &[])
|
||||
.unwrap()
|
||||
.unwrap_trap();
|
||||
|
||||
assert_eq!(trap, CraneliftTrap::User(TrapCode::IntegerOverflow));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -597,9 +597,9 @@ where
|
||||
Opcode::Srem => binary_can_trap(Value::rem, arg(0)?, arg(1)?)?,
|
||||
Opcode::IaddImm => binary(Value::add, arg(0)?, imm_as_ctrl_ty()?)?,
|
||||
Opcode::ImulImm => binary(Value::mul, arg(0)?, imm_as_ctrl_ty()?)?,
|
||||
Opcode::UdivImm => binary_unsigned_can_trap(Value::div, arg(0)?, imm())?,
|
||||
Opcode::UdivImm => binary_unsigned_can_trap(Value::div, arg(0)?, imm_as_ctrl_ty()?)?,
|
||||
Opcode::SdivImm => binary_can_trap(Value::div, arg(0)?, imm_as_ctrl_ty()?)?,
|
||||
Opcode::UremImm => binary_unsigned_can_trap(Value::rem, arg(0)?, imm())?,
|
||||
Opcode::UremImm => binary_unsigned_can_trap(Value::rem, arg(0)?, imm_as_ctrl_ty()?)?,
|
||||
Opcode::SremImm => binary_can_trap(Value::rem, arg(0)?, imm_as_ctrl_ty()?)?,
|
||||
Opcode::IrsubImm => binary(Value::sub, imm_as_ctrl_ty()?, arg(0)?)?,
|
||||
Opcode::IaddCin => choose(
|
||||
|
||||
@@ -529,15 +529,23 @@ impl Value for DataValue {
|
||||
return Err(ValueError::IntegerDivisionByZero);
|
||||
}
|
||||
|
||||
binary_match!(/(&self, &other); [I8, I16, I32, I64, U8, U16, U32, U64])
|
||||
binary_match!(/(&self, &other); [I8, I16, I32, I64, I128, U8, U16, U32, U64, U128])
|
||||
}
|
||||
|
||||
fn rem(self, other: Self) -> ValueResult<Self> {
|
||||
if other.clone().into_int()? == 0 {
|
||||
let denominator = other.clone().into_int()?;
|
||||
|
||||
// Check if we are dividing INT_MIN / -1. This causes an integer overflow trap.
|
||||
let min = Value::int(1i128 << (self.ty().bits() - 1), self.ty())?;
|
||||
if self == min && denominator == -1 {
|
||||
return Err(ValueError::IntegerOverflow);
|
||||
}
|
||||
|
||||
if denominator == 0 {
|
||||
return Err(ValueError::IntegerDivisionByZero);
|
||||
}
|
||||
|
||||
binary_match!(%(&self, &other); [I8, I16, I32, I64])
|
||||
binary_match!(%(&self, &other); [I8, I16, I32, I64, I128, U8, U16, U32, U64, U128])
|
||||
}
|
||||
|
||||
fn sqrt(self) -> ValueResult<Self> {
|
||||
|
||||
Reference in New Issue
Block a user