Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cranelift: Fuzz icmp and fcmp #4713

Merged
merged 3 commits into from
Aug 15, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
84 changes: 46 additions & 38 deletions cranelift/codegen/src/ir/condcodes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,24 @@ impl CondCode for IntCC {
}

impl IntCC {
/// Returns a slice with all possible [IntCC] values.
pub fn all() -> &'static [IntCC] {
&[
IntCC::Equal,
IntCC::NotEqual,
IntCC::SignedLessThan,
IntCC::SignedGreaterThanOrEqual,
IntCC::SignedGreaterThan,
IntCC::SignedLessThanOrEqual,
IntCC::UnsignedLessThan,
IntCC::UnsignedGreaterThanOrEqual,
IntCC::UnsignedGreaterThan,
IntCC::UnsignedLessThanOrEqual,
IntCC::Overflow,
IntCC::NotOverflow,
]
}

/// Get the corresponding IntCC with the equal component removed.
/// For conditions without a zero component, this is a no-op.
pub fn without_equal(self) -> Self {
Expand Down Expand Up @@ -227,6 +245,28 @@ pub enum FloatCC {
UnorderedOrGreaterThanOrEqual,
}

impl FloatCC {
/// Returns a slice with all possible [FloatCC] values.
pub fn all() -> &'static [FloatCC] {
&[
FloatCC::Ordered,
FloatCC::Unordered,
FloatCC::Equal,
FloatCC::NotEqual,
FloatCC::OrderedNotEqual,
FloatCC::UnorderedOrEqual,
FloatCC::LessThan,
FloatCC::LessThanOrEqual,
FloatCC::GreaterThan,
FloatCC::GreaterThanOrEqual,
FloatCC::UnorderedOrLessThan,
FloatCC::UnorderedOrLessThanOrEqual,
FloatCC::UnorderedOrGreaterThan,
FloatCC::UnorderedOrGreaterThanOrEqual,
]
}
}

