cranelift: Remove of/nof overflow flags from icmp (#4879)

* cranelift: Remove of/nof overflow flags from icmp

Neither Wasmtime nor cg-clif use these flags under any circumstances.
From discussion on #3060 I see it's long been unclear what purpose these
flags served.

Fixes #3060, fixes #4406, and fixes #4875... by deleting all the code
that could have been buggy.

This changes the cranelift-fuzzgen input format by removing some IntCC
options, so I've gone ahead and enabled I128 icmp tests at the same
time. Since only the of/nof cases were failing before, I expect these to
work.

* Restore trapif tests

It's still useful to validate that iadd_ifcout's iflags result can be
forwarded correctly to trapif, and for that purpose it doesn't really
matter what condition code is checked.
This commit is contained in:
Jamey Sharp
2022-09-07 08:38:41 -07:00
committed by GitHub
parent cd982c5a3f
commit 3d6d49daba
22 changed files with 8 additions and 788 deletions

View File

@@ -155,8 +155,6 @@ impl Immediates {
intcc_values.insert("ugt", "UnsignedGreaterThan"); intcc_values.insert("ugt", "UnsignedGreaterThan");
intcc_values.insert("ule", "UnsignedLessThanOrEqual"); intcc_values.insert("ule", "UnsignedLessThanOrEqual");
intcc_values.insert("ult", "UnsignedLessThan"); intcc_values.insert("ult", "UnsignedLessThan");
intcc_values.insert("of", "Overflow");
intcc_values.insert("nof", "NotOverflow");
new_enum( new_enum(
"cond", "cond",
"ir::condcodes::IntCC", "ir::condcodes::IntCC",

View File

@@ -1759,12 +1759,6 @@ pub(crate) fn define(
| sge | uge | Greater than or equal | | sge | uge | Greater than or equal |
| sgt | ugt | Greater than | | sgt | ugt | Greater than |
| sle | ule | Less than or equal | | sle | ule | Less than or equal |
| of | * | Overflow |
| nof | * | No Overflow |
\* The unsigned version of overflow condition for add has ISA-specific semantics and thus
has been kept as a method on the TargetIsa trait as
[unsigned_add_overflow_condition][crate::isa::TargetIsa::unsigned_add_overflow_condition].
When this instruction compares integer vectors, it returns a boolean When this instruction compares integer vectors, it returns a boolean
vector of lane-wise comparisons. vector of lane-wise comparisons.

View File

@@ -55,10 +55,6 @@ pub enum IntCC {
UnsignedGreaterThan, UnsignedGreaterThan,
/// Unsigned `<=`. /// Unsigned `<=`.
UnsignedLessThanOrEqual, UnsignedLessThanOrEqual,
/// Signed Overflow.
Overflow,
/// Signed No Overflow.
NotOverflow,
} }
impl CondCode for IntCC { impl CondCode for IntCC {
@@ -75,8 +71,6 @@ impl CondCode for IntCC {
UnsignedGreaterThanOrEqual => UnsignedLessThan, UnsignedGreaterThanOrEqual => UnsignedLessThan,
UnsignedGreaterThan => UnsignedLessThanOrEqual, UnsignedGreaterThan => UnsignedLessThanOrEqual,
UnsignedLessThanOrEqual => UnsignedGreaterThan, UnsignedLessThanOrEqual => UnsignedGreaterThan,
Overflow => NotOverflow,
NotOverflow => Overflow,
} }
} }
@@ -93,8 +87,6 @@ impl CondCode for IntCC {
UnsignedGreaterThanOrEqual => UnsignedLessThanOrEqual, UnsignedGreaterThanOrEqual => UnsignedLessThanOrEqual,
UnsignedLessThan => UnsignedGreaterThan, UnsignedLessThan => UnsignedGreaterThan,
UnsignedLessThanOrEqual => UnsignedGreaterThanOrEqual, UnsignedLessThanOrEqual => UnsignedGreaterThanOrEqual,
Overflow => Overflow,
NotOverflow => NotOverflow,
} }
} }
} }
@@ -113,8 +105,6 @@ impl IntCC {
IntCC::UnsignedGreaterThanOrEqual, IntCC::UnsignedGreaterThanOrEqual,
IntCC::UnsignedGreaterThan, IntCC::UnsignedGreaterThan,
IntCC::UnsignedLessThanOrEqual, IntCC::UnsignedLessThanOrEqual,
IntCC::Overflow,
IntCC::NotOverflow,
] ]
} }
@@ -158,8 +148,6 @@ impl IntCC {
UnsignedGreaterThanOrEqual => "uge", UnsignedGreaterThanOrEqual => "uge",
UnsignedLessThan => "ult", UnsignedLessThan => "ult",
UnsignedLessThanOrEqual => "ule", UnsignedLessThanOrEqual => "ule",
Overflow => "of",
NotOverflow => "nof",
} }
} }
} }
@@ -186,8 +174,6 @@ impl FromStr for IntCC {
"ugt" => Ok(UnsignedGreaterThan), "ugt" => Ok(UnsignedGreaterThan),
"ule" => Ok(UnsignedLessThanOrEqual), "ule" => Ok(UnsignedLessThanOrEqual),
"ult" => Ok(UnsignedLessThan), "ult" => Ok(UnsignedLessThan),
"of" => Ok(Overflow),
"nof" => Ok(NotOverflow),
_ => Err(()), _ => Err(()),
} }
} }

View File

