diff --git a/cranelift/codegen/src/isa/aarch64/lower_inst.rs b/cranelift/codegen/src/isa/aarch64/lower_inst.rs index c4384fa83a..4fdb6942b6 100644 --- a/cranelift/codegen/src/isa/aarch64/lower_inst.rs +++ b/cranelift/codegen/src/isa/aarch64/lower_inst.rs @@ -1,7 +1,7 @@ //! Lower a single Cranelift instruction into vcode. use crate::binemit::CodeOffset; -use crate::ir::condcodes::FloatCC; +use crate::ir::condcodes::{FloatCC, IntCC}; use crate::ir::types::*; use crate::ir::Inst as IRInst; use crate::ir::{InstructionData, Opcode, TrapCode}; @@ -1673,14 +1673,112 @@ pub(crate) fn lower_insn_to_regs>( (false, true) => NarrowValueMode::SignExtend64, (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 rn = put_input_in_reg(ctx, inputs[0], 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)); materialize_bool_result(ctx, insn, rd, cond); } else { + let rn = put_input_in_reg(ctx, inputs[0], narrow_mode); let rm = put_input_in_reg(ctx, inputs[1], narrow_mode); lower_vector_compare(ctx, rd, rn, rm, ty, cond)?; } diff --git a/cranelift/filetests/filetests/isa/aarch64/condbr.clif b/cranelift/filetests/filetests/isa/aarch64/condbr.clif index 9ab5cfb2df..bfa4d04f77 100644 --- a/cranelift/filetests/filetests/isa/aarch64/condbr.clif +++ b/cranelift/filetests/filetests/isa/aarch64/condbr.clif @@ -15,6 +15,197 @@ block0(v0: i64, v1: i64): ; nextln: ldp fp, lr, [sp], #16 ; 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 { block0(v0: i64, v1: i64): v2 = ifcmp v0, v1 diff --git a/cranelift/filetests/filetests/runtests/i128-icmp-overflow.clif b/cranelift/filetests/filetests/runtests/i128-icmp-overflow.clif new file mode 100644 index 0000000000..e91b21de50 --- /dev/null +++ b/cranelift/filetests/filetests/runtests/i128-icmp-overflow.clif @@ -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 diff --git a/cranelift/filetests/filetests/runtests/i128-icmp.clif b/cranelift/filetests/filetests/runtests/i128-icmp.clif index 5ebf051682..657e6e339d 100644 --- a/cranelift/filetests/filetests/runtests/i128-icmp.clif +++ b/cranelift/filetests/filetests/runtests/i128-icmp.clif @@ -1,20 +1,191 @@ test run +target aarch64 target x86_64 machinst -function %test_icmp_eq_i128() -> b1 { -block0: - v11 = iconst.i64 0x0 - v12 = iconst.i64 0x0 - v1 = iconcat v11, v12 - v21 = iconst.i64 0x0 - v22 = iconst.i64 0x0 - v2 = iconcat v21, v22 - v10 = icmp.i128 eq v1, v2 - return v10 +; TODO: Cleanup these tests when we have native support for i128 immediates in CLIF's parser +function %icmp_eq_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 eq v4, v5 + return v6 } +; 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 { block0: v11 = iconst.i64 0x0 @@ -26,20 +197,6 @@ block0: ; 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 { block0: v11 = iconst.i64 0x0 @@ -50,45 +207,3 @@ block0: } ; 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