aarch64: Implement lowering i128 icmp instructions
We have 3 different aproaches depending on the type of comparision requested: * For eq/ne we compare the high bits and low bits and check if they are equal * For overflow checks, we perform a i128 add and check the resulting overflow flag * For the remaining comparisions (gt/lt/sgt/etc...) We compare both the low bits and high bits, and if the high bits are equal we return the result of the unsigned comparision on the low bits As with other i128 ops, we are still missing immlogic support.
This commit is contained in:
@@ -1,7 +1,7 @@
|
|||||||
//! Lower a single Cranelift instruction into vcode.
|
//! Lower a single Cranelift instruction into vcode.
|
||||||
|
|
||||||
use crate::binemit::CodeOffset;
|
use crate::binemit::CodeOffset;
|
||||||
use crate::ir::condcodes::FloatCC;
|
use crate::ir::condcodes::{FloatCC, IntCC};
|
||||||
use crate::ir::types::*;
|
use crate::ir::types::*;
|
||||||
use crate::ir::Inst as IRInst;
|
use crate::ir::Inst as IRInst;
|
||||||
use crate::ir::{InstructionData, Opcode, TrapCode};
|
use crate::ir::{InstructionData, Opcode, TrapCode};
|
||||||
@@ -1673,14 +1673,112 @@ pub(crate) fn lower_insn_to_regs<C: LowerCtx<I = Inst>>(
|
|||||||
(false, true) => NarrowValueMode::SignExtend64,
|
(false, true) => NarrowValueMode::SignExtend64,
|
||||||
(false, false) => NarrowValueMode::ZeroExtend64,
|
(false, false) => NarrowValueMode::ZeroExtend64,
|
||||||
};
|
};
|
||||||
let rn = put_input_in_reg(ctx, inputs[0], narrow_mode);
|
|
||||||
|
|
||||||
if !ty.is_vector() {
|
if ty == I128 {
|
||||||
|
let lhs = put_input_in_regs(ctx, inputs[0]);
|
||||||
|
let rhs = put_input_in_regs(ctx, inputs[1]);
|
||||||
|
|
||||||
|
let tmp1 = ctx.alloc_tmp(I64).only_reg().unwrap();
|
||||||
|
let tmp2 = ctx.alloc_tmp(I64).only_reg().unwrap();
|
||||||
|
|
||||||
|
match condcode {
|
||||||
|
IntCC::Equal | IntCC::NotEqual => {
|
||||||
|
// eor tmp1, lhs_lo, rhs_lo
|
||||||
|
// eor tmp2, lhs_hi, rhs_hi
|
||||||
|
// adds xzr, tmp1, tmp2
|
||||||
|
// cset dst, {eq, ne}
|
||||||
|
|
||||||
|
ctx.emit(Inst::AluRRR {
|
||||||
|
alu_op: ALUOp::Eor64,
|
||||||
|
rd: tmp1,
|
||||||
|
rn: lhs.regs()[0],
|
||||||
|
rm: rhs.regs()[0],
|
||||||
|
});
|
||||||
|
ctx.emit(Inst::AluRRR {
|
||||||
|
alu_op: ALUOp::Eor64,
|
||||||
|
rd: tmp2,
|
||||||
|
rn: lhs.regs()[1],
|
||||||
|
rm: rhs.regs()[1],
|
||||||
|
});
|
||||||
|
ctx.emit(Inst::AluRRR {
|
||||||
|
alu_op: ALUOp::AddS64,
|
||||||
|
rd: writable_zero_reg(),
|
||||||
|
rn: tmp1.to_reg(),
|
||||||
|
rm: tmp2.to_reg(),
|
||||||
|
});
|
||||||
|
materialize_bool_result(ctx, insn, rd, cond);
|
||||||
|
}
|
||||||
|
IntCC::Overflow | IntCC::NotOverflow => {
|
||||||
|
// We can do an 128bit add while throwing away the results
|
||||||
|
// and check the overflow flags at the end.
|
||||||
|
//
|
||||||
|
// adds xzr, lhs_lo, rhs_lo
|
||||||
|
// adcs xzr, lhs_hi, rhs_hi
|
||||||
|
// cset dst, {vs, vc}
|
||||||
|
|
||||||
|
ctx.emit(Inst::AluRRR {
|
||||||
|
alu_op: ALUOp::AddS64,
|
||||||
|
rd: writable_zero_reg(),
|
||||||
|
rn: lhs.regs()[0],
|
||||||
|
rm: rhs.regs()[0],
|
||||||
|
});
|
||||||
|
ctx.emit(Inst::AluRRR {
|
||||||
|
alu_op: ALUOp::AdcS64,
|
||||||
|
rd: writable_zero_reg(),
|
||||||
|
rn: lhs.regs()[1],
|
||||||
|
rm: rhs.regs()[1],
|
||||||
|
});
|
||||||
|
materialize_bool_result(ctx, insn, rd, cond);
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
// cmp lhs_lo, rhs_lo
|
||||||
|
// cset tmp1, low_cc
|
||||||
|
// cmp lhs_hi, rhs_hi
|
||||||
|
// cset tmp2, cond
|
||||||
|
// csel dst, tmp1, tmp2, eq
|
||||||
|
|
||||||
|
let low_cc = match condcode {
|
||||||
|
IntCC::SignedGreaterThanOrEqual | IntCC::UnsignedGreaterThanOrEqual => {
|
||||||
|
Cond::Hs
|
||||||
|
}
|
||||||
|
IntCC::SignedGreaterThan | IntCC::UnsignedGreaterThan => Cond::Hi,
|
||||||
|
IntCC::SignedLessThanOrEqual | IntCC::UnsignedLessThanOrEqual => {
|
||||||
|
Cond::Ls
|
||||||
|
}
|
||||||
|
IntCC::SignedLessThan | IntCC::UnsignedLessThan => Cond::Lo,
|
||||||
|
_ => unreachable!(),
|
||||||
|
};
|
||||||
|
|
||||||
|
ctx.emit(Inst::AluRRR {
|
||||||
|
alu_op: ALUOp::SubS64,
|
||||||
|
rd: writable_zero_reg(),
|
||||||
|
rn: lhs.regs()[0],
|
||||||
|
rm: rhs.regs()[0],
|
||||||
|
});
|
||||||
|
materialize_bool_result(ctx, insn, tmp1, low_cc);
|
||||||
|
ctx.emit(Inst::AluRRR {
|
||||||
|
alu_op: ALUOp::SubS64,
|
||||||
|
rd: writable_zero_reg(),
|
||||||
|
rn: lhs.regs()[1],
|
||||||
|
rm: rhs.regs()[1],
|
||||||
|
});
|
||||||
|
materialize_bool_result(ctx, insn, tmp2, cond);
|
||||||
|
ctx.emit(Inst::CSel {
|
||||||
|
cond: Cond::Eq,
|
||||||
|
rd,
|
||||||
|
rn: tmp1.to_reg(),
|
||||||
|
rm: tmp2.to_reg(),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if !ty.is_vector() {
|
||||||
let alu_op = choose_32_64(ty, ALUOp::SubS32, ALUOp::SubS64);
|
let alu_op = choose_32_64(ty, ALUOp::SubS32, ALUOp::SubS64);
|
||||||
|
let rn = put_input_in_reg(ctx, inputs[0], narrow_mode);
|
||||||
let rm = put_input_in_rse_imm12(ctx, inputs[1], narrow_mode);
|
let rm = put_input_in_rse_imm12(ctx, inputs[1], narrow_mode);
|
||||||
ctx.emit(alu_inst_imm12(alu_op, writable_zero_reg(), rn, rm));
|
ctx.emit(alu_inst_imm12(alu_op, writable_zero_reg(), rn, rm));
|
||||||
materialize_bool_result(ctx, insn, rd, cond);
|
materialize_bool_result(ctx, insn, rd, cond);
|
||||||
} else {
|
} else {
|
||||||
|
let rn = put_input_in_reg(ctx, inputs[0], narrow_mode);
|
||||||
let rm = put_input_in_reg(ctx, inputs[1], narrow_mode);
|
let rm = put_input_in_reg(ctx, inputs[1], narrow_mode);
|
||||||
lower_vector_compare(ctx, rd, rn, rm, ty, cond)?;
|
lower_vector_compare(ctx, rd, rn, rm, ty, cond)?;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,6 +15,197 @@ block0(v0: i64, v1: i64):
|
|||||||
; nextln: ldp fp, lr, [sp], #16
|
; nextln: ldp fp, lr, [sp], #16
|
||||||
; nextln: ret
|
; nextln: ret
|
||||||
|
|
||||||
|
function %icmp_eq_i128(i128, i128) -> b1 {
|
||||||
|
block0(v0: i128, v1: i128):
|
||||||
|
v2 = icmp eq v0, v1
|
||||||
|
return v2
|
||||||
|
}
|
||||||
|
|
||||||
|
; check: stp fp, lr, [sp, #-16]!
|
||||||
|
; nextln: mov fp, sp
|
||||||
|
; nextln: eor x0, x0, x2
|
||||||
|
; nextln: eor x1, x1, x3
|
||||||
|
; nextln: adds xzr, x0, x1
|
||||||
|
; nextln: cset x0, eq
|
||||||
|
; nextln: ldp fp, lr, [sp], #16
|
||||||
|
; nextln: ret
|
||||||
|
|
||||||
|
|
||||||
|
function %icmp_ne_i128(i128, i128) -> b1 {
|
||||||
|
block0(v0: i128, v1: i128):
|
||||||
|
v2 = icmp ne v0, v1
|
||||||
|
return v2
|
||||||
|
}
|
||||||
|
|
||||||
|
; check: stp fp, lr, [sp, #-16]!
|
||||||
|
; nextln: mov fp, sp
|
||||||
|
; nextln: eor x0, x0, x2
|
||||||
|
; nextln: eor x1, x1, x3
|
||||||
|
; nextln: adds xzr, x0, x1
|
||||||
|
; nextln: cset x0, ne
|
||||||
|
; nextln: ldp fp, lr, [sp], #16
|
||||||
|
; nextln: ret
|
||||||
|
|
||||||
|
|
||||||
|
function %icmp_slt_i128(i128, i128) -> b1 {
|
||||||
|
block0(v0: i128, v1: i128):
|
||||||
|
v2 = icmp slt v0, v1
|
||||||
|
return v2
|
||||||
|
}
|
||||||
|
|
||||||
|
; check: stp fp, lr, [sp, #-16]!
|
||||||
|
; nextln: mov fp, sp
|
||||||
|
; nextln: subs xzr, x0, x2
|
||||||
|
; nextln: cset x0, lo
|
||||||
|
; nextln: subs xzr, x1, x3
|
||||||
|
; nextln: cset x1, lt
|
||||||
|
; nextln: csel x0, x0, x1, eq
|
||||||
|
; nextln: ldp fp, lr, [sp], #16
|
||||||
|
; nextln: ret
|
||||||
|
|
||||||
|
|
||||||
|
function %icmp_ult_i128(i128, i128) -> b1 {
|
||||||
|
block0(v0: i128, v1: i128):
|
||||||
|
v2 = icmp ult v0, v1
|
||||||
|
return v2
|
||||||
|
}
|
||||||
|
|
||||||
|
; check: stp fp, lr, [sp, #-16]!
|
||||||
|
; nextln: mov fp, sp
|
||||||
|
; nextln: subs xzr, x0, x2
|
||||||
|
; nextln: cset x0, lo
|
||||||
|
; nextln: subs xzr, x1, x3
|
||||||
|
; nextln: cset x1, lo
|
||||||
|
; nextln: csel x0, x0, x1, eq
|
||||||
|
; nextln: ldp fp, lr, [sp], #16
|
||||||
|
; nextln: ret
|
||||||
|
|
||||||
|
function %icmp_sle_i128(i128, i128) -> b1 {
|
||||||
|
block0(v0: i128, v1: i128):
|
||||||
|
v2 = icmp sle v0, v1
|
||||||
|
return v2
|
||||||
|
}
|
||||||
|
|
||||||
|
; check: stp fp, lr, [sp, #-16]!
|
||||||
|
; nextln: mov fp, sp
|
||||||
|
; nextln: subs xzr, x0, x2
|
||||||
|
; nextln: cset x0, ls
|
||||||
|
; nextln: subs xzr, x1, x3
|
||||||
|
; nextln: cset x1, le
|
||||||
|
; nextln: csel x0, x0, x1, eq
|
||||||
|
; nextln: ldp fp, lr, [sp], #16
|
||||||
|
; nextln: ret
|
||||||
|
|
||||||
|
function %icmp_ule_i128(i128, i128) -> b1 {
|
||||||
|
block0(v0: i128, v1: i128):
|
||||||
|
v2 = icmp ule v0, v1
|
||||||
|
return v2
|
||||||
|
}
|
||||||
|
|
||||||
|
; check: stp fp, lr, [sp, #-16]!
|
||||||
|
; nextln: mov fp, sp
|
||||||
|
; nextln: subs xzr, x0, x2
|
||||||
|
; nextln: cset x0, ls
|
||||||
|
; nextln: subs xzr, x1, x3
|
||||||
|
; nextln: cset x1, ls
|
||||||
|
; nextln: csel x0, x0, x1, eq
|
||||||
|
; nextln: ldp fp, lr, [sp], #16
|
||||||
|
; nextln: ret
|
||||||
|
|
||||||
|
function %icmp_sgt_i128(i128, i128) -> b1 {
|
||||||
|
block0(v0: i128, v1: i128):
|
||||||
|
v2 = icmp sgt v0, v1
|
||||||
|
return v2
|
||||||
|
}
|
||||||
|
|
||||||
|
; check: stp fp, lr, [sp, #-16]!
|
||||||
|
; nextln: mov fp, sp
|
||||||
|
; nextln: subs xzr, x0, x2
|
||||||
|
; nextln: cset x0, hi
|
||||||
|
; nextln: subs xzr, x1, x3
|
||||||
|
; nextln: cset x1, gt
|
||||||
|
; nextln: csel x0, x0, x1, eq
|
||||||
|
; nextln: ldp fp, lr, [sp], #16
|
||||||
|
; nextln: ret
|
||||||
|
|
||||||
|
function %icmp_ugt_i128(i128, i128) -> b1 {
|
||||||
|
block0(v0: i128, v1: i128):
|
||||||
|
v2 = icmp ugt v0, v1
|
||||||
|
return v2
|
||||||
|
}
|
||||||
|
|
||||||
|
; check: stp fp, lr, [sp, #-16]!
|
||||||
|
; nextln: mov fp, sp
|
||||||
|
; nextln: subs xzr, x0, x2
|
||||||
|
; nextln: cset x0, hi
|
||||||
|
; nextln: subs xzr, x1, x3
|
||||||
|
; nextln: cset x1, hi
|
||||||
|
; nextln: csel x0, x0, x1, eq
|
||||||
|
; nextln: ldp fp, lr, [sp], #16
|
||||||
|
; nextln: ret
|
||||||
|
|
||||||
|
|
||||||
|
function %icmp_sge_i128(i128, i128) -> b1 {
|
||||||
|
block0(v0: i128, v1: i128):
|
||||||
|
v2 = icmp sge v0, v1
|
||||||
|
return v2
|
||||||
|
}
|
||||||
|
|
||||||
|
; check: stp fp, lr, [sp, #-16]!
|
||||||
|
; nextln: mov fp, sp
|
||||||
|
; nextln: subs xzr, x0, x2
|
||||||
|
; nextln: cset x0, hs
|
||||||
|
; nextln: subs xzr, x1, x3
|
||||||
|
; nextln: cset x1, ge
|
||||||
|
; nextln: csel x0, x0, x1, eq
|
||||||
|
; nextln: ldp fp, lr, [sp], #16
|
||||||
|
; nextln: ret
|
||||||
|
|
||||||
|
function %icmp_uge_i128(i128, i128) -> b1 {
|
||||||
|
block0(v0: i128, v1: i128):
|
||||||
|
v2 = icmp uge v0, v1
|
||||||
|
return v2
|
||||||
|
}
|
||||||
|
|
||||||
|
; check: stp fp, lr, [sp, #-16]!
|
||||||
|
; nextln: mov fp, sp
|
||||||
|
; nextln: subs xzr, x0, x2
|
||||||
|
; nextln: cset x0, hs
|
||||||
|
; nextln: subs xzr, x1, x3
|
||||||
|
; nextln: cset x1, hs
|
||||||
|
; nextln: csel x0, x0, x1, eq
|
||||||
|
; nextln: ldp fp, lr, [sp], #16
|
||||||
|
; nextln: ret
|
||||||
|
|
||||||
|
function %icmp_of_i128(i128, i128) -> b1 {
|
||||||
|
block0(v0: i128, v1: i128):
|
||||||
|
v2 = icmp of v0, v1
|
||||||
|
return v2
|
||||||
|
}
|
||||||
|
|
||||||
|
; check: stp fp, lr, [sp, #-16]!
|
||||||
|
; nextln: mov fp, sp
|
||||||
|
; nextln: adds xzr, x0, x2
|
||||||
|
; nextln: adcs xzr, x1, x3
|
||||||
|
; nextln: cset x0, vs
|
||||||
|
; nextln: ldp fp, lr, [sp], #16
|
||||||
|
; nextln: ret
|
||||||
|
|
||||||
|
function %icmp_nof_i128(i128, i128) -> b1 {
|
||||||
|
block0(v0: i128, v1: i128):
|
||||||
|
v2 = icmp nof v0, v1
|
||||||
|
return v2
|
||||||
|
}
|
||||||
|
|
||||||
|
; check: stp fp, lr, [sp, #-16]!
|
||||||
|
; nextln: mov fp, sp
|
||||||
|
; nextln: adds xzr, x0, x2
|
||||||
|
; nextln: adcs xzr, x1, x3
|
||||||
|
; nextln: cset x0, vc
|
||||||
|
; nextln: ldp fp, lr, [sp], #16
|
||||||
|
; nextln: ret
|
||||||
|
|
||||||
|
|
||||||
function %f(i64, i64) -> i64 {
|
function %f(i64, i64) -> i64 {
|
||||||
block0(v0: i64, v1: i64):
|
block0(v0: i64, v1: i64):
|
||||||
v2 = ifcmp v0, v1
|
v2 = ifcmp v0, v1
|
||||||
|
|||||||
@@ -0,0 +1,46 @@
|
|||||||
|
test run
|
||||||
|
target aarch64
|
||||||
|
; target x86_64 machinst TODO: X86_64 does not implement i128 icmp overflow
|
||||||
|
|
||||||
|
; TODO: Cleanup these tests when we have native support for i128 immediates in CLIF's parser
|
||||||
|
function %icmp_of_i128(i64, i64, i64, i64) -> b1 {
|
||||||
|
block0(v0: i64,v1: i64,v2: i64,v3: i64):
|
||||||
|
v4 = iconcat v0, v1
|
||||||
|
v5 = iconcat v2, v3
|
||||||
|
|
||||||
|
v6 = icmp.i128 of v4, v5
|
||||||
|
return v6
|
||||||
|
}
|
||||||
|
; run: %icmp_of_i128(0, 0, 0, 0) == false
|
||||||
|
; run: %icmp_of_i128(0, 0, 1, 0) == false
|
||||||
|
; run: %icmp_of_i128(0, 0, -1, -1) == false
|
||||||
|
; run: %icmp_of_i128(-1, -1, -1, -1) == false
|
||||||
|
; run: %icmp_of_i128(0x00000000_00000000, 0x80000000_00000000, 0, 0) == false
|
||||||
|
; run: %icmp_of_i128(0xFFFFFFFF_FFFFFFFF, 0x7FFFFFFF_FFFFFFFF, 0, 0) == false
|
||||||
|
; run: %icmp_of_i128(1, 0, 0xFFFFFFFF_FFFFFFFF, 0x7FFFFFFF_FFFFFFFF) == true
|
||||||
|
; run: %icmp_of_i128(0xFFFFFFFF_FFFFFFFF, 0x7FFFFFFF_FFFFFFFF, 1, 0) == true
|
||||||
|
; run: %icmp_of_i128(0xFFFFFFFF_FFFFFFFF, 0x7FFFFFFF_FFFFFFFF, 0x00000000_00000000, 0x80000000_00000000) == false
|
||||||
|
; run: %icmp_of_i128(0x00000000_00000000, 0x80000000_00000000, 0xFFFFFFFF_FFFFFFFF, 0x7FFFFFFF_FFFFFFFF) == false
|
||||||
|
; run: %icmp_of_i128(0xFFFFFFFF_FFFFFFFF, 0x4FFFFFFF_FFFFFFFF, 0x00000000_00000000, 0x30000000_00000000) == false
|
||||||
|
; run: %icmp_of_i128(0xFFFFFFFF_FFFFFFFF, 0x4FFFFFFF_FFFFFFFF, 0x00000000_00000001, 0x30000000_00000000) == true
|
||||||
|
|
||||||
|
function %icmp_nof_i128(i64, i64, i64, i64) -> b1 {
|
||||||
|
block0(v0: i64,v1: i64,v2: i64,v3: i64):
|
||||||
|
v4 = iconcat v0, v1
|
||||||
|
v5 = iconcat v2, v3
|
||||||
|
|
||||||
|
v6 = icmp.i128 nof v4, v5
|
||||||
|
return v6
|
||||||
|
}
|
||||||
|
; run: %icmp_nof_i128(0, 0, 0, 0) == true
|
||||||
|
; run: %icmp_nof_i128(0, 0, 1, 0) == true
|
||||||
|
; run: %icmp_nof_i128(0, 0, -1, -1) == true
|
||||||
|
; run: %icmp_nof_i128(-1, -1, -1, -1) == true
|
||||||
|
; run: %icmp_nof_i128(0x00000000_00000000, 0x80000000_00000000, 0, 0) == true
|
||||||
|
; run: %icmp_nof_i128(0xFFFFFFFF_FFFFFFFF, 0x7FFFFFFF_FFFFFFFF, 0, 0) == true
|
||||||
|
; run: %icmp_nof_i128(1, 0, 0xFFFFFFFF_FFFFFFFF, 0x7FFFFFFF_FFFFFFFF) == false
|
||||||
|
; run: %icmp_nof_i128(0xFFFFFFFF_FFFFFFFF, 0x7FFFFFFF_FFFFFFFF, 1, 0) == false
|
||||||
|
; run: %icmp_nof_i128(0xFFFFFFFF_FFFFFFFF, 0x7FFFFFFF_FFFFFFFF, 0x00000000_00000000, 0x80000000_00000000) == true
|
||||||
|
; run: %icmp_nof_i128(0x00000000_00000000, 0x80000000_00000000, 0xFFFFFFFF_FFFFFFFF, 0x7FFFFFFF_FFFFFFFF) == true
|
||||||
|
; run: %icmp_nof_i128(0xFFFFFFFF_FFFFFFFF, 0x4FFFFFFF_FFFFFFFF, 0x00000000_00000000, 0x30000000_00000000) == true
|
||||||
|
; run: %icmp_nof_i128(0xFFFFFFFF_FFFFFFFF, 0x4FFFFFFF_FFFFFFFF, 0x00000000_00000001, 0x30000000_00000000) == false
|
||||||
@@ -1,20 +1,191 @@
|
|||||||
test run
|
test run
|
||||||
|
target aarch64
|
||||||
target x86_64 machinst
|
target x86_64 machinst
|
||||||
|
|
||||||
function %test_icmp_eq_i128() -> b1 {
|
; TODO: Cleanup these tests when we have native support for i128 immediates in CLIF's parser
|
||||||
block0:
|
function %icmp_eq_i128(i64, i64, i64, i64) -> b1 {
|
||||||
v11 = iconst.i64 0x0
|
block0(v0: i64,v1: i64,v2: i64,v3: i64):
|
||||||
v12 = iconst.i64 0x0
|
v4 = iconcat v0, v1
|
||||||
v1 = iconcat v11, v12
|
v5 = iconcat v2, v3
|
||||||
v21 = iconst.i64 0x0
|
|
||||||
v22 = iconst.i64 0x0
|
v6 = icmp.i128 eq v4, v5
|
||||||
v2 = iconcat v21, v22
|
return v6
|
||||||
v10 = icmp.i128 eq v1, v2
|
|
||||||
return v10
|
|
||||||
}
|
}
|
||||||
|
; run: %icmp_eq_i128(0, 0, 0, 0) == true
|
||||||
|
; run: %icmp_eq_i128(-1, -1, -1, -1) == true
|
||||||
|
; run: %icmp_eq_i128(-1, -1, 0, 0) == false
|
||||||
|
; run: %icmp_eq_i128(-1, -1, 0, -1) == false
|
||||||
|
; run: %icmp_eq_i128(-1, 0, -1, -1) == false
|
||||||
|
; run: %icmp_eq_i128(0, -1, -1, -1) == false
|
||||||
|
; run: %icmp_eq_i128(0xC0FFEEEE_DECAFFFF, 0xDECAFFFF_C0FFEEEE, 0xC0FFEEEE_DECAFFFF, 0xDECAFFFF_C0FFEEEE) == true
|
||||||
|
; run: %icmp_eq_i128(0xFFFFFFFF_FFFFFFFF, 0xFFFFFFFF_FFFFFFFF, 0x00000000_00000001, 0x00000000_00000001) == false
|
||||||
|
; run: %icmp_eq_i128(0xFFFFFFFF_FFFFFFFF, 0x00000000_00000001, 0x00000000_00000001, 0x00000000_00000001) == false
|
||||||
|
|
||||||
; run
|
function %icmp_ne_i128(i64, i64, i64, i64) -> b1 {
|
||||||
|
block0(v0: i64,v1: i64,v2: i64,v3: i64):
|
||||||
|
v4 = iconcat v0, v1
|
||||||
|
v5 = iconcat v2, v3
|
||||||
|
|
||||||
|
v6 = icmp.i128 ne v4, v5
|
||||||
|
return v6
|
||||||
|
}
|
||||||
|
; run: %icmp_ne_i128(0, 0, 0, 0) == false
|
||||||
|
; run: %icmp_ne_i128(-1, -1, -1, -1) == false
|
||||||
|
; run: %icmp_ne_i128(-1, -1, 0, 0) == true
|
||||||
|
; run: %icmp_ne_i128(-1, -1, 0, -1) == true
|
||||||
|
; run: %icmp_ne_i128(-1, 0, -1, -1) == true
|
||||||
|
; run: %icmp_ne_i128(0, -1, -1, -1) == true
|
||||||
|
; run: %icmp_ne_i128(0xC0FFEEEE_DECAFFFF, 0xDECAFFFF_C0FFEEEE, 0xC0FFEEEE_DECAFFFF, 0xDECAFFFF_C0FFEEEE) == false
|
||||||
|
; run: %icmp_ne_i128(0xFFFFFFFF_FFFFFFFF, 0xFFFFFFFF_FFFFFFFF, 0x00000000_00000001, 0x00000000_00000001) == true
|
||||||
|
; run: %icmp_ne_i128(0xFFFFFFFF_FFFFFFFF, 0x00000000_00000001, 0x00000000_00000001, 0x00000000_00000001) == true
|
||||||
|
|
||||||
|
|
||||||
|
function %icmp_slt_i128(i64, i64, i64, i64) -> b1 {
|
||||||
|
block0(v0: i64,v1: i64,v2: i64,v3: i64):
|
||||||
|
v4 = iconcat v0, v1
|
||||||
|
v5 = iconcat v2, v3
|
||||||
|
|
||||||
|
v6 = icmp.i128 slt v4, v5
|
||||||
|
return v6
|
||||||
|
}
|
||||||
|
; run: %icmp_slt_i128(0, 0, 0, 0) == false
|
||||||
|
; run: %icmp_slt_i128(1, 0, 1, 0) == false
|
||||||
|
; run: %icmp_slt_i128(0, 0, 1, 0) == true
|
||||||
|
; run: %icmp_slt_i128(-1, -1, 0, 0) == true
|
||||||
|
; run: %icmp_slt_i128(0, 0, -1, -1) == false
|
||||||
|
; run: %icmp_slt_i128(-1, -1, -1, -1) == false
|
||||||
|
; run: %icmp_slt_i128(0xFFFFFFFF_FFFFFFFD, 0xFFFFFFFF_FFFFFFFF, 0xFFFFFFFF_FFFFFFFF, 0xFFFFFFFF_FFFFFFFF) == true
|
||||||
|
; run: %icmp_slt_i128(0x00000000_00000000, 0xC0FFEEEE_C0FFEEEE, 0x00000000_00000000, 0xDECAFFFF_DECAFFFF) == true
|
||||||
|
; run: %icmp_slt_i128(0x00000000_00000000, 0xDECAFFFF_DECAFFFF, 0x00000000_00000000, 0xC0FFEEEE_C0FFEEEE) == false
|
||||||
|
|
||||||
|
function %icmp_ult_i128(i64, i64, i64, i64) -> b1 {
|
||||||
|
block0(v0: i64,v1: i64,v2: i64,v3: i64):
|
||||||
|
v4 = iconcat v0, v1
|
||||||
|
v5 = iconcat v2, v3
|
||||||
|
|
||||||
|
v6 = icmp.i128 ult v4, v5
|
||||||
|
return v6
|
||||||
|
}
|
||||||
|
; run: %icmp_ult_i128(0, 0, 0, 0) == false
|
||||||
|
; run: %icmp_ult_i128(1, 0, 1, 0) == false
|
||||||
|
; run: %icmp_ult_i128(0, 0, 1, 0) == true
|
||||||
|
; run: %icmp_ult_i128(-1, -1, 0, 0) == false
|
||||||
|
; run: %icmp_ult_i128(0, 0, -1, -1) == true
|
||||||
|
; run: %icmp_ult_i128(-1, -1, -1, -1) == false
|
||||||
|
; run: %icmp_ult_i128(0xFFFFFFFF_FFFFFFFD, 0xFFFFFFFF_FFFFFFFF, 0xFFFFFFFF_FFFFFFFF, 0xFFFFFFFF_FFFFFFFF) == true
|
||||||
|
; run: %icmp_ult_i128(0x00000000_00000000, 0xC0FFEEEE_C0FFEEEE, 0x00000000_00000000, 0xDECAFFFF_DECAFFFF) == true
|
||||||
|
; run: %icmp_ult_i128(0x00000000_00000000, 0xDECAFFFF_DECAFFFF, 0x00000000_00000000, 0xC0FFEEEE_C0FFEEEE) == false
|
||||||
|
|
||||||
|
function %icmp_sle_i128(i64, i64, i64, i64) -> b1 {
|
||||||
|
block0(v0: i64,v1: i64,v2: i64,v3: i64):
|
||||||
|
v4 = iconcat v0, v1
|
||||||
|
v5 = iconcat v2, v3
|
||||||
|
|
||||||
|
v6 = icmp.i128 sle v4, v5
|
||||||
|
return v6
|
||||||
|
}
|
||||||
|
; run: %icmp_sle_i128(0, 0, 0, 0) == true
|
||||||
|
; run: %icmp_sle_i128(1, 0, 1, 0) == true
|
||||||
|
; run: %icmp_sle_i128(0, 0, 1, 0) == true
|
||||||
|
; run: %icmp_sle_i128(-1, -1, 0, 0) == true
|
||||||
|
; run: %icmp_sle_i128(0, 0, -1, -1) == false
|
||||||
|
; run: %icmp_sle_i128(-1, -1, -1, -1) == true
|
||||||
|
; run: %icmp_sle_i128(0xFFFFFFFF_FFFFFFFD, 0xFFFFFFFF_FFFFFFFF, 0xFFFFFFFF_FFFFFFFF, 0xFFFFFFFF_FFFFFFFF) == true
|
||||||
|
; run: %icmp_sle_i128(0x00000000_00000000, 0xC0FFEEEE_C0FFEEEE, 0x00000000_00000000, 0xDECAFFFF_DECAFFFF) == true
|
||||||
|
; run: %icmp_sle_i128(0x00000000_00000000, 0xDECAFFFF_DECAFFFF, 0x00000000_00000000, 0xC0FFEEEE_C0FFEEEE) == false
|
||||||
|
|
||||||
|
function %icmp_ule_i128(i64, i64, i64, i64) -> b1 {
|
||||||
|
block0(v0: i64,v1: i64,v2: i64,v3: i64):
|
||||||
|
v4 = iconcat v0, v1
|
||||||
|
v5 = iconcat v2, v3
|
||||||
|
|
||||||
|
v6 = icmp.i128 ule v4, v5
|
||||||
|
return v6
|
||||||
|
}
|
||||||
|
; run: %icmp_ule_i128(0, 0, 0, 0) == true
|
||||||
|
; run: %icmp_ule_i128(1, 0, 1, 0) == true
|
||||||
|
; run: %icmp_ule_i128(0, 0, 1, 0) == true
|
||||||
|
; run: %icmp_ule_i128(-1, -1, 0, 0) == false
|
||||||
|
; run: %icmp_ule_i128(0, 0, -1, -1) == true
|
||||||
|
; run: %icmp_ule_i128(-1, -1, -1, -1) == true
|
||||||
|
; run: %icmp_ule_i128(0xFFFFFFFF_FFFFFFFD, 0xFFFFFFFF_FFFFFFFF, 0xFFFFFFFF_FFFFFFFF, 0xFFFFFFFF_FFFFFFFF) == true
|
||||||
|
; run: %icmp_ule_i128(0x00000000_00000000, 0xC0FFEEEE_C0FFEEEE, 0x00000000_00000000, 0xDECAFFFF_DECAFFFF) == true
|
||||||
|
; run: %icmp_ule_i128(0x00000000_00000000, 0xDECAFFFF_DECAFFFF, 0x00000000_00000000, 0xC0FFEEEE_C0FFEEEE) == false
|
||||||
|
|
||||||
|
function %icmp_sgt_i128(i64, i64, i64, i64) -> b1 {
|
||||||
|
block0(v0: i64,v1: i64,v2: i64,v3: i64):
|
||||||
|
v4 = iconcat v0, v1
|
||||||
|
v5 = iconcat v2, v3
|
||||||
|
|
||||||
|
v6 = icmp.i128 sgt v4, v5
|
||||||
|
return v6
|
||||||
|
}
|
||||||
|
; run: %icmp_sgt_i128(0, 0, 0, 0) == false
|
||||||
|
; run: %icmp_sgt_i128(1, 0, 1, 0) == false
|
||||||
|
; run: %icmp_sgt_i128(0, 0, 1, 0) == false
|
||||||
|
; run: %icmp_sgt_i128(-1, -1, 0, 0) == false
|
||||||
|
; run: %icmp_sgt_i128(0, 0, -1, -1) == true
|
||||||
|
; run: %icmp_sgt_i128(-1, -1, -1, -1) == false
|
||||||
|
; run: %icmp_sgt_i128(0xFFFFFFFF_FFFFFFFD, 0xFFFFFFFF_FFFFFFFF, 0xFFFFFFFF_FFFFFFFF, 0xFFFFFFFF_FFFFFFFF) == false
|
||||||
|
; run: %icmp_sgt_i128(0x00000000_00000000, 0xC0FFEEEE_C0FFEEEE, 0x00000000_00000000, 0xDECAFFFF_DECAFFFF) == false
|
||||||
|
; run: %icmp_sgt_i128(0x00000000_00000000, 0xDECAFFFF_DECAFFFF, 0x00000000_00000000, 0xC0FFEEEE_C0FFEEEE) == true
|
||||||
|
|
||||||
|
function %icmp_ugt_i128(i64, i64, i64, i64) -> b1 {
|
||||||
|
block0(v0: i64,v1: i64,v2: i64,v3: i64):
|
||||||
|
v4 = iconcat v0, v1
|
||||||
|
v5 = iconcat v2, v3
|
||||||
|
|
||||||
|
v6 = icmp.i128 ugt v4, v5
|
||||||
|
return v6
|
||||||
|
}
|
||||||
|
; run: %icmp_ugt_i128(0, 0, 0, 0) == false
|
||||||
|
; run: %icmp_ugt_i128(1, 0, 1, 0) == false
|
||||||
|
; run: %icmp_ugt_i128(0, 0, 1, 0) == false
|
||||||
|
; run: %icmp_ugt_i128(-1, -1, 0, 0) == true
|
||||||
|
; run: %icmp_ugt_i128(0, 0, -1, -1) == false
|
||||||
|
; run: %icmp_ugt_i128(-1, -1, -1, -1) == false
|
||||||
|
; run: %icmp_ugt_i128(0xFFFFFFFF_FFFFFFFD, 0xFFFFFFFF_FFFFFFFF, 0xFFFFFFFF_FFFFFFFF, 0xFFFFFFFF_FFFFFFFF) == false
|
||||||
|
; run: %icmp_ugt_i128(0x00000000_00000000, 0xC0FFEEEE_C0FFEEEE, 0x00000000_00000000, 0xDECAFFFF_DECAFFFF) == false
|
||||||
|
; run: %icmp_ugt_i128(0x00000000_00000000, 0xDECAFFFF_DECAFFFF, 0x00000000_00000000, 0xC0FFEEEE_C0FFEEEE) == true
|
||||||
|
|
||||||
|
function %icmp_sge_i128(i64, i64, i64, i64) -> b1 {
|
||||||
|
block0(v0: i64,v1: i64,v2: i64,v3: i64):
|
||||||
|
v4 = iconcat v0, v1
|
||||||
|
v5 = iconcat v2, v3
|
||||||
|
|
||||||
|
v6 = icmp.i128 sge v4, v5
|
||||||
|
return v6
|
||||||
|
}
|
||||||
|
; run: %icmp_sge_i128(0, 0, 0, 0) == true
|
||||||
|
; run: %icmp_sge_i128(1, 0, 1, 0) == true
|
||||||
|
; run: %icmp_sge_i128(0, 0, 1, 0) == false
|
||||||
|
; run: %icmp_sge_i128(-1, -1, 0, 0) == false
|
||||||
|
; run: %icmp_sge_i128(0, 0, -1, -1) == true
|
||||||
|
; run: %icmp_sge_i128(-1, -1, -1, -1) == true
|
||||||
|
; run: %icmp_sge_i128(0xFFFFFFFF_FFFFFFFD, 0xFFFFFFFF_FFFFFFFF, 0xFFFFFFFF_FFFFFFFF, 0xFFFFFFFF_FFFFFFFF) == false
|
||||||
|
; run: %icmp_sge_i128(0x00000000_00000000, 0xC0FFEEEE_C0FFEEEE, 0x00000000_00000000, 0xDECAFFFF_DECAFFFF) == false
|
||||||
|
; run: %icmp_sge_i128(0x00000000_00000000, 0xDECAFFFF_DECAFFFF, 0x00000000_00000000, 0xC0FFEEEE_C0FFEEEE) == true
|
||||||
|
|
||||||
|
function %icmp_uge_i128(i64, i64, i64, i64) -> b1 {
|
||||||
|
block0(v0: i64,v1: i64,v2: i64,v3: i64):
|
||||||
|
v4 = iconcat v0, v1
|
||||||
|
v5 = iconcat v2, v3
|
||||||
|
|
||||||
|
v6 = icmp.i128 uge v4, v5
|
||||||
|
return v6
|
||||||
|
}
|
||||||
|
; run: %icmp_uge_i128(0, 0, 0, 0) == true
|
||||||
|
; run: %icmp_uge_i128(1, 0, 1, 0) == true
|
||||||
|
; run: %icmp_uge_i128(0, 0, 1, 0) == false
|
||||||
|
; run: %icmp_uge_i128(-1, -1, 0, 0) == true
|
||||||
|
; run: %icmp_uge_i128(0, 0, -1, -1) == false
|
||||||
|
; run: %icmp_uge_i128(-1, -1, -1, -1) == true
|
||||||
|
; run: %icmp_uge_i128(0xFFFFFFFF_FFFFFFFD, 0xFFFFFFFF_FFFFFFFF, 0xFFFFFFFF_FFFFFFFF, 0xFFFFFFFF_FFFFFFFF) == false
|
||||||
|
; run: %icmp_uge_i128(0x00000000_00000000, 0xC0FFEEEE_C0FFEEEE, 0x00000000_00000000, 0xDECAFFFF_DECAFFFF) == false
|
||||||
|
; run: %icmp_uge_i128(0x00000000_00000000, 0xDECAFFFF_DECAFFFF, 0x00000000_00000000, 0xC0FFEEEE_C0FFEEEE) == true
|
||||||
|
|
||||||
|
|
||||||
|
; Icmp Imm Tests
|
||||||
function %test_icmp_imm_eq_i128() -> b1 {
|
function %test_icmp_imm_eq_i128() -> b1 {
|
||||||
block0:
|
block0:
|
||||||
v11 = iconst.i64 0x0
|
v11 = iconst.i64 0x0
|
||||||
@@ -26,20 +197,6 @@ block0:
|
|||||||
|
|
||||||
; run
|
; run
|
||||||
|
|
||||||
function %test_icmp_ne_i128() -> b1 {
|
|
||||||
block0:
|
|
||||||
v11 = iconst.i64 0x0
|
|
||||||
v12 = iconst.i64 0x0
|
|
||||||
v1 = iconcat v11, v12
|
|
||||||
v21 = iconst.i64 0x0
|
|
||||||
v22 = iconst.i64 0x1
|
|
||||||
v2 = iconcat v21, v22
|
|
||||||
v10 = icmp.i128 ne v1, v2
|
|
||||||
return v10
|
|
||||||
}
|
|
||||||
|
|
||||||
; run
|
|
||||||
|
|
||||||
function %test_icmp_imm_ne_i128() -> b1 {
|
function %test_icmp_imm_ne_i128() -> b1 {
|
||||||
block0:
|
block0:
|
||||||
v11 = iconst.i64 0x0
|
v11 = iconst.i64 0x0
|
||||||
@@ -50,45 +207,3 @@ block0:
|
|||||||
}
|
}
|
||||||
|
|
||||||
; run
|
; run
|
||||||
|
|
||||||
function %test_icmp_nz_eq_i128() -> b1 {
|
|
||||||
block0:
|
|
||||||
v11 = iconst.i64 0x1
|
|
||||||
v12 = iconst.i64 0x1
|
|
||||||
v1 = iconcat v11, v12
|
|
||||||
v21 = iconst.i64 0x1
|
|
||||||
v22 = iconst.i64 0x1
|
|
||||||
v2 = iconcat v21, v22
|
|
||||||
v10 = icmp.i128 eq v1, v2
|
|
||||||
return v10
|
|
||||||
}
|
|
||||||
|
|
||||||
; run
|
|
||||||
|
|
||||||
function %test_icmp_nz_gt_i128() -> b1 {
|
|
||||||
block0:
|
|
||||||
v11 = iconst.i64 0x1
|
|
||||||
v12 = iconst.i64 0x1
|
|
||||||
v1 = iconcat v11, v12
|
|
||||||
v21 = iconst.i64 0x1
|
|
||||||
v22 = iconst.i64 0x2
|
|
||||||
v2 = iconcat v21, v22
|
|
||||||
v10 = icmp.i128 ugt v2, v1
|
|
||||||
return v10
|
|
||||||
}
|
|
||||||
|
|
||||||
; run
|
|
||||||
|
|
||||||
function %test_icmp_nz_ge_i128() -> b1 {
|
|
||||||
block0:
|
|
||||||
v11 = iconst.i64 0x1
|
|
||||||
v12 = iconst.i64 0x1
|
|
||||||
v1 = iconcat v11, v12
|
|
||||||
v21 = iconst.i64 0x1
|
|
||||||
v22 = iconst.i64 0x1
|
|
||||||
v2 = iconcat v21, v22
|
|
||||||
v10 = icmp.i128 uge v1, v2
|
|
||||||
return v10
|
|
||||||
}
|
|
||||||
|
|
||||||
; run
|
|
||||||
|
|||||||
Reference in New Issue
Block a user