@@ -924,8 +924,6 @@ pub(crate) fn lower_condcode(cc: IntCC) -> Cond {
IntCC::UnsignedGreaterThan => Cond::Hi, IntCC::UnsignedGreaterThan => Cond::Hi,
IntCC::UnsignedLessThanOrEqual => Cond::Ls, IntCC::UnsignedLessThanOrEqual => Cond::Ls,
IntCC::UnsignedLessThan => Cond::Lo, IntCC::UnsignedLessThan => Cond::Lo,
IntCC::Overflow => Cond::Vs,
IntCC::NotOverflow => Cond::Vc,
} }
} }
@@ -1088,9 +1086,7 @@ pub(crate) fn condcode_is_signed(cc: IntCC) -> bool {
IntCC::SignedGreaterThanOrEqual IntCC::SignedGreaterThanOrEqual
| IntCC::SignedGreaterThan | IntCC::SignedGreaterThan
| IntCC::SignedLessThanOrEqual | IntCC::SignedLessThanOrEqual
| IntCC::SignedLessThan | IntCC::SignedLessThan => true,
| IntCC::Overflow
| IntCC::NotOverflow => true,
} }
} }
@@ -1274,59 +1270,6 @@ pub(crate) fn lower_icmp(
}); });
cond cond
} }
IntCC::Overflow | IntCC::NotOverflow => {
// cmp lhs_lo, rhs_lo
// sbcs tmp1, lhs_hi, rhs_hi
// eor tmp2, lhs_hi, rhs_hi
// eor tmp1, lhs_hi, tmp1
// tst tmp2, tmp1
// cset dst, {lt, ge}
ctx.emit(Inst::AluRRR {
alu_op: ALUOp::SubS,
size: OperandSize::Size64,
rd: writable_zero_reg(),
rn: lhs.regs()[0],
rm: rhs.regs()[0],
});
ctx.emit(Inst::AluRRR {
alu_op: ALUOp::SbcS,
size: OperandSize::Size64,
rd: tmp1,
rn: lhs.regs()[1],
rm: rhs.regs()[1],
});
ctx.emit(Inst::AluRRR {
alu_op: ALUOp::Eor,
size: OperandSize::Size64,
rd: tmp2,
rn: lhs.regs()[1],
rm: rhs.regs()[1],
});
ctx.emit(Inst::AluRRR {
alu_op: ALUOp::Eor,
size: OperandSize::Size64,
rd: tmp1,
rn: lhs.regs()[1],
rm: tmp1.to_reg(),
});
ctx.emit(Inst::AluRRR {
alu_op: ALUOp::AndS,
size: OperandSize::Size64,
rd: writable_zero_reg(),
rn: tmp2.to_reg(),
rm: tmp1.to_reg(),
});
// This instruction sequence sets the condition codes
// on the lt and ge flags instead of the vs/vc so we
// need to signal that
if condcode == IntCC::Overflow {
Cond::Lt
} else {
Cond::Ge
}
}
_ => { _ => {
// cmp lhs_lo, rhs_lo // cmp lhs_lo, rhs_lo
// cset tmp1, unsigned_cond // cset tmp1, unsigned_cond
@@ -1409,45 +1352,6 @@ pub(crate) fn lower_icmp(
} else { } else {
let rn = put_input_in_reg(ctx, inputs[0], narrow_mode); 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);
let is_overflow = condcode == IntCC::Overflow || condcode == IntCC::NotOverflow;
let is_small_type = ty == I8 || ty == I16;
let (cond, rn, rm) = if is_overflow && is_small_type {
// Overflow checks for non native types require additional instructions, other than
// just the extend op.
//
// TODO: Codegen improvements: Merge the second sxt{h,b} into the following sub instruction.
//
// sxt{h,b} w0, w0
// sxt{h,b} w1, w1
// sub w0, w0, w1
// cmp w0, w0, sxt{h,b}
//
// The result of this comparison is either the EQ or NE condition code, so we need to
// signal that to the caller
let extend_op = if ty == I8 {
ExtendOp::SXTB
} else {
ExtendOp::SXTH
};
let tmp1 = ctx.alloc_tmp(I32).only_reg().unwrap();
ctx.emit(alu_inst_imm12(ALUOp::Sub, I32, tmp1, rn, rm));
let out_cond = match condcode {
IntCC::Overflow => Cond::Ne,
IntCC::NotOverflow => Cond::Eq,
_ => unreachable!(),
};
(
out_cond,
tmp1.to_reg(),
ResultRSEImm12::RegExtend(tmp1.to_reg(), extend_op),
)
} else {
(cond, rn, rm)
};
ctx.emit(alu_inst_imm12(ALUOp::SubS, ty, writable_zero_reg(), rn, rm)); ctx.emit(alu_inst_imm12(ALUOp::SubS, ty, writable_zero_reg(), rn, rm));
cond cond
}; };

View File

@@ -233,8 +233,6 @@ impl Cond {
IntCC::UnsignedGreaterThan => 2, IntCC::UnsignedGreaterThan => 2,
IntCC::UnsignedLessThanOrEqual => 8 | 4, IntCC::UnsignedLessThanOrEqual => 8 | 4,
IntCC::UnsignedLessThan => 4, IntCC::UnsignedLessThan => 4,
IntCC::Overflow => 1,
IntCC::NotOverflow => 8 | 4 | 2,
}; };
Cond { mask } Cond { mask }
} }

View File

@@ -891,7 +891,5 @@ fn condcode_is_signed(cc: IntCC) -> bool {
IntCC::UnsignedGreaterThan => false, IntCC::UnsignedGreaterThan => false,
IntCC::UnsignedLessThanOrEqual => false, IntCC::UnsignedLessThanOrEqual => false,
IntCC::UnsignedLessThan => false, IntCC::UnsignedLessThan => false,
IntCC::Overflow => true,
IntCC::NotOverflow => true,
} }
} }

View File

@@ -1659,8 +1659,6 @@ impl CC {
IntCC::UnsignedGreaterThan => CC::NBE, IntCC::UnsignedGreaterThan => CC::NBE,
IntCC::UnsignedLessThanOrEqual => CC::BE, IntCC::UnsignedLessThanOrEqual => CC::BE,
IntCC::UnsignedLessThan => CC::B, IntCC::UnsignedLessThan => CC::B,
IntCC::Overflow => CC::O,
IntCC::NotOverflow => CC::NO,
} }
} }

View File

@@ -149,36 +149,6 @@ block0(v0: i128, v1: i128):
; csel x0, x11, x14, eq ; csel x0, x11, x14, eq
; ret ; ret
function %icmp_of_i128(i128, i128) -> b1 {
block0(v0: i128, v1: i128):
v2 = icmp of v0, v1
return v2
}
; block0:
; subs xzr, x0, x2
; sbcs x11, x1, x3
; eor x13, x1, x3
; eor x11, x1, x11
; ands xzr, x13, x11
; cset x0, lt
; ret
function %icmp_nof_i128(i128, i128) -> b1 {
block0(v0: i128, v1: i128):
v2 = icmp nof v0, v1
return v2
}
; block0:
; subs xzr, x0, x2
; sbcs x11, x1, x3
; eor x13, x1, x3
; eor x11, x1, x11
; ands xzr, x13, x11
; cset x0, ge
; 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
@@ -502,49 +472,3 @@ block1:
; block3: ; block3:
; ret ; ret
function %i128_bricmp_of(i128, i128) {
block0(v0: i128, v1: i128):
br_icmp of v0, v1, block1
jump block1
block1:
return
}
; block0:
; subs xzr, x0, x2
; sbcs x9, x1, x3
; eor x11, x1, x3
; eor x9, x1, x9
; ands xzr, x11, x9
; b.lt label1 ; b label2
; block1:
; b label3
; block2:
; b label3
; block3:
; ret
function %i128_bricmp_nof(i128, i128) {
block0(v0: i128, v1: i128):
br_icmp nof v0, v1, block1
jump block1
block1:
return
}
; block0:
; subs xzr, x0, x2
; sbcs x9, x1, x3
; eor x11, x1, x3
; eor x9, x1, x9
; ands xzr, x11, x9
; b.ge label1 ; b label2
; block1:
; b label3
; block2:
; b label3
; block3:
; ret

