Port icmp to ISLE (AArch64) (#4898)

* Port `icmp` to ISLE (AArch64)

Ported the existing implementation of `icmp` (and, by extension, the
`lower_icmp` function) to ISLE for AArch64.

Copyright (c) 2022 Arm Limited

* Allow 'producer chains', eliminating `Nop0`s

Copyright (c) 2022 Arm Limited
This commit is contained in:
Damian Heaton
2022-09-13 16:56:50 +01:00
committed by GitHub
parent c3f8415ac7
commit e9b08b856d
11 changed files with 310 additions and 54 deletions

View File

@@ -1960,6 +1960,12 @@
(MInst.AluRRImm12 (ALUOp.AddS) size (writable_zero_reg)
src1 src2)))
(decl cmp (OperandSize Reg Reg) ProducesFlags)
(rule (cmp size src1 src2)
(ProducesFlags.ProducesFlagsSideEffect
(MInst.AluRRR (ALUOp.SubS) size (writable_zero_reg)
src1 src2)))
(decl cmp_imm (OperandSize Reg Imm12) ProducesFlags)
(rule (cmp_imm size src1 src2)
(ProducesFlags.ProducesFlagsSideEffect
@@ -1970,6 +1976,12 @@
(rule (cmp64_imm src1 src2)
(cmp_imm (OperandSize.Size64) src1 src2))
(decl cmp_extend (OperandSize Reg Reg ExtendOp) ProducesFlags)
(rule (cmp_extend size src1 src2 extend)
(ProducesFlags.ProducesFlagsSideEffect
(MInst.AluRRRExtend (ALUOp.SubS) size (writable_zero_reg)
src1 src2 extend)))
;; Helper for emitting `sbc` instructions.
(decl sbc_paired (Type Reg Reg) ConsumesFlags)
(rule (sbc_paired ty src1 src2)
@@ -2199,6 +2211,13 @@
(MInst.CSNeg dst cond if_true if_false)
dst)))
;; Helper for generating `MInst.CCmp` instructions.
;; Creates a new `ProducesFlags` from the supplied `ProducesFlags` followed
;; immediately by the `MInst.CCmp` instruction.
(decl ccmp (OperandSize Reg Reg NZCV Cond ProducesFlags) ProducesFlags)
(rule (ccmp size rn rm nzcv cond inst_input)
(produces_flags_append inst_input (MInst.CCmp size rn rm nzcv cond)))
;; Helper for generating `MInst.CCmpImm` instructions.
(decl ccmp_imm (OperandSize u8 Reg UImm5 NZCV Cond) ConsumesFlags)
(rule (ccmp_imm size 1 rn imm nzcv cond)
@@ -2845,6 +2864,11 @@
;; TODO: Port lower_fp_condcode() to ISLE.
(extern constructor fp_cond_code fp_cond_code)
;; Lower an integer cond code.
(decl cond_code (IntCC) Cond)
;; TODO: Port lower_condcode() to ISLE.
(extern constructor cond_code cond_code)
;; Generate comparison to zero operator from input condition code
(decl float_cc_cmp_zero_to_vec_misc_op (FloatCC) VecMisc2)
(extern constructor float_cc_cmp_zero_to_vec_misc_op float_cc_cmp_zero_to_vec_misc_op)
@@ -3280,3 +3304,169 @@
(let ((dst WritableReg (temp_writable_reg $I64))
(_ Unit (emit (MInst.ElfTlsGetAddr name dst))))
dst))
;; Helpers for lowering `icmp` sequences.
;; `lower_icmp` contains shared functionality for lowering `icmp`
;; sequences, which `lower_icmp_into_{reg,flags}` extend from.
(decl lower_icmp (IntCC Value Value Type) ProducesFlags)
(decl lower_icmp_into_reg (IntCC Value Value Type Type) ValueRegs)
(decl lower_icmp_into_flags (IntCC Value Value Type) ProducesFlags)
;; For most cases, `lower_icmp_into_flags` is the same as `lower_icmp`,
;; except for some I128 cases (see below).
(rule -1 (lower_icmp_into_flags cond x y ty) (lower_icmp cond x y ty))
;; Vectors.
;; `icmp` into flags for vectors is invalid.
(rule (lower_icmp_into_reg cond x y in_ty @ (multi_lane _ _) _out_ty)
(let ((cond Cond (cond_code cond))
(rn Reg (put_in_reg x))
(rm Reg (put_in_reg y)))
(vec_cmp rn rm in_ty cond)))
;; Determines the appropriate extend op given the value type and whether it is signed.
(decl lower_icmp_extend (Type bool) ExtendOp)
(rule (lower_icmp_extend $I8 $true) (ExtendOp.SXTB))
(rule (lower_icmp_extend $I16 $true) (ExtendOp.SXTH))
(rule (lower_icmp_extend $I8 $false) (ExtendOp.UXTB))
(rule (lower_icmp_extend $I16 $false) (ExtendOp.UXTH))
;; Integers <= 64-bits.
(rule (lower_icmp_into_reg cond rn rm in_ty out_ty)
(if (ty_int_bool_ref_scalar_64 in_ty))
(let ((cc Cond (cond_code cond)))
(with_flags
(lower_icmp cond rn rm in_ty)
(materialize_bool_result (ty_bits out_ty) cc))))
(rule 1 (lower_icmp cond rn rm (fits_in_16 ty))
(if (signed_cond_code cond))
(let ((rn Reg (put_in_reg_sext32 rn)))
(cmp_extend (operand_size ty) rn rm (lower_icmp_extend ty $true))))
(rule (lower_icmp cond rn (imm12_from_value rm) (fits_in_16 ty))
(let ((rn Reg (put_in_reg_zext32 rn)))
(cmp_imm (operand_size ty) rn rm)))
(rule -1 (lower_icmp cond rn rm (fits_in_16 ty))
(let ((rn Reg (put_in_reg_zext32 rn)))
(cmp_extend (operand_size ty) rn rm (lower_icmp_extend ty $false))))
(rule -2 (lower_icmp cond rn (imm12_from_value rm) ty)
(if (ty_int_bool_ref_scalar_64 ty))
(cmp_imm (operand_size ty) rn rm))
(rule -3 (lower_icmp cond rn rm ty)
(if (ty_int_bool_ref_scalar_64 ty))
(cmp (operand_size ty) rn rm))
;; 128-bit integers.
(rule (lower_icmp_into_reg cond @ (IntCC.Equal) rn rm $I128 out_ty)
(let ((cc Cond (cond_code cond)))
(with_flags
(lower_icmp cond rn rm $I128)
(materialize_bool_result (ty_bits out_ty) cc))))
(rule (lower_icmp_into_reg cond @ (IntCC.NotEqual) rn rm $I128 out_ty)
(let ((cc Cond (cond_code cond)))
(with_flags
(lower_icmp cond rn rm $I128)
(materialize_bool_result (ty_bits out_ty) cc))))
;; cmp lhs_lo, rhs_lo
;; 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))
(lhs_hi Reg (value_regs_get lhs 1))
(rhs_lo Reg (value_regs_get rhs 0))
(rhs_hi Reg (value_regs_get rhs 1))
(cmp_inst ProducesFlags (cmp (OperandSize.Size64) lhs_lo rhs_lo)))
(ccmp (OperandSize.Size64) lhs_hi rhs_hi
(nzcv $false $false $false $false) (Cond.Eq) cmp_inst)))
(rule (lower_icmp (IntCC.Equal) lhs rhs $I128)
(lower_icmp_i128_eq_ne lhs rhs))
(rule (lower_icmp (IntCC.NotEqual) lhs rhs $I128)
(lower_icmp_i128_eq_ne lhs rhs))
;; cmp lhs_lo, rhs_lo
;; cset tmp1, unsigned_cond
;; cmp lhs_hi, rhs_hi
;; cset tmp2, cond
;; csel dst, tmp1, tmp2, eq
(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_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))
(tmp1 ValueRegs
(with_flags (cmp (OperandSize.Size64) lhs_lo rhs_lo)
(materialize_bool_result
(ty_bits out_ty) unsigned_cond)))
(tmp1 Reg (value_regs_get tmp1 0))
(dst ValueRegs
(with_flags (cmp (OperandSize.Size64) lhs_hi rhs_hi)
(lower_icmp_i128_consumer cond (ty_bits out_ty)
tmp1 lhs_hi rhs_hi))))
dst))
(decl lower_icmp_i128_consumer (Cond u8 Reg Reg Reg) ConsumesFlags)
(rule (lower_icmp_i128_consumer cond 1 tmp1 lhs_hi rhs_hi)
(let ((tmp2 WritableReg (temp_writable_reg $I64))
(dst WritableReg (temp_writable_reg $I64)))
(ConsumesFlags.ConsumesFlagsTwiceReturnsValueRegs
(MInst.CSet tmp2 cond)
(MInst.CSel dst (Cond.Eq) tmp1 tmp2)
(value_reg dst))))
(rule (lower_icmp_i128_consumer cond 128 tmp1 lhs_hi rhs_hi)
(let ((tmp2 WritableReg (temp_writable_reg $I64))
(dst WritableReg (temp_writable_reg $I64)))
(ConsumesFlags.ConsumesFlagsTwiceReturnsValueRegs
(MInst.CSetm tmp2 cond)
(MInst.CSel dst (Cond.Eq) tmp1 tmp2)
(value_regs dst dst))))
(rule -1 (lower_icmp_i128_consumer cond _out_ty_bits tmp1 lhs_hi rhs_hi)
(let ((tmp2 WritableReg (temp_writable_reg $I64))
(dst WritableReg (temp_writable_reg $I64)))
(ConsumesFlags.ConsumesFlagsTwiceReturnsValueRegs
(MInst.CSetm tmp2 cond)
(MInst.CSel dst (Cond.Eq) tmp1 tmp2)
(value_reg dst))))
;; Exceptional `lower_icmp_into_flags` rules.
;; We need to guarantee that the flags for `cond` are correct, so we
;; compare `dst` with 1.
(rule (lower_icmp_into_flags cond @ (IntCC.SignedGreaterThanOrEqual) lhs rhs $I128)
(let ((dst ValueRegs (lower_icmp_into_reg cond lhs rhs $I128 $B1))
(dst Reg (value_regs_get dst 0))
(tmp Reg (imm $I64 (ImmExtend.Sign) 1))) ;; mov tmp, #1
(cmp (OperandSize.Size64) dst tmp)))
(rule (lower_icmp_into_flags cond @ (IntCC.UnsignedGreaterThanOrEqual) lhs rhs $I128)
(let ((dst ValueRegs (lower_icmp_into_reg cond lhs rhs $I128 $B1))
(dst Reg (value_regs_get dst 0))
(tmp Reg (imm $I64 (ImmExtend.Zero) 1)))
(cmp (OperandSize.Size64) dst tmp)))
(rule (lower_icmp_into_flags cond @ (IntCC.SignedLessThanOrEqual) lhs rhs $I128)
(let ((dst ValueRegs (lower_icmp_into_reg cond lhs rhs $I128 $B1))
(dst Reg (value_regs_get dst 0))
(tmp Reg (imm $I64 (ImmExtend.Sign) 1)))
(cmp (OperandSize.Size64) tmp dst)))
(rule (lower_icmp_into_flags cond @ (IntCC.UnsignedLessThanOrEqual) lhs rhs $I128)
(let ((dst ValueRegs (lower_icmp_into_reg cond lhs rhs $I128 $B1))
(dst Reg (value_regs_get dst 0))
(tmp Reg (imm $I64 (ImmExtend.Zero) 1)))
(cmp (OperandSize.Size64) tmp dst)))
;; For strict comparisons, we compare with 0.
(rule (lower_icmp_into_flags cond @ (IntCC.SignedGreaterThan) lhs rhs $I128)
(let ((dst ValueRegs (lower_icmp_into_reg cond lhs rhs $I128 $B1))
(dst Reg (value_regs_get dst 0)))
(cmp (OperandSize.Size64) dst (zero_reg))))
(rule (lower_icmp_into_flags cond @ (IntCC.UnsignedGreaterThan) lhs rhs $I128)
(let ((dst ValueRegs (lower_icmp_into_reg cond lhs rhs $I128 $B1))
(dst Reg (value_regs_get dst 0)))
(cmp (OperandSize.Size64) dst (zero_reg))))
(rule (lower_icmp_into_flags cond @ (IntCC.SignedLessThan) lhs rhs $I128)
(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)))
(rule (lower_icmp_into_flags cond @ (IntCC.UnsignedLessThan) lhs rhs $I128)
(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)))

