From aeceea28e24383655f74face6be40d357b30c835 Mon Sep 17 00:00:00 2001 From: Trevor Elliott Date: Thu, 3 Nov 2022 09:25:11 -0700 Subject: [PATCH] Remove trapif and trapff (#5162) This branch removes the trapif and trapff instructions, in favor of using an explicit comparison and trapnz. This moves us closer to removing iflags and fflags, but introduces the need to implement instructions like iadd_cout in the x64 and aarch64 backends. --- cranelift/codegen/meta/src/shared/formats.rs | 14 -------- .../codegen/meta/src/shared/instructions.rs | 32 ------------------- cranelift/codegen/src/ir/instructions.rs | 14 ++------ cranelift/codegen/src/isa/aarch64/lower.isle | 20 ------------ .../codegen/src/isa/aarch64/lower_inst.rs | 2 -- cranelift/codegen/src/isa/riscv64/lower.isle | 19 ----------- cranelift/codegen/src/isa/s390x/lower.isle | 30 ++--------------- cranelift/codegen/src/isa/s390x/lower.rs | 3 +- cranelift/codegen/src/isa/x64/lower.isle | 18 ----------- cranelift/codegen/src/isa/x64/lower.rs | 2 -- cranelift/codegen/src/verifier/mod.rs | 2 -- cranelift/codegen/src/write.rs | 6 ---- .../filetests/isa/aarch64/traps.clif | 5 ++- .../filetests/isa/riscv64/traps.clif | 11 ++++--- .../filetests/filetests/isa/x64/traps.clif | 3 +- .../filetests/filetests/parser/tiny.clif | 16 +++++----- cranelift/interpreter/src/step.rs | 8 ----- cranelift/reader/src/parser.rs | 24 -------------- cranelift/wasm/src/code_translator.rs | 16 ++++------ 19 files changed, 30 insertions(+), 215 deletions(-) diff --git a/cranelift/codegen/meta/src/shared/formats.rs b/cranelift/codegen/meta/src/shared/formats.rs index 2d94d1e3c3..057e03bd39 100644 --- a/cranelift/codegen/meta/src/shared/formats.rs +++ b/cranelift/codegen/meta/src/shared/formats.rs @@ -14,12 +14,10 @@ pub(crate) struct Formats { pub(crate) call_indirect: Rc, pub(crate) cond_trap: Rc, pub(crate) float_compare: Rc, - pub(crate) float_cond_trap: Rc, pub(crate) func_addr: Rc, pub(crate) heap_addr: Rc, pub(crate) int_compare: Rc, pub(crate) int_compare_imm: Rc, - pub(crate) int_cond_trap: Rc, pub(crate) int_add_trap: Rc, pub(crate) jump: Rc, pub(crate) load: Rc, @@ -218,23 +216,11 @@ impl Formats { cond_trap: Builder::new("CondTrap").value().imm(&imm.trapcode).build(), - int_cond_trap: Builder::new("IntCondTrap") - .imm(&imm.intcc) - .value() - .imm(&imm.trapcode) - .build(), - int_add_trap: Builder::new("IntAddTrap") .value() .value() .imm(&imm.trapcode) .build(), - - float_cond_trap: Builder::new("FloatCondTrap") - .imm(&imm.floatcc) - .value() - .imm(&imm.trapcode) - .build(), } } } diff --git a/cranelift/codegen/meta/src/shared/instructions.rs b/cranelift/codegen/meta/src/shared/instructions.rs index c8aeaa50de..e9f128edaf 100644 --- a/cranelift/codegen/meta/src/shared/instructions.rs +++ b/cranelift/codegen/meta/src/shared/instructions.rs @@ -75,9 +75,6 @@ fn define_control_flow( ); } - let iflags: &TypeVar = &ValueType::Special(types::Flag::IFlags.into()).into(); - let fflags: &TypeVar = &ValueType::Special(types::Flag::FFlags.into()).into(); - { let _i32 = &TypeVar::new( "i32", @@ -205,35 +202,6 @@ fn define_control_flow( .operands_in(vec![c, code]) .can_trap(true), ); - - let Cond = &Operand::new("Cond", &imm.intcc); - let f = &Operand::new("f", iflags); - ig.push( - Inst::new( - "trapif", - r#" - Trap when condition is true in integer CPU flags. - "#, - &formats.int_cond_trap, - ) - .operands_in(vec![Cond, f, code]) - .can_trap(true), - ); - - let Cond = &Operand::new("Cond", &imm.floatcc); - let f = &Operand::new("f", fflags); - let code = &Operand::new("code", &imm.trapcode); - ig.push( - Inst::new( - "trapff", - r#" - Trap when condition is true in floating point CPU flags. - "#, - &formats.float_cond_trap, - ) - .operands_in(vec![Cond, f, code]) - .can_trap(true), - ); } let rvals = &Operand::new("rvals", &entities.varargs).with_doc("return values"); diff --git a/cranelift/codegen/src/ir/instructions.rs b/cranelift/codegen/src/ir/instructions.rs index 3d8638714a..e74662bf71 100644 --- a/cranelift/codegen/src/ir/instructions.rs +++ b/cranelift/codegen/src/ir/instructions.rs @@ -241,10 +241,7 @@ impl InstructionData { /// `None`. pub fn trap_code(&self) -> Option { match *self { - Self::CondTrap { code, .. } - | Self::FloatCondTrap { code, .. } - | Self::IntCondTrap { code, .. } - | Self::Trap { code, .. } => Some(code), + Self::CondTrap { code, .. } | Self::Trap { code, .. } => Some(code), _ => None, } } @@ -254,7 +251,6 @@ impl InstructionData { pub fn cond_code(&self) -> Option { match self { &InstructionData::IntCompare { cond, .. } - | &InstructionData::IntCondTrap { cond, .. } | &InstructionData::IntCompareImm { cond, .. } => Some(cond), _ => None, } @@ -264,8 +260,7 @@ impl InstructionData { /// condition. Otherwise, return `None`. pub fn fp_cond_code(&self) -> Option { match self { - &InstructionData::FloatCompare { cond, .. } - | &InstructionData::FloatCondTrap { cond, .. } => Some(cond), + &InstructionData::FloatCompare { cond, .. } => Some(cond), _ => None, } } @@ -274,10 +269,7 @@ impl InstructionData { /// trap code. Otherwise, return `None`. pub fn trap_code_mut(&mut self) -> Option<&mut TrapCode> { match self { - Self::CondTrap { code, .. } - | Self::FloatCondTrap { code, .. } - | Self::IntCondTrap { code, .. } - | Self::Trap { code, .. } => Some(code), + Self::CondTrap { code, .. } | Self::Trap { code, .. } => Some(code), _ => None, } } diff --git a/cranelift/codegen/src/isa/aarch64/lower.isle b/cranelift/codegen/src/isa/aarch64/lower.isle index 5d6fc3b0b3..8c5d8bea81 100644 --- a/cranelift/codegen/src/isa/aarch64/lower.isle +++ b/cranelift/codegen/src/isa/aarch64/lower.isle @@ -1682,26 +1682,6 @@ (rule (lower (trap trap_code)) (side_effect (udf trap_code))) -;;;; Rules for `trapif` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -(rule (lower (trapif cc insn @ (iadd_ifcout x y) trap_code)) - ;; The flags must not have been clobbered by any other instruction, as - ;; verified by the CLIF validator; so we can simply use the flags here. - (let ((insn ProducesFlags (flags_to_producesflags insn))) - (trap_if insn trap_code (cond_code cc)))) - -;; Verification ensures the input is always a single-def ifcmp. -(rule (lower (trapif cc insn @ (ifcmp x @ (value_type ty) y) trap_code)) - (let ((cond Cond (cond_code cc))) - (trap_if (lower_icmp_into_flags cc x y ty) trap_code cond))) - -;;;; Rules for `trapff` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -;; Verification ensures the input is always a single-def ffcmp. -(rule (lower (trapff cc insn @ (ffcmp x @ (value_type ty) y) trap_code)) - (let ((cond Cond (fp_cond_code cc))) - (trap_if (fpu_cmp (scalar_size ty) x y) trap_code cond))) - ;;;; Rules for `resumable_trap` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (rule (lower (resumable_trap trap_code)) diff --git a/cranelift/codegen/src/isa/aarch64/lower_inst.rs b/cranelift/codegen/src/isa/aarch64/lower_inst.rs index 3d54e18737..537e1dfc68 100644 --- a/cranelift/codegen/src/isa/aarch64/lower_inst.rs +++ b/cranelift/codegen/src/isa/aarch64/lower_inst.rs @@ -183,8 +183,6 @@ pub(crate) fn lower_insn_to_regs( Opcode::Trap | Opcode::ResumableTrap => implemented_in_isle(ctx), - Opcode::Trapif | Opcode::Trapff => implemented_in_isle(ctx), - Opcode::Trapz | Opcode::Trapnz | Opcode::ResumableTrapnz => { panic!("trapz / trapnz / resumable_trapnz should have been removed by legalization!"); } diff --git a/cranelift/codegen/src/isa/riscv64/lower.isle b/cranelift/codegen/src/isa/riscv64/lower.isle index abd193055f..2d99f3155b 100644 --- a/cranelift/codegen/src/isa/riscv64/lower.isle +++ b/cranelift/codegen/src/isa/riscv64/lower.isle @@ -845,25 +845,6 @@ (vec_writable_to_regs dst))) -;;;;; Rules for `trapif`;;;;;;;;; -(rule - (lower (trapif cc (ifcmp a @ (value_type ty) b) trap_code)) - (let - ((test Reg (lower_icmp cc a b ty))) - (gen_trapif test trap_code))) - -(rule - (lower (trapif _ (iadd_ifcout a @ (value_type ty) b) trap_code)) - (let - ((res ValueRegs (lower_uadd_overflow a b ty))) - (gen_trapif (value_regs_get res 1) trap_code))) - - -;;;;; Rules for `trapff`;;;;;;;;; -(rule - (lower (trapff cc (ffcmp a @ (value_type ty) b) trap_code)) - (gen_trapff cc a b ty trap_code)) - ;;;;; Rules for `bmask`;;;;;;;;; (rule (lower (has_type oty (bmask x @ (value_type ity)))) diff --git a/cranelift/codegen/src/isa/s390x/lower.isle b/cranelift/codegen/src/isa/s390x/lower.isle index e52d4ce415..9e0e43bb2d 100644 --- a/cranelift/codegen/src/isa/s390x/lower.isle +++ b/cranelift/codegen/src/isa/s390x/lower.isle @@ -3851,27 +3851,9 @@ (rule (lower (debugtrap)) (side_effect (debugtrap_impl))) +;;;; Rules for `uadd_overflow_trap` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;;;; Rules for `trapif` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -;; Similarly to `selectif_spectre_guard`, we only recognize specific patterns -;; generated by common code here. Others will fail to lower. - -;; Recognize the case of `ifcmp` feeding into `trapif`. Directly generate -;; the desired comparison here; there is no separate `ifcmp` lowering. - -(rule (lower (trapif int_cc (ifcmp x y) trap_code)) - (side_effect (trap_if_bool (icmp_val $false int_cc x y) trap_code))) - -;; Recognize the case of `iadd_ifcout` feeding into `trapif`. Note that -;; in the case, the `iadd_ifcout` is generated by a separate lowering -;; (in order to properly handle the register output of that instruction.) -;; -;; The flags must not have been clobbered by any other instruction between the -;; iadd_ifcout and this instruction, as verified by the CLIF validator; so we -;; can simply rely on the condition code here. -;; -;; IaddIfcout is implemented via a ADD LOGICAL instruction, which sets the +;; UaddOverflowTrap is implemented via a ADD LOGICAL instruction, which sets the ;; the condition code as follows: ;; 0 Result zero; no carry ;; 1 Result not zero; no carry @@ -3885,14 +3867,6 @@ ;; remap the IntCC::UnsignedGreaterThan value that we have here as result ;; of the unsigned_add_overflow_condition call to the correct mask. -(rule (lower (trapif (IntCC.UnsignedGreaterThan) - flags @ (iadd_ifcout _ _) trap_code)) - (side_effect - (trap_if_bool (bool (flags_to_producesflags flags) (mask_as_cond 3)) - trap_code))) - -;;;; Rules for `uadd_overflow_trap` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - (rule 0 (lower (has_type (fits_in_64 ty) (uadd_overflow_trap x y tc))) (with_flags (add_logical_reg_with_flags_paired ty x y) diff --git a/cranelift/codegen/src/isa/s390x/lower.rs b/cranelift/codegen/src/isa/s390x/lower.rs index 6bb59cfb4f..4a461cc313 100644 --- a/cranelift/codegen/src/isa/s390x/lower.rs +++ b/cranelift/codegen/src/isa/s390x/lower.rs @@ -176,7 +176,6 @@ impl LowerBackend for S390xBackend { | Opcode::Trapz | Opcode::Trapnz | Opcode::ResumableTrapnz - | Opcode::Trapif | Opcode::Debugtrap | Opcode::Call | Opcode::CallIndirect @@ -222,7 +221,7 @@ impl LowerBackend for S390xBackend { Opcode::GlobalValue => { panic!("global_value should have been removed by legalization!"); } - Opcode::Ifcmp | Opcode::Ffcmp | Opcode::Trapff => { + Opcode::Ifcmp | Opcode::Ffcmp => { panic!("Flags opcode should not be encountered."); } Opcode::Jump | Opcode::Brz | Opcode::Brnz | Opcode::BrTable => { diff --git a/cranelift/codegen/src/isa/x64/lower.isle b/cranelift/codegen/src/isa/x64/lower.isle index 41ef7eb1db..18d3f01890 100644 --- a/cranelift/codegen/src/isa/x64/lower.isle +++ b/cranelift/codegen/src/isa/x64/lower.isle @@ -1440,24 +1440,6 @@ (x64_add_with_flags_paired ty b (sink_load_to_gpr_mem_imm a)) (trap_if (CC.B) tc))) -;;;; Rules for `trapif` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -;; The flags must not have been clobbered by any other instruction between the -;; iadd_ifcout and this instruction, as verified by the CLIF validator; so we -;; can simply use the flags here. -(rule (lower (trapif cc flags @ (iadd_ifcout _ _) tc)) - (side_effect - (trap_if_icmp (icmp_cond_result (flags_to_producesflags flags) cc) tc))) - -;; Verification ensures that the input is always a single-def ifcmp. -(rule (lower (trapif cc (ifcmp a b) tc)) - (side_effect (trap_if_icmp (emit_cmp cc a b) tc))) - -;;;; Rules for `trapff` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -(rule (lower (trapff cc (ffcmp a b) tc)) - (side_effect (trap_if_fcmp (emit_fcmp cc a b) tc))) - ;;;; Rules for `resumable_trap` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (rule (lower (resumable_trap code)) diff --git a/cranelift/codegen/src/isa/x64/lower.rs b/cranelift/codegen/src/isa/x64/lower.rs index db9fa4eba4..5208da78fa 100644 --- a/cranelift/codegen/src/isa/x64/lower.rs +++ b/cranelift/codegen/src/isa/x64/lower.rs @@ -414,8 +414,6 @@ fn lower_insn_to_regs( | Opcode::Return | Opcode::Call | Opcode::CallIndirect - | Opcode::Trapif - | Opcode::Trapff | Opcode::GetFramePointer | Opcode::GetStackPointer | Opcode::GetReturnAddress diff --git a/cranelift/codegen/src/verifier/mod.rs b/cranelift/codegen/src/verifier/mod.rs index 00855f46d1..80c79eb456 100644 --- a/cranelift/codegen/src/verifier/mod.rs +++ b/cranelift/codegen/src/verifier/mod.rs @@ -767,8 +767,6 @@ impl<'a> Verifier<'a> { | Store { .. } | Trap { .. } | CondTrap { .. } - | IntCondTrap { .. } - | FloatCondTrap { .. } | NullAry { .. } => {} } diff --git a/cranelift/codegen/src/write.rs b/cranelift/codegen/src/write.rs index 79fae3e96f..8e4ae92437 100644 --- a/cranelift/codegen/src/write.rs +++ b/cranelift/codegen/src/write.rs @@ -489,12 +489,6 @@ pub fn write_operands(w: &mut dyn Write, dfg: &DataFlowGraph, inst: Inst) -> fmt } => write!(w, "{} {}, {}{}", flags, args[0], args[1], offset), Trap { code, .. } => write!(w, " {}", code), CondTrap { arg, code, .. } => write!(w, " {}, {}", arg, code), - IntCondTrap { - cond, arg, code, .. - } => write!(w, " {} {}, {}", cond, arg, code), - FloatCondTrap { - cond, arg, code, .. - } => write!(w, " {} {}, {}", cond, arg, code), }?; let mut sep = " ; "; diff --git a/cranelift/filetests/filetests/isa/aarch64/traps.clif b/cranelift/filetests/filetests/isa/aarch64/traps.clif index 41864bdd02..c2a89b0f70 100644 --- a/cranelift/filetests/filetests/isa/aarch64/traps.clif +++ b/cranelift/filetests/filetests/isa/aarch64/traps.clif @@ -11,13 +11,12 @@ block0: function %trap_iadd_ifcout(i64, i64) { block0(v0: i64, v1: i64): - v2, v3 = iadd_ifcout v0, v1 - trapif ult v3, user0 + v2 = uadd_overflow_trap v0, v1, user0 return } ; block0: ; adds x3, x0, x1 -; b.hs 8 ; udf +; b.lo 8 ; udf ; ret diff --git a/cranelift/filetests/filetests/isa/riscv64/traps.clif b/cranelift/filetests/filetests/isa/riscv64/traps.clif index 9ebe09422c..ca3126346e 100644 --- a/cranelift/filetests/filetests/isa/riscv64/traps.clif +++ b/cranelift/filetests/filetests/isa/riscv64/traps.clif @@ -13,16 +13,19 @@ block0: function %g(i64) { block0(v0: i64): v1 = iconst.i64 42 - v2 = ifcmp v0, v1 - trapif eq v2, user0 + v2 = icmp eq v0, v1 + trapnz v2, user0 return } ; block0: ; li t2,42 -; eq a1,a0,t2##ty=i64 -; trap_if a1,user0 +; ne a1,a0,t2##ty=i64 +; bne a1,zero,taken(label1),not_taken(label2) +; block1: ; ret +; block2: +; udf##trap_code=user0 function %h() { block0: diff --git a/cranelift/filetests/filetests/isa/x64/traps.clif b/cranelift/filetests/filetests/isa/x64/traps.clif index fcde18bed7..b314f8884a 100644 --- a/cranelift/filetests/filetests/isa/x64/traps.clif +++ b/cranelift/filetests/filetests/isa/x64/traps.clif @@ -14,8 +14,7 @@ block0: function %trap_iadd_ifcout(i64, i64) { block0(v0: i64, v1: i64): - v2, v3 = iadd_ifcout v0, v1 - trapif ult v3, user0 + v2 = uadd_overflow_trap v0, v1, user0 return } diff --git a/cranelift/filetests/filetests/parser/tiny.clif b/cranelift/filetests/filetests/parser/tiny.clif index f4d6bcc1ec..901e4ef12d 100644 --- a/cranelift/filetests/filetests/parser/tiny.clif +++ b/cranelift/filetests/filetests/parser/tiny.clif @@ -176,20 +176,20 @@ block0(v1: i32): function %cond_traps(i32) { block0(v0: i32): trapz v0, stk_ovf - v1 = ifcmp_imm v0, 5 - trapif ugt v1, heap_oob + v1 = icmp_imm ugt v0, 5 + trapnz v1, heap_oob v2 = bitcast.f32 v1 - v3 = ffcmp v2, v2 - trapff uno v3, int_ovf + v3 = fcmp uno v2, v2 + trapnz v3, int_ovf return } ; sameln: function %cond_traps(i32) ; nextln: block0(v0: i32): ; nextln: trapz v0, stk_ovf -; nextln: v1 = ifcmp_imm v0, 5 -; nextln: trapif ugt v1, heap_oob +; nextln: v1 = icmp_imm ugt v0, 5 +; nextln: trapnz v1, heap_oob ; nextln: v2 = bitcast.f32 v1 -; nextln: v3 = ffcmp v2, v2 -; nextln: trapff uno v3, int_ovf +; nextln: v3 = fcmp uno v2, v2 +; nextln: trapnz v3, int_ovf ; nextln: return ; nextln: } diff --git a/cranelift/interpreter/src/step.rs b/cranelift/interpreter/src/step.rs index b6d05530b7..7377e1d681 100644 --- a/cranelift/interpreter/src/step.rs +++ b/cranelift/interpreter/src/step.rs @@ -315,14 +315,6 @@ where Opcode::Trapz => trap_when(!arg(0)?.into_bool()?, CraneliftTrap::User(trap_code())), Opcode::Trapnz => trap_when(arg(0)?.into_bool()?, CraneliftTrap::User(trap_code())), Opcode::ResumableTrapnz => trap_when(arg(0)?.into_bool()?, CraneliftTrap::Resumable), - Opcode::Trapif => trap_when( - state.has_iflag(inst.cond_code().unwrap()), - CraneliftTrap::User(trap_code()), - ), - Opcode::Trapff => trap_when( - state.has_fflag(inst.fp_cond_code().unwrap()), - CraneliftTrap::User(trap_code()), - ), Opcode::Return => ControlFlow::Return(args()?), Opcode::Call => { let func_ref = if let InstructionData::Call { func_ref, .. } = inst { diff --git a/cranelift/reader/src/parser.rs b/cranelift/reader/src/parser.rs index 794648ce2a..912282bae4 100644 --- a/cranelift/reader/src/parser.rs +++ b/cranelift/reader/src/parser.rs @@ -3021,30 +3021,6 @@ impl<'a> Parser<'a> { let code = self.match_enum("expected trap code")?; InstructionData::CondTrap { opcode, arg, code } } - InstructionFormat::IntCondTrap => { - let cond = self.match_enum("expected intcc condition code")?; - let arg = self.match_value("expected SSA value operand")?; - self.match_token(Token::Comma, "expected ',' between operands")?; - let code = self.match_enum("expected trap code")?; - InstructionData::IntCondTrap { - opcode, - cond, - arg, - code, - } - } - InstructionFormat::FloatCondTrap => { - let cond = self.match_enum("expected floatcc condition code")?; - let arg = self.match_value("expected SSA value operand")?; - self.match_token(Token::Comma, "expected ',' between operands")?; - let code = self.match_enum("expected trap code")?; - InstructionData::FloatCondTrap { - opcode, - cond, - arg, - code, - } - } InstructionFormat::AtomicCas => { let flags = self.optional_memflags(); let addr = self.match_value("expected SSA value address")?; diff --git a/cranelift/wasm/src/code_translator.rs b/cranelift/wasm/src/code_translator.rs index 7842eacba0..a8d8b51b01 100644 --- a/cranelift/wasm/src/code_translator.rs +++ b/cranelift/wasm/src/code_translator.rs @@ -2324,12 +2324,10 @@ fn prepare_addr( Err(_) => { let index_type = builder.func.heaps[heap].index_type; let offset = builder.ins().iconst(index_type, memarg.offset as i64); - let (addr, overflow) = builder.ins().iadd_ifcout(addr, offset); - builder.ins().trapif( - environ.unsigned_add_overflow_condition(), - overflow, - ir::TrapCode::HeapOutOfBounds, - ); + let addr = + builder + .ins() + .uadd_overflow_trap(addr, offset, ir::TrapCode::HeapOutOfBounds); let base = builder .ins() .heap_addr(environ.pointer_type(), heap, addr, access_size); @@ -2384,10 +2382,8 @@ fn prepare_atomic_addr( let misalignment = builder .ins() .band_imm(effective_addr, i64::from(loaded_bytes - 1)); - let f = builder.ins().ifcmp_imm(misalignment, 0); - builder - .ins() - .trapif(IntCC::NotEqual, f, ir::TrapCode::HeapMisaligned); + let f = builder.ins().icmp_imm(IntCC::NotEqual, misalignment, 0); + builder.ins().trapnz(f, ir::TrapCode::HeapMisaligned); } let (flags, mut addr, offset) = prepare_addr(memarg, loaded_bytes, builder, state, environ)?;