View File

@@ -12,11 +12,11 @@ block0:
function %trap_iadd_ifcout(i64, i64) { function %trap_iadd_ifcout(i64, i64) {
block0(v0: i64, v1: i64): block0(v0: i64, v1: i64):
v2, v3 = iadd_ifcout v0, v1 v2, v3 = iadd_ifcout v0, v1
trapif of v3, user0 trapif ult v3, user0
return return
} }
; block0: ; block0:
; b.vc 8 ; udf ; b.hs 8 ; udf
; ret ; ret

View File

@@ -15,7 +15,7 @@ block0:
function %trap_iadd_ifcout(i64, i64) { function %trap_iadd_ifcout(i64, i64) {
block0(v0: i64, v1: i64): block0(v0: i64, v1: i64):
v2, v3 = iadd_ifcout v0, v1 v2, v3 = iadd_ifcout v0, v1
trapif of v3, user0 trapif ult v3, user0
return return
} }
@@ -23,7 +23,7 @@ block0(v0: i64, v1: i64):
; movq %rsp, %rbp ; movq %rsp, %rbp
; block0: ; block0:
; addq %rdi, %rsi, %rdi ; addq %rdi, %rsi, %rdi
; jno ; ud2 user0 ; ; jnb ; ud2 user0 ;
; movq %rbp, %rsp ; movq %rbp, %rsp
; popq %rbp ; popq %rbp
; ret ; ret

View File

@@ -1,217 +0,0 @@
test interpret
test run
target aarch64
target x86_64
; TODO: Merge this with the main br_icmp file when s390x supports overflows.
; See: https://github.com/bytecodealliance/wasmtime/issues/3060
function %bricmp_of_i64(i64, i64) -> b1 {
block0(v0: i64, v1: i64):
br_icmp.i64 of v0, v1, block2
jump block1
block1:
v2 = bconst.b1 false
return v2
block2:
v3 = bconst.b1 true
return v3
}
; run: %bricmp_of_i64(0, 0) == false
; run: %bricmp_of_i64(0, 1) == false
; run: %bricmp_of_i64(1, 0) == false
; run: %bricmp_of_i64(0, -1) == false
; run: %bricmp_of_i64(0x80000000_00000000, 0x80000000_00000000) == false
; run: %bricmp_of_i64(0x7FFFFFFF_FFFFFFFF, 1) == false
; run: %bricmp_of_i64(0x7FFFFFFF_FFFFFFFF, 0x7FFFFFFF_FFFFFFFF) == false
; run: %bricmp_of_i64(0xFFFFFFFF_FFFFFFFF, 1) == false
; run: %bricmp_of_i64(0x80000000_00000000, 1) == true
; run: %bricmp_of_i64(0x7FFFFFFF_FFFFFFFF, 0x80000000_00000000) == true
; run: %bricmp_of_i64(0x80000000_00000000, 0x7FFFFFFF_FFFFFFFF) == true
; run: %bricmp_of_i64(0x7FFFFFFF_FFFFFFFF, 0xFFFFFFFF_FFFFFFFF) == true
function %bricmp_of_i32(i32, i32) -> b1 {
block0(v0: i32, v1: i32):
br_icmp.i32 of v0, v1, block2
jump block1
block1:
v2 = bconst.b1 false
return v2
block2:
v3 = bconst.b1 true
return v3
}
; run: %bricmp_of_i32(0, 0) == false
; run: %bricmp_of_i32(0, 1) == false
; run: %bricmp_of_i32(1, 0) == false
; run: %bricmp_of_i32(0, -1) == false
; run: %bricmp_of_i32(0x80000000, 0x80000000) == false
; run: %bricmp_of_i32(0x7FFFFFFF, 1) == false
; run: %bricmp_of_i32(0x7FFFFFFF, 0x7FFFFFFF) == false
; run: %bricmp_of_i32(0xFFFFFFFF, 1) == false
; run: %bricmp_of_i32(0x80000000, 1) == true
; run: %bricmp_of_i32(0x7FFFFFFF, 0x80000000) == true
; run: %bricmp_of_i32(0x80000000, 0x7FFFFFFF) == true
; run: %bricmp_of_i32(0x7FFFFFFF, 0xFFFFFFFF) == true
function %bricmp_of_i16(i16, i16) -> b1 {
block0(v0: i16, v1: i16):
br_icmp.i16 of v0, v1, block2
jump block1
block1:
v2 = bconst.b1 false
return v2
block2:
v3 = bconst.b1 true
return v3
}
; run: %bricmp_of_i16(0, 0) == false
; run: %bricmp_of_i16(0, 1) == false
; run: %bricmp_of_i16(1, 0) == false
; run: %bricmp_of_i16(0, -1) == false
; run: %bricmp_of_i16(0x8000, 0x8000) == false
; run: %bricmp_of_i16(0x7FFF, 1) == false
; run: %bricmp_of_i16(0x7FFF, 0x7FFF) == false
; run: %bricmp_of_i16(0xFFFF, 1) == false
; run: %bricmp_of_i16(0x8000, 1) == true
; run: %bricmp_of_i16(0x7FFF, 0x8000) == true
; run: %bricmp_of_i16(0x8000, 0x7FFF) == true
; run: %bricmp_of_i16(0x7FFF, 0xFFFF) == true
function %bricmp_of_i8(i8, i8) -> b1 {
block0(v0: i8, v1: i8):
br_icmp.i8 of v0, v1, block2
jump block1
block1:
v2 = bconst.b1 false
return v2
block2:
v3 = bconst.b1 true
return v3
}
; run: %bricmp_of_i8(0, 0) == false
; run: %bricmp_of_i8(0, 1) == false
; run: %bricmp_of_i8(1, 0) == false
; run: %bricmp_of_i8(0, -1) == false
; run: %bricmp_of_i8(0x80, 0x80) == false
; run: %bricmp_of_i8(0x7F, 1) == false
; run: %bricmp_of_i8(0x7F, 0x7F) == false
; run: %bricmp_of_i8(0xFF, 1) == false
; run: %bricmp_of_i8(0x80, 1) == true
; run: %bricmp_of_i8(0x7F, 0x80) == true
; run: %bricmp_of_i8(0x80, 0x7F) == true
; run: %bricmp_of_i8(0x7F, 0xFF) == true
function %bricmp_nof_i64(i64, i64) -> b1 {
block0(v0: i64, v1: i64):
br_icmp.i64 nof v0, v1, block2
jump block1
block1:
v2 = bconst.b1 false
return v2
block2:
v3 = bconst.b1 true
return v3
}
; run: %bricmp_nof_i64(0, 0) == true
; run: %bricmp_nof_i64(0, 1) == true
; run: %bricmp_nof_i64(1, 0) == true
; run: %bricmp_nof_i64(0, -1) == true
; run: %bricmp_nof_i64(0x80000000_00000000, 0x80000000_00000000) == true
; run: %bricmp_nof_i64(0x7FFFFFFF_FFFFFFFF, 1) == true
; run: %bricmp_nof_i64(0x7FFFFFFF_FFFFFFFF, 0x7FFFFFFF_FFFFFFFF) == true
; run: %bricmp_nof_i64(0xFFFFFFFF_FFFFFFFF, 1) == true
; run: %bricmp_nof_i64(0x80000000_00000000, 1) == false
; run: %bricmp_nof_i64(0x7FFFFFFF_FFFFFFFF, 0x80000000_00000000) == false
; run: %bricmp_nof_i64(0x80000000_00000000, 0x7FFFFFFF_FFFFFFFF) == false
; run: %bricmp_nof_i64(0x7FFFFFFF_FFFFFFFF, 0xFFFFFFFF_FFFFFFFF) == false
function %bricmp_nof_i32(i32, i32) -> b1 {
block0(v0: i32, v1: i32):
br_icmp.i32 nof v0, v1, block2
jump block1
block1:
v2 = bconst.b1 false
return v2
block2:
v3 = bconst.b1 true
return v3
}
; run: %bricmp_nof_i32(0, 0) == true
; run: %bricmp_nof_i32(0, 1) == true
; run: %bricmp_nof_i32(1, 0) == true
; run: %bricmp_nof_i32(0, -1) == true
; run: %bricmp_nof_i32(0x80000000, 0x80000000) == true
; run: %bricmp_nof_i32(0x7FFFFFFF, 1) == true
; run: %bricmp_nof_i32(0x7FFFFFFF, 0x7FFFFFFF) == true
; run: %bricmp_nof_i32(0xFFFFFFFF, 1) == true
; run: %bricmp_nof_i32(0x80000000, 1) == false
; run: %bricmp_nof_i32(0x7FFFFFFF, 0x80000000) == false
; run: %bricmp_nof_i32(0x80000000, 0x7FFFFFFF) == false
; run: %bricmp_nof_i32(0x7FFFFFFF, 0xFFFFFFFF) == false
function %bricmp_nof_i16(i16, i16) -> b1 {
block0(v0: i16, v1: i16):
br_icmp.i16 nof v0, v1, block2
jump block1
block1:
v2 = bconst.b1 false
return v2
block2:
v3 = bconst.b1 true
return v3
}
; run: %bricmp_nof_i16(0, 0) == true
; run: %bricmp_nof_i16(0, 1) == true
; run: %bricmp_nof_i16(1, 0) == true
; run: %bricmp_nof_i16(0, -1) == true
; run: %bricmp_nof_i16(0x8000, 0x8000) == true
; run: %bricmp_nof_i16(0x7FFF, 1) == true
; run: %bricmp_nof_i16(0x7FFF, 0x7FFF) == true
; run: %bricmp_nof_i16(0xFFFF, 1) == true
; run: %bricmp_nof_i16(0x8000, 1) == false
; run: %bricmp_nof_i16(0x7FFF, 0x8000) == false
; run: %bricmp_nof_i16(0x8000, 0x7FFF) == false
; run: %bricmp_nof_i16(0x7FFF, 0xFFFF) == false
function %bricmp_nof_i8(i8, i8) -> b1 {
block0(v0: i8, v1: i8):
br_icmp.i8 nof v0, v1, block2
jump block1
block1:
v2 = bconst.b1 false
return v2
block2:
v3 = bconst.b1 true
return v3
}
; run: %bricmp_nof_i8(0, 0) == true
; run: %bricmp_nof_i8(0, 1) == true
; run: %bricmp_nof_i8(1, 0) == true
; run: %bricmp_nof_i8(0, -1) == true
; run: %bricmp_nof_i8(0x80, 0x80) == true
; run: %bricmp_nof_i8(0x7F, 1) == true
; run: %bricmp_nof_i8(0x7F, 0x7F) == true
; run: %bricmp_nof_i8(0xFF, 1) == true
; run: %bricmp_nof_i8(0x80, 1) == false
; run: %bricmp_nof_i8(0x7F, 0x80) == false
; run: %bricmp_nof_i8(0x80, 0x7F) == false
; run: %bricmp_nof_i8(0x7F, 0xFF) == false