View File

@@ -1730,6 +1730,9 @@
(vec_size VectorSize (vector_size ty)))
(value_reg (int_cmp_zero_swap cond rn vec_size))))
(rule -1 (lower (has_type out_ty (icmp cond x @ (value_type in_ty) y)))
(lower_icmp_into_reg cond x y in_ty out_ty))
;;;; Rules for `trap` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(rule (lower (trap trap_code))

View File

@@ -6,10 +6,10 @@ use generated_code::Context;
// Types that the generated ISLE code uses via `use super::*`.
use super::{
fp_reg, lower_constant_f128, lower_constant_f32, lower_constant_f64, lower_fp_condcode,
stack_reg, writable_link_reg, writable_zero_reg, zero_reg, AMode, ASIMDFPModImm,
ASIMDMovModImm, BranchTarget, CallIndInfo, CallInfo, Cond, CondBrKind, ExtendOp, FPUOpRI,
FPUOpRIMod, FloatCC, Imm12, ImmLogic, ImmShift, Inst as MInst, IntCC, JTSequenceInfo,
fp_reg, lower_condcode, lower_constant_f128, lower_constant_f32, lower_constant_f64,
lower_fp_condcode, stack_reg, writable_link_reg, writable_zero_reg, zero_reg, AMode,
ASIMDFPModImm, ASIMDMovModImm, BranchTarget, CallIndInfo, CallInfo, Cond, CondBrKind, ExtendOp,
FPUOpRI, FPUOpRIMod, FloatCC, Imm12, ImmLogic, ImmShift, Inst as MInst, IntCC, JTSequenceInfo,
MachLabel, MemLabel, MoveWideConst, MoveWideOp, NarrowValueMode, Opcode, OperandSize,
PairAMode, Reg, SImm9, ScalarSize, ShiftOpAndAmt, UImm12Scaled, UImm5, VecMisc2, VectorSize,
NZCV,
@@ -517,6 +517,10 @@ impl Context for IsleContext<'_, '_, MInst, Flags, IsaFlags, 6> {
lower_fp_condcode(*cc)
}
fn cond_code(&mut self, cc: &condcodes::IntCC) -> Cond {
lower_condcode(*cc)
}
fn preg_sp(&mut self) -> PReg {
super::regs::stack_reg().to_real_reg().unwrap().into()
}

View File

@@ -293,11 +293,7 @@ pub(crate) fn lower_insn_to_regs(
panic!("Should never reach ifcmp as isel root!");
}
Opcode::Icmp => {
let condcode = ctx.data(insn).cond_code().unwrap();
let rd = get_output_reg(ctx, outputs[0]).only_reg().unwrap();
lower_icmp(ctx, insn, condcode, IcmpOutput::Register(rd))?;
}
Opcode::Icmp => implemented_in_isle(ctx),
Opcode::Fcmp => implemented_in_isle(ctx),

View File

@@ -1362,12 +1362,6 @@
(decl intcc_without_eq (IntCC) IntCC)
(extern constructor intcc_without_eq intcc_without_eq)
;; This is a direct import of `IntCC::unsigned`.
;; Get the corresponding IntCC with the signed component removed.
;; For conditions without a signed component, this is a no-op.
(decl intcc_unsigned (IntCC) IntCC)
(extern constructor intcc_unsigned intcc_unsigned)
;;;; Helpers for Getting Particular Physical Registers ;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; These should only be used for legalization purposes, when we can't otherwise

View File

@@ -596,11 +596,6 @@ impl Context for IsleContext<'_, '_, MInst, Flags, IsaFlags, 6> {
x.without_equal()
}
#[inline]
fn intcc_unsigned(&mut self, x: &IntCC) -> IntCC {
x.unsigned()
}
#[inline]
fn intcc_to_cc(&mut self, intcc: &IntCC) -> CC {
CC::from_intcc(*intcc)

View File

@@ -8,8 +8,8 @@ use target_lexicon::Triple;
pub use super::MachLabel;
pub use crate::ir::{
dynamic_to_fixed, ArgumentExtension, Constant, DynamicStackSlot, ExternalName, FuncRef,
GlobalValue, Immediate, SigRef, StackSlot,
condcodes, dynamic_to_fixed, ArgumentExtension, Constant, DynamicStackSlot, ExternalName,
FuncRef, GlobalValue, Immediate, SigRef, StackSlot,
};
pub use crate::isa::unwind::UnwindInst;
pub use crate::machinst::{
@@ -1087,6 +1087,27 @@ macro_rules! isle_prelude_methods {
fn gen_move(&mut self, ty: Type, dst: WritableReg, src: Reg) -> MInst {
MInst::gen_move(dst, src, ty)
}
#[inline]
fn intcc_unsigned(&mut self, x: &IntCC) -> IntCC {
x.unsigned()
}
#[inline]
fn signed_cond_code(&mut self, cc: &condcodes::IntCC) -> Option<condcodes::IntCC> {
match cc {
IntCC::Equal
| IntCC::UnsignedGreaterThanOrEqual
| IntCC::UnsignedGreaterThan
| IntCC::UnsignedLessThanOrEqual
| IntCC::UnsignedLessThan
| IntCC::NotEqual => None,
IntCC::SignedGreaterThanOrEqual
| IntCC::SignedGreaterThan
| IntCC::SignedLessThanOrEqual
| IntCC::SignedLessThan => Some(*cc),
}
}
};
}

View File

@@ -571,6 +571,16 @@
(decl pure is_sinkable_inst (Value) Inst)
(extern constructor is_sinkable_inst is_sinkable_inst)
;; This is a direct import of `IntCC::unsigned`.
;; Get the corresponding IntCC with the signed component removed.
;; For conditions without a signed component, this is a no-op.
(decl intcc_unsigned (IntCC) IntCC)
(extern constructor intcc_unsigned intcc_unsigned)
;; Pure constructor that only matches signed integer cond codes.
(decl pure signed_cond_code (IntCC) IntCC)
(extern constructor signed_cond_code signed_cond_code)
;; Instruction creation helpers ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Emit an instruction.
@@ -657,11 +667,17 @@
;; them.
(AlreadyExistingFlags)
(ProducesFlagsSideEffect (inst MInst))
(ProducesFlagsTwiceSideEffect (inst1 MInst) (inst2 MInst))
;; Not directly combinable with a ConsumesFlags;
;; used in s390x and unwrapped directly by `trapif`.
(ProducesFlagsReturnsReg (inst MInst) (result Reg))
(ProducesFlagsReturnsResultWithConsumer (inst MInst) (result Reg))))
;; Chain another producer to a `ProducesFlags`.
(decl produces_flags_append (ProducesFlags MInst) ProducesFlags)
(rule (produces_flags_append (ProducesFlags.ProducesFlagsSideEffect inst1) inst2)
(ProducesFlags.ProducesFlagsTwiceSideEffect inst1 inst2))
;; Newtype wrapper around `MInst` for instructions that consume flags.
;;
;; Variant determines how result is given when combined with a
@@ -761,6 +777,43 @@
(_v Unit (emit consumer_inst_4)))
consumer_result))
(rule (with_flags (ProducesFlags.ProducesFlagsTwiceSideEffect producer_inst1 producer_inst2)
(ConsumesFlags.ConsumesFlagsReturnsReg consumer_inst consumer_result))
(let ((_ Unit (emit producer_inst1))
(_ Unit (emit producer_inst2))
(_ Unit (emit consumer_inst)))
(value_reg consumer_result)))
(rule (with_flags (ProducesFlags.ProducesFlagsTwiceSideEffect producer_inst1 producer_inst2)
(ConsumesFlags.ConsumesFlagsTwiceReturnsValueRegs consumer_inst_1
consumer_inst_2
consumer_result))
;; We must emit these instructions in order as the creator of
;; the ConsumesFlags may be relying on dataflow dependencies
;; amongst them.
(let ((_ Unit (emit producer_inst1))
(_ Unit (emit producer_inst2))
(_ Unit (emit consumer_inst_1))
(_ Unit (emit consumer_inst_2)))
consumer_result))
(rule (with_flags (ProducesFlags.ProducesFlagsTwiceSideEffect producer_inst1 producer_inst2)
(ConsumesFlags.ConsumesFlagsFourTimesReturnsValueRegs consumer_inst_1
consumer_inst_2
consumer_inst_3
consumer_inst_4
consumer_result))
;; We must emit these instructions in order as the creator of
;; the ConsumesFlags may be relying on dataflow dependencies
;; amongst them.
(let ((_ Unit (emit producer_inst1))
(_ Unit (emit producer_inst2))
(_ Unit (emit consumer_inst_1))
(_ Unit (emit consumer_inst_2))
(_ Unit (emit consumer_inst_3))
(_ Unit (emit consumer_inst_4)))
consumer_result))
(decl with_flags_reg (ProducesFlags ConsumesFlags) Reg)
(rule (with_flags_reg p c)
(let ((v ValueRegs (with_flags p c)))

View File

@@ -45,10 +45,10 @@ block0(v0: i128, v1: i128):
; block0:
; subs xzr, x0, x2
; cset x8, lo
; cset x7, lo
; subs xzr, x1, x3
; cset x11, lt
; csel x0, x8, x11, eq
; cset x10, lt
; csel x0, x7, x10, eq
; ret
function %icmp_ult_i128(i128, i128) -> b1 {
@@ -59,10 +59,10 @@ block0(v0: i128, v1: i128):
; block0:
; subs xzr, x0, x2
; cset x8, lo
; cset x7, lo
; subs xzr, x1, x3
; cset x11, lo
; csel x0, x8, x11, eq
; cset x10, lo
; csel x0, x7, x10, eq
; ret
function %icmp_sle_i128(i128, i128) -> b1 {
@@ -73,10 +73,10 @@ block0(v0: i128, v1: i128):
; block0:
; subs xzr, x0, x2
; cset x8, ls
; cset x7, ls
; subs xzr, x1, x3
; cset x11, le
; csel x0, x8, x11, eq
; cset x10, le
; csel x0, x7, x10, eq
; ret
function %icmp_ule_i128(i128, i128) -> b1 {
@@ -87,10 +87,10 @@ block0(v0: i128, v1: i128):
; block0:
; subs xzr, x0, x2
; cset x8, ls
; cset x7, ls
; subs xzr, x1, x3
; cset x11, ls
; csel x0, x8, x11, eq
; cset x10, ls
; csel x0, x7, x10, eq
; ret
function %icmp_sgt_i128(i128, i128) -> b1 {
@@ -101,10 +101,10 @@ block0(v0: i128, v1: i128):
; block0:
; subs xzr, x0, x2
; cset x8, hi
; cset x7, hi
; subs xzr, x1, x3
; cset x11, gt
; csel x0, x8, x11, eq
; cset x10, gt
; csel x0, x7, x10, eq
; ret
function %icmp_ugt_i128(i128, i128) -> b1 {
@@ -115,10 +115,10 @@ block0(v0: i128, v1: i128):
; block0:
; subs xzr, x0, x2
; cset x8, hi
; cset x7, hi
; subs xzr, x1, x3
; cset x11, hi
; csel x0, x8, x11, eq
; cset x10, hi
; csel x0, x7, x10, eq
; ret
function %icmp_sge_i128(i128, i128) -> b1 {
@@ -129,10 +129,10 @@ block0(v0: i128, v1: i128):
; block0:
; subs xzr, x0, x2
; cset x8, hs
; cset x7, hs
; subs xzr, x1, x3
; cset x11, ge
; csel x0, x8, x11, eq
; cset x10, ge
; csel x0, x7, x10, eq
; ret
function %icmp_uge_i128(i128, i128) -> b1 {
@@ -143,10 +143,10 @@ block0(v0: i128, v1: i128):
; block0:
; subs xzr, x0, x2
; cset x8, hs
; cset x7, hs
; subs xzr, x1, x3
; cset x11, hs
; csel x0, x8, x11, eq
; cset x10, hs
; csel x0, x7, x10, eq
; ret
function %f(i64, i64) -> i64 {

View File

@@ -15,11 +15,11 @@ block0:
}
; block0:
; movz x3, #56780
; uxth w5, w3
; movz x7, #56780
; subs wzr, w5, w7, UXTH
; cset x4, ne
; and w0, w4, #1
; movz x2, #56780
; uxth w4, w2
; movz x6, #56780
; subs wzr, w4, w6, UXTH
; cset x9, ne
; and w0, w9, #1
; ret

View File

@@ -9,8 +9,8 @@ block0(v0: i32x4, v1: i32x4):
}
; block0:
; cmeq v0.4s, v0.4s, v1.4s
; mvn v0.16b, v0.16b
; cmeq v4.4s, v0.4s, v1.4s
; mvn v0.16b, v4.16b
; ret
function %icmp_ugt_i32x4(i32x4, i32x4) -> b32x4 {