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.
This commit is contained in:
@@ -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))
|
||||
|
||||
@@ -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!");
|
||||
}
|
||||
|
||||
@@ -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))))
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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 => {
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user