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)?;