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:
@@ -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",
|
||||||
|
|||||||
@@ -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.
|
||||||
|
|||||||
@@ -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(()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -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 }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
|
||||||
@@ -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
|
|
||||||
@@ -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
|
|
||||||
@@ -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
|
|
||||||
@@ -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
|
|
||||||
@@ -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]
|
|
||||||
@@ -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]
|
|
||||||
@@ -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 {
|
||||||
|
|||||||
@@ -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),
|
||||||
|
|||||||
@@ -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));
|
||||||
|
|||||||
@@ -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,
|
||||||
)?)
|
)?)
|
||||||
|
|||||||
@@ -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])
|
||||||
|
|||||||
Reference in New Issue
Block a user