View File

@@ -1,61 +0,0 @@
test run
target aarch64
; TODO: Merge this with the main i128-bricmp file when s390x supports overflows.
; See: https://github.com/bytecodealliance/wasmtime/issues/3060
function %i128_bricmp_of(i128, i128) -> b1 {
block0(v0: i128,v1: i128):
br_icmp.i128 of v0, v1, block2
jump block1
block1:
v2 = bconst.b1 false
return v2
block2:
v3 = bconst.b1 true
return v3
}
; run: %i128_bricmp_of(0, 0) == false
; run: %i128_bricmp_of(0, 1) == false
; run: %i128_bricmp_of(0, -1) == false
; run: %i128_bricmp_of(-1, -1) == false
; run: %i128_bricmp_of(0x80000000_00000000_00000000_00000000, 0) == false
; run: %i128_bricmp_of(0x7FFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFF, 0) == false
; run: %i128_bricmp_of(1, 0x7FFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFF) == false
; run: %i128_bricmp_of(0x7FFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFF, 1) == false
; run: %i128_bricmp_of(0x80000000_00000000_00000000_00000000, 1) == true
; run: %i128_bricmp_of(1, 0x80000000_00000000_00000000_00000000) == true
; run: %i128_bricmp_of(0x7FFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFF, 0x80000000_00000000_00000000_00000000) == true
; run: %i128_bricmp_of(0x80000000_00000000_00000000_00000000, 0x7FFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFF) == true
; run: %i128_bricmp_of(0x4FFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFF, 0x30000000_00000000_00000000_00000000) == false
; run: %i128_bricmp_of(0x4FFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFF, 0x30000000_00000000_00000000_00000001) == false
function %i128_bricmp_nof(i128, i128) -> b1 {
block0(v0: i128,v1: i128):
br_icmp.i128 nof v0, v1, block2
jump block1
block1:
v2 = bconst.b1 false
return v2
block2:
v3 = bconst.b1 true
return v3
}
; run: %i128_bricmp_nof(0, 0) == true
; run: %i128_bricmp_nof(0, 1) == true
; run: %i128_bricmp_nof(0, -1) == true
; run: %i128_bricmp_nof(-1, -1) == true
; run: %i128_bricmp_nof(0x80000000_00000000_00000000_00000000, 0) == true
; run: %i128_bricmp_nof(0x7FFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFF, 0) == true
; run: %i128_bricmp_nof(1, 0x7FFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFF) == true
; run: %i128_bricmp_nof(0x7FFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFF, 1) == true
; run: %i128_bricmp_nof(0x80000000_00000000_00000000_00000000, 1) == false
; run: %i128_bricmp_nof(1, 0x80000000_00000000_00000000_00000000) == false
; run: %i128_bricmp_nof(0x7FFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFF, 0x80000000_00000000_00000000_00000000) == false
; run: %i128_bricmp_nof(0x80000000_00000000_00000000_00000000, 0x7FFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFF) == false
; run: %i128_bricmp_nof(0x4FFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFF, 0x30000000_00000000_00000000_00000000) == true
; run: %i128_bricmp_nof(0x4FFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFF, 0x30000000_00000000_00000000_00000001) == true

