cranelift: Remove redundant branch and select instructions (#5097)
As discussed in the 2022/10/19 meeting, this PR removes many of the branch and select instructions that used iflags, in favor if using brz/brnz and select in their place. Additionally, it reworks selectif_spectre_guard to take an i8 input instead of an iflags input. For reference, the removed instructions are: br_icmp, brif, brff, trueif, trueff, and selectif.
This commit is contained in:
@@ -9,23 +9,17 @@ pub(crate) struct Formats {
|
||||
pub(crate) binary_imm8: Rc<InstructionFormat>,
|
||||
pub(crate) binary_imm64: Rc<InstructionFormat>,
|
||||
pub(crate) branch: Rc<InstructionFormat>,
|
||||
pub(crate) branch_float: Rc<InstructionFormat>,
|
||||
pub(crate) branch_icmp: Rc<InstructionFormat>,
|
||||
pub(crate) branch_int: Rc<InstructionFormat>,
|
||||
pub(crate) branch_table: Rc<InstructionFormat>,
|
||||
pub(crate) call: Rc<InstructionFormat>,
|
||||
pub(crate) call_indirect: Rc<InstructionFormat>,
|
||||
pub(crate) cond_trap: Rc<InstructionFormat>,
|
||||
pub(crate) float_compare: Rc<InstructionFormat>,
|
||||
pub(crate) float_cond: Rc<InstructionFormat>,
|
||||
pub(crate) float_cond_trap: Rc<InstructionFormat>,
|
||||
pub(crate) func_addr: Rc<InstructionFormat>,
|
||||
pub(crate) heap_addr: Rc<InstructionFormat>,
|
||||
pub(crate) int_compare: Rc<InstructionFormat>,
|
||||
pub(crate) int_compare_imm: Rc<InstructionFormat>,
|
||||
pub(crate) int_cond: Rc<InstructionFormat>,
|
||||
pub(crate) int_cond_trap: Rc<InstructionFormat>,
|
||||
pub(crate) int_select: Rc<InstructionFormat>,
|
||||
pub(crate) jump: Rc<InstructionFormat>,
|
||||
pub(crate) load: Rc<InstructionFormat>,
|
||||
pub(crate) load_no_offset: Rc<InstructionFormat>,
|
||||
@@ -113,23 +107,12 @@ impl Formats {
|
||||
.imm(&imm.imm64)
|
||||
.build(),
|
||||
|
||||
int_cond: Builder::new("IntCond").imm(&imm.intcc).value().build(),
|
||||
|
||||
float_compare: Builder::new("FloatCompare")
|
||||
.imm(&imm.floatcc)
|
||||
.value()
|
||||
.value()
|
||||
.build(),
|
||||
|
||||
float_cond: Builder::new("FloatCond").imm(&imm.floatcc).value().build(),
|
||||
|
||||
int_select: Builder::new("IntSelect")
|
||||
.imm(&imm.intcc)
|
||||
.value()
|
||||
.value()
|
||||
.value()
|
||||
.build(),
|
||||
|
||||
jump: Builder::new("Jump").imm(&entities.block).varargs().build(),
|
||||
|
||||
branch: Builder::new("Branch")
|
||||
@@ -138,28 +121,6 @@ impl Formats {
|
||||
.varargs()
|
||||
.build(),
|
||||
|
||||
branch_int: Builder::new("BranchInt")
|
||||
.imm(&imm.intcc)
|
||||
.value()
|
||||
.imm(&entities.block)
|
||||
.varargs()
|
||||
.build(),
|
||||
|
||||
branch_float: Builder::new("BranchFloat")
|
||||
.imm(&imm.floatcc)
|
||||
.value()
|
||||
.imm(&entities.block)
|
||||
.varargs()
|
||||
.build(),
|
||||
|
||||
branch_icmp: Builder::new("BranchIcmp")
|
||||
.imm(&imm.intcc)
|
||||
.value()
|
||||
.value()
|
||||
.imm(&entities.block)
|
||||
.varargs()
|
||||
.build(),
|
||||
|
||||
branch_table: Builder::new("BranchTable")
|
||||
.value()
|
||||
.imm(&entities.block)
|
||||
|
||||
@@ -75,82 +75,9 @@ fn define_control_flow(
|
||||
);
|
||||
}
|
||||
|
||||
let iB = &TypeVar::new(
|
||||
"iB",
|
||||
"A scalar integer type",
|
||||
TypeSetBuilder::new().ints(Interval::All).build(),
|
||||
);
|
||||
let iflags: &TypeVar = &ValueType::Special(types::Flag::IFlags.into()).into();
|
||||
let fflags: &TypeVar = &ValueType::Special(types::Flag::FFlags.into()).into();
|
||||
|
||||
{
|
||||
let Cond = &Operand::new("Cond", &imm.intcc);
|
||||
let x = &Operand::new("x", iB);
|
||||
let y = &Operand::new("y", iB);
|
||||
|
||||
ig.push(
|
||||
Inst::new(
|
||||
"br_icmp",
|
||||
r#"
|
||||
Compare scalar integers and branch.
|
||||
|
||||
Compare ``x`` and ``y`` in the same way as the `icmp` instruction
|
||||
and take the branch if the condition is true:
|
||||
|
||||
```text
|
||||
br_icmp ugt v1, v2, block4(v5, v6)
|
||||
```
|
||||
|
||||
is semantically equivalent to:
|
||||
|
||||
```text
|
||||
v10 = icmp ugt, v1, v2
|
||||
brnz v10, block4(v5, v6)
|
||||
```
|
||||
|
||||
Some RISC architectures like MIPS and RISC-V provide instructions that
|
||||
implement all or some of the condition codes. The instruction can also
|
||||
be used to represent *macro-op fusion* on architectures like Intel's.
|
||||
"#,
|
||||
&formats.branch_icmp,
|
||||
)
|
||||
.operands_in(vec![Cond, x, y, block, args])
|
||||
.is_branch(true),
|
||||
);
|
||||
|
||||
let f = &Operand::new("f", iflags);
|
||||
|
||||
ig.push(
|
||||
Inst::new(
|
||||
"brif",
|
||||
r#"
|
||||
Branch when condition is true in integer CPU flags.
|
||||
"#,
|
||||
&formats.branch_int,
|
||||
)
|
||||
.operands_in(vec![Cond, f, block, args])
|
||||
.is_branch(true),
|
||||
);
|
||||
}
|
||||
|
||||
{
|
||||
let Cond = &Operand::new("Cond", &imm.floatcc);
|
||||
|
||||
let f = &Operand::new("f", fflags);
|
||||
|
||||
ig.push(
|
||||
Inst::new(
|
||||
"brff",
|
||||
r#"
|
||||
Branch when condition is true in floating point CPU flags.
|
||||
"#,
|
||||
&formats.branch_float,
|
||||
)
|
||||
.operands_in(vec![Cond, f, block, args])
|
||||
.is_branch(true),
|
||||
);
|
||||
}
|
||||
|
||||
{
|
||||
let _i32 = &TypeVar::new(
|
||||
"i32",
|
||||
@@ -1498,28 +1425,13 @@ pub(crate) fn define(
|
||||
.operands_out(vec![a]),
|
||||
);
|
||||
|
||||
let cc = &Operand::new("cc", &imm.intcc).with_doc("Controlling condition code");
|
||||
let flags = &Operand::new("flags", iflags).with_doc("The machine's flag register");
|
||||
|
||||
ig.push(
|
||||
Inst::new(
|
||||
"selectif",
|
||||
r#"
|
||||
Conditional select, dependent on integer condition codes.
|
||||
"#,
|
||||
&formats.int_select,
|
||||
)
|
||||
.operands_in(vec![cc, flags, x, y])
|
||||
.operands_out(vec![a]),
|
||||
);
|
||||
|
||||
ig.push(
|
||||
Inst::new(
|
||||
"selectif_spectre_guard",
|
||||
"select_spectre_guard",
|
||||
r#"
|
||||
Conditional select intended for Spectre guards.
|
||||
|
||||
This operation is semantically equivalent to a selectif instruction.
|
||||
This operation is semantically equivalent to a select instruction.
|
||||
However, it is guaranteed to not be removed or otherwise altered by any
|
||||
optimization pass, and is guaranteed to result in a conditional-move
|
||||
instruction, not a branch-based lowering. As such, it is suitable
|
||||
@@ -1534,9 +1446,9 @@ pub(crate) fn define(
|
||||
speculative path, this ensures that no Spectre vulnerability will
|
||||
exist.
|
||||
"#,
|
||||
&formats.int_select,
|
||||
&formats.ternary,
|
||||
)
|
||||
.operands_in(vec![cc, flags, x, y])
|
||||
.operands_in(vec![c, x, y])
|
||||
.operands_out(vec![a])
|
||||
.other_side_effects(true),
|
||||
);
|
||||
@@ -3194,43 +3106,6 @@ pub(crate) fn define(
|
||||
.operands_out(vec![a]),
|
||||
);
|
||||
|
||||
let Cond = &Operand::new("Cond", &imm.intcc);
|
||||
let f = &Operand::new("f", iflags);
|
||||
let a = &Operand::new("a", i8);
|
||||
|
||||
ig.push(
|
||||
Inst::new(
|
||||
"trueif",
|
||||
r#"
|
||||
Test integer CPU flags for a specific condition.
|
||||
|
||||
Check the CPU flags in ``f`` against the ``Cond`` condition code and
|
||||
return true when the condition code is satisfied.
|
||||
"#,
|
||||
&formats.int_cond,
|
||||
)
|
||||
.operands_in(vec![Cond, f])
|
||||
.operands_out(vec![a]),
|
||||
);
|
||||
|
||||
let Cond = &Operand::new("Cond", &imm.floatcc);
|
||||
let f = &Operand::new("f", fflags);
|
||||
|
||||
ig.push(
|
||||
Inst::new(
|
||||
"trueff",
|
||||
r#"
|
||||
Test floating point CPU flags for a specific condition.
|
||||
|
||||
Check the CPU flags in ``f`` against the ``Cond`` condition code and
|
||||
return true when the condition code is satisfied.
|
||||
"#,
|
||||
&formats.float_cond,
|
||||
)
|
||||
.operands_in(vec![Cond, f])
|
||||
.operands_out(vec![a]),
|
||||
);
|
||||
|
||||
let x = &Operand::new("x", Mem);
|
||||
let a = &Operand::new("a", MemTo).with_doc("Bits of `x` reinterpreted");
|
||||
|
||||
|
||||
@@ -185,26 +185,11 @@ impl InstructionData {
|
||||
ref args,
|
||||
..
|
||||
} => BranchInfo::SingleDest(destination, args.as_slice(pool)),
|
||||
Self::BranchInt {
|
||||
destination,
|
||||
ref args,
|
||||
..
|
||||
}
|
||||
| Self::BranchFloat {
|
||||
destination,
|
||||
ref args,
|
||||
..
|
||||
}
|
||||
| Self::Branch {
|
||||
Self::Branch {
|
||||
destination,
|
||||
ref args,
|
||||
..
|
||||
} => BranchInfo::SingleDest(destination, &args.as_slice(pool)[1..]),
|
||||
Self::BranchIcmp {
|
||||
destination,
|
||||
ref args,
|
||||
..
|
||||
} => BranchInfo::SingleDest(destination, &args.as_slice(pool)[2..]),
|
||||
Self::BranchTable {
|
||||
table, destination, ..
|
||||
} => BranchInfo::Table(table, Some(destination)),
|
||||
@@ -221,11 +206,7 @@ impl InstructionData {
|
||||
/// Multi-destination branches like `br_table` return `None`.
|
||||
pub fn branch_destination(&self) -> Option<Block> {
|
||||
match *self {
|
||||
Self::Jump { destination, .. }
|
||||
| Self::Branch { destination, .. }
|
||||
| Self::BranchInt { destination, .. }
|
||||
| Self::BranchFloat { destination, .. }
|
||||
| Self::BranchIcmp { destination, .. } => Some(destination),
|
||||
Self::Jump { destination, .. } | Self::Branch { destination, .. } => Some(destination),
|
||||
Self::BranchTable { .. } => None,
|
||||
_ => {
|
||||
debug_assert!(!self.opcode().is_branch());
|
||||
@@ -247,18 +228,6 @@ impl InstructionData {
|
||||
| Self::Branch {
|
||||
ref mut destination,
|
||||
..
|
||||
}
|
||||
| Self::BranchInt {
|
||||
ref mut destination,
|
||||
..
|
||||
}
|
||||
| Self::BranchFloat {
|
||||
ref mut destination,
|
||||
..
|
||||
}
|
||||
| Self::BranchIcmp {
|
||||
ref mut destination,
|
||||
..
|
||||
} => Some(destination),
|
||||
Self::BranchTable { .. } => None,
|
||||
_ => {
|
||||
@@ -284,12 +253,8 @@ impl InstructionData {
|
||||
/// condition. Otherwise, return `None`.
|
||||
pub fn cond_code(&self) -> Option<IntCC> {
|
||||
match self {
|
||||
&InstructionData::IntCond { cond, .. }
|
||||
| &InstructionData::BranchIcmp { cond, .. }
|
||||
| &InstructionData::IntCompare { cond, .. }
|
||||
&InstructionData::IntCompare { cond, .. }
|
||||
| &InstructionData::IntCondTrap { cond, .. }
|
||||
| &InstructionData::BranchInt { cond, .. }
|
||||
| &InstructionData::IntSelect { cond, .. }
|
||||
| &InstructionData::IntCompareImm { cond, .. } => Some(cond),
|
||||
_ => None,
|
||||
}
|
||||
@@ -299,9 +264,7 @@ impl InstructionData {
|
||||
/// condition. Otherwise, return `None`.
|
||||
pub fn fp_cond_code(&self) -> Option<FloatCC> {
|
||||
match self {
|
||||
&InstructionData::BranchFloat { cond, .. }
|
||||
| &InstructionData::FloatCompare { cond, .. }
|
||||
| &InstructionData::FloatCond { cond, .. }
|
||||
&InstructionData::FloatCompare { cond, .. }
|
||||
| &InstructionData::FloatCondTrap { cond, .. } => Some(cond),
|
||||
_ => None,
|
||||
}
|
||||
|
||||
@@ -1706,21 +1706,6 @@
|
||||
(rule (lower (resumable_trap trap_code))
|
||||
(side_effect (udf trap_code)))
|
||||
|
||||
;;;; Rules for `trueif` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
;; Verification ensures the input is always a single-def ifcmp.
|
||||
(rule (lower (has_type out_ty
|
||||
(trueif cc insn @ (ifcmp x @ (value_type in_ty) y))))
|
||||
(lower_icmp_into_reg cc x y in_ty out_ty))
|
||||
|
||||
;;;; Rules for `trueff` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
;; Verification ensures the input is always a single-def ffcmp.
|
||||
(rule (lower (trueff cc insn @ (ffcmp x @ (value_type in_ty) y)))
|
||||
(with_flags_reg
|
||||
(fpu_cmp (scalar_size in_ty) x y)
|
||||
(materialize_bool_result (fp_cond_code cc))))
|
||||
|
||||
;;;; Rules for `select` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
(rule (lower (has_type ty
|
||||
@@ -1755,22 +1740,11 @@
|
||||
(cmp (OperandSize.Size64) rcond (zero_reg))
|
||||
(Cond.Ne) ty rn rm)))
|
||||
|
||||
;;;; Rules for `selectif` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
;; Verification ensures that the input is always a single-def ifcmp.
|
||||
(rule (lower (has_type ty
|
||||
(selectif cc flags @ (ifcmp x @ (value_type in_ty) y)
|
||||
if_true if_false)))
|
||||
(let ((cond Cond (cond_code cc)))
|
||||
(lower_select
|
||||
(lower_icmp_into_flags cc x y in_ty)
|
||||
cond ty if_true if_false)))
|
||||
|
||||
;;;; Rules for `selectif_spectre_guard` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;;;; Rules for `select_spectre_guard` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
(rule (lower (has_type ty
|
||||
(selectif_spectre_guard cc
|
||||
flags @ (ifcmp x @ (value_type in_ty) y) if_true if_false)))
|
||||
(select_spectre_guard
|
||||
(icmp cc x @ (value_type in_ty) y) if_true if_false)))
|
||||
(let ((cond Cond (cond_code cc))
|
||||
(dst ValueRegs (lower_select
|
||||
(lower_icmp_into_flags cc x y in_ty)
|
||||
@@ -2422,7 +2396,7 @@
|
||||
(rule (lower (fvpromote_low val))
|
||||
(vec_rr_long (VecRRLongOp.Fcvtl32) val $false))
|
||||
|
||||
;;; Rules for `brz`/`brnz`/`brif`/`brff`/`bricmp` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;;; Rules for `brz`/`brnz` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
;; `brz` following `icmp`
|
||||
(rule (lower_branch (brz (icmp cc x @ (value_type ty) y) _ _) targets)
|
||||
@@ -2505,58 +2479,6 @@
|
||||
(with_flags_side_effect flags
|
||||
(cond_br taken not_taken (cond_br_not_zero rt))))))
|
||||
|
||||
;; `br_icmp`
|
||||
(rule (lower_branch (br_icmp cc x @ (value_type ty) y _ _) targets)
|
||||
(let ((cond Cond (cond_code cc))
|
||||
(taken BranchTarget (branch_target targets 0))
|
||||
(not_taken BranchTarget (branch_target targets 1)))
|
||||
(side_effect
|
||||
(with_flags_side_effect (lower_icmp_into_flags cc x y ty)
|
||||
(cond_br taken not_taken
|
||||
(cond_br_cond cond))))))
|
||||
|
||||
;; `brif`
|
||||
(rule (lower_branch (brif cc (ifcmp x @ (value_type ty) y) _ _) targets)
|
||||
(let ((cond Cond (cond_code cc))
|
||||
(taken BranchTarget (branch_target targets 0))
|
||||
(not_taken BranchTarget (branch_target targets 1)))
|
||||
(side_effect
|
||||
(with_flags_side_effect (lower_icmp_into_flags cc x y ty)
|
||||
(cond_br taken not_taken
|
||||
(cond_br_cond cond))))))
|
||||
;; If the `ifcmp` result is actually placed in a register, we need to move it
|
||||
;; back into the flags.
|
||||
(rule -1 (lower_branch (brif cc f _ _) targets)
|
||||
(let ((cond Cond (cond_code cc))
|
||||
(rn Reg (put_in_reg f))
|
||||
(taken BranchTarget (branch_target targets 0))
|
||||
(not_taken BranchTarget (branch_target targets 1)))
|
||||
(side_effect
|
||||
(with_flags_side_effect (mov_to_nzcv rn)
|
||||
(cond_br taken not_taken
|
||||
(cond_br_cond cond))))))
|
||||
|
||||
;; `brff`
|
||||
(rule (lower_branch (brff cc (ffcmp x @ (value_type ty) y) _ _) targets)
|
||||
(let ((cond Cond (fp_cond_code cc))
|
||||
(taken BranchTarget (branch_target targets 0))
|
||||
(not_taken BranchTarget (branch_target targets 1)))
|
||||
(side_effect
|
||||
(with_flags_side_effect (fpu_cmp (scalar_size ty) x y)
|
||||
(cond_br taken not_taken
|
||||
(cond_br_cond cond))))))
|
||||
;; If the `ffcmp` result is actually placed in a register, we need to move it
|
||||
;; back into the flags.
|
||||
(rule -1 (lower_branch (brff cc f _ _) targets)
|
||||
(let ((cond Cond (fp_cond_code cc))
|
||||
(rn Reg (put_in_reg f))
|
||||
(taken BranchTarget (branch_target targets 0))
|
||||
(not_taken BranchTarget (branch_target targets 1)))
|
||||
(side_effect
|
||||
(with_flags_side_effect (mov_to_nzcv rn)
|
||||
(cond_br taken not_taken
|
||||
(cond_br_cond cond))))))
|
||||
|
||||
;;; Rules for `jump` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
(rule (lower_branch (jump _ _) targets)
|
||||
|
||||
@@ -151,14 +151,10 @@ pub(crate) fn lower_insn_to_regs(
|
||||
|
||||
Opcode::Select => implemented_in_isle(ctx),
|
||||
|
||||
Opcode::Selectif | Opcode::SelectifSpectreGuard => implemented_in_isle(ctx),
|
||||
Opcode::SelectSpectreGuard => implemented_in_isle(ctx),
|
||||
|
||||
Opcode::Bitselect | Opcode::Vselect => implemented_in_isle(ctx),
|
||||
|
||||
Opcode::Trueif => implemented_in_isle(ctx),
|
||||
|
||||
Opcode::Trueff => implemented_in_isle(ctx),
|
||||
|
||||
Opcode::IsNull | Opcode::IsInvalid => implemented_in_isle(ctx),
|
||||
|
||||
Opcode::Copy => implemented_in_isle(ctx),
|
||||
@@ -205,13 +201,7 @@ pub(crate) fn lower_insn_to_regs(
|
||||
|
||||
Opcode::GetPinnedReg | Opcode::SetPinnedReg => implemented_in_isle(ctx),
|
||||
|
||||
Opcode::Jump
|
||||
| Opcode::Brz
|
||||
| Opcode::Brnz
|
||||
| Opcode::BrIcmp
|
||||
| Opcode::Brif
|
||||
| Opcode::Brff
|
||||
| Opcode::BrTable => {
|
||||
Opcode::Jump | Opcode::Brz | Opcode::Brnz | Opcode::BrTable => {
|
||||
panic!("Branch opcode reached non-branch lowering logic!");
|
||||
}
|
||||
|
||||
|
||||
@@ -1915,24 +1915,29 @@
|
||||
(rule
|
||||
(lower_branch (brz v @ (value_type ty) _ _) targets)
|
||||
(lower_brz_or_nz (IntCC.Equal) (normalize_value ty v) targets ty))
|
||||
|
||||
(rule 1
|
||||
(lower_branch (brz (icmp cc a @ (value_type ty) b) _ _) targets)
|
||||
(lower_br_icmp (intcc_inverse cc) a b targets ty))
|
||||
|
||||
(rule 1
|
||||
(lower_branch (brz (fcmp cc a @ (value_type ty) b) _ _) targets)
|
||||
(lower_br_fcmp (floatcc_inverse cc) a b targets ty))
|
||||
|
||||
;;;;
|
||||
(rule
|
||||
(lower_branch (brnz v @ (value_type ty) _ _) targets)
|
||||
(lower_brz_or_nz (IntCC.NotEqual) (normalize_value ty v) targets ty))
|
||||
|
||||
;;;
|
||||
(rule
|
||||
(lower_branch (br_icmp cc a @ (value_type ty) b _ _) targets)
|
||||
(rule 1
|
||||
(lower_branch (brnz (icmp cc a @ (value_type ty) b) _ _) targets)
|
||||
(lower_br_icmp cc a b targets ty))
|
||||
|
||||
(rule
|
||||
(lower_branch (brif cc (ifcmp a @ (value_type ty) b) _ _) targets)
|
||||
(lower_br_icmp cc a b targets ty))
|
||||
|
||||
(rule
|
||||
(lower_branch (brff cc (ffcmp a @ (value_type ty) b) _ _) targets)
|
||||
(rule 1
|
||||
(lower_branch (brnz (fcmp cc a @ (value_type ty) b) _ _) targets)
|
||||
(lower_br_fcmp cc a b targets ty))
|
||||
|
||||
;;;
|
||||
(decl lower_br_table (Reg VecMachLabel) InstOutput)
|
||||
(extern constructor lower_br_table lower_br_table)
|
||||
|
||||
|
||||
@@ -605,6 +605,11 @@
|
||||
(gen_select ty (normalize_value cty c) x y)
|
||||
)
|
||||
|
||||
(rule 1
|
||||
(lower (has_type ty (select (icmp cc a b) x y)))
|
||||
(gen_select_reg cc a b x y)
|
||||
)
|
||||
|
||||
;;;;; Rules for `bitselect`;;;;;;;;;
|
||||
|
||||
(rule
|
||||
@@ -832,35 +837,15 @@
|
||||
(gen_float_round (FloatRoundOP.Nearest) x ty))
|
||||
|
||||
|
||||
;;;;; Rules for `selectif`;;;;;;;;;
|
||||
;;;;; Rules for `select_spectre_guard`;;;;;;;;;
|
||||
(rule
|
||||
(lower (has_type r_ty (selectif cc (ifcmp ca @ (value_type cty) cb) a b)))
|
||||
(let
|
||||
((dst VecWritableReg (alloc_vec_writable r_ty))
|
||||
(r Reg (lower_icmp cc ca cb cty))
|
||||
(_ Unit (emit (MInst.SelectIf $false (vec_writable_clone dst) r a b))))
|
||||
(vec_writable_to_regs dst)))
|
||||
|
||||
;;;;; Rules for `selectif_spectre_guard`;;;;;;;;;
|
||||
(rule
|
||||
(lower (has_type r_ty (selectif_spectre_guard cc (ifcmp ca @ (value_type cty) cb) a b)))
|
||||
(lower (has_type r_ty (select_spectre_guard (icmp cc ca @ (value_type cty) cb) a b)))
|
||||
(let
|
||||
((dst VecWritableReg (alloc_vec_writable r_ty))
|
||||
(r Reg (lower_icmp cc ca cb cty))
|
||||
(_ Unit (emit (MInst.SelectIf $true (vec_writable_clone dst) r a b))))
|
||||
(vec_writable_to_regs dst)))
|
||||
|
||||
;;;;; Rules for `trueif`;;;;;;;;;
|
||||
|
||||
(rule
|
||||
(lower (has_type ty (trueif cc (ifcmp ca @ (value_type cty) cb))))
|
||||
(lower_icmp cc ca cb cty))
|
||||
|
||||
;;;;; Rules for `trueff`;;;;;;;;;
|
||||
(rule
|
||||
(lower (has_type ty (trueff cc (ffcmp ca @ (value_type cty) cb))))
|
||||
(gen_fcmp cc ca cb cty))
|
||||
|
||||
|
||||
;;;;; Rules for `trapif`;;;;;;;;;
|
||||
(rule
|
||||
|
||||
@@ -3726,15 +3726,15 @@
|
||||
(put_in_reg val_true) (put_in_reg val_false)))
|
||||
|
||||
|
||||
;;;; Rules for `selectif_spectre_guard` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;;;; Rules for `select_spectre_guard` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
;; We do not support the `iflags` mechanism on our platform. However, common
|
||||
;; code will unconditionally emit certain patterns using `iflags` which we
|
||||
;; need to handle somehow. Note that only those specific patterns are
|
||||
;; recognized by the code below, other uses will fail to lower.
|
||||
|
||||
(rule (lower (has_type ty (selectif_spectre_guard int_cc
|
||||
(ifcmp x y) val_true val_false)))
|
||||
(rule (lower (has_type ty (select_spectre_guard
|
||||
(icmp int_cc x y) val_true val_false)))
|
||||
(select_bool_reg ty (icmp_val $false int_cc x y)
|
||||
(put_in_reg val_true) (put_in_reg val_false)))
|
||||
|
||||
@@ -3801,17 +3801,6 @@
|
||||
(vec_element targets 1))))
|
||||
|
||||
|
||||
;;;; Rules for `brif` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
;; Similarly to `selectif_spectre_guard`, we only recognize specific patterns
|
||||
;; generated by common code here. Others will fail to lower.
|
||||
|
||||
(rule (lower_branch (brif int_cc (ifcmp x y) _ _) targets)
|
||||
(side_effect (cond_br_bool (icmp_val $false int_cc x y)
|
||||
(vec_element targets 0)
|
||||
(vec_element targets 1))))
|
||||
|
||||
|
||||
;;;; Rules for `trap` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
(rule (lower (trap trap_code))
|
||||
|
||||
@@ -171,7 +171,7 @@ impl LowerBackend for S390xBackend {
|
||||
| Opcode::IsNull
|
||||
| Opcode::IsInvalid
|
||||
| Opcode::Select
|
||||
| Opcode::SelectifSpectreGuard
|
||||
| Opcode::SelectSpectreGuard
|
||||
| Opcode::Trap
|
||||
| Opcode::ResumableTrap
|
||||
| Opcode::Trapz
|
||||
@@ -223,21 +223,10 @@ impl LowerBackend for S390xBackend {
|
||||
Opcode::GlobalValue => {
|
||||
panic!("global_value should have been removed by legalization!");
|
||||
}
|
||||
Opcode::Ifcmp
|
||||
| Opcode::Ffcmp
|
||||
| Opcode::Trapff
|
||||
| Opcode::Trueif
|
||||
| Opcode::Trueff
|
||||
| Opcode::Selectif => {
|
||||
Opcode::Ifcmp | Opcode::Ffcmp | Opcode::Trapff => {
|
||||
panic!("Flags opcode should not be encountered.");
|
||||
}
|
||||
Opcode::Jump
|
||||
| Opcode::Brz
|
||||
| Opcode::Brnz
|
||||
| Opcode::BrIcmp
|
||||
| Opcode::Brif
|
||||
| Opcode::Brff
|
||||
| Opcode::BrTable => {
|
||||
Opcode::Jump | Opcode::Brz | Opcode::Brnz | Opcode::BrTable => {
|
||||
panic!("Branch opcode reached non-branch lowering logic!");
|
||||
}
|
||||
Opcode::IaddImm
|
||||
|
||||
@@ -1089,12 +1089,6 @@
|
||||
(decl cc_invert (CC) CC)
|
||||
(extern constructor cc_invert cc_invert)
|
||||
|
||||
(decl intcc_reverse (IntCC) IntCC)
|
||||
(extern constructor intcc_reverse intcc_reverse)
|
||||
|
||||
(decl floatcc_inverse (FloatCC) FloatCC)
|
||||
(extern constructor floatcc_inverse floatcc_inverse)
|
||||
|
||||
;; Fails if the argument is not either CC.NZ or CC.Z.
|
||||
(decl cc_nz_or_z (CC) CC)
|
||||
(extern extractor cc_nz_or_z cc_nz_or_z)
|
||||
|
||||
@@ -2760,16 +2760,6 @@
|
||||
(rule (lower_branch (jump _ _) (single_target target))
|
||||
(side_effect (jmp_known target)))
|
||||
|
||||
;; Rules for `brif` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
(rule (lower_branch (brif cc (ifcmp a b) _ _) (two_targets taken not_taken))
|
||||
(side_effect (jmp_cond_icmp (emit_cmp cc a b) taken not_taken)))
|
||||
|
||||
;; Rules for `brff` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
(rule (lower_branch (brff cc (ffcmp a b) _ _) (two_targets taken not_taken))
|
||||
(side_effect (jmp_cond_fcmp (emit_fcmp cc a b) taken not_taken)))
|
||||
|
||||
;; Rules for `brz` and `brnz` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
(rule 2 (lower_branch (brz (icmp cc a b) _ _) (two_targets taken not_taken))
|
||||
@@ -2828,22 +2818,14 @@
|
||||
(src Gpr val))
|
||||
(x64_test size src src)))
|
||||
|
||||
;; Rules for `bricmp` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
(rule (lower_branch (br_icmp cc a b _ _) (two_targets taken not_taken))
|
||||
(side_effect (jmp_cond_icmp (emit_cmp cc a b) taken not_taken)))
|
||||
|
||||
;; Rules for `br_table` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
(rule (lower_branch (br_table idx @ (value_type ty) _ _) (jump_table_targets default_target jt_targets))
|
||||
(side_effect (jmp_table_seq ty idx default_target jt_targets)))
|
||||
|
||||
;; Rules for `selectif` and `selectif_spectre_guard` ;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; Rules for `select_spectre_guard` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
(rule (lower (selectif cc (ifcmp a b) x y))
|
||||
(select_icmp (emit_cmp cc a b) x y))
|
||||
|
||||
(rule (lower (selectif_spectre_guard cc (ifcmp a b) x y))
|
||||
(rule (lower (select_spectre_guard (icmp cc a b) x y))
|
||||
(select_icmp (emit_cmp cc a b) x y))
|
||||
|
||||
;; Rules for `fcvt_from_sint` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
@@ -419,8 +419,7 @@ fn lower_insn_to_regs(
|
||||
| Opcode::GetStackPointer
|
||||
| Opcode::GetReturnAddress
|
||||
| Opcode::Select
|
||||
| Opcode::Selectif
|
||||
| Opcode::SelectifSpectreGuard
|
||||
| Opcode::SelectSpectreGuard
|
||||
| Opcode::FcvtFromSint
|
||||
| Opcode::FcvtLowFromSint
|
||||
| Opcode::FcvtFromUint
|
||||
@@ -499,8 +498,6 @@ fn lower_insn_to_regs(
|
||||
|
||||
Opcode::Bmask => unimplemented!("Bmask not implemented"),
|
||||
|
||||
Opcode::Trueif | Opcode::Trueff => unimplemented!("trueif / trueff not implemented"),
|
||||
|
||||
Opcode::Vsplit | Opcode::Vconcat => {
|
||||
unimplemented!("Vector split/concat ops not implemented.");
|
||||
}
|
||||
@@ -570,13 +567,7 @@ fn lower_insn_to_regs(
|
||||
panic!("trapz / trapnz / resumable_trapnz should have been removed by legalization!");
|
||||
}
|
||||
|
||||
Opcode::Jump
|
||||
| Opcode::Brz
|
||||
| Opcode::Brnz
|
||||
| Opcode::BrIcmp
|
||||
| Opcode::Brif
|
||||
| Opcode::Brff
|
||||
| Opcode::BrTable => {
|
||||
Opcode::Jump | Opcode::Brz | Opcode::Brnz | Opcode::BrTable => {
|
||||
panic!("Branch opcode reached non-branch lowering logic!");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -593,16 +593,6 @@ impl Context for IsleContext<'_, '_, MInst, Flags, IsaFlags, 6> {
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn intcc_reverse(&mut self, cc: &IntCC) -> IntCC {
|
||||
cc.reverse()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn floatcc_inverse(&mut self, cc: &FloatCC) -> FloatCC {
|
||||
cc.inverse()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn sum_extend_fits_in_32_bits(
|
||||
&mut self,
|
||||
|
||||
@@ -250,11 +250,11 @@ fn compute_addr(
|
||||
if let Some((cc, a, b)) = spectre_oob_comparison {
|
||||
let final_addr = pos.ins().iadd(base, offset);
|
||||
let zero = pos.ins().iconst(addr_ty, 0);
|
||||
let flags = pos.ins().ifcmp(a, b);
|
||||
let cmp = pos.ins().icmp(cc, a, b);
|
||||
pos.func
|
||||
.dfg
|
||||
.replace(inst)
|
||||
.selectif_spectre_guard(addr_ty, cc, flags, zero, final_addr);
|
||||
.select_spectre_guard(cmp, zero, final_addr);
|
||||
} else {
|
||||
pos.func.dfg.replace(inst).iadd(base, offset);
|
||||
}
|
||||
|
||||
@@ -54,27 +54,6 @@ pub fn simple_legalize(func: &mut ir::Function, cfg: &mut ControlFlowGraph, isa:
|
||||
while let Some(inst) = pos.next_inst() {
|
||||
match pos.func.dfg[inst] {
|
||||
// control flow
|
||||
InstructionData::BranchIcmp {
|
||||
opcode: ir::Opcode::BrIcmp,
|
||||
cond,
|
||||
destination,
|
||||
ref args,
|
||||
} => {
|
||||
let a = args.get(0, &pos.func.dfg.value_lists).unwrap();
|
||||
let b = args.get(1, &pos.func.dfg.value_lists).unwrap();
|
||||
let block_args = args.as_slice(&pos.func.dfg.value_lists)[2..].to_vec();
|
||||
|
||||
let old_block = pos.func.layout.pp_block(inst);
|
||||
pos.func.dfg.clear_results(inst);
|
||||
|
||||
let icmp_res = pos.func.dfg.replace(inst).icmp(cond, a, b);
|
||||
let mut pos = FuncCursor::new(pos.func).after_inst(inst);
|
||||
pos.use_srcloc(inst);
|
||||
pos.ins().brnz(icmp_res, destination, &block_args);
|
||||
|
||||
cfg.recompute_block(pos.func, destination);
|
||||
cfg.recompute_block(pos.func, old_block);
|
||||
}
|
||||
InstructionData::CondTrap {
|
||||
opcode:
|
||||
opcode @ (ir::Opcode::Trapnz | ir::Opcode::Trapz | ir::Opcode::ResumableTrapnz),
|
||||
|
||||
@@ -99,15 +99,11 @@ fn compute_addr(
|
||||
};
|
||||
|
||||
let element_addr = if let Some((index, bound)) = spectre_oob_cmp {
|
||||
let flags = pos.ins().ifcmp(index, bound);
|
||||
let cond = pos
|
||||
.ins()
|
||||
.icmp(IntCC::UnsignedGreaterThanOrEqual, index, bound);
|
||||
// If out-of-bounds, choose the table base on the misspeculation path.
|
||||
pos.ins().selectif_spectre_guard(
|
||||
addr_ty,
|
||||
IntCC::UnsignedGreaterThanOrEqual,
|
||||
flags,
|
||||
base,
|
||||
element_addr,
|
||||
)
|
||||
pos.ins().select_spectre_guard(cond, base, element_addr)
|
||||
} else {
|
||||
element_addr
|
||||
};
|
||||
|
||||
@@ -8,8 +8,8 @@ use target_lexicon::Triple;
|
||||
|
||||
pub use super::MachLabel;
|
||||
pub use crate::ir::{
|
||||
condcodes, dynamic_to_fixed, ArgumentExtension, Constant, DynamicStackSlot, ExternalName,
|
||||
FuncRef, GlobalValue, Immediate, SigRef, StackSlot,
|
||||
condcodes, condcodes::CondCode, dynamic_to_fixed, ArgumentExtension, Constant,
|
||||
DynamicStackSlot, ExternalName, FuncRef, GlobalValue, Immediate, SigRef, StackSlot,
|
||||
};
|
||||
pub use crate::isa::unwind::UnwindInst;
|
||||
pub use crate::machinst::{
|
||||
@@ -570,6 +570,26 @@ macro_rules! isle_lower_prelude_methods {
|
||||
fn gen_move(&mut self, ty: Type, dst: WritableReg, src: Reg) -> MInst {
|
||||
MInst::gen_move(dst, src, ty)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn intcc_reverse(&mut self, cc: &IntCC) -> IntCC {
|
||||
cc.reverse()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn intcc_inverse(&mut self, cc: &IntCC) -> IntCC {
|
||||
cc.inverse()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn floatcc_reverse(&mut self, cc: &FloatCC) -> FloatCC {
|
||||
cc.reverse()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn floatcc_inverse(&mut self, cc: &FloatCC) -> FloatCC {
|
||||
cc.inverse()
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -320,6 +320,23 @@
|
||||
|
||||
;;;; Helpers for Working with Flags ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
;; Reverse an IntCC flag.
|
||||
(decl intcc_reverse (IntCC) IntCC)
|
||||
(extern constructor intcc_reverse intcc_reverse)
|
||||
|
||||
;; Invert an IntCC flag.
|
||||
(decl intcc_inverse (IntCC) IntCC)
|
||||
(extern constructor intcc_inverse intcc_inverse)
|
||||
|
||||
;; Reverse an FloatCC flag.
|
||||
(decl floatcc_reverse (FloatCC) FloatCC)
|
||||
(extern constructor floatcc_reverse floatcc_reverse)
|
||||
|
||||
;; Invert an FloatCC flag.
|
||||
(decl floatcc_inverse (FloatCC) FloatCC)
|
||||
(extern constructor floatcc_inverse floatcc_inverse)
|
||||
|
||||
|
||||
;; Newtype wrapper around `MInst` for instructions that are used for their
|
||||
;; effect on flags.
|
||||
;;
|
||||
|
||||
@@ -469,7 +469,6 @@ fn do_divrem_transformation(divrem_info: &DivRemByConstInfo, pos: &mut FuncCurso
|
||||
enum BranchOrderKind {
|
||||
BrzToBrnz(Value),
|
||||
BrnzToBrz(Value),
|
||||
InvertIcmpCond(IntCC, Value, Value),
|
||||
}
|
||||
|
||||
/// Reorder branches to encourage fallthroughs.
|
||||
@@ -538,27 +537,6 @@ fn branch_order(pos: &mut FuncCursor, cfg: &mut ControlFlowGraph, block: Block,
|
||||
kind,
|
||||
)
|
||||
}
|
||||
InstructionData::BranchIcmp {
|
||||
opcode: Opcode::BrIcmp,
|
||||
cond,
|
||||
destination: cond_dest,
|
||||
args: ref prev_args,
|
||||
} => {
|
||||
let (x_arg, y_arg) = {
|
||||
let args = pos.func.dfg.inst_args(prev_inst);
|
||||
(args[0], args[1])
|
||||
};
|
||||
|
||||
(
|
||||
inst,
|
||||
args.clone(),
|
||||
destination,
|
||||
prev_inst,
|
||||
prev_args.clone(),
|
||||
*cond_dest,
|
||||
BranchOrderKind::InvertIcmpCond(*cond, x_arg, y_arg),
|
||||
)
|
||||
}
|
||||
_ => return,
|
||||
}
|
||||
}
|
||||
@@ -590,19 +568,6 @@ fn branch_order(pos: &mut FuncCursor, cfg: &mut ControlFlowGraph, block: Block,
|
||||
.replace(cond_inst)
|
||||
.brnz(cond_arg, term_dest, &term_args);
|
||||
}
|
||||
BranchOrderKind::InvertIcmpCond(cond, x_arg, y_arg) => {
|
||||
pos.func
|
||||
.dfg
|
||||
.replace(term_inst)
|
||||
.jump(cond_dest, &cond_args[2..]);
|
||||
pos.func.dfg.replace(cond_inst).br_icmp(
|
||||
cond.inverse(),
|
||||
x_arg,
|
||||
y_arg,
|
||||
term_dest,
|
||||
&term_args,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
cfg.recompute_block(pos.func, block);
|
||||
|
||||
@@ -639,21 +639,6 @@ impl<'a> Verifier<'a> {
|
||||
destination,
|
||||
ref args,
|
||||
..
|
||||
}
|
||||
| BranchInt {
|
||||
destination,
|
||||
ref args,
|
||||
..
|
||||
}
|
||||
| BranchFloat {
|
||||
destination,
|
||||
ref args,
|
||||
..
|
||||
}
|
||||
| BranchIcmp {
|
||||
destination,
|
||||
ref args,
|
||||
..
|
||||
} => {
|
||||
self.verify_block(inst, destination, errors)?;
|
||||
self.verify_value_list(inst, args, errors)?;
|
||||
@@ -776,10 +761,7 @@ impl<'a> Verifier<'a> {
|
||||
| Shuffle { .. }
|
||||
| IntCompare { .. }
|
||||
| IntCompareImm { .. }
|
||||
| IntCond { .. }
|
||||
| FloatCompare { .. }
|
||||
| FloatCond { .. }
|
||||
| IntSelect { .. }
|
||||
| Load { .. }
|
||||
| Store { .. }
|
||||
| Trap { .. }
|
||||
|
||||
@@ -418,12 +418,7 @@ pub fn write_operands(w: &mut dyn Write, dfg: &DataFlowGraph, inst: Inst) -> fmt
|
||||
}
|
||||
IntCompare { cond, args, .. } => write!(w, " {} {}, {}", cond, args[0], args[1]),
|
||||
IntCompareImm { cond, arg, imm, .. } => write!(w, " {} {}, {}", cond, arg, imm),
|
||||
IntCond { cond, arg, .. } => write!(w, " {} {}", cond, arg),
|
||||
FloatCompare { cond, args, .. } => write!(w, " {} {}, {}", cond, args[0], args[1]),
|
||||
FloatCond { cond, arg, .. } => write!(w, " {} {}", cond, arg),
|
||||
IntSelect { cond, args, .. } => {
|
||||
write!(w, " {} {}, {}, {}", cond, args[0], args[1], args[2])
|
||||
}
|
||||
Jump {
|
||||
destination,
|
||||
ref args,
|
||||
@@ -441,36 +436,6 @@ pub fn write_operands(w: &mut dyn Write, dfg: &DataFlowGraph, inst: Inst) -> fmt
|
||||
write!(w, " {}, {}", args[0], destination)?;
|
||||
write_block_args(w, &args[1..])
|
||||
}
|
||||
BranchInt {
|
||||
cond,
|
||||
destination,
|
||||
ref args,
|
||||
..
|
||||
} => {
|
||||
let args = args.as_slice(pool);
|
||||
write!(w, " {} {}, {}", cond, args[0], destination)?;
|
||||
write_block_args(w, &args[1..])
|
||||
}
|
||||
BranchFloat {
|
||||
cond,
|
||||
destination,
|
||||
ref args,
|
||||
..
|
||||
} => {
|
||||
let args = args.as_slice(pool);
|
||||
write!(w, " {} {}, {}", cond, args[0], destination)?;
|
||||
write_block_args(w, &args[1..])
|
||||
}
|
||||
BranchIcmp {
|
||||
cond,
|
||||
destination,
|
||||
ref args,
|
||||
..
|
||||
} => {
|
||||
let args = args.as_slice(pool);
|
||||
write!(w, " {} {}, {}, {}", cond, args[0], args[1], destination)?;
|
||||
write_block_args(w, &args[2..])
|
||||
}
|
||||
BranchTable {
|
||||
arg,
|
||||
destination,
|
||||
|
||||
@@ -151,8 +151,8 @@ block0(v0: i128, v1: i128):
|
||||
|
||||
function %f(i64, i64) -> i64 {
|
||||
block0(v0: i64, v1: i64):
|
||||
v2 = ifcmp v0, v1
|
||||
brif eq v2, block1
|
||||
v2 = icmp eq v0, v1
|
||||
brnz v2, block1
|
||||
jump block2
|
||||
|
||||
block1:
|
||||
@@ -176,8 +176,8 @@ block2:
|
||||
|
||||
function %f(i64, i64) -> i64 {
|
||||
block0(v0: i64, v1: i64):
|
||||
v2 = ifcmp v0, v1
|
||||
brif eq v2, block1
|
||||
v2 = icmp eq v0, v1
|
||||
brnz v2, block1
|
||||
jump block1
|
||||
|
||||
block1:
|
||||
@@ -238,7 +238,8 @@ block1:
|
||||
|
||||
function %i128_bricmp_eq(i128, i128) {
|
||||
block0(v0: i128, v1: i128):
|
||||
br_icmp eq v0, v1, block1
|
||||
v2 = icmp eq v0, v1
|
||||
brnz v2, block1
|
||||
jump block1
|
||||
|
||||
block1:
|
||||
@@ -258,7 +259,8 @@ block1:
|
||||
|
||||
function %i128_bricmp_ne(i128, i128) {
|
||||
block0(v0: i128, v1: i128):
|
||||
br_icmp ne v0, v1, block1
|
||||
v2 = icmp ne v0, v1
|
||||
brnz v2, block1
|
||||
jump block1
|
||||
|
||||
block1:
|
||||
@@ -278,7 +280,8 @@ block1:
|
||||
|
||||
function %i128_bricmp_slt(i128, i128) {
|
||||
block0(v0: i128, v1: i128):
|
||||
br_icmp slt v0, v1, block1
|
||||
v2 = icmp slt v0, v1
|
||||
brnz v2, block1
|
||||
jump block1
|
||||
|
||||
block1:
|
||||
@@ -302,7 +305,8 @@ block1:
|
||||
|
||||
function %i128_bricmp_ult(i128, i128) {
|
||||
block0(v0: i128, v1: i128):
|
||||
br_icmp ult v0, v1, block1
|
||||
v2 = icmp ult v0, v1
|
||||
brnz v2, block1
|
||||
jump block1
|
||||
|
||||
block1:
|
||||
@@ -326,7 +330,8 @@ block1:
|
||||
|
||||
function %i128_bricmp_sle(i128, i128) {
|
||||
block0(v0: i128, v1: i128):
|
||||
br_icmp sle v0, v1, block1
|
||||
v2 = icmp sle v0, v1
|
||||
brnz v2, block1
|
||||
jump block1
|
||||
|
||||
block1:
|
||||
@@ -351,7 +356,8 @@ block1:
|
||||
|
||||
function %i128_bricmp_ule(i128, i128) {
|
||||
block0(v0: i128, v1: i128):
|
||||
br_icmp ule v0, v1, block1
|
||||
v2 = icmp ule v0, v1
|
||||
brnz v2, block1
|
||||
jump block1
|
||||
|
||||
block1:
|
||||
@@ -376,7 +382,8 @@ block1:
|
||||
|
||||
function %i128_bricmp_sgt(i128, i128) {
|
||||
block0(v0: i128, v1: i128):
|
||||
br_icmp sgt v0, v1, block1
|
||||
v2 = icmp sgt v0, v1
|
||||
brnz v2, block1
|
||||
jump block1
|
||||
|
||||
block1:
|
||||
@@ -400,7 +407,8 @@ block1:
|
||||
|
||||
function %i128_bricmp_ugt(i128, i128) {
|
||||
block0(v0: i128, v1: i128):
|
||||
br_icmp ugt v0, v1, block1
|
||||
v2 = icmp ugt v0, v1
|
||||
brnz v2, block1
|
||||
jump block1
|
||||
|
||||
block1:
|
||||
@@ -424,7 +432,8 @@ block1:
|
||||
|
||||
function %i128_bricmp_sge(i128, i128) {
|
||||
block0(v0: i128, v1: i128):
|
||||
br_icmp sge v0, v1, block1
|
||||
v2 = icmp sge v0, v1
|
||||
brnz v2, block1
|
||||
jump block1
|
||||
|
||||
block1:
|
||||
@@ -449,7 +458,8 @@ block1:
|
||||
|
||||
function %i128_bricmp_uge(i128, i128) {
|
||||
block0(v0: i128, v1: i128):
|
||||
br_icmp uge v0, v1, block1
|
||||
v2 = icmp uge v0, v1
|
||||
brnz v2, block1
|
||||
jump block1
|
||||
|
||||
block1:
|
||||
|
||||
@@ -5,8 +5,8 @@ target aarch64
|
||||
function %f(i8, i8, i8) -> i8 {
|
||||
block0(v0: i8, v1: i8, v2: i8):
|
||||
v3 = iconst.i8 42
|
||||
v4 = ifcmp v0, v3
|
||||
v5 = selectif.i8 eq v4, v1, v2
|
||||
v4 = icmp eq v0, v3
|
||||
v5 = select v4, v1, v2
|
||||
return v5
|
||||
}
|
||||
|
||||
@@ -19,8 +19,8 @@ block0(v0: i8, v1: i8, v2: i8):
|
||||
function %f(i8, i16, i16) -> i16 {
|
||||
block0(v0: i8, v1: i16, v2: i16):
|
||||
v3 = iconst.i8 42
|
||||
v4 = ifcmp v0, v3
|
||||
v5 = selectif.i16 eq v4, v1, v2
|
||||
v4 = icmp eq v0, v3
|
||||
v5 = select v4, v1, v2
|
||||
return v5
|
||||
}
|
||||
|
||||
@@ -33,8 +33,8 @@ block0(v0: i8, v1: i16, v2: i16):
|
||||
function %f(i8, i32, i32) -> i32 {
|
||||
block0(v0: i8, v1: i32, v2: i32):
|
||||
v3 = iconst.i8 42
|
||||
v4 = ifcmp v0, v3
|
||||
v5 = selectif.i32 eq v4, v1, v2
|
||||
v4 = icmp eq v0, v3
|
||||
v5 = select v4, v1, v2
|
||||
return v5
|
||||
}
|
||||
|
||||
@@ -47,8 +47,8 @@ block0(v0: i8, v1: i32, v2: i32):
|
||||
function %f(i8, i64, i64) -> i64 {
|
||||
block0(v0: i8, v1: i64, v2: i64):
|
||||
v3 = iconst.i8 42
|
||||
v4 = ifcmp v0, v3
|
||||
v5 = selectif.i64 eq v4, v1, v2
|
||||
v4 = icmp eq v0, v3
|
||||
v5 = select v4, v1, v2
|
||||
return v5
|
||||
}
|
||||
|
||||
@@ -61,8 +61,8 @@ block0(v0: i8, v1: i64, v2: i64):
|
||||
function %f(i8, i128, i128) -> i128 {
|
||||
block0(v0: i8, v1: i128, v2: i128):
|
||||
v3 = iconst.i8 42
|
||||
v4 = ifcmp v0, v3
|
||||
v5 = selectif.i128 eq v4, v1, v2
|
||||
v4 = icmp eq v0, v3
|
||||
v5 = select v4, v1, v2
|
||||
return v5
|
||||
}
|
||||
|
||||
@@ -76,8 +76,8 @@ block0(v0: i8, v1: i128, v2: i128):
|
||||
function %f(i16, i8, i8) -> i8 {
|
||||
block0(v0: i16, v1: i8, v2: i8):
|
||||
v3 = iconst.i16 42
|
||||
v4 = ifcmp v0, v3
|
||||
v5 = selectif.i8 eq v4, v1, v2
|
||||
v4 = icmp eq v0, v3
|
||||
v5 = select v4, v1, v2
|
||||
return v5
|
||||
}
|
||||
|
||||
@@ -90,8 +90,8 @@ block0(v0: i16, v1: i8, v2: i8):
|
||||
function %f(i16, i16, i16) -> i16 {
|
||||
block0(v0: i16, v1: i16, v2: i16):
|
||||
v3 = iconst.i16 42
|
||||
v4 = ifcmp v0, v3
|
||||
v5 = selectif.i16 eq v4, v1, v2
|
||||
v4 = icmp eq v0, v3
|
||||
v5 = select v4, v1, v2
|
||||
return v5
|
||||
}
|
||||
|
||||
@@ -104,8 +104,8 @@ block0(v0: i16, v1: i16, v2: i16):
|
||||
function %f(i16, i32, i32) -> i32 {
|
||||
block0(v0: i16, v1: i32, v2: i32):
|
||||
v3 = iconst.i16 42
|
||||
v4 = ifcmp v0, v3
|
||||
v5 = selectif.i32 eq v4, v1, v2
|
||||
v4 = icmp eq v0, v3
|
||||
v5 = select v4, v1, v2
|
||||
return v5
|
||||
}
|
||||
|
||||
@@ -118,8 +118,8 @@ block0(v0: i16, v1: i32, v2: i32):
|
||||
function %f(i16, i64, i64) -> i64 {
|
||||
block0(v0: i16, v1: i64, v2: i64):
|
||||
v3 = iconst.i16 42
|
||||
v4 = ifcmp v0, v3
|
||||
v5 = selectif.i64 eq v4, v1, v2
|
||||
v4 = icmp eq v0, v3
|
||||
v5 = select v4, v1, v2
|
||||
return v5
|
||||
}
|
||||
|
||||
@@ -132,8 +132,8 @@ block0(v0: i16, v1: i64, v2: i64):
|
||||
function %f(i16, i128, i128) -> i128 {
|
||||
block0(v0: i16, v1: i128, v2: i128):
|
||||
v3 = iconst.i16 42
|
||||
v4 = ifcmp v0, v3
|
||||
v5 = selectif.i128 eq v4, v1, v2
|
||||
v4 = icmp eq v0, v3
|
||||
v5 = select v4, v1, v2
|
||||
return v5
|
||||
}
|
||||
|
||||
@@ -147,8 +147,8 @@ block0(v0: i16, v1: i128, v2: i128):
|
||||
function %f(i32, i8, i8) -> i8 {
|
||||
block0(v0: i32, v1: i8, v2: i8):
|
||||
v3 = iconst.i32 42
|
||||
v4 = ifcmp v0, v3
|
||||
v5 = selectif.i8 eq v4, v1, v2
|
||||
v4 = icmp eq v0, v3
|
||||
v5 = select v4, v1, v2
|
||||
return v5
|
||||
}
|
||||
|
||||
@@ -160,8 +160,8 @@ block0(v0: i32, v1: i8, v2: i8):
|
||||
function %f(i32, i16, i16) -> i16 {
|
||||
block0(v0: i32, v1: i16, v2: i16):
|
||||
v3 = iconst.i32 42
|
||||
v4 = ifcmp v0, v3
|
||||
v5 = selectif.i16 eq v4, v1, v2
|
||||
v4 = icmp eq v0, v3
|
||||
v5 = select v4, v1, v2
|
||||
return v5
|
||||
}
|
||||
|
||||
@@ -173,8 +173,8 @@ block0(v0: i32, v1: i16, v2: i16):
|
||||
function %f(i32, i32, i32) -> i32 {
|
||||
block0(v0: i32, v1: i32, v2: i32):
|
||||
v3 = iconst.i32 42
|
||||
v4 = ifcmp v0, v3
|
||||
v5 = selectif.i32 eq v4, v1, v2
|
||||
v4 = icmp eq v0, v3
|
||||
v5 = select v4, v1, v2
|
||||
return v5
|
||||
}
|
||||
|
||||
@@ -186,8 +186,8 @@ block0(v0: i32, v1: i32, v2: i32):
|
||||
function %f(i32, i64, i64) -> i64 {
|
||||
block0(v0: i32, v1: i64, v2: i64):
|
||||
v3 = iconst.i32 42
|
||||
v4 = ifcmp v0, v3
|
||||
v5 = selectif.i64 eq v4, v1, v2
|
||||
v4 = icmp eq v0, v3
|
||||
v5 = select v4, v1, v2
|
||||
return v5
|
||||
}
|
||||
|
||||
@@ -199,8 +199,8 @@ block0(v0: i32, v1: i64, v2: i64):
|
||||
function %f(i32, i128, i128) -> i128 {
|
||||
block0(v0: i32, v1: i128, v2: i128):
|
||||
v3 = iconst.i32 42
|
||||
v4 = ifcmp v0, v3
|
||||
v5 = selectif.i128 eq v4, v1, v2
|
||||
v4 = icmp eq v0, v3
|
||||
v5 = select v4, v1, v2
|
||||
return v5
|
||||
}
|
||||
|
||||
@@ -213,8 +213,8 @@ block0(v0: i32, v1: i128, v2: i128):
|
||||
function %f(i64, i8, i8) -> i8 {
|
||||
block0(v0: i64, v1: i8, v2: i8):
|
||||
v3 = iconst.i64 42
|
||||
v4 = ifcmp v0, v3
|
||||
v5 = selectif.i8 eq v4, v1, v2
|
||||
v4 = icmp eq v0, v3
|
||||
v5 = select v4, v1, v2
|
||||
return v5
|
||||
}
|
||||
|
||||
@@ -226,8 +226,8 @@ block0(v0: i64, v1: i8, v2: i8):
|
||||
function %f(i64, i16, i16) -> i16 {
|
||||
block0(v0: i64, v1: i16, v2: i16):
|
||||
v3 = iconst.i64 42
|
||||
v4 = ifcmp v0, v3
|
||||
v5 = selectif.i16 eq v4, v1, v2
|
||||
v4 = icmp eq v0, v3
|
||||
v5 = select v4, v1, v2
|
||||
return v5
|
||||
}
|
||||
|
||||
@@ -239,8 +239,8 @@ block0(v0: i64, v1: i16, v2: i16):
|
||||
function %f(i64, i32, i32) -> i32 {
|
||||
block0(v0: i64, v1: i32, v2: i32):
|
||||
v3 = iconst.i64 42
|
||||
v4 = ifcmp v0, v3
|
||||
v5 = selectif.i32 eq v4, v1, v2
|
||||
v4 = icmp eq v0, v3
|
||||
v5 = select v4, v1, v2
|
||||
return v5
|
||||
}
|
||||
|
||||
@@ -252,8 +252,8 @@ block0(v0: i64, v1: i32, v2: i32):
|
||||
function %f(i64, i64, i64) -> i64 {
|
||||
block0(v0: i64, v1: i64, v2: i64):
|
||||
v3 = iconst.i64 42
|
||||
v4 = ifcmp v0, v3
|
||||
v5 = selectif.i64 eq v4, v1, v2
|
||||
v4 = icmp eq v0, v3
|
||||
v5 = select v4, v1, v2
|
||||
return v5
|
||||
}
|
||||
|
||||
@@ -265,8 +265,8 @@ block0(v0: i64, v1: i64, v2: i64):
|
||||
function %f(i64, i128, i128) -> i128 {
|
||||
block0(v0: i64, v1: i128, v2: i128):
|
||||
v3 = iconst.i64 42
|
||||
v4 = ifcmp v0, v3
|
||||
v5 = selectif.i128 eq v4, v1, v2
|
||||
v4 = icmp eq v0, v3
|
||||
v5 = select v4, v1, v2
|
||||
return v5
|
||||
}
|
||||
|
||||
@@ -280,8 +280,8 @@ function %f(i128, i8, i8) -> i8 {
|
||||
block0(v0: i128, v1: i8, v2: i8):
|
||||
v3 = iconst.i64 42
|
||||
v4 = uextend.i128 v3
|
||||
v5 = ifcmp v0, v4
|
||||
v6 = selectif.i8 eq v5, v1, v2
|
||||
v5 = icmp eq v0, v4
|
||||
v6 = select.i8 v5, v1, v2
|
||||
return v6
|
||||
}
|
||||
|
||||
@@ -297,8 +297,8 @@ function %f(i128, i16, i16) -> i16 {
|
||||
block0(v0: i128, v1: i16, v2: i16):
|
||||
v3 = iconst.i64 42
|
||||
v4 = uextend.i128 v3
|
||||
v5 = ifcmp v0, v4
|
||||
v6 = selectif.i16 eq v5, v1, v2
|
||||
v5 = icmp eq v0, v4
|
||||
v6 = select.i16 v5, v1, v2
|
||||
return v6
|
||||
}
|
||||
|
||||
@@ -314,8 +314,8 @@ function %f(i128, i32, i32) -> i32 {
|
||||
block0(v0: i128, v1: i32, v2: i32):
|
||||
v3 = iconst.i64 42
|
||||
v4 = uextend.i128 v3
|
||||
v5 = ifcmp v0, v4
|
||||
v6 = selectif.i32 eq v5, v1, v2
|
||||
v5 = icmp eq v0, v4
|
||||
v6 = select.i32 v5, v1, v2
|
||||
return v6
|
||||
}
|
||||
|
||||
@@ -331,8 +331,8 @@ function %f(i128, i64, i64) -> i64 {
|
||||
block0(v0: i128, v1: i64, v2: i64):
|
||||
v3 = iconst.i64 42
|
||||
v4 = uextend.i128 v3
|
||||
v5 = ifcmp v0, v4
|
||||
v6 = selectif.i64 eq v5, v1, v2
|
||||
v5 = icmp eq v0, v4
|
||||
v6 = select.i64 v5, v1, v2
|
||||
return v6
|
||||
}
|
||||
|
||||
@@ -348,8 +348,8 @@ function %f(i128, i128, i128) -> i128 {
|
||||
block0(v0: i128, v1: i128, v2: i128):
|
||||
v3 = iconst.i64 42
|
||||
v4 = uextend.i128 v3
|
||||
v5 = ifcmp v0, v4
|
||||
v6 = selectif.i128 eq v5, v1, v2
|
||||
v5 = icmp eq v0, v4
|
||||
v6 = select.i128 v5, v1, v2
|
||||
return v6
|
||||
}
|
||||
|
||||
@@ -365,8 +365,8 @@ block0(v0: i128, v1: i128, v2: i128):
|
||||
function %f(i8, i8, i8) -> i8 {
|
||||
block0(v0: i8, v1: i8, v2: i8):
|
||||
v3 = iconst.i8 42
|
||||
v4 = ifcmp v0, v3
|
||||
v5 = selectif_spectre_guard.i8 eq v4, v1, v2
|
||||
v4 = icmp eq v0, v3
|
||||
v5 = select_spectre_guard.i8 v4, v1, v2
|
||||
return v5
|
||||
}
|
||||
|
||||
@@ -380,8 +380,8 @@ block0(v0: i8, v1: i8, v2: i8):
|
||||
function %f(i8, i16, i16) -> i16 {
|
||||
block0(v0: i8, v1: i16, v2: i16):
|
||||
v3 = iconst.i8 42
|
||||
v4 = ifcmp v0, v3
|
||||
v5 = selectif_spectre_guard.i16 eq v4, v1, v2
|
||||
v4 = icmp eq v0, v3
|
||||
v5 = select_spectre_guard.i16 v4, v1, v2
|
||||
return v5
|
||||
}
|
||||
|
||||
@@ -395,8 +395,8 @@ block0(v0: i8, v1: i16, v2: i16):
|
||||
function %f(i8, i32, i32) -> i32 {
|
||||
block0(v0: i8, v1: i32, v2: i32):
|
||||
v3 = iconst.i8 42
|
||||
v4 = ifcmp v0, v3
|
||||
v5 = selectif_spectre_guard.i32 eq v4, v1, v2
|
||||
v4 = icmp eq v0, v3
|
||||
v5 = select_spectre_guard.i32 v4, v1, v2
|
||||
return v5
|
||||
}
|
||||
|
||||
@@ -410,8 +410,8 @@ block0(v0: i8, v1: i32, v2: i32):
|
||||
function %f(i8, i64, i64) -> i64 {
|
||||
block0(v0: i8, v1: i64, v2: i64):
|
||||
v3 = iconst.i8 42
|
||||
v4 = ifcmp v0, v3
|
||||
v5 = selectif_spectre_guard.i64 eq v4, v1, v2
|
||||
v4 = icmp eq v0, v3
|
||||
v5 = select_spectre_guard.i64 v4, v1, v2
|
||||
return v5
|
||||
}
|
||||
|
||||
@@ -425,8 +425,8 @@ block0(v0: i8, v1: i64, v2: i64):
|
||||
function %f(i8, i128, i128) -> i128 {
|
||||
block0(v0: i8, v1: i128, v2: i128):
|
||||
v3 = iconst.i8 42
|
||||
v4 = ifcmp v0, v3
|
||||
v5 = selectif_spectre_guard.i128 eq v4, v1, v2
|
||||
v4 = icmp eq v0, v3
|
||||
v5 = select_spectre_guard.i128 v4, v1, v2
|
||||
return v5
|
||||
}
|
||||
|
||||
@@ -441,8 +441,8 @@ block0(v0: i8, v1: i128, v2: i128):
|
||||
function %f(i16, i8, i8) -> i8 {
|
||||
block0(v0: i16, v1: i8, v2: i8):
|
||||
v3 = iconst.i16 42
|
||||
v4 = ifcmp v0, v3
|
||||
v5 = selectif_spectre_guard.i8 eq v4, v1, v2
|
||||
v4 = icmp eq v0, v3
|
||||
v5 = select_spectre_guard.i8 v4, v1, v2
|
||||
return v5
|
||||
}
|
||||
|
||||
@@ -456,8 +456,8 @@ block0(v0: i16, v1: i8, v2: i8):
|
||||
function %f(i16, i16, i16) -> i16 {
|
||||
block0(v0: i16, v1: i16, v2: i16):
|
||||
v3 = iconst.i16 42
|
||||
v4 = ifcmp v0, v3
|
||||
v5 = selectif_spectre_guard.i16 eq v4, v1, v2
|
||||
v4 = icmp eq v0, v3
|
||||
v5 = select_spectre_guard.i16 v4, v1, v2
|
||||
return v5
|
||||
}
|
||||
|
||||
@@ -471,8 +471,8 @@ block0(v0: i16, v1: i16, v2: i16):
|
||||
function %f(i16, i32, i32) -> i32 {
|
||||
block0(v0: i16, v1: i32, v2: i32):
|
||||
v3 = iconst.i16 42
|
||||
v4 = ifcmp v0, v3
|
||||
v5 = selectif_spectre_guard.i32 eq v4, v1, v2
|
||||
v4 = icmp eq v0, v3
|
||||
v5 = select_spectre_guard.i32 v4, v1, v2
|
||||
return v5
|
||||
}
|
||||
|
||||
@@ -486,8 +486,8 @@ block0(v0: i16, v1: i32, v2: i32):
|
||||
function %f(i16, i64, i64) -> i64 {
|
||||
block0(v0: i16, v1: i64, v2: i64):
|
||||
v3 = iconst.i16 42
|
||||
v4 = ifcmp v0, v3
|
||||
v5 = selectif_spectre_guard.i64 eq v4, v1, v2
|
||||
v4 = icmp eq v0, v3
|
||||
v5 = select_spectre_guard.i64 v4, v1, v2
|
||||
return v5
|
||||
}
|
||||
|
||||
@@ -501,8 +501,8 @@ block0(v0: i16, v1: i64, v2: i64):
|
||||
function %f(i16, i128, i128) -> i128 {
|
||||
block0(v0: i16, v1: i128, v2: i128):
|
||||
v3 = iconst.i16 42
|
||||
v4 = ifcmp v0, v3
|
||||
v5 = selectif_spectre_guard.i128 eq v4, v1, v2
|
||||
v4 = icmp eq v0, v3
|
||||
v5 = select_spectre_guard.i128 v4, v1, v2
|
||||
return v5
|
||||
}
|
||||
|
||||
@@ -517,8 +517,8 @@ block0(v0: i16, v1: i128, v2: i128):
|
||||
function %f(i32, i8, i8) -> i8 {
|
||||
block0(v0: i32, v1: i8, v2: i8):
|
||||
v3 = iconst.i32 42
|
||||
v4 = ifcmp v0, v3
|
||||
v5 = selectif_spectre_guard.i8 eq v4, v1, v2
|
||||
v4 = icmp eq v0, v3
|
||||
v5 = select_spectre_guard.i8 v4, v1, v2
|
||||
return v5
|
||||
}
|
||||
|
||||
@@ -531,8 +531,8 @@ block0(v0: i32, v1: i8, v2: i8):
|
||||
function %f(i32, i16, i16) -> i16 {
|
||||
block0(v0: i32, v1: i16, v2: i16):
|
||||
v3 = iconst.i32 42
|
||||
v4 = ifcmp v0, v3
|
||||
v5 = selectif_spectre_guard.i16 eq v4, v1, v2
|
||||
v4 = icmp eq v0, v3
|
||||
v5 = select_spectre_guard.i16 v4, v1, v2
|
||||
return v5
|
||||
}
|
||||
|
||||
@@ -545,8 +545,8 @@ block0(v0: i32, v1: i16, v2: i16):
|
||||
function %f(i32, i32, i32) -> i32 {
|
||||
block0(v0: i32, v1: i32, v2: i32):
|
||||
v3 = iconst.i32 42
|
||||
v4 = ifcmp v0, v3
|
||||
v5 = selectif_spectre_guard.i32 eq v4, v1, v2
|
||||
v4 = icmp eq v0, v3
|
||||
v5 = select_spectre_guard.i32 v4, v1, v2
|
||||
return v5
|
||||
}
|
||||
|
||||
@@ -559,8 +559,8 @@ block0(v0: i32, v1: i32, v2: i32):
|
||||
function %f(i32, i64, i64) -> i64 {
|
||||
block0(v0: i32, v1: i64, v2: i64):
|
||||
v3 = iconst.i32 42
|
||||
v4 = ifcmp v0, v3
|
||||
v5 = selectif_spectre_guard.i64 eq v4, v1, v2
|
||||
v4 = icmp eq v0, v3
|
||||
v5 = select_spectre_guard.i64 v4, v1, v2
|
||||
return v5
|
||||
}
|
||||
|
||||
@@ -573,8 +573,8 @@ block0(v0: i32, v1: i64, v2: i64):
|
||||
function %f(i32, i128, i128) -> i128 {
|
||||
block0(v0: i32, v1: i128, v2: i128):
|
||||
v3 = iconst.i32 42
|
||||
v4 = ifcmp v0, v3
|
||||
v5 = selectif_spectre_guard.i128 eq v4, v1, v2
|
||||
v4 = icmp eq v0, v3
|
||||
v5 = select_spectre_guard.i128 v4, v1, v2
|
||||
return v5
|
||||
}
|
||||
|
||||
@@ -588,8 +588,8 @@ block0(v0: i32, v1: i128, v2: i128):
|
||||
function %f(i64, i8, i8) -> i8 {
|
||||
block0(v0: i64, v1: i8, v2: i8):
|
||||
v3 = iconst.i64 42
|
||||
v4 = ifcmp v0, v3
|
||||
v5 = selectif_spectre_guard.i8 eq v4, v1, v2
|
||||
v4 = icmp eq v0, v3
|
||||
v5 = select_spectre_guard.i8 v4, v1, v2
|
||||
return v5
|
||||
}
|
||||
|
||||
@@ -602,8 +602,8 @@ block0(v0: i64, v1: i8, v2: i8):
|
||||
function %f(i64, i16, i16) -> i16 {
|
||||
block0(v0: i64, v1: i16, v2: i16):
|
||||
v3 = iconst.i64 42
|
||||
v4 = ifcmp v0, v3
|
||||
v5 = selectif_spectre_guard.i16 eq v4, v1, v2
|
||||
v4 = icmp eq v0, v3
|
||||
v5 = select_spectre_guard.i16 v4, v1, v2
|
||||
return v5
|
||||
}
|
||||
|
||||
@@ -616,8 +616,8 @@ block0(v0: i64, v1: i16, v2: i16):
|
||||
function %f(i64, i32, i32) -> i32 {
|
||||
block0(v0: i64, v1: i32, v2: i32):
|
||||
v3 = iconst.i64 42
|
||||
v4 = ifcmp v0, v3
|
||||
v5 = selectif_spectre_guard.i32 eq v4, v1, v2
|
||||
v4 = icmp eq v0, v3
|
||||
v5 = select_spectre_guard.i32 v4, v1, v2
|
||||
return v5
|
||||
}
|
||||
|
||||
@@ -630,8 +630,8 @@ block0(v0: i64, v1: i32, v2: i32):
|
||||
function %f(i64, i64, i64) -> i64 {
|
||||
block0(v0: i64, v1: i64, v2: i64):
|
||||
v3 = iconst.i64 42
|
||||
v4 = ifcmp v0, v3
|
||||
v5 = selectif_spectre_guard.i64 eq v4, v1, v2
|
||||
v4 = icmp eq v0, v3
|
||||
v5 = select_spectre_guard.i64 v4, v1, v2
|
||||
return v5
|
||||
}
|
||||
|
||||
@@ -644,8 +644,8 @@ block0(v0: i64, v1: i64, v2: i64):
|
||||
function %f(i64, i128, i128) -> i128 {
|
||||
block0(v0: i64, v1: i128, v2: i128):
|
||||
v3 = iconst.i64 42
|
||||
v4 = ifcmp v0, v3
|
||||
v5 = selectif_spectre_guard.i128 eq v4, v1, v2
|
||||
v4 = icmp eq v0, v3
|
||||
v5 = select_spectre_guard.i128 v4, v1, v2
|
||||
return v5
|
||||
}
|
||||
|
||||
@@ -660,8 +660,8 @@ function %f(i128, i8, i8) -> i8 {
|
||||
block0(v0: i128, v1: i8, v2: i8):
|
||||
v3 = iconst.i64 42
|
||||
v4 = uextend.i128 v3
|
||||
v5 = ifcmp v0, v4
|
||||
v6 = selectif_spectre_guard.i8 eq v5, v1, v2
|
||||
v5 = icmp eq v0, v4
|
||||
v6 = select_spectre_guard.i8 v5, v1, v2
|
||||
return v6
|
||||
}
|
||||
|
||||
@@ -678,8 +678,8 @@ function %f(i128, i16, i16) -> i16 {
|
||||
block0(v0: i128, v1: i16, v2: i16):
|
||||
v3 = iconst.i64 42
|
||||
v4 = uextend.i128 v3
|
||||
v5 = ifcmp v0, v4
|
||||
v6 = selectif_spectre_guard.i16 eq v5, v1, v2
|
||||
v5 = icmp eq v0, v4
|
||||
v6 = select_spectre_guard.i16 v5, v1, v2
|
||||
return v6
|
||||
}
|
||||
|
||||
@@ -696,8 +696,8 @@ function %f(i128, i32, i32) -> i32 {
|
||||
block0(v0: i128, v1: i32, v2: i32):
|
||||
v3 = iconst.i64 42
|
||||
v4 = uextend.i128 v3
|
||||
v5 = ifcmp v0, v4
|
||||
v6 = selectif_spectre_guard.i32 eq v5, v1, v2
|
||||
v5 = icmp eq v0, v4
|
||||
v6 = select_spectre_guard.i32 v5, v1, v2
|
||||
return v6
|
||||
}
|
||||
|
||||
@@ -714,8 +714,8 @@ function %f(i128, i64, i64) -> i64 {
|
||||
block0(v0: i128, v1: i64, v2: i64):
|
||||
v3 = iconst.i64 42
|
||||
v4 = uextend.i128 v3
|
||||
v5 = ifcmp v0, v4
|
||||
v6 = selectif_spectre_guard.i64 eq v5, v1, v2
|
||||
v5 = icmp eq v0, v4
|
||||
v6 = select_spectre_guard.i64 v5, v1, v2
|
||||
return v6
|
||||
}
|
||||
|
||||
@@ -732,8 +732,8 @@ function %f(i128, i128, i128) -> i128 {
|
||||
block0(v0: i128, v1: i128, v2: i128):
|
||||
v3 = iconst.i64 42
|
||||
v4 = uextend.i128 v3
|
||||
v5 = ifcmp v0, v4
|
||||
v6 = selectif_spectre_guard.i128 eq v5, v1, v2
|
||||
v5 = icmp eq v0, v4
|
||||
v6 = select_spectre_guard.i128 v5, v1, v2
|
||||
return v6
|
||||
}
|
||||
|
||||
@@ -750,9 +750,8 @@ block0(v0: i128, v1: i128, v2: i128):
|
||||
function %g(i8) -> i8 {
|
||||
block0(v0: i8):
|
||||
v3 = iconst.i8 42
|
||||
v4 = ifcmp v0, v3
|
||||
v5 = trueif eq v4
|
||||
return v5
|
||||
v4 = icmp eq v0, v3
|
||||
return v4
|
||||
}
|
||||
|
||||
; block0:
|
||||
|
||||
@@ -114,8 +114,8 @@ block0(v0: i128, v1: i128):
|
||||
|
||||
function %f(i64, i64) -> i64 {
|
||||
block0(v0: i64, v1: i64):
|
||||
v2 = ifcmp v0, v1
|
||||
brif eq v2, block1
|
||||
v2 = icmp eq v0, v1
|
||||
brnz v2, block1
|
||||
jump block2
|
||||
|
||||
block1:
|
||||
@@ -139,8 +139,8 @@ block2:
|
||||
|
||||
function %f(i64, i64) -> i64 {
|
||||
block0(v0: i64, v1: i64):
|
||||
v2 = ifcmp v0, v1
|
||||
brif eq v2, block1
|
||||
v2 = icmp eq v0, v1
|
||||
brnz v2, block1
|
||||
jump block1
|
||||
|
||||
block1:
|
||||
@@ -201,7 +201,8 @@ block1:
|
||||
|
||||
function %i128_bricmp_eq(i128, i128) {
|
||||
block0(v0: i128, v1: i128):
|
||||
br_icmp eq v0, v1, block1
|
||||
v2 = icmp eq v0, v1
|
||||
brnz v2, block1
|
||||
jump block1
|
||||
|
||||
block1:
|
||||
@@ -209,9 +210,8 @@ block1:
|
||||
}
|
||||
|
||||
; block0:
|
||||
; eq a3,[a0,a1],[a2,a3]##ty=i128
|
||||
; andi a3,a3,255
|
||||
; bne a3,zero,taken(label1),not_taken(label2)
|
||||
; eq a2,[a0,a1],[a2,a3]##ty=i128
|
||||
; bne a2,zero,taken(label1),not_taken(label2)
|
||||
; block1:
|
||||
; j label3
|
||||
; block2:
|
||||
@@ -221,7 +221,8 @@ block1:
|
||||
|
||||
function %i128_bricmp_ne(i128, i128) {
|
||||
block0(v0: i128, v1: i128):
|
||||
br_icmp ne v0, v1, block1
|
||||
v2 = icmp ne v0, v1
|
||||
brnz v2, block1
|
||||
jump block1
|
||||
|
||||
block1:
|
||||
@@ -229,9 +230,8 @@ block1:
|
||||
}
|
||||
|
||||
; block0:
|
||||
; ne a3,[a0,a1],[a2,a3]##ty=i128
|
||||
; andi a3,a3,255
|
||||
; bne a3,zero,taken(label1),not_taken(label2)
|
||||
; ne a2,[a0,a1],[a2,a3]##ty=i128
|
||||
; bne a2,zero,taken(label1),not_taken(label2)
|
||||
; block1:
|
||||
; j label3
|
||||
; block2:
|
||||
@@ -241,7 +241,8 @@ block1:
|
||||
|
||||
function %i128_bricmp_slt(i128, i128) {
|
||||
block0(v0: i128, v1: i128):
|
||||
br_icmp slt v0, v1, block1
|
||||
v2 = icmp slt v0, v1
|
||||
brnz v2, block1
|
||||
jump block1
|
||||
|
||||
block1:
|
||||
@@ -249,9 +250,8 @@ block1:
|
||||
}
|
||||
|
||||
; block0:
|
||||
; slt a3,[a0,a1],[a2,a3]##ty=i128
|
||||
; andi a3,a3,255
|
||||
; bne a3,zero,taken(label1),not_taken(label2)
|
||||
; slt a2,[a0,a1],[a2,a3]##ty=i128
|
||||
; bne a2,zero,taken(label1),not_taken(label2)
|
||||
; block1:
|
||||
; j label3
|
||||
; block2:
|
||||
@@ -261,7 +261,8 @@ block1:
|
||||
|
||||
function %i128_bricmp_ult(i128, i128) {
|
||||
block0(v0: i128, v1: i128):
|
||||
br_icmp ult v0, v1, block1
|
||||
v2 = icmp ult v0, v1
|
||||
brnz v2, block1
|
||||
jump block1
|
||||
|
||||
block1:
|
||||
@@ -269,9 +270,8 @@ block1:
|
||||
}
|
||||
|
||||
; block0:
|
||||
; ult a3,[a0,a1],[a2,a3]##ty=i128
|
||||
; andi a3,a3,255
|
||||
; bne a3,zero,taken(label1),not_taken(label2)
|
||||
; ult a2,[a0,a1],[a2,a3]##ty=i128
|
||||
; bne a2,zero,taken(label1),not_taken(label2)
|
||||
; block1:
|
||||
; j label3
|
||||
; block2:
|
||||
@@ -281,7 +281,8 @@ block1:
|
||||
|
||||
function %i128_bricmp_sle(i128, i128) {
|
||||
block0(v0: i128, v1: i128):
|
||||
br_icmp sle v0, v1, block1
|
||||
v2 = icmp sle v0, v1
|
||||
brnz v2, block1
|
||||
jump block1
|
||||
|
||||
block1:
|
||||
@@ -289,9 +290,8 @@ block1:
|
||||
}
|
||||
|
||||
; block0:
|
||||
; sle a3,[a0,a1],[a2,a3]##ty=i128
|
||||
; andi a3,a3,255
|
||||
; bne a3,zero,taken(label1),not_taken(label2)
|
||||
; sle a2,[a0,a1],[a2,a3]##ty=i128
|
||||
; bne a2,zero,taken(label1),not_taken(label2)
|
||||
; block1:
|
||||
; j label3
|
||||
; block2:
|
||||
@@ -301,7 +301,8 @@ block1:
|
||||
|
||||
function %i128_bricmp_ule(i128, i128) {
|
||||
block0(v0: i128, v1: i128):
|
||||
br_icmp ule v0, v1, block1
|
||||
v2 = icmp ule v0, v1
|
||||
brnz v2, block1
|
||||
jump block1
|
||||
|
||||
block1:
|
||||
@@ -309,9 +310,8 @@ block1:
|
||||
}
|
||||
|
||||
; block0:
|
||||
; ule a3,[a0,a1],[a2,a3]##ty=i128
|
||||
; andi a3,a3,255
|
||||
; bne a3,zero,taken(label1),not_taken(label2)
|
||||
; ule a2,[a0,a1],[a2,a3]##ty=i128
|
||||
; bne a2,zero,taken(label1),not_taken(label2)
|
||||
; block1:
|
||||
; j label3
|
||||
; block2:
|
||||
@@ -321,7 +321,8 @@ block1:
|
||||
|
||||
function %i128_bricmp_sgt(i128, i128) {
|
||||
block0(v0: i128, v1: i128):
|
||||
br_icmp sgt v0, v1, block1
|
||||
v2 = icmp sgt v0, v1
|
||||
brnz v2, block1
|
||||
jump block1
|
||||
|
||||
block1:
|
||||
@@ -329,9 +330,8 @@ block1:
|
||||
}
|
||||
|
||||
; block0:
|
||||
; sgt a3,[a0,a1],[a2,a3]##ty=i128
|
||||
; andi a3,a3,255
|
||||
; bne a3,zero,taken(label1),not_taken(label2)
|
||||
; sgt a2,[a0,a1],[a2,a3]##ty=i128
|
||||
; bne a2,zero,taken(label1),not_taken(label2)
|
||||
; block1:
|
||||
; j label3
|
||||
; block2:
|
||||
@@ -341,7 +341,8 @@ block1:
|
||||
|
||||
function %i128_bricmp_ugt(i128, i128) {
|
||||
block0(v0: i128, v1: i128):
|
||||
br_icmp ugt v0, v1, block1
|
||||
v2 = icmp ugt v0, v1
|
||||
brnz v2, block1
|
||||
jump block1
|
||||
|
||||
block1:
|
||||
@@ -349,9 +350,8 @@ block1:
|
||||
}
|
||||
|
||||
; block0:
|
||||
; ugt a3,[a0,a1],[a2,a3]##ty=i128
|
||||
; andi a3,a3,255
|
||||
; bne a3,zero,taken(label1),not_taken(label2)
|
||||
; ugt a2,[a0,a1],[a2,a3]##ty=i128
|
||||
; bne a2,zero,taken(label1),not_taken(label2)
|
||||
; block1:
|
||||
; j label3
|
||||
; block2:
|
||||
@@ -361,7 +361,8 @@ block1:
|
||||
|
||||
function %i128_bricmp_sge(i128, i128) {
|
||||
block0(v0: i128, v1: i128):
|
||||
br_icmp sge v0, v1, block1
|
||||
v2 = icmp sge v0, v1
|
||||
brnz v2, block1
|
||||
jump block1
|
||||
|
||||
block1:
|
||||
@@ -369,9 +370,8 @@ block1:
|
||||
}
|
||||
|
||||
; block0:
|
||||
; sge a3,[a0,a1],[a2,a3]##ty=i128
|
||||
; andi a3,a3,255
|
||||
; bne a3,zero,taken(label1),not_taken(label2)
|
||||
; sge a2,[a0,a1],[a2,a3]##ty=i128
|
||||
; bne a2,zero,taken(label1),not_taken(label2)
|
||||
; block1:
|
||||
; j label3
|
||||
; block2:
|
||||
@@ -381,7 +381,8 @@ block1:
|
||||
|
||||
function %i128_bricmp_uge(i128, i128) {
|
||||
block0(v0: i128, v1: i128):
|
||||
br_icmp uge v0, v1, block1
|
||||
v2 = icmp uge v0, v1
|
||||
brnz v2, block1
|
||||
jump block1
|
||||
|
||||
block1:
|
||||
@@ -389,9 +390,8 @@ block1:
|
||||
}
|
||||
|
||||
; block0:
|
||||
; uge a3,[a0,a1],[a2,a3]##ty=i128
|
||||
; andi a3,a3,255
|
||||
; bne a3,zero,taken(label1),not_taken(label2)
|
||||
; uge a2,[a0,a1],[a2,a3]##ty=i128
|
||||
; bne a2,zero,taken(label1),not_taken(label2)
|
||||
; block1:
|
||||
; j label3
|
||||
; block2:
|
||||
|
||||
@@ -5,25 +5,21 @@ target riscv64
|
||||
function %f(i8, i64, i64) -> i64 {
|
||||
block0(v0: i8, v1: i64, v2: i64):
|
||||
v3 = iconst.i8 42
|
||||
v4 = ifcmp v0, v3
|
||||
v5 = selectif.i64 eq v4, v1, v2
|
||||
v4 = icmp eq v0, v3
|
||||
v5 = select.i64 v4, v1, v2
|
||||
return v5
|
||||
}
|
||||
|
||||
; block0:
|
||||
; li a3,42
|
||||
; uext.b a5,a0
|
||||
; uext.b a7,a3
|
||||
; eq t4,a5,a7##ty=i8
|
||||
; selectif a0,a1,a2##test=t4
|
||||
; select_reg a0,a1,a2##condition=(a0 eq a3)
|
||||
; ret
|
||||
|
||||
function %g(i8) -> i8 {
|
||||
block0(v0: i8):
|
||||
v3 = iconst.i8 42
|
||||
v4 = ifcmp v0, v3
|
||||
v5 = trueif eq v4
|
||||
return v5
|
||||
v4 = icmp eq v0, v3
|
||||
return v4
|
||||
}
|
||||
|
||||
; block0:
|
||||
@@ -68,12 +64,8 @@ block0(v0: i32, v1: i8, v2: i8):
|
||||
}
|
||||
|
||||
; block0:
|
||||
; li a4,42
|
||||
; uext.w a6,a0
|
||||
; uext.w t3,a4
|
||||
; eq t0,a6,t3##ty=i32
|
||||
; andi a6,t0,255
|
||||
; select_i8 a0,a1,a2##condition=a6
|
||||
; li a3,42
|
||||
; select_reg a0,a1,a2##condition=(a0 eq a3)
|
||||
; ret
|
||||
|
||||
function %i128_select(i8, i128, i128) -> i128 {
|
||||
|
||||
@@ -13,17 +13,16 @@ block0(v0: i64, v1: i32):
|
||||
}
|
||||
|
||||
; block0:
|
||||
; uext.w t4,a1
|
||||
; ld t0,0(a0)
|
||||
; addi t0,t0,0
|
||||
; ugt t1,t4,t0##ty=i64
|
||||
; andi t1,t1,255
|
||||
; beq t1,zero,taken(label1),not_taken(label2)
|
||||
; uext.w t3,a1
|
||||
; ld t4,0(a0)
|
||||
; addi t4,t4,0
|
||||
; ule t0,t3,t4##ty=i64
|
||||
; bne t0,zero,taken(label1),not_taken(label2)
|
||||
; block1:
|
||||
; add t1,a0,t4
|
||||
; ugt t4,t4,t0##ty=i64
|
||||
; li t2,0
|
||||
; selectif_spectre_guard a0,t2,t1##test=t4
|
||||
; add t0,a0,t3
|
||||
; ugt t3,t3,t4##ty=i64
|
||||
; li t1,0
|
||||
; selectif_spectre_guard a0,t1,t0##test=t3
|
||||
; ret
|
||||
; block2:
|
||||
; udf##trap_code=heap_oob
|
||||
@@ -38,17 +37,16 @@ block0(v0: i64, v1: i32):
|
||||
}
|
||||
|
||||
; block0:
|
||||
; uext.w t4,a1
|
||||
; lui t3,16
|
||||
; ugt t0,t4,t3##ty=i64
|
||||
; andi t0,t0,255
|
||||
; beq t0,zero,taken(label1),not_taken(label2)
|
||||
; uext.w t3,a1
|
||||
; lui a7,16
|
||||
; ule t4,t3,a7##ty=i64
|
||||
; bne t4,zero,taken(label1),not_taken(label2)
|
||||
; block1:
|
||||
; add t0,a0,t4
|
||||
; lui t3,16
|
||||
; ugt t1,t4,t3##ty=i64
|
||||
; li t2,0
|
||||
; selectif_spectre_guard a0,t2,t0##test=t1
|
||||
; add t4,a0,t3
|
||||
; lui a7,16
|
||||
; ugt t0,t3,a7##ty=i64
|
||||
; li t1,0
|
||||
; selectif_spectre_guard a0,t1,t4##test=t0
|
||||
; ret
|
||||
; block2:
|
||||
; udf##trap_code=heap_oob
|
||||
|
||||
@@ -65,8 +65,8 @@ block2:
|
||||
|
||||
function %f2(i32, i32) -> i32 {
|
||||
block0(v0: i32, v1: i32):
|
||||
v2 = ifcmp v0, v1
|
||||
brif eq v2, block1
|
||||
v2 = icmp eq v0, v1
|
||||
brnz v2, block1
|
||||
jump block2
|
||||
|
||||
block1:
|
||||
@@ -96,8 +96,8 @@ block2:
|
||||
|
||||
function %f3(f32, f32) -> i32 {
|
||||
block0(v0: f32, v1: f32):
|
||||
v2 = ffcmp v0, v1
|
||||
brff eq v2, block1
|
||||
v2 = fcmp eq v0, v1
|
||||
brnz v2, block1
|
||||
jump block2
|
||||
|
||||
block1:
|
||||
@@ -282,3 +282,49 @@ block2:
|
||||
; popq %rbp
|
||||
; ret
|
||||
|
||||
function %fflags(f32) {
|
||||
block200(v0: f32):
|
||||
v1 = f32const 0x34.0p0
|
||||
v2 = fcmp eq v0, v1
|
||||
brnz v2, block201
|
||||
jump block400
|
||||
|
||||
block400:
|
||||
v3 = fcmp ord v0, v1
|
||||
brnz v3, block202
|
||||
jump block201
|
||||
|
||||
block401:
|
||||
return
|
||||
|
||||
block201:
|
||||
return
|
||||
|
||||
block202:
|
||||
trap heap_oob
|
||||
}
|
||||
|
||||
; pushq %rbp
|
||||
; movq %rsp, %rbp
|
||||
; block0:
|
||||
; movl $1112539136, %r8d
|
||||
; movd %r8d, %xmm5
|
||||
; ucomiss %xmm5, %xmm0
|
||||
; jp label2
|
||||
; jnz label2; j label1
|
||||
; block1:
|
||||
; jmp label5
|
||||
; block2:
|
||||
; movl $1112539136, %esi
|
||||
; movd %esi, %xmm9
|
||||
; ucomiss %xmm9, %xmm0
|
||||
; jnp label3; j label4
|
||||
; block3:
|
||||
; ud2 heap_oob
|
||||
; block4:
|
||||
; jmp label5
|
||||
; block5:
|
||||
; movq %rbp, %rsp
|
||||
; popq %rbp
|
||||
; ret
|
||||
|
||||
|
||||
@@ -3,49 +3,19 @@ test verifier
|
||||
|
||||
function %iflags(i32) {
|
||||
block200(v0: i32):
|
||||
v1 = ifcmp_imm v0, 17
|
||||
brif eq v1, block201
|
||||
v17 = iconst.i32 17
|
||||
v1 = icmp eq v0, v17
|
||||
brnz v1, block201
|
||||
jump block400
|
||||
|
||||
block400:
|
||||
brif ugt v1, block202
|
||||
v5 = icmp ugt v0, v17
|
||||
brnz v5, block202
|
||||
jump block401
|
||||
|
||||
block401:
|
||||
v2 = iconst.i32 34
|
||||
v3 = ifcmp v0, v2
|
||||
v4 = trueif eq v3
|
||||
brnz v4, block202
|
||||
jump block402
|
||||
|
||||
block402:
|
||||
return
|
||||
|
||||
block201:
|
||||
return
|
||||
|
||||
block202:
|
||||
trap heap_oob
|
||||
}
|
||||
; check: v1 = ifcmp_imm v0, 17
|
||||
; check: brif eq v1, block201
|
||||
; check: brif ugt v1, block202
|
||||
; check: v3 = ifcmp.i32 v0, v2
|
||||
; check: v4 = trueif eq v3
|
||||
|
||||
function %fflags(f32) {
|
||||
block200(v0: f32):
|
||||
v1 = f32const 0x34.0p0
|
||||
v2 = ffcmp v0, v1
|
||||
brff eq v2, block201
|
||||
jump block400
|
||||
|
||||
block400:
|
||||
brff ord v2, block202
|
||||
jump block401
|
||||
|
||||
block401:
|
||||
v3 = trueff gt v2
|
||||
v3 = icmp eq v0, v2
|
||||
brnz v3, block202
|
||||
jump block402
|
||||
|
||||
@@ -58,7 +28,41 @@ block201:
|
||||
block202:
|
||||
trap heap_oob
|
||||
}
|
||||
; check: v2 = ffcmp v0, v1
|
||||
; check: brff eq v2, block201
|
||||
; check: brff ord v2, block202
|
||||
; check: v3 = trueff gt v2
|
||||
; check: v17 = iconst.i32 17
|
||||
; check: v1 = icmp eq v0, v17
|
||||
; check: brnz v1, block201
|
||||
; check: v5 = icmp.i32 ugt v0, v17
|
||||
; check: brnz v5, block202
|
||||
; check: v3 = icmp.i32 eq v0, v2
|
||||
|
||||
function %fflags(f32) {
|
||||
block200(v0: f32):
|
||||
v1 = f32const 0x34.0p0
|
||||
v2 = fcmp eq v0, v1
|
||||
brnz v2, block201
|
||||
jump block400
|
||||
|
||||
block400:
|
||||
v5 = fcmp ord v0, v1
|
||||
brnz v5, block202
|
||||
jump block401
|
||||
|
||||
block401:
|
||||
v3 = fcmp gt v0, v1
|
||||
brnz v3, block202
|
||||
jump block402
|
||||
|
||||
block402:
|
||||
return
|
||||
|
||||
block201:
|
||||
return
|
||||
|
||||
block202:
|
||||
trap heap_oob
|
||||
}
|
||||
; check: v2 = fcmp eq v0, v1
|
||||
; check: brnz v2, block201
|
||||
; check: v5 = fcmp.f32 ord v0, v1
|
||||
; check: brnz v5, block202
|
||||
; check: v3 = fcmp.f32 gt v0, v1
|
||||
|
||||
@@ -53,13 +53,15 @@ block0(v90: i32, v91: i32, v92: i8):
|
||||
; nextln: }
|
||||
|
||||
; Polymorphic instruction controlled by third operand.
|
||||
function %selectif() system_v {
|
||||
function %select() system_v {
|
||||
block0(v95: i32, v96: i32, v97: i8):
|
||||
v98 = selectif.i32 eq v97, v95, v96
|
||||
v99 = icmp eq v97, v95
|
||||
v98 = select v99, v95, v96
|
||||
}
|
||||
; sameln: function %selectif() system_v {
|
||||
; sameln: function %select() system_v {
|
||||
; nextln: block0(v95: i32, v96: i32, v97: i8):
|
||||
; nextln: v98 = selectif.i32 eq v97, v95, v96
|
||||
; nextln: v99 = icmp eq v97, v95
|
||||
; nextln: v98 = select v99, v95, v96
|
||||
; nextln: }
|
||||
|
||||
; Lane indexes.
|
||||
@@ -83,7 +85,8 @@ block0(v90: i32, v91: i32):
|
||||
v1 = icmp ult v90, v91
|
||||
v2 = icmp_imm sge v90, -12
|
||||
v3 = irsub_imm v91, 45
|
||||
br_icmp eq v90, v91, block0(v91, v90)
|
||||
v4 = icmp eq v90, v91
|
||||
brnz v4, block0(v91, v90)
|
||||
}
|
||||
; sameln: function %icmp(i32, i32) fast {
|
||||
; nextln: block0(v90: i32, v91: i32):
|
||||
@@ -91,7 +94,8 @@ block0(v90: i32, v91: i32):
|
||||
; nextln: v1 = icmp ult v90, v91
|
||||
; nextln: v2 = icmp_imm sge v90, -12
|
||||
; nextln: v3 = irsub_imm v91, 45
|
||||
; nextln: br_icmp eq v90, v91, block0(v91, v90)
|
||||
; nextln: v4 = icmp eq v90, v91
|
||||
; nextln: brnz v4, block0(v91, v90)
|
||||
; nextln: }
|
||||
|
||||
; Floating condition codes.
|
||||
|
||||
@@ -1,767 +0,0 @@
|
||||
test interpret
|
||||
test run
|
||||
target aarch64
|
||||
target s390x
|
||||
target x86_64
|
||||
target riscv64
|
||||
|
||||
function %bricmp_eq_i64(i64, i64) -> i8 {
|
||||
block0(v0: i64, v1: i64):
|
||||
br_icmp.i64 eq v0, v1, block2
|
||||
jump block1
|
||||
|
||||
block1:
|
||||
v2 = iconst.i8 0
|
||||
return v2
|
||||
|
||||
block2:
|
||||
v3 = iconst.i8 1
|
||||
return v3
|
||||
}
|
||||
; run: %bricmp_eq_i64(0, 0) == 1
|
||||
; run: %bricmp_eq_i64(0, 1) == 0
|
||||
; run: %bricmp_eq_i64(1, 0) == 0
|
||||
; run: %bricmp_eq_i64(0xC0FFEEEE_DECAFFFF, 0xDECAFFFF_C0FFEEEE) == 0
|
||||
|
||||
function %bricmp_eq_i32(i32, i32) -> i8 {
|
||||
block0(v0: i32, v1: i32):
|
||||
br_icmp.i32 eq v0, v1, block2
|
||||
jump block1
|
||||
|
||||
block1:
|
||||
v2 = iconst.i8 0
|
||||
return v2
|
||||
|
||||
block2:
|
||||
v3 = iconst.i8 1
|
||||
return v3
|
||||
}
|
||||
; run: %bricmp_eq_i32(0, 0) == 1
|
||||
; run: %bricmp_eq_i32(0, 1) == 0
|
||||
; run: %bricmp_eq_i32(1, 0) == 0
|
||||
; run: %bricmp_eq_i32(0xC0FFEEEE, 0xDECAFFFF) == 0
|
||||
|
||||
function %bricmp_eq_i16(i16, i16) -> i8 {
|
||||
block0(v0: i16, v1: i16):
|
||||
br_icmp.i16 eq v0, v1, block2
|
||||
jump block1
|
||||
|
||||
block1:
|
||||
v2 = iconst.i8 0
|
||||
return v2
|
||||
|
||||
block2:
|
||||
v3 = iconst.i8 1
|
||||
return v3
|
||||
}
|
||||
; run: %bricmp_eq_i16(0, 0) == 1
|
||||
; run: %bricmp_eq_i16(0, 1) == 0
|
||||
; run: %bricmp_eq_i16(1, 0) == 0
|
||||
; run: %bricmp_eq_i16(0xC0FF, 0xDECA) == 0
|
||||
|
||||
function %bricmp_eq_i8(i8, i8) -> i8 {
|
||||
block0(v0: i8, v1: i8):
|
||||
br_icmp.i8 eq v0, v1, block2
|
||||
jump block1
|
||||
|
||||
block1:
|
||||
v2 = iconst.i8 0
|
||||
return v2
|
||||
|
||||
block2:
|
||||
v3 = iconst.i8 1
|
||||
return v3
|
||||
}
|
||||
; run: %bricmp_eq_i8(0, 0) == 1
|
||||
; run: %bricmp_eq_i8(0, 1) == 0
|
||||
; run: %bricmp_eq_i8(1, 0) == 0
|
||||
; run: %bricmp_eq_i8(0xC0, 0xDE) == 0
|
||||
|
||||
|
||||
function %bricmp_ne_i64(i64, i64) -> i8 {
|
||||
block0(v0: i64, v1: i64):
|
||||
br_icmp.i64 ne v0, v1, block2
|
||||
jump block1
|
||||
|
||||
block1:
|
||||
v2 = iconst.i8 0
|
||||
return v2
|
||||
|
||||
block2:
|
||||
v3 = iconst.i8 1
|
||||
return v3
|
||||
}
|
||||
; run: %bricmp_ne_i64(0, 0) == 0
|
||||
; run: %bricmp_ne_i64(0, 1) == 1
|
||||
; run: %bricmp_ne_i64(1, 0) == 1
|
||||
; run: %bricmp_ne_i64(0xC0FFEEEE_DECAFFFF, 0xDECAFFFF_C0FFEEEE) == 1
|
||||
|
||||
function %bricmp_ne_i32(i32, i32) -> i8 {
|
||||
block0(v0: i32, v1: i32):
|
||||
br_icmp.i32 ne v0, v1, block2
|
||||
jump block1
|
||||
|
||||
block1:
|
||||
v2 = iconst.i8 0
|
||||
return v2
|
||||
|
||||
block2:
|
||||
v3 = iconst.i8 1
|
||||
return v3
|
||||
}
|
||||
; run: %bricmp_ne_i32(0, 0) == 0
|
||||
; run: %bricmp_ne_i32(0, 1) == 1
|
||||
; run: %bricmp_ne_i32(1, 0) == 1
|
||||
; run: %bricmp_ne_i32(0xC0FFEEEE, 0xDECAFFFF) == 1
|
||||
|
||||
function %bricmp_ne_i16(i16, i16) -> i8 {
|
||||
block0(v0: i16, v1: i16):
|
||||
br_icmp.i16 ne v0, v1, block2
|
||||
jump block1
|
||||
|
||||
block1:
|
||||
v2 = iconst.i8 0
|
||||
return v2
|
||||
|
||||
block2:
|
||||
v3 = iconst.i8 1
|
||||
return v3
|
||||
}
|
||||
; run: %bricmp_ne_i16(0, 0) == 0
|
||||
; run: %bricmp_ne_i16(0, 1) == 1
|
||||
; run: %bricmp_ne_i16(1, 0) == 1
|
||||
; run: %bricmp_ne_i16(0xC0FF, 0xDECA) == 1
|
||||
|
||||
function %bricmp_ne_i8(i8, i8) -> i8 {
|
||||
block0(v0: i8, v1: i8):
|
||||
br_icmp.i8 ne v0, v1, block2
|
||||
jump block1
|
||||
|
||||
block1:
|
||||
v2 = iconst.i8 0
|
||||
return v2
|
||||
|
||||
block2:
|
||||
v3 = iconst.i8 1
|
||||
return v3
|
||||
}
|
||||
; run: %bricmp_ne_i8(0, 0) == 0
|
||||
; run: %bricmp_ne_i8(0, 1) == 1
|
||||
; run: %bricmp_ne_i8(1, 0) == 1
|
||||
; run: %bricmp_ne_i8(0xC0, 0xDE) == 1
|
||||
|
||||
|
||||
function %bricmp_slt_i64(i64, i64) -> i8 {
|
||||
block0(v0: i64, v1: i64):
|
||||
br_icmp.i64 slt v0, v1, block2
|
||||
jump block1
|
||||
|
||||
block1:
|
||||
v2 = iconst.i8 0
|
||||
return v2
|
||||
|
||||
block2:
|
||||
v3 = iconst.i8 1
|
||||
return v3
|
||||
}
|
||||
; run: %bricmp_slt_i64(0, 0) == 0
|
||||
; run: %bricmp_slt_i64(0, 1) == 1
|
||||
; run: %bricmp_slt_i64(1, 0) == 0
|
||||
; run: %bricmp_slt_i64(0, -1) == 0
|
||||
; run: %bricmp_slt_i64(-1, 0) == 1
|
||||
|
||||
function %bricmp_slt_i32(i32, i32) -> i8 {
|
||||
block0(v0: i32, v1: i32):
|
||||
br_icmp.i32 slt v0, v1, block2
|
||||
jump block1
|
||||
|
||||
block1:
|
||||
v2 = iconst.i8 0
|
||||
return v2
|
||||
|
||||
block2:
|
||||
v3 = iconst.i8 1
|
||||
return v3
|
||||
}
|
||||
; run: %bricmp_slt_i32(0, 0) == 0
|
||||
; run: %bricmp_slt_i32(0, 1) == 1
|
||||
; run: %bricmp_slt_i32(1, 0) == 0
|
||||
; run: %bricmp_slt_i32(0, -1) == 0
|
||||
; run: %bricmp_slt_i32(-1, 0) == 1
|
||||
|
||||
function %bricmp_slt_i16(i16, i16) -> i8 {
|
||||
block0(v0: i16, v1: i16):
|
||||
br_icmp.i16 slt v0, v1, block2
|
||||
jump block1
|
||||
|
||||
block1:
|
||||
v2 = iconst.i8 0
|
||||
return v2
|
||||
|
||||
block2:
|
||||
v3 = iconst.i8 1
|
||||
return v3
|
||||
}
|
||||
; run: %bricmp_slt_i16(0, 0) == 0
|
||||
; run: %bricmp_slt_i16(0, 1) == 1
|
||||
; run: %bricmp_slt_i16(1, 0) == 0
|
||||
; run: %bricmp_slt_i16(0, -1) == 0
|
||||
; run: %bricmp_slt_i16(-1, 0) == 1
|
||||
|
||||
function %bricmp_slt_i8(i8, i8) -> i8 {
|
||||
block0(v0: i8, v1: i8):
|
||||
br_icmp.i8 slt v0, v1, block2
|
||||
jump block1
|
||||
|
||||
block1:
|
||||
v2 = iconst.i8 0
|
||||
return v2
|
||||
|
||||
block2:
|
||||
v3 = iconst.i8 1
|
||||
return v3
|
||||
}
|
||||
; run: %bricmp_slt_i8(0, 0) == 0
|
||||
; run: %bricmp_slt_i8(0, 1) == 1
|
||||
; run: %bricmp_slt_i8(1, 0) == 0
|
||||
; run: %bricmp_slt_i8(0, -1) == 0
|
||||
; run: %bricmp_slt_i8(-1, 0) == 1
|
||||
|
||||
|
||||
function %bricmp_ult_i64(i64, i64) -> i8 {
|
||||
block0(v0: i64, v1: i64):
|
||||
br_icmp.i64 ult v0, v1, block2
|
||||
jump block1
|
||||
|
||||
block1:
|
||||
v2 = iconst.i8 0
|
||||
return v2
|
||||
|
||||
block2:
|
||||
v3 = iconst.i8 1
|
||||
return v3
|
||||
}
|
||||
; run: %bricmp_ult_i64(0, 0) == 0
|
||||
; run: %bricmp_ult_i64(0, 1) == 1
|
||||
; run: %bricmp_ult_i64(1, 0) == 0
|
||||
; run: %bricmp_ult_i64(0, -1) == 1
|
||||
; run: %bricmp_ult_i64(-1, 0) == 0
|
||||
|
||||
function %bricmp_ult_i32(i32, i32) -> i8 {
|
||||
block0(v0: i32, v1: i32):
|
||||
br_icmp.i32 ult v0, v1, block2
|
||||
jump block1
|
||||
|
||||
block1:
|
||||
v2 = iconst.i8 0
|
||||
return v2
|
||||
|
||||
block2:
|
||||
v3 = iconst.i8 1
|
||||
return v3
|
||||
}
|
||||
; run: %bricmp_ult_i32(0, 0) == 0
|
||||
; run: %bricmp_ult_i32(0, 1) == 1
|
||||
; run: %bricmp_ult_i32(1, 0) == 0
|
||||
; run: %bricmp_ult_i32(0, -1) == 1
|
||||
; run: %bricmp_ult_i32(-1, 0) == 0
|
||||
|
||||
function %bricmp_ult_i16(i16, i16) -> i8 {
|
||||
block0(v0: i16, v1: i16):
|
||||
br_icmp.i16 ult v0, v1, block2
|
||||
jump block1
|
||||
|
||||
block1:
|
||||
v2 = iconst.i8 0
|
||||
return v2
|
||||
|
||||
block2:
|
||||
v3 = iconst.i8 1
|
||||
return v3
|
||||
}
|
||||
; run: %bricmp_ult_i16(0, 0) == 0
|
||||
; run: %bricmp_ult_i16(0, 1) == 1
|
||||
; run: %bricmp_ult_i16(1, 0) == 0
|
||||
; run: %bricmp_ult_i16(0, -1) == 1
|
||||
; run: %bricmp_ult_i16(-1, 0) == 0
|
||||
|
||||
function %bricmp_ult_i8(i8, i8) -> i8 {
|
||||
block0(v0: i8, v1: i8):
|
||||
br_icmp.i8 ult v0, v1, block2
|
||||
jump block1
|
||||
|
||||
block1:
|
||||
v2 = iconst.i8 0
|
||||
return v2
|
||||
|
||||
block2:
|
||||
v3 = iconst.i8 1
|
||||
return v3
|
||||
}
|
||||
; run: %bricmp_ult_i8(0, 0) == 0
|
||||
; run: %bricmp_ult_i8(0, 1) == 1
|
||||
; run: %bricmp_ult_i8(1, 0) == 0
|
||||
; run: %bricmp_ult_i8(0, -1) == 1
|
||||
; run: %bricmp_ult_i8(-1, 0) == 0
|
||||
|
||||
|
||||
function %bricmp_sle_i64(i64, i64) -> i8 {
|
||||
block0(v0: i64, v1: i64):
|
||||
br_icmp.i64 sle v0, v1, block2
|
||||
jump block1
|
||||
|
||||
block1:
|
||||
v2 = iconst.i8 0
|
||||
return v2
|
||||
|
||||
block2:
|
||||
v3 = iconst.i8 1
|
||||
return v3
|
||||
}
|
||||
; run: %bricmp_sle_i64(0, 0) == 1
|
||||
; run: %bricmp_sle_i64(0, 1) == 1
|
||||
; run: %bricmp_sle_i64(1, 0) == 0
|
||||
; run: %bricmp_sle_i64(0, -1) == 0
|
||||
; run: %bricmp_sle_i64(-1, 0) == 1
|
||||
|
||||
function %bricmp_sle_i32(i32, i32) -> i8 {
|
||||
block0(v0: i32, v1: i32):
|
||||
br_icmp.i32 sle v0, v1, block2
|
||||
jump block1
|
||||
|
||||
block1:
|
||||
v2 = iconst.i8 0
|
||||
return v2
|
||||
|
||||
block2:
|
||||
v3 = iconst.i8 1
|
||||
return v3
|
||||
}
|
||||
; run: %bricmp_sle_i32(0, 0) == 1
|
||||
; run: %bricmp_sle_i32(0, 1) == 1
|
||||
; run: %bricmp_sle_i32(1, 0) == 0
|
||||
; run: %bricmp_sle_i32(0, -1) == 0
|
||||
; run: %bricmp_sle_i32(-1, 0) == 1
|
||||
|
||||
function %bricmp_sle_i16(i16, i16) -> i8 {
|
||||
block0(v0: i16, v1: i16):
|
||||
br_icmp.i16 sle v0, v1, block2
|
||||
jump block1
|
||||
|
||||
block1:
|
||||
v2 = iconst.i8 0
|
||||
return v2
|
||||
|
||||
block2:
|
||||
v3 = iconst.i8 1
|
||||
return v3
|
||||
}
|
||||
; run: %bricmp_sle_i16(0, 0) == 1
|
||||
; run: %bricmp_sle_i16(0, 1) == 1
|
||||
; run: %bricmp_sle_i16(1, 0) == 0
|
||||
; run: %bricmp_sle_i16(0, -1) == 0
|
||||
; run: %bricmp_sle_i16(-1, 0) == 1
|
||||
|
||||
function %bricmp_sle_i8(i8, i8) -> i8 {
|
||||
block0(v0: i8, v1: i8):
|
||||
br_icmp.i8 sle v0, v1, block2
|
||||
jump block1
|
||||
|
||||
block1:
|
||||
v2 = iconst.i8 0
|
||||
return v2
|
||||
|
||||
block2:
|
||||
v3 = iconst.i8 1
|
||||
return v3
|
||||
}
|
||||
; run: %bricmp_sle_i8(0, 0) == 1
|
||||
; run: %bricmp_sle_i8(0, 1) == 1
|
||||
; run: %bricmp_sle_i8(1, 0) == 0
|
||||
; run: %bricmp_sle_i8(0, -1) == 0
|
||||
; run: %bricmp_sle_i8(-1, 0) == 1
|
||||
|
||||
|
||||
function %bricmp_ule_i64(i64, i64) -> i8 {
|
||||
block0(v0: i64, v1: i64):
|
||||
br_icmp.i64 ule v0, v1, block2
|
||||
jump block1
|
||||
|
||||
block1:
|
||||
v2 = iconst.i8 0
|
||||
return v2
|
||||
|
||||
block2:
|
||||
v3 = iconst.i8 1
|
||||
return v3
|
||||
}
|
||||
; run: %bricmp_ule_i64(0, 0) == 1
|
||||
; run: %bricmp_ule_i64(0, 1) == 1
|
||||
; run: %bricmp_ule_i64(1, 0) == 0
|
||||
; run: %bricmp_ule_i64(0, -1) == 1
|
||||
; run: %bricmp_ule_i64(-1, 0) == 0
|
||||
|
||||
function %bricmp_ule_i32(i32, i32) -> i8 {
|
||||
block0(v0: i32, v1: i32):
|
||||
br_icmp.i32 ule v0, v1, block2
|
||||
jump block1
|
||||
|
||||
block1:
|
||||
v2 = iconst.i8 0
|
||||
return v2
|
||||
|
||||
block2:
|
||||
v3 = iconst.i8 1
|
||||
return v3
|
||||
}
|
||||
; run: %bricmp_ule_i32(0, 0) == 1
|
||||
; run: %bricmp_ule_i32(0, 1) == 1
|
||||
; run: %bricmp_ule_i32(1, 0) == 0
|
||||
; run: %bricmp_ule_i32(0, -1) == 1
|
||||
; run: %bricmp_ule_i32(-1, 0) == 0
|
||||
|
||||
function %bricmp_ule_i16(i16, i16) -> i8 {
|
||||
block0(v0: i16, v1: i16):
|
||||
br_icmp.i16 ule v0, v1, block2
|
||||
jump block1
|
||||
|
||||
block1:
|
||||
v2 = iconst.i8 0
|
||||
return v2
|
||||
|
||||
block2:
|
||||
v3 = iconst.i8 1
|
||||
return v3
|
||||
}
|
||||
; run: %bricmp_ule_i16(0, 0) == 1
|
||||
; run: %bricmp_ule_i16(0, 1) == 1
|
||||
; run: %bricmp_ule_i16(1, 0) == 0
|
||||
; run: %bricmp_ule_i16(0, -1) == 1
|
||||
; run: %bricmp_ule_i16(-1, 0) == 0
|
||||
|
||||
function %bricmp_ule_i8(i8, i8) -> i8 {
|
||||
block0(v0: i8, v1: i8):
|
||||
br_icmp.i8 ule v0, v1, block2
|
||||
jump block1
|
||||
|
||||
block1:
|
||||
v2 = iconst.i8 0
|
||||
return v2
|
||||
|
||||
block2:
|
||||
v3 = iconst.i8 1
|
||||
return v3
|
||||
}
|
||||
; run: %bricmp_ule_i8(0, 0) == 1
|
||||
; run: %bricmp_ule_i8(0, 1) == 1
|
||||
; run: %bricmp_ule_i8(1, 0) == 0
|
||||
; run: %bricmp_ule_i8(0, -1) == 1
|
||||
; run: %bricmp_ule_i8(-1, 0) == 0
|
||||
|
||||
|
||||
function %bricmp_sgt_i64(i64, i64) -> i8 {
|
||||
block0(v0: i64, v1: i64):
|
||||
br_icmp.i64 sgt v0, v1, block2
|
||||
jump block1
|
||||
|
||||
block1:
|
||||
v2 = iconst.i8 0
|
||||
return v2
|
||||
|
||||
block2:
|
||||
v3 = iconst.i8 1
|
||||
return v3
|
||||
}
|
||||
; run: %bricmp_sgt_i64(0, 0) == 0
|
||||
; run: %bricmp_sgt_i64(0, 1) == 0
|
||||
; run: %bricmp_sgt_i64(1, 0) == 1
|
||||
; run: %bricmp_sgt_i64(0, -1) == 1
|
||||
; run: %bricmp_sgt_i64(-1, 0) == 0
|
||||
|
||||
function %bricmp_sgt_i32(i32, i32) -> i8 {
|
||||
block0(v0: i32, v1: i32):
|
||||
br_icmp.i32 sgt v0, v1, block2
|
||||
jump block1
|
||||
|
||||
block1:
|
||||
v2 = iconst.i8 0
|
||||
return v2
|
||||
|
||||
block2:
|
||||
v3 = iconst.i8 1
|
||||
return v3
|
||||
}
|
||||
; run: %bricmp_sgt_i32(0, 0) == 0
|
||||
; run: %bricmp_sgt_i32(0, 1) == 0
|
||||
; run: %bricmp_sgt_i32(1, 0) == 1
|
||||
; run: %bricmp_sgt_i32(0, -1) == 1
|
||||
; run: %bricmp_sgt_i32(-1, 0) == 0
|
||||
|
||||
function %bricmp_sgt_i16(i16, i16) -> i8 {
|
||||
block0(v0: i16, v1: i16):
|
||||
br_icmp.i16 sgt v0, v1, block2
|
||||
jump block1
|
||||
|
||||
block1:
|
||||
v2 = iconst.i8 0
|
||||
return v2
|
||||
|
||||
block2:
|
||||
v3 = iconst.i8 1
|
||||
return v3
|
||||
}
|
||||
; run: %bricmp_sgt_i16(0, 0) == 0
|
||||
; run: %bricmp_sgt_i16(0, 1) == 0
|
||||
; run: %bricmp_sgt_i16(1, 0) == 1
|
||||
; run: %bricmp_sgt_i16(0, -1) == 1
|
||||
; run: %bricmp_sgt_i16(-1, 0) == 0
|
||||
|
||||
function %bricmp_sgt_i8(i8, i8) -> i8 {
|
||||
block0(v0: i8, v1: i8):
|
||||
br_icmp.i8 sgt v0, v1, block2
|
||||
jump block1
|
||||
|
||||
block1:
|
||||
v2 = iconst.i8 0
|
||||
return v2
|
||||
|
||||
block2:
|
||||
v3 = iconst.i8 1
|
||||
return v3
|
||||
}
|
||||
; run: %bricmp_sgt_i8(0, 0) == 0
|
||||
; run: %bricmp_sgt_i8(0, 1) == 0
|
||||
; run: %bricmp_sgt_i8(1, 0) == 1
|
||||
; run: %bricmp_sgt_i8(0, -1) == 1
|
||||
; run: %bricmp_sgt_i8(-1, 0) == 0
|
||||
|
||||
|
||||
function %bricmp_ugt_i64(i64, i64) -> i8 {
|
||||
block0(v0: i64, v1: i64):
|
||||
br_icmp.i64 ugt v0, v1, block2
|
||||
jump block1
|
||||
|
||||
block1:
|
||||
v2 = iconst.i8 0
|
||||
return v2
|
||||
|
||||
block2:
|
||||
v3 = iconst.i8 1
|
||||
return v3
|
||||
}
|
||||
; run: %bricmp_ugt_i64(0, 0) == 0
|
||||
; run: %bricmp_ugt_i64(0, 1) == 0
|
||||
; run: %bricmp_ugt_i64(1, 0) == 1
|
||||
; run: %bricmp_ugt_i64(0, -1) == 0
|
||||
; run: %bricmp_ugt_i64(-1, 0) == 1
|
||||
|
||||
function %bricmp_ugt_i32(i32, i32) -> i8 {
|
||||
block0(v0: i32, v1: i32):
|
||||
br_icmp.i32 ugt v0, v1, block2
|
||||
jump block1
|
||||
|
||||
block1:
|
||||
v2 = iconst.i8 0
|
||||
return v2
|
||||
|
||||
block2:
|
||||
v3 = iconst.i8 1
|
||||
return v3
|
||||
}
|
||||
; run: %bricmp_ugt_i32(0, 0) == 0
|
||||
; run: %bricmp_ugt_i32(0, 1) == 0
|
||||
; run: %bricmp_ugt_i32(1, 0) == 1
|
||||
; run: %bricmp_ugt_i32(0, -1) == 0
|
||||
; run: %bricmp_ugt_i32(-1, 0) == 1
|
||||
|
||||
function %bricmp_ugt_i16(i16, i16) -> i8 {
|
||||
block0(v0: i16, v1: i16):
|
||||
br_icmp.i16 ugt v0, v1, block2
|
||||
jump block1
|
||||
|
||||
block1:
|
||||
v2 = iconst.i8 0
|
||||
return v2
|
||||
|
||||
block2:
|
||||
v3 = iconst.i8 1
|
||||
return v3
|
||||
}
|
||||
; run: %bricmp_ugt_i16(0, 0) == 0
|
||||
; run: %bricmp_ugt_i16(0, 1) == 0
|
||||
; run: %bricmp_ugt_i16(1, 0) == 1
|
||||
; run: %bricmp_ugt_i16(0, -1) == 0
|
||||
; run: %bricmp_ugt_i16(-1, 0) == 1
|
||||
|
||||
function %bricmp_ugt_i8(i8, i8) -> i8 {
|
||||
block0(v0: i8, v1: i8):
|
||||
br_icmp.i8 ugt v0, v1, block2
|
||||
jump block1
|
||||
|
||||
block1:
|
||||
v2 = iconst.i8 0
|
||||
return v2
|
||||
|
||||
block2:
|
||||
v3 = iconst.i8 1
|
||||
return v3
|
||||
}
|
||||
; run: %bricmp_ugt_i8(0, 0) == 0
|
||||
; run: %bricmp_ugt_i8(0, 1) == 0
|
||||
; run: %bricmp_ugt_i8(1, 0) == 1
|
||||
; run: %bricmp_ugt_i8(0, -1) == 0
|
||||
; run: %bricmp_ugt_i8(-1, 0) == 1
|
||||
|
||||
|
||||
function %bricmp_sge_i64(i64, i64) -> i8 {
|
||||
block0(v0: i64, v1: i64):
|
||||
br_icmp.i64 sge v0, v1, block2
|
||||
jump block1
|
||||
|
||||
block1:
|
||||
v2 = iconst.i8 0
|
||||
return v2
|
||||
|
||||
block2:
|
||||
v3 = iconst.i8 1
|
||||
return v3
|
||||
}
|
||||
; run: %bricmp_sge_i64(0, 0) == 1
|
||||
; run: %bricmp_sge_i64(0, 1) == 0
|
||||
; run: %bricmp_sge_i64(1, 0) == 1
|
||||
; run: %bricmp_sge_i64(0, -1) == 1
|
||||
; run: %bricmp_sge_i64(-1, 0) == 0
|
||||
|
||||
function %bricmp_sge_i32(i32, i32) -> i8 {
|
||||
block0(v0: i32, v1: i32):
|
||||
br_icmp.i32 sge v0, v1, block2
|
||||
jump block1
|
||||
|
||||
block1:
|
||||
v2 = iconst.i8 0
|
||||
return v2
|
||||
|
||||
block2:
|
||||
v3 = iconst.i8 1
|
||||
return v3
|
||||
}
|
||||
; run: %bricmp_sge_i32(0, 0) == 1
|
||||
; run: %bricmp_sge_i32(0, 1) == 0
|
||||
; run: %bricmp_sge_i32(1, 0) == 1
|
||||
; run: %bricmp_sge_i32(0, -1) == 1
|
||||
; run: %bricmp_sge_i32(-1, 0) == 0
|
||||
|
||||
function %bricmp_sge_i16(i16, i16) -> i8 {
|
||||
block0(v0: i16, v1: i16):
|
||||
br_icmp.i16 sge v0, v1, block2
|
||||
jump block1
|
||||
|
||||
block1:
|
||||
v2 = iconst.i8 0
|
||||
return v2
|
||||
|
||||
block2:
|
||||
v3 = iconst.i8 1
|
||||
return v3
|
||||
}
|
||||
; run: %bricmp_sge_i16(0, 0) == 1
|
||||
; run: %bricmp_sge_i16(0, 1) == 0
|
||||
; run: %bricmp_sge_i16(1, 0) == 1
|
||||
; run: %bricmp_sge_i16(0, -1) == 1
|
||||
; run: %bricmp_sge_i16(-1, 0) == 0
|
||||
|
||||
function %bricmp_sge_i8(i8, i8) -> i8 {
|
||||
block0(v0: i8, v1: i8):
|
||||
br_icmp.i8 sge v0, v1, block2
|
||||
jump block1
|
||||
|
||||
block1:
|
||||
v2 = iconst.i8 0
|
||||
return v2
|
||||
|
||||
block2:
|
||||
v3 = iconst.i8 1
|
||||
return v3
|
||||
}
|
||||
; run: %bricmp_sge_i8(0, 0) == 1
|
||||
; run: %bricmp_sge_i8(0, 1) == 0
|
||||
; run: %bricmp_sge_i8(1, 0) == 1
|
||||
; run: %bricmp_sge_i8(0, -1) == 1
|
||||
; run: %bricmp_sge_i8(-1, 0) == 0
|
||||
|
||||
|
||||
function %bricmp_uge_i64(i64, i64) -> i8 {
|
||||
block0(v0: i64, v1: i64):
|
||||
br_icmp.i64 uge v0, v1, block2
|
||||
jump block1
|
||||
|
||||
block1:
|
||||
v2 = iconst.i8 0
|
||||
return v2
|
||||
|
||||
block2:
|
||||
v3 = iconst.i8 1
|
||||
return v3
|
||||
}
|
||||
; run: %bricmp_uge_i64(0, 0) == 1
|
||||
; run: %bricmp_uge_i64(0, 1) == 0
|
||||
; run: %bricmp_uge_i64(1, 0) == 1
|
||||
; run: %bricmp_uge_i64(0, -1) == 0
|
||||
; run: %bricmp_uge_i64(-1, 0) == 1
|
||||
|
||||
function %bricmp_uge_i32(i32, i32) -> i8 {
|
||||
block0(v0: i32, v1: i32):
|
||||
br_icmp.i32 uge v0, v1, block2
|
||||
jump block1
|
||||
|
||||
block1:
|
||||
v2 = iconst.i8 0
|
||||
return v2
|
||||
|
||||
block2:
|
||||
v3 = iconst.i8 1
|
||||
return v3
|
||||
}
|
||||
; run: %bricmp_uge_i32(0, 0) == 1
|
||||
; run: %bricmp_uge_i32(0, 1) == 0
|
||||
; run: %bricmp_uge_i32(1, 0) == 1
|
||||
; run: %bricmp_uge_i32(0, -1) == 0
|
||||
; run: %bricmp_uge_i32(-1, 0) == 1
|
||||
|
||||
function %bricmp_uge_i16(i16, i16) -> i8 {
|
||||
block0(v0: i16, v1: i16):
|
||||
br_icmp.i16 uge v0, v1, block2
|
||||
jump block1
|
||||
|
||||
block1:
|
||||
v2 = iconst.i8 0
|
||||
return v2
|
||||
|
||||
block2:
|
||||
v3 = iconst.i8 1
|
||||
return v3
|
||||
}
|
||||
; run: %bricmp_uge_i16(0, 0) == 1
|
||||
; run: %bricmp_uge_i16(0, 1) == 0
|
||||
; run: %bricmp_uge_i16(1, 0) == 1
|
||||
; run: %bricmp_uge_i16(0, -1) == 0
|
||||
; run: %bricmp_uge_i16(-1, 0) == 1
|
||||
|
||||
function %bricmp_uge_i8(i8, i8) -> i8 {
|
||||
block0(v0: i8, v1: i8):
|
||||
br_icmp.i8 uge v0, v1, block2
|
||||
jump block1
|
||||
|
||||
block1:
|
||||
v2 = iconst.i8 0
|
||||
return v2
|
||||
|
||||
block2:
|
||||
v3 = iconst.i8 1
|
||||
return v3
|
||||
}
|
||||
; run: %bricmp_uge_i8(0, 0) == 1
|
||||
; run: %bricmp_uge_i8(0, 1) == 0
|
||||
; run: %bricmp_uge_i8(1, 0) == 1
|
||||
; run: %bricmp_uge_i8(0, -1) == 0
|
||||
; run: %bricmp_uge_i8(-1, 0) == 1
|
||||
@@ -1,235 +0,0 @@
|
||||
test run
|
||||
target aarch64
|
||||
target riscv64
|
||||
target s390x
|
||||
|
||||
function %i128_bricmp_eq(i128, i128) -> i8 {
|
||||
block0(v0: i128, v1: i128):
|
||||
br_icmp.i128 eq v0, v1, block2
|
||||
jump block1
|
||||
|
||||
block1:
|
||||
v2 = iconst.i8 0
|
||||
return v2
|
||||
|
||||
block2:
|
||||
v3 = iconst.i8 1
|
||||
return v3
|
||||
}
|
||||
; run: %i128_bricmp_eq(0, 0) == 1
|
||||
; run: %i128_bricmp_eq(-1, -1) == 1
|
||||
; run: %i128_bricmp_eq(-1, 0) == 0
|
||||
; run: %i128_bricmp_eq(-1, 0xFFFFFFFF_FFFFFFFF_00000000_00000000) == 0
|
||||
; run: %i128_bricmp_eq(0x00000000_00000000_FFFFFFFF_FFFFFFFF, -1) == 0
|
||||
; run: %i128_bricmp_eq(0xFFFFFFFF_FFFFFFFF_00000000_00000000, -1) == 0
|
||||
; run: %i128_bricmp_eq(0xDECAFFFF_C0FFEEEE_C0FFEEEE_DECAFFFF, 0xDECAFFFF_C0FFEEEE_C0FFEEEE_DECAFFFF) == 1
|
||||
; run: %i128_bricmp_eq(0xFFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFF, 0x00000000_00000001_00000000_00000001) == 0
|
||||
; run: %i128_bricmp_eq(0x00000000_00000001_FFFFFFFF_FFFFFFFF, 0x00000000_00000001_00000000_00000001) == 0
|
||||
|
||||
function %i128_bricmp_ne(i128, i128) -> i8 {
|
||||
block0(v0: i128,v1: i128):
|
||||
br_icmp.i128 ne v0, v1, block2
|
||||
jump block1
|
||||
|
||||
block1:
|
||||
v2 = iconst.i8 0
|
||||
return v2
|
||||
|
||||
block2:
|
||||
v3 = iconst.i8 1
|
||||
return v3
|
||||
}
|
||||
; run: %i128_bricmp_ne(0, 0) == 0
|
||||
; run: %i128_bricmp_ne(-1, -1) == 0
|
||||
; run: %i128_bricmp_ne(-1, 0) == 1
|
||||
; run: %i128_bricmp_ne(-1, 0xFFFFFFFF_FFFFFFFF_00000000_00000000) == 1
|
||||
; run: %i128_bricmp_ne(0x00000000_00000000_FFFFFFFF_FFFFFFFF, -1) == 1
|
||||
; run: %i128_bricmp_ne(0xFFFFFFFF_FFFFFFFF_00000000_00000000, -1) == 1
|
||||
; run: %i128_bricmp_ne(0xDECAFFFF_C0FFEEEE_C0FFEEEE_DECAFFFF, 0xDECAFFFF_C0FFEEEE_C0FFEEEE_DECAFFFF) == 0
|
||||
; run: %i128_bricmp_ne(0xFFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFF, 0x00000000_00000001_00000000_00000001) == 1
|
||||
; run: %i128_bricmp_ne(0x00000000_00000001_FFFFFFFF_FFFFFFFF, 0x00000000_00000001_00000000_00000001) == 1
|
||||
|
||||
|
||||
function %i128_bricmp_slt(i128, i128) -> i8 {
|
||||
block0(v0: i128,v1: i128):
|
||||
br_icmp.i128 slt v0, v1, block2
|
||||
jump block1
|
||||
|
||||
block1:
|
||||
v2 = iconst.i8 0
|
||||
return v2
|
||||
|
||||
block2:
|
||||
v3 = iconst.i8 1
|
||||
return v3
|
||||
}
|
||||
; run: %i128_bricmp_slt(0, 0) == 0
|
||||
; run: %i128_bricmp_slt(1, 1) == 0
|
||||
; run: %i128_bricmp_slt(0, 1) == 1
|
||||
; run: %i128_bricmp_slt(-1, 0) == 1
|
||||
; run: %i128_bricmp_slt(0, -1) == 0
|
||||
; run: %i128_bricmp_slt(-1, -1) == 0
|
||||
; run: %i128_bricmp_slt(0xFFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFD, 0xFFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFF) == 1
|
||||
; run: %i128_bricmp_slt(0xC0FFEEEE_C0FFEEEE_00000000_00000000, 0xDECAFFFF_DECAFFFF_00000000_00000000) == 1
|
||||
; run: %i128_bricmp_slt(0xDECAFFFF_DECAFFFF_00000000_00000000, 0xC0FFEEEE_C0FFEEEE_00000000_00000000) == 0
|
||||
|
||||
function %i128_bricmp_ult(i128, i128) -> i8 {
|
||||
block0(v0: i128,v1: i128):
|
||||
br_icmp.i128 ult v0, v1, block2
|
||||
jump block1
|
||||
|
||||
block1:
|
||||
v2 = iconst.i8 0
|
||||
return v2
|
||||
|
||||
block2:
|
||||
v3 = iconst.i8 1
|
||||
return v3
|
||||
}
|
||||
; run: %i128_bricmp_ult(0, 0) == 0
|
||||
; run: %i128_bricmp_ult(1, 1) == 0
|
||||
; run: %i128_bricmp_ult(0, 1) == 1
|
||||
; run: %i128_bricmp_ult(-1, 0) == 0
|
||||
; run: %i128_bricmp_ult(0, -1) == 1
|
||||
; run: %i128_bricmp_ult(-1, -1) == 0
|
||||
; run: %i128_bricmp_ult(0xFFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFD, 0xFFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFF) == 1
|
||||
; run: %i128_bricmp_ult(0xC0FFEEEE_C0FFEEEE_00000000_00000000, 0xDECAFFFF_DECAFFFF_00000000_00000000) == 1
|
||||
; run: %i128_bricmp_ult(0xDECAFFFF_DECAFFFF_00000000_00000000, 0xC0FFEEEE_C0FFEEEE_00000000_00000000) == 0
|
||||
|
||||
function %i128_bricmp_sle(i128, i128) -> i8 {
|
||||
block0(v0: i128,v1: i128):
|
||||
br_icmp.i128 sle v0, v1, block2
|
||||
jump block1
|
||||
|
||||
block1:
|
||||
v2 = iconst.i8 0
|
||||
return v2
|
||||
|
||||
block2:
|
||||
v3 = iconst.i8 1
|
||||
return v3
|
||||
}
|
||||
; run: %i128_bricmp_sle(0, 0) == 1
|
||||
; run: %i128_bricmp_sle(1, 1) == 1
|
||||
; run: %i128_bricmp_sle(0, 1) == 1
|
||||
; run: %i128_bricmp_sle(-1, 0) == 1
|
||||
; run: %i128_bricmp_sle(0, -1) == 0
|
||||
; run: %i128_bricmp_sle(-1, -1) == 1
|
||||
; run: %i128_bricmp_sle(0xFFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFD, 0xFFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFF) == 1
|
||||
; run: %i128_bricmp_sle(0xC0FFEEEE_C0FFEEEE_00000000_00000000, 0xDECAFFFF_DECAFFFF_00000000_00000000) == 1
|
||||
; run: %i128_bricmp_sle(0xDECAFFFF_DECAFFFF_00000000_00000000, 0xC0FFEEEE_C0FFEEEE_00000000_00000000) == 0
|
||||
|
||||
function %i128_bricmp_ule(i128, i128) -> i8 {
|
||||
block0(v0: i128,v1: i128):
|
||||
br_icmp.i128 ule v0, v1, block2
|
||||
jump block1
|
||||
|
||||
block1:
|
||||
v2 = iconst.i8 0
|
||||
return v2
|
||||
|
||||
block2:
|
||||
v3 = iconst.i8 1
|
||||
return v3
|
||||
}
|
||||
; run: %i128_bricmp_ule(0, 0) == 1
|
||||
; run: %i128_bricmp_ule(1, 1) == 1
|
||||
; run: %i128_bricmp_ule(0, 1) == 1
|
||||
; run: %i128_bricmp_ule(-1, 0) == 0
|
||||
; run: %i128_bricmp_ule(0, -1) == 1
|
||||
; run: %i128_bricmp_ule(-1, -1) == 1
|
||||
; run: %i128_bricmp_ule(0xFFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFD, 0xFFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFF) == 1
|
||||
; run: %i128_bricmp_ule(0xC0FFEEEE_C0FFEEEE_00000000_00000000, 0xDECAFFFF_DECAFFFF_00000000_00000000) == 1
|
||||
; run: %i128_bricmp_ule(0xDECAFFFF_DECAFFFF_00000000_00000000, 0xC0FFEEEE_C0FFEEEE_00000000_00000000) == 0
|
||||
|
||||
function %i128_bricmp_sgt(i128, i128) -> i8 {
|
||||
block0(v0: i128,v1: i128):
|
||||
br_icmp.i128 sgt v0, v1, block2
|
||||
jump block1
|
||||
|
||||
block1:
|
||||
v2 = iconst.i8 0
|
||||
return v2
|
||||
|
||||
block2:
|
||||
v3 = iconst.i8 1
|
||||
return v3
|
||||
}
|
||||
; run: %i128_bricmp_sgt(0, 0) == 0
|
||||
; run: %i128_bricmp_sgt(1, 1) == 0
|
||||
; run: %i128_bricmp_sgt(0, 1) == 0
|
||||
; run: %i128_bricmp_sgt(-1, 0) == 0
|
||||
; run: %i128_bricmp_sgt(0, -1) == 1
|
||||
; run: %i128_bricmp_sgt(-1, -1) == 0
|
||||
; run: %i128_bricmp_sgt(0xFFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFD, 0xFFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFF) == 0
|
||||
; run: %i128_bricmp_sgt(0xC0FFEEEE_C0FFEEEE_00000000_00000000, 0xDECAFFFF_DECAFFFF_00000000_00000000) == 0
|
||||
; run: %i128_bricmp_sgt(0xDECAFFFF_DECAFFFF_00000000_00000000, 0xC0FFEEEE_C0FFEEEE_00000000_00000000) == 1
|
||||
|
||||
function %i128_bricmp_ugt(i128, i128) -> i8 {
|
||||
block0(v0: i128,v1: i128):
|
||||
br_icmp.i128 ugt v0, v1, block2
|
||||
jump block1
|
||||
|
||||
block1:
|
||||
v2 = iconst.i8 0
|
||||
return v2
|
||||
|
||||
block2:
|
||||
v3 = iconst.i8 1
|
||||
return v3
|
||||
}
|
||||
; run: %i128_bricmp_ugt(0, 0) == 0
|
||||
; run: %i128_bricmp_ugt(1, 1) == 0
|
||||
; run: %i128_bricmp_ugt(0, 1) == 0
|
||||
; run: %i128_bricmp_ugt(-1, 0) == 1
|
||||
; run: %i128_bricmp_ugt(0, -1) == 0
|
||||
; run: %i128_bricmp_ugt(-1, -1) == 0
|
||||
; run: %i128_bricmp_ugt(0xFFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFD, 0xFFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFF) == 0
|
||||
; run: %i128_bricmp_ugt(0xC0FFEEEE_C0FFEEEE_00000000_00000000, 0xDECAFFFF_DECAFFFF_00000000_00000000) == 0
|
||||
; run: %i128_bricmp_ugt(0xDECAFFFF_DECAFFFF_00000000_00000000, 0xC0FFEEEE_C0FFEEEE_00000000_00000000) == 1
|
||||
|
||||
function %i128_bricmp_sge(i128, i128) -> i8 {
|
||||
block0(v0: i128,v1: i128):
|
||||
br_icmp.i128 sge v0, v1, block2
|
||||
jump block1
|
||||
|
||||
block1:
|
||||
v2 = iconst.i8 0
|
||||
return v2
|
||||
|
||||
block2:
|
||||
v3 = iconst.i8 1
|
||||
return v3
|
||||
}
|
||||
; run: %i128_bricmp_sge(0, 0) == 1
|
||||
; run: %i128_bricmp_sge(1, 1) == 1
|
||||
; run: %i128_bricmp_sge(0, 1) == 0
|
||||
; run: %i128_bricmp_sge(-1, 0) == 0
|
||||
; run: %i128_bricmp_sge(0, -1) == 1
|
||||
; run: %i128_bricmp_sge(-1, -1) == 1
|
||||
; run: %i128_bricmp_sge(0xFFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFD, 0xFFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFF) == 0
|
||||
; run: %i128_bricmp_sge(0xC0FFEEEE_C0FFEEEE_00000000_00000000, 0xDECAFFFF_DECAFFFF_00000000_00000000) == 0
|
||||
; run: %i128_bricmp_sge(0xDECAFFFF_DECAFFFF_00000000_00000000, 0xC0FFEEEE_C0FFEEEE_00000000_00000000) == 1
|
||||
|
||||
function %i128_bricmp_uge(i128, i128) -> i8 {
|
||||
block0(v0: i128,v1: i128):
|
||||
br_icmp.i128 uge v0, v1, block2
|
||||
jump block1
|
||||
|
||||
block1:
|
||||
v2 = iconst.i8 0
|
||||
return v2
|
||||
|
||||
block2:
|
||||
v3 = iconst.i8 1
|
||||
return v3
|
||||
}
|
||||
; run: %i128_bricmp_uge(0, 0) == 1
|
||||
; run: %i128_bricmp_uge(1, 1) == 1
|
||||
; run: %i128_bricmp_uge(0, 1) == 0
|
||||
; run: %i128_bricmp_uge(-1, 0) == 1
|
||||
; run: %i128_bricmp_uge(0, -1) == 0
|
||||
; run: %i128_bricmp_uge(-1, -1) == 1
|
||||
; run: %i128_bricmp_uge(0xFFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFD, 0xFFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFF) == 0
|
||||
; run: %i128_bricmp_uge(0xC0FFEEEE_C0FFEEEE_00000000_00000000, 0xDECAFFFF_DECAFFFF_00000000_00000000) == 0
|
||||
; run: %i128_bricmp_uge(0xDECAFFFF_DECAFFFF_00000000_00000000, 0xC0FFEEEE_C0FFEEEE_00000000_00000000) == 1
|
||||
@@ -1,316 +1,316 @@
|
||||
;; the interpreter does not support `selectif_spectre_guard`.
|
||||
;; the interpreter does not support `select_spectre_guard`.
|
||||
test run
|
||||
set enable_llvm_abi_extensions=true
|
||||
target aarch64
|
||||
target s390x
|
||||
target x86_64
|
||||
|
||||
function %selectif_spectre_guard_i8_eq(i8, i8, i8) -> i8 {
|
||||
function %select_spectre_guard_i8_eq(i8, i8, i8) -> i8 {
|
||||
block0(v0: i8, v1: i8, v2: i8):
|
||||
v3 = iconst.i8 42
|
||||
v4 = ifcmp v0, v3
|
||||
v5 = selectif_spectre_guard.i8 eq v4, v1, v2
|
||||
v4 = icmp eq v0, v3
|
||||
v5 = select_spectre_guard.i8 v4, v1, v2
|
||||
return v5
|
||||
}
|
||||
|
||||
; run: %selectif_spectre_guard_i8_eq(0, 32, 255) == 255
|
||||
; run: %selectif_spectre_guard_i8_eq(255, 32, -1) == -1
|
||||
; run: %selectif_spectre_guard_i8_eq(42, 32, 255) == 32
|
||||
; run: %select_spectre_guard_i8_eq(0, 32, 255) == 255
|
||||
; run: %select_spectre_guard_i8_eq(255, 32, -1) == -1
|
||||
; run: %select_spectre_guard_i8_eq(42, 32, 255) == 32
|
||||
|
||||
function %selectif_spectre_guard_i16_eq(i8, i16, i16) -> i16 {
|
||||
function %select_spectre_guard_i16_eq(i8, i16, i16) -> i16 {
|
||||
block0(v0: i8, v1: i16, v2: i16):
|
||||
v3 = iconst.i8 42
|
||||
v4 = ifcmp v0, v3
|
||||
v5 = selectif_spectre_guard.i16 eq v4, v1, v2
|
||||
v4 = icmp eq v0, v3
|
||||
v5 = select_spectre_guard.i16 v4, v1, v2
|
||||
return v5
|
||||
}
|
||||
|
||||
; run: %selectif_spectre_guard_i16_eq(0, 32, 65535) == 65535
|
||||
; run: %selectif_spectre_guard_i16_eq(255, 32, -1) == -1
|
||||
; run: %selectif_spectre_guard_i16_eq(42, 32, 65535) == 32
|
||||
; run: %select_spectre_guard_i16_eq(0, 32, 65535) == 65535
|
||||
; run: %select_spectre_guard_i16_eq(255, 32, -1) == -1
|
||||
; run: %select_spectre_guard_i16_eq(42, 32, 65535) == 32
|
||||
|
||||
function %selectif_spectre_guard_i32_eq(i8, i32, i32) -> i32 {
|
||||
function %select_spectre_guard_i32_eq(i8, i32, i32) -> i32 {
|
||||
block0(v0: i8, v1: i32, v2: i32):
|
||||
v3 = iconst.i8 42
|
||||
v4 = ifcmp v0, v3
|
||||
v5 = selectif_spectre_guard.i32 eq v4, v1, v2
|
||||
v4 = icmp eq v0, v3
|
||||
v5 = select_spectre_guard.i32 v4, v1, v2
|
||||
return v5
|
||||
}
|
||||
|
||||
; run: %selectif_spectre_guard_i32_eq(0, 32, 4294967295) == 4294967295
|
||||
; run: %selectif_spectre_guard_i32_eq(255, 32, -1) == -1
|
||||
; run: %selectif_spectre_guard_i32_eq(42, 32, 4294967295) == 32
|
||||
; run: %select_spectre_guard_i32_eq(0, 32, 4294967295) == 4294967295
|
||||
; run: %select_spectre_guard_i32_eq(255, 32, -1) == -1
|
||||
; run: %select_spectre_guard_i32_eq(42, 32, 4294967295) == 32
|
||||
|
||||
function %selectif_spectre_guard_i64_eq(i8, i64, i64) -> i64 {
|
||||
function %select_spectre_guard_i64_eq(i8, i64, i64) -> i64 {
|
||||
block0(v0: i8, v1: i64, v2: i64):
|
||||
v3 = iconst.i8 42
|
||||
v4 = ifcmp v0, v3
|
||||
v5 = selectif_spectre_guard.i64 eq v4, v1, v2
|
||||
v4 = icmp eq v0, v3
|
||||
v5 = select_spectre_guard.i64 v4, v1, v2
|
||||
return v5
|
||||
}
|
||||
|
||||
; run: %selectif_spectre_guard_i64_eq(0, 32, 18446744073709551615) == 18446744073709551615
|
||||
; run: %selectif_spectre_guard_i64_eq(255, 32, -1) == -1
|
||||
; run: %selectif_spectre_guard_i64_eq(42, 32, 18446744073709551615) == 32
|
||||
; run: %select_spectre_guard_i64_eq(0, 32, 18446744073709551615) == 18446744073709551615
|
||||
; run: %select_spectre_guard_i64_eq(255, 32, -1) == -1
|
||||
; run: %select_spectre_guard_i64_eq(42, 32, 18446744073709551615) == 32
|
||||
|
||||
function %selectif_spectre_guard_i128_eq(i8, i128, i128) -> i128 {
|
||||
function %select_spectre_guard_i128_eq(i8, i128, i128) -> i128 {
|
||||
block0(v0: i8, v1: i128, v2: i128):
|
||||
v3 = iconst.i8 42
|
||||
v4 = ifcmp v0, v3
|
||||
v5 = selectif_spectre_guard.i128 eq v4, v1, v2
|
||||
v4 = icmp eq v0, v3
|
||||
v5 = select_spectre_guard.i128 v4, v1, v2
|
||||
return v5
|
||||
}
|
||||
|
||||
; run: %selectif_spectre_guard_i128_eq(0, 32, 19000000000000000000) == 19000000000000000000
|
||||
; run: %selectif_spectre_guard_i128_eq(255, 32, -1) == -1
|
||||
; run: %selectif_spectre_guard_i128_eq(42, 32, 19000000000000000000) == 32
|
||||
; run: %select_spectre_guard_i128_eq(0, 32, 19000000000000000000) == 19000000000000000000
|
||||
; run: %select_spectre_guard_i128_eq(255, 32, -1) == -1
|
||||
; run: %select_spectre_guard_i128_eq(42, 32, 19000000000000000000) == 32
|
||||
|
||||
function %selectif_spectre_guard_i8_ult(i8, i8, i8) -> i8 {
|
||||
function %select_spectre_guard_i8_ult(i8, i8, i8) -> i8 {
|
||||
block0(v0: i8, v1: i8, v2: i8):
|
||||
v3 = iconst.i8 42
|
||||
v4 = ifcmp v0, v3
|
||||
v5 = selectif_spectre_guard.i8 ult v4, v1, v2
|
||||
v4 = icmp ult v0, v3
|
||||
v5 = select_spectre_guard.i8 v4, v1, v2
|
||||
return v5
|
||||
}
|
||||
|
||||
; run: %selectif_spectre_guard_i8_ult(0, 32, 255) == 32
|
||||
; run: %selectif_spectre_guard_i8_ult(255, 32, -1) == -1
|
||||
; run: %selectif_spectre_guard_i8_ult(42, 32, 255) == 255
|
||||
; run: %select_spectre_guard_i8_ult(0, 32, 255) == 32
|
||||
; run: %select_spectre_guard_i8_ult(255, 32, -1) == -1
|
||||
; run: %select_spectre_guard_i8_ult(42, 32, 255) == 255
|
||||
|
||||
function %selectif_spectre_guard_i16_ult(i8, i16, i16) -> i16 {
|
||||
function %select_spectre_guard_i16_ult(i8, i16, i16) -> i16 {
|
||||
block0(v0: i8, v1: i16, v2: i16):
|
||||
v3 = iconst.i8 42
|
||||
v4 = ifcmp v0, v3
|
||||
v5 = selectif_spectre_guard.i16 ult v4, v1, v2
|
||||
v4 = icmp ult v0, v3
|
||||
v5 = select_spectre_guard.i16 v4, v1, v2
|
||||
return v5
|
||||
}
|
||||
|
||||
; run: %selectif_spectre_guard_i16_ult(0, 32, 65535) == 32
|
||||
; run: %selectif_spectre_guard_i16_ult(255, 32, -1) == -1
|
||||
; run: %selectif_spectre_guard_i16_ult(42, 32, 65535) == 65535
|
||||
; run: %select_spectre_guard_i16_ult(0, 32, 65535) == 32
|
||||
; run: %select_spectre_guard_i16_ult(255, 32, -1) == -1
|
||||
; run: %select_spectre_guard_i16_ult(42, 32, 65535) == 65535
|
||||
|
||||
function %selectif_spectre_guard_i32_ult(i8, i32, i32) -> i32 {
|
||||
function %select_spectre_guard_i32_ult(i8, i32, i32) -> i32 {
|
||||
block0(v0: i8, v1: i32, v2: i32):
|
||||
v3 = iconst.i8 42
|
||||
v4 = ifcmp v0, v3
|
||||
v5 = selectif_spectre_guard.i32 ult v4, v1, v2
|
||||
v4 = icmp ult v0, v3
|
||||
v5 = select_spectre_guard.i32 v4, v1, v2
|
||||
return v5
|
||||
}
|
||||
|
||||
; run: %selectif_spectre_guard_i32_ult(0, 32, 4294967295) == 32
|
||||
; run: %selectif_spectre_guard_i32_ult(255, 32, -1) == -1
|
||||
; run: %selectif_spectre_guard_i32_ult(42, 32, 4294967295) == 4294967295
|
||||
; run: %select_spectre_guard_i32_ult(0, 32, 4294967295) == 32
|
||||
; run: %select_spectre_guard_i32_ult(255, 32, -1) == -1
|
||||
; run: %select_spectre_guard_i32_ult(42, 32, 4294967295) == 4294967295
|
||||
|
||||
function %selectif_spectre_guard_i64_ult(i8, i64, i64) -> i64 {
|
||||
function %select_spectre_guard_i64_ult(i8, i64, i64) -> i64 {
|
||||
block0(v0: i8, v1: i64, v2: i64):
|
||||
v3 = iconst.i8 42
|
||||
v4 = ifcmp v0, v3
|
||||
v5 = selectif_spectre_guard.i64 ult v4, v1, v2
|
||||
v4 = icmp ult v0, v3
|
||||
v5 = select_spectre_guard.i64 v4, v1, v2
|
||||
return v5
|
||||
}
|
||||
|
||||
; run: %selectif_spectre_guard_i64_ult(0, 32, 18446744073709551615) == 32
|
||||
; run: %selectif_spectre_guard_i64_ult(255, 32, -1) == -1
|
||||
; run: %selectif_spectre_guard_i64_ult(42, 32, 18446744073709551615) == 18446744073709551615
|
||||
; run: %select_spectre_guard_i64_ult(0, 32, 18446744073709551615) == 32
|
||||
; run: %select_spectre_guard_i64_ult(255, 32, -1) == -1
|
||||
; run: %select_spectre_guard_i64_ult(42, 32, 18446744073709551615) == 18446744073709551615
|
||||
|
||||
function %selectif_spectre_guard_i128_ult(i8, i128, i128) -> i128 {
|
||||
function %select_spectre_guard_i128_ult(i8, i128, i128) -> i128 {
|
||||
block0(v0: i8, v1: i128, v2: i128):
|
||||
v3 = iconst.i8 42
|
||||
v4 = ifcmp v0, v3
|
||||
v5 = selectif_spectre_guard.i128 ult v4, v1, v2
|
||||
v4 = icmp ult v0, v3
|
||||
v5 = select_spectre_guard.i128 v4, v1, v2
|
||||
return v5
|
||||
}
|
||||
|
||||
; run: %selectif_spectre_guard_i128_ult(0, 32, 19000000000000000000) == 32
|
||||
; run: %selectif_spectre_guard_i128_ult(255, 32, -1) == -1
|
||||
; run: %selectif_spectre_guard_i128_ult(42, 32, 19000000000000000000) == 19000000000000000000
|
||||
; run: %select_spectre_guard_i128_ult(0, 32, 19000000000000000000) == 32
|
||||
; run: %select_spectre_guard_i128_ult(255, 32, -1) == -1
|
||||
; run: %select_spectre_guard_i128_ult(42, 32, 19000000000000000000) == 19000000000000000000
|
||||
|
||||
function %selectif_spectre_guard_i8_ule(i8, i8, i8) -> i8 {
|
||||
function %select_spectre_guard_i8_ule(i8, i8, i8) -> i8 {
|
||||
block0(v0: i8, v1: i8, v2: i8):
|
||||
v3 = iconst.i8 42
|
||||
v4 = ifcmp v0, v3
|
||||
v5 = selectif_spectre_guard.i8 ule v4, v1, v2
|
||||
v4 = icmp ule v0, v3
|
||||
v5 = select_spectre_guard.i8 v4, v1, v2
|
||||
return v5
|
||||
}
|
||||
|
||||
; run: %selectif_spectre_guard_i8_ule(0, 32, 255) == 32
|
||||
; run: %selectif_spectre_guard_i8_ule(255, 32, -1) == -1
|
||||
; run: %selectif_spectre_guard_i8_ule(42, 32, 255) == 32
|
||||
; run: %select_spectre_guard_i8_ule(0, 32, 255) == 32
|
||||
; run: %select_spectre_guard_i8_ule(255, 32, -1) == -1
|
||||
; run: %select_spectre_guard_i8_ule(42, 32, 255) == 32
|
||||
|
||||
function %selectif_spectre_guard_i16_ule(i8, i16, i16) -> i16 {
|
||||
function %select_spectre_guard_i16_ule(i8, i16, i16) -> i16 {
|
||||
block0(v0: i8, v1: i16, v2: i16):
|
||||
v3 = iconst.i8 42
|
||||
v4 = ifcmp v0, v3
|
||||
v5 = selectif_spectre_guard.i16 ule v4, v1, v2
|
||||
v4 = icmp ule v0, v3
|
||||
v5 = select_spectre_guard.i16 v4, v1, v2
|
||||
return v5
|
||||
}
|
||||
|
||||
; run: %selectif_spectre_guard_i16_ule(0, 32, 65535) == 32
|
||||
; run: %selectif_spectre_guard_i16_ule(255, 32, -1) == -1
|
||||
; run: %selectif_spectre_guard_i16_ule(42, 32, 65535) == 32
|
||||
; run: %select_spectre_guard_i16_ule(0, 32, 65535) == 32
|
||||
; run: %select_spectre_guard_i16_ule(255, 32, -1) == -1
|
||||
; run: %select_spectre_guard_i16_ule(42, 32, 65535) == 32
|
||||
|
||||
function %selectif_spectre_guard_i32_ule(i8, i32, i32) -> i32 {
|
||||
function %select_spectre_guard_i32_ule(i8, i32, i32) -> i32 {
|
||||
block0(v0: i8, v1: i32, v2: i32):
|
||||
v3 = iconst.i8 42
|
||||
v4 = ifcmp v0, v3
|
||||
v5 = selectif_spectre_guard.i32 ule v4, v1, v2
|
||||
v4 = icmp ule v0, v3
|
||||
v5 = select_spectre_guard.i32 v4, v1, v2
|
||||
return v5
|
||||
}
|
||||
|
||||
; run: %selectif_spectre_guard_i32_ule(0, 32, 4294967295) == 32
|
||||
; run: %selectif_spectre_guard_i32_ule(255, 32, -1) == -1
|
||||
; run: %selectif_spectre_guard_i32_ule(42, 32, 4294967295) == 32
|
||||
; run: %select_spectre_guard_i32_ule(0, 32, 4294967295) == 32
|
||||
; run: %select_spectre_guard_i32_ule(255, 32, -1) == -1
|
||||
; run: %select_spectre_guard_i32_ule(42, 32, 4294967295) == 32
|
||||
|
||||
function %selectif_spectre_guard_i64_ule(i8, i64, i64) -> i64 {
|
||||
function %select_spectre_guard_i64_ule(i8, i64, i64) -> i64 {
|
||||
block0(v0: i8, v1: i64, v2: i64):
|
||||
v3 = iconst.i8 42
|
||||
v4 = ifcmp v0, v3
|
||||
v5 = selectif_spectre_guard.i64 ule v4, v1, v2
|
||||
v4 = icmp ule v0, v3
|
||||
v5 = select_spectre_guard.i64 v4, v1, v2
|
||||
return v5
|
||||
}
|
||||
|
||||
; run: %selectif_spectre_guard_i64_ule(0, 32, 18446744073709551615) == 32
|
||||
; run: %selectif_spectre_guard_i64_ule(255, 32, -1) == -1
|
||||
; run: %selectif_spectre_guard_i64_ule(42, 32, 18446744073709551615) == 32
|
||||
; run: %select_spectre_guard_i64_ule(0, 32, 18446744073709551615) == 32
|
||||
; run: %select_spectre_guard_i64_ule(255, 32, -1) == -1
|
||||
; run: %select_spectre_guard_i64_ule(42, 32, 18446744073709551615) == 32
|
||||
|
||||
function %selectif_spectre_guard_i128_ule(i8, i128, i128) -> i128 {
|
||||
function %select_spectre_guard_i128_ule(i8, i128, i128) -> i128 {
|
||||
block0(v0: i8, v1: i128, v2: i128):
|
||||
v3 = iconst.i8 42
|
||||
v4 = ifcmp v0, v3
|
||||
v5 = selectif_spectre_guard.i128 ule v4, v1, v2
|
||||
v4 = icmp ule v0, v3
|
||||
v5 = select_spectre_guard.i128 v4, v1, v2
|
||||
return v5
|
||||
}
|
||||
|
||||
; run: %selectif_spectre_guard_i128_ule(0, 32, 19000000000000000000) == 32
|
||||
; run: %selectif_spectre_guard_i128_ule(255, 32, -1) == -1
|
||||
; run: %selectif_spectre_guard_i128_ule(42, 32, 19000000000000000000) == 32
|
||||
; run: %select_spectre_guard_i128_ule(0, 32, 19000000000000000000) == 32
|
||||
; run: %select_spectre_guard_i128_ule(255, 32, -1) == -1
|
||||
; run: %select_spectre_guard_i128_ule(42, 32, 19000000000000000000) == 32
|
||||
|
||||
function %selectif_spectre_guard_i8_slt(i8, i8, i8) -> i8 {
|
||||
function %select_spectre_guard_i8_slt(i8, i8, i8) -> i8 {
|
||||
block0(v0: i8, v1: i8, v2: i8):
|
||||
v3 = iconst.i8 42
|
||||
v4 = ifcmp v0, v3
|
||||
v5 = selectif_spectre_guard.i8 slt v4, v1, v2
|
||||
v4 = icmp slt v0, v3
|
||||
v5 = select_spectre_guard.i8 v4, v1, v2
|
||||
return v5
|
||||
}
|
||||
|
||||
; run: %selectif_spectre_guard_i8_slt(0, 32, 255) == 32
|
||||
; run: %selectif_spectre_guard_i8_slt(-128, 32, -1) == 32
|
||||
; run: %selectif_spectre_guard_i8_slt(42, 32, 255) == 255
|
||||
; run: %select_spectre_guard_i8_slt(0, 32, 255) == 32
|
||||
; run: %select_spectre_guard_i8_slt(-128, 32, -1) == 32
|
||||
; run: %select_spectre_guard_i8_slt(42, 32, 255) == 255
|
||||
|
||||
function %selectif_spectre_guard_i16_slt(i8, i16, i16) -> i16 {
|
||||
function %select_spectre_guard_i16_slt(i8, i16, i16) -> i16 {
|
||||
block0(v0: i8, v1: i16, v2: i16):
|
||||
v3 = iconst.i8 42
|
||||
v4 = ifcmp v0, v3
|
||||
v5 = selectif_spectre_guard.i16 slt v4, v1, v2
|
||||
v4 = icmp slt v0, v3
|
||||
v5 = select_spectre_guard.i16 v4, v1, v2
|
||||
return v5
|
||||
}
|
||||
|
||||
; run: %selectif_spectre_guard_i16_slt(0, 32, 65535) == 32
|
||||
; run: %selectif_spectre_guard_i16_slt(-128, 32, -1) == 32
|
||||
; run: %selectif_spectre_guard_i16_slt(42, 32, 65535) == 65535
|
||||
; run: %select_spectre_guard_i16_slt(0, 32, 65535) == 32
|
||||
; run: %select_spectre_guard_i16_slt(-128, 32, -1) == 32
|
||||
; run: %select_spectre_guard_i16_slt(42, 32, 65535) == 65535
|
||||
|
||||
function %selectif_spectre_guard_i32_slt(i8, i32, i32) -> i32 {
|
||||
function %select_spectre_guard_i32_slt(i8, i32, i32) -> i32 {
|
||||
block0(v0: i8, v1: i32, v2: i32):
|
||||
v3 = iconst.i8 42
|
||||
v4 = ifcmp v0, v3
|
||||
v5 = selectif_spectre_guard.i32 slt v4, v1, v2
|
||||
v4 = icmp slt v0, v3
|
||||
v5 = select_spectre_guard.i32 v4, v1, v2
|
||||
return v5
|
||||
}
|
||||
|
||||
; run: %selectif_spectre_guard_i32_slt(0, 32, 4294967295) == 32
|
||||
; run: %selectif_spectre_guard_i32_slt(-128, 32, -1) == 32
|
||||
; run: %selectif_spectre_guard_i32_slt(42, 32, 4294967295) == 4294967295
|
||||
; run: %select_spectre_guard_i32_slt(0, 32, 4294967295) == 32
|
||||
; run: %select_spectre_guard_i32_slt(-128, 32, -1) == 32
|
||||
; run: %select_spectre_guard_i32_slt(42, 32, 4294967295) == 4294967295
|
||||
|
||||
function %selectif_spectre_guard_i64_slt(i8, i64, i64) -> i64 {
|
||||
function %select_spectre_guard_i64_slt(i8, i64, i64) -> i64 {
|
||||
block0(v0: i8, v1: i64, v2: i64):
|
||||
v3 = iconst.i8 42
|
||||
v4 = ifcmp v0, v3
|
||||
v5 = selectif_spectre_guard.i64 slt v4, v1, v2
|
||||
v4 = icmp slt v0, v3
|
||||
v5 = select_spectre_guard.i64 v4, v1, v2
|
||||
return v5
|
||||
}
|
||||
|
||||
; run: %selectif_spectre_guard_i64_slt(0, 32, 18446744073709551615) == 32
|
||||
; run: %selectif_spectre_guard_i64_slt(-128, 32, -1) == 32
|
||||
; run: %selectif_spectre_guard_i64_slt(42, 32, 18446744073709551615) == 18446744073709551615
|
||||
; run: %select_spectre_guard_i64_slt(0, 32, 18446744073709551615) == 32
|
||||
; run: %select_spectre_guard_i64_slt(-128, 32, -1) == 32
|
||||
; run: %select_spectre_guard_i64_slt(42, 32, 18446744073709551615) == 18446744073709551615
|
||||
|
||||
function %selectif_spectre_guard_i128_slt(i8, i128, i128) -> i128 {
|
||||
function %select_spectre_guard_i128_slt(i8, i128, i128) -> i128 {
|
||||
block0(v0: i8, v1: i128, v2: i128):
|
||||
v3 = iconst.i8 42
|
||||
v4 = ifcmp v0, v3
|
||||
v5 = selectif_spectre_guard.i128 slt v4, v1, v2
|
||||
v4 = icmp slt v0, v3
|
||||
v5 = select_spectre_guard.i128 v4, v1, v2
|
||||
return v5
|
||||
}
|
||||
|
||||
; run: %selectif_spectre_guard_i128_slt(0, 32, 19000000000000000000) == 32
|
||||
; run: %selectif_spectre_guard_i128_slt(-128, 32, -1) == 32
|
||||
; run: %selectif_spectre_guard_i128_slt(42, 32, 19000000000000000000) == 19000000000000000000
|
||||
; run: %select_spectre_guard_i128_slt(0, 32, 19000000000000000000) == 32
|
||||
; run: %select_spectre_guard_i128_slt(-128, 32, -1) == 32
|
||||
; run: %select_spectre_guard_i128_slt(42, 32, 19000000000000000000) == 19000000000000000000
|
||||
|
||||
function %selectif_spectre_guard_i8_sle(i8, i8, i8) -> i8 {
|
||||
function %select_spectre_guard_i8_sle(i8, i8, i8) -> i8 {
|
||||
block0(v0: i8, v1: i8, v2: i8):
|
||||
v3 = iconst.i8 42
|
||||
v4 = ifcmp v0, v3
|
||||
v5 = selectif_spectre_guard.i8 sle v4, v1, v2
|
||||
v4 = icmp sle v0, v3
|
||||
v5 = select_spectre_guard.i8 v4, v1, v2
|
||||
return v5
|
||||
}
|
||||
|
||||
; run: %selectif_spectre_guard_i8_sle(0, 32, 127) == 32
|
||||
; run: %selectif_spectre_guard_i8_sle(-128, 32, -1) == 32
|
||||
; run: %selectif_spectre_guard_i8_sle(127, 32, -1) == -1
|
||||
; run: %selectif_spectre_guard_i8_sle(127, 32, 127) == 127
|
||||
; run: %selectif_spectre_guard_i8_sle(42, 32, 127) == 32
|
||||
; run: %select_spectre_guard_i8_sle(0, 32, 127) == 32
|
||||
; run: %select_spectre_guard_i8_sle(-128, 32, -1) == 32
|
||||
; run: %select_spectre_guard_i8_sle(127, 32, -1) == -1
|
||||
; run: %select_spectre_guard_i8_sle(127, 32, 127) == 127
|
||||
; run: %select_spectre_guard_i8_sle(42, 32, 127) == 32
|
||||
|
||||
function %selectif_spectre_guard_i16_sle(i8, i16, i16) -> i16 {
|
||||
function %select_spectre_guard_i16_sle(i8, i16, i16) -> i16 {
|
||||
block0(v0: i8, v1: i16, v2: i16):
|
||||
v3 = iconst.i8 42
|
||||
v4 = ifcmp v0, v3
|
||||
v5 = selectif_spectre_guard.i16 sle v4, v1, v2
|
||||
v4 = icmp sle v0, v3
|
||||
v5 = select_spectre_guard.i16 v4, v1, v2
|
||||
return v5
|
||||
}
|
||||
|
||||
; run: %selectif_spectre_guard_i16_sle(0, 32, 65535) == 32
|
||||
; run: %selectif_spectre_guard_i16_sle(-128, 32, -1) == 32
|
||||
; run: %selectif_spectre_guard_i16_sle(127, 32, -1) == -1
|
||||
; run: %selectif_spectre_guard_i16_sle(127, 32, 65535) == 65535
|
||||
; run: %selectif_spectre_guard_i16_sle(42, 32, 65535) == 32
|
||||
; run: %select_spectre_guard_i16_sle(0, 32, 65535) == 32
|
||||
; run: %select_spectre_guard_i16_sle(-128, 32, -1) == 32
|
||||
; run: %select_spectre_guard_i16_sle(127, 32, -1) == -1
|
||||
; run: %select_spectre_guard_i16_sle(127, 32, 65535) == 65535
|
||||
; run: %select_spectre_guard_i16_sle(42, 32, 65535) == 32
|
||||
|
||||
function %selectif_spectre_guard_i32_sle(i8, i32, i32) -> i32 {
|
||||
function %select_spectre_guard_i32_sle(i8, i32, i32) -> i32 {
|
||||
block0(v0: i8, v1: i32, v2: i32):
|
||||
v3 = iconst.i8 42
|
||||
v4 = ifcmp v0, v3
|
||||
v5 = selectif_spectre_guard.i32 sle v4, v1, v2
|
||||
v4 = icmp sle v0, v3
|
||||
v5 = select_spectre_guard.i32 v4, v1, v2
|
||||
return v5
|
||||
}
|
||||
|
||||
; run: %selectif_spectre_guard_i32_sle(0, 32, 4294967295) == 32
|
||||
; run: %selectif_spectre_guard_i32_sle(-128, 32, -1) == 32
|
||||
; run: %selectif_spectre_guard_i32_sle(127, 32, -1) == -1
|
||||
; run: %selectif_spectre_guard_i32_sle(127, 32, 4294967295) == 4294967295
|
||||
; run: %selectif_spectre_guard_i32_sle(42, 32, 4294967295) == 32
|
||||
; run: %select_spectre_guard_i32_sle(0, 32, 4294967295) == 32
|
||||
; run: %select_spectre_guard_i32_sle(-128, 32, -1) == 32
|
||||
; run: %select_spectre_guard_i32_sle(127, 32, -1) == -1
|
||||
; run: %select_spectre_guard_i32_sle(127, 32, 4294967295) == 4294967295
|
||||
; run: %select_spectre_guard_i32_sle(42, 32, 4294967295) == 32
|
||||
|
||||
function %selectif_spectre_guard_i64_sle(i8, i64, i64) -> i64 {
|
||||
function %select_spectre_guard_i64_sle(i8, i64, i64) -> i64 {
|
||||
block0(v0: i8, v1: i64, v2: i64):
|
||||
v3 = iconst.i8 42
|
||||
v4 = ifcmp v0, v3
|
||||
v5 = selectif_spectre_guard.i64 sle v4, v1, v2
|
||||
v4 = icmp sle v0, v3
|
||||
v5 = select_spectre_guard.i64 v4, v1, v2
|
||||
return v5
|
||||
}
|
||||
|
||||
; run: %selectif_spectre_guard_i64_sle(0, 32, 18446744073709551615) == 32
|
||||
; run: %selectif_spectre_guard_i64_sle(-128, 32, -1) == 32
|
||||
; run: %selectif_spectre_guard_i64_sle(127, 32, -1) == -1
|
||||
; run: %selectif_spectre_guard_i64_sle(127, 32, 18446744073709551615) == 18446744073709551615
|
||||
; run: %selectif_spectre_guard_i64_sle(42, 32, 18446744073709551615) == 32
|
||||
; run: %select_spectre_guard_i64_sle(0, 32, 18446744073709551615) == 32
|
||||
; run: %select_spectre_guard_i64_sle(-128, 32, -1) == 32
|
||||
; run: %select_spectre_guard_i64_sle(127, 32, -1) == -1
|
||||
; run: %select_spectre_guard_i64_sle(127, 32, 18446744073709551615) == 18446744073709551615
|
||||
; run: %select_spectre_guard_i64_sle(42, 32, 18446744073709551615) == 32
|
||||
|
||||
function %selectif_spectre_guard_i128_sle(i8, i128, i128) -> i128 {
|
||||
function %select_spectre_guard_i128_sle(i8, i128, i128) -> i128 {
|
||||
block0(v0: i8, v1: i128, v2: i128):
|
||||
v3 = iconst.i8 42
|
||||
v4 = ifcmp v0, v3
|
||||
v5 = selectif_spectre_guard.i128 sle v4, v1, v2
|
||||
v4 = icmp sle v0, v3
|
||||
v5 = select_spectre_guard.i128 v4, v1, v2
|
||||
return v5
|
||||
}
|
||||
|
||||
; run: %selectif_spectre_guard_i128_sle(0, 32, 19000000000000000000) == 32
|
||||
; run: %selectif_spectre_guard_i128_sle(-128, 32, -1) == 32
|
||||
; run: %selectif_spectre_guard_i128_sle(127, 32, -1) == -1
|
||||
; run: %selectif_spectre_guard_i128_sle(127, 32, 19000000000000000000) == 19000000000000000000
|
||||
; run: %selectif_spectre_guard_i128_sle(42, 32, 19000000000000000000) == 32
|
||||
; run: %select_spectre_guard_i128_sle(0, 32, 19000000000000000000) == 32
|
||||
; run: %select_spectre_guard_i128_sle(-128, 32, -1) == 32
|
||||
; run: %select_spectre_guard_i128_sle(127, 32, -1) == -1
|
||||
; run: %select_spectre_guard_i128_sle(127, 32, 19000000000000000000) == 19000000000000000000
|
||||
; run: %select_spectre_guard_i128_sle(42, 32, 19000000000000000000) == 32
|
||||
|
||||
@@ -1,316 +0,0 @@
|
||||
test interpret
|
||||
test run
|
||||
set enable_llvm_abi_extensions=true
|
||||
target aarch64
|
||||
target x86_64
|
||||
; `selectif` panics on s390x.
|
||||
|
||||
function %selectif_i8_eq(i8, i8, i8) -> i8 {
|
||||
block0(v0: i8, v1: i8, v2: i8):
|
||||
v3 = iconst.i8 42
|
||||
v4 = ifcmp v0, v3
|
||||
v5 = selectif.i8 eq v4, v1, v2
|
||||
return v5
|
||||
}
|
||||
|
||||
; run: %selectif_i8_eq(0, 32, 255) == 255
|
||||
; run: %selectif_i8_eq(255, 32, -1) == -1
|
||||
; run: %selectif_i8_eq(42, 32, 255) == 32
|
||||
|
||||
function %selectif_i16_eq(i8, i16, i16) -> i16 {
|
||||
block0(v0: i8, v1: i16, v2: i16):
|
||||
v3 = iconst.i8 42
|
||||
v4 = ifcmp v0, v3
|
||||
v5 = selectif.i16 eq v4, v1, v2
|
||||
return v5
|
||||
}
|
||||
|
||||
; run: %selectif_i16_eq(0, 32, 65535) == 65535
|
||||
; run: %selectif_i16_eq(255, 32, -1) == -1
|
||||
; run: %selectif_i16_eq(42, 32, 65535) == 32
|
||||
|
||||
function %selectif_i32_eq(i8, i32, i32) -> i32 {
|
||||
block0(v0: i8, v1: i32, v2: i32):
|
||||
v3 = iconst.i8 42
|
||||
v4 = ifcmp v0, v3
|
||||
v5 = selectif.i32 eq v4, v1, v2
|
||||
return v5
|
||||
}
|
||||
|
||||
; run: %selectif_i32_eq(0, 32, 4294967295) == 4294967295
|
||||
; run: %selectif_i32_eq(255, 32, -1) == -1
|
||||
; run: %selectif_i32_eq(42, 32, 4294967295) == 32
|
||||
|
||||
function %selectif_i64_eq(i8, i64, i64) -> i64 {
|
||||
block0(v0: i8, v1: i64, v2: i64):
|
||||
v3 = iconst.i8 42
|
||||
v4 = ifcmp v0, v3
|
||||
v5 = selectif.i64 eq v4, v1, v2
|
||||
return v5
|
||||
}
|
||||
|
||||
; run: %selectif_i64_eq(0, 32, 18446744073709551615) == 18446744073709551615
|
||||
; run: %selectif_i64_eq(255, 32, -1) == -1
|
||||
; run: %selectif_i64_eq(42, 32, 18446744073709551615) == 32
|
||||
|
||||
function %selectif_i128_eq(i8, i128, i128) -> i128 {
|
||||
block0(v0: i8, v1: i128, v2: i128):
|
||||
v3 = iconst.i8 42
|
||||
v4 = ifcmp v0, v3
|
||||
v5 = selectif.i128 eq v4, v1, v2
|
||||
return v5
|
||||
}
|
||||
|
||||
; run: %selectif_i128_eq(0, 32, 19000000000000000000) == 19000000000000000000
|
||||
; run: %selectif_i128_eq(255, 32, -1) == -1
|
||||
; run: %selectif_i128_eq(42, 32, 19000000000000000000) == 32
|
||||
|
||||
function %selectif_i8_ult(i8, i8, i8) -> i8 {
|
||||
block0(v0: i8, v1: i8, v2: i8):
|
||||
v3 = iconst.i8 42
|
||||
v4 = ifcmp v0, v3
|
||||
v5 = selectif.i8 ult v4, v1, v2
|
||||
return v5
|
||||
}
|
||||
|
||||
; run: %selectif_i8_ult(0, 32, 255) == 32
|
||||
; run: %selectif_i8_ult(255, 32, -1) == -1
|
||||
; run: %selectif_i8_ult(42, 32, 255) == 255
|
||||
|
||||
function %selectif_i16_ult(i8, i16, i16) -> i16 {
|
||||
block0(v0: i8, v1: i16, v2: i16):
|
||||
v3 = iconst.i8 42
|
||||
v4 = ifcmp v0, v3
|
||||
v5 = selectif.i16 ult v4, v1, v2
|
||||
return v5
|
||||
}
|
||||
|
||||
; run: %selectif_i16_ult(0, 32, 65535) == 32
|
||||
; run: %selectif_i16_ult(255, 32, -1) == -1
|
||||
; run: %selectif_i16_ult(42, 32, 65535) == 65535
|
||||
|
||||
function %selectif_i32_ult(i8, i32, i32) -> i32 {
|
||||
block0(v0: i8, v1: i32, v2: i32):
|
||||
v3 = iconst.i8 42
|
||||
v4 = ifcmp v0, v3
|
||||
v5 = selectif.i32 ult v4, v1, v2
|
||||
return v5
|
||||
}
|
||||
|
||||
; run: %selectif_i32_ult(0, 32, 4294967295) == 32
|
||||
; run: %selectif_i32_ult(255, 32, -1) == -1
|
||||
; run: %selectif_i32_ult(42, 32, 4294967295) == 4294967295
|
||||
|
||||
function %selectif_i64_ult(i8, i64, i64) -> i64 {
|
||||
block0(v0: i8, v1: i64, v2: i64):
|
||||
v3 = iconst.i8 42
|
||||
v4 = ifcmp v0, v3
|
||||
v5 = selectif.i64 ult v4, v1, v2
|
||||
return v5
|
||||
}
|
||||
|
||||
; run: %selectif_i64_ult(0, 32, 18446744073709551615) == 32
|
||||
; run: %selectif_i64_ult(255, 32, -1) == -1
|
||||
; run: %selectif_i64_ult(42, 32, 18446744073709551615) == 18446744073709551615
|
||||
|
||||
function %selectif_i128_ult(i8, i128, i128) -> i128 {
|
||||
block0(v0: i8, v1: i128, v2: i128):
|
||||
v3 = iconst.i8 42
|
||||
v4 = ifcmp v0, v3
|
||||
v5 = selectif.i128 ult v4, v1, v2
|
||||
return v5
|
||||
}
|
||||
|
||||
; run: %selectif_i128_ult(0, 32, 19000000000000000000) == 32
|
||||
; run: %selectif_i128_ult(255, 32, -1) == -1
|
||||
; run: %selectif_i128_ult(42, 32, 19000000000000000000) == 19000000000000000000
|
||||
|
||||
function %selectif_i8_ule(i8, i8, i8) -> i8 {
|
||||
block0(v0: i8, v1: i8, v2: i8):
|
||||
v3 = iconst.i8 42
|
||||
v4 = ifcmp v0, v3
|
||||
v5 = selectif.i8 ule v4, v1, v2
|
||||
return v5
|
||||
}
|
||||
|
||||
; run: %selectif_i8_ule(0, 32, 255) == 32
|
||||
; run: %selectif_i8_ule(255, 32, -1) == -1
|
||||
; run: %selectif_i8_ule(42, 32, 255) == 32
|
||||
|
||||
function %selectif_i16_ule(i8, i16, i16) -> i16 {
|
||||
block0(v0: i8, v1: i16, v2: i16):
|
||||
v3 = iconst.i8 42
|
||||
v4 = ifcmp v0, v3
|
||||
v5 = selectif.i16 ule v4, v1, v2
|
||||
return v5
|
||||
}
|
||||
|
||||
; run: %selectif_i16_ule(0, 32, 65535) == 32
|
||||
; run: %selectif_i16_ule(255, 32, -1) == -1
|
||||
; run: %selectif_i16_ule(42, 32, 65535) == 32
|
||||
|
||||
function %selectif_i32_ule(i8, i32, i32) -> i32 {
|
||||
block0(v0: i8, v1: i32, v2: i32):
|
||||
v3 = iconst.i8 42
|
||||
v4 = ifcmp v0, v3
|
||||
v5 = selectif.i32 ule v4, v1, v2
|
||||
return v5
|
||||
}
|
||||
|
||||
; run: %selectif_i32_ule(0, 32, 4294967295) == 32
|
||||
; run: %selectif_i32_ule(255, 32, -1) == -1
|
||||
; run: %selectif_i32_ule(42, 32, 4294967295) == 32
|
||||
|
||||
function %selectif_i64_ule(i8, i64, i64) -> i64 {
|
||||
block0(v0: i8, v1: i64, v2: i64):
|
||||
v3 = iconst.i8 42
|
||||
v4 = ifcmp v0, v3
|
||||
v5 = selectif.i64 ule v4, v1, v2
|
||||
return v5
|
||||
}
|
||||
|
||||
; run: %selectif_i64_ule(0, 32, 18446744073709551615) == 32
|
||||
; run: %selectif_i64_ule(255, 32, -1) == -1
|
||||
; run: %selectif_i64_ule(42, 32, 18446744073709551615) == 32
|
||||
|
||||
function %selectif_i128_ule(i8, i128, i128) -> i128 {
|
||||
block0(v0: i8, v1: i128, v2: i128):
|
||||
v3 = iconst.i8 42
|
||||
v4 = ifcmp v0, v3
|
||||
v5 = selectif.i128 ule v4, v1, v2
|
||||
return v5
|
||||
}
|
||||
|
||||
; run: %selectif_i128_ule(0, 32, 19000000000000000000) == 32
|
||||
; run: %selectif_i128_ule(255, 32, -1) == -1
|
||||
; run: %selectif_i128_ule(42, 32, 19000000000000000000) == 32
|
||||
|
||||
function %selectif_i8_slt(i8, i8, i8) -> i8 {
|
||||
block0(v0: i8, v1: i8, v2: i8):
|
||||
v3 = iconst.i8 42
|
||||
v4 = ifcmp v0, v3
|
||||
v5 = selectif.i8 slt v4, v1, v2
|
||||
return v5
|
||||
}
|
||||
|
||||
; run: %selectif_i8_slt(0, 32, 255) == 32
|
||||
; run: %selectif_i8_slt(-128, 32, -1) == 32
|
||||
; run: %selectif_i8_slt(42, 32, 255) == 255
|
||||
|
||||
function %selectif_i16_slt(i8, i16, i16) -> i16 {
|
||||
block0(v0: i8, v1: i16, v2: i16):
|
||||
v3 = iconst.i8 42
|
||||
v4 = ifcmp v0, v3
|
||||
v5 = selectif.i16 slt v4, v1, v2
|
||||
return v5
|
||||
}
|
||||
|
||||
; run: %selectif_i16_slt(0, 32, 65535) == 32
|
||||
; run: %selectif_i16_slt(-128, 32, -1) == 32
|
||||
; run: %selectif_i16_slt(42, 32, 65535) == 65535
|
||||
|
||||
function %selectif_i32_slt(i8, i32, i32) -> i32 {
|
||||
block0(v0: i8, v1: i32, v2: i32):
|
||||
v3 = iconst.i8 42
|
||||
v4 = ifcmp v0, v3
|
||||
v5 = selectif.i32 slt v4, v1, v2
|
||||
return v5
|
||||
}
|
||||
|
||||
; run: %selectif_i32_slt(0, 32, 4294967295) == 32
|
||||
; run: %selectif_i32_slt(-128, 32, -1) == 32
|
||||
; run: %selectif_i32_slt(42, 32, 4294967295) == 4294967295
|
||||
|
||||
function %selectif_i64_slt(i8, i64, i64) -> i64 {
|
||||
block0(v0: i8, v1: i64, v2: i64):
|
||||
v3 = iconst.i8 42
|
||||
v4 = ifcmp v0, v3
|
||||
v5 = selectif.i64 slt v4, v1, v2
|
||||
return v5
|
||||
}
|
||||
|
||||
; run: %selectif_i64_slt(0, 32, 18446744073709551615) == 32
|
||||
; run: %selectif_i64_slt(-128, 32, -1) == 32
|
||||
; run: %selectif_i64_slt(42, 32, 18446744073709551615) == 18446744073709551615
|
||||
|
||||
function %selectif_i128_slt(i8, i128, i128) -> i128 {
|
||||
block0(v0: i8, v1: i128, v2: i128):
|
||||
v3 = iconst.i8 42
|
||||
v4 = ifcmp v0, v3
|
||||
v5 = selectif.i128 slt v4, v1, v2
|
||||
return v5
|
||||
}
|
||||
|
||||
; run: %selectif_i128_slt(0, 32, 19000000000000000000) == 32
|
||||
; run: %selectif_i128_slt(-128, 32, -1) == 32
|
||||
; run: %selectif_i128_slt(42, 32, 19000000000000000000) == 19000000000000000000
|
||||
|
||||
function %selectif_i8_sle(i8, i8, i8) -> i8 {
|
||||
block0(v0: i8, v1: i8, v2: i8):
|
||||
v3 = iconst.i8 42
|
||||
v4 = ifcmp v0, v3
|
||||
v5 = selectif.i8 sle v4, v1, v2
|
||||
return v5
|
||||
}
|
||||
|
||||
; run: %selectif_i8_sle(0, 32, 127) == 32
|
||||
; run: %selectif_i8_sle(-128, 32, -1) == 32
|
||||
; run: %selectif_i8_sle(127, 32, -1) == -1
|
||||
; run: %selectif_i8_sle(127, 32, 127) == 127
|
||||
; run: %selectif_i8_sle(42, 32, 127) == 32
|
||||
|
||||
function %selectif_i16_sle(i8, i16, i16) -> i16 {
|
||||
block0(v0: i8, v1: i16, v2: i16):
|
||||
v3 = iconst.i8 42
|
||||
v4 = ifcmp v0, v3
|
||||
v5 = selectif.i16 sle v4, v1, v2
|
||||
return v5
|
||||
}
|
||||
|
||||
; run: %selectif_i16_sle(0, 32, 65535) == 32
|
||||
; run: %selectif_i16_sle(-128, 32, -1) == 32
|
||||
; run: %selectif_i16_sle(127, 32, -1) == -1
|
||||
; run: %selectif_i16_sle(127, 32, 65535) == 65535
|
||||
; run: %selectif_i16_sle(42, 32, 65535) == 32
|
||||
|
||||
function %selectif_i32_sle(i8, i32, i32) -> i32 {
|
||||
block0(v0: i8, v1: i32, v2: i32):
|
||||
v3 = iconst.i8 42
|
||||
v4 = ifcmp v0, v3
|
||||
v5 = selectif.i32 sle v4, v1, v2
|
||||
return v5
|
||||
}
|
||||
|
||||
; run: %selectif_i32_sle(0, 32, 4294967295) == 32
|
||||
; run: %selectif_i32_sle(-128, 32, -1) == 32
|
||||
; run: %selectif_i32_sle(127, 32, -1) == -1
|
||||
; run: %selectif_i32_sle(127, 32, 4294967295) == 4294967295
|
||||
; run: %selectif_i32_sle(42, 32, 4294967295) == 32
|
||||
|
||||
function %selectif_i64_sle(i8, i64, i64) -> i64 {
|
||||
block0(v0: i8, v1: i64, v2: i64):
|
||||
v3 = iconst.i8 42
|
||||
v4 = ifcmp v0, v3
|
||||
v5 = selectif.i64 sle v4, v1, v2
|
||||
return v5
|
||||
}
|
||||
|
||||
; run: %selectif_i64_sle(0, 32, 18446744073709551615) == 32
|
||||
; run: %selectif_i64_sle(-128, 32, -1) == 32
|
||||
; run: %selectif_i64_sle(127, 32, -1) == -1
|
||||
; run: %selectif_i64_sle(127, 32, 18446744073709551615) == 18446744073709551615
|
||||
; run: %selectif_i64_sle(42, 32, 18446744073709551615) == 32
|
||||
|
||||
function %selectif_i128_sle(i8, i128, i128) -> i128 {
|
||||
block0(v0: i8, v1: i128, v2: i128):
|
||||
v3 = iconst.i8 42
|
||||
v4 = ifcmp v0, v3
|
||||
v5 = selectif.i128 sle v4, v1, v2
|
||||
return v5
|
||||
}
|
||||
|
||||
; run: %selectif_i128_sle(0, 32, 19000000000000000000) == 32
|
||||
; run: %selectif_i128_sle(-128, 32, -1) == 32
|
||||
; run: %selectif_i128_sle(127, 32, -1) == -1
|
||||
; run: %selectif_i128_sle(127, 32, 19000000000000000000) == 19000000000000000000
|
||||
; run: %selectif_i128_sle(42, 32, 19000000000000000000) == 32
|
||||
@@ -1,110 +0,0 @@
|
||||
test interpret
|
||||
test run
|
||||
target aarch64
|
||||
; `true{if,ff}` not implemented on x86_64, and panics on s390x.
|
||||
|
||||
function %trueif_i8_eq(i8, i8) -> i8 {
|
||||
block0(v0: i8, v1: i8):
|
||||
v2 = ifcmp v0, v1
|
||||
v3 = trueif eq v2
|
||||
return v3
|
||||
}
|
||||
|
||||
; run: %trueif_i8_eq(42, 42) == 1
|
||||
; run: %trueif_i8_eq(-1, 255) == 1
|
||||
; run: %trueif_i8_eq(255, 0) == 0
|
||||
; run: %trueif_i8_eq(32, 64) == 0
|
||||
|
||||
function %trueif_i16_eq(i16, i16) -> i8 {
|
||||
block0(v0: i16, v1: i16):
|
||||
v2 = ifcmp v0, v1
|
||||
v3 = trueif eq v2
|
||||
return v3
|
||||
}
|
||||
|
||||
; run: %trueif_i16_eq(42, 42) == 1
|
||||
; run: %trueif_i16_eq(-1, 65535) == 1
|
||||
; run: %trueif_i16_eq(65535, 0) == 0
|
||||
; run: %trueif_i16_eq(32, 64) == 0
|
||||
|
||||
function %trueif_i32_eq(i32, i32) -> i8 {
|
||||
block0(v0: i32, v1: i32):
|
||||
v2 = ifcmp v0, v1
|
||||
v3 = trueif eq v2
|
||||
return v3
|
||||
}
|
||||
|
||||
; run: %trueif_i32_eq(42, 42) == 1
|
||||
; run: %trueif_i32_eq(-1, 4294967295) == 1
|
||||
; run: %trueif_i32_eq(4294967295, 0) == 0
|
||||
; run: %trueif_i32_eq(32, 64) == 0
|
||||
|
||||
function %trueif_i64_eq(i64, i64) -> i8 {
|
||||
block0(v0: i64, v1: i64):
|
||||
v2 = ifcmp v0, v1
|
||||
v3 = trueif eq v2
|
||||
return v3
|
||||
}
|
||||
|
||||
; run: %trueif_i64_eq(42, 42) == 1
|
||||
; run: %trueif_i64_eq(-1, 18446744073709551615) == 1
|
||||
; run: %trueif_i64_eq(18446744073709551615, 0) == 0
|
||||
; run: %trueif_i64_eq(32, 64) == 0
|
||||
|
||||
function %trueif_i128_eq(i128, i128) -> i8 {
|
||||
block0(v0: i128, v1: i128):
|
||||
v2 = ifcmp v0, v1
|
||||
v3 = trueif eq v2
|
||||
return v3
|
||||
}
|
||||
|
||||
; run: %trueif_i128_eq(42, 42) == 1
|
||||
; run: %trueif_i128_eq(-1, 18446744073709551615) == 0
|
||||
; run: %trueif_i128_eq(19000000000000000000, 0) == 0
|
||||
; run: %trueif_i128_eq(32, 64) == 0
|
||||
|
||||
function %trueff_f32_eq(f32, f32) -> i8 {
|
||||
block0(v0: f32, v1: f32):
|
||||
v2 = ffcmp v0, v1
|
||||
v3 = trueff eq v2
|
||||
return v3
|
||||
}
|
||||
|
||||
; run: %trueff_f32_eq(0x42.0, 0x42.0) == 1
|
||||
; run: %trueff_f32_eq(-0x1.0, -0x1.0) == 1
|
||||
; run: %trueff_f32_eq(0x1.0, 0x0.0) == 0
|
||||
|
||||
function %trueff_f64_eq(f64, f64) -> i8 {
|
||||
block0(v0: f64, v1: f64):
|
||||
v2 = ffcmp v0, v1
|
||||
v3 = trueff eq v2
|
||||
return v3
|
||||
}
|
||||
|
||||
; run: %trueff_f64_eq(0x42.0, 0x42.0) == 1
|
||||
; run: %trueff_f64_eq(-0x1.0, -0x1.0) == 1
|
||||
; run: %trueff_f64_eq(0x1.0, 0x0.0) == 0
|
||||
|
||||
function %trueff_f32_ne(f32, f32) -> i8 {
|
||||
block0(v0: f32, v1: f32):
|
||||
v2 = ffcmp v0, v1
|
||||
v3 = trueff ne v2
|
||||
return v3
|
||||
}
|
||||
|
||||
; run: %trueff_f32_ne(0x42.0, 0x42.0) == 0
|
||||
; run: %trueff_f32_ne(-0x1.0, -0x1.0) == 0
|
||||
; run: %trueff_f32_ne(0x1.0, 0x0.0) == 1
|
||||
; run: %trueff_f32_ne(NaN, NaN) == 1
|
||||
|
||||
function %trueff_f64_ne(f64, f64) -> i8 {
|
||||
block0(v0: f64, v1: f64):
|
||||
v2 = ffcmp v0, v1
|
||||
v3 = trueff ne v2
|
||||
return v3
|
||||
}
|
||||
|
||||
; run: %trueff_f64_ne(0x42.0, 0x42.0) == 0
|
||||
; run: %trueff_f64_ne(-0x1.0, -0x1.0) == 0
|
||||
; run: %trueff_f64_ne(0x1.0, 0x0.0) == 1
|
||||
; run: %trueff_f64_ne(NaN, NaN) == 1
|
||||
@@ -18,14 +18,10 @@ function %cpu_flags() -> i8 {
|
||||
block0:
|
||||
v0 = iconst.i32 7
|
||||
v1 = iconst.i32 8
|
||||
v2 = ifcmp v0, v1
|
||||
v3 = trueif eq v2
|
||||
v4 = ifcmp v0, v1
|
||||
v5 = trueif eq v4
|
||||
v6 = bor v3, v5
|
||||
; check: v2 = ifcmp v0, v1
|
||||
; check: v3 = trueif eq v2
|
||||
; check: v4 = ifcmp v0, v1
|
||||
; check: v5 = trueif eq v4
|
||||
return v6
|
||||
v2 = icmp eq v0, v1
|
||||
v3 = icmp eq v0, v1
|
||||
v4 = bor v2, v3
|
||||
; check: v2 = icmp eq v0, v1
|
||||
; check: v4 = bor v2, v2
|
||||
return v4
|
||||
}
|
||||
|
||||
@@ -55,28 +55,3 @@ block2:
|
||||
; nextln: v4 = iconst.i32 2
|
||||
; nextln: return v4
|
||||
; nextln: }
|
||||
|
||||
function %br_icmp_inversion(i32, i32) -> i32 {
|
||||
block0(v0: i32, v1: i32):
|
||||
br_icmp ugt v0, v1, block1
|
||||
jump block2
|
||||
block1:
|
||||
v2 = iconst.i32 1
|
||||
return v2
|
||||
block2:
|
||||
v3 = iconst.i32 2
|
||||
return v3
|
||||
}
|
||||
; sameln: function %br_icmp_inversion
|
||||
; nextln: block0(v0: i32, v1: i32):
|
||||
; nextln: br_icmp ule v0, v1, block2
|
||||
; nextln: jump block1
|
||||
; nextln:
|
||||
; nextln: block1:
|
||||
; nextln: v2 = iconst.i32 1
|
||||
; nextln: return v2
|
||||
; nextln:
|
||||
; nextln: block2:
|
||||
; nextln: v3 = iconst.i32 2
|
||||
; nextln: return v3
|
||||
; nextln: }
|
||||
|
||||
@@ -812,7 +812,6 @@ enum BlockTerminator {
|
||||
Return,
|
||||
Jump(Block),
|
||||
Br(Block, Block),
|
||||
BrIcmp(Block, Block),
|
||||
BrTable(Block, Vec<Block>),
|
||||
Switch(Type, Block, HashMap<u128, Block>),
|
||||
}
|
||||
@@ -822,7 +821,6 @@ enum BlockTerminatorKind {
|
||||
Return,
|
||||
Jump,
|
||||
Br,
|
||||
BrIcmp,
|
||||
BrTable,
|
||||
Switch,
|
||||
}
|
||||
@@ -1101,19 +1099,6 @@ where
|
||||
}
|
||||
builder.ins().jump(right, &right_args[..]);
|
||||
}
|
||||
BlockTerminator::BrIcmp(left, right) => {
|
||||
let cc = *self.u.choose(IntCC::all())?;
|
||||
let _type = *self.u.choose(&[I8, I16, I32, I64, I128])?;
|
||||
|
||||
let lhs = builder.use_var(self.get_variable_of_type(_type)?);
|
||||
let rhs = builder.use_var(self.get_variable_of_type(_type)?);
|
||||
|
||||
let left_args = self.generate_values_for_block(builder, left)?;
|
||||
let right_args = self.generate_values_for_block(builder, right)?;
|
||||
|
||||
builder.ins().br_icmp(cc, lhs, rhs, left, &left_args[..]);
|
||||
builder.ins().jump(right, &right_args[..]);
|
||||
}
|
||||
BlockTerminator::BrTable(default, targets) => {
|
||||
// Create jump tables on demand
|
||||
let jt = builder.create_jump_table(JumpTableData::with_blocks(targets));
|
||||
@@ -1295,13 +1280,10 @@ where
|
||||
valid_terminators.push(BlockTerminatorKind::Return);
|
||||
} else {
|
||||
// If we have more than one block we can allow terminators that target blocks.
|
||||
// TODO: We could add some kind of BrReturn/BrIcmpReturn here, to explore edges where we exit
|
||||
// in the middle of the function
|
||||
valid_terminators.extend_from_slice(&[
|
||||
BlockTerminatorKind::Jump,
|
||||
BlockTerminatorKind::Br,
|
||||
BlockTerminatorKind::BrIcmp,
|
||||
]);
|
||||
// TODO: We could add some kind of BrReturn here, to explore edges where we
|
||||
// exit in the middle of the function
|
||||
valid_terminators
|
||||
.extend_from_slice(&[BlockTerminatorKind::Jump, BlockTerminatorKind::Br]);
|
||||
}
|
||||
|
||||
// BrTable and the Switch interface only allow targeting blocks without params
|
||||
@@ -1323,9 +1305,6 @@ where
|
||||
BlockTerminatorKind::Br => {
|
||||
BlockTerminator::Br(next_block, self.generate_target_block(block)?)
|
||||
}
|
||||
BlockTerminatorKind::BrIcmp => {
|
||||
BlockTerminator::BrIcmp(next_block, self.generate_target_block(block)?)
|
||||
}
|
||||
// TODO: Allow generating backwards branches here
|
||||
BlockTerminatorKind::BrTable => {
|
||||
// Make the default the next block, and then we don't have to worry
|
||||
|
||||
@@ -245,10 +245,7 @@ where
|
||||
let branch_when = |condition: bool| -> Result<ControlFlow<V>, StepError> {
|
||||
let branch_args = match inst {
|
||||
InstructionData::Jump { .. } => args_range(0..),
|
||||
InstructionData::BranchInt { .. }
|
||||
| InstructionData::BranchFloat { .. }
|
||||
| InstructionData::Branch { .. } => args_range(1..),
|
||||
InstructionData::BranchIcmp { .. } => args_range(2..),
|
||||
InstructionData::Branch { .. } => args_range(1..),
|
||||
_ => panic!("Unrecognized branch inst: {:?}", inst),
|
||||
}?;
|
||||
|
||||
@@ -293,11 +290,6 @@ where
|
||||
.convert(ValueConversionKind::ToBoolean)?
|
||||
.into_bool()?,
|
||||
)?,
|
||||
Opcode::BrIcmp => {
|
||||
branch_when(icmp(ctrl_ty, inst.cond_code().unwrap(), &arg(0)?, &arg(1)?)?.into_bool()?)?
|
||||
}
|
||||
Opcode::Brif => branch_when(state.has_iflag(inst.cond_code().unwrap()))?,
|
||||
Opcode::Brff => branch_when(state.has_fflag(inst.fp_cond_code().unwrap()))?,
|
||||
Opcode::BrTable => {
|
||||
if let InstructionData::BranchTable {
|
||||
table, destination, ..
|
||||
@@ -554,8 +546,7 @@ where
|
||||
Opcode::Null => unimplemented!("Null"),
|
||||
Opcode::Nop => ControlFlow::Continue,
|
||||
Opcode::Select => choose(arg(0)?.into_bool()?, arg(1)?, arg(2)?),
|
||||
Opcode::Selectif => choose(state.has_iflag(inst.cond_code().unwrap()), arg(1)?, arg(2)?),
|
||||
Opcode::SelectifSpectreGuard => unimplemented!("SelectifSpectreGuard"),
|
||||
Opcode::SelectSpectreGuard => unimplemented!("SelectSpectreGuard"),
|
||||
Opcode::Bitselect => {
|
||||
let mask_a = Value::and(arg(0)?, arg(1)?)?;
|
||||
let mask_b = Value::and(Value::not(arg(0)?)?, arg(2)?)?;
|
||||
@@ -940,18 +931,6 @@ where
|
||||
Opcode::Nearest => assign(Value::nearest(arg(0)?)?),
|
||||
Opcode::IsNull => unimplemented!("IsNull"),
|
||||
Opcode::IsInvalid => unimplemented!("IsInvalid"),
|
||||
// `ctrl_ty` is `INVALID` for `Trueif` and `Trueff`, but both should
|
||||
// return a 1-bit boolean value.
|
||||
Opcode::Trueif => choose(
|
||||
state.has_iflag(inst.cond_code().unwrap()),
|
||||
Value::bool(true, false, types::I8)?,
|
||||
Value::bool(false, false, types::I8)?,
|
||||
),
|
||||
Opcode::Trueff => choose(
|
||||
state.has_fflag(inst.fp_cond_code().unwrap()),
|
||||
Value::bool(true, false, types::I8)?,
|
||||
Value::bool(false, false, types::I8)?,
|
||||
),
|
||||
Opcode::Bitcast | Opcode::RawBitcast | Opcode::ScalarToVector => {
|
||||
let input_ty = inst_context.type_of(inst_context.args()[0]).unwrap();
|
||||
let arg0 = extractlanes(&arg(0)?, input_ty)?;
|
||||
|
||||
@@ -2813,47 +2813,6 @@ impl<'a> Parser<'a> {
|
||||
args: args.into_value_list(&[ctrl_arg], &mut ctx.function.dfg.value_lists),
|
||||
}
|
||||
}
|
||||
InstructionFormat::BranchInt => {
|
||||
let cond = self.match_enum("expected intcc condition code")?;
|
||||
let arg = self.match_value("expected SSA value first operand")?;
|
||||
self.match_token(Token::Comma, "expected ',' between operands")?;
|
||||
let block_num = self.match_block("expected branch destination block")?;
|
||||
let args = self.parse_opt_value_list()?;
|
||||
InstructionData::BranchInt {
|
||||
opcode,
|
||||
cond,
|
||||
destination: block_num,
|
||||
args: args.into_value_list(&[arg], &mut ctx.function.dfg.value_lists),
|
||||
}
|
||||
}
|
||||
InstructionFormat::BranchFloat => {
|
||||
let cond = self.match_enum("expected floatcc condition code")?;
|
||||
let arg = self.match_value("expected SSA value first operand")?;
|
||||
self.match_token(Token::Comma, "expected ',' between operands")?;
|
||||
let block_num = self.match_block("expected branch destination block")?;
|
||||
let args = self.parse_opt_value_list()?;
|
||||
InstructionData::BranchFloat {
|
||||
opcode,
|
||||
cond,
|
||||
destination: block_num,
|
||||
args: args.into_value_list(&[arg], &mut ctx.function.dfg.value_lists),
|
||||
}
|
||||
}
|
||||
InstructionFormat::BranchIcmp => {
|
||||
let cond = self.match_enum("expected intcc condition code")?;
|
||||
let lhs = self.match_value("expected SSA value first operand")?;
|
||||
self.match_token(Token::Comma, "expected ',' between operands")?;
|
||||
let rhs = self.match_value("expected SSA value second operand")?;
|
||||
self.match_token(Token::Comma, "expected ',' between operands")?;
|
||||
let block_num = self.match_block("expected branch destination block")?;
|
||||
let args = self.parse_opt_value_list()?;
|
||||
InstructionData::BranchIcmp {
|
||||
opcode,
|
||||
cond,
|
||||
destination: block_num,
|
||||
args: args.into_value_list(&[lhs, rhs], &mut ctx.function.dfg.value_lists),
|
||||
}
|
||||
}
|
||||
InstructionFormat::BranchTable => {
|
||||
let arg = self.match_value("expected SSA value operand")?;
|
||||
self.match_token(Token::Comma, "expected ',' between operands")?;
|
||||
@@ -2916,11 +2875,6 @@ impl<'a> Parser<'a> {
|
||||
imm: rhs,
|
||||
}
|
||||
}
|
||||
InstructionFormat::IntCond => {
|
||||
let cond = self.match_enum("expected intcc condition code")?;
|
||||
let arg = self.match_value("expected SSA value")?;
|
||||
InstructionData::IntCond { opcode, cond, arg }
|
||||
}
|
||||
InstructionFormat::FloatCompare => {
|
||||
let cond = self.match_enum("expected floatcc condition code")?;
|
||||
let lhs = self.match_value("expected SSA value first operand")?;
|
||||
@@ -2932,24 +2886,6 @@ impl<'a> Parser<'a> {
|
||||
args: [lhs, rhs],
|
||||
}
|
||||
}
|
||||
InstructionFormat::FloatCond => {
|
||||
let cond = self.match_enum("expected floatcc condition code")?;
|
||||
let arg = self.match_value("expected SSA value")?;
|
||||
InstructionData::FloatCond { opcode, cond, arg }
|
||||
}
|
||||
InstructionFormat::IntSelect => {
|
||||
let cond = self.match_enum("expected intcc condition code")?;
|
||||
let guard = self.match_value("expected SSA value first operand")?;
|
||||
self.match_token(Token::Comma, "expected ',' between operands")?;
|
||||
let v_true = self.match_value("expected SSA value second operand")?;
|
||||
self.match_token(Token::Comma, "expected ',' between operands")?;
|
||||
let v_false = self.match_value("expected SSA value third operand")?;
|
||||
InstructionData::IntSelect {
|
||||
opcode,
|
||||
cond,
|
||||
args: [guard, v_true, v_false],
|
||||
}
|
||||
}
|
||||
InstructionFormat::Call => {
|
||||
let func_ref = self.match_fn("expected function reference")?;
|
||||
ctx.check_fn(func_ref, self.loc)?;
|
||||
|
||||
@@ -542,10 +542,10 @@ impl<'module_environment> FuncEnvironment<'module_environment> {
|
||||
// Otherwise we can continue on like usual.
|
||||
let zero = builder.ins().iconst(ir::types::I64, 0);
|
||||
let fuel = builder.use_var(self.fuel_var);
|
||||
let cmp = builder.ins().ifcmp(fuel, zero);
|
||||
builder
|
||||
let cmp = builder
|
||||
.ins()
|
||||
.brif(IntCC::SignedGreaterThanOrEqual, cmp, out_of_gas_block, &[]);
|
||||
.icmp(IntCC::SignedGreaterThanOrEqual, fuel, zero);
|
||||
builder.ins().brnz(cmp, out_of_gas_block, &[]);
|
||||
builder.ins().jump(continuation_block, &[]);
|
||||
builder.seal_block(out_of_gas_block);
|
||||
|
||||
@@ -649,10 +649,12 @@ impl<'module_environment> FuncEnvironment<'module_environment> {
|
||||
// fine, as we'll reload it and check again before yielding in
|
||||
// the cold path.
|
||||
let cur_epoch_value = self.epoch_load_current(builder);
|
||||
let cmp = builder.ins().ifcmp(cur_epoch_value, epoch_deadline);
|
||||
builder
|
||||
.ins()
|
||||
.brif(IntCC::UnsignedGreaterThanOrEqual, cmp, new_epoch_block, &[]);
|
||||
let cmp = builder.ins().icmp(
|
||||
IntCC::UnsignedGreaterThanOrEqual,
|
||||
cur_epoch_value,
|
||||
epoch_deadline,
|
||||
);
|
||||
builder.ins().brnz(cmp, new_epoch_block, &[]);
|
||||
builder.ins().jump(continuation_block, &[]);
|
||||
builder.seal_block(new_epoch_block);
|
||||
|
||||
@@ -666,13 +668,14 @@ impl<'module_environment> FuncEnvironment<'module_environment> {
|
||||
builder.switch_to_block(new_epoch_block);
|
||||
self.epoch_load_deadline_into_var(builder);
|
||||
let fresh_epoch_deadline = builder.use_var(self.epoch_deadline_var);
|
||||
let fresh_cmp = builder.ins().ifcmp(cur_epoch_value, fresh_epoch_deadline);
|
||||
builder.ins().brif(
|
||||
let fresh_cmp = builder.ins().icmp(
|
||||
IntCC::UnsignedGreaterThanOrEqual,
|
||||
fresh_cmp,
|
||||
new_epoch_doublecheck_block,
|
||||
&[],
|
||||
cur_epoch_value,
|
||||
fresh_epoch_deadline,
|
||||
);
|
||||
builder
|
||||
.ins()
|
||||
.brnz(fresh_cmp, new_epoch_doublecheck_block, &[]);
|
||||
builder.ins().jump(continuation_block, &[]);
|
||||
builder.seal_block(new_epoch_doublecheck_block);
|
||||
|
||||
@@ -1183,9 +1186,8 @@ impl<'module_environment> cranelift_wasm::FuncEnvironment for FuncEnvironment<'m
|
||||
builder.switch_to_block(dec_ref_count_block);
|
||||
let prev_ref_count = self.mutate_externref_ref_count(builder, current_elem, -1);
|
||||
let one = builder.ins().iconst(pointer_type, 1);
|
||||
builder
|
||||
.ins()
|
||||
.br_icmp(IntCC::Equal, one, prev_ref_count, drop_block, &[]);
|
||||
let cond = builder.ins().icmp(IntCC::Equal, one, prev_ref_count);
|
||||
builder.ins().brnz(cond, drop_block, &[]);
|
||||
builder.ins().jump(continue_block, &[]);
|
||||
|
||||
// Call the `drop_externref` builtin to (you guessed it) drop
|
||||
|
||||
Reference in New Issue
Block a user