impl CondCode for FloatCC {
fn inverse(self) -> Self {
use self::FloatCC::*;
Expand Down Expand Up @@ -320,24 +360,9 @@ mod tests {
use super::*;
use std::string::ToString;

static INT_ALL: [IntCC; 12] = [
IntCC::Equal,
IntCC::NotEqual,
IntCC::SignedLessThan,
IntCC::SignedGreaterThanOrEqual,
IntCC::SignedGreaterThan,
IntCC::SignedLessThanOrEqual,
IntCC::UnsignedLessThan,
IntCC::UnsignedGreaterThanOrEqual,
IntCC::UnsignedGreaterThan,
IntCC::UnsignedLessThanOrEqual,
IntCC::Overflow,
IntCC::NotOverflow,
];

#[test]
fn int_inverse() {
for r in &INT_ALL {
for r in IntCC::all() {
let cc = *r;
let inv = cc.inverse();
assert!(cc != inv);
Expand All @@ -347,7 +372,7 @@ mod tests {

#[test]
fn int_reverse() {
for r in &INT_ALL {
for r in IntCC::all() {
let cc = *r;
let rev = cc.reverse();
assert_eq!(rev.reverse(), cc);
Expand All @@ -356,33 +381,16 @@ mod tests {

#[test]
fn int_display() {
for r in &INT_ALL {
for r in IntCC::all() {
let cc = *r;
assert_eq!(cc.to_string().parse(), Ok(cc));
}
assert_eq!("bogus".parse::<IntCC>(), Err(()));
}

static FLOAT_ALL: [FloatCC; 14] = [
FloatCC::Ordered,
FloatCC::Unordered,
FloatCC::Equal,
FloatCC::NotEqual,
FloatCC::OrderedNotEqual,
FloatCC::UnorderedOrEqual,
FloatCC::LessThan,
FloatCC::LessThanOrEqual,
FloatCC::GreaterThan,
FloatCC::GreaterThanOrEqual,
FloatCC::UnorderedOrLessThan,
FloatCC::UnorderedOrLessThanOrEqual,
FloatCC::UnorderedOrGreaterThan,
FloatCC::UnorderedOrGreaterThanOrEqual,
];

#[test]
fn float_inverse() {
for r in &FLOAT_ALL {
for r in FloatCC::all() {
let cc = *r;
let inv = cc.inverse();
assert!(cc != inv);
Expand All @@ -392,7 +400,7 @@ mod tests {

#[test]
fn float_reverse() {
for r in &FLOAT_ALL {
for r in FloatCC::all() {
let cc = *r;
let rev = cc.reverse();
assert_eq!(rev.reverse(), cc);
Expand All @@ -401,7 +409,7 @@ mod tests {

#[test]
fn float_display() {
for r in &FLOAT_ALL {
for r in FloatCC::all() {
let cc = *r;
assert_eq!(cc.to_string().parse(), Ok(cc));
}
Expand Down
61 changes: 40 additions & 21 deletions cranelift/fuzzgen/src/function_generator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ use cranelift::codegen::ir::{
use cranelift::codegen::isa::CallConv;
use cranelift::frontend::{FunctionBuilder, FunctionBuilderContext, Switch, Variable};
use cranelift::prelude::{
EntityRef, ExtFuncData, InstBuilder, IntCC, JumpTableData, StackSlotData, StackSlotKind,
EntityRef, ExtFuncData, FloatCC, InstBuilder, IntCC, JumpTableData, StackSlotData,
StackSlotKind,
};
use std::collections::HashMap;
use std::ops::RangeInclusive;
Expand Down Expand Up @@ -110,6 +111,32 @@ fn insert_stack_store(
Ok(())
}

fn insert_cmp(
fgen: &mut FunctionGenerator,
builder: &mut FunctionBuilder,
opcode: Opcode,
args: &'static [Type],
rets: &'static [Type],
) -> Result<()> {
let lhs = fgen.get_variable_of_type(args[0])?;
let lhs = builder.use_var(lhs);

let rhs = fgen.get_variable_of_type(args[1])?;
let rhs = builder.use_var(rhs);

let res = if opcode == Opcode::Fcmp {
let cc = *fgen.u.choose(FloatCC::all())?;
builder.ins().fcmp(cc, lhs, rhs)
} else {
let cc = *fgen.u.choose(IntCC::all())?;
builder.ins().icmp(cc, lhs, rhs)
};

let var = fgen.get_variable_of_type(rets[0])?;
builder.def_var(var, res);
Ok(())
}

fn insert_const(
fgen: &mut FunctionGenerator,
builder: &mut FunctionBuilder,
Expand Down Expand Up @@ -391,6 +418,17 @@ const OPCODE_SIGNATURES: &'static [(
// Nearest
(Opcode::Nearest, &[F32], &[F32], insert_opcode),
(Opcode::Nearest, &[F64], &[F64], insert_opcode),
// Fcmp
(Opcode::Fcmp, &[F32, F32], &[B1], insert_cmp),
(Opcode::Fcmp, &[F64, F64], &[B1], insert_cmp),
// Icmp
(Opcode::Icmp, &[I8, I8], &[B1], insert_cmp),
(Opcode::Icmp, &[I16, I16], &[B1], insert_cmp),
(Opcode::Icmp, &[I32, I32], &[B1], insert_cmp),
(Opcode::Icmp, &[I64, I64], &[B1], insert_cmp),
// TODO: icmp of/nof broken for i128 on x86_64
// See: https://github.com/bytecodealliance/wasmtime/issues/4406
// (Opcode::Icmp, &[I128, I128], &[B1], insert_cmp),
// Stack Access
(Opcode::StackStore, &[I8], &[], insert_stack_store),
(Opcode::StackStore, &[I16], &[], insert_stack_store),
Expand Down Expand Up @@ -458,25 +496,6 @@ where
Ok(CallConv::SystemV)
}

fn generate_intcc(&mut self) -> Result<IntCC> {
Ok(*self.u.choose(
&[
IntCC::Equal,
IntCC::NotEqual,
IntCC::SignedLessThan,
IntCC::SignedGreaterThanOrEqual,
IntCC::SignedGreaterThan,
IntCC::SignedLessThanOrEqual,
IntCC::UnsignedLessThan,
IntCC::UnsignedGreaterThanOrEqual,
IntCC::UnsignedGreaterThan,
IntCC::UnsignedLessThanOrEqual,
IntCC::Overflow,
IntCC::NotOverflow,
][..],
)?)
}

fn generate_type(&mut self) -> Result<Type> {
// TODO: It would be nice if we could get these directly from cranelift
let scalars = [
Expand Down Expand Up @@ -681,7 +700,7 @@ where

fn generate_bricmp(&mut self, builder: &mut FunctionBuilder) -> Result<()> {
let (block, args) = self.generate_target_block(builder)?;
let cond = self.generate_intcc()?;
let cond = *self.u.choose(IntCC::all())?;

let bricmp_types = [
I8, I16, I32,
Expand Down