View File

@@ -1,43 +0,0 @@
test interpret
test run
target aarch64
function %icmp_of_i128(i128, i128) -> b1 {
block0(v0: i128, v1: i128):
v2 = icmp.i128 of v0, v1
return v2
}
; run: %icmp_of_i128(0, 0) == false
; run: %icmp_of_i128(0, 1) == false
; run: %icmp_of_i128(0, -1) == false
; run: %icmp_of_i128(-1, -1) == false
; run: %icmp_of_i128(0x80000000_00000000_00000000_00000000, 0) == false
; run: %icmp_of_i128(0x7FFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFF, 0) == false
; run: %icmp_of_i128(1, 0x7FFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFF) == false
; run: %icmp_of_i128(0x7FFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFF, 1) == false
; run: %icmp_of_i128(0x80000000_00000000_00000000_00000000, 1) == true
; run: %icmp_of_i128(1, 0x80000000_00000000_00000000_00000000) == true
; run: %icmp_of_i128(0x7FFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFF, 0x80000000_00000000_00000000_00000000) == true
; run: %icmp_of_i128(0x80000000_00000000_00000000_00000000, 0x7FFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFF) == true
; run: %icmp_of_i128(0x4FFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFF, 0x30000000_00000000_00000000_00000000) == false
; run: %icmp_of_i128(0x4FFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFF, 0x30000000_00000000_00000000_00000001) == false
function %icmp_nof_i128(i128, i128) -> b1 {
block0(v0: i128, v1: i128):
v2 = icmp.i128 nof v0, v1
return v2
}
; run: %icmp_nof_i128(0, 0) == true
; run: %icmp_nof_i128(0, 1) == true
; run: %icmp_nof_i128(0, -1) == true
; run: %icmp_nof_i128(-1, -1) == true
; run: %icmp_nof_i128(0x80000000_00000000_00000000_00000000, 0) == true
; run: %icmp_nof_i128(0x7FFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFF, 0) == true
; run: %icmp_nof_i128(1, 0x7FFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFF) == true
; run: %icmp_nof_i128(0x7FFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFF, 1) == true
; run: %icmp_nof_i128(0x80000000_00000000_00000000_00000000, 1) == false
; run: %icmp_nof_i128(1, 0x80000000_00000000_00000000_00000000) == false
; run: %icmp_nof_i128(0x7FFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFF, 0x80000000_00000000_00000000_00000000) == false
; run: %icmp_nof_i128(0x80000000_00000000_00000000_00000000, 0x7FFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFF) == false
; run: %icmp_nof_i128(0x4FFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFF, 0x30000000_00000000_00000000_00000000) == true
; run: %icmp_nof_i128(0x4FFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFF, 0x30000000_00000000_00000000_00000001) == true

View File

@@ -1,75 +0,0 @@
test interpret
test run
target x86_64
function %icmp_nof_i8(i8, i8) -> b1 {
block0(v0: i8, v1: i8):
v2 = icmp nof v0, v1
return v2
}
; run: %icmp_nof_i8(0, 0) == true
; run: %icmp_nof_i8(0, 1) == true
; run: %icmp_nof_i8(1, 0) == true
; run: %icmp_nof_i8(0, -1) == true
; run: %icmp_nof_i8(0x80, 0x80) == true
; run: %icmp_nof_i8(0x7F, 1) == true
; run: %icmp_nof_i8(0x7F, 0x7F) == true
; run: %icmp_nof_i8(0xFF, 1) == true
; run: %icmp_nof_i8(0x80, 1) == false
; run: %icmp_nof_i8(0x7F, 0x80) == false
; run: %icmp_nof_i8(0x80, 0x7F) == false
; run: %icmp_nof_i8(0x7F, 0xFF) == false
function %icmp_nof_i16(i16, i16) -> b1 {
block0(v0: i16, v1: i16):
v2 = icmp nof v0, v1
return v2
}
; run: %icmp_nof_i16(0, 0) == true
; run: %icmp_nof_i16(0, 1) == true
; run: %icmp_nof_i16(1, 0) == true
; run: %icmp_nof_i16(0, -1) == true
; run: %icmp_nof_i16(0x8000, 0x8000) == true
; run: %icmp_nof_i16(0x7FFF, 1) == true
; run: %icmp_nof_i16(0x7FFF, 0x7FFF) == true
; run: %icmp_nof_i16(0xFFFF, 1) == true
; run: %icmp_nof_i16(0x8000, 1) == false
; run: %icmp_nof_i16(0x7FFF, 0x8000) == false
; run: %icmp_nof_i16(0x8000, 0x7FFF) == false
; run: %icmp_nof_i16(0x7FFF, 0xFFFF) == false
function %icmp_nof_i32(i32, i32) -> b1 {
block0(v0: i32, v1: i32):
v2 = icmp nof v0, v1
return v2
}
; run: %icmp_nof_i32(0, 0) == true
; run: %icmp_nof_i32(0, 1) == true
; run: %icmp_nof_i32(1, 0) == true
; run: %icmp_nof_i32(0, -1) == true
; run: %icmp_nof_i32(0x80000000, 0x80000000) == true
; run: %icmp_nof_i32(0x7FFFFFFF, 1) == true
; run: %icmp_nof_i32(0x7FFFFFFF, 0x7FFFFFFF) == true
; run: %icmp_nof_i32(0xFFFFFFFF, 1) == true
; run: %icmp_nof_i32(0x80000000, 1) == false
; run: %icmp_nof_i32(0x7FFFFFFF, 0x80000000) == false
; run: %icmp_nof_i32(0x80000000, 0x7FFFFFFF) == false
; run: %icmp_nof_i32(0x7FFFFFFF, 0xFFFFFFFF) == false
function %icmp_nof_i64(i64, i64) -> b1 {
block0(v0: i64, v1: i64):
v2 = icmp nof v0, v1
return v2
}
; run: %icmp_nof_i64(0, 0) == true
; run: %icmp_nof_i64(0, 1) == true
; run: %icmp_nof_i64(1, 0) == true
; run: %icmp_nof_i64(0, -1) == true
; run: %icmp_nof_i64(0x80000000_00000000, 0x80000000_00000000) == true
; run: %icmp_nof_i64(0x7FFFFFFF_FFFFFFFF, 1) == true
; run: %icmp_nof_i64(0x7FFFFFFF_FFFFFFFF, 0x7FFFFFFF_FFFFFFFF) == true
; run: %icmp_nof_i64(0xFFFFFFFF_FFFFFFFF, 1) == true
; run: %icmp_nof_i64(0x80000000_00000000, 1) == false
; run: %icmp_nof_i64(0x7FFFFFFF_FFFFFFFF, 0x80000000_00000000) == false
; run: %icmp_nof_i64(0x80000000_00000000, 0x7FFFFFFF_FFFFFFFF) == false
; run: %icmp_nof_i64(0x7FFFFFFF_FFFFFFFF, 0xFFFFFFFF_FFFFFFFF) == false

