Port flag-based ops to ISLE (AArch64) (#4942)
Ported the existing implementations of the following opcodes for AArch64 to ISLE: - `Trueif` - `Trueff` - `Trapif` - `Trapff` - `Select` - `Selectif` - `SelectifSpectreGuard` Copyright (c) 2022 Arm Limited
This commit is contained in:
@@ -2077,6 +2077,14 @@
|
||||
(MInst.FpuCSel64 dst if_true if_false cond)
|
||||
dst)))
|
||||
|
||||
;; Helper for emitting `MInst.VecCSel` instructions.
|
||||
(decl vec_csel (Cond Reg Reg) ConsumesFlags)
|
||||
(rule (vec_csel cond if_true if_false)
|
||||
(let ((dst WritableReg (temp_writable_reg $I8X16)))
|
||||
(ConsumesFlags.ConsumesFlagsReturnsReg
|
||||
(MInst.VecCSel dst if_true if_false cond)
|
||||
dst)))
|
||||
|
||||
;; Helper for emitting `MInst.FpuRound` instructions.
|
||||
(decl fpu_round (FpuRoundMode Reg) Reg)
|
||||
(rule (fpu_round op rn)
|
||||
@@ -2353,6 +2361,11 @@
|
||||
(rule (aarch64_fence)
|
||||
(SideEffectNoResult.Inst (MInst.Fence)))
|
||||
|
||||
;; Helper for generating `csdb` instructions.
|
||||
(decl csdb () SideEffectNoResult)
|
||||
(rule (csdb)
|
||||
(SideEffectNoResult.Inst (MInst.Csdb)))
|
||||
|
||||
;; Helper for generating `brk` instructions.
|
||||
(decl brk () SideEffectNoResult)
|
||||
(rule (brk)
|
||||
@@ -2641,6 +2654,15 @@
|
||||
(rule (aarch64_storep64 amode flags val1 val2)
|
||||
(SideEffectNoResult.Inst (MInst.StoreP64 val1 val2 amode flags)))
|
||||
|
||||
;; Helper for generating a `trapif` instruction.
|
||||
|
||||
(decl trap_if (ProducesFlags TrapCode Cond) InstOutput)
|
||||
(rule (trap_if flags trap_code cond)
|
||||
(side_effect
|
||||
(with_flags_side_effect flags
|
||||
(ConsumesFlags.ConsumesFlagsSideEffect
|
||||
(MInst.TrapIf (cond_br_cond cond) trap_code)))))
|
||||
|
||||
;; Immediate value helpers ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
;; Type of extension performed by an immediate helper
|
||||
@@ -3378,7 +3400,9 @@
|
||||
;; ccmp lhs_hi, rhs_hi, #0, eq
|
||||
(decl lower_icmp_i128_eq_ne (Value Value) ProducesFlags)
|
||||
(rule (lower_icmp_i128_eq_ne lhs rhs)
|
||||
(let ((lhs_lo Reg (value_regs_get lhs 0))
|
||||
(let ((lhs ValueRegs (put_in_regs lhs))
|
||||
(rhs ValueRegs (put_in_regs rhs))
|
||||
(lhs_lo Reg (value_regs_get lhs 0))
|
||||
(lhs_hi Reg (value_regs_get lhs 1))
|
||||
(rhs_lo Reg (value_regs_get rhs 0))
|
||||
(rhs_hi Reg (value_regs_get rhs 1))
|
||||
@@ -3399,6 +3423,8 @@
|
||||
(rule -1 (lower_icmp_into_reg cond lhs rhs $I128 out_ty)
|
||||
(let ((unsigned_cond Cond (cond_code (intcc_unsigned cond)))
|
||||
(cond Cond (cond_code cond))
|
||||
(lhs ValueRegs (put_in_regs lhs))
|
||||
(rhs ValueRegs (put_in_regs rhs))
|
||||
(lhs_lo Reg (value_regs_get lhs 0))
|
||||
(lhs_hi Reg (value_regs_get lhs 1))
|
||||
(rhs_lo Reg (value_regs_get rhs 0))
|
||||
@@ -3477,3 +3503,30 @@
|
||||
(let ((dst ValueRegs (lower_icmp_into_reg cond lhs rhs $I128 $B1))
|
||||
(dst Reg (value_regs_get dst 0)))
|
||||
(cmp (OperandSize.Size64) (zero_reg) dst)))
|
||||
|
||||
;; Helpers for generating select instruction sequences.
|
||||
(decl lower_select (ProducesFlags Cond Type Value Value) ValueRegs)
|
||||
(rule (lower_select flags cond (ty_scalar_float ty) rn rm)
|
||||
(with_flags flags (fpu_csel ty cond rn rm)))
|
||||
(rule (lower_select flags cond (ty_vec128 ty) rn rm)
|
||||
(with_flags flags (vec_csel cond rn rm)))
|
||||
(rule (lower_select flags cond ty rn rm)
|
||||
(if (ty_vec64 ty))
|
||||
(with_flags flags (fpu_csel $F64 cond rn rm)))
|
||||
(rule (lower_select flags cond $I128 rn rm)
|
||||
(let ((dst_lo WritableReg (temp_writable_reg $I64))
|
||||
(dst_hi WritableReg (temp_writable_reg $I64))
|
||||
(rn ValueRegs (put_in_regs rn))
|
||||
(rm ValueRegs (put_in_regs rm))
|
||||
(rn_lo Reg (value_regs_get rn 0))
|
||||
(rn_hi Reg (value_regs_get rn 1))
|
||||
(rm_lo Reg (value_regs_get rm 0))
|
||||
(rm_hi Reg (value_regs_get rm 1)))
|
||||
(with_flags flags
|
||||
(ConsumesFlags.ConsumesFlagsTwiceReturnsValueRegs
|
||||
(MInst.CSel dst_lo cond rn_lo rm_lo)
|
||||
(MInst.CSel dst_hi cond rn_hi rm_hi)
|
||||
(value_regs dst_lo dst_hi)))))
|
||||
(rule (lower_select flags cond ty rn rm)
|
||||
(if (ty_int_bool_ref_scalar_64 ty))
|
||||
(with_flags flags (csel cond rn rm)))
|
||||
|
||||
@@ -1738,11 +1738,111 @@
|
||||
(rule (lower (trap trap_code))
|
||||
(side_effect (udf trap_code)))
|
||||
|
||||
;;;; Rules for `trapif` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
(rule (lower (trapif cc insn @ (iadd_ifcout x y) trap_code))
|
||||
;; The flags must not have been clobbered by any other instruction, as
|
||||
;; verified by the CLIF validator; so we can simply use the flags here.
|
||||
(let ((insn ProducesFlags (flags_to_producesflags insn)))
|
||||
(trap_if insn trap_code (cond_code cc))))
|
||||
|
||||
;; Verification ensures the input is always a single-def ifcmp.
|
||||
(rule (lower (trapif cc insn @ (ifcmp x @ (value_type ty) y) trap_code))
|
||||
(let ((cond Cond (cond_code cc)))
|
||||
(trap_if (lower_icmp_into_flags cc x y ty) trap_code cond)))
|
||||
|
||||
;;;; Rules for `trapff` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
;; Verification ensures the input is always a single-def ffcmp.
|
||||
(rule (lower (trapff cc insn @ (ffcmp x @ (value_type ty) y) trap_code))
|
||||
(let ((cond Cond (fp_cond_code cc)))
|
||||
(trap_if (fpu_cmp (scalar_size ty) x y) trap_code cond)))
|
||||
|
||||
;;;; Rules for `resumable_trap` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
(rule (lower (resumable_trap trap_code))
|
||||
(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 (has_type ty (trueff cc insn @ (ffcmp x @ (value_type in_ty) y))))
|
||||
(with_flags_reg
|
||||
(fpu_cmp (scalar_size in_ty) x y)
|
||||
(materialize_bool_result (ty_bits ty) (fp_cond_code cc))))
|
||||
|
||||
;;;; Rules for `select` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
(rule (lower (has_type ty
|
||||
(select _flags @ (icmp cc x @ (value_type in_ty) y) rn rm)))
|
||||
(let ((cond Cond (cond_code cc)))
|
||||
(lower_select
|
||||
(lower_icmp_into_flags cc x y in_ty)
|
||||
cond ty rn rm)))
|
||||
|
||||
(rule (lower (has_type ty
|
||||
(select _flags @ (bint (icmp cc x @ (value_type in_ty) y)) rn rm)))
|
||||
(let ((cond Cond (cond_code cc)))
|
||||
(lower_select
|
||||
(lower_icmp_into_flags cc x y in_ty)
|
||||
cond ty rn rm)))
|
||||
|
||||
(rule (lower (has_type ty
|
||||
(select _flags @ (fcmp cc x @ (value_type in_ty) y) rn rm)))
|
||||
(let ((cond Cond (fp_cond_code cc)))
|
||||
(lower_select
|
||||
(fpu_cmp (scalar_size in_ty) x y)
|
||||
cond ty rn rm)))
|
||||
|
||||
(rule (lower (has_type ty
|
||||
(select _flags @ (bint (fcmp cc x @ (value_type in_ty) y)) rn rm)))
|
||||
(let ((cond Cond (fp_cond_code cc)))
|
||||
(lower_select
|
||||
(fpu_cmp (scalar_size in_ty) x y)
|
||||
cond ty rn rm)))
|
||||
|
||||
(rule -1 (lower (has_type ty (select rcond @ (value_type (fits_in_32 _)) rn rm)))
|
||||
(let ((rcond Reg (put_in_reg_zext32 rcond)))
|
||||
(lower_select
|
||||
(cmp (OperandSize.Size32) rcond (zero_reg))
|
||||
(Cond.Ne) ty rn rm)))
|
||||
|
||||
(rule -2 (lower (has_type ty (select rcond rn rm)))
|
||||
(let ((rcond Reg (put_in_reg_zext64 rcond)))
|
||||
(lower_select
|
||||
(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` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
(rule (lower (has_type ty
|
||||
(selectif_spectre_guard cc
|
||||
flags @ (ifcmp 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)
|
||||
cond ty if_true if_false))
|
||||
(_ InstOutput (side_effect (csdb))))
|
||||
dst))
|
||||
|
||||
;;;; Rules for `vconst` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
(rule (lower (has_type (ty_vec128 _) (vconst (u128_from_constant x))))
|
||||
@@ -2395,18 +2495,6 @@
|
||||
(rule (lower (fvpromote_low val))
|
||||
(vec_rr_long (VecRRLongOp.Fcvtl32) val $false))
|
||||
|
||||
;;; Rules for `select` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
;; TODO: requires icmp/fcmp first.
|
||||
|
||||
;;; Rules for `selectif` / `selectif_spectre_guard` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
;; TODO: requires icmp/fcmp first.
|
||||
|
||||
;;; Rules for `trueif` / `trueff` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
;; TODO: requires icmp/fcmp first.
|
||||
|
||||
;;; Rules for `brz`/`brnz`/`brif`/`brff`/`bricmp` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
;; TODO: requires icmp/fcmp first.
|
||||
|
||||
@@ -1178,15 +1178,12 @@ pub(crate) enum IcmpOutput {
|
||||
/// Lowers the comparison into a cond code, discarding the results. The cond code emitted can
|
||||
/// be checked in the resulting [IcmpResult].
|
||||
CondCode,
|
||||
/// Materializes the results into a register. This may overwrite any flags previously set.
|
||||
Register(Writable<Reg>),
|
||||
}
|
||||
|
||||
impl IcmpOutput {
|
||||
pub fn reg(&self) -> Option<Writable<Reg>> {
|
||||
match self {
|
||||
IcmpOutput::CondCode => None,
|
||||
IcmpOutput::Register(reg) => Some(*reg),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1197,15 +1194,12 @@ pub(crate) enum IcmpResult {
|
||||
/// The result was output into the given [Cond]. Callers may perform operations using this [Cond]
|
||||
/// and its inverse, other [Cond]'s are not guaranteed to be correct.
|
||||
CondCode(Cond),
|
||||
/// The result was materialized into the output register.
|
||||
Register,
|
||||
}
|
||||
|
||||
impl IcmpResult {
|
||||
pub fn unwrap_cond(&self) -> Cond {
|
||||
match self {
|
||||
IcmpResult::CondCode(c) => *c,
|
||||
_ => panic!("Unwrapped cond, but IcmpResult was {:?}", self),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1364,8 +1358,6 @@ pub(crate) fn lower_icmp(
|
||||
}
|
||||
|
||||
Ok(match output {
|
||||
// We currently never emit a different register than what was asked for
|
||||
IcmpOutput::Register(_) => IcmpResult::Register,
|
||||
IcmpOutput::CondCode => IcmpResult::CondCode(out_condcode),
|
||||
})
|
||||
}
|
||||
|
||||
@@ -24,7 +24,6 @@ pub(crate) fn lower_insn_to_regs(
|
||||
isa_flags: &aarch64_settings::Flags,
|
||||
) -> CodegenResult<()> {
|
||||
let op = ctx.data(insn).opcode();
|
||||
let inputs = insn_inputs(ctx, insn);
|
||||
let outputs = insn_outputs(ctx, insn);
|
||||
let ty = if outputs.len() > 0 {
|
||||
Some(ctx.output_ty(insn, 0))
|
||||
@@ -140,131 +139,15 @@ pub(crate) fn lower_insn_to_regs(
|
||||
// Nothing.
|
||||
}
|
||||
|
||||
Opcode::Select => {
|
||||
let flag_input = inputs[0];
|
||||
let cond = if let Some(icmp_insn) =
|
||||
maybe_input_insn_via_conv(ctx, flag_input, Opcode::Icmp, Opcode::Bint)
|
||||
{
|
||||
let condcode = ctx.data(icmp_insn).cond_code().unwrap();
|
||||
lower_icmp(ctx, icmp_insn, condcode, IcmpOutput::CondCode)?.unwrap_cond()
|
||||
} else if let Some(fcmp_insn) =
|
||||
maybe_input_insn_via_conv(ctx, flag_input, Opcode::Fcmp, Opcode::Bint)
|
||||
{
|
||||
let condcode = ctx.data(fcmp_insn).fp_cond_code().unwrap();
|
||||
let cond = lower_fp_condcode(condcode);
|
||||
lower_fcmp_or_ffcmp_to_flags(ctx, fcmp_insn);
|
||||
cond
|
||||
} else {
|
||||
let (size, narrow_mode) = if ty_bits(ctx.input_ty(insn, 0)) > 32 {
|
||||
(OperandSize::Size64, NarrowValueMode::ZeroExtend64)
|
||||
} else {
|
||||
(OperandSize::Size32, NarrowValueMode::ZeroExtend32)
|
||||
};
|
||||
Opcode::Select => implemented_in_isle(ctx),
|
||||
|
||||
let rcond = put_input_in_reg(ctx, inputs[0], narrow_mode);
|
||||
// cmp rcond, #0
|
||||
ctx.emit(Inst::AluRRR {
|
||||
alu_op: ALUOp::SubS,
|
||||
size,
|
||||
rd: writable_zero_reg(),
|
||||
rn: rcond,
|
||||
rm: zero_reg(),
|
||||
});
|
||||
Cond::Ne
|
||||
};
|
||||
|
||||
// csel.cond rd, rn, rm
|
||||
let ty = ctx.output_ty(insn, 0);
|
||||
let bits = ty_bits(ty);
|
||||
let is_float = ty_has_float_or_vec_representation(ty);
|
||||
|
||||
let dst = get_output_reg(ctx, outputs[0]);
|
||||
let lhs = put_input_in_regs(ctx, inputs[1]);
|
||||
let rhs = put_input_in_regs(ctx, inputs[2]);
|
||||
|
||||
let rd = dst.regs()[0];
|
||||
let rn = lhs.regs()[0];
|
||||
let rm = rhs.regs()[0];
|
||||
|
||||
match (is_float, bits) {
|
||||
(true, 32) => ctx.emit(Inst::FpuCSel32 { cond, rd, rn, rm }),
|
||||
(true, 64) => ctx.emit(Inst::FpuCSel64 { cond, rd, rn, rm }),
|
||||
(true, 128) => ctx.emit(Inst::VecCSel { cond, rd, rn, rm }),
|
||||
(false, 128) => {
|
||||
ctx.emit(Inst::CSel {
|
||||
cond,
|
||||
rd: dst.regs()[0],
|
||||
rn: lhs.regs()[0],
|
||||
rm: rhs.regs()[0],
|
||||
});
|
||||
ctx.emit(Inst::CSel {
|
||||
cond,
|
||||
rd: dst.regs()[1],
|
||||
rn: lhs.regs()[1],
|
||||
rm: rhs.regs()[1],
|
||||
});
|
||||
}
|
||||
(false, bits) if bits <= 64 => ctx.emit(Inst::CSel { cond, rd, rn, rm }),
|
||||
_ => {
|
||||
return Err(CodegenError::Unsupported(format!(
|
||||
"Select: Unsupported type: {:?}",
|
||||
ty
|
||||
)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Opcode::Selectif | Opcode::SelectifSpectreGuard => {
|
||||
let condcode = ctx.data(insn).cond_code().unwrap();
|
||||
// Verification ensures that the input is always a
|
||||
// single-def ifcmp.
|
||||
let ifcmp_insn = maybe_input_insn(ctx, inputs[0], Opcode::Ifcmp).unwrap();
|
||||
let cond = lower_icmp(ctx, ifcmp_insn, condcode, IcmpOutput::CondCode)?.unwrap_cond();
|
||||
|
||||
// csel.COND rd, rn, rm
|
||||
let rd = get_output_reg(ctx, outputs[0]).only_reg().unwrap();
|
||||
let rn = put_input_in_reg(ctx, inputs[1], NarrowValueMode::None);
|
||||
let rm = put_input_in_reg(ctx, inputs[2], NarrowValueMode::None);
|
||||
let ty = ctx.output_ty(insn, 0);
|
||||
let bits = ty_bits(ty);
|
||||
let is_float = ty_has_float_or_vec_representation(ty);
|
||||
if is_float && bits == 32 {
|
||||
ctx.emit(Inst::FpuCSel32 { cond, rd, rn, rm });
|
||||
} else if is_float && bits == 64 {
|
||||
ctx.emit(Inst::FpuCSel64 { cond, rd, rn, rm });
|
||||
} else if !is_float && bits <= 64 {
|
||||
ctx.emit(Inst::CSel { cond, rd, rn, rm });
|
||||
} else {
|
||||
return Err(CodegenError::Unsupported(format!(
|
||||
"{}: Unsupported type: {:?}",
|
||||
op, ty
|
||||
)));
|
||||
}
|
||||
|
||||
if op == Opcode::SelectifSpectreGuard {
|
||||
ctx.emit(Inst::Csdb);
|
||||
}
|
||||
}
|
||||
Opcode::Selectif | Opcode::SelectifSpectreGuard => implemented_in_isle(ctx),
|
||||
|
||||
Opcode::Bitselect | Opcode::Vselect => implemented_in_isle(ctx),
|
||||
|
||||
Opcode::Trueif => {
|
||||
let condcode = ctx.data(insn).cond_code().unwrap();
|
||||
// Verification ensures that the input is always a
|
||||
// single-def ifcmp.
|
||||
let ifcmp_insn = maybe_input_insn(ctx, inputs[0], Opcode::Ifcmp).unwrap();
|
||||
let rd = get_output_reg(ctx, outputs[0]).only_reg().unwrap();
|
||||
lower_icmp(ctx, ifcmp_insn, condcode, IcmpOutput::Register(rd))?;
|
||||
}
|
||||
Opcode::Trueif => implemented_in_isle(ctx),
|
||||
|
||||
Opcode::Trueff => {
|
||||
let condcode = ctx.data(insn).fp_cond_code().unwrap();
|
||||
let cond = lower_fp_condcode(condcode);
|
||||
let ffcmp_insn = maybe_input_insn(ctx, inputs[0], Opcode::Ffcmp).unwrap();
|
||||
lower_fcmp_or_ffcmp_to_flags(ctx, ffcmp_insn);
|
||||
let rd = get_output_reg(ctx, outputs[0]).only_reg().unwrap();
|
||||
materialize_bool_result(ctx, insn, rd, cond);
|
||||
}
|
||||
Opcode::Trueff => implemented_in_isle(ctx),
|
||||
|
||||
Opcode::IsNull | Opcode::IsInvalid => implemented_in_isle(ctx),
|
||||
|
||||
@@ -296,39 +179,7 @@ pub(crate) fn lower_insn_to_regs(
|
||||
|
||||
Opcode::Trap | Opcode::ResumableTrap => implemented_in_isle(ctx),
|
||||
|
||||
Opcode::Trapif | Opcode::Trapff => {
|
||||
let trap_code = ctx.data(insn).trap_code().unwrap();
|
||||
|
||||
let cond = if maybe_input_insn(ctx, inputs[0], Opcode::IaddIfcout).is_some() {
|
||||
let condcode = ctx.data(insn).cond_code().unwrap();
|
||||
let cond = lower_condcode(condcode);
|
||||
// The flags must not have been clobbered by any other
|
||||
// instruction between the iadd_ifcout and this instruction, as
|
||||
// verified by the CLIF validator; so we can simply use the
|
||||
// flags here.
|
||||
cond
|
||||
} else if op == Opcode::Trapif {
|
||||
let condcode = ctx.data(insn).cond_code().unwrap();
|
||||
|
||||
// Verification ensures that the input is always a single-def ifcmp.
|
||||
let ifcmp_insn = maybe_input_insn(ctx, inputs[0], Opcode::Ifcmp).unwrap();
|
||||
lower_icmp(ctx, ifcmp_insn, condcode, IcmpOutput::CondCode)?.unwrap_cond()
|
||||
} else {
|
||||
let condcode = ctx.data(insn).fp_cond_code().unwrap();
|
||||
let cond = lower_fp_condcode(condcode);
|
||||
|
||||
// Verification ensures that the input is always a
|
||||
// single-def ffcmp.
|
||||
let ffcmp_insn = maybe_input_insn(ctx, inputs[0], Opcode::Ffcmp).unwrap();
|
||||
lower_fcmp_or_ffcmp_to_flags(ctx, ffcmp_insn);
|
||||
cond
|
||||
};
|
||||
|
||||
ctx.emit(Inst::TrapIf {
|
||||
trap_code,
|
||||
kind: CondBrKind::Cond(cond),
|
||||
});
|
||||
}
|
||||
Opcode::Trapif | Opcode::Trapff => implemented_in_isle(ctx),
|
||||
|
||||
Opcode::Trapz | Opcode::Trapnz | Opcode::ResumableTrapnz => {
|
||||
panic!("trapz / trapnz / resumable_trapnz should have been removed by legalization!");
|
||||
|
||||
@@ -2,6 +2,48 @@ test compile precise-output
|
||||
set unwind_info=false
|
||||
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
|
||||
return v5
|
||||
}
|
||||
|
||||
; block0:
|
||||
; uxtb w5, w0
|
||||
; subs wzr, w5, #42
|
||||
; csel x0, x1, x2, eq
|
||||
; ret
|
||||
|
||||
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
|
||||
return v5
|
||||
}
|
||||
|
||||
; block0:
|
||||
; uxtb w5, w0
|
||||
; subs wzr, w5, #42
|
||||
; csel x0, x1, x2, eq
|
||||
; ret
|
||||
|
||||
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
|
||||
return v5
|
||||
}
|
||||
|
||||
; block0:
|
||||
; uxtb w5, w0
|
||||
; subs wzr, w5, #42
|
||||
; csel x0, x1, x2, eq
|
||||
; ret
|
||||
|
||||
function %f(i8, i64, i64) -> i64 {
|
||||
block0(v0: i8, v1: i64, v2: i64):
|
||||
v3 = iconst.i8 42
|
||||
@@ -11,11 +53,690 @@ block0(v0: i8, v1: i64, v2: i64):
|
||||
}
|
||||
|
||||
; block0:
|
||||
; uxtb w6, w0
|
||||
; subs wzr, w6, #42
|
||||
; uxtb w5, w0
|
||||
; subs wzr, w5, #42
|
||||
; csel x0, x1, x2, eq
|
||||
; ret
|
||||
|
||||
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
|
||||
return v5
|
||||
}
|
||||
|
||||
; block0:
|
||||
; uxtb w8, w0
|
||||
; subs wzr, w8, #42
|
||||
; csel x0, x2, x4, eq
|
||||
; csel x1, x3, x5, eq
|
||||
; ret
|
||||
|
||||
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
|
||||
return v5
|
||||
}
|
||||
|
||||
; block0:
|
||||
; uxth w5, w0
|
||||
; subs wzr, w5, #42
|
||||
; csel x0, x1, x2, eq
|
||||
; ret
|
||||
|
||||
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
|
||||
return v5
|
||||
}
|
||||
|
||||
; block0:
|
||||
; uxth w5, w0
|
||||
; subs wzr, w5, #42
|
||||
; csel x0, x1, x2, eq
|
||||
; ret
|
||||
|
||||
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
|
||||
return v5
|
||||
}
|
||||
|
||||
; block0:
|
||||
; uxth w5, w0
|
||||
; subs wzr, w5, #42
|
||||
; csel x0, x1, x2, eq
|
||||
; ret
|
||||
|
||||
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
|
||||
return v5
|
||||
}
|
||||
|
||||
; block0:
|
||||
; uxth w5, w0
|
||||
; subs wzr, w5, #42
|
||||
; csel x0, x1, x2, eq
|
||||
; ret
|
||||
|
||||
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
|
||||
return v5
|
||||
}
|
||||
|
||||
; block0:
|
||||
; uxth w8, w0
|
||||
; subs wzr, w8, #42
|
||||
; csel x0, x2, x4, eq
|
||||
; csel x1, x3, x5, eq
|
||||
; ret
|
||||
|
||||
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
|
||||
return v5
|
||||
}
|
||||
|
||||
; block0:
|
||||
; subs wzr, w0, #42
|
||||
; csel x0, x1, x2, eq
|
||||
; ret
|
||||
|
||||
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
|
||||
return v5
|
||||
}
|
||||
|
||||
; block0:
|
||||
; subs wzr, w0, #42
|
||||
; csel x0, x1, x2, eq
|
||||
; ret
|
||||
|
||||
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
|
||||
return v5
|
||||
}
|
||||
|
||||
; block0:
|
||||
; subs wzr, w0, #42
|
||||
; csel x0, x1, x2, eq
|
||||
; ret
|
||||
|
||||
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
|
||||
return v5
|
||||
}
|
||||
|
||||
; block0:
|
||||
; subs wzr, w0, #42
|
||||
; csel x0, x1, x2, eq
|
||||
; ret
|
||||
|
||||
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
|
||||
return v5
|
||||
}
|
||||
|
||||
; block0:
|
||||
; subs wzr, w0, #42
|
||||
; csel x0, x2, x4, eq
|
||||
; csel x1, x3, x5, eq
|
||||
; ret
|
||||
|
||||
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
|
||||
return v5
|
||||
}
|
||||
|
||||
; block0:
|
||||
; subs xzr, x0, #42
|
||||
; csel x0, x1, x2, eq
|
||||
; ret
|
||||
|
||||
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
|
||||
return v5
|
||||
}
|
||||
|
||||
; block0:
|
||||
; subs xzr, x0, #42
|
||||
; csel x0, x1, x2, eq
|
||||
; ret
|
||||
|
||||
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
|
||||
return v5
|
||||
}
|
||||
|
||||
; block0:
|
||||
; subs xzr, x0, #42
|
||||
; csel x0, x1, x2, eq
|
||||
; ret
|
||||
|
||||
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
|
||||
return v5
|
||||
}
|
||||
|
||||
; block0:
|
||||
; subs xzr, x0, #42
|
||||
; csel x0, x1, x2, eq
|
||||
; ret
|
||||
|
||||
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
|
||||
return v5
|
||||
}
|
||||
|
||||
; block0:
|
||||
; subs xzr, x0, #42
|
||||
; csel x0, x2, x4, eq
|
||||
; csel x1, x3, x5, eq
|
||||
; ret
|
||||
|
||||
function %f(i128, i8, i8) -> i8 {
|
||||
block0(v0: i128, v1: i8, v2: i8):
|
||||
v3 = iconst.i128 42
|
||||
v4 = ifcmp v0, v3
|
||||
v5 = selectif.i8 eq v4, v1, v2
|
||||
return v5
|
||||
}
|
||||
|
||||
; block0:
|
||||
; movz x6, #42
|
||||
; movz x8, #0
|
||||
; subs xzr, x0, x6
|
||||
; ccmp x1, x8, #nzcv, eq
|
||||
; csel x0, x2, x3, eq
|
||||
; ret
|
||||
|
||||
function %f(i128, i16, i16) -> i16 {
|
||||
block0(v0: i128, v1: i16, v2: i16):
|
||||
v3 = iconst.i128 42
|
||||
v4 = ifcmp v0, v3
|
||||
v5 = selectif.i16 eq v4, v1, v2
|
||||
return v5
|
||||
}
|
||||
|
||||
; block0:
|
||||
; movz x6, #42
|
||||
; movz x8, #0
|
||||
; subs xzr, x0, x6
|
||||
; ccmp x1, x8, #nzcv, eq
|
||||
; csel x0, x2, x3, eq
|
||||
; ret
|
||||
|
||||
function %f(i128, i32, i32) -> i32 {
|
||||
block0(v0: i128, v1: i32, v2: i32):
|
||||
v3 = iconst.i128 42
|
||||
v4 = ifcmp v0, v3
|
||||
v5 = selectif.i32 eq v4, v1, v2
|
||||
return v5
|
||||
}
|
||||
|
||||
; block0:
|
||||
; movz x6, #42
|
||||
; movz x8, #0
|
||||
; subs xzr, x0, x6
|
||||
; ccmp x1, x8, #nzcv, eq
|
||||
; csel x0, x2, x3, eq
|
||||
; ret
|
||||
|
||||
function %f(i128, i64, i64) -> i64 {
|
||||
block0(v0: i128, v1: i64, v2: i64):
|
||||
v3 = iconst.i128 42
|
||||
v4 = ifcmp v0, v3
|
||||
v5 = selectif.i64 eq v4, v1, v2
|
||||
return v5
|
||||
}
|
||||
|
||||
; block0:
|
||||
; movz x6, #42
|
||||
; movz x8, #0
|
||||
; subs xzr, x0, x6
|
||||
; ccmp x1, x8, #nzcv, eq
|
||||
; csel x0, x2, x3, eq
|
||||
; ret
|
||||
|
||||
function %f(i128, i128, i128) -> i128 {
|
||||
block0(v0: i128, v1: i128, v2: i128):
|
||||
v3 = iconst.i128 42
|
||||
v4 = ifcmp v0, v3
|
||||
v5 = selectif.i128 eq v4, v1, v2
|
||||
return v5
|
||||
}
|
||||
|
||||
; block0:
|
||||
; movz x9, #42
|
||||
; movz x11, #0
|
||||
; subs xzr, x0, x9
|
||||
; ccmp x1, x11, #nzcv, eq
|
||||
; csel x0, x2, x4, eq
|
||||
; csel x1, x3, x5, eq
|
||||
; ret
|
||||
|
||||
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
|
||||
return v5
|
||||
}
|
||||
|
||||
; block0:
|
||||
; uxtb w5, w0
|
||||
; subs wzr, w5, #42
|
||||
; csel x0, x1, x2, eq
|
||||
; csdb
|
||||
; ret
|
||||
|
||||
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
|
||||
return v5
|
||||
}
|
||||
|
||||
; block0:
|
||||
; uxtb w5, w0
|
||||
; subs wzr, w5, #42
|
||||
; csel x0, x1, x2, eq
|
||||
; csdb
|
||||
; ret
|
||||
|
||||
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
|
||||
return v5
|
||||
}
|
||||
|
||||
; block0:
|
||||
; uxtb w5, w0
|
||||
; subs wzr, w5, #42
|
||||
; csel x0, x1, x2, eq
|
||||
; csdb
|
||||
; ret
|
||||
|
||||
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
|
||||
return v5
|
||||
}
|
||||
|
||||
; block0:
|
||||
; uxtb w5, w0
|
||||
; subs wzr, w5, #42
|
||||
; csel x0, x1, x2, eq
|
||||
; csdb
|
||||
; ret
|
||||
|
||||
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
|
||||
return v5
|
||||
}
|
||||
|
||||
; block0:
|
||||
; uxtb w8, w0
|
||||
; subs wzr, w8, #42
|
||||
; csel x0, x2, x4, eq
|
||||
; csel x1, x3, x5, eq
|
||||
; csdb
|
||||
; ret
|
||||
|
||||
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
|
||||
return v5
|
||||
}
|
||||
|
||||
; block0:
|
||||
; uxth w5, w0
|
||||
; subs wzr, w5, #42
|
||||
; csel x0, x1, x2, eq
|
||||
; csdb
|
||||
; ret
|
||||
|
||||
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
|
||||
return v5
|
||||
}
|
||||
|
||||
; block0:
|
||||
; uxth w5, w0
|
||||
; subs wzr, w5, #42
|
||||
; csel x0, x1, x2, eq
|
||||
; csdb
|
||||
; ret
|
||||
|
||||
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
|
||||
return v5
|
||||
}
|
||||
|
||||
; block0:
|
||||
; uxth w5, w0
|
||||
; subs wzr, w5, #42
|
||||
; csel x0, x1, x2, eq
|
||||
; csdb
|
||||
; ret
|
||||
|
||||
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
|
||||
return v5
|
||||
}
|
||||
|
||||
; block0:
|
||||
; uxth w5, w0
|
||||
; subs wzr, w5, #42
|
||||
; csel x0, x1, x2, eq
|
||||
; csdb
|
||||
; ret
|
||||
|
||||
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
|
||||
return v5
|
||||
}
|
||||
|
||||
; block0:
|
||||
; uxth w8, w0
|
||||
; subs wzr, w8, #42
|
||||
; csel x0, x2, x4, eq
|
||||
; csel x1, x3, x5, eq
|
||||
; csdb
|
||||
; ret
|
||||
|
||||
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
|
||||
return v5
|
||||
}
|
||||
|
||||
; block0:
|
||||
; subs wzr, w0, #42
|
||||
; csel x0, x1, x2, eq
|
||||
; csdb
|
||||
; ret
|
||||
|
||||
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
|
||||
return v5
|
||||
}
|
||||
|
||||
; block0:
|
||||
; subs wzr, w0, #42
|
||||
; csel x0, x1, x2, eq
|
||||
; csdb
|
||||
; ret
|
||||
|
||||
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
|
||||
return v5
|
||||
}
|
||||
|
||||
; block0:
|
||||
; subs wzr, w0, #42
|
||||
; csel x0, x1, x2, eq
|
||||
; csdb
|
||||
; ret
|
||||
|
||||
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
|
||||
return v5
|
||||
}
|
||||
|
||||
; block0:
|
||||
; subs wzr, w0, #42
|
||||
; csel x0, x1, x2, eq
|
||||
; csdb
|
||||
; ret
|
||||
|
||||
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
|
||||
return v5
|
||||
}
|
||||
|
||||
; block0:
|
||||
; subs wzr, w0, #42
|
||||
; csel x0, x2, x4, eq
|
||||
; csel x1, x3, x5, eq
|
||||
; csdb
|
||||
; ret
|
||||
|
||||
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
|
||||
return v5
|
||||
}
|
||||
|
||||
; block0:
|
||||
; subs xzr, x0, #42
|
||||
; csel x0, x1, x2, eq
|
||||
; csdb
|
||||
; ret
|
||||
|
||||
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
|
||||
return v5
|
||||
}
|
||||
|
||||
; block0:
|
||||
; subs xzr, x0, #42
|
||||
; csel x0, x1, x2, eq
|
||||
; csdb
|
||||
; ret
|
||||
|
||||
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
|
||||
return v5
|
||||
}
|
||||
|
||||
; block0:
|
||||
; subs xzr, x0, #42
|
||||
; csel x0, x1, x2, eq
|
||||
; csdb
|
||||
; ret
|
||||
|
||||
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
|
||||
return v5
|
||||
}
|
||||
|
||||
; block0:
|
||||
; subs xzr, x0, #42
|
||||
; csel x0, x1, x2, eq
|
||||
; csdb
|
||||
; ret
|
||||
|
||||
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
|
||||
return v5
|
||||
}
|
||||
|
||||
; block0:
|
||||
; subs xzr, x0, #42
|
||||
; csel x0, x2, x4, eq
|
||||
; csel x1, x3, x5, eq
|
||||
; csdb
|
||||
; ret
|
||||
|
||||
function %f(i128, i8, i8) -> i8 {
|
||||
block0(v0: i128, v1: i8, v2: i8):
|
||||
v3 = iconst.i128 42
|
||||
v4 = ifcmp v0, v3
|
||||
v5 = selectif_spectre_guard.i8 eq v4, v1, v2
|
||||
return v5
|
||||
}
|
||||
|
||||
; block0:
|
||||
; movz x6, #42
|
||||
; movz x8, #0
|
||||
; subs xzr, x0, x6
|
||||
; ccmp x1, x8, #nzcv, eq
|
||||
; csel x0, x2, x3, eq
|
||||
; csdb
|
||||
; ret
|
||||
|
||||
function %f(i128, i16, i16) -> i16 {
|
||||
block0(v0: i128, v1: i16, v2: i16):
|
||||
v3 = iconst.i128 42
|
||||
v4 = ifcmp v0, v3
|
||||
v5 = selectif_spectre_guard.i16 eq v4, v1, v2
|
||||
return v5
|
||||
}
|
||||
|
||||
; block0:
|
||||
; movz x6, #42
|
||||
; movz x8, #0
|
||||
; subs xzr, x0, x6
|
||||
; ccmp x1, x8, #nzcv, eq
|
||||
; csel x0, x2, x3, eq
|
||||
; csdb
|
||||
; ret
|
||||
|
||||
function %f(i128, i32, i32) -> i32 {
|
||||
block0(v0: i128, v1: i32, v2: i32):
|
||||
v3 = iconst.i128 42
|
||||
v4 = ifcmp v0, v3
|
||||
v5 = selectif_spectre_guard.i32 eq v4, v1, v2
|
||||
return v5
|
||||
}
|
||||
|
||||
; block0:
|
||||
; movz x6, #42
|
||||
; movz x8, #0
|
||||
; subs xzr, x0, x6
|
||||
; ccmp x1, x8, #nzcv, eq
|
||||
; csel x0, x2, x3, eq
|
||||
; csdb
|
||||
; ret
|
||||
|
||||
function %f(i128, i64, i64) -> i64 {
|
||||
block0(v0: i128, v1: i64, v2: i64):
|
||||
v3 = iconst.i128 42
|
||||
v4 = ifcmp v0, v3
|
||||
v5 = selectif_spectre_guard.i64 eq v4, v1, v2
|
||||
return v5
|
||||
}
|
||||
|
||||
; block0:
|
||||
; movz x6, #42
|
||||
; movz x8, #0
|
||||
; subs xzr, x0, x6
|
||||
; ccmp x1, x8, #nzcv, eq
|
||||
; csel x0, x2, x3, eq
|
||||
; csdb
|
||||
; ret
|
||||
|
||||
function %f(i128, i128, i128) -> i128 {
|
||||
block0(v0: i128, v1: i128, v2: i128):
|
||||
v3 = iconst.i128 42
|
||||
v4 = ifcmp v0, v3
|
||||
v5 = selectif_spectre_guard.i128 eq v4, v1, v2
|
||||
return v5
|
||||
}
|
||||
|
||||
; block0:
|
||||
; movz x9, #42
|
||||
; movz x11, #0
|
||||
; subs xzr, x0, x9
|
||||
; ccmp x1, x11, #nzcv, eq
|
||||
; csel x0, x2, x4, eq
|
||||
; csel x1, x3, x5, eq
|
||||
; csdb
|
||||
; ret
|
||||
|
||||
function %g(i8) -> b1 {
|
||||
block0(v0: i8):
|
||||
v3 = iconst.i8 42
|
||||
@@ -25,8 +746,8 @@ block0(v0: i8):
|
||||
}
|
||||
|
||||
; block0:
|
||||
; uxtb w4, w0
|
||||
; subs wzr, w4, #42
|
||||
; uxtb w3, w0
|
||||
; subs wzr, w3, #42
|
||||
; cset x0, eq
|
||||
; ret
|
||||
|
||||
@@ -49,8 +770,8 @@ block0(v0: b1, v1: i8, v2: i8):
|
||||
}
|
||||
|
||||
; block0:
|
||||
; and w6, w0, #1
|
||||
; subs wzr, w6, wzr
|
||||
; and w5, w0, #1
|
||||
; subs wzr, w5, wzr
|
||||
; csel x0, x1, x2, ne
|
||||
; ret
|
||||
|
||||
@@ -74,8 +795,8 @@ block0(v0: b1, v1: i128, v2: i128):
|
||||
}
|
||||
|
||||
; block0:
|
||||
; and w10, w0, #1
|
||||
; subs wzr, w10, wzr
|
||||
; and w8, w0, #1
|
||||
; subs wzr, w8, wzr
|
||||
; csel x0, x2, x4, ne
|
||||
; csel x1, x3, x5, ne
|
||||
; ret
|
||||
|
||||
@@ -21,8 +21,8 @@ block0(v0: i64, v1: i32):
|
||||
; b.ls label1 ; b label2
|
||||
; block1:
|
||||
; add x11, x0, x1, UXTW
|
||||
; subs xzr, x9, x10
|
||||
; movz x12, #0
|
||||
; subs xzr, x9, x10
|
||||
; csel x0, x12, x11, hi
|
||||
; csdb
|
||||
; ret
|
||||
@@ -44,9 +44,9 @@ block0(v0: i64, v1: i32):
|
||||
; b.ls label1 ; b label2
|
||||
; block1:
|
||||
; add x9, x0, x1, UXTW
|
||||
; movz x8, #0
|
||||
; subs xzr, x7, #65536
|
||||
; movz x10, #0
|
||||
; csel x0, x10, x9, hi
|
||||
; csel x0, x8, x9, hi
|
||||
; csdb
|
||||
; ret
|
||||
; block2:
|
||||
|
||||
@@ -17,6 +17,7 @@ block0(v0: i64, v1: i64):
|
||||
}
|
||||
|
||||
; block0:
|
||||
; adds x3, x0, x1
|
||||
; b.hs 8 ; udf
|
||||
; ret
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
test interpret
|
||||
test run
|
||||
target aarch64
|
||||
target s390x
|
||||
target x86_64
|
||||
|
||||
|
||||
@@ -0,0 +1,316 @@
|
||||
;; the interpreter does not support `selectif_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 {
|
||||
block0(v0: i8, v1: i8, v2: i8):
|
||||
v3 = iconst.i8 42
|
||||
v4 = ifcmp v0, v3
|
||||
v5 = selectif_spectre_guard.i8 eq 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
|
||||
|
||||
function %selectif_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
|
||||
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
|
||||
|
||||
function %selectif_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
|
||||
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
|
||||
|
||||
function %selectif_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
|
||||
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
|
||||
|
||||
function %selectif_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
|
||||
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
|
||||
|
||||
function %selectif_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
|
||||
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
|
||||
|
||||
function %selectif_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
|
||||
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
|
||||
|
||||
function %selectif_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
|
||||
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
|
||||
|
||||
function %selectif_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
|
||||
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
|
||||
|
||||
function %selectif_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
|
||||
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
|
||||
|
||||
function %selectif_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
|
||||
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
|
||||
|
||||
function %selectif_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
|
||||
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
|
||||
|
||||
function %selectif_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
|
||||
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
|
||||
|
||||
function %selectif_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
|
||||
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
|
||||
|
||||
function %selectif_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
|
||||
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
|
||||
|
||||
function %selectif_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
|
||||
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
|
||||
|
||||
function %selectif_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
|
||||
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
|
||||
|
||||
function %selectif_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
|
||||
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
|
||||
|
||||
function %selectif_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
|
||||
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
|
||||
|
||||
function %selectif_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
|
||||
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
|
||||
|
||||
function %selectif_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
|
||||
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
|
||||
|
||||
function %selectif_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
|
||||
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
|
||||
|
||||
function %selectif_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
|
||||
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
|
||||
|
||||
function %selectif_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
|
||||
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
|
||||
|
||||
function %selectif_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
|
||||
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
|
||||
316
cranelift/filetests/filetests/runtests/selectif.clif
Normal file
316
cranelift/filetests/filetests/runtests/selectif.clif
Normal file
@@ -0,0 +1,316 @@
|
||||
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
|
||||
110
cranelift/filetests/filetests/runtests/trueif-ff.clif
Normal file
110
cranelift/filetests/filetests/runtests/trueif-ff.clif
Normal file
@@ -0,0 +1,110 @@
|
||||
test interpret
|
||||
test run
|
||||
target aarch64
|
||||
; `true{if,ff}` not implemented on x86_64, and panics on s390x.
|
||||
|
||||
function %trueif_i8_eq(i8, i8) -> b1 {
|
||||
block0(v0: i8, v1: i8):
|
||||
v2 = ifcmp v0, v1
|
||||
v3 = trueif eq v2
|
||||
return v3
|
||||
}
|
||||
|
||||
; run: %trueif_i8_eq(42, 42) == true
|
||||
; run: %trueif_i8_eq(-1, 255) == true
|
||||
; run: %trueif_i8_eq(255, 0) == false
|
||||
; run: %trueif_i8_eq(32, 64) == false
|
||||
|
||||
function %trueif_i16_eq(i16, i16) -> b1 {
|
||||
block0(v0: i16, v1: i16):
|
||||
v2 = ifcmp v0, v1
|
||||
v3 = trueif eq v2
|
||||
return v3
|
||||
}
|
||||
|
||||
; run: %trueif_i16_eq(42, 42) == true
|
||||
; run: %trueif_i16_eq(-1, 65535) == true
|
||||
; run: %trueif_i16_eq(65535, 0) == false
|
||||
; run: %trueif_i16_eq(32, 64) == false
|
||||
|
||||
function %trueif_i32_eq(i32, i32) -> b1 {
|
||||
block0(v0: i32, v1: i32):
|
||||
v2 = ifcmp v0, v1
|
||||
v3 = trueif eq v2
|
||||
return v3
|
||||
}
|
||||
|
||||
; run: %trueif_i32_eq(42, 42) == true
|
||||
; run: %trueif_i32_eq(-1, 4294967295) == true
|
||||
; run: %trueif_i32_eq(4294967295, 0) == false
|
||||
; run: %trueif_i32_eq(32, 64) == false
|
||||
|
||||
function %trueif_i64_eq(i64, i64) -> b1 {
|
||||
block0(v0: i64, v1: i64):
|
||||
v2 = ifcmp v0, v1
|
||||
v3 = trueif eq v2
|
||||
return v3
|
||||
}
|
||||
|
||||
; run: %trueif_i64_eq(42, 42) == true
|
||||
; run: %trueif_i64_eq(-1, 18446744073709551615) == true
|
||||
; run: %trueif_i64_eq(18446744073709551615, 0) == false
|
||||
; run: %trueif_i64_eq(32, 64) == false
|
||||
|
||||
function %trueif_i128_eq(i128, i128) -> b1 {
|
||||
block0(v0: i128, v1: i128):
|
||||
v2 = ifcmp v0, v1
|
||||
v3 = trueif eq v2
|
||||
return v3
|
||||
}
|
||||
|
||||
; run: %trueif_i128_eq(42, 42) == true
|
||||
; run: %trueif_i128_eq(-1, 18446744073709551615) == false
|
||||
; run: %trueif_i128_eq(19000000000000000000, 0) == false
|
||||
; run: %trueif_i128_eq(32, 64) == false
|
||||
|
||||
function %trueff_f32_eq(f32, f32) -> b1 {
|
||||
block0(v0: f32, v1: f32):
|
||||
v2 = ffcmp v0, v1
|
||||
v3 = trueff eq v2
|
||||
return v3
|
||||
}
|
||||
|
||||
; run: %trueff_f32_eq(0x42.0, 0x42.0) == true
|
||||
; run: %trueff_f32_eq(-0x1.0, -0x1.0) == true
|
||||
; run: %trueff_f32_eq(0x1.0, 0x0.0) == false
|
||||
|
||||
function %trueff_f64_eq(f64, f64) -> b1 {
|
||||
block0(v0: f64, v1: f64):
|
||||
v2 = ffcmp v0, v1
|
||||
v3 = trueff eq v2
|
||||
return v3
|
||||
}
|
||||
|
||||
; run: %trueff_f64_eq(0x42.0, 0x42.0) == true
|
||||
; run: %trueff_f64_eq(-0x1.0, -0x1.0) == true
|
||||
; run: %trueff_f64_eq(0x1.0, 0x0.0) == false
|
||||
|
||||
function %trueff_f32_ne(f32, f32) -> b1 {
|
||||
block0(v0: f32, v1: f32):
|
||||
v2 = ffcmp v0, v1
|
||||
v3 = trueff ne v2
|
||||
return v3
|
||||
}
|
||||
|
||||
; run: %trueff_f32_ne(0x42.0, 0x42.0) == false
|
||||
; run: %trueff_f32_ne(-0x1.0, -0x1.0) == false
|
||||
; run: %trueff_f32_ne(0x1.0, 0x0.0) == true
|
||||
; run: %trueff_f32_ne(NaN, NaN) == true
|
||||
|
||||
function %trueff_f64_ne(f64, f64) -> b1 {
|
||||
block0(v0: f64, v1: f64):
|
||||
v2 = ffcmp v0, v1
|
||||
v3 = trueff ne v2
|
||||
return v3
|
||||
}
|
||||
|
||||
; run: %trueff_f64_ne(0x42.0, 0x42.0) == false
|
||||
; run: %trueff_f64_ne(-0x1.0, -0x1.0) == false
|
||||
; run: %trueff_f64_ne(0x1.0, 0x0.0) == true
|
||||
; run: %trueff_f64_ne(NaN, NaN) == true
|
||||
@@ -942,15 +942,17 @@ 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, ctrl_ty)?,
|
||||
Value::bool(false, ctrl_ty)?,
|
||||
Value::bool(true, types::B1)?,
|
||||
Value::bool(false, types::B1)?,
|
||||
),
|
||||
Opcode::Trueff => choose(
|
||||
state.has_fflag(inst.fp_cond_code().unwrap()),
|
||||
Value::bool(true, ctrl_ty)?,
|
||||
Value::bool(false, ctrl_ty)?,
|
||||
Value::bool(true, types::B1)?,
|
||||
Value::bool(false, types::B1)?,
|
||||
),
|
||||
Opcode::Bitcast
|
||||
| Opcode::RawBitcast
|
||||
|
||||
Reference in New Issue
Block a user