From e84e6e24e2a259588744504f766caea334448a14 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Wed, 15 Mar 2023 10:36:51 -0700 Subject: [PATCH 1/8] x64: Take SIGFPE signals for divide traps Prior to this commit Wasmtime would configure `avoid_div_traps=true` unconditionally for Cranelift. This, for the division-based instructions, would change emitted code to explicitly trap on trap conditions instead of letting the `div` x86 instruction trap. There's no specific reason for Wasmtime, however, to specifically avoid traps in the `div` instruction. This means that the extra generated branches on x86 aren't necessary since the `div` and `idiv` instructions already trap for similar conditions as wasm requires. This commit instead disables the `avoid_div_traps` setting for Wasmtime's usage of Cranelift. Subsequently the codegen rules were updated slightly: * When `avoid_div_traps=true`, traps are no longer emitted for `div` instructions. * The `udiv`/`urem` instructions now list their trap as divide-by-zero instead of integer overflow. * The lowering for `sdiv` was updated to still explicitly check for zero but the integer overflow case is deferred to the instruction itself. * The lowering of `srem` no longer checks for zero and the listed trap for the `div` instruction is a divide-by-zero. This means that the codegen for `udiv` and `urem` no longer have any branches. The codegen for `sdiv` removes one branch but keeps the zero-check to differentiate the two kinds of traps. The codegen for `srem` removes one branch but keeps the -1 check since the semantics of `srem` mismatch with the semantics of `idiv` with a -1 divisor (specifically for INT_MIN). This is unlikely to have really all that much of a speedup but was something I noticed during #6008 which seemed like it'd be good to clean up. Plus Wasmtime's signal handling was already set up to catch `SIGFPE`, it was just never firing. --- cranelift/codegen/src/isa/x64/inst/emit.rs | 31 +++++++++- cranelift/codegen/src/isa/x64/inst/mod.rs | 4 ++ cranelift/codegen/src/isa/x64/lower.isle | 59 +++++++++++-------- .../filetests/isa/x64/sdiv-checked.clif | 16 ++--- .../filetests/filetests/isa/x64/sdiv.clif | 28 +++++++-- .../filetests/isa/x64/srem-checked.clif | 16 ++--- .../filetests/filetests/isa/x64/srem.clif | 8 +-- .../filetests/isa/x64/udiv-checked.clif | 16 ++--- .../filetests/isa/x64/urem-checked.clif | 16 ++--- crates/cranelift-shared/src/isa_builder.rs | 6 -- crates/wasmtime/src/engine.rs | 4 +- crates/wasmtime/src/engine/serialization.rs | 9 +-- 12 files changed, 134 insertions(+), 79 deletions(-) diff --git a/cranelift/codegen/src/isa/x64/inst/emit.rs b/cranelift/codegen/src/isa/x64/inst/emit.rs index 4e409979dddf..3e751e70362b 100644 --- a/cranelift/codegen/src/isa/x64/inst/emit.rs +++ b/cranelift/codegen/src/isa/x64/inst/emit.rs @@ -437,7 +437,33 @@ pub(crate) fn emit( OperandSize::Size64 => (0xF7, LegacyPrefixes::None), }; - sink.add_trap(TrapCode::IntegerDivisionByZero); + // If div traps are avoided then no trap is registered here since + // the instruction should never trap due to lowering rules. + // + // Otherwise though this instruction is allowed to trap. There's + // one trapping condition for unsigned division, which is + // always divide-by-zero, so that's reported here. There are two + // conditions for signed division, though, either divide-by-zero + // or integer overflow with INT_MIN/-1. Lowering explicitly + // checks for 0 because it's easier and defers the overflow + // detection to happening via a trap. + // + // Note, though, that this instruction is also used as part of the + // `CheckedSRemSeq*` lowering which uses signed division but + // statically rules out the integer overflow case, in which case + // the listed trap here is divide-by-zero. This means that only the + // actual CLIF `sdiv` instruction ends up triggering the integer + // overflow case. + if !info.flags.avoid_div_traps() { + sink.add_trap(if state.div_trap_is_divide_by_zero { + TrapCode::IntegerDivisionByZero + } else { + match sign { + DivSignedness::Signed => TrapCode::IntegerOverflow, + DivSignedness::Unsigned => TrapCode::IntegerDivisionByZero, + } + }); + } let subopcode = match sign { DivSignedness::Signed => 7, @@ -626,7 +652,10 @@ pub(crate) fn emit( Writable::from_reg(Gpr::new(regs::rdx()).unwrap()), ), }; + assert!(!state.div_trap_is_divide_by_zero); + state.div_trap_is_divide_by_zero = true; inst.emit(&[], sink, info, state); + state.div_trap_is_divide_by_zero = false; sink.bind_label(done_label); } diff --git a/cranelift/codegen/src/isa/x64/inst/mod.rs b/cranelift/codegen/src/isa/x64/inst/mod.rs index b7865b21b54d..6dab29da9d83 100644 --- a/cranelift/codegen/src/isa/x64/inst/mod.rs +++ b/cranelift/codegen/src/isa/x64/inst/mod.rs @@ -2551,6 +2551,9 @@ pub struct EmitState { stack_map: Option, /// Current source location. cur_srcloc: RelSourceLoc, + /// Used for `CheckedSRemSeq*` to configure the trap emitted for its `div` + /// instruction. + div_trap_is_divide_by_zero: bool, } /// Constant state used during emissions of a sequence of instructions. @@ -2593,6 +2596,7 @@ impl MachInstEmitState for EmitState { nominal_sp_to_fp: abi.frame_size() as i64, stack_map: None, cur_srcloc: Default::default(), + div_trap_is_divide_by_zero: false, } } diff --git a/cranelift/codegen/src/isa/x64/lower.isle b/cranelift/codegen/src/isa/x64/lower.isle index b5fcffe4804c..0dcbb3aaa3b8 100644 --- a/cranelift/codegen/src/isa/x64/lower.isle +++ b/cranelift/codegen/src/isa/x64/lower.isle @@ -3496,7 +3496,7 @@ ;; different shape. (rule 2 (lower (udiv a @ (value_type $I8) b)) (x64_div8 (extend_to_gpr a $I32 (ExtendKind.Zero)) - (nonzero_divisor $I8 b) + (validate_udiv_divisor $I8 b) (DivSignedness.Unsigned))) ;; 16-to-64-bit division is all done with a similar instruction and the only @@ -3505,28 +3505,23 @@ (rule 1 (lower (udiv a @ (value_type (fits_in_64 ty)) b)) (x64_div_quotient a (imm $I64 0) - (nonzero_divisor ty b) + (validate_udiv_divisor ty b) (raw_operand_size_of_type ty) (DivSignedness.Unsigned))) -;; Helper to place `Value` into a `Gpr` while possibly trapping if it's zero. -;; -;; If the `avoid_div_traps=true` codegen setting is specified then the value -;; is checked for zero and a trap happens before the value is returned as a -;; register here. -(decl nonzero_divisor (Type Value) Gpr) - -;; As a special-case if the divisor is a constant number which is nonzero then -;; no matter what there's no checks necessary. -(rule 2 (nonzero_divisor ty (iconst (u64_from_imm64 (u64_nonzero n)))) - (imm ty n)) - -;; No checks necessary when `avoid_div_traps=false` -(rule 1 (nonzero_divisor ty val) +;; Small helper which does nothing if `avoid_div_traps=false` because udiv +;; is allowed to trap and only has one trapping condition. Otherwise defers +;; to `nonzero_divisor` to perform an explicit check. +(decl validate_udiv_divisor (Type Value) Gpr) +(rule 1 (validate_udiv_divisor ty val) (if-let $false (avoid_div_traps)) val) +(rule (validate_udiv_divisor ty val) (nonzero_divisor ty val)) -;; Base case traps if `val` is zero by using a `test` + `trap_if` combo +;; Helper to place `Value` into a `Gpr` while possibly trapping if it's zero. +(decl nonzero_divisor (Type Value) Gpr) +(rule 1 (nonzero_divisor ty (iconst (u64_from_imm64 (u64_nonzero n)))) + (imm ty n)) (rule (nonzero_divisor ty val) (let ( (val Reg val) @@ -3562,14 +3557,15 @@ (if-let n (safe_divisor_from_imm64 ty imm)) (imm ty n)) -;; With `avoid_div_traps=false` the divisor can be plumbed through. +;; With `avoid_div_traps=false` then the div instruction is allowed to trap but +;; lowering still needs to differentiate each case. The divide-by-zero case +;; is explicitly checked here and then if div traps it's due to overflow. ;; -;; Note that CLIF semantics dictate that division-by-zero and INT_MIN/-1 both -;; trap, but this matches the hardware semantics of `idiv` on x64 so they're -;; fine to get plumbed through as-is. +;; Note that check-for-zero happens here explicitly since it's a bit smaller to +;; codegen than to check for integer overflow (checking one reg vs two). (rule 2 (safe_sdiv_divisor ty a b) (if-let $false (avoid_div_traps)) - b) + (nonzero_divisor ty b)) ;; The base cases here rely on some pseudo-instructions to do the checks to ;; jump around with labels and such. @@ -3583,7 +3579,7 @@ (rule 2 (lower (urem a @ (value_type $I8) b)) (let ( (a Gpr (extend_to_gpr a $I32 (ExtendKind.Zero))) - (b Gpr (nonzero_divisor $I8 b)) + (b Gpr (validate_udiv_divisor $I8 b)) (result Gpr (x64_div8 a b (DivSignedness.Unsigned))) ) (x64_shr $I64 result (Imm8Reg.Imm8 8)))) @@ -3591,7 +3587,7 @@ (rule 1 (lower (urem a @ (value_type (fits_in_64 ty)) b)) (x64_div_remainder a (imm $I64 0) - (nonzero_divisor ty b) + (validate_udiv_divisor ty b) (raw_operand_size_of_type ty) (DivSignedness.Unsigned))) @@ -3623,17 +3619,28 @@ size (DivSignedness.Signed)))) +;; Note the usage of `validate_udiv_divisor` here and below which conditionally +;; checks for 0 depending on `avoid_div_traps`. If `div` can trap then despite +;; signed division having two trap conditions the srem sequence handles the +;; integer overflow case manually so the only trapping condition for this +;; instruction is divide-by-zero. This means that when `avoid_div_traps=true` +;; this must explicitly check for 0, and when `avoid_div_traps=false` the check +;; for 0 can be elided. +;; +;; No matter what the value is of `avoid_div_traps`, though, the divisor must +;; always be checked for -1. This happens inside of the `x64_checked_srem_seq*` +;; pseudo-instruction. (rule 1 (lower (srem a @ (value_type $I8) b)) (let ( (a Gpr (x64_sign_extend_data a (OperandSize.Size8))) - (b Gpr (nonzero_divisor $I8 b)) + (b Gpr (validate_udiv_divisor $I8 b)) ) (x64_shr $I64 (x64_checked_srem_seq8 a b) (Imm8Reg.Imm8 8)))) (rule (lower (srem a @ (value_type ty) b)) (let ( (a Gpr a) - (b Gpr (nonzero_divisor ty b)) + (b Gpr (validate_udiv_divisor ty b)) (size OperandSize (raw_operand_size_of_type ty)) (hi Gpr (x64_sign_extend_data a size)) (tmp ValueRegs (x64_checked_srem_seq size a hi b)) diff --git a/cranelift/filetests/filetests/isa/x64/sdiv-checked.clif b/cranelift/filetests/filetests/isa/x64/sdiv-checked.clif index 7505a3078997..7dd3771c1f34 100644 --- a/cranelift/filetests/filetests/isa/x64/sdiv-checked.clif +++ b/cranelift/filetests/filetests/isa/x64/sdiv-checked.clif @@ -35,7 +35,7 @@ block0(v0: i8, v1: i8): ; cmpb $0x80, %al ; jne 0x2a ; ud2 ; trap: int_ovf -; idivb %sil ; trap: int_divz +; idivb %sil ; movq %rbp, %rsp ; popq %rbp ; retq @@ -73,7 +73,7 @@ block0(v0: i16, v1: i16): ; ud2 ; trap: int_ovf ; movq %rdi, %rax ; cwtd -; idivw %si ; trap: int_divz +; idivw %si ; movq %rbp, %rsp ; popq %rbp ; retq @@ -111,7 +111,7 @@ block0(v0: i32, v1: i32): ; ud2 ; trap: int_ovf ; movq %rdi, %rax ; cltd -; idivl %esi ; trap: int_divz +; idivl %esi ; movq %rbp, %rsp ; popq %rbp ; retq @@ -150,7 +150,7 @@ block0(v0: i64, v1: i64): ; ud2 ; trap: int_ovf ; movq %rdi, %rax ; cqto -; idivq %rsi ; trap: int_divz +; idivq %rsi ; movq %rbp, %rsp ; popq %rbp ; retq @@ -182,7 +182,7 @@ block0(v0: i8): ; movq %rdi, %rax ; cbtw ; movl $0x11, %edx -; idivb %dl ; trap: int_divz +; idivb %dl ; movq %rbp, %rsp ; popq %rbp ; retq @@ -214,7 +214,7 @@ block0(v0: i16): ; movl $0x11, %ecx ; movq %rdi, %rax ; cwtd -; idivw %cx ; trap: int_divz +; idivw %cx ; movq %rbp, %rsp ; popq %rbp ; retq @@ -246,7 +246,7 @@ block0(v0: i32): ; movl $0x11, %ecx ; movq %rdi, %rax ; cltd -; idivl %ecx ; trap: int_divz +; idivl %ecx ; movq %rbp, %rsp ; popq %rbp ; retq @@ -278,7 +278,7 @@ block0(v0: i64): ; movl $0x11, %ecx ; movq %rdi, %rax ; cqto -; idivq %rcx ; trap: int_divz +; idivq %rcx ; movq %rbp, %rsp ; popq %rbp ; retq diff --git a/cranelift/filetests/filetests/isa/x64/sdiv.clif b/cranelift/filetests/filetests/isa/x64/sdiv.clif index 657a1e7fa4f4..f14002512ad4 100644 --- a/cranelift/filetests/filetests/isa/x64/sdiv.clif +++ b/cranelift/filetests/filetests/isa/x64/sdiv.clif @@ -13,6 +13,8 @@ block0(v0: i8, v1: i8): ; block0: ; movq %rdi, %rax ; cbw %al, %al +; testb %sil, %sil +; jnz ; ud2 int_divz ; ; idiv %al, %sil, %al ; movq %rbp, %rsp ; popq %rbp @@ -25,7 +27,10 @@ block0(v0: i8, v1: i8): ; block1: ; offset 0x4 ; movq %rdi, %rax ; cbtw -; idivb %sil ; trap: int_divz +; testb %sil, %sil +; jne 0x14 +; ud2 ; trap: int_divz +; idivb %sil ; trap: int_ovf ; movq %rbp, %rsp ; popq %rbp ; retq @@ -40,6 +45,8 @@ block0(v0: i16, v1: i16): ; pushq %rbp ; movq %rsp, %rbp ; block0: +; testw %si, %si +; jnz ; ud2 int_divz ; ; movq %rdi, %rax ; cwd %ax, %dx ; idiv %ax, %dx, %si, %ax, %dx @@ -52,9 +59,12 @@ block0(v0: i16, v1: i16): ; pushq %rbp ; movq %rsp, %rbp ; block1: ; offset 0x4 +; testw %si, %si +; jne 0xf +; ud2 ; trap: int_divz ; movq %rdi, %rax ; cwtd -; idivw %si ; trap: int_divz +; idivw %si ; trap: int_ovf ; movq %rbp, %rsp ; popq %rbp ; retq @@ -69,6 +79,8 @@ block0(v0: i32, v1: i32): ; pushq %rbp ; movq %rsp, %rbp ; block0: +; testl %esi, %esi +; jnz ; ud2 int_divz ; ; movq %rdi, %rax ; cdq %eax, %edx ; idiv %eax, %edx, %esi, %eax, %edx @@ -81,9 +93,12 @@ block0(v0: i32, v1: i32): ; pushq %rbp ; movq %rsp, %rbp ; block1: ; offset 0x4 +; testl %esi, %esi +; jne 0xe +; ud2 ; trap: int_divz ; movq %rdi, %rax ; cltd -; idivl %esi ; trap: int_divz +; idivl %esi ; trap: int_ovf ; movq %rbp, %rsp ; popq %rbp ; retq @@ -98,6 +113,8 @@ block0(v0: i64, v1: i64): ; pushq %rbp ; movq %rsp, %rbp ; block0: +; testq %rsi, %rsi +; jnz ; ud2 int_divz ; ; movq %rdi, %rax ; cqo %rax, %rdx ; idiv %rax, %rdx, %rsi, %rax, %rdx @@ -110,9 +127,12 @@ block0(v0: i64, v1: i64): ; pushq %rbp ; movq %rsp, %rbp ; block1: ; offset 0x4 +; testq %rsi, %rsi +; jne 0xf +; ud2 ; trap: int_divz ; movq %rdi, %rax ; cqto -; idivq %rsi ; trap: int_divz +; idivq %rsi ; trap: int_ovf ; movq %rbp, %rsp ; popq %rbp ; retq diff --git a/cranelift/filetests/filetests/isa/x64/srem-checked.clif b/cranelift/filetests/filetests/isa/x64/srem-checked.clif index e4bb829b3a20..a79131231b33 100644 --- a/cranelift/filetests/filetests/isa/x64/srem-checked.clif +++ b/cranelift/filetests/filetests/isa/x64/srem-checked.clif @@ -36,7 +36,7 @@ block0(v0: i8, v1: i8): ; jne 0x28 ; movl $0, %eax ; jmp 0x2b -; idivb %sil ; trap: int_divz +; idivb %sil ; shrq $8, %rax ; movq %rbp, %rsp ; popq %rbp @@ -76,7 +76,7 @@ block0(v0: i16, v1: i16): ; jne 0x28 ; movl $0, %edx ; jmp 0x2b -; idivw %si ; trap: int_divz +; idivw %si ; movq %rdx, %rax ; movq %rbp, %rsp ; popq %rbp @@ -116,7 +116,7 @@ block0(v0: i32, v1: i32): ; jne 0x25 ; movl $0, %edx ; jmp 0x27 -; idivl %esi ; trap: int_divz +; idivl %esi ; movq %rdx, %rax ; movq %rbp, %rsp ; popq %rbp @@ -156,7 +156,7 @@ block0(v0: i64, v1: i64): ; jne 0x28 ; movl $0, %edx ; jmp 0x2b -; idivq %rsi ; trap: int_divz +; idivq %rsi ; movq %rdx, %rax ; movq %rbp, %rsp ; popq %rbp @@ -190,7 +190,7 @@ block0(v0: i8): ; movq %rdi, %rax ; cbtw ; movl $0x11, %edx -; idivb %dl ; trap: int_divz +; idivb %dl ; shrq $8, %rax ; movq %rbp, %rsp ; popq %rbp @@ -224,7 +224,7 @@ block0(v0: i16): ; movq %rdi, %rax ; cwtd ; movl $0x11, %r8d -; idivw %r8w ; trap: int_divz +; idivw %r8w ; movq %rdx, %rax ; movq %rbp, %rsp ; popq %rbp @@ -258,7 +258,7 @@ block0(v0: i32): ; movq %rdi, %rax ; cltd ; movl $0x11, %r8d -; idivl %r8d ; trap: int_divz +; idivl %r8d ; movq %rdx, %rax ; movq %rbp, %rsp ; popq %rbp @@ -292,7 +292,7 @@ block0(v0: i64): ; movq %rdi, %rax ; cqto ; movl $0x11, %r8d -; idivq %r8 ; trap: int_divz +; idivq %r8 ; movq %rdx, %rax ; movq %rbp, %rsp ; popq %rbp diff --git a/cranelift/filetests/filetests/isa/x64/srem.clif b/cranelift/filetests/filetests/isa/x64/srem.clif index 973a9f0beefa..f311fbc00570 100644 --- a/cranelift/filetests/filetests/isa/x64/srem.clif +++ b/cranelift/filetests/filetests/isa/x64/srem.clif @@ -169,7 +169,7 @@ block0(v0: i8): ; movq %rdi, %rax ; cbtw ; movl $0x11, %edx -; idivb %dl ; trap: int_divz +; idivb %dl ; trap: int_ovf ; shrq $8, %rax ; movq %rbp, %rsp ; popq %rbp @@ -203,7 +203,7 @@ block0(v0: i16): ; movq %rdi, %rax ; cwtd ; movl $0x11, %r8d -; idivw %r8w ; trap: int_divz +; idivw %r8w ; trap: int_ovf ; movq %rdx, %rax ; movq %rbp, %rsp ; popq %rbp @@ -237,7 +237,7 @@ block0(v0: i32): ; movq %rdi, %rax ; cltd ; movl $0x11, %r8d -; idivl %r8d ; trap: int_divz +; idivl %r8d ; trap: int_ovf ; movq %rdx, %rax ; movq %rbp, %rsp ; popq %rbp @@ -271,7 +271,7 @@ block0(v0: i64): ; movq %rdi, %rax ; cqto ; movl $0x11, %r8d -; idivq %r8 ; trap: int_divz +; idivq %r8 ; trap: int_ovf ; movq %rdx, %rax ; movq %rbp, %rsp ; popq %rbp diff --git a/cranelift/filetests/filetests/isa/x64/udiv-checked.clif b/cranelift/filetests/filetests/isa/x64/udiv-checked.clif index 4eec243fb1ba..e9cb803133bf 100644 --- a/cranelift/filetests/filetests/isa/x64/udiv-checked.clif +++ b/cranelift/filetests/filetests/isa/x64/udiv-checked.clif @@ -29,7 +29,7 @@ block0(v0: i8, v1: i8): ; testb %sil, %sil ; jne 0x13 ; ud2 ; trap: int_divz -; divb %sil ; trap: int_divz +; divb %sil ; movq %rbp, %rsp ; popq %rbp ; retq @@ -63,7 +63,7 @@ block0(v0: i16, v1: i16): ; testw %si, %si ; jne 0x15 ; ud2 ; trap: int_divz -; divw %si ; trap: int_divz +; divw %si ; movq %rbp, %rsp ; popq %rbp ; retq @@ -97,7 +97,7 @@ block0(v0: i32, v1: i32): ; testl %esi, %esi ; jne 0x14 ; ud2 ; trap: int_divz -; divl %esi ; trap: int_divz +; divl %esi ; movq %rbp, %rsp ; popq %rbp ; retq @@ -131,7 +131,7 @@ block0(v0: i64, v1: i64): ; testq %rsi, %rsi ; jne 0x15 ; ud2 ; trap: int_divz -; divq %rsi ; trap: int_divz +; divq %rsi ; movq %rbp, %rsp ; popq %rbp ; retq @@ -161,7 +161,7 @@ block0(v0: i8): ; block1: ; offset 0x4 ; movzbl %dil, %eax ; movl $0x11, %edx -; divb %dl ; trap: int_divz +; divb %dl ; movq %rbp, %rsp ; popq %rbp ; retq @@ -193,7 +193,7 @@ block0(v0: i16): ; movq %rdi, %rax ; xorq %rdx, %rdx ; movl $0x11, %r8d -; divw %r8w ; trap: int_divz +; divw %r8w ; movq %rbp, %rsp ; popq %rbp ; retq @@ -225,7 +225,7 @@ block0(v0: i32): ; movq %rdi, %rax ; xorq %rdx, %rdx ; movl $0x11, %r8d -; divl %r8d ; trap: int_divz +; divl %r8d ; movq %rbp, %rsp ; popq %rbp ; retq @@ -257,7 +257,7 @@ block0(v0: i64): ; movq %rdi, %rax ; xorq %rdx, %rdx ; movl $0x11, %r8d -; divq %r8 ; trap: int_divz +; divq %r8 ; movq %rbp, %rsp ; popq %rbp ; retq diff --git a/cranelift/filetests/filetests/isa/x64/urem-checked.clif b/cranelift/filetests/filetests/isa/x64/urem-checked.clif index df6e20e1c3f6..f304fa296249 100644 --- a/cranelift/filetests/filetests/isa/x64/urem-checked.clif +++ b/cranelift/filetests/filetests/isa/x64/urem-checked.clif @@ -30,7 +30,7 @@ block0(v0: i8, v1: i8): ; testb %sil, %sil ; jne 0x13 ; ud2 ; trap: int_divz -; divb %sil ; trap: int_divz +; divb %sil ; shrq $8, %rax ; movq %rbp, %rsp ; popq %rbp @@ -66,7 +66,7 @@ block0(v0: i16, v1: i16): ; testw %si, %si ; jne 0x15 ; ud2 ; trap: int_divz -; divw %si ; trap: int_divz +; divw %si ; movq %rdx, %rax ; movq %rbp, %rsp ; popq %rbp @@ -102,7 +102,7 @@ block0(v0: i32, v1: i32): ; testl %esi, %esi ; jne 0x14 ; ud2 ; trap: int_divz -; divl %esi ; trap: int_divz +; divl %esi ; movq %rdx, %rax ; movq %rbp, %rsp ; popq %rbp @@ -138,7 +138,7 @@ block0(v0: i64, v1: i64): ; testq %rsi, %rsi ; jne 0x15 ; ud2 ; trap: int_divz -; divq %rsi ; trap: int_divz +; divq %rsi ; movq %rdx, %rax ; movq %rbp, %rsp ; popq %rbp @@ -170,7 +170,7 @@ block0(v0: i8): ; block1: ; offset 0x4 ; movzbl %dil, %eax ; movl $0x11, %edx -; divb %dl ; trap: int_divz +; divb %dl ; shrq $8, %rax ; movq %rbp, %rsp ; popq %rbp @@ -204,7 +204,7 @@ block0(v0: i16): ; movq %rdi, %rax ; xorq %rdx, %rdx ; movl $0x11, %r8d -; divw %r8w ; trap: int_divz +; divw %r8w ; movq %rdx, %rax ; movq %rbp, %rsp ; popq %rbp @@ -238,7 +238,7 @@ block0(v0: i32): ; movq %rdi, %rax ; xorq %rdx, %rdx ; movl $0x11, %r8d -; divl %r8d ; trap: int_divz +; divl %r8d ; movq %rdx, %rax ; movq %rbp, %rsp ; popq %rbp @@ -272,7 +272,7 @@ block0(v0: i64): ; movq %rdi, %rax ; xorq %rdx, %rdx ; movl $0x11, %r8d -; divq %r8 ; trap: int_divz +; divq %r8 ; movq %rdx, %rax ; movq %rbp, %rsp ; popq %rbp diff --git a/crates/cranelift-shared/src/isa_builder.rs b/crates/cranelift-shared/src/isa_builder.rs index d15abe992967..ad16bb8e8591 100644 --- a/crates/cranelift-shared/src/isa_builder.rs +++ b/crates/cranelift-shared/src/isa_builder.rs @@ -23,12 +23,6 @@ impl IsaBuilder { pub fn new(lookup: fn(Triple) -> Result>) -> Self { let mut flags = settings::builder(); - // There are two possible traps for division, and this way - // we get the proper one if code traps. - flags - .enable("avoid_div_traps") - .expect("should be valid flag"); - // We don't use probestack as a stack limit mechanism flags .set("enable_probestack", "false") diff --git a/crates/wasmtime/src/engine.rs b/crates/wasmtime/src/engine.rs index 9523278f5460..a71e4cfbfb22 100644 --- a/crates/wasmtime/src/engine.rs +++ b/crates/wasmtime/src/engine.rs @@ -350,7 +350,7 @@ impl Engine { /// currently rely on the compiler informing us of all settings, including /// those disabled. Settings then fall in a few buckets: /// - /// * Some settings must be enabled, such as `avoid_div_traps`. + /// * Some settings must be enabled, such as `preserve_frame_pointers`. /// * Some settings must have a particular value, such as /// `libcall_call_conv`. /// * Some settings do not matter as to their value, such as `opt_level`. @@ -364,7 +364,6 @@ impl Engine { // These settings must all have be enabled, since their value // can affect the way the generated code performs or behaves at // runtime. - "avoid_div_traps" => *value == FlagValue::Bool(true), "libcall_call_conv" => *value == FlagValue::Enum("isa_default".into()), "preserve_frame_pointers" => *value == FlagValue::Bool(true), "enable_probestack" => *value == FlagValue::Bool(crate::config::probestack_supported(target.architecture)), @@ -419,6 +418,7 @@ impl Engine { | "probestack_size_log2" // probestack above asserted disabled | "regalloc" // shouldn't change semantics | "enable_incremental_compilation_cache_checks" // shouldn't change semantics + | "avoid_div_traps" // doesn't change the CLIF semantics | "enable_atomics" => return Ok(()), // Everything else is unknown and needs to be added somewhere to diff --git a/crates/wasmtime/src/engine/serialization.rs b/crates/wasmtime/src/engine/serialization.rs index 36063b49509f..f8b2f83e8e43 100644 --- a/crates/wasmtime/src/engine/serialization.rs +++ b/crates/wasmtime/src/engine/serialization.rs @@ -489,9 +489,10 @@ mod test { let engine = Engine::default(); let mut metadata = Metadata::new(&engine); - metadata - .shared_flags - .insert("avoid_div_traps".to_string(), FlagValue::Bool(false)); + metadata.shared_flags.insert( + "preserve_frame_pointers".to_string(), + FlagValue::Bool(false), + ); match metadata.check_compatible(&engine) { Ok(_) => unreachable!(), @@ -500,7 +501,7 @@ mod test { compilation settings of module incompatible with native host Caused by: - setting \"avoid_div_traps\" is configured to Bool(false) which is not supported" + setting \"preserve_frame_pointers\" is configured to Bool(false) which is not supported" )), } From 79b3636b5c04cd3dac77850ba03ae3ffb5373e09 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Wed, 15 Mar 2023 15:04:44 -0700 Subject: [PATCH 2/8] Remove the `avoid_div_traps` cranelift setting With no known users currently removing this should be possible and helps simplify the x64 backend. --- cranelift/codegen/meta/src/shared/settings.rs | 13 - cranelift/codegen/src/isa/s390x/inst.isle | 4 - cranelift/codegen/src/isa/s390x/lower.isle | 39 +- cranelift/codegen/src/isa/s390x/lower/isle.rs | 9 - cranelift/codegen/src/isa/x64/inst/emit.rs | 18 +- cranelift/codegen/src/isa/x64/lower.isle | 62 +- cranelift/codegen/src/machinst/isle.rs | 4 - cranelift/codegen/src/prelude_lower.isle | 3 - cranelift/codegen/src/settings.rs | 1 - .../filetests/isa/s390x/div-traps.clif | 727 ------------------ .../filetests/isa/x64/div-checks.clif | 6 +- .../filetests/isa/x64/sdiv-checked.clif | 285 ------- .../filetests/isa/x64/srem-checked.clif | 300 -------- .../filetests/isa/x64/udiv-checked.clif | 264 ------- .../filetests/isa/x64/urem-checked.clif | 280 ------- .../filetests/runtests/div-checks.clif | 7 +- .../filetests/filetests/runtests/srem.clif | 2 - .../filetests/filetests/runtests/urem.clif | 5 - crates/wasmtime/src/engine.rs | 1 - 19 files changed, 23 insertions(+), 2007 deletions(-) delete mode 100644 cranelift/filetests/filetests/isa/s390x/div-traps.clif delete mode 100644 cranelift/filetests/filetests/isa/x64/sdiv-checked.clif delete mode 100644 cranelift/filetests/filetests/isa/x64/srem-checked.clif delete mode 100644 cranelift/filetests/filetests/isa/x64/udiv-checked.clif delete mode 100644 cranelift/filetests/filetests/isa/x64/urem-checked.clif diff --git a/cranelift/codegen/meta/src/shared/settings.rs b/cranelift/codegen/meta/src/shared/settings.rs index 2db1f1303439..e68412183aee 100644 --- a/cranelift/codegen/meta/src/shared/settings.rs +++ b/cranelift/codegen/meta/src/shared/settings.rs @@ -97,19 +97,6 @@ pub(crate) fn define() -> SettingGroup { false, ); - settings.add_bool( - "avoid_div_traps", - "Generate explicit checks around native division instructions to avoid their trapping.", - r#" - Generate explicit checks around native division instructions to - avoid their trapping. - - On ISAs like ARM where the native division instructions don't trap, - this setting has no effect - explicit checks are always inserted. - "#, - false, - ); - settings.add_bool( "enable_float", "Enable the use of floating-point instructions.", diff --git a/cranelift/codegen/src/isa/s390x/inst.isle b/cranelift/codegen/src/isa/s390x/inst.isle index 4330b33e01df..92a95603720b 100644 --- a/cranelift/codegen/src/isa/s390x/inst.isle +++ b/cranelift/codegen/src/isa/s390x/inst.isle @@ -1446,10 +1446,6 @@ (decl vxrs_ext2_disabled () Type) (extern extractor vxrs_ext2_disabled vxrs_ext2_disabled) -(decl allow_div_traps () Type) -(extern extractor allow_div_traps allow_div_traps) - - ;; Helpers for SIMD lane number operations ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; There are two ways to map vector types onto the SIMD vector registers diff --git a/cranelift/codegen/src/isa/s390x/lower.isle b/cranelift/codegen/src/isa/s390x/lower.isle index 965074fa6982..1db1e8de3261 100644 --- a/cranelift/codegen/src/isa/s390x/lower.isle +++ b/cranelift/codegen/src/isa/s390x/lower.isle @@ -536,7 +536,6 @@ (rule (lower (has_type (fits_in_64 ty) (udiv x y))) (let (;; Look at the divisor to determine whether we need to generate ;; an explicit division-by zero check. - (DZcheck bool (zero_divisor_check_needed y)) ;; Load up the dividend, by loading the input (possibly zero- ;; extended) input into the low half of the register pair, ;; and setting the high half to zero. @@ -545,10 +544,6 @@ ;; Load up the divisor, zero-extended if necessary. (ext_y Reg (put_in_reg_zext32 y)) (ext_ty Type (ty_ext32 ty)) - ;; Now actually perform the division-by zero check if necessary. - ;; This cannot be done earlier than here, because the check - ;; requires an already extended divisor value. - (_ Reg (maybe_trap_if_zero_divisor DZcheck ext_ty ext_y)) ;; Emit the actual divide instruction. (pair RegPair (udivmod ext_ty ext_x ext_y))) ;; The quotient can be found in the low half of the result. @@ -557,38 +552,13 @@ ;; Implement `urem`. Same as `udiv`, but finds the remainder in ;; the high half of the result register pair instead. (rule (lower (has_type (fits_in_64 ty) (urem x y))) - (let ((DZcheck bool (zero_divisor_check_needed y)) - (ext_x RegPair (regpair (imm (ty_ext32 ty) 0) + (let ((ext_x RegPair (regpair (imm (ty_ext32 ty) 0) (put_in_reg_zext32 x))) (ext_y Reg (put_in_reg_zext32 y)) (ext_ty Type (ty_ext32 ty)) - (_ Reg (maybe_trap_if_zero_divisor DZcheck ext_ty ext_y)) (pair RegPair (udivmod ext_ty ext_x ext_y))) (copy_reg ty (regpair_hi pair)))) -;; Determine whether we need to perform a divide-by-zero-check. -;; -;; If the `avoid_div_traps` flag is false, we never need to perform -;; that check; we can rely on the divide instruction itself to trap. -;; -;; If the `avoid_div_traps` flag is true, we perform the check explicitly. -;; This still can be omittted if the divisor is a non-zero immediate. -(decl zero_divisor_check_needed (Value) bool) -(rule 2 (zero_divisor_check_needed (i64_from_value x)) - (if (i64_nonzero x)) - $false) -(rule 1 (zero_divisor_check_needed (value_type (allow_div_traps))) $false) -(rule 0 (zero_divisor_check_needed _) $true) - -;; Perform the divide-by-zero check if required. -;; This is simply a compare-and-trap of the (extended) divisor against 0. -(decl maybe_trap_if_zero_divisor (bool Type Reg) Reg) -(rule (maybe_trap_if_zero_divisor $false _ _) (invalid_reg)) -(rule (maybe_trap_if_zero_divisor $true ext_ty reg) - (icmps_simm16_and_trap ext_ty reg 0 - (intcc_as_cond (IntCC.Equal)) - (trap_code_division_by_zero))) - ;;;; Rules for `sdiv` and `srem` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -610,15 +580,12 @@ (rule (lower (has_type (fits_in_64 ty) (sdiv x y))) (let (;; Look at the divisor to determine whether we need to generate ;; explicit division-by-zero and/or integer-overflow checks. - (DZcheck bool (zero_divisor_check_needed y)) (OFcheck bool (div_overflow_check_needed y)) ;; Load up the dividend (sign-extended to 64-bit) (ext_x Reg (put_in_reg_sext64 x)) ;; Load up the divisor (sign-extended if necessary). (ext_y Reg (put_in_reg_sext32 y)) (ext_ty Type (ty_ext32 ty)) - ;; Perform division-by-zero check (same as for `udiv`). - (_ Reg (maybe_trap_if_zero_divisor DZcheck ext_ty ext_y)) ;; Perform integer-overflow check if necessary. (_ Reg (maybe_trap_if_sdiv_overflow OFcheck ext_ty ty ext_x ext_y)) ;; Emit the actual divide instruction. @@ -630,12 +597,10 @@ ;; the high half of the result register pair instead. Also, handle ;; the integer overflow case differently, see below. (rule (lower (has_type (fits_in_64 ty) (srem x y))) - (let ((DZcheck bool (zero_divisor_check_needed y)) - (OFcheck bool (div_overflow_check_needed y)) + (let ((OFcheck bool (div_overflow_check_needed y)) (ext_x Reg (put_in_reg_sext64 x)) (ext_y Reg (put_in_reg_sext32 y)) (ext_ty Type (ty_ext32 ty)) - (_ Reg (maybe_trap_if_zero_divisor DZcheck ext_ty ext_y)) (checked_x Reg (maybe_avoid_srem_overflow OFcheck ext_ty ext_x ext_y)) (pair RegPair (sdivmod ext_ty checked_x ext_y))) (copy_reg ty (regpair_hi pair)))) diff --git a/cranelift/codegen/src/isa/s390x/lower/isle.rs b/cranelift/codegen/src/isa/s390x/lower/isle.rs index 7baf0f5cf520..f32d38b79a61 100644 --- a/cranelift/codegen/src/isa/s390x/lower/isle.rs +++ b/cranelift/codegen/src/isa/s390x/lower/isle.rs @@ -291,15 +291,6 @@ impl generated_code::Context for IsleContext<'_, '_, MInst, S390xBackend> { Box::new(symbol_reloc.clone()) } - #[inline] - fn allow_div_traps(&mut self, _: Type) -> Option<()> { - if !self.backend.flags.avoid_div_traps() { - Some(()) - } else { - None - } - } - #[inline] fn mie2_enabled(&mut self, _: Type) -> Option<()> { if self.backend.isa_flags.has_mie2() { diff --git a/cranelift/codegen/src/isa/x64/inst/emit.rs b/cranelift/codegen/src/isa/x64/inst/emit.rs index 3e751e70362b..d59994de2524 100644 --- a/cranelift/codegen/src/isa/x64/inst/emit.rs +++ b/cranelift/codegen/src/isa/x64/inst/emit.rs @@ -454,16 +454,14 @@ pub(crate) fn emit( // the listed trap here is divide-by-zero. This means that only the // actual CLIF `sdiv` instruction ends up triggering the integer // overflow case. - if !info.flags.avoid_div_traps() { - sink.add_trap(if state.div_trap_is_divide_by_zero { - TrapCode::IntegerDivisionByZero - } else { - match sign { - DivSignedness::Signed => TrapCode::IntegerOverflow, - DivSignedness::Unsigned => TrapCode::IntegerDivisionByZero, - } - }); - } + sink.add_trap(if state.div_trap_is_divide_by_zero { + TrapCode::IntegerDivisionByZero + } else { + match sign { + DivSignedness::Signed => TrapCode::IntegerOverflow, + DivSignedness::Unsigned => TrapCode::IntegerDivisionByZero, + } + }); let subopcode = match sign { DivSignedness::Signed => 7, diff --git a/cranelift/codegen/src/isa/x64/lower.isle b/cranelift/codegen/src/isa/x64/lower.isle index 0dcbb3aaa3b8..bae3a0922609 100644 --- a/cranelift/codegen/src/isa/x64/lower.isle +++ b/cranelift/codegen/src/isa/x64/lower.isle @@ -3496,7 +3496,7 @@ ;; different shape. (rule 2 (lower (udiv a @ (value_type $I8) b)) (x64_div8 (extend_to_gpr a $I32 (ExtendKind.Zero)) - (validate_udiv_divisor $I8 b) + b (DivSignedness.Unsigned))) ;; 16-to-64-bit division is all done with a similar instruction and the only @@ -3505,32 +3505,10 @@ (rule 1 (lower (udiv a @ (value_type (fits_in_64 ty)) b)) (x64_div_quotient a (imm $I64 0) - (validate_udiv_divisor ty b) + b (raw_operand_size_of_type ty) (DivSignedness.Unsigned))) -;; Small helper which does nothing if `avoid_div_traps=false` because udiv -;; is allowed to trap and only has one trapping condition. Otherwise defers -;; to `nonzero_divisor` to perform an explicit check. -(decl validate_udiv_divisor (Type Value) Gpr) -(rule 1 (validate_udiv_divisor ty val) - (if-let $false (avoid_div_traps)) - val) -(rule (validate_udiv_divisor ty val) (nonzero_divisor ty val)) - -;; Helper to place `Value` into a `Gpr` while possibly trapping if it's zero. -(decl nonzero_divisor (Type Value) Gpr) -(rule 1 (nonzero_divisor ty (iconst (u64_from_imm64 (u64_nonzero n)))) - (imm ty n)) -(rule (nonzero_divisor ty val) - (let ( - (val Reg val) - (_ InstOutput (side_effect (with_flags_side_effect - (x64_test (raw_operand_size_of_type ty) val val) - (trap_if (CC.Z) (TrapCode.IntegerDivisionByZero))))) - ) - val)) - ;; Rules for `sdiv` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (rule 2 (lower (sdiv a @ (value_type $I8) b)) @@ -3557,20 +3535,14 @@ (if-let n (safe_divisor_from_imm64 ty imm)) (imm ty n)) -;; With `avoid_div_traps=false` then the div instruction is allowed to trap but -;; lowering still needs to differentiate each case. The divide-by-zero case -;; is explicitly checked here and then if div traps it's due to overflow. -;; -;; Note that check-for-zero happens here explicitly since it's a bit smaller to -;; codegen than to check for integer overflow (checking one reg vs two). (rule 2 (safe_sdiv_divisor ty a b) - (if-let $false (avoid_div_traps)) - (nonzero_divisor ty b)) - -;; The base cases here rely on some pseudo-instructions to do the checks to -;; jump around with labels and such. -(rule 1 (safe_sdiv_divisor $I64 a b) (validate_sdiv_divisor64 a b)) -(rule 0 (safe_sdiv_divisor ty a b) (validate_sdiv_divisor (raw_operand_size_of_type ty) a b)) + (let ( + (val Reg b) + (_ InstOutput (side_effect (with_flags_side_effect + (x64_test (raw_operand_size_of_type ty) val val) + (trap_if (CC.Z) (TrapCode.IntegerDivisionByZero))))) + ) + val)) ;; Rules for `urem` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -3579,7 +3551,6 @@ (rule 2 (lower (urem a @ (value_type $I8) b)) (let ( (a Gpr (extend_to_gpr a $I32 (ExtendKind.Zero))) - (b Gpr (validate_udiv_divisor $I8 b)) (result Gpr (x64_div8 a b (DivSignedness.Unsigned))) ) (x64_shr $I64 result (Imm8Reg.Imm8 8)))) @@ -3587,7 +3558,7 @@ (rule 1 (lower (urem a @ (value_type (fits_in_64 ty)) b)) (x64_div_remainder a (imm $I64 0) - (validate_udiv_divisor ty b) + b (raw_operand_size_of_type ty) (DivSignedness.Unsigned))) @@ -3619,28 +3590,15 @@ size (DivSignedness.Signed)))) -;; Note the usage of `validate_udiv_divisor` here and below which conditionally -;; checks for 0 depending on `avoid_div_traps`. If `div` can trap then despite -;; signed division having two trap conditions the srem sequence handles the -;; integer overflow case manually so the only trapping condition for this -;; instruction is divide-by-zero. This means that when `avoid_div_traps=true` -;; this must explicitly check for 0, and when `avoid_div_traps=false` the check -;; for 0 can be elided. -;; -;; No matter what the value is of `avoid_div_traps`, though, the divisor must -;; always be checked for -1. This happens inside of the `x64_checked_srem_seq*` -;; pseudo-instruction. (rule 1 (lower (srem a @ (value_type $I8) b)) (let ( (a Gpr (x64_sign_extend_data a (OperandSize.Size8))) - (b Gpr (validate_udiv_divisor $I8 b)) ) (x64_shr $I64 (x64_checked_srem_seq8 a b) (Imm8Reg.Imm8 8)))) (rule (lower (srem a @ (value_type ty) b)) (let ( (a Gpr a) - (b Gpr (validate_udiv_divisor ty b)) (size OperandSize (raw_operand_size_of_type ty)) (hi Gpr (x64_sign_extend_data a size)) (tmp ValueRegs (x64_checked_srem_seq size a hi b)) diff --git a/cranelift/codegen/src/machinst/isle.rs b/cranelift/codegen/src/machinst/isle.rs index ca39d0feb391..867102c32d6a 100644 --- a/cranelift/codegen/src/machinst/isle.rs +++ b/cranelift/codegen/src/machinst/isle.rs @@ -285,10 +285,6 @@ macro_rules! isle_lower_prelude_methods { } } - fn avoid_div_traps(&mut self) -> bool { - self.backend.flags().avoid_div_traps() - } - #[inline] fn tls_model(&mut self, _: Type) -> TlsModel { self.backend.flags().tls_model() diff --git a/cranelift/codegen/src/prelude_lower.isle b/cranelift/codegen/src/prelude_lower.isle index 8db2f73556e1..eab34154e065 100644 --- a/cranelift/codegen/src/prelude_lower.isle +++ b/cranelift/codegen/src/prelude_lower.isle @@ -530,9 +530,6 @@ ;;;; Helpers for accessing compilation flags ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -(decl pure avoid_div_traps () bool) -(extern constructor avoid_div_traps avoid_div_traps) - ;; This definition should be kept up to date with the values defined in ;; cranelift/codegen/meta/src/shared/settings.rs (type TlsModel extern (enum (None) (ElfGd) (Macho) (Coff))) diff --git a/cranelift/codegen/src/settings.rs b/cranelift/codegen/src/settings.rs index 5485779de817..44d2504dff75 100644 --- a/cranelift/codegen/src/settings.rs +++ b/cranelift/codegen/src/settings.rs @@ -532,7 +532,6 @@ use_egraphs = true enable_verifier = true is_pic = false use_colocated_libcalls = false -avoid_div_traps = false enable_float = true enable_nan_canonicalization = false enable_pinned_reg = false diff --git a/cranelift/filetests/filetests/isa/s390x/div-traps.clif b/cranelift/filetests/filetests/isa/s390x/div-traps.clif deleted file mode 100644 index 5b776de46cd0..000000000000 --- a/cranelift/filetests/filetests/isa/s390x/div-traps.clif +++ /dev/null @@ -1,727 +0,0 @@ -test compile precise-output -set avoid_div_traps=1 -target s390x - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; SDIV -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -function %sdiv_i64(i64, i64) -> i64 { -block0(v0: i64, v1: i64): - v2 = sdiv.i64 v0, v1 - return v2 -} - -; VCode: -; block0: -; cgite %r3, 0 -; llihf %r4, 2147483647 -; iilf %r4, 4294967295 -; xgr %r4, %r2 -; lgr %r5, %r2 -; ngr %r4, %r3 -; lgr %r2, %r3 -; cgite %r4, -1 -; lgr %r4, %r2 -; lgr %r3, %r5 -; dsgr %r2, %r4 -; lgr %r2, %r3 -; br %r14 -; -; Disassembled: -; block0: ; offset 0x0 -; cgite %r3, 0 ; trap: int_divz -; llihf %r4, 0x7fffffff -; iilf %r4, 0xffffffff -; xgr %r4, %r2 -; lgr %r5, %r2 -; ngr %r4, %r3 -; lgr %r2, %r3 -; cgite %r4, -1 ; trap: int_ovf -; lgr %r4, %r2 -; lgr %r3, %r5 -; dsgr %r2, %r4 ; trap: int_divz -; lgr %r2, %r3 -; br %r14 - -function %sdiv_i64_imm(i64) -> i64 { -block0(v0: i64): - v1 = iconst.i64 2 - v2 = sdiv.i64 v0, v1 - return v2 -} - -; VCode: -; block0: -; lgr %r3, %r2 -; lghi %r4, 2 -; dsgr %r2, %r4 -; lgr %r2, %r3 -; br %r14 -; -; Disassembled: -; block0: ; offset 0x0 -; lgr %r3, %r2 -; lghi %r4, 2 -; dsgr %r2, %r4 ; trap: int_divz -; lgr %r2, %r3 -; br %r14 - -function %sdiv_i32(i32, i32) -> i32 { -block0(v0: i32, v1: i32): - v2 = sdiv.i32 v0, v1 - return v2 -} - -; VCode: -; stmg %r7, %r15, 56(%r15) -; block0: -; lgfr %r5, %r2 -; lgr %r7, %r5 -; cite %r3, 0 -; iilf %r5, 2147483647 -; lgr %r4, %r7 -; xrk %r2, %r5, %r4 -; nrk %r4, %r2, %r3 -; lgr %r5, %r3 -; cite %r4, -1 -; lgr %r3, %r7 -; dsgfr %r2, %r5 -; lgr %r2, %r3 -; lmg %r7, %r15, 56(%r15) -; br %r14 -; -; Disassembled: -; block0: ; offset 0x0 -; stmg %r7, %r15, 0x38(%r15) -; block1: ; offset 0x6 -; lgfr %r5, %r2 -; lgr %r7, %r5 -; cite %r3, 0 ; trap: int_divz -; iilf %r5, 0x7fffffff -; lgr %r4, %r7 -; xrk %r2, %r5, %r4 -; nrk %r4, %r2, %r3 -; lgr %r5, %r3 -; cite %r4, -1 ; trap: int_ovf -; lgr %r3, %r7 -; dsgfr %r2, %r5 ; trap: int_divz -; lgr %r2, %r3 -; lmg %r7, %r15, 0x38(%r15) -; br %r14 - -function %sdiv_i32_imm(i32) -> i32 { -block0(v0: i32): - v1 = iconst.i32 2 - v2 = sdiv.i32 v0, v1 - return v2 -} - -; VCode: -; block0: -; lgfr %r3, %r2 -; lhi %r2, 2 -; dsgfr %r2, %r2 -; lgr %r2, %r3 -; br %r14 -; -; Disassembled: -; block0: ; offset 0x0 -; lgfr %r3, %r2 -; lhi %r2, 2 -; dsgfr %r2, %r2 ; trap: int_divz -; lgr %r2, %r3 -; br %r14 - -function %sdiv_i16(i16, i16) -> i16 { -block0(v0: i16, v1: i16): - v2 = sdiv.i16 v0, v1 - return v2 -} - -; VCode: -; block0: -; lghr %r5, %r2 -; lhr %r4, %r3 -; cite %r4, 0 -; lhi %r2, 32767 -; lgr %r3, %r5 -; xrk %r5, %r2, %r3 -; nrk %r2, %r5, %r4 -; cite %r2, -1 -; dsgfr %r2, %r4 -; lgr %r2, %r3 -; br %r14 -; -; Disassembled: -; block0: ; offset 0x0 -; lghr %r5, %r2 -; lhr %r4, %r3 -; cite %r4, 0 ; trap: int_divz -; lhi %r2, 0x7fff -; lgr %r3, %r5 -; xrk %r5, %r2, %r3 -; nrk %r2, %r5, %r4 -; cite %r2, -1 ; trap: int_ovf -; dsgfr %r2, %r4 ; trap: int_divz -; lgr %r2, %r3 -; br %r14 - -function %sdiv_i16_imm(i16) -> i16 { -block0(v0: i16): - v1 = iconst.i16 2 - v2 = sdiv.i16 v0, v1 - return v2 -} - -; VCode: -; block0: -; lghr %r3, %r2 -; lhi %r2, 2 -; dsgfr %r2, %r2 -; lgr %r2, %r3 -; br %r14 -; -; Disassembled: -; block0: ; offset 0x0 -; lghr %r3, %r2 -; lhi %r2, 2 -; dsgfr %r2, %r2 ; trap: int_divz -; lgr %r2, %r3 -; br %r14 - -function %sdiv_i8(i8, i8) -> i8 { -block0(v0: i8, v1: i8): - v2 = sdiv.i8 v0, v1 - return v2 -} - -; VCode: -; block0: -; lgbr %r5, %r2 -; lbr %r4, %r3 -; cite %r4, 0 -; lhi %r2, 127 -; lgr %r3, %r5 -; xrk %r5, %r2, %r3 -; nrk %r2, %r5, %r4 -; cite %r2, -1 -; dsgfr %r2, %r4 -; lgr %r2, %r3 -; br %r14 -; -; Disassembled: -; block0: ; offset 0x0 -; lgbr %r5, %r2 -; lbr %r4, %r3 -; cite %r4, 0 ; trap: int_divz -; lhi %r2, 0x7f -; lgr %r3, %r5 -; xrk %r5, %r2, %r3 -; nrk %r2, %r5, %r4 -; cite %r2, -1 ; trap: int_ovf -; dsgfr %r2, %r4 ; trap: int_divz -; lgr %r2, %r3 -; br %r14 - -function %sdiv_i8_imm(i8) -> i8 { -block0(v0: i8): - v1 = iconst.i8 2 - v2 = sdiv.i8 v0, v1 - return v2 -} - -; VCode: -; block0: -; lgbr %r3, %r2 -; lhi %r2, 2 -; dsgfr %r2, %r2 -; lgr %r2, %r3 -; br %r14 -; -; Disassembled: -; block0: ; offset 0x0 -; lgbr %r3, %r2 -; lhi %r2, 2 -; dsgfr %r2, %r2 ; trap: int_divz -; lgr %r2, %r3 -; br %r14 - -function %udiv_i64(i64, i64) -> i64 { -block0(v0: i64, v1: i64): - v2 = udiv.i64 v0, v1 - return v2 -} - -; VCode: -; block0: -; lgr %r5, %r2 -; lghi %r2, 0 -; cgite %r3, 0 -; lgr %r4, %r3 -; lgr %r3, %r5 -; lgr %r5, %r4 -; dlgr %r2, %r5 -; lgr %r2, %r3 -; br %r14 -; -; Disassembled: -; block0: ; offset 0x0 -; lgr %r5, %r2 -; lghi %r2, 0 -; cgite %r3, 0 ; trap: int_divz -; lgr %r4, %r3 -; lgr %r3, %r5 -; lgr %r5, %r4 -; dlgr %r2, %r5 ; trap: int_divz -; lgr %r2, %r3 -; br %r14 - -function %udiv_i64_imm(i64) -> i64 { -block0(v0: i64): - v1 = iconst.i64 2 - v2 = udiv.i64 v0, v1 - return v2 -} - -; VCode: -; block0: -; lgr %r3, %r2 -; lghi %r2, 0 -; lghi %r4, 2 -; dlgr %r2, %r4 -; lgr %r2, %r3 -; br %r14 -; -; Disassembled: -; block0: ; offset 0x0 -; lgr %r3, %r2 -; lghi %r2, 0 -; lghi %r4, 2 -; dlgr %r2, %r4 ; trap: int_divz -; lgr %r2, %r3 -; br %r14 - -function %udiv_i32(i32, i32) -> i32 { -block0(v0: i32, v1: i32): - v2 = udiv.i32 v0, v1 - return v2 -} - -; VCode: -; block0: -; lgr %r5, %r2 -; lhi %r2, 0 -; cite %r3, 0 -; lgr %r4, %r3 -; lgr %r3, %r5 -; lgr %r5, %r4 -; dlr %r2, %r5 -; lgr %r2, %r3 -; br %r14 -; -; Disassembled: -; block0: ; offset 0x0 -; lgr %r5, %r2 -; lhi %r2, 0 -; cite %r3, 0 ; trap: int_divz -; lgr %r4, %r3 -; lgr %r3, %r5 -; lgr %r5, %r4 -; dlr %r2, %r5 ; trap: int_divz -; lgr %r2, %r3 -; br %r14 - -function %udiv_i32_imm(i32) -> i32 { -block0(v0: i32): - v1 = iconst.i32 2 - v2 = udiv.i32 v0, v1 - return v2 -} - -; VCode: -; block0: -; lgr %r3, %r2 -; lhi %r2, 0 -; lhi %r4, 2 -; dlr %r2, %r4 -; lgr %r2, %r3 -; br %r14 -; -; Disassembled: -; block0: ; offset 0x0 -; lgr %r3, %r2 -; lhi %r2, 0 -; lhi %r4, 2 -; dlr %r2, %r4 ; trap: int_divz -; lgr %r2, %r3 -; br %r14 - -function %udiv_i16(i16, i16) -> i16 { -block0(v0: i16, v1: i16): - v2 = udiv.i16 v0, v1 - return v2 -} - -; VCode: -; stmg %r8, %r15, 64(%r15) -; block0: -; lgr %r4, %r3 -; lhi %r5, 0 -; lgr %r8, %r5 -; llhr %r3, %r2 -; lgr %r5, %r4 -; llhr %r5, %r5 -; cite %r5, 0 -; lgr %r2, %r8 -; dlr %r2, %r5 -; lgr %r2, %r3 -; lmg %r8, %r15, 64(%r15) -; br %r14 -; -; Disassembled: -; block0: ; offset 0x0 -; stmg %r8, %r15, 0x40(%r15) -; block1: ; offset 0x6 -; lgr %r4, %r3 -; lhi %r5, 0 -; lgr %r8, %r5 -; llhr %r3, %r2 -; lgr %r5, %r4 -; llhr %r5, %r5 -; cite %r5, 0 ; trap: int_divz -; lgr %r2, %r8 -; dlr %r2, %r5 ; trap: int_divz -; lgr %r2, %r3 -; lmg %r8, %r15, 0x40(%r15) -; br %r14 - -function %udiv_i16_imm(i16) -> i16 { -block0(v0: i16): - v1 = iconst.i16 2 - v2 = udiv.i16 v0, v1 - return v2 -} - -; VCode: -; block0: -; lhi %r4, 0 -; lgr %r5, %r4 -; llhr %r3, %r2 -; lhi %r4, 2 -; lgr %r2, %r5 -; dlr %r2, %r4 -; lgr %r2, %r3 -; br %r14 -; -; Disassembled: -; block0: ; offset 0x0 -; lhi %r4, 0 -; lgr %r5, %r4 -; llhr %r3, %r2 -; lhi %r4, 2 -; lgr %r2, %r5 -; dlr %r2, %r4 ; trap: int_divz -; lgr %r2, %r3 -; br %r14 - -function %udiv_i8(i8, i8) -> i8 { -block0(v0: i8, v1: i8): - v2 = udiv.i8 v0, v1 - return v2 -} - -; VCode: -; stmg %r8, %r15, 64(%r15) -; block0: -; lgr %r4, %r3 -; lhi %r5, 0 -; lgr %r8, %r5 -; llcr %r3, %r2 -; lgr %r5, %r4 -; llcr %r5, %r5 -; cite %r5, 0 -; lgr %r2, %r8 -; dlr %r2, %r5 -; lgr %r2, %r3 -; lmg %r8, %r15, 64(%r15) -; br %r14 -; -; Disassembled: -; block0: ; offset 0x0 -; stmg %r8, %r15, 0x40(%r15) -; block1: ; offset 0x6 -; lgr %r4, %r3 -; lhi %r5, 0 -; lgr %r8, %r5 -; llcr %r3, %r2 -; lgr %r5, %r4 -; llcr %r5, %r5 -; cite %r5, 0 ; trap: int_divz -; lgr %r2, %r8 -; dlr %r2, %r5 ; trap: int_divz -; lgr %r2, %r3 -; lmg %r8, %r15, 0x40(%r15) -; br %r14 - -function %udiv_i8_imm(i8) -> i8 { -block0(v0: i8): - v1 = iconst.i8 2 - v2 = udiv.i8 v0, v1 - return v2 -} - -; VCode: -; block0: -; lhi %r4, 0 -; lgr %r5, %r4 -; llcr %r3, %r2 -; lhi %r4, 2 -; lgr %r2, %r5 -; dlr %r2, %r4 -; lgr %r2, %r3 -; br %r14 -; -; Disassembled: -; block0: ; offset 0x0 -; lhi %r4, 0 -; lgr %r5, %r4 -; llcr %r3, %r2 -; lhi %r4, 2 -; lgr %r2, %r5 -; dlr %r2, %r4 ; trap: int_divz -; lgr %r2, %r3 -; br %r14 - -function %srem_i64(i64, i64) -> i64 { -block0(v0: i64, v1: i64): - v2 = srem.i64 v0, v1 - return v2 -} - -; VCode: -; block0: -; cgite %r3, 0 -; cghi %r3, -1 -; lgr %r4, %r3 -; lgr %r3, %r2 -; locghie %r3, 0 -; dsgr %r2, %r4 -; br %r14 -; -; Disassembled: -; block0: ; offset 0x0 -; cgite %r3, 0 ; trap: int_divz -; cghi %r3, -1 -; lgr %r4, %r3 -; lgr %r3, %r2 -; locghie %r3, 0 -; dsgr %r2, %r4 ; trap: int_divz -; br %r14 - -function %srem_i32(i32, i32) -> i32 { -block0(v0: i32, v1: i32): - v2 = srem.i32 v0, v1 - return v2 -} - -; VCode: -; block0: -; lgr %r5, %r3 -; lgfr %r3, %r2 -; lgr %r2, %r5 -; cite %r2, 0 -; dsgfr %r2, %r2 -; br %r14 -; -; Disassembled: -; block0: ; offset 0x0 -; lgr %r5, %r3 -; lgfr %r3, %r2 -; lgr %r2, %r5 -; cite %r2, 0 ; trap: int_divz -; dsgfr %r2, %r2 ; trap: int_divz -; br %r14 - -function %srem_i16(i16, i16) -> i16 { -block0(v0: i16, v1: i16): - v2 = srem.i16 v0, v1 - return v2 -} - -; VCode: -; block0: -; lghr %r5, %r2 -; lgr %r2, %r5 -; lhr %r4, %r3 -; cite %r4, 0 -; lgr %r3, %r2 -; dsgfr %r2, %r4 -; br %r14 -; -; Disassembled: -; block0: ; offset 0x0 -; lghr %r5, %r2 -; lgr %r2, %r5 -; lhr %r4, %r3 -; cite %r4, 0 ; trap: int_divz -; lgr %r3, %r2 -; dsgfr %r2, %r4 ; trap: int_divz -; br %r14 - -function %srem_i8(i8, i8) -> i8 { -block0(v0: i8, v1: i8): - v2 = srem.i8 v0, v1 - return v2 -} - -; VCode: -; block0: -; lgbr %r5, %r2 -; lgr %r2, %r5 -; lbr %r4, %r3 -; cite %r4, 0 -; lgr %r3, %r2 -; dsgfr %r2, %r4 -; br %r14 -; -; Disassembled: -; block0: ; offset 0x0 -; lgbr %r5, %r2 -; lgr %r2, %r5 -; lbr %r4, %r3 -; cite %r4, 0 ; trap: int_divz -; lgr %r3, %r2 -; dsgfr %r2, %r4 ; trap: int_divz -; br %r14 - -function %urem_i64(i64, i64) -> i64 { -block0(v0: i64, v1: i64): - v2 = urem.i64 v0, v1 - return v2 -} - -; VCode: -; block0: -; lgr %r5, %r2 -; lghi %r2, 0 -; cgite %r3, 0 -; lgr %r4, %r3 -; lgr %r3, %r5 -; lgr %r5, %r4 -; dlgr %r2, %r5 -; br %r14 -; -; Disassembled: -; block0: ; offset 0x0 -; lgr %r5, %r2 -; lghi %r2, 0 -; cgite %r3, 0 ; trap: int_divz -; lgr %r4, %r3 -; lgr %r3, %r5 -; lgr %r5, %r4 -; dlgr %r2, %r5 ; trap: int_divz -; br %r14 - -function %urem_i32(i32, i32) -> i32 { -block0(v0: i32, v1: i32): - v2 = urem.i32 v0, v1 - return v2 -} - -; VCode: -; block0: -; lgr %r5, %r2 -; lhi %r2, 0 -; cite %r3, 0 -; lgr %r4, %r3 -; lgr %r3, %r5 -; lgr %r5, %r4 -; dlr %r2, %r5 -; br %r14 -; -; Disassembled: -; block0: ; offset 0x0 -; lgr %r5, %r2 -; lhi %r2, 0 -; cite %r3, 0 ; trap: int_divz -; lgr %r4, %r3 -; lgr %r3, %r5 -; lgr %r5, %r4 -; dlr %r2, %r5 ; trap: int_divz -; br %r14 - -function %urem_i16(i16, i16) -> i16 { -block0(v0: i16, v1: i16): - v2 = urem.i16 v0, v1 - return v2 -} - -; VCode: -; stmg %r8, %r15, 64(%r15) -; block0: -; lgr %r4, %r3 -; lhi %r5, 0 -; lgr %r8, %r5 -; llhr %r3, %r2 -; lgr %r5, %r4 -; llhr %r5, %r5 -; cite %r5, 0 -; lgr %r2, %r8 -; dlr %r2, %r5 -; lmg %r8, %r15, 64(%r15) -; br %r14 -; -; Disassembled: -; block0: ; offset 0x0 -; stmg %r8, %r15, 0x40(%r15) -; block1: ; offset 0x6 -; lgr %r4, %r3 -; lhi %r5, 0 -; lgr %r8, %r5 -; llhr %r3, %r2 -; lgr %r5, %r4 -; llhr %r5, %r5 -; cite %r5, 0 ; trap: int_divz -; lgr %r2, %r8 -; dlr %r2, %r5 ; trap: int_divz -; lmg %r8, %r15, 0x40(%r15) -; br %r14 - -function %urem_i8(i8, i8) -> i8 { -block0(v0: i8, v1: i8): - v2 = urem.i8 v0, v1 - return v2 -} - -; VCode: -; stmg %r8, %r15, 64(%r15) -; block0: -; lgr %r4, %r3 -; lhi %r5, 0 -; lgr %r8, %r5 -; llcr %r3, %r2 -; lgr %r5, %r4 -; llcr %r5, %r5 -; cite %r5, 0 -; lgr %r2, %r8 -; dlr %r2, %r5 -; lmg %r8, %r15, 64(%r15) -; br %r14 -; -; Disassembled: -; block0: ; offset 0x0 -; stmg %r8, %r15, 0x40(%r15) -; block1: ; offset 0x6 -; lgr %r4, %r3 -; lhi %r5, 0 -; lgr %r8, %r5 -; llcr %r3, %r2 -; lgr %r5, %r4 -; llcr %r5, %r5 -; cite %r5, 0 ; trap: int_divz -; lgr %r2, %r8 -; dlr %r2, %r5 ; trap: int_divz -; lmg %r8, %r15, 0x40(%r15) -; br %r14 - diff --git a/cranelift/filetests/filetests/isa/x64/div-checks.clif b/cranelift/filetests/filetests/isa/x64/div-checks.clif index 381a66b63cb4..9dd90788c0e8 100644 --- a/cranelift/filetests/filetests/isa/x64/div-checks.clif +++ b/cranelift/filetests/filetests/isa/x64/div-checks.clif @@ -1,10 +1,8 @@ test compile precise-output -set avoid_div_traps=false target x86_64 -;; We should get the checked-div/rem sequence (`srem` pseudoinst below) even -;; when `avoid_div_traps` above is false (i.e. even when the host is normally -;; willing to accept SIGFPEs as Wasm traps). The machine will SIGFPE in some +;; We should get the checked-div/rem sequence (`srem` pseudoinst below). +;; The machine will SIGFPE in some ;; cases when `srem` is valid (specifically -INT_MIN % -1). function %i8(i8, i8) -> i8 { diff --git a/cranelift/filetests/filetests/isa/x64/sdiv-checked.clif b/cranelift/filetests/filetests/isa/x64/sdiv-checked.clif deleted file mode 100644 index 7dd3771c1f34..000000000000 --- a/cranelift/filetests/filetests/isa/x64/sdiv-checked.clif +++ /dev/null @@ -1,285 +0,0 @@ -test compile precise-output -set avoid_div_traps=true -target x86_64 - -function %f1(i8, i8) -> i8 { -block0(v0: i8, v1: i8): - v2 = sdiv v0, v1 - return v2 -} - -; VCode: -; pushq %rbp -; movq %rsp, %rbp -; block0: -; movq %rdi, %rax -; cbw %al, %al -; validate_sdiv_divisor %sil, %al -; idiv %al, %sil, %al -; movq %rbp, %rsp -; popq %rbp -; ret -; -; Disassembled: -; block0: ; offset 0x0 -; pushq %rbp -; movq %rsp, %rbp -; block1: ; offset 0x4 -; movq %rdi, %rax -; cbtw -; cmpb $0, %sil -; jne 0x15 -; ud2 ; trap: int_divz -; cmpb $0xff, %sil -; jne 0x2a -; cmpb $0x80, %al -; jne 0x2a -; ud2 ; trap: int_ovf -; idivb %sil -; movq %rbp, %rsp -; popq %rbp -; retq - -function %f2(i16, i16) -> i16 { -block0(v0: i16, v1: i16): - v2 = sdiv v0, v1 - return v2 -} - -; VCode: -; pushq %rbp -; movq %rsp, %rbp -; block0: -; validate_sdiv_divisor %si, %di -; movq %rdi, %rax -; cwd %ax, %dx -; idiv %ax, %dx, %si, %ax, %dx -; movq %rbp, %rsp -; popq %rbp -; ret -; -; Disassembled: -; block0: ; offset 0x0 -; pushq %rbp -; movq %rsp, %rbp -; block1: ; offset 0x4 -; cmpw $0, %si -; jne 0x10 -; ud2 ; trap: int_divz -; cmpw $-1, %si -; jne 0x27 -; cmpw $0x8000, %di -; jne 0x27 -; ud2 ; trap: int_ovf -; movq %rdi, %rax -; cwtd -; idivw %si -; movq %rbp, %rsp -; popq %rbp -; retq - -function %f3(i32, i32) -> i32 { -block0(v0: i32, v1: i32): - v2 = sdiv v0, v1 - return v2 -} - -; VCode: -; pushq %rbp -; movq %rsp, %rbp -; block0: -; validate_sdiv_divisor %esi, %edi -; movq %rdi, %rax -; cdq %eax, %edx -; idiv %eax, %edx, %esi, %eax, %edx -; movq %rbp, %rsp -; popq %rbp -; ret -; -; Disassembled: -; block0: ; offset 0x0 -; pushq %rbp -; movq %rsp, %rbp -; block1: ; offset 0x4 -; cmpl $0, %esi -; jne 0xf -; ud2 ; trap: int_divz -; cmpl $-1, %esi -; jne 0x26 -; cmpl $0x80000000, %edi -; jne 0x26 -; ud2 ; trap: int_ovf -; movq %rdi, %rax -; cltd -; idivl %esi -; movq %rbp, %rsp -; popq %rbp -; retq - -function %f4(i64, i64) -> i64 { -block0(v0: i64, v1: i64): - v2 = sdiv v0, v1 - return v2 -} - -; VCode: -; pushq %rbp -; movq %rsp, %rbp -; block0: -; validate_sdiv_divisor %rsi, %rdi %rcx -; movq %rdi, %rax -; cqo %rax, %rdx -; idiv %rax, %rdx, %rsi, %rax, %rdx -; movq %rbp, %rsp -; popq %rbp -; ret -; -; Disassembled: -; block0: ; offset 0x0 -; pushq %rbp -; movq %rsp, %rbp -; block1: ; offset 0x4 -; cmpq $0, %rsi -; jne 0x10 -; ud2 ; trap: int_divz -; cmpq $-1, %rsi -; jne 0x2f -; movabsq $9223372036854775808, %rcx -; cmpq %rcx, %rdi -; jne 0x2f -; ud2 ; trap: int_ovf -; movq %rdi, %rax -; cqto -; idivq %rsi -; movq %rbp, %rsp -; popq %rbp -; retq - -function %i8_imm(i8) -> i8 { -block0(v0: i8): - v1 = iconst.i8 17 - v2 = sdiv v0, v1 - return v2 -} - -; VCode: -; pushq %rbp -; movq %rsp, %rbp -; block0: -; movq %rdi, %rax -; cbw %al, %al -; movl $17, %edx -; idiv %al, %dl, %al -; movq %rbp, %rsp -; popq %rbp -; ret -; -; Disassembled: -; block0: ; offset 0x0 -; pushq %rbp -; movq %rsp, %rbp -; block1: ; offset 0x4 -; movq %rdi, %rax -; cbtw -; movl $0x11, %edx -; idivb %dl -; movq %rbp, %rsp -; popq %rbp -; retq - -function %i16_imm(i16) -> i16 { -block0(v0: i16): - v1 = iconst.i16 17 - v2 = sdiv v0, v1 - return v2 -} - -; VCode: -; pushq %rbp -; movq %rsp, %rbp -; block0: -; movl $17, %ecx -; movq %rdi, %rax -; cwd %ax, %dx -; idiv %ax, %dx, %cx, %ax, %dx -; movq %rbp, %rsp -; popq %rbp -; ret -; -; Disassembled: -; block0: ; offset 0x0 -; pushq %rbp -; movq %rsp, %rbp -; block1: ; offset 0x4 -; movl $0x11, %ecx -; movq %rdi, %rax -; cwtd -; idivw %cx -; movq %rbp, %rsp -; popq %rbp -; retq - -function %i32_imm(i32) -> i32 { -block0(v0: i32): - v1 = iconst.i32 17 - v2 = sdiv v0, v1 - return v2 -} - -; VCode: -; pushq %rbp -; movq %rsp, %rbp -; block0: -; movl $17, %ecx -; movq %rdi, %rax -; cdq %eax, %edx -; idiv %eax, %edx, %ecx, %eax, %edx -; movq %rbp, %rsp -; popq %rbp -; ret -; -; Disassembled: -; block0: ; offset 0x0 -; pushq %rbp -; movq %rsp, %rbp -; block1: ; offset 0x4 -; movl $0x11, %ecx -; movq %rdi, %rax -; cltd -; idivl %ecx -; movq %rbp, %rsp -; popq %rbp -; retq - -function %i64_imm(i64) -> i64 { -block0(v0: i64): - v1 = iconst.i64 17 - v2 = sdiv v0, v1 - return v2 -} - -; VCode: -; pushq %rbp -; movq %rsp, %rbp -; block0: -; movl $17, %ecx -; movq %rdi, %rax -; cqo %rax, %rdx -; idiv %rax, %rdx, %rcx, %rax, %rdx -; movq %rbp, %rsp -; popq %rbp -; ret -; -; Disassembled: -; block0: ; offset 0x0 -; pushq %rbp -; movq %rsp, %rbp -; block1: ; offset 0x4 -; movl $0x11, %ecx -; movq %rdi, %rax -; cqto -; idivq %rcx -; movq %rbp, %rsp -; popq %rbp -; retq - diff --git a/cranelift/filetests/filetests/isa/x64/srem-checked.clif b/cranelift/filetests/filetests/isa/x64/srem-checked.clif deleted file mode 100644 index a79131231b33..000000000000 --- a/cranelift/filetests/filetests/isa/x64/srem-checked.clif +++ /dev/null @@ -1,300 +0,0 @@ -test compile precise-output -set avoid_div_traps=true -target x86_64 - -function %f1(i8, i8) -> i8 { -block0(v0: i8, v1: i8): - v2 = srem v0, v1 - return v2 -} - -; VCode: -; pushq %rbp -; movq %rsp, %rbp -; block0: -; movq %rdi, %rax -; cbw %al, %al -; testb %sil, %sil -; jnz ; ud2 int_divz ; -; checked_srem_seq %al, %sil, %al -; shrq $8, %rax, %rax -; movq %rbp, %rsp -; popq %rbp -; ret -; -; Disassembled: -; block0: ; offset 0x0 -; pushq %rbp -; movq %rsp, %rbp -; block1: ; offset 0x4 -; movq %rdi, %rax -; cbtw -; testb %sil, %sil -; jne 0x14 -; ud2 ; trap: int_divz -; cmpb $0xff, %sil -; jne 0x28 -; movl $0, %eax -; jmp 0x2b -; idivb %sil -; shrq $8, %rax -; movq %rbp, %rsp -; popq %rbp -; retq - -function %f2(i16, i16) -> i16 { -block0(v0: i16, v1: i16): - v2 = srem v0, v1 - return v2 -} - -; VCode: -; pushq %rbp -; movq %rsp, %rbp -; block0: -; testw %si, %si -; jnz ; ud2 int_divz ; -; movq %rdi, %rax -; cwd %ax, %dx -; checked_srem_seq %ax, %dx, %si, %ax, %dx -; movq %rdx, %rax -; movq %rbp, %rsp -; popq %rbp -; ret -; -; Disassembled: -; block0: ; offset 0x0 -; pushq %rbp -; movq %rsp, %rbp -; block1: ; offset 0x4 -; testw %si, %si -; jne 0xf -; ud2 ; trap: int_divz -; movq %rdi, %rax -; cwtd -; cmpw $-1, %si -; jne 0x28 -; movl $0, %edx -; jmp 0x2b -; idivw %si -; movq %rdx, %rax -; movq %rbp, %rsp -; popq %rbp -; retq - -function %f3(i32, i32) -> i32 { -block0(v0: i32, v1: i32): - v2 = srem v0, v1 - return v2 -} - -; VCode: -; pushq %rbp -; movq %rsp, %rbp -; block0: -; testl %esi, %esi -; jnz ; ud2 int_divz ; -; movq %rdi, %rax -; cdq %eax, %edx -; checked_srem_seq %eax, %edx, %esi, %eax, %edx -; movq %rdx, %rax -; movq %rbp, %rsp -; popq %rbp -; ret -; -; Disassembled: -; block0: ; offset 0x0 -; pushq %rbp -; movq %rsp, %rbp -; block1: ; offset 0x4 -; testl %esi, %esi -; jne 0xe -; ud2 ; trap: int_divz -; movq %rdi, %rax -; cltd -; cmpl $-1, %esi -; jne 0x25 -; movl $0, %edx -; jmp 0x27 -; idivl %esi -; movq %rdx, %rax -; movq %rbp, %rsp -; popq %rbp -; retq - -function %f4(i64, i64) -> i64 { -block0(v0: i64, v1: i64): - v2 = srem v0, v1 - return v2 -} - -; VCode: -; pushq %rbp -; movq %rsp, %rbp -; block0: -; testq %rsi, %rsi -; jnz ; ud2 int_divz ; -; movq %rdi, %rax -; cqo %rax, %rdx -; checked_srem_seq %rax, %rdx, %rsi, %rax, %rdx -; movq %rdx, %rax -; movq %rbp, %rsp -; popq %rbp -; ret -; -; Disassembled: -; block0: ; offset 0x0 -; pushq %rbp -; movq %rsp, %rbp -; block1: ; offset 0x4 -; testq %rsi, %rsi -; jne 0xf -; ud2 ; trap: int_divz -; movq %rdi, %rax -; cqto -; cmpq $-1, %rsi -; jne 0x28 -; movl $0, %edx -; jmp 0x2b -; idivq %rsi -; movq %rdx, %rax -; movq %rbp, %rsp -; popq %rbp -; retq - -function %i8_imm(i8) -> i8 { -block0(v0: i8): - v1 = iconst.i8 17 - v2 = srem v0, v1 - return v2 -} - -; VCode: -; pushq %rbp -; movq %rsp, %rbp -; block0: -; movq %rdi, %rax -; cbw %al, %al -; movl $17, %edx -; idiv %al, %dl, %al -; shrq $8, %rax, %rax -; movq %rbp, %rsp -; popq %rbp -; ret -; -; Disassembled: -; block0: ; offset 0x0 -; pushq %rbp -; movq %rsp, %rbp -; block1: ; offset 0x4 -; movq %rdi, %rax -; cbtw -; movl $0x11, %edx -; idivb %dl -; shrq $8, %rax -; movq %rbp, %rsp -; popq %rbp -; retq - -function %i16_imm(i16) -> i16 { -block0(v0: i16): - v1 = iconst.i16 17 - v2 = srem v0, v1 - return v2 -} - -; VCode: -; pushq %rbp -; movq %rsp, %rbp -; block0: -; movq %rdi, %rax -; cwd %ax, %dx -; movl $17, %r8d -; idiv %ax, %dx, %r8w, %ax, %dx -; movq %rdx, %rax -; movq %rbp, %rsp -; popq %rbp -; ret -; -; Disassembled: -; block0: ; offset 0x0 -; pushq %rbp -; movq %rsp, %rbp -; block1: ; offset 0x4 -; movq %rdi, %rax -; cwtd -; movl $0x11, %r8d -; idivw %r8w -; movq %rdx, %rax -; movq %rbp, %rsp -; popq %rbp -; retq - -function %i32_imm(i32) -> i32 { -block0(v0: i32): - v1 = iconst.i32 17 - v2 = srem v0, v1 - return v2 -} - -; VCode: -; pushq %rbp -; movq %rsp, %rbp -; block0: -; movq %rdi, %rax -; cdq %eax, %edx -; movl $17, %r8d -; idiv %eax, %edx, %r8d, %eax, %edx -; movq %rdx, %rax -; movq %rbp, %rsp -; popq %rbp -; ret -; -; Disassembled: -; block0: ; offset 0x0 -; pushq %rbp -; movq %rsp, %rbp -; block1: ; offset 0x4 -; movq %rdi, %rax -; cltd -; movl $0x11, %r8d -; idivl %r8d -; movq %rdx, %rax -; movq %rbp, %rsp -; popq %rbp -; retq - -function %i64_imm(i64) -> i64 { -block0(v0: i64): - v1 = iconst.i64 17 - v2 = srem v0, v1 - return v2 -} - -; VCode: -; pushq %rbp -; movq %rsp, %rbp -; block0: -; movq %rdi, %rax -; cqo %rax, %rdx -; movl $17, %r8d -; idiv %rax, %rdx, %r8, %rax, %rdx -; movq %rdx, %rax -; movq %rbp, %rsp -; popq %rbp -; ret -; -; Disassembled: -; block0: ; offset 0x0 -; pushq %rbp -; movq %rsp, %rbp -; block1: ; offset 0x4 -; movq %rdi, %rax -; cqto -; movl $0x11, %r8d -; idivq %r8 -; movq %rdx, %rax -; movq %rbp, %rsp -; popq %rbp -; retq - diff --git a/cranelift/filetests/filetests/isa/x64/udiv-checked.clif b/cranelift/filetests/filetests/isa/x64/udiv-checked.clif deleted file mode 100644 index e9cb803133bf..000000000000 --- a/cranelift/filetests/filetests/isa/x64/udiv-checked.clif +++ /dev/null @@ -1,264 +0,0 @@ -test compile precise-output -set avoid_div_traps=true -target x86_64 - -function %f1(i8, i8) -> i8 { -block0(v0: i8, v1: i8): - v2 = udiv v0, v1 - return v2 -} - -; VCode: -; pushq %rbp -; movq %rsp, %rbp -; block0: -; movzbl %dil, %eax -; testb %sil, %sil -; jnz ; ud2 int_divz ; -; div %al, %sil, %al -; movq %rbp, %rsp -; popq %rbp -; ret -; -; Disassembled: -; block0: ; offset 0x0 -; pushq %rbp -; movq %rsp, %rbp -; block1: ; offset 0x4 -; movzbl %dil, %eax -; testb %sil, %sil -; jne 0x13 -; ud2 ; trap: int_divz -; divb %sil -; movq %rbp, %rsp -; popq %rbp -; retq - -function %f2(i16, i16) -> i16 { -block0(v0: i16, v1: i16): - v2 = udiv v0, v1 - return v2 -} - -; VCode: -; pushq %rbp -; movq %rsp, %rbp -; block0: -; movq %rdi, %rax -; xorq %rdx, %rdx, %rdx -; testw %si, %si -; jnz ; ud2 int_divz ; -; div %ax, %dx, %si, %ax, %dx -; movq %rbp, %rsp -; popq %rbp -; ret -; -; Disassembled: -; block0: ; offset 0x0 -; pushq %rbp -; movq %rsp, %rbp -; block1: ; offset 0x4 -; movq %rdi, %rax -; xorq %rdx, %rdx -; testw %si, %si -; jne 0x15 -; ud2 ; trap: int_divz -; divw %si -; movq %rbp, %rsp -; popq %rbp -; retq - -function %f3(i32, i32) -> i32 { -block0(v0: i32, v1: i32): - v2 = udiv v0, v1 - return v2 -} - -; VCode: -; pushq %rbp -; movq %rsp, %rbp -; block0: -; movq %rdi, %rax -; xorq %rdx, %rdx, %rdx -; testl %esi, %esi -; jnz ; ud2 int_divz ; -; div %eax, %edx, %esi, %eax, %edx -; movq %rbp, %rsp -; popq %rbp -; ret -; -; Disassembled: -; block0: ; offset 0x0 -; pushq %rbp -; movq %rsp, %rbp -; block1: ; offset 0x4 -; movq %rdi, %rax -; xorq %rdx, %rdx -; testl %esi, %esi -; jne 0x14 -; ud2 ; trap: int_divz -; divl %esi -; movq %rbp, %rsp -; popq %rbp -; retq - -function %f4(i64, i64) -> i64 { -block0(v0: i64, v1: i64): - v2 = udiv v0, v1 - return v2 -} - -; VCode: -; pushq %rbp -; movq %rsp, %rbp -; block0: -; movq %rdi, %rax -; xorq %rdx, %rdx, %rdx -; testq %rsi, %rsi -; jnz ; ud2 int_divz ; -; div %rax, %rdx, %rsi, %rax, %rdx -; movq %rbp, %rsp -; popq %rbp -; ret -; -; Disassembled: -; block0: ; offset 0x0 -; pushq %rbp -; movq %rsp, %rbp -; block1: ; offset 0x4 -; movq %rdi, %rax -; xorq %rdx, %rdx -; testq %rsi, %rsi -; jne 0x15 -; ud2 ; trap: int_divz -; divq %rsi -; movq %rbp, %rsp -; popq %rbp -; retq - -function %i8_imm(i8) -> i8 { -block0(v0: i8): - v1 = iconst.i8 17 - v2 = udiv v0, v1 - return v2 -} - -; VCode: -; pushq %rbp -; movq %rsp, %rbp -; block0: -; movzbl %dil, %eax -; movl $17, %edx -; div %al, %dl, %al -; movq %rbp, %rsp -; popq %rbp -; ret -; -; Disassembled: -; block0: ; offset 0x0 -; pushq %rbp -; movq %rsp, %rbp -; block1: ; offset 0x4 -; movzbl %dil, %eax -; movl $0x11, %edx -; divb %dl -; movq %rbp, %rsp -; popq %rbp -; retq - -function %i16_imm(i16) -> i16 { -block0(v0: i16): - v1 = iconst.i16 17 - v2 = udiv v0, v1 - return v2 -} - -; VCode: -; pushq %rbp -; movq %rsp, %rbp -; block0: -; movq %rdi, %rax -; xorq %rdx, %rdx, %rdx -; movl $17, %r8d -; div %ax, %dx, %r8w, %ax, %dx -; movq %rbp, %rsp -; popq %rbp -; ret -; -; Disassembled: -; block0: ; offset 0x0 -; pushq %rbp -; movq %rsp, %rbp -; block1: ; offset 0x4 -; movq %rdi, %rax -; xorq %rdx, %rdx -; movl $0x11, %r8d -; divw %r8w -; movq %rbp, %rsp -; popq %rbp -; retq - -function %i32_imm(i32) -> i32 { -block0(v0: i32): - v1 = iconst.i32 17 - v2 = udiv v0, v1 - return v2 -} - -; VCode: -; pushq %rbp -; movq %rsp, %rbp -; block0: -; movq %rdi, %rax -; xorq %rdx, %rdx, %rdx -; movl $17, %r8d -; div %eax, %edx, %r8d, %eax, %edx -; movq %rbp, %rsp -; popq %rbp -; ret -; -; Disassembled: -; block0: ; offset 0x0 -; pushq %rbp -; movq %rsp, %rbp -; block1: ; offset 0x4 -; movq %rdi, %rax -; xorq %rdx, %rdx -; movl $0x11, %r8d -; divl %r8d -; movq %rbp, %rsp -; popq %rbp -; retq - -function %i64_imm(i64) -> i64 { -block0(v0: i64): - v1 = iconst.i64 17 - v2 = udiv v0, v1 - return v2 -} - -; VCode: -; pushq %rbp -; movq %rsp, %rbp -; block0: -; movq %rdi, %rax -; xorq %rdx, %rdx, %rdx -; movl $17, %r8d -; div %rax, %rdx, %r8, %rax, %rdx -; movq %rbp, %rsp -; popq %rbp -; ret -; -; Disassembled: -; block0: ; offset 0x0 -; pushq %rbp -; movq %rsp, %rbp -; block1: ; offset 0x4 -; movq %rdi, %rax -; xorq %rdx, %rdx -; movl $0x11, %r8d -; divq %r8 -; movq %rbp, %rsp -; popq %rbp -; retq - diff --git a/cranelift/filetests/filetests/isa/x64/urem-checked.clif b/cranelift/filetests/filetests/isa/x64/urem-checked.clif deleted file mode 100644 index f304fa296249..000000000000 --- a/cranelift/filetests/filetests/isa/x64/urem-checked.clif +++ /dev/null @@ -1,280 +0,0 @@ -test compile precise-output -set avoid_div_traps=true -target x86_64 - -function %f1(i8, i8) -> i8 { -block0(v0: i8, v1: i8): - v2 = urem v0, v1 - return v2 -} - -; VCode: -; pushq %rbp -; movq %rsp, %rbp -; block0: -; movzbl %dil, %eax -; testb %sil, %sil -; jnz ; ud2 int_divz ; -; div %al, %sil, %al -; shrq $8, %rax, %rax -; movq %rbp, %rsp -; popq %rbp -; ret -; -; Disassembled: -; block0: ; offset 0x0 -; pushq %rbp -; movq %rsp, %rbp -; block1: ; offset 0x4 -; movzbl %dil, %eax -; testb %sil, %sil -; jne 0x13 -; ud2 ; trap: int_divz -; divb %sil -; shrq $8, %rax -; movq %rbp, %rsp -; popq %rbp -; retq - -function %f2(i16, i16) -> i16 { -block0(v0: i16, v1: i16): - v2 = urem v0, v1 - return v2 -} - -; VCode: -; pushq %rbp -; movq %rsp, %rbp -; block0: -; movq %rdi, %rax -; xorq %rdx, %rdx, %rdx -; testw %si, %si -; jnz ; ud2 int_divz ; -; div %ax, %dx, %si, %ax, %dx -; movq %rdx, %rax -; movq %rbp, %rsp -; popq %rbp -; ret -; -; Disassembled: -; block0: ; offset 0x0 -; pushq %rbp -; movq %rsp, %rbp -; block1: ; offset 0x4 -; movq %rdi, %rax -; xorq %rdx, %rdx -; testw %si, %si -; jne 0x15 -; ud2 ; trap: int_divz -; divw %si -; movq %rdx, %rax -; movq %rbp, %rsp -; popq %rbp -; retq - -function %f3(i32, i32) -> i32 { -block0(v0: i32, v1: i32): - v2 = urem v0, v1 - return v2 -} - -; VCode: -; pushq %rbp -; movq %rsp, %rbp -; block0: -; movq %rdi, %rax -; xorq %rdx, %rdx, %rdx -; testl %esi, %esi -; jnz ; ud2 int_divz ; -; div %eax, %edx, %esi, %eax, %edx -; movq %rdx, %rax -; movq %rbp, %rsp -; popq %rbp -; ret -; -; Disassembled: -; block0: ; offset 0x0 -; pushq %rbp -; movq %rsp, %rbp -; block1: ; offset 0x4 -; movq %rdi, %rax -; xorq %rdx, %rdx -; testl %esi, %esi -; jne 0x14 -; ud2 ; trap: int_divz -; divl %esi -; movq %rdx, %rax -; movq %rbp, %rsp -; popq %rbp -; retq - -function %f4(i64, i64) -> i64 { -block0(v0: i64, v1: i64): - v2 = urem v0, v1 - return v2 -} - -; VCode: -; pushq %rbp -; movq %rsp, %rbp -; block0: -; movq %rdi, %rax -; xorq %rdx, %rdx, %rdx -; testq %rsi, %rsi -; jnz ; ud2 int_divz ; -; div %rax, %rdx, %rsi, %rax, %rdx -; movq %rdx, %rax -; movq %rbp, %rsp -; popq %rbp -; ret -; -; Disassembled: -; block0: ; offset 0x0 -; pushq %rbp -; movq %rsp, %rbp -; block1: ; offset 0x4 -; movq %rdi, %rax -; xorq %rdx, %rdx -; testq %rsi, %rsi -; jne 0x15 -; ud2 ; trap: int_divz -; divq %rsi -; movq %rdx, %rax -; movq %rbp, %rsp -; popq %rbp -; retq - -function %i8_imm(i8) -> i8 { -block0(v0: i8): - v1 = iconst.i8 17 - v2 = urem v0, v1 - return v2 -} - -; VCode: -; pushq %rbp -; movq %rsp, %rbp -; block0: -; movzbl %dil, %eax -; movl $17, %edx -; div %al, %dl, %al -; shrq $8, %rax, %rax -; movq %rbp, %rsp -; popq %rbp -; ret -; -; Disassembled: -; block0: ; offset 0x0 -; pushq %rbp -; movq %rsp, %rbp -; block1: ; offset 0x4 -; movzbl %dil, %eax -; movl $0x11, %edx -; divb %dl -; shrq $8, %rax -; movq %rbp, %rsp -; popq %rbp -; retq - -function %i16_imm(i16) -> i16 { -block0(v0: i16): - v1 = iconst.i16 17 - v2 = urem v0, v1 - return v2 -} - -; VCode: -; pushq %rbp -; movq %rsp, %rbp -; block0: -; movq %rdi, %rax -; xorq %rdx, %rdx, %rdx -; movl $17, %r8d -; div %ax, %dx, %r8w, %ax, %dx -; movq %rdx, %rax -; movq %rbp, %rsp -; popq %rbp -; ret -; -; Disassembled: -; block0: ; offset 0x0 -; pushq %rbp -; movq %rsp, %rbp -; block1: ; offset 0x4 -; movq %rdi, %rax -; xorq %rdx, %rdx -; movl $0x11, %r8d -; divw %r8w -; movq %rdx, %rax -; movq %rbp, %rsp -; popq %rbp -; retq - -function %i32_imm(i32) -> i32 { -block0(v0: i32): - v1 = iconst.i32 17 - v2 = urem v0, v1 - return v2 -} - -; VCode: -; pushq %rbp -; movq %rsp, %rbp -; block0: -; movq %rdi, %rax -; xorq %rdx, %rdx, %rdx -; movl $17, %r8d -; div %eax, %edx, %r8d, %eax, %edx -; movq %rdx, %rax -; movq %rbp, %rsp -; popq %rbp -; ret -; -; Disassembled: -; block0: ; offset 0x0 -; pushq %rbp -; movq %rsp, %rbp -; block1: ; offset 0x4 -; movq %rdi, %rax -; xorq %rdx, %rdx -; movl $0x11, %r8d -; divl %r8d -; movq %rdx, %rax -; movq %rbp, %rsp -; popq %rbp -; retq - -function %i64_imm(i64) -> i64 { -block0(v0: i64): - v1 = iconst.i64 17 - v2 = urem v0, v1 - return v2 -} - -; VCode: -; pushq %rbp -; movq %rsp, %rbp -; block0: -; movq %rdi, %rax -; xorq %rdx, %rdx, %rdx -; movl $17, %r8d -; div %rax, %rdx, %r8, %rax, %rdx -; movq %rdx, %rax -; movq %rbp, %rsp -; popq %rbp -; ret -; -; Disassembled: -; block0: ; offset 0x0 -; pushq %rbp -; movq %rsp, %rbp -; block1: ; offset 0x4 -; movq %rdi, %rax -; xorq %rdx, %rdx -; movl $0x11, %r8d -; divq %r8 -; movq %rdx, %rax -; movq %rbp, %rsp -; popq %rbp -; retq - diff --git a/cranelift/filetests/filetests/runtests/div-checks.clif b/cranelift/filetests/filetests/runtests/div-checks.clif index 3a854adbad70..2c385fa19722 100644 --- a/cranelift/filetests/filetests/runtests/div-checks.clif +++ b/cranelift/filetests/filetests/runtests/div-checks.clif @@ -1,13 +1,8 @@ test run -set avoid_div_traps=false target aarch64 target s390x target x86_64 -target riscv64 - - -; Tests that the `avoid_div_traps` flag prevents a trap when {s,u}rem is called -; with INT_MIN % -1. +target riscv64 function %i8(i8, i8) -> i8 { block0(v0: i8, v1: i8): diff --git a/cranelift/filetests/filetests/runtests/srem.clif b/cranelift/filetests/filetests/runtests/srem.clif index 96b0f95fe966..6d0a6217f990 100644 --- a/cranelift/filetests/filetests/runtests/srem.clif +++ b/cranelift/filetests/filetests/runtests/srem.clif @@ -1,7 +1,5 @@ test interpret test run -; Test these inputs without div traps, it shouldn't affect normal inputs -set avoid_div_traps target aarch64 target s390x target x86_64 diff --git a/cranelift/filetests/filetests/runtests/urem.clif b/cranelift/filetests/filetests/runtests/urem.clif index f0b6bb067317..8ab17fc4efa7 100644 --- a/cranelift/filetests/filetests/runtests/urem.clif +++ b/cranelift/filetests/filetests/runtests/urem.clif @@ -4,11 +4,6 @@ target aarch64 target s390x target x86_64 target riscv64 -; 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): diff --git a/crates/wasmtime/src/engine.rs b/crates/wasmtime/src/engine.rs index a71e4cfbfb22..de7ba922d8d2 100644 --- a/crates/wasmtime/src/engine.rs +++ b/crates/wasmtime/src/engine.rs @@ -418,7 +418,6 @@ impl Engine { | "probestack_size_log2" // probestack above asserted disabled | "regalloc" // shouldn't change semantics | "enable_incremental_compilation_cache_checks" // shouldn't change semantics - | "avoid_div_traps" // doesn't change the CLIF semantics | "enable_atomics" => return Ok(()), // Everything else is unknown and needs to be added somewhere to From 1546459c3974a79d6724d74f02007c320dac4738 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Wed, 15 Mar 2023 15:10:10 -0700 Subject: [PATCH 3/8] x64: GC more support for avoid_div_traps Remove the `validate_sdiv_divisor*` pseudo-instructions and clean up some of the ISLE rules now that `div` is allowed to itself trap unconditionally. --- cranelift/codegen/src/isa/x64/inst.isle | 38 -------------- cranelift/codegen/src/isa/x64/inst/emit.rs | 49 ------------------- cranelift/codegen/src/isa/x64/inst/mod.rs | 42 ---------------- cranelift/codegen/src/isa/x64/lower.isle | 37 +++++++------- .../filetests/filetests/isa/x64/sdiv.clif | 30 ++++++------ 5 files changed, 34 insertions(+), 162 deletions(-) diff --git a/cranelift/codegen/src/isa/x64/inst.isle b/cranelift/codegen/src/isa/x64/inst.isle index faf5bc045279..57038807ca34 100644 --- a/cranelift/codegen/src/isa/x64/inst.isle +++ b/cranelift/codegen/src/isa/x64/inst.isle @@ -103,29 +103,6 @@ (divisor Gpr) (dst WritableGpr)) - ;; Validates that the `divisor` can be safely divided into the - ;; `dividend`. - ;; - ;; This is a separate pseudo-instruction because it has some jumps in - ;; ways that can't be modeled otherwise with instructions right now. This - ;; will trap if the `divisor` is zero or if it's -1 and `dividend` is - ;; INT_MIN for the associated type. - ;; - ;; Note that 64-bit types must use `ValidateSdivDivisor64`. - (ValidateSdivDivisor (size OperandSize) - (dividend Gpr) - (divisor Gpr)) - - ;; Same as `ValidateSdivDivisor` but for 64-bit types. - ;; - ;; This is a distinct instruction because the emission in `emit.rs` - ;; requires a temporary register to load an immediate into, hence the - ;; `tmp` field in this instruction not present in the non-64-bit one. - (ValidateSdivDivisor64 (dividend Gpr) - (divisor Gpr) - (tmp WritableGpr)) - - ;; Do a sign-extend based on the sign of the value in rax into rdx: (cwd ;; cdq cqo) or al into ah: (cbw) (SignExtendData (size OperandSize) ;; 1, 2, 4, or 8 @@ -4605,21 +4582,6 @@ (_ Unit (emit (MInst.SignExtendData size src dst)))) dst)) -;; Helper for creating `ValidateSdivDivisor` instructions. -(decl validate_sdiv_divisor (OperandSize Gpr Gpr) Gpr) -(rule (validate_sdiv_divisor size dividend divisor) - (let ((_ Unit (emit (MInst.ValidateSdivDivisor size dividend divisor)))) - divisor)) - -;; Helper for creating `ValidateSdivDivisor64` instructions. -(decl validate_sdiv_divisor64 (Gpr Gpr) Gpr) -(rule (validate_sdiv_divisor64 dividend divisor) - (let ( - (tmp WritableGpr (temp_writable_gpr)) - (_ Unit (emit (MInst.ValidateSdivDivisor64 dividend divisor tmp))) - ) - divisor)) - ;;;; Pinned Register ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (decl read_pinned_gpr () Gpr) diff --git a/cranelift/codegen/src/isa/x64/inst/emit.rs b/cranelift/codegen/src/isa/x64/inst/emit.rs index d59994de2524..8078b525c5a0 100644 --- a/cranelift/codegen/src/isa/x64/inst/emit.rs +++ b/cranelift/codegen/src/isa/x64/inst/emit.rs @@ -658,55 +658,6 @@ pub(crate) fn emit( sink.bind_label(done_label); } - Inst::ValidateSdivDivisor { - dividend, divisor, .. - } - | Inst::ValidateSdivDivisor64 { - dividend, divisor, .. - } => { - let orig_inst = &inst; - let divisor = allocs.next(divisor.to_reg()); - let dividend = allocs.next(dividend.to_reg()); - let size = match inst { - Inst::ValidateSdivDivisor { size, .. } => *size, - _ => OperandSize::Size64, - }; - - // First trap if the divisor is zero - let inst = Inst::cmp_rmi_r(size, RegMemImm::imm(0), divisor); - inst.emit(&[], sink, info, state); - let inst = Inst::trap_if(CC::Z, TrapCode::IntegerDivisionByZero); - inst.emit(&[], sink, info, state); - - // Now check if the divisor is -1. If it is then additionally - // check if the dividend is INT_MIN. If it isn't then jump to the - // end. If both conditions here are true then trap. - let inst = Inst::cmp_rmi_r(size, RegMemImm::imm(0xffffffff), divisor); - inst.emit(&[], sink, info, state); - let done = sink.get_label(); - one_way_jmp(sink, CC::NZ, done); - let int_min = match orig_inst { - Inst::ValidateSdivDivisor64 { tmp, .. } => { - let tmp = allocs.next(tmp.to_reg().to_reg()); - let inst = Inst::imm(size, i64::MIN as u64, Writable::from_reg(tmp)); - inst.emit(&[], sink, info, state); - RegMemImm::reg(tmp) - } - _ => RegMemImm::imm(match size { - OperandSize::Size8 => 0x80, - OperandSize::Size16 => 0x8000, - OperandSize::Size32 => 0x80000000, - OperandSize::Size64 => unreachable!(), - }), - }; - let inst = Inst::cmp_rmi_r(size, int_min, dividend); - inst.emit(&[], sink, info, state); - let inst = Inst::trap_if(CC::Z, TrapCode::IntegerOverflow); - inst.emit(&[], sink, info, state); - - sink.bind_label(done); - } - Inst::Imm { dst_size, simm64, diff --git a/cranelift/codegen/src/isa/x64/inst/mod.rs b/cranelift/codegen/src/isa/x64/inst/mod.rs index 6dab29da9d83..7196a9641e5c 100644 --- a/cranelift/codegen/src/isa/x64/inst/mod.rs +++ b/cranelift/codegen/src/isa/x64/inst/mod.rs @@ -73,8 +73,6 @@ impl Inst { | Inst::CallUnknown { .. } | Inst::CheckedSRemSeq { .. } | Inst::CheckedSRemSeq8 { .. } - | Inst::ValidateSdivDivisor { .. } - | Inst::ValidateSdivDivisor64 { .. } | Inst::Cmove { .. } | Inst::CmpRmiR { .. } | Inst::CvtFloatToSintSeq { .. } @@ -547,10 +545,6 @@ impl Inst { Inst::JmpUnknown { target } } - pub(crate) fn trap_if(cc: CC, trap_code: TrapCode) -> Inst { - Inst::TrapIf { cc, trap_code } - } - /// Choose which instruction to use for loading a register value from memory. For loads smaller /// than 64 bits, this method expects a way to extend the value (i.e. [ExtKind::SignExtend], /// [ExtKind::ZeroExtend]); loads with no extension necessary will ignore this. @@ -873,27 +867,6 @@ impl PrettyPrint for Inst { format!("checked_srem_seq {dividend}, {divisor}, {dst}") } - Inst::ValidateSdivDivisor { - dividend, - divisor, - size, - } => { - let dividend = pretty_print_reg(dividend.to_reg(), size.to_bytes(), allocs); - let divisor = pretty_print_reg(divisor.to_reg(), size.to_bytes(), allocs); - format!("validate_sdiv_divisor {dividend}, {divisor}") - } - - Inst::ValidateSdivDivisor64 { - dividend, - divisor, - tmp, - } => { - let dividend = pretty_print_reg(dividend.to_reg(), 8, allocs); - let divisor = pretty_print_reg(divisor.to_reg(), 8, allocs); - let tmp = pretty_print_reg(tmp.to_reg().to_reg(), 8, allocs); - format!("validate_sdiv_divisor {dividend}, {divisor} {tmp}") - } - Inst::SignExtendData { size, src, dst } => { let src = pretty_print_reg(src.to_reg(), size.to_bytes(), allocs); let dst = pretty_print_reg(dst.to_reg().to_reg(), size.to_bytes(), allocs); @@ -1916,21 +1889,6 @@ fn x64_get_operands VReg>(inst: &Inst, collector: &mut OperandCol collector.reg_fixed_def(dst_hi.to_writable_reg(), regs::rdx()); src2.get_operands(collector); } - Inst::ValidateSdivDivisor { - dividend, divisor, .. - } => { - collector.reg_use(divisor.to_reg()); - collector.reg_use(dividend.to_reg()); - } - Inst::ValidateSdivDivisor64 { - dividend, - divisor, - tmp, - } => { - collector.reg_use(divisor.to_reg()); - collector.reg_use(dividend.to_reg()); - collector.reg_early_def(tmp.to_writable_reg()); - } Inst::SignExtendData { size, src, dst } => { match size { OperandSize::Size8 => { diff --git a/cranelift/codegen/src/isa/x64/lower.isle b/cranelift/codegen/src/isa/x64/lower.isle index bae3a0922609..207d3076651b 100644 --- a/cranelift/codegen/src/isa/x64/lower.isle +++ b/cranelift/codegen/src/isa/x64/lower.isle @@ -3512,32 +3512,32 @@ ;; Rules for `sdiv` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (rule 2 (lower (sdiv a @ (value_type $I8) b)) - (let ( - (a Gpr (x64_sign_extend_data a (OperandSize.Size8))) - ) - (x64_div8 a (safe_sdiv_divisor $I8 a b) (DivSignedness.Signed)))) + (x64_div8 (x64_sign_extend_data a (OperandSize.Size8)) + (nonzero_sdiv_divisor $I8 b) + (DivSignedness.Signed))) (rule 1 (lower (sdiv a @ (value_type (fits_in_64 ty)) b)) (let ( (a Gpr a) (size OperandSize (raw_operand_size_of_type ty)) - (b Gpr (safe_sdiv_divisor ty a b)) ) - (x64_div_quotient a (x64_sign_extend_data a size) b size (DivSignedness.Signed)))) - -;; Similar to `nonzero_divisor` except this checks to make sure that the divisor -;; provided as a `Value` is safe to divide into the dividend `Gpr` provided. -(decl safe_sdiv_divisor (Type Gpr Value) Reg) + (x64_div_quotient a + (x64_sign_extend_data a size) + (nonzero_sdiv_divisor ty b) + size + (DivSignedness.Signed)))) -;; If the divisor is a constant that isn't 0 or -1, then it's always safe so -;; materialize it into a register. -(rule 3 (safe_sdiv_divisor ty a (iconst imm)) +;; Checks to make sure that the input `Value` is a non-zero value for `sdiv`. +;; +;; This is required to differentiate the divide-by-zero trap from the +;; integer-overflow trap, the two trapping conditions of signed division. +(decl nonzero_sdiv_divisor (Type Value) Reg) +(rule 1 (nonzero_sdiv_divisor ty (iconst imm)) (if-let n (safe_divisor_from_imm64 ty imm)) (imm ty n)) - -(rule 2 (safe_sdiv_divisor ty a b) +(rule 0 (nonzero_sdiv_divisor ty val) (let ( - (val Reg b) + (val Reg val) (_ InstOutput (side_effect (with_flags_side_effect (x64_test (raw_operand_size_of_type ty) val val) (trap_if (CC.Z) (TrapCode.IntegerDivisionByZero))))) @@ -3550,8 +3550,9 @@ ;; by 8. (rule 2 (lower (urem a @ (value_type $I8) b)) (let ( - (a Gpr (extend_to_gpr a $I32 (ExtendKind.Zero))) - (result Gpr (x64_div8 a b (DivSignedness.Unsigned))) + (result Gpr (x64_div8 (extend_to_gpr a $I32 (ExtendKind.Zero)) + b + (DivSignedness.Unsigned))) ) (x64_shr $I64 result (Imm8Reg.Imm8 8)))) diff --git a/cranelift/filetests/filetests/isa/x64/sdiv.clif b/cranelift/filetests/filetests/isa/x64/sdiv.clif index f14002512ad4..05a2aadbfc89 100644 --- a/cranelift/filetests/filetests/isa/x64/sdiv.clif +++ b/cranelift/filetests/filetests/isa/x64/sdiv.clif @@ -45,10 +45,10 @@ block0(v0: i16, v1: i16): ; pushq %rbp ; movq %rsp, %rbp ; block0: -; testw %si, %si -; jnz ; ud2 int_divz ; ; movq %rdi, %rax ; cwd %ax, %dx +; testw %si, %si +; jnz ; ud2 int_divz ; ; idiv %ax, %dx, %si, %ax, %dx ; movq %rbp, %rsp ; popq %rbp @@ -59,11 +59,11 @@ block0(v0: i16, v1: i16): ; pushq %rbp ; movq %rsp, %rbp ; block1: ; offset 0x4 -; testw %si, %si -; jne 0xf -; ud2 ; trap: int_divz ; movq %rdi, %rax ; cwtd +; testw %si, %si +; jne 0x14 +; ud2 ; trap: int_divz ; idivw %si ; trap: int_ovf ; movq %rbp, %rsp ; popq %rbp @@ -79,10 +79,10 @@ block0(v0: i32, v1: i32): ; pushq %rbp ; movq %rsp, %rbp ; block0: -; testl %esi, %esi -; jnz ; ud2 int_divz ; ; movq %rdi, %rax ; cdq %eax, %edx +; testl %esi, %esi +; jnz ; ud2 int_divz ; ; idiv %eax, %edx, %esi, %eax, %edx ; movq %rbp, %rsp ; popq %rbp @@ -93,11 +93,11 @@ block0(v0: i32, v1: i32): ; pushq %rbp ; movq %rsp, %rbp ; block1: ; offset 0x4 -; testl %esi, %esi -; jne 0xe -; ud2 ; trap: int_divz ; movq %rdi, %rax ; cltd +; testl %esi, %esi +; jne 0x12 +; ud2 ; trap: int_divz ; idivl %esi ; trap: int_ovf ; movq %rbp, %rsp ; popq %rbp @@ -113,10 +113,10 @@ block0(v0: i64, v1: i64): ; pushq %rbp ; movq %rsp, %rbp ; block0: -; testq %rsi, %rsi -; jnz ; ud2 int_divz ; ; movq %rdi, %rax ; cqo %rax, %rdx +; testq %rsi, %rsi +; jnz ; ud2 int_divz ; ; idiv %rax, %rdx, %rsi, %rax, %rdx ; movq %rbp, %rsp ; popq %rbp @@ -127,11 +127,11 @@ block0(v0: i64, v1: i64): ; pushq %rbp ; movq %rsp, %rbp ; block1: ; offset 0x4 -; testq %rsi, %rsi -; jne 0xf -; ud2 ; trap: int_divz ; movq %rdi, %rax ; cqto +; testq %rsi, %rsi +; jne 0x14 +; ud2 ; trap: int_divz ; idivq %rsi ; trap: int_ovf ; movq %rbp, %rsp ; popq %rbp From 43f1bf81e3a31b1fb5efe39ab4c59e075971dc93 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Wed, 15 Mar 2023 15:15:58 -0700 Subject: [PATCH 4/8] x64: Store div trap code in instruction itself --- cranelift/codegen/src/isa/x64/inst.isle | 26 ++++++----- cranelift/codegen/src/isa/x64/inst/emit.rs | 44 +++++++------------ cranelift/codegen/src/isa/x64/inst/mod.rs | 14 +++--- cranelift/codegen/src/isa/x64/lower.isle | 23 ++++++---- .../filetests/filetests/isa/x64/sdiv.clif | 8 ++-- .../filetests/filetests/isa/x64/srem.clif | 16 +++---- .../filetests/filetests/isa/x64/udiv.clif | 8 ++-- .../filetests/filetests/isa/x64/udivrem.clif | 16 +++---- .../filetests/filetests/isa/x64/urem.clif | 8 ++-- 9 files changed, 80 insertions(+), 83 deletions(-) diff --git a/cranelift/codegen/src/isa/x64/inst.isle b/cranelift/codegen/src/isa/x64/inst.isle index 57038807ca34..b0ecab9baf09 100644 --- a/cranelift/codegen/src/isa/x64/inst.isle +++ b/cranelift/codegen/src/isa/x64/inst.isle @@ -63,6 +63,7 @@ ;; instruction. (Div (size OperandSize) ;; 2, 4, or 8 (sign DivSignedness) + (trap TrapCode) (divisor GprMem) (dividend_lo Gpr) (dividend_hi Gpr) @@ -71,6 +72,7 @@ ;; Same as `Div`, but for 8-bits where the regalloc behavior is different (Div8 (sign DivSignedness) + (trap TrapCode) (divisor GprMem) (dividend Gpr) (dst WritableGpr)) @@ -4548,32 +4550,32 @@ dst)) ;; Helper for creating `Div8` instructions -(decl x64_div8 (Gpr GprMem DivSignedness) Gpr) -(rule (x64_div8 dividend divisor sign) +(decl x64_div8 (Gpr GprMem DivSignedness TrapCode) Gpr) +(rule (x64_div8 dividend divisor sign trap) (let ((dst WritableGpr (temp_writable_gpr)) - (_ Unit (emit (MInst.Div8 sign divisor dividend dst)))) + (_ Unit (emit (MInst.Div8 sign trap divisor dividend dst)))) dst)) ;; Helper for creating `Div` instructions ;; ;; Two registers are returned through `ValueRegs` where the first is the ;; quotient and the second is the remainder. -(decl x64_div (Gpr Gpr GprMem OperandSize DivSignedness) ValueRegs) -(rule (x64_div dividend_lo dividend_hi divisor size sign) +(decl x64_div (Gpr Gpr GprMem OperandSize DivSignedness TrapCode) ValueRegs) +(rule (x64_div dividend_lo dividend_hi divisor size sign trap) (let ((dst_quotient WritableGpr (temp_writable_gpr)) (dst_remainder WritableGpr (temp_writable_gpr)) - (_ Unit (emit (MInst.Div size sign divisor dividend_lo dividend_hi dst_quotient dst_remainder)))) + (_ Unit (emit (MInst.Div size sign trap divisor dividend_lo dividend_hi dst_quotient dst_remainder)))) (value_regs dst_quotient dst_remainder))) ;; Helper for `Div`, returning the quotient and discarding the remainder. -(decl x64_div_quotient (Gpr Gpr GprMem OperandSize DivSignedness) ValueRegs) -(rule (x64_div_quotient dividend_lo dividend_hi divisor size sign) - (value_regs_get (x64_div dividend_lo dividend_hi divisor size sign) 0)) +(decl x64_div_quotient (Gpr Gpr GprMem OperandSize DivSignedness TrapCode) ValueRegs) +(rule (x64_div_quotient dividend_lo dividend_hi divisor size sign trap) + (value_regs_get (x64_div dividend_lo dividend_hi divisor size sign trap) 0)) ;; Helper for `Div`, returning the remainder and discarding the quotient. -(decl x64_div_remainder (Gpr Gpr GprMem OperandSize DivSignedness) ValueRegs) -(rule (x64_div_remainder dividend_lo dividend_hi divisor size sign) - (value_regs_get (x64_div dividend_lo dividend_hi divisor size sign) 1)) +(decl x64_div_remainder (Gpr Gpr GprMem OperandSize DivSignedness TrapCode) ValueRegs) +(rule (x64_div_remainder dividend_lo dividend_hi divisor size sign trap) + (value_regs_get (x64_div dividend_lo dividend_hi divisor size sign trap) 1)) ;; Helper for creating `SignExtendData` instructions (decl x64_sign_extend_data (Gpr OperandSize) Gpr) diff --git a/cranelift/codegen/src/isa/x64/inst/emit.rs b/cranelift/codegen/src/isa/x64/inst/emit.rs index 8078b525c5a0..f22892865e54 100644 --- a/cranelift/codegen/src/isa/x64/inst/emit.rs +++ b/cranelift/codegen/src/isa/x64/inst/emit.rs @@ -399,7 +399,18 @@ pub(crate) fn emit( emit_std_enc_enc(sink, prefix, opcode, 1, subopcode, enc_src, rex_flags) } - Inst::Div { sign, divisor, .. } | Inst::Div8 { sign, divisor, .. } => { + Inst::Div { + sign, + trap, + divisor, + .. + } + | Inst::Div8 { + sign, + trap, + divisor, + .. + } => { let divisor = divisor.clone().to_reg_mem().with_allocs(allocs); let size = match inst { Inst::Div { @@ -437,31 +448,7 @@ pub(crate) fn emit( OperandSize::Size64 => (0xF7, LegacyPrefixes::None), }; - // If div traps are avoided then no trap is registered here since - // the instruction should never trap due to lowering rules. - // - // Otherwise though this instruction is allowed to trap. There's - // one trapping condition for unsigned division, which is - // always divide-by-zero, so that's reported here. There are two - // conditions for signed division, though, either divide-by-zero - // or integer overflow with INT_MIN/-1. Lowering explicitly - // checks for 0 because it's easier and defers the overflow - // detection to happening via a trap. - // - // Note, though, that this instruction is also used as part of the - // `CheckedSRemSeq*` lowering which uses signed division but - // statically rules out the integer overflow case, in which case - // the listed trap here is divide-by-zero. This means that only the - // actual CLIF `sdiv` instruction ends up triggering the integer - // overflow case. - sink.add_trap(if state.div_trap_is_divide_by_zero { - TrapCode::IntegerDivisionByZero - } else { - match sign { - DivSignedness::Signed => TrapCode::IntegerOverflow, - DivSignedness::Unsigned => TrapCode::IntegerDivisionByZero, - } - }); + sink.add_trap(*trap); let subopcode = match sign { DivSignedness::Signed => 7, @@ -636,6 +623,7 @@ pub(crate) fn emit( let inst = match size { OperandSize::Size8 => Inst::div8( DivSignedness::Signed, + TrapCode::IntegerDivisionByZero, RegMem::reg(divisor), Gpr::new(regs::rax()).unwrap(), Writable::from_reg(Gpr::new(regs::rax()).unwrap()), @@ -643,6 +631,7 @@ pub(crate) fn emit( _ => Inst::div( size, DivSignedness::Signed, + TrapCode::IntegerDivisionByZero, RegMem::reg(divisor), Gpr::new(regs::rax()).unwrap(), Gpr::new(regs::rdx()).unwrap(), @@ -650,10 +639,7 @@ pub(crate) fn emit( Writable::from_reg(Gpr::new(regs::rdx()).unwrap()), ), }; - assert!(!state.div_trap_is_divide_by_zero); - state.div_trap_is_divide_by_zero = true; inst.emit(&[], sink, info, state); - state.div_trap_is_divide_by_zero = false; sink.bind_label(done_label); } diff --git a/cranelift/codegen/src/isa/x64/inst/mod.rs b/cranelift/codegen/src/isa/x64/inst/mod.rs index 7196a9641e5c..3f7eb314ffcf 100644 --- a/cranelift/codegen/src/isa/x64/inst/mod.rs +++ b/cranelift/codegen/src/isa/x64/inst/mod.rs @@ -223,6 +223,7 @@ impl Inst { pub(crate) fn div( size: OperandSize, sign: DivSignedness, + trap: TrapCode, divisor: RegMem, dividend_lo: Gpr, dividend_hi: Gpr, @@ -233,6 +234,7 @@ impl Inst { Inst::Div { size, sign, + trap, divisor: GprMem::new(divisor).unwrap(), dividend_lo, dividend_hi, @@ -243,6 +245,7 @@ impl Inst { pub(crate) fn div8( sign: DivSignedness, + trap: TrapCode, divisor: RegMem, dividend: Gpr, dst: WritableGpr, @@ -250,6 +253,7 @@ impl Inst { divisor.assert_regclass_is(RegClass::Int); Inst::Div8 { sign, + trap, divisor: GprMem::new(divisor).unwrap(), dividend, dst, @@ -764,6 +768,7 @@ impl PrettyPrint for Inst { Inst::Div { size, sign, + trap, divisor, dividend_lo, dividend_hi, @@ -778,7 +783,7 @@ impl PrettyPrint for Inst { let dst_remainder = pretty_print_reg(dst_remainder.to_reg().to_reg(), size.to_bytes(), allocs); format!( - "{} {}, {}, {}, {}, {}", + "{} {}, {}, {}, {}, {} ; trap={trap}", ljustify(match sign { DivSignedness::Signed => "idiv".to_string(), DivSignedness::Unsigned => "div".to_string(), @@ -793,6 +798,7 @@ impl PrettyPrint for Inst { Inst::Div8 { sign, + trap, divisor, dividend, dst, @@ -801,7 +807,7 @@ impl PrettyPrint for Inst { let dividend = pretty_print_reg(dividend.to_reg(), 1, allocs); let dst = pretty_print_reg(dst.to_reg().to_reg(), 1, allocs); format!( - "{} {dividend}, {divisor}, {dst}", + "{} {dividend}, {divisor}, {dst} ; trap={trap}", ljustify(match sign { DivSignedness::Signed => "idiv".to_string(), DivSignedness::Unsigned => "div".to_string(), @@ -2509,9 +2515,6 @@ pub struct EmitState { stack_map: Option, /// Current source location. cur_srcloc: RelSourceLoc, - /// Used for `CheckedSRemSeq*` to configure the trap emitted for its `div` - /// instruction. - div_trap_is_divide_by_zero: bool, } /// Constant state used during emissions of a sequence of instructions. @@ -2554,7 +2557,6 @@ impl MachInstEmitState for EmitState { nominal_sp_to_fp: abi.frame_size() as i64, stack_map: None, cur_srcloc: Default::default(), - div_trap_is_divide_by_zero: false, } } diff --git a/cranelift/codegen/src/isa/x64/lower.isle b/cranelift/codegen/src/isa/x64/lower.isle index 207d3076651b..92808e4b9d51 100644 --- a/cranelift/codegen/src/isa/x64/lower.isle +++ b/cranelift/codegen/src/isa/x64/lower.isle @@ -3497,7 +3497,8 @@ (rule 2 (lower (udiv a @ (value_type $I8) b)) (x64_div8 (extend_to_gpr a $I32 (ExtendKind.Zero)) b - (DivSignedness.Unsigned))) + (DivSignedness.Unsigned) + (TrapCode.IntegerDivisionByZero))) ;; 16-to-64-bit division is all done with a similar instruction and the only ;; tricky requirement here is that when div traps are disallowed the divisor @@ -3507,14 +3508,16 @@ (imm $I64 0) b (raw_operand_size_of_type ty) - (DivSignedness.Unsigned))) + (DivSignedness.Unsigned) + (TrapCode.IntegerDivisionByZero))) ;; Rules for `sdiv` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (rule 2 (lower (sdiv a @ (value_type $I8) b)) (x64_div8 (x64_sign_extend_data a (OperandSize.Size8)) (nonzero_sdiv_divisor $I8 b) - (DivSignedness.Signed))) + (DivSignedness.Signed) + (TrapCode.IntegerOverflow))) (rule 1 (lower (sdiv a @ (value_type (fits_in_64 ty)) b)) (let ( @@ -3525,7 +3528,8 @@ (x64_sign_extend_data a size) (nonzero_sdiv_divisor ty b) size - (DivSignedness.Signed)))) + (DivSignedness.Signed) + (TrapCode.IntegerOverflow)))) ;; Checks to make sure that the input `Value` is a non-zero value for `sdiv`. ;; @@ -3552,7 +3556,8 @@ (let ( (result Gpr (x64_div8 (extend_to_gpr a $I32 (ExtendKind.Zero)) b - (DivSignedness.Unsigned))) + (DivSignedness.Unsigned) + (TrapCode.IntegerDivisionByZero))) ) (x64_shr $I64 result (Imm8Reg.Imm8 8)))) @@ -3561,7 +3566,8 @@ (imm $I64 0) b (raw_operand_size_of_type ty) - (DivSignedness.Unsigned))) + (DivSignedness.Unsigned) + (TrapCode.IntegerDivisionByZero))) ;; Rules for `srem` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -3574,7 +3580,7 @@ (if-let n (safe_divisor_from_imm64 $I8 imm)) (let ( (a Gpr (x64_sign_extend_data a (OperandSize.Size8))) - (result Gpr (x64_div8 a (imm $I8 n) (DivSignedness.Signed))) + (result Gpr (x64_div8 a (imm $I8 n) (DivSignedness.Signed) (TrapCode.IntegerDivisionByZero))) ) (x64_shr $I64 result (Imm8Reg.Imm8 8)))) @@ -3589,7 +3595,8 @@ (x64_sign_extend_data a size) (imm ty n) size - (DivSignedness.Signed)))) + (DivSignedness.Signed) + (TrapCode.IntegerDivisionByZero)))) (rule 1 (lower (srem a @ (value_type $I8) b)) (let ( diff --git a/cranelift/filetests/filetests/isa/x64/sdiv.clif b/cranelift/filetests/filetests/isa/x64/sdiv.clif index 05a2aadbfc89..f20b17d0b43c 100644 --- a/cranelift/filetests/filetests/isa/x64/sdiv.clif +++ b/cranelift/filetests/filetests/isa/x64/sdiv.clif @@ -15,7 +15,7 @@ block0(v0: i8, v1: i8): ; cbw %al, %al ; testb %sil, %sil ; jnz ; ud2 int_divz ; -; idiv %al, %sil, %al +; idiv %al, %sil, %al ; trap=int_ovf ; movq %rbp, %rsp ; popq %rbp ; ret @@ -49,7 +49,7 @@ block0(v0: i16, v1: i16): ; cwd %ax, %dx ; testw %si, %si ; jnz ; ud2 int_divz ; -; idiv %ax, %dx, %si, %ax, %dx +; idiv %ax, %dx, %si, %ax, %dx ; trap=int_ovf ; movq %rbp, %rsp ; popq %rbp ; ret @@ -83,7 +83,7 @@ block0(v0: i32, v1: i32): ; cdq %eax, %edx ; testl %esi, %esi ; jnz ; ud2 int_divz ; -; idiv %eax, %edx, %esi, %eax, %edx +; idiv %eax, %edx, %esi, %eax, %edx ; trap=int_ovf ; movq %rbp, %rsp ; popq %rbp ; ret @@ -117,7 +117,7 @@ block0(v0: i64, v1: i64): ; cqo %rax, %rdx ; testq %rsi, %rsi ; jnz ; ud2 int_divz ; -; idiv %rax, %rdx, %rsi, %rax, %rdx +; idiv %rax, %rdx, %rsi, %rax, %rdx ; trap=int_ovf ; movq %rbp, %rsp ; popq %rbp ; ret diff --git a/cranelift/filetests/filetests/isa/x64/srem.clif b/cranelift/filetests/filetests/isa/x64/srem.clif index f311fbc00570..14ed4efeed8b 100644 --- a/cranelift/filetests/filetests/isa/x64/srem.clif +++ b/cranelift/filetests/filetests/isa/x64/srem.clif @@ -155,7 +155,7 @@ block0(v0: i8): ; movq %rdi, %rax ; cbw %al, %al ; movl $17, %edx -; idiv %al, %dl, %al +; idiv %al, %dl, %al ; trap=int_divz ; shrq $8, %rax, %rax ; movq %rbp, %rsp ; popq %rbp @@ -169,7 +169,7 @@ block0(v0: i8): ; movq %rdi, %rax ; cbtw ; movl $0x11, %edx -; idivb %dl ; trap: int_ovf +; idivb %dl ; trap: int_divz ; shrq $8, %rax ; movq %rbp, %rsp ; popq %rbp @@ -189,7 +189,7 @@ block0(v0: i16): ; movq %rdi, %rax ; cwd %ax, %dx ; movl $17, %r8d -; idiv %ax, %dx, %r8w, %ax, %dx +; idiv %ax, %dx, %r8w, %ax, %dx ; trap=int_divz ; movq %rdx, %rax ; movq %rbp, %rsp ; popq %rbp @@ -203,7 +203,7 @@ block0(v0: i16): ; movq %rdi, %rax ; cwtd ; movl $0x11, %r8d -; idivw %r8w ; trap: int_ovf +; idivw %r8w ; trap: int_divz ; movq %rdx, %rax ; movq %rbp, %rsp ; popq %rbp @@ -223,7 +223,7 @@ block0(v0: i32): ; movq %rdi, %rax ; cdq %eax, %edx ; movl $17, %r8d -; idiv %eax, %edx, %r8d, %eax, %edx +; idiv %eax, %edx, %r8d, %eax, %edx ; trap=int_divz ; movq %rdx, %rax ; movq %rbp, %rsp ; popq %rbp @@ -237,7 +237,7 @@ block0(v0: i32): ; movq %rdi, %rax ; cltd ; movl $0x11, %r8d -; idivl %r8d ; trap: int_ovf +; idivl %r8d ; trap: int_divz ; movq %rdx, %rax ; movq %rbp, %rsp ; popq %rbp @@ -257,7 +257,7 @@ block0(v0: i64): ; movq %rdi, %rax ; cqo %rax, %rdx ; movl $17, %r8d -; idiv %rax, %rdx, %r8, %rax, %rdx +; idiv %rax, %rdx, %r8, %rax, %rdx ; trap=int_divz ; movq %rdx, %rax ; movq %rbp, %rsp ; popq %rbp @@ -271,7 +271,7 @@ block0(v0: i64): ; movq %rdi, %rax ; cqto ; movl $0x11, %r8d -; idivq %r8 ; trap: int_ovf +; idivq %r8 ; trap: int_divz ; movq %rdx, %rax ; movq %rbp, %rsp ; popq %rbp diff --git a/cranelift/filetests/filetests/isa/x64/udiv.clif b/cranelift/filetests/filetests/isa/x64/udiv.clif index 391abff20af1..bf3ec0820f18 100644 --- a/cranelift/filetests/filetests/isa/x64/udiv.clif +++ b/cranelift/filetests/filetests/isa/x64/udiv.clif @@ -12,7 +12,7 @@ block0(v0: i8, v1: i8): ; movq %rsp, %rbp ; block0: ; movzbl %dil, %eax -; div %al, %sil, %al +; div %al, %sil, %al ; trap=int_divz ; movq %rbp, %rsp ; popq %rbp ; ret @@ -40,7 +40,7 @@ block0(v0: i16, v1: i16): ; block0: ; movq %rdi, %rax ; xorq %rdx, %rdx, %rdx -; div %ax, %dx, %si, %ax, %dx +; div %ax, %dx, %si, %ax, %dx ; trap=int_divz ; movq %rbp, %rsp ; popq %rbp ; ret @@ -69,7 +69,7 @@ block0(v0: i32, v1: i32): ; block0: ; movq %rdi, %rax ; xorq %rdx, %rdx, %rdx -; div %eax, %edx, %esi, %eax, %edx +; div %eax, %edx, %esi, %eax, %edx ; trap=int_divz ; movq %rbp, %rsp ; popq %rbp ; ret @@ -98,7 +98,7 @@ block0(v0: i64, v1: i64): ; block0: ; movq %rdi, %rax ; xorq %rdx, %rdx, %rdx -; div %rax, %rdx, %rsi, %rax, %rdx +; div %rax, %rdx, %rsi, %rax, %rdx ; trap=int_divz ; movq %rbp, %rsp ; popq %rbp ; ret diff --git a/cranelift/filetests/filetests/isa/x64/udivrem.clif b/cranelift/filetests/filetests/isa/x64/udivrem.clif index d0368a430b28..4d0708e8995d 100644 --- a/cranelift/filetests/filetests/isa/x64/udivrem.clif +++ b/cranelift/filetests/filetests/isa/x64/udivrem.clif @@ -15,10 +15,10 @@ block0(v0: i8, v1: i8): ; movq %rsp, %rbp ; block0: ; movzbl %dil, %eax -; div %al, %sil, %al +; div %al, %sil, %al ; trap=int_divz ; movq %rax, %r11 ; movzbl %dil, %eax -; div %al, %sil, %al +; div %al, %sil, %al ; trap=int_divz ; movq %rax, %rdx ; shrq $8, %rdx, %rdx ; movq %r11, %rax @@ -56,11 +56,11 @@ block0(v0: i16, v1: i16): ; block0: ; xorq %rdx, %rdx, %rdx ; movq %rdi, %rax -; div %ax, %dx, %si, %ax, %dx +; div %ax, %dx, %si, %ax, %dx ; trap=int_divz ; movq %rax, %rcx ; movq %rdi, %rax ; xorq %rdx, %rdx, %rdx -; div %ax, %dx, %si, %ax, %dx +; div %ax, %dx, %si, %ax, %dx ; trap=int_divz ; movq %rcx, %rax ; movq %rbp, %rsp ; popq %rbp @@ -96,11 +96,11 @@ block0(v0: i32, v1: i32): ; block0: ; xorq %rdx, %rdx, %rdx ; movq %rdi, %rax -; div %eax, %edx, %esi, %eax, %edx +; div %eax, %edx, %esi, %eax, %edx ; trap=int_divz ; movq %rax, %rcx ; movq %rdi, %rax ; xorq %rdx, %rdx, %rdx -; div %eax, %edx, %esi, %eax, %edx +; div %eax, %edx, %esi, %eax, %edx ; trap=int_divz ; movq %rcx, %rax ; movq %rbp, %rsp ; popq %rbp @@ -136,11 +136,11 @@ block0(v0: i64, v1: i64): ; block0: ; xorq %rdx, %rdx, %rdx ; movq %rdi, %rax -; div %rax, %rdx, %rsi, %rax, %rdx +; div %rax, %rdx, %rsi, %rax, %rdx ; trap=int_divz ; movq %rax, %rcx ; movq %rdi, %rax ; xorq %rdx, %rdx, %rdx -; div %rax, %rdx, %rsi, %rax, %rdx +; div %rax, %rdx, %rsi, %rax, %rdx ; trap=int_divz ; movq %rcx, %rax ; movq %rbp, %rsp ; popq %rbp diff --git a/cranelift/filetests/filetests/isa/x64/urem.clif b/cranelift/filetests/filetests/isa/x64/urem.clif index 63daeaade0c8..7cf197041395 100644 --- a/cranelift/filetests/filetests/isa/x64/urem.clif +++ b/cranelift/filetests/filetests/isa/x64/urem.clif @@ -12,7 +12,7 @@ block0(v0: i8, v1: i8): ; movq %rsp, %rbp ; block0: ; movzbl %dil, %eax -; div %al, %sil, %al +; div %al, %sil, %al ; trap=int_divz ; shrq $8, %rax, %rax ; movq %rbp, %rsp ; popq %rbp @@ -42,7 +42,7 @@ block0(v0: i16, v1: i16): ; block0: ; movq %rdi, %rax ; xorq %rdx, %rdx, %rdx -; div %ax, %dx, %si, %ax, %dx +; div %ax, %dx, %si, %ax, %dx ; trap=int_divz ; movq %rdx, %rax ; movq %rbp, %rsp ; popq %rbp @@ -73,7 +73,7 @@ block0(v0: i32, v1: i32): ; block0: ; movq %rdi, %rax ; xorq %rdx, %rdx, %rdx -; div %eax, %edx, %esi, %eax, %edx +; div %eax, %edx, %esi, %eax, %edx ; trap=int_divz ; movq %rdx, %rax ; movq %rbp, %rsp ; popq %rbp @@ -104,7 +104,7 @@ block0(v0: i64, v1: i64): ; block0: ; movq %rdi, %rax ; xorq %rdx, %rdx, %rdx -; div %rax, %rdx, %rsi, %rax, %rdx +; div %rax, %rdx, %rsi, %rax, %rdx ; trap=int_divz ; movq %rdx, %rax ; movq %rbp, %rsp ; popq %rbp From a21196c8aeabcbb9c571163e77e56c62974034dd Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Wed, 15 Mar 2023 15:44:34 -0700 Subject: [PATCH 5/8] Keep divisors in registers, not in memory Don't accidentally fold multiple traps together --- cranelift/codegen/src/isa/x64/lower.isle | 14 +++- tests/all/traps.rs | 94 ++++++++++++++++++++++++ 2 files changed, 104 insertions(+), 4 deletions(-) diff --git a/cranelift/codegen/src/isa/x64/lower.isle b/cranelift/codegen/src/isa/x64/lower.isle index 92808e4b9d51..745f041cd310 100644 --- a/cranelift/codegen/src/isa/x64/lower.isle +++ b/cranelift/codegen/src/isa/x64/lower.isle @@ -3491,12 +3491,18 @@ ;; Rules for `udiv` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; NB: a `RegMem` divisor, while allowed in the instruction encoding, isn't +;; used right now to prevent a possibly-trapping load getting folded into the +;; `div` instruction. Ideally non-trapping loads would get folded, however, or +;; alternatively Wasmtime/Cranelift would grow support for multiple traps on +;; a single opcode and the signal kind would differentiate at runtime. + ;; The inputs to the `div` instruction are different for 8-bit division so ;; it needs a special case here since the instruction being crafted has a ;; different shape. (rule 2 (lower (udiv a @ (value_type $I8) b)) (x64_div8 (extend_to_gpr a $I32 (ExtendKind.Zero)) - b + (put_in_gpr b) (DivSignedness.Unsigned) (TrapCode.IntegerDivisionByZero))) @@ -3506,7 +3512,7 @@ (rule 1 (lower (udiv a @ (value_type (fits_in_64 ty)) b)) (x64_div_quotient a (imm $I64 0) - b + (put_in_gpr b) (raw_operand_size_of_type ty) (DivSignedness.Unsigned) (TrapCode.IntegerDivisionByZero))) @@ -3555,7 +3561,7 @@ (rule 2 (lower (urem a @ (value_type $I8) b)) (let ( (result Gpr (x64_div8 (extend_to_gpr a $I32 (ExtendKind.Zero)) - b + (put_in_gpr b) ;; see `udiv` for why not `gpr_mem` (DivSignedness.Unsigned) (TrapCode.IntegerDivisionByZero))) ) @@ -3564,7 +3570,7 @@ (rule 1 (lower (urem a @ (value_type (fits_in_64 ty)) b)) (x64_div_remainder a (imm $I64 0) - b + (put_in_gpr b) ;; see `udiv` for why not `gpr_mem` (raw_operand_size_of_type ty) (DivSignedness.Unsigned) (TrapCode.IntegerDivisionByZero))) diff --git a/tests/all/traps.rs b/tests/all/traps.rs index ae62280c6e73..ccceb711635c 100644 --- a/tests/all/traps.rs +++ b/tests/all/traps.rs @@ -1185,3 +1185,97 @@ fn host_return_error_no_backtrace() -> Result<()> { assert!(f.call(&mut store, ()).is_err()); Ok(()) } + +#[test] +fn div_plus_load_reported_right() -> Result<()> { + let engine = Engine::default(); + let mut store = Store::new(&engine, ()); + let module = Module::new( + &engine, + r#" + (module + (memory (export "memory") 1) + (func (export "i32.div_s") (param i32 i32) (result i32) + (i32.div_s (local.get 0) (i32.load (local.get 1)))) + (func (export "i32.div_u") (param i32 i32) (result i32) + (i32.div_u (local.get 0) (i32.load (local.get 1)))) + (func (export "i32.rem_s") (param i32 i32) (result i32) + (i32.rem_s (local.get 0) (i32.load (local.get 1)))) + (func (export "i32.rem_u") (param i32 i32) (result i32) + (i32.rem_u (local.get 0) (i32.load (local.get 1)))) + ) + "#, + )?; + let instance = Instance::new(&mut store, &module, &[])?; + let memory = instance.get_memory(&mut store, "memory").unwrap(); + let i32_div_s = instance.get_typed_func::<(i32, i32), i32>(&mut store, "i32.div_s")?; + let i32_div_u = instance.get_typed_func::<(u32, u32), u32>(&mut store, "i32.div_u")?; + let i32_rem_s = instance.get_typed_func::<(i32, i32), i32>(&mut store, "i32.rem_s")?; + let i32_rem_u = instance.get_typed_func::<(u32, u32), u32>(&mut store, "i32.rem_u")?; + + memory.write(&mut store, 0, &1i32.to_le_bytes()).unwrap(); + memory.write(&mut store, 4, &0i32.to_le_bytes()).unwrap(); + memory.write(&mut store, 8, &(-1i32).to_le_bytes()).unwrap(); + + assert_eq!(i32_div_s.call(&mut store, (100, 0))?, 100); + assert_eq!(i32_div_u.call(&mut store, (101, 0))?, 101); + assert_eq!(i32_rem_s.call(&mut store, (102, 0))?, 0); + assert_eq!(i32_rem_u.call(&mut store, (103, 0))?, 0); + + assert_trap( + i32_div_s.call(&mut store, (100, 4)), + Trap::IntegerDivisionByZero, + ); + assert_trap( + i32_div_u.call(&mut store, (100, 4)), + Trap::IntegerDivisionByZero, + ); + assert_trap( + i32_rem_s.call(&mut store, (100, 4)), + Trap::IntegerDivisionByZero, + ); + assert_trap( + i32_rem_u.call(&mut store, (100, 4)), + Trap::IntegerDivisionByZero, + ); + + assert_trap( + i32_div_s.call(&mut store, (i32::MIN, 8)), + Trap::IntegerOverflow, + ); + assert_eq!(i32_rem_s.call(&mut store, (i32::MIN, 8))?, 0); + + assert_trap( + i32_div_s.call(&mut store, (100, 100_000)), + Trap::MemoryOutOfBounds, + ); + assert_trap( + i32_div_u.call(&mut store, (100, 100_000)), + Trap::MemoryOutOfBounds, + ); + assert_trap( + i32_rem_s.call(&mut store, (100, 100_000)), + Trap::MemoryOutOfBounds, + ); + assert_trap( + i32_rem_u.call(&mut store, (100, 100_000)), + Trap::MemoryOutOfBounds, + ); + + return Ok(()); + + #[track_caller] + fn assert_trap(result: Result, expected: Trap) { + match result { + Ok(_) => panic!("expected failure"), + Err(e) => { + if let Some(code) = e.downcast_ref::() { + if *code == expected { + return; + } + } + panic!("unexpected error {e:?}"); + } + } + } +} From ba8a5769c52b53c334dd43bc81c5d9227f77713e Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Wed, 15 Mar 2023 15:49:08 -0700 Subject: [PATCH 6/8] Handle EXC_ARITHMETIC on macos --- crates/runtime/src/traphandlers/macos.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/runtime/src/traphandlers/macos.rs b/crates/runtime/src/traphandlers/macos.rs index b8047e03a289..da2cdac91ab9 100644 --- a/crates/runtime/src/traphandlers/macos.rs +++ b/crates/runtime/src/traphandlers/macos.rs @@ -244,7 +244,7 @@ unsafe fn handle_exception(request: &mut ExceptionRequest) -> bool { // First make sure that this exception is one that we actually expect to // get raised by wasm code. All other exceptions we safely ignore. match request.body.exception as u32 { - EXC_BAD_ACCESS | EXC_BAD_INSTRUCTION => {} + EXC_BAD_ACCESS | EXC_BAD_INSTRUCTION | EXC_ARITHMETIC => {} _ => return false, } @@ -424,7 +424,7 @@ pub fn lazy_per_thread_init() { let this_thread = mach_thread_self(); let kret = thread_set_exception_ports( this_thread, - EXC_MASK_BAD_ACCESS | EXC_MASK_BAD_INSTRUCTION, + EXC_MASK_BAD_ACCESS | EXC_MASK_BAD_INSTRUCTION | EXC_MASK_ARITHMETIC, WASMTIME_PORT, EXCEPTION_DEFAULT | MACH_EXCEPTION_CODES, mach_addons::THREAD_STATE_NONE, From 48a2477f1a5214c7ef843b70fb8ecbe305b6fe42 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Wed, 15 Mar 2023 16:44:12 -0700 Subject: [PATCH 7/8] Update emit tests --- .../codegen/src/isa/x64/inst/emit_tests.rs | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/cranelift/codegen/src/isa/x64/inst/emit_tests.rs b/cranelift/codegen/src/isa/x64/inst/emit_tests.rs index 7e258bb8fe6c..ee759d1a1069 100644 --- a/cranelift/codegen/src/isa/x64/inst/emit_tests.rs +++ b/cranelift/codegen/src/isa/x64/inst/emit_tests.rs @@ -1750,6 +1750,7 @@ fn test_x64_emit() { Inst::div( OperandSize::Size32, DivSignedness::Signed, + TrapCode::IntegerDivisionByZero, RegMem::reg(regs::rsi()), Gpr::new(regs::rax()).unwrap(), Gpr::new(regs::rdx()).unwrap(), @@ -1757,12 +1758,13 @@ fn test_x64_emit() { WritableGpr::from_reg(Gpr::new(regs::rdx()).unwrap()), ), "F7FE", - "idiv %eax, %edx, %esi, %eax, %edx", + "idiv %eax, %edx, %esi, %eax, %edx ; trap=int_divz", )); insns.push(( Inst::div( OperandSize::Size64, DivSignedness::Signed, + TrapCode::IntegerDivisionByZero, RegMem::reg(regs::r15()), Gpr::new(regs::rax()).unwrap(), Gpr::new(regs::rdx()).unwrap(), @@ -1770,12 +1772,13 @@ fn test_x64_emit() { WritableGpr::from_reg(Gpr::new(regs::rdx()).unwrap()), ), "49F7FF", - "idiv %rax, %rdx, %r15, %rax, %rdx", + "idiv %rax, %rdx, %r15, %rax, %rdx ; trap=int_divz", )); insns.push(( Inst::div( OperandSize::Size32, DivSignedness::Unsigned, + TrapCode::IntegerDivisionByZero, RegMem::reg(regs::r14()), Gpr::new(regs::rax()).unwrap(), Gpr::new(regs::rdx()).unwrap(), @@ -1783,12 +1786,13 @@ fn test_x64_emit() { WritableGpr::from_reg(Gpr::new(regs::rdx()).unwrap()), ), "41F7F6", - "div %eax, %edx, %r14d, %eax, %edx", + "div %eax, %edx, %r14d, %eax, %edx ; trap=int_divz", )); insns.push(( Inst::div( OperandSize::Size64, DivSignedness::Unsigned, + TrapCode::IntegerDivisionByZero, RegMem::reg(regs::rdi()), Gpr::new(regs::rax()).unwrap(), Gpr::new(regs::rdx()).unwrap(), @@ -1796,27 +1800,29 @@ fn test_x64_emit() { WritableGpr::from_reg(Gpr::new(regs::rdx()).unwrap()), ), "48F7F7", - "div %rax, %rdx, %rdi, %rax, %rdx", + "div %rax, %rdx, %rdi, %rax, %rdx ; trap=int_divz", )); insns.push(( Inst::div8( DivSignedness::Unsigned, + TrapCode::IntegerDivisionByZero, RegMem::reg(regs::rax()), Gpr::new(regs::rax()).unwrap(), WritableGpr::from_reg(Gpr::new(regs::rax()).unwrap()), ), "F6F0", - "div %al, %al, %al", + "div %al, %al, %al ; trap=int_divz", )); insns.push(( Inst::div8( DivSignedness::Unsigned, + TrapCode::IntegerDivisionByZero, RegMem::reg(regs::rsi()), Gpr::new(regs::rax()).unwrap(), WritableGpr::from_reg(Gpr::new(regs::rax()).unwrap()), ), "40F6F6", - "div %al, %sil, %al", + "div %al, %sil, %al ; trap=int_divz", )); // ======================================================== From 840a6ff2c0d820b19aa641a478bb9730a35aa708 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Wed, 15 Mar 2023 16:45:31 -0700 Subject: [PATCH 8/8] Update winch and tests --- winch/codegen/src/isa/x64/asm.rs | 63 +++++++------------ .../filetests/x64/i32_divs/const.wat | 13 ++-- .../filetests/x64/i32_divs/one_zero.wat | 13 ++-- .../filetests/x64/i32_divs/overflow.wat | 13 ++-- .../filetests/x64/i32_divs/params.wat | 15 ++--- .../filetests/x64/i32_divs/zero_zero.wat | 13 ++-- .../filetests/x64/i32_divu/const.wat | 11 ++-- .../filetests/x64/i32_divu/one_zero.wat | 11 ++-- .../filetests/x64/i32_divu/params.wat | 13 ++-- .../filetests/x64/i32_divu/signed.wat | 11 ++-- .../filetests/x64/i32_divu/zero_zero.wat | 11 ++-- .../filetests/x64/i32_rems/const.wat | 21 +++---- .../filetests/x64/i32_rems/one_zero.wat | 21 +++---- .../filetests/x64/i32_rems/overflow.wat | 21 +++---- .../filetests/x64/i32_rems/params.wat | 23 +++---- .../filetests/x64/i32_rems/zero_zero.wat | 21 +++---- .../filetests/x64/i32_remu/const.wat | 13 ++-- .../filetests/x64/i32_remu/one_zero.wat | 13 ++-- .../filetests/x64/i32_remu/params.wat | 15 ++--- .../filetests/x64/i32_remu/signed.wat | 13 ++-- .../filetests/x64/i32_remu/zero_zero.wat | 13 ++-- .../filetests/x64/i64_divs/const.wat | 15 ++--- .../filetests/x64/i64_divs/one_zero.wat | 15 ++--- .../filetests/x64/i64_divs/overflow.wat | 15 ++--- .../filetests/x64/i64_divs/params.wat | 17 ++--- .../filetests/x64/i64_divs/zero_zero.wat | 15 ++--- .../filetests/x64/i64_divu/const.wat | 11 ++-- .../filetests/x64/i64_divu/one_zero.wat | 11 ++-- .../filetests/x64/i64_divu/params.wat | 13 ++-- .../filetests/x64/i64_divu/signed.wat | 11 ++-- .../filetests/x64/i64_divu/zero_zero.wat | 11 ++-- .../filetests/x64/i64_rems/const.wat | 21 +++---- .../filetests/x64/i64_rems/one_zero.wat | 21 +++---- .../filetests/x64/i64_rems/overflow.wat | 21 +++---- .../filetests/x64/i64_rems/params.wat | 23 +++---- .../filetests/x64/i64_rems/zero_zero.wat | 21 +++---- .../filetests/x64/i64_remu/const.wat | 13 ++-- .../filetests/x64/i64_remu/one_zero.wat | 13 ++-- .../filetests/x64/i64_remu/params.wat | 15 ++--- .../filetests/x64/i64_remu/signed.wat | 13 ++-- .../filetests/x64/i64_remu/zero_zero.wat | 13 ++-- 41 files changed, 252 insertions(+), 417 deletions(-) diff --git a/winch/codegen/src/isa/x64/asm.rs b/winch/codegen/src/isa/x64/asm.rs index f60dde22d617..c6a2548c8622 100644 --- a/winch/codegen/src/isa/x64/asm.rs +++ b/winch/codegen/src/isa/x64/asm.rs @@ -282,34 +282,13 @@ impl Assembler { /// caller has correctly allocated the dividend as `(rdx:rax)` and /// accounted for the quotient to be stored in `rax`. pub fn div(&mut self, divisor: Reg, dst: (Reg, Reg), kind: DivKind, size: OperandSize) { - match kind { - // Signed division goes through a pseudo-instruction to validate - // the divisor followed by a sign extension to initialize `rdx`. + let trap = match kind { + // Signed division has two trapping conditions, integer overflow and + // divide-by-zero. Check for divide-by-zero explicitly and let the + // hardware detect overflow. + // + // The dividend is sign extended to initialize `rdx`. DivKind::Signed => { - if size == OperandSize::S64 { - self.emit(Inst::ValidateSdivDivisor64 { - dividend: dst.0.into(), - divisor: divisor.into(), - tmp: regs::scratch().into(), - }); - } else { - self.emit(Inst::ValidateSdivDivisor { - dividend: dst.0.into(), - divisor: divisor.into(), - size: size.into(), - }); - } - self.emit(Inst::SignExtendData { - size: size.into(), - src: dst.0.into(), - dst: dst.1.into(), - }); - } - - // Unsigned division only needs to check for 0 and then the `rdx` - // divisor_hi is initialized with zero through an xor-against-itself - // op. - DivKind::Unsigned => { self.emit(Inst::CmpRmiR { size: size.into(), src: GprMemImm::new(RegMemImm::imm(0)).unwrap(), @@ -320,6 +299,20 @@ impl Assembler { cc: CC::Z, trap_code: TrapCode::IntegerDivisionByZero, }); + self.emit(Inst::SignExtendData { + size: size.into(), + src: dst.0.into(), + dst: dst.1.into(), + }); + TrapCode::IntegerOverflow + } + + // Unsigned division only traps in one case, on divide-by-zero, so + // defer that to the trap opcode. + // + // The divisor_hi reg is initialized with zero through an + // xor-against-itself op. + DivKind::Unsigned => { self.emit(Inst::AluRmiR { size: size.into(), op: AluRmiROpcode::Xor, @@ -327,11 +320,13 @@ impl Assembler { src2: dst.1.into(), dst: dst.1.into(), }); + TrapCode::IntegerDivisionByZero } - } + }; self.emit(Inst::Div { sign: kind.into(), size: size.into(), + trap, divisor: GprMem::new(RegMem::reg(divisor.into())).unwrap(), dividend_lo: dst.0.into(), dividend_hi: dst.1.into(), @@ -348,17 +343,6 @@ impl Assembler { /// caller has correctly allocated the dividend as `(rdx:rax)` and /// accounted for the remainder to be stored in `rdx`. pub fn rem(&mut self, divisor: Reg, dst: (Reg, Reg), kind: RemKind, size: OperandSize) { - // First check for zero and explicitly trap. - self.emit(Inst::CmpRmiR { - size: size.into(), - src: GprMemImm::new(RegMemImm::imm(0)).unwrap(), - dst: divisor.into(), - opcode: CmpOpcode::Cmp, - }); - self.emit(Inst::TrapIf { - cc: CC::Z, - trap_code: TrapCode::IntegerDivisionByZero, - }); match kind { // Signed remainder goes through a pseudo-instruction which has // some internal branching. The `dividend_hi`, or `rdx`, is @@ -391,6 +375,7 @@ impl Assembler { }); self.emit(Inst::Div { sign: DivSignedness::Unsigned, + trap: TrapCode::IntegerDivisionByZero, size: size.into(), divisor: GprMem::new(RegMem::reg(divisor.into())).unwrap(), dividend_lo: dst.0.into(), diff --git a/winch/filetests/filetests/x64/i32_divs/const.wat b/winch/filetests/filetests/x64/i32_divs/const.wat index c32078198f74..cd9be27f2dd6 100644 --- a/winch/filetests/filetests/x64/i32_divs/const.wat +++ b/winch/filetests/filetests/x64/i32_divs/const.wat @@ -14,12 +14,7 @@ ;; e: 83f900 cmp ecx, 0 ;; 11: 0f8502000000 jne 0x19 ;; 17: 0f0b ud2 -;; 19: 83f9ff cmp ecx, -1 -;; 1c: 0f850e000000 jne 0x30 -;; 22: 81f800000080 cmp eax, 0x80000000 -;; 28: 0f8502000000 jne 0x30 -;; 2e: 0f0b ud2 -;; 30: 99 cdq -;; 31: f7f9 idiv ecx -;; 33: 5d pop rbp -;; 34: c3 ret +;; 19: 99 cdq +;; 1a: f7f9 idiv ecx +;; 1c: 5d pop rbp +;; 1d: c3 ret diff --git a/winch/filetests/filetests/x64/i32_divs/one_zero.wat b/winch/filetests/filetests/x64/i32_divs/one_zero.wat index 1ef0d78855ec..6b3094ea6538 100644 --- a/winch/filetests/filetests/x64/i32_divs/one_zero.wat +++ b/winch/filetests/filetests/x64/i32_divs/one_zero.wat @@ -14,12 +14,7 @@ ;; e: 83f900 cmp ecx, 0 ;; 11: 0f8502000000 jne 0x19 ;; 17: 0f0b ud2 -;; 19: 83f9ff cmp ecx, -1 -;; 1c: 0f850e000000 jne 0x30 -;; 22: 81f800000080 cmp eax, 0x80000000 -;; 28: 0f8502000000 jne 0x30 -;; 2e: 0f0b ud2 -;; 30: 99 cdq -;; 31: f7f9 idiv ecx -;; 33: 5d pop rbp -;; 34: c3 ret +;; 19: 99 cdq +;; 1a: f7f9 idiv ecx +;; 1c: 5d pop rbp +;; 1d: c3 ret diff --git a/winch/filetests/filetests/x64/i32_divs/overflow.wat b/winch/filetests/filetests/x64/i32_divs/overflow.wat index 7f2499a1b83d..33c7d05bb96f 100644 --- a/winch/filetests/filetests/x64/i32_divs/overflow.wat +++ b/winch/filetests/filetests/x64/i32_divs/overflow.wat @@ -14,12 +14,7 @@ ;; e: 83f900 cmp ecx, 0 ;; 11: 0f8502000000 jne 0x19 ;; 17: 0f0b ud2 -;; 19: 83f9ff cmp ecx, -1 -;; 1c: 0f850e000000 jne 0x30 -;; 22: 81f800000080 cmp eax, 0x80000000 -;; 28: 0f8502000000 jne 0x30 -;; 2e: 0f0b ud2 -;; 30: 99 cdq -;; 31: f7f9 idiv ecx -;; 33: 5d pop rbp -;; 34: c3 ret +;; 19: 99 cdq +;; 1a: f7f9 idiv ecx +;; 1c: 5d pop rbp +;; 1d: c3 ret diff --git a/winch/filetests/filetests/x64/i32_divs/params.wat b/winch/filetests/filetests/x64/i32_divs/params.wat index ec999077ba1c..cc3c25b8c1ab 100644 --- a/winch/filetests/filetests/x64/i32_divs/params.wat +++ b/winch/filetests/filetests/x64/i32_divs/params.wat @@ -17,13 +17,8 @@ ;; 16: 83f900 cmp ecx, 0 ;; 19: 0f8502000000 jne 0x21 ;; 1f: 0f0b ud2 -;; 21: 83f9ff cmp ecx, -1 -;; 24: 0f850e000000 jne 0x38 -;; 2a: 81f800000080 cmp eax, 0x80000000 -;; 30: 0f8502000000 jne 0x38 -;; 36: 0f0b ud2 -;; 38: 99 cdq -;; 39: f7f9 idiv ecx -;; 3b: 4883c408 add rsp, 8 -;; 3f: 5d pop rbp -;; 40: c3 ret +;; 21: 99 cdq +;; 22: f7f9 idiv ecx +;; 24: 4883c408 add rsp, 8 +;; 28: 5d pop rbp +;; 29: c3 ret diff --git a/winch/filetests/filetests/x64/i32_divs/zero_zero.wat b/winch/filetests/filetests/x64/i32_divs/zero_zero.wat index 807b7f7eb848..7158174ad62a 100644 --- a/winch/filetests/filetests/x64/i32_divs/zero_zero.wat +++ b/winch/filetests/filetests/x64/i32_divs/zero_zero.wat @@ -14,12 +14,7 @@ ;; e: 83f900 cmp ecx, 0 ;; 11: 0f8502000000 jne 0x19 ;; 17: 0f0b ud2 -;; 19: 83f9ff cmp ecx, -1 -;; 1c: 0f850e000000 jne 0x30 -;; 22: 81f800000080 cmp eax, 0x80000000 -;; 28: 0f8502000000 jne 0x30 -;; 2e: 0f0b ud2 -;; 30: 99 cdq -;; 31: f7f9 idiv ecx -;; 33: 5d pop rbp -;; 34: c3 ret +;; 19: 99 cdq +;; 1a: f7f9 idiv ecx +;; 1c: 5d pop rbp +;; 1d: c3 ret diff --git a/winch/filetests/filetests/x64/i32_divu/const.wat b/winch/filetests/filetests/x64/i32_divu/const.wat index 3ba1c3dbb8db..a2bbfd014091 100644 --- a/winch/filetests/filetests/x64/i32_divu/const.wat +++ b/winch/filetests/filetests/x64/i32_divu/const.wat @@ -11,10 +11,7 @@ ;; 1: 4889e5 mov rbp, rsp ;; 4: b90a000000 mov ecx, 0xa ;; 9: b814000000 mov eax, 0x14 -;; e: 83f900 cmp ecx, 0 -;; 11: 0f8502000000 jne 0x19 -;; 17: 0f0b ud2 -;; 19: 31d2 xor edx, edx -;; 1b: f7f1 div ecx -;; 1d: 5d pop rbp -;; 1e: c3 ret +;; e: 31d2 xor edx, edx +;; 10: f7f1 div ecx +;; 12: 5d pop rbp +;; 13: c3 ret diff --git a/winch/filetests/filetests/x64/i32_divu/one_zero.wat b/winch/filetests/filetests/x64/i32_divu/one_zero.wat index 938f787785be..3f3de081ea14 100644 --- a/winch/filetests/filetests/x64/i32_divu/one_zero.wat +++ b/winch/filetests/filetests/x64/i32_divu/one_zero.wat @@ -11,10 +11,7 @@ ;; 1: 4889e5 mov rbp, rsp ;; 4: b900000000 mov ecx, 0 ;; 9: b801000000 mov eax, 1 -;; e: 83f900 cmp ecx, 0 -;; 11: 0f8502000000 jne 0x19 -;; 17: 0f0b ud2 -;; 19: 31d2 xor edx, edx -;; 1b: f7f1 div ecx -;; 1d: 5d pop rbp -;; 1e: c3 ret +;; e: 31d2 xor edx, edx +;; 10: f7f1 div ecx +;; 12: 5d pop rbp +;; 13: c3 ret diff --git a/winch/filetests/filetests/x64/i32_divu/params.wat b/winch/filetests/filetests/x64/i32_divu/params.wat index e732e05bc873..a566659c1897 100644 --- a/winch/filetests/filetests/x64/i32_divu/params.wat +++ b/winch/filetests/filetests/x64/i32_divu/params.wat @@ -14,11 +14,8 @@ ;; c: 893424 mov dword ptr [rsp], esi ;; f: 8b0c24 mov ecx, dword ptr [rsp] ;; 12: 8b442404 mov eax, dword ptr [rsp + 4] -;; 16: 83f900 cmp ecx, 0 -;; 19: 0f8502000000 jne 0x21 -;; 1f: 0f0b ud2 -;; 21: 31d2 xor edx, edx -;; 23: f7f1 div ecx -;; 25: 4883c408 add rsp, 8 -;; 29: 5d pop rbp -;; 2a: c3 ret +;; 16: 31d2 xor edx, edx +;; 18: f7f1 div ecx +;; 1a: 4883c408 add rsp, 8 +;; 1e: 5d pop rbp +;; 1f: c3 ret diff --git a/winch/filetests/filetests/x64/i32_divu/signed.wat b/winch/filetests/filetests/x64/i32_divu/signed.wat index ce39cff780a4..a0b91f279f22 100644 --- a/winch/filetests/filetests/x64/i32_divu/signed.wat +++ b/winch/filetests/filetests/x64/i32_divu/signed.wat @@ -11,10 +11,7 @@ ;; 1: 4889e5 mov rbp, rsp ;; 4: b9ffffffff mov ecx, 0xffffffff ;; 9: b8ffffffff mov eax, 0xffffffff -;; e: 83f900 cmp ecx, 0 -;; 11: 0f8502000000 jne 0x19 -;; 17: 0f0b ud2 -;; 19: 31d2 xor edx, edx -;; 1b: f7f1 div ecx -;; 1d: 5d pop rbp -;; 1e: c3 ret +;; e: 31d2 xor edx, edx +;; 10: f7f1 div ecx +;; 12: 5d pop rbp +;; 13: c3 ret diff --git a/winch/filetests/filetests/x64/i32_divu/zero_zero.wat b/winch/filetests/filetests/x64/i32_divu/zero_zero.wat index 418d084329bd..e78558a66832 100644 --- a/winch/filetests/filetests/x64/i32_divu/zero_zero.wat +++ b/winch/filetests/filetests/x64/i32_divu/zero_zero.wat @@ -11,10 +11,7 @@ ;; 1: 4889e5 mov rbp, rsp ;; 4: b900000000 mov ecx, 0 ;; 9: b800000000 mov eax, 0 -;; e: 83f900 cmp ecx, 0 -;; 11: 0f8502000000 jne 0x19 -;; 17: 0f0b ud2 -;; 19: 31d2 xor edx, edx -;; 1b: f7f1 div ecx -;; 1d: 5d pop rbp -;; 1e: c3 ret +;; e: 31d2 xor edx, edx +;; 10: f7f1 div ecx +;; 12: 5d pop rbp +;; 13: c3 ret diff --git a/winch/filetests/filetests/x64/i32_rems/const.wat b/winch/filetests/filetests/x64/i32_rems/const.wat index 1edb0d89625e..221b810c52c6 100644 --- a/winch/filetests/filetests/x64/i32_rems/const.wat +++ b/winch/filetests/filetests/x64/i32_rems/const.wat @@ -11,15 +11,12 @@ ;; 1: 4889e5 mov rbp, rsp ;; 4: b905000000 mov ecx, 5 ;; 9: b807000000 mov eax, 7 -;; e: 83f900 cmp ecx, 0 -;; 11: 0f8502000000 jne 0x19 -;; 17: 0f0b ud2 -;; 19: 99 cdq -;; 1a: 83f9ff cmp ecx, -1 -;; 1d: 0f850a000000 jne 0x2d -;; 23: ba00000000 mov edx, 0 -;; 28: e902000000 jmp 0x2f -;; 2d: f7f9 idiv ecx -;; 2f: 4889d0 mov rax, rdx -;; 32: 5d pop rbp -;; 33: c3 ret +;; e: 99 cdq +;; f: 83f9ff cmp ecx, -1 +;; 12: 0f850a000000 jne 0x22 +;; 18: ba00000000 mov edx, 0 +;; 1d: e902000000 jmp 0x24 +;; 22: f7f9 idiv ecx +;; 24: 4889d0 mov rax, rdx +;; 27: 5d pop rbp +;; 28: c3 ret diff --git a/winch/filetests/filetests/x64/i32_rems/one_zero.wat b/winch/filetests/filetests/x64/i32_rems/one_zero.wat index 3b618c3c1002..d8569b3c0983 100644 --- a/winch/filetests/filetests/x64/i32_rems/one_zero.wat +++ b/winch/filetests/filetests/x64/i32_rems/one_zero.wat @@ -11,15 +11,12 @@ ;; 1: 4889e5 mov rbp, rsp ;; 4: b900000000 mov ecx, 0 ;; 9: b801000000 mov eax, 1 -;; e: 83f900 cmp ecx, 0 -;; 11: 0f8502000000 jne 0x19 -;; 17: 0f0b ud2 -;; 19: 99 cdq -;; 1a: 83f9ff cmp ecx, -1 -;; 1d: 0f850a000000 jne 0x2d -;; 23: ba00000000 mov edx, 0 -;; 28: e902000000 jmp 0x2f -;; 2d: f7f9 idiv ecx -;; 2f: 4889d0 mov rax, rdx -;; 32: 5d pop rbp -;; 33: c3 ret +;; e: 99 cdq +;; f: 83f9ff cmp ecx, -1 +;; 12: 0f850a000000 jne 0x22 +;; 18: ba00000000 mov edx, 0 +;; 1d: e902000000 jmp 0x24 +;; 22: f7f9 idiv ecx +;; 24: 4889d0 mov rax, rdx +;; 27: 5d pop rbp +;; 28: c3 ret diff --git a/winch/filetests/filetests/x64/i32_rems/overflow.wat b/winch/filetests/filetests/x64/i32_rems/overflow.wat index b42f2ce35d42..fcfed2582860 100644 --- a/winch/filetests/filetests/x64/i32_rems/overflow.wat +++ b/winch/filetests/filetests/x64/i32_rems/overflow.wat @@ -11,15 +11,12 @@ ;; 1: 4889e5 mov rbp, rsp ;; 4: b9ffffffff mov ecx, 0xffffffff ;; 9: b800000080 mov eax, 0x80000000 -;; e: 83f900 cmp ecx, 0 -;; 11: 0f8502000000 jne 0x19 -;; 17: 0f0b ud2 -;; 19: 99 cdq -;; 1a: 83f9ff cmp ecx, -1 -;; 1d: 0f850a000000 jne 0x2d -;; 23: ba00000000 mov edx, 0 -;; 28: e902000000 jmp 0x2f -;; 2d: f7f9 idiv ecx -;; 2f: 4889d0 mov rax, rdx -;; 32: 5d pop rbp -;; 33: c3 ret +;; e: 99 cdq +;; f: 83f9ff cmp ecx, -1 +;; 12: 0f850a000000 jne 0x22 +;; 18: ba00000000 mov edx, 0 +;; 1d: e902000000 jmp 0x24 +;; 22: f7f9 idiv ecx +;; 24: 4889d0 mov rax, rdx +;; 27: 5d pop rbp +;; 28: c3 ret diff --git a/winch/filetests/filetests/x64/i32_rems/params.wat b/winch/filetests/filetests/x64/i32_rems/params.wat index 752f5abee9c6..cfa264e0ff51 100644 --- a/winch/filetests/filetests/x64/i32_rems/params.wat +++ b/winch/filetests/filetests/x64/i32_rems/params.wat @@ -14,16 +14,13 @@ ;; c: 893424 mov dword ptr [rsp], esi ;; f: 8b0c24 mov ecx, dword ptr [rsp] ;; 12: 8b442404 mov eax, dword ptr [rsp + 4] -;; 16: 83f900 cmp ecx, 0 -;; 19: 0f8502000000 jne 0x21 -;; 1f: 0f0b ud2 -;; 21: 99 cdq -;; 22: 83f9ff cmp ecx, -1 -;; 25: 0f850a000000 jne 0x35 -;; 2b: ba00000000 mov edx, 0 -;; 30: e902000000 jmp 0x37 -;; 35: f7f9 idiv ecx -;; 37: 4889d0 mov rax, rdx -;; 3a: 4883c408 add rsp, 8 -;; 3e: 5d pop rbp -;; 3f: c3 ret +;; 16: 99 cdq +;; 17: 83f9ff cmp ecx, -1 +;; 1a: 0f850a000000 jne 0x2a +;; 20: ba00000000 mov edx, 0 +;; 25: e902000000 jmp 0x2c +;; 2a: f7f9 idiv ecx +;; 2c: 4889d0 mov rax, rdx +;; 2f: 4883c408 add rsp, 8 +;; 33: 5d pop rbp +;; 34: c3 ret diff --git a/winch/filetests/filetests/x64/i32_rems/zero_zero.wat b/winch/filetests/filetests/x64/i32_rems/zero_zero.wat index 01358814fb5e..5fff7d4a6836 100644 --- a/winch/filetests/filetests/x64/i32_rems/zero_zero.wat +++ b/winch/filetests/filetests/x64/i32_rems/zero_zero.wat @@ -11,15 +11,12 @@ ;; 1: 4889e5 mov rbp, rsp ;; 4: b900000000 mov ecx, 0 ;; 9: b800000000 mov eax, 0 -;; e: 83f900 cmp ecx, 0 -;; 11: 0f8502000000 jne 0x19 -;; 17: 0f0b ud2 -;; 19: 99 cdq -;; 1a: 83f9ff cmp ecx, -1 -;; 1d: 0f850a000000 jne 0x2d -;; 23: ba00000000 mov edx, 0 -;; 28: e902000000 jmp 0x2f -;; 2d: f7f9 idiv ecx -;; 2f: 4889d0 mov rax, rdx -;; 32: 5d pop rbp -;; 33: c3 ret +;; e: 99 cdq +;; f: 83f9ff cmp ecx, -1 +;; 12: 0f850a000000 jne 0x22 +;; 18: ba00000000 mov edx, 0 +;; 1d: e902000000 jmp 0x24 +;; 22: f7f9 idiv ecx +;; 24: 4889d0 mov rax, rdx +;; 27: 5d pop rbp +;; 28: c3 ret diff --git a/winch/filetests/filetests/x64/i32_remu/const.wat b/winch/filetests/filetests/x64/i32_remu/const.wat index bbcb387cb690..0a48c6c4c794 100644 --- a/winch/filetests/filetests/x64/i32_remu/const.wat +++ b/winch/filetests/filetests/x64/i32_remu/const.wat @@ -11,11 +11,8 @@ ;; 1: 4889e5 mov rbp, rsp ;; 4: b905000000 mov ecx, 5 ;; 9: b807000000 mov eax, 7 -;; e: 83f900 cmp ecx, 0 -;; 11: 0f8502000000 jne 0x19 -;; 17: 0f0b ud2 -;; 19: 31d2 xor edx, edx -;; 1b: f7f1 div ecx -;; 1d: 4889d0 mov rax, rdx -;; 20: 5d pop rbp -;; 21: c3 ret +;; e: 31d2 xor edx, edx +;; 10: f7f1 div ecx +;; 12: 4889d0 mov rax, rdx +;; 15: 5d pop rbp +;; 16: c3 ret diff --git a/winch/filetests/filetests/x64/i32_remu/one_zero.wat b/winch/filetests/filetests/x64/i32_remu/one_zero.wat index 404264c8633e..4b3975ab17c8 100644 --- a/winch/filetests/filetests/x64/i32_remu/one_zero.wat +++ b/winch/filetests/filetests/x64/i32_remu/one_zero.wat @@ -11,11 +11,8 @@ ;; 1: 4889e5 mov rbp, rsp ;; 4: b900000000 mov ecx, 0 ;; 9: b801000000 mov eax, 1 -;; e: 83f900 cmp ecx, 0 -;; 11: 0f8502000000 jne 0x19 -;; 17: 0f0b ud2 -;; 19: 31d2 xor edx, edx -;; 1b: f7f1 div ecx -;; 1d: 4889d0 mov rax, rdx -;; 20: 5d pop rbp -;; 21: c3 ret +;; e: 31d2 xor edx, edx +;; 10: f7f1 div ecx +;; 12: 4889d0 mov rax, rdx +;; 15: 5d pop rbp +;; 16: c3 ret diff --git a/winch/filetests/filetests/x64/i32_remu/params.wat b/winch/filetests/filetests/x64/i32_remu/params.wat index 9d6a2e632ebe..714217d78ed4 100644 --- a/winch/filetests/filetests/x64/i32_remu/params.wat +++ b/winch/filetests/filetests/x64/i32_remu/params.wat @@ -14,12 +14,9 @@ ;; c: 893424 mov dword ptr [rsp], esi ;; f: 8b0c24 mov ecx, dword ptr [rsp] ;; 12: 8b442404 mov eax, dword ptr [rsp + 4] -;; 16: 83f900 cmp ecx, 0 -;; 19: 0f8502000000 jne 0x21 -;; 1f: 0f0b ud2 -;; 21: 31d2 xor edx, edx -;; 23: f7f1 div ecx -;; 25: 4889d0 mov rax, rdx -;; 28: 4883c408 add rsp, 8 -;; 2c: 5d pop rbp -;; 2d: c3 ret +;; 16: 31d2 xor edx, edx +;; 18: f7f1 div ecx +;; 1a: 4889d0 mov rax, rdx +;; 1d: 4883c408 add rsp, 8 +;; 21: 5d pop rbp +;; 22: c3 ret diff --git a/winch/filetests/filetests/x64/i32_remu/signed.wat b/winch/filetests/filetests/x64/i32_remu/signed.wat index f886e5ac7c6b..85e83eb0ab40 100644 --- a/winch/filetests/filetests/x64/i32_remu/signed.wat +++ b/winch/filetests/filetests/x64/i32_remu/signed.wat @@ -11,11 +11,8 @@ ;; 1: 4889e5 mov rbp, rsp ;; 4: b9ffffffff mov ecx, 0xffffffff ;; 9: b8ffffffff mov eax, 0xffffffff -;; e: 83f900 cmp ecx, 0 -;; 11: 0f8502000000 jne 0x19 -;; 17: 0f0b ud2 -;; 19: 31d2 xor edx, edx -;; 1b: f7f1 div ecx -;; 1d: 4889d0 mov rax, rdx -;; 20: 5d pop rbp -;; 21: c3 ret +;; e: 31d2 xor edx, edx +;; 10: f7f1 div ecx +;; 12: 4889d0 mov rax, rdx +;; 15: 5d pop rbp +;; 16: c3 ret diff --git a/winch/filetests/filetests/x64/i32_remu/zero_zero.wat b/winch/filetests/filetests/x64/i32_remu/zero_zero.wat index 4654eafd47dc..c60bac6e3655 100644 --- a/winch/filetests/filetests/x64/i32_remu/zero_zero.wat +++ b/winch/filetests/filetests/x64/i32_remu/zero_zero.wat @@ -11,11 +11,8 @@ ;; 1: 4889e5 mov rbp, rsp ;; 4: b900000000 mov ecx, 0 ;; 9: b800000000 mov eax, 0 -;; e: 83f900 cmp ecx, 0 -;; 11: 0f8502000000 jne 0x19 -;; 17: 0f0b ud2 -;; 19: 31d2 xor edx, edx -;; 1b: f7f1 div ecx -;; 1d: 4889d0 mov rax, rdx -;; 20: 5d pop rbp -;; 21: c3 ret +;; e: 31d2 xor edx, edx +;; 10: f7f1 div ecx +;; 12: 4889d0 mov rax, rdx +;; 15: 5d pop rbp +;; 16: c3 ret diff --git a/winch/filetests/filetests/x64/i64_divs/const.wat b/winch/filetests/filetests/x64/i64_divs/const.wat index 840f1ad5f94e..4f2d67cb2751 100644 --- a/winch/filetests/filetests/x64/i64_divs/const.wat +++ b/winch/filetests/filetests/x64/i64_divs/const.wat @@ -14,14 +14,7 @@ ;; 12: 4883f900 cmp rcx, 0 ;; 16: 0f8502000000 jne 0x1e ;; 1c: 0f0b ud2 -;; 1e: 4883f9ff cmp rcx, -1 -;; 22: 0f8515000000 jne 0x3d -;; 28: 49bb0000000000000080 -;; movabs r11, 0x8000000000000000 -;; 32: 4c39d8 cmp rax, r11 -;; 35: 0f8502000000 jne 0x3d -;; 3b: 0f0b ud2 -;; 3d: 4899 cqo -;; 3f: 48f7f9 idiv rcx -;; 42: 5d pop rbp -;; 43: c3 ret +;; 1e: 4899 cqo +;; 20: 48f7f9 idiv rcx +;; 23: 5d pop rbp +;; 24: c3 ret diff --git a/winch/filetests/filetests/x64/i64_divs/one_zero.wat b/winch/filetests/filetests/x64/i64_divs/one_zero.wat index c274f531e03b..3c015643415a 100644 --- a/winch/filetests/filetests/x64/i64_divs/one_zero.wat +++ b/winch/filetests/filetests/x64/i64_divs/one_zero.wat @@ -14,14 +14,7 @@ ;; 12: 4883f900 cmp rcx, 0 ;; 16: 0f8502000000 jne 0x1e ;; 1c: 0f0b ud2 -;; 1e: 4883f9ff cmp rcx, -1 -;; 22: 0f8515000000 jne 0x3d -;; 28: 49bb0000000000000080 -;; movabs r11, 0x8000000000000000 -;; 32: 4c39d8 cmp rax, r11 -;; 35: 0f8502000000 jne 0x3d -;; 3b: 0f0b ud2 -;; 3d: 4899 cqo -;; 3f: 48f7f9 idiv rcx -;; 42: 5d pop rbp -;; 43: c3 ret +;; 1e: 4899 cqo +;; 20: 48f7f9 idiv rcx +;; 23: 5d pop rbp +;; 24: c3 ret diff --git a/winch/filetests/filetests/x64/i64_divs/overflow.wat b/winch/filetests/filetests/x64/i64_divs/overflow.wat index 18630116b10d..0161afa14af8 100644 --- a/winch/filetests/filetests/x64/i64_divs/overflow.wat +++ b/winch/filetests/filetests/x64/i64_divs/overflow.wat @@ -15,14 +15,7 @@ ;; 15: 4883f900 cmp rcx, 0 ;; 19: 0f8502000000 jne 0x21 ;; 1f: 0f0b ud2 -;; 21: 4883f9ff cmp rcx, -1 -;; 25: 0f8515000000 jne 0x40 -;; 2b: 49bb0000000000000080 -;; movabs r11, 0x8000000000000000 -;; 35: 4c39d8 cmp rax, r11 -;; 38: 0f8502000000 jne 0x40 -;; 3e: 0f0b ud2 -;; 40: 4899 cqo -;; 42: 48f7f9 idiv rcx -;; 45: 5d pop rbp -;; 46: c3 ret +;; 21: 4899 cqo +;; 23: 48f7f9 idiv rcx +;; 26: 5d pop rbp +;; 27: c3 ret diff --git a/winch/filetests/filetests/x64/i64_divs/params.wat b/winch/filetests/filetests/x64/i64_divs/params.wat index d52e28cff6d5..ee29c99b5e07 100644 --- a/winch/filetests/filetests/x64/i64_divs/params.wat +++ b/winch/filetests/filetests/x64/i64_divs/params.wat @@ -17,15 +17,8 @@ ;; 1a: 4883f900 cmp rcx, 0 ;; 1e: 0f8502000000 jne 0x26 ;; 24: 0f0b ud2 -;; 26: 4883f9ff cmp rcx, -1 -;; 2a: 0f8515000000 jne 0x45 -;; 30: 49bb0000000000000080 -;; movabs r11, 0x8000000000000000 -;; 3a: 4c39d8 cmp rax, r11 -;; 3d: 0f8502000000 jne 0x45 -;; 43: 0f0b ud2 -;; 45: 4899 cqo -;; 47: 48f7f9 idiv rcx -;; 4a: 4883c410 add rsp, 0x10 -;; 4e: 5d pop rbp -;; 4f: c3 ret +;; 26: 4899 cqo +;; 28: 48f7f9 idiv rcx +;; 2b: 4883c410 add rsp, 0x10 +;; 2f: 5d pop rbp +;; 30: c3 ret diff --git a/winch/filetests/filetests/x64/i64_divs/zero_zero.wat b/winch/filetests/filetests/x64/i64_divs/zero_zero.wat index 4a08ab105348..82069945101d 100644 --- a/winch/filetests/filetests/x64/i64_divs/zero_zero.wat +++ b/winch/filetests/filetests/x64/i64_divs/zero_zero.wat @@ -14,14 +14,7 @@ ;; 12: 4883f900 cmp rcx, 0 ;; 16: 0f8502000000 jne 0x1e ;; 1c: 0f0b ud2 -;; 1e: 4883f9ff cmp rcx, -1 -;; 22: 0f8515000000 jne 0x3d -;; 28: 49bb0000000000000080 -;; movabs r11, 0x8000000000000000 -;; 32: 4c39d8 cmp rax, r11 -;; 35: 0f8502000000 jne 0x3d -;; 3b: 0f0b ud2 -;; 3d: 4899 cqo -;; 3f: 48f7f9 idiv rcx -;; 42: 5d pop rbp -;; 43: c3 ret +;; 1e: 4899 cqo +;; 20: 48f7f9 idiv rcx +;; 23: 5d pop rbp +;; 24: c3 ret diff --git a/winch/filetests/filetests/x64/i64_divu/const.wat b/winch/filetests/filetests/x64/i64_divu/const.wat index c44bc609153f..ba7bf6507a9d 100644 --- a/winch/filetests/filetests/x64/i64_divu/const.wat +++ b/winch/filetests/filetests/x64/i64_divu/const.wat @@ -11,10 +11,7 @@ ;; 1: 4889e5 mov rbp, rsp ;; 4: 48c7c10a000000 mov rcx, 0xa ;; b: 48c7c014000000 mov rax, 0x14 -;; 12: 4883f900 cmp rcx, 0 -;; 16: 0f8502000000 jne 0x1e -;; 1c: 0f0b ud2 -;; 1e: 4831d2 xor rdx, rdx -;; 21: 48f7f1 div rcx -;; 24: 5d pop rbp -;; 25: c3 ret +;; 12: 4831d2 xor rdx, rdx +;; 15: 48f7f1 div rcx +;; 18: 5d pop rbp +;; 19: c3 ret diff --git a/winch/filetests/filetests/x64/i64_divu/one_zero.wat b/winch/filetests/filetests/x64/i64_divu/one_zero.wat index 7c5accf2369e..13ed6781516e 100644 --- a/winch/filetests/filetests/x64/i64_divu/one_zero.wat +++ b/winch/filetests/filetests/x64/i64_divu/one_zero.wat @@ -11,10 +11,7 @@ ;; 1: 4889e5 mov rbp, rsp ;; 4: 48c7c100000000 mov rcx, 0 ;; b: 48c7c001000000 mov rax, 1 -;; 12: 4883f900 cmp rcx, 0 -;; 16: 0f8502000000 jne 0x1e -;; 1c: 0f0b ud2 -;; 1e: 4831d2 xor rdx, rdx -;; 21: 48f7f1 div rcx -;; 24: 5d pop rbp -;; 25: c3 ret +;; 12: 4831d2 xor rdx, rdx +;; 15: 48f7f1 div rcx +;; 18: 5d pop rbp +;; 19: c3 ret diff --git a/winch/filetests/filetests/x64/i64_divu/params.wat b/winch/filetests/filetests/x64/i64_divu/params.wat index 8dfbdbe85bdb..2c4e612b029d 100644 --- a/winch/filetests/filetests/x64/i64_divu/params.wat +++ b/winch/filetests/filetests/x64/i64_divu/params.wat @@ -14,11 +14,8 @@ ;; d: 48893424 mov qword ptr [rsp], rsi ;; 11: 488b0c24 mov rcx, qword ptr [rsp] ;; 15: 488b442408 mov rax, qword ptr [rsp + 8] -;; 1a: 4883f900 cmp rcx, 0 -;; 1e: 0f8502000000 jne 0x26 -;; 24: 0f0b ud2 -;; 26: 4831d2 xor rdx, rdx -;; 29: 48f7f1 div rcx -;; 2c: 4883c410 add rsp, 0x10 -;; 30: 5d pop rbp -;; 31: c3 ret +;; 1a: 4831d2 xor rdx, rdx +;; 1d: 48f7f1 div rcx +;; 20: 4883c410 add rsp, 0x10 +;; 24: 5d pop rbp +;; 25: c3 ret diff --git a/winch/filetests/filetests/x64/i64_divu/signed.wat b/winch/filetests/filetests/x64/i64_divu/signed.wat index af7cc2d2089d..28208571a62c 100644 --- a/winch/filetests/filetests/x64/i64_divu/signed.wat +++ b/winch/filetests/filetests/x64/i64_divu/signed.wat @@ -11,10 +11,7 @@ ;; 1: 4889e5 mov rbp, rsp ;; 4: 48c7c1ffffffff mov rcx, 0xffffffffffffffff ;; b: 48c7c0ffffffff mov rax, 0xffffffffffffffff -;; 12: 4883f900 cmp rcx, 0 -;; 16: 0f8502000000 jne 0x1e -;; 1c: 0f0b ud2 -;; 1e: 4831d2 xor rdx, rdx -;; 21: 48f7f1 div rcx -;; 24: 5d pop rbp -;; 25: c3 ret +;; 12: 4831d2 xor rdx, rdx +;; 15: 48f7f1 div rcx +;; 18: 5d pop rbp +;; 19: c3 ret diff --git a/winch/filetests/filetests/x64/i64_divu/zero_zero.wat b/winch/filetests/filetests/x64/i64_divu/zero_zero.wat index 458e4965af7d..e8c119a9ae1e 100644 --- a/winch/filetests/filetests/x64/i64_divu/zero_zero.wat +++ b/winch/filetests/filetests/x64/i64_divu/zero_zero.wat @@ -11,10 +11,7 @@ ;; 1: 4889e5 mov rbp, rsp ;; 4: 48c7c100000000 mov rcx, 0 ;; b: 48c7c000000000 mov rax, 0 -;; 12: 4883f900 cmp rcx, 0 -;; 16: 0f8502000000 jne 0x1e -;; 1c: 0f0b ud2 -;; 1e: 4831d2 xor rdx, rdx -;; 21: 48f7f1 div rcx -;; 24: 5d pop rbp -;; 25: c3 ret +;; 12: 4831d2 xor rdx, rdx +;; 15: 48f7f1 div rcx +;; 18: 5d pop rbp +;; 19: c3 ret diff --git a/winch/filetests/filetests/x64/i64_rems/const.wat b/winch/filetests/filetests/x64/i64_rems/const.wat index f8e1c343951c..ad6182c23117 100644 --- a/winch/filetests/filetests/x64/i64_rems/const.wat +++ b/winch/filetests/filetests/x64/i64_rems/const.wat @@ -11,15 +11,12 @@ ;; 1: 4889e5 mov rbp, rsp ;; 4: 48c7c105000000 mov rcx, 5 ;; b: 48c7c007000000 mov rax, 7 -;; 12: 4883f900 cmp rcx, 0 -;; 16: 0f8502000000 jne 0x1e -;; 1c: 0f0b ud2 -;; 1e: 4899 cqo -;; 20: 4883f9ff cmp rcx, -1 -;; 24: 0f850a000000 jne 0x34 -;; 2a: ba00000000 mov edx, 0 -;; 2f: e903000000 jmp 0x37 -;; 34: 48f7f9 idiv rcx -;; 37: 4889d0 mov rax, rdx -;; 3a: 5d pop rbp -;; 3b: c3 ret +;; 12: 4899 cqo +;; 14: 4883f9ff cmp rcx, -1 +;; 18: 0f850a000000 jne 0x28 +;; 1e: ba00000000 mov edx, 0 +;; 23: e903000000 jmp 0x2b +;; 28: 48f7f9 idiv rcx +;; 2b: 4889d0 mov rax, rdx +;; 2e: 5d pop rbp +;; 2f: c3 ret diff --git a/winch/filetests/filetests/x64/i64_rems/one_zero.wat b/winch/filetests/filetests/x64/i64_rems/one_zero.wat index 3ef0f3289fd7..0ac94edd6e58 100644 --- a/winch/filetests/filetests/x64/i64_rems/one_zero.wat +++ b/winch/filetests/filetests/x64/i64_rems/one_zero.wat @@ -11,15 +11,12 @@ ;; 1: 4889e5 mov rbp, rsp ;; 4: 48c7c100000000 mov rcx, 0 ;; b: 48c7c001000000 mov rax, 1 -;; 12: 4883f900 cmp rcx, 0 -;; 16: 0f8502000000 jne 0x1e -;; 1c: 0f0b ud2 -;; 1e: 4899 cqo -;; 20: 4883f9ff cmp rcx, -1 -;; 24: 0f850a000000 jne 0x34 -;; 2a: ba00000000 mov edx, 0 -;; 2f: e903000000 jmp 0x37 -;; 34: 48f7f9 idiv rcx -;; 37: 4889d0 mov rax, rdx -;; 3a: 5d pop rbp -;; 3b: c3 ret +;; 12: 4899 cqo +;; 14: 4883f9ff cmp rcx, -1 +;; 18: 0f850a000000 jne 0x28 +;; 1e: ba00000000 mov edx, 0 +;; 23: e903000000 jmp 0x2b +;; 28: 48f7f9 idiv rcx +;; 2b: 4889d0 mov rax, rdx +;; 2e: 5d pop rbp +;; 2f: c3 ret diff --git a/winch/filetests/filetests/x64/i64_rems/overflow.wat b/winch/filetests/filetests/x64/i64_rems/overflow.wat index d3c69a9c638e..6de1bfe75dc2 100644 --- a/winch/filetests/filetests/x64/i64_rems/overflow.wat +++ b/winch/filetests/filetests/x64/i64_rems/overflow.wat @@ -12,15 +12,12 @@ ;; 4: 48c7c1ffffffff mov rcx, 0xffffffffffffffff ;; b: 48b80000000000000080 ;; movabs rax, 0x8000000000000000 -;; 15: 4883f900 cmp rcx, 0 -;; 19: 0f8502000000 jne 0x21 -;; 1f: 0f0b ud2 -;; 21: 4899 cqo -;; 23: 4883f9ff cmp rcx, -1 -;; 27: 0f850a000000 jne 0x37 -;; 2d: ba00000000 mov edx, 0 -;; 32: e903000000 jmp 0x3a -;; 37: 48f7f9 idiv rcx -;; 3a: 4889d0 mov rax, rdx -;; 3d: 5d pop rbp -;; 3e: c3 ret +;; 15: 4899 cqo +;; 17: 4883f9ff cmp rcx, -1 +;; 1b: 0f850a000000 jne 0x2b +;; 21: ba00000000 mov edx, 0 +;; 26: e903000000 jmp 0x2e +;; 2b: 48f7f9 idiv rcx +;; 2e: 4889d0 mov rax, rdx +;; 31: 5d pop rbp +;; 32: c3 ret diff --git a/winch/filetests/filetests/x64/i64_rems/params.wat b/winch/filetests/filetests/x64/i64_rems/params.wat index 9851aa14c4a7..222b54efa0b0 100644 --- a/winch/filetests/filetests/x64/i64_rems/params.wat +++ b/winch/filetests/filetests/x64/i64_rems/params.wat @@ -14,16 +14,13 @@ ;; d: 48893424 mov qword ptr [rsp], rsi ;; 11: 488b0c24 mov rcx, qword ptr [rsp] ;; 15: 488b442408 mov rax, qword ptr [rsp + 8] -;; 1a: 4883f900 cmp rcx, 0 -;; 1e: 0f8502000000 jne 0x26 -;; 24: 0f0b ud2 -;; 26: 4899 cqo -;; 28: 4883f9ff cmp rcx, -1 -;; 2c: 0f850a000000 jne 0x3c -;; 32: ba00000000 mov edx, 0 -;; 37: e903000000 jmp 0x3f -;; 3c: 48f7f9 idiv rcx -;; 3f: 4889d0 mov rax, rdx -;; 42: 4883c410 add rsp, 0x10 -;; 46: 5d pop rbp -;; 47: c3 ret +;; 1a: 4899 cqo +;; 1c: 4883f9ff cmp rcx, -1 +;; 20: 0f850a000000 jne 0x30 +;; 26: ba00000000 mov edx, 0 +;; 2b: e903000000 jmp 0x33 +;; 30: 48f7f9 idiv rcx +;; 33: 4889d0 mov rax, rdx +;; 36: 4883c410 add rsp, 0x10 +;; 3a: 5d pop rbp +;; 3b: c3 ret diff --git a/winch/filetests/filetests/x64/i64_rems/zero_zero.wat b/winch/filetests/filetests/x64/i64_rems/zero_zero.wat index 3a745e384a41..e3f24719a855 100644 --- a/winch/filetests/filetests/x64/i64_rems/zero_zero.wat +++ b/winch/filetests/filetests/x64/i64_rems/zero_zero.wat @@ -11,15 +11,12 @@ ;; 1: 4889e5 mov rbp, rsp ;; 4: 48c7c100000000 mov rcx, 0 ;; b: 48c7c000000000 mov rax, 0 -;; 12: 4883f900 cmp rcx, 0 -;; 16: 0f8502000000 jne 0x1e -;; 1c: 0f0b ud2 -;; 1e: 4899 cqo -;; 20: 4883f9ff cmp rcx, -1 -;; 24: 0f850a000000 jne 0x34 -;; 2a: ba00000000 mov edx, 0 -;; 2f: e903000000 jmp 0x37 -;; 34: 48f7f9 idiv rcx -;; 37: 4889d0 mov rax, rdx -;; 3a: 5d pop rbp -;; 3b: c3 ret +;; 12: 4899 cqo +;; 14: 4883f9ff cmp rcx, -1 +;; 18: 0f850a000000 jne 0x28 +;; 1e: ba00000000 mov edx, 0 +;; 23: e903000000 jmp 0x2b +;; 28: 48f7f9 idiv rcx +;; 2b: 4889d0 mov rax, rdx +;; 2e: 5d pop rbp +;; 2f: c3 ret diff --git a/winch/filetests/filetests/x64/i64_remu/const.wat b/winch/filetests/filetests/x64/i64_remu/const.wat index 3b86a6769f67..101877d1348c 100644 --- a/winch/filetests/filetests/x64/i64_remu/const.wat +++ b/winch/filetests/filetests/x64/i64_remu/const.wat @@ -11,11 +11,8 @@ ;; 1: 4889e5 mov rbp, rsp ;; 4: 48c7c105000000 mov rcx, 5 ;; b: 48c7c007000000 mov rax, 7 -;; 12: 4883f900 cmp rcx, 0 -;; 16: 0f8502000000 jne 0x1e -;; 1c: 0f0b ud2 -;; 1e: 4831d2 xor rdx, rdx -;; 21: 48f7f1 div rcx -;; 24: 4889d0 mov rax, rdx -;; 27: 5d pop rbp -;; 28: c3 ret +;; 12: 4831d2 xor rdx, rdx +;; 15: 48f7f1 div rcx +;; 18: 4889d0 mov rax, rdx +;; 1b: 5d pop rbp +;; 1c: c3 ret diff --git a/winch/filetests/filetests/x64/i64_remu/one_zero.wat b/winch/filetests/filetests/x64/i64_remu/one_zero.wat index e31033b33cda..5af4f5989bfd 100644 --- a/winch/filetests/filetests/x64/i64_remu/one_zero.wat +++ b/winch/filetests/filetests/x64/i64_remu/one_zero.wat @@ -11,11 +11,8 @@ ;; 1: 4889e5 mov rbp, rsp ;; 4: 48c7c100000000 mov rcx, 0 ;; b: 48c7c001000000 mov rax, 1 -;; 12: 4883f900 cmp rcx, 0 -;; 16: 0f8502000000 jne 0x1e -;; 1c: 0f0b ud2 -;; 1e: 4831d2 xor rdx, rdx -;; 21: 48f7f1 div rcx -;; 24: 4889d0 mov rax, rdx -;; 27: 5d pop rbp -;; 28: c3 ret +;; 12: 4831d2 xor rdx, rdx +;; 15: 48f7f1 div rcx +;; 18: 4889d0 mov rax, rdx +;; 1b: 5d pop rbp +;; 1c: c3 ret diff --git a/winch/filetests/filetests/x64/i64_remu/params.wat b/winch/filetests/filetests/x64/i64_remu/params.wat index 773debc84101..4d6d4abce40d 100644 --- a/winch/filetests/filetests/x64/i64_remu/params.wat +++ b/winch/filetests/filetests/x64/i64_remu/params.wat @@ -14,12 +14,9 @@ ;; d: 48893424 mov qword ptr [rsp], rsi ;; 11: 488b0c24 mov rcx, qword ptr [rsp] ;; 15: 488b442408 mov rax, qword ptr [rsp + 8] -;; 1a: 4883f900 cmp rcx, 0 -;; 1e: 0f8502000000 jne 0x26 -;; 24: 0f0b ud2 -;; 26: 4831d2 xor rdx, rdx -;; 29: 48f7f1 div rcx -;; 2c: 4889d0 mov rax, rdx -;; 2f: 4883c410 add rsp, 0x10 -;; 33: 5d pop rbp -;; 34: c3 ret +;; 1a: 4831d2 xor rdx, rdx +;; 1d: 48f7f1 div rcx +;; 20: 4889d0 mov rax, rdx +;; 23: 4883c410 add rsp, 0x10 +;; 27: 5d pop rbp +;; 28: c3 ret diff --git a/winch/filetests/filetests/x64/i64_remu/signed.wat b/winch/filetests/filetests/x64/i64_remu/signed.wat index 77b185982443..2556ecfcc850 100644 --- a/winch/filetests/filetests/x64/i64_remu/signed.wat +++ b/winch/filetests/filetests/x64/i64_remu/signed.wat @@ -11,11 +11,8 @@ ;; 1: 4889e5 mov rbp, rsp ;; 4: 48c7c1ffffffff mov rcx, 0xffffffffffffffff ;; b: 48c7c0ffffffff mov rax, 0xffffffffffffffff -;; 12: 4883f900 cmp rcx, 0 -;; 16: 0f8502000000 jne 0x1e -;; 1c: 0f0b ud2 -;; 1e: 4831d2 xor rdx, rdx -;; 21: 48f7f1 div rcx -;; 24: 4889d0 mov rax, rdx -;; 27: 5d pop rbp -;; 28: c3 ret +;; 12: 4831d2 xor rdx, rdx +;; 15: 48f7f1 div rcx +;; 18: 4889d0 mov rax, rdx +;; 1b: 5d pop rbp +;; 1c: c3 ret diff --git a/winch/filetests/filetests/x64/i64_remu/zero_zero.wat b/winch/filetests/filetests/x64/i64_remu/zero_zero.wat index df358d922717..18983cd085e6 100644 --- a/winch/filetests/filetests/x64/i64_remu/zero_zero.wat +++ b/winch/filetests/filetests/x64/i64_remu/zero_zero.wat @@ -11,11 +11,8 @@ ;; 1: 4889e5 mov rbp, rsp ;; 4: 48c7c100000000 mov rcx, 0 ;; b: 48c7c000000000 mov rax, 0 -;; 12: 4883f900 cmp rcx, 0 -;; 16: 0f8502000000 jne 0x1e -;; 1c: 0f0b ud2 -;; 1e: 4831d2 xor rdx, rdx -;; 21: 48f7f1 div rcx -;; 24: 4889d0 mov rax, rdx -;; 27: 5d pop rbp -;; 28: c3 ret +;; 12: 4831d2 xor rdx, rdx +;; 15: 48f7f1 div rcx +;; 18: 4889d0 mov rax, rdx +;; 1b: 5d pop rbp +;; 1c: c3 ret