View File

@@ -1,75 +0,0 @@
test interpret
test run
target x86_64
function %icmp_of_i8(i8, i8) -> b1 {
block0(v0: i8, v1: i8):
v2 = icmp of v0, v1
return v2
}
; run: %icmp_of_i8(0, 0) == false
; run: %icmp_of_i8(0, 1) == false
; run: %icmp_of_i8(1, 0) == false
; run: %icmp_of_i8(0, -1) == false
; run: %icmp_of_i8(0x80, 0x80) == false
; run: %icmp_of_i8(0x7F, 1) == false
; run: %icmp_of_i8(0x7F, 0x7F) == false
; run: %icmp_of_i8(0xFF, 1) == false
; run: %icmp_of_i8(0x80, 1) == true
; run: %icmp_of_i8(0x7F, 0x80) == true
; run: %icmp_of_i8(0x80, 0x7F) == true
; run: %icmp_of_i8(0x7F, 0xFF) == true
function %icmp_of_i16(i16, i16) -> b1 {
block0(v0: i16, v1: i16):
v2 = icmp of v0, v1
return v2
}
; run: %icmp_of_i16(0, 0) == false
; run: %icmp_of_i16(0, 1) == false
; run: %icmp_of_i16(1, 0) == false
; run: %icmp_of_i16(0, -1) == false
; run: %icmp_of_i16(0x8000, 0x8000) == false
; run: %icmp_of_i16(0x7FFF, 1) == false
; run: %icmp_of_i16(0x7FFF, 0x7FFF) == false
; run: %icmp_of_i16(0xFFFF, 1) == false
; run: %icmp_of_i16(0x8000, 1) == true
; run: %icmp_of_i16(0x7FFF, 0x8000) == true
; run: %icmp_of_i16(0x8000, 0x7FFF) == true
; run: %icmp_of_i16(0x7FFF, 0xFFFF) == true
function %icmp_of_i32(i32, i32) -> b1 {
block0(v0: i32, v1: i32):
v2 = icmp of v0, v1
return v2
}
; run: %icmp_of_i32(0, 0) == false
; run: %icmp_of_i32(0, 1) == false
; run: %icmp_of_i32(1, 0) == false
; run: %icmp_of_i32(0, -1) == false
; run: %icmp_of_i32(0x80000000, 0x80000000) == false
; run: %icmp_of_i32(0x7FFFFFFF, 1) == false
; run: %icmp_of_i32(0x7FFFFFFF, 0x7FFFFFFF) == false
; run: %icmp_of_i32(0xFFFFFFFF, 1) == false
; run: %icmp_of_i32(0x80000000, 1) == true
; run: %icmp_of_i32(0x7FFFFFFF, 0x80000000) == true
; run: %icmp_of_i32(0x80000000, 0x7FFFFFFF) == true
; run: %icmp_of_i32(0x7FFFFFFF, 0xFFFFFFFF) == true
function %icmp_of_i64(i64, i64) -> b1 {
block0(v0: i64, v1: i64):
v2 = icmp of v0, v1
return v2
}
; run: %icmp_of_i64(0, 0) == false
; run: %icmp_of_i64(0, 1) == false
; run: %icmp_of_i64(1, 0) == false
; run: %icmp_of_i64(0, -1) == false
; run: %icmp_of_i64(0x80000000_00000000, 0x80000000_00000000) == false
; run: %icmp_of_i64(0x7FFFFFFF_FFFFFFFF, 1) == false
; run: %icmp_of_i64(0x7FFFFFFF_FFFFFFFF, 0x7FFFFFFF_FFFFFFFF) == false
; run: %icmp_of_i64(0xFFFFFFFF_FFFFFFFF, 1) == false
; run: %icmp_of_i64(0x80000000_00000000, 1) == true
; run: %icmp_of_i64(0x7FFFFFFF_FFFFFFFF, 0x80000000_00000000) == true
; run: %icmp_of_i64(0x80000000_00000000, 0x7FFFFFFF_FFFFFFFF) == true
; run: %icmp_of_i64(0x7FFFFFFF_FFFFFFFF, 0xFFFFFFFF_FFFFFFFF) == true

View File

@@ -1,45 +0,0 @@
test interpret
function %simd_icmp_nof_i8(i8x16, i8x16) -> b8x16 {
block0(v0: i8x16, v1: i8x16):
v2 = icmp nof v0, v1
return v2
}
; run: %simd_icmp_nof_i8([0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0], [0 1 0 0xFF 0 0 0 0 0 0 0 0 0 0 0 0]) == [true true true true true true true true true true true true true true true true]
; run: %simd_icmp_nof_i8([0x80 0x7F 0x7F 0xFF 0 0 0 0 0 0 0 0 0 0 0 0], [0x80 0x01 0x7F 0x01 0 0 0 0 0 0 0 0 0 0 0 0]) == [true true true true true true true true true true true true true true true true]
; run: %simd_icmp_nof_i8([0x80 0x7F 0x80 0x7F 0 0 0 0 0 0 0 0 0 0 0 0], [0x01 0x80 0x7F 0xFF 0 0 0 0 0 0 0 0 0 0 0 0]) == [false false false false true true true true true true true true true true true true]
; run: %simd_icmp_nof_i8([0x7F 0x7F 0x7F 0x7F 0x7F 0x7F 0x7F 0x7F 0x7F 0x7F 0x7F 0x7F 0x7F 0x7F 0x7F 0x7F], [0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF]) == [false false false false false false false false false false false false false false false false]
function %simd_icmp_nof_i16(i16x8, i16x8) -> b16x8 {
block0(v0: i16x8, v1: i16x8):
v2 = icmp nof v0, v1
return v2
}
; run: %simd_icmp_nof_i16([0 0 1 0 0 0 0 0], [0 1 0 0xFFFF 0 0 0 0]) == [true true true true true true true true]
; run: %simd_icmp_nof_i16([0x8000 0x7FFF 0x7FFF 0xFFFF 0 0 0 0], [0x8000 0x0001 0x7FFF 0x0001 0 0 0 0]) == [true true true true true true true true]
; run: %simd_icmp_nof_i16([0x8000 0x7FFF 0x8000 0x7FFF 0 0 0 0], [0x0001 0x8000 0x7FFF 0xFFFF 0 0 0 0]) == [false false false false true true true true]
; run: %simd_icmp_nof_i16([0x7FFF 0x7FFF 0x7FFF 0x7FFF 0x7FFF 0x7FFF 0x7FFF 0x7FFF], [0xFFFF 0xFFFF 0xFFFF 0xFFFF 0xFFFF 0xFFFF 0xFFFF 0xFFFF]) == [false false false false false false false false]
function %simd_icmp_nof_i32(i32x4, i32x4) -> b32x4 {
block0(v0: i32x4, v1: i32x4):
v2 = icmp nof v0, v1
return v2
}
; run: %simd_icmp_nof_i32([0 0 1 0], [0 1 0 0xFFFFFFFF]) == [true true true true]
; run: %simd_icmp_nof_i32([0x80000000 0x7FFFFFFF 0x7FFFFFFF 0xFFFFFFFF], [0x80000000 0x00000001 0x7FFFFFFF 0x00000001]) == [true true true true]
; run: %simd_icmp_nof_i32([0x80000000 0x7FFFFFFF 0x80000000 0x7FFFFFFF], [0x00000001 0x80000000 0x7FFFFFFF 0xFFFFFFFF]) == [false false false false]
; run: %simd_icmp_nof_i32([0x7FFFFFFF 0x7FFFFFFF 0x7FFFFFFF 0x7FFFFFFF], [0xFFFFFFFF 0xFFFFFFFF 0xFFFFFFFF 0xFFFFFFFF]) == [false false false false]
function %simd_icmp_nof_i64(i64x2, i64x2) -> b64x2 {
block0(v0: i64x2, v1: i64x2):
v2 = icmp nof v0, v1
return v2
}
; run: %simd_icmp_nof_i64([0 0], [0 1]) == [true true]
; run: %simd_icmp_nof_i64([1 0], [0 0xFFFFFFFF_FFFFFFFF]) == [true true]
; run: %simd_icmp_nof_i64([0x80000000_00000000 0x7FFFFFFF_FFFFFFFF], [0x80000000_00000000 0x00000000_00000001]) == [true true]
; run: %simd_icmp_nof_i64([0x7FFFFFFF_FFFFFFFF 0xFFFFFFFF_FFFFFFFF], [0x7FFFFFFF_FFFFFFFF 0x00000000_00000001]) == [true true]
; run: %simd_icmp_nof_i64([0x80000000_00000000 0x7FFFFFFF_FFFFFFFF], [0x01 0x80000000_00000000]) == [false false]
; run: %simd_icmp_nof_i64([0x80000000_00000000 0x7FFFFFFF_FFFFFFFF], [0x7FFFFFFF_FFFFFFFF 0xFFFFFFFF_FFFFFFFF]) == [false false]

View File

@@ -1,45 +0,0 @@
test interpret
function %simd_icmp_of_i8(i8x16, i8x16) -> b8x16 {
block0(v0: i8x16, v1: i8x16):
v2 = icmp of v0, v1
return v2
}
; run: %simd_icmp_of_i8([0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0], [0 1 0 0xFF 0 0 0 0 0 0 0 0 0 0 0 0]) == [false false false false false false false false false false false false false false false false]
; run: %simd_icmp_of_i8([0x80 0x7F 0x7F 0xFF 0 0 0 0 0 0 0 0 0 0 0 0], [0x80 0x01 0x7F 0x01 0 0 0 0 0 0 0 0 0 0 0 0]) == [false false false false false false false false false false false false false false false false]
; run: %simd_icmp_of_i8([0x80 0x7F 0x80 0x7F 0 0 0 0 0 0 0 0 0 0 0 0], [0x01 0x80 0x7F 0xFF 0 0 0 0 0 0 0 0 0 0 0 0]) == [true true true true false false false false false false false false false false false false]
; run: %simd_icmp_of_i8([0x7F 0x7F 0x7F 0x7F 0x7F 0x7F 0x7F 0x7F 0x7F 0x7F 0x7F 0x7F 0x7F 0x7F 0x7F 0x7F], [0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF]) == [true true true true true true true true true true true true true true true true]
function %simd_icmp_of_i16(i16x8, i16x8) -> b16x8 {
block0(v0: i16x8, v1: i16x8):
v2 = icmp of v0, v1
return v2
}
; run: %simd_icmp_of_i16([0 0 1 0 0 0 0 0], [0 1 0 0xFFFF 0 0 0 0]) == [false false false false false false false false]
; run: %simd_icmp_of_i16([0x8000 0x7FFF 0x7FFF 0xFFFF 0 0 0 0], [0x8000 0x0001 0x7FFF 0x0001 0 0 0 0]) == [false false false false false false false false]
; run: %simd_icmp_of_i16([0x8000 0x7FFF 0x8000 0x7FFF 0 0 0 0], [0x0001 0x8000 0x7FFF 0xFFFF 0 0 0 0]) == [true true true true false false false false]
; run: %simd_icmp_of_i16([0x7FFF 0x7FFF 0x7FFF 0x7FFF 0x7FFF 0x7FFF 0x7FFF 0x7FFF], [0xFFFF 0xFFFF 0xFFFF 0xFFFF 0xFFFF 0xFFFF 0xFFFF 0xFFFF]) == [true true true true true true true true]
function %simd_icmp_of_i32(i32x4, i32x4) -> b32x4 {
block0(v0: i32x4, v1: i32x4):
v2 = icmp of v0, v1
return v2
}
; run: %simd_icmp_of_i32([0 0 1 0], [0 1 0 0xFFFFFFFF]) == [false false false false]
; run: %simd_icmp_of_i32([0x80000000 0x7FFFFFFF 0x7FFFFFFF 0xFFFFFFFF], [0x80000000 0x00000001 0x7FFFFFFF 0x00000001]) == [false false false false]
; run: %simd_icmp_of_i32([0x80000000 0x7FFFFFFF 0x80000000 0x7FFFFFFF], [0x00000001 0x80000000 0x7FFFFFFF 0xFFFFFFFF]) == [true true true true]
; run: %simd_icmp_of_i32([0x7FFFFFFF 0x7FFFFFFF 0x7FFFFFFF 0x7FFFFFFF], [0xFFFFFFFF 0xFFFFFFFF 0xFFFFFFFF 0xFFFFFFFF]) == [true true true true]
function %simd_icmp_of_i64(i64x2, i64x2) -> b64x2 {
block0(v0: i64x2, v1: i64x2):
v2 = icmp of v0, v1
return v2
}
; run: %simd_icmp_of_i64([0 0], [0 1]) == [false false]
; run: %simd_icmp_of_i64([1 0], [0 0xFFFFFFFF_FFFFFFFF]) == [false false]
; run: %simd_icmp_of_i64([0x80000000_00000000 0x7FFFFFFF_FFFFFFFF], [0x80000000_00000000 0x00000000_00000001]) == [false false]
; run: %simd_icmp_of_i64([0x7FFFFFFF_FFFFFFFF 0xFFFFFFFF_FFFFFFFF], [0x7FFFFFFF_FFFFFFFF 0x00000000_00000001]) == [false false]
; run: %simd_icmp_of_i64([0x80000000_00000000 0x7FFFFFFF_FFFFFFFF], [0x01 0x80000000_00000000]) == [true true]
; run: %simd_icmp_of_i64([0x80000000_00000000 0x7FFFFFFF_FFFFFFFF], [0x7FFFFFFF_FFFFFFFF 0xFFFFFFFF_FFFFFFFF]) == [true true]

View File

@@ -1005,7 +1005,7 @@ impl<'a> FunctionBuilder<'a> {
/// misbehave as described in [`MemFlags::aligned`]. /// misbehave as described in [`MemFlags::aligned`].
/// ///
/// Note that `memcmp` is a *big-endian* and *unsigned* comparison. /// Note that `memcmp` is a *big-endian* and *unsigned* comparison.
/// As such, this panics when called with `IntCC::Signed*` or `IntCC::*Overflow`. /// As such, this panics when called with `IntCC::Signed*`.
pub fn emit_small_memory_compare( pub fn emit_small_memory_compare(
&mut self, &mut self,
config: TargetFrontendConfig, config: TargetFrontendConfig,
@@ -1034,9 +1034,6 @@ impl<'a> FunctionBuilder<'a> {
| SignedLessThanOrEqual => { | SignedLessThanOrEqual => {
panic!("Signed comparison {} not supported by memcmp", int_cc) panic!("Signed comparison {} not supported by memcmp", int_cc)
} }
Overflow | NotOverflow => {
panic!("Overflow comparison {} not supported by memcmp", int_cc)
}
}; };
if size == 0 { if size == 0 {

View File

@@ -436,9 +436,7 @@ const OPCODE_SIGNATURES: &'static [(
(Opcode::Icmp, &[I16, I16], &[B1], insert_cmp), (Opcode::Icmp, &[I16, I16], &[B1], insert_cmp),
(Opcode::Icmp, &[I32, I32], &[B1], insert_cmp), (Opcode::Icmp, &[I32, I32], &[B1], insert_cmp),
(Opcode::Icmp, &[I64, I64], &[B1], insert_cmp), (Opcode::Icmp, &[I64, I64], &[B1], insert_cmp),
// TODO: icmp of/nof broken for i128 on x86_64 (Opcode::Icmp, &[I128, I128], &[B1], insert_cmp),
// See: https://github.com/bytecodealliance/wasmtime/issues/4406
// (Opcode::Icmp, &[I128, I128], &[B1], insert_cmp),
// Stack Access // Stack Access
(Opcode::StackStore, &[I8], &[], insert_stack_store), (Opcode::StackStore, &[I8], &[], insert_stack_store),
(Opcode::StackStore, &[I16], &[], insert_stack_store), (Opcode::StackStore, &[I16], &[], insert_stack_store),

View File

@@ -740,7 +740,7 @@ mod tests {
#[test] #[test]
fn state_flags() { fn state_flags() {
let mut state = InterpreterState::default(); let mut state = InterpreterState::default();
let flag = IntCC::Overflow; let flag = IntCC::UnsignedLessThan;
assert!(!state.has_iflag(flag)); assert!(!state.has_iflag(flag));
state.set_iflag(flag); state.set_iflag(flag);
assert!(state.has_iflag(flag)); assert!(state.has_iflag(flag));

View File

@@ -1293,8 +1293,6 @@ where
&left.clone().convert(ValueConversionKind::ToUnsigned)?, &left.clone().convert(ValueConversionKind::ToUnsigned)?,
&right.clone().convert(ValueConversionKind::ToUnsigned)?, &right.clone().convert(ValueConversionKind::ToUnsigned)?,
)?, )?,
IntCC::Overflow => Value::overflow(left, right)?,
IntCC::NotOverflow => !Value::overflow(left, right)?,
}, },
bool_ty, bool_ty,
)?) )?)

View File

@@ -46,7 +46,6 @@ pub trait Value: Clone + From<DataValue> {
Ok(other.eq(self)? || other.gt(self)?) Ok(other.eq(self)? || other.gt(self)?)
} }
fn uno(&self, other: &Self) -> ValueResult<bool>; fn uno(&self, other: &Self) -> ValueResult<bool>;
fn overflow(&self, other: &Self) -> ValueResult<bool>;
// Arithmetic. // Arithmetic.
fn add(self, other: Self) -> ValueResult<Self>; fn add(self, other: Self) -> ValueResult<Self>;
@@ -478,17 +477,6 @@ impl Value for DataValue {
Ok(self.is_nan()? || other.is_nan()?) Ok(self.is_nan()? || other.is_nan()?)
} }
fn overflow(&self, other: &Self) -> ValueResult<bool> {
Ok(match (self, other) {
(DataValue::I8(a), DataValue::I8(b)) => a.checked_sub(*b).is_none(),
(DataValue::I16(a), DataValue::I16(b)) => a.checked_sub(*b).is_none(),
(DataValue::I32(a), DataValue::I32(b)) => a.checked_sub(*b).is_none(),
(DataValue::I64(a), DataValue::I64(b)) => a.checked_sub(*b).is_none(),
(DataValue::I128(a), DataValue::I128(b)) => a.checked_sub(*b).is_none(),
_ => unimplemented!(),
})
}
fn add(self, other: Self) -> ValueResult<Self> { fn add(self, other: Self) -> ValueResult<Self> {
if self.is_float() { if self.is_float() {
binary_match!(+(self, other); [F32, F64]) binary_match!(+(self, other); [F32, F64])