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("ule", "UnsignedLessThanOrEqual");
intcc_values.insert("ult", "UnsignedLessThan");
intcc_values.insert("of", "Overflow");
intcc_values.insert("nof", "NotOverflow");
new_enum(
"cond",
"ir::condcodes::IntCC",

View File

@@ -1759,12 +1759,6 @@ pub(crate) fn define(
| sge | uge | Greater than or equal |
| sgt | ugt | Greater than |
| 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
vector of lane-wise comparisons.

View File

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

View File

@@ -924,8 +924,6 @@ pub(crate) fn lower_condcode(cc: IntCC) -> Cond {
IntCC::UnsignedGreaterThan => Cond::Hi,
IntCC::UnsignedLessThanOrEqual => Cond::Ls,
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::SignedGreaterThan
| IntCC::SignedLessThanOrEqual
| IntCC::SignedLessThan
| IntCC::Overflow
| IntCC::NotOverflow => true,
| IntCC::SignedLessThan => true,
}
}
@@ -1274,59 +1270,6 @@ pub(crate) fn lower_icmp(
});
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
// cset tmp1, unsigned_cond
@@ -1409,45 +1352,6 @@ pub(crate) fn lower_icmp(
} else {
let rn = put_input_in_reg(ctx, inputs[0], 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));
cond
};

View File

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

View File

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

View File

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