Skip to content

Commit

Permalink
fuzzgen: Enable bitcast instruction (#6747)
Browse files Browse the repository at this point in the history
  • Loading branch information
afonso360 authored Jul 19, 2023
1 parent a90f625 commit fe69c04
Showing 1 changed file with 35 additions and 170 deletions.
205 changes: 35 additions & 170 deletions cranelift/fuzzgen/src/function_generator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ use cranelift::codegen::ir::instructions::{InstructionFormat, ResolvedConstraint
use cranelift::codegen::ir::stackslot::StackSize;

use cranelift::codegen::ir::{
types::*, AtomicRmwOp, Block, ConstantData, ExternalName, FuncRef, Function, LibCall, Opcode,
SigRef, Signature, StackSlot, Type, UserExternalName, UserFuncName, Value,
types::*, AtomicRmwOp, Block, ConstantData, Endianness, ExternalName, FuncRef, Function,
LibCall, Opcode, SigRef, Signature, StackSlot, Type, UserExternalName, UserFuncName, Value,
};
use cranelift::codegen::isa::CallConv;
use cranelift::frontend::{FunctionBuilder, FunctionBuilderContext, Switch, Variable};
Expand Down Expand Up @@ -236,7 +236,13 @@ fn insert_bitcast(
let to_var = fgen.get_variable_of_type(rets[0])?;

// TODO: We can generate little/big endian flags here.
let memflags = MemFlags::new();
let mut memflags = MemFlags::new();

// When bitcasting between vectors of different lane counts, we need to
// specify the endianness.
if args[0].lane_count() != rets[0].lane_count() {
memflags.set_endianness(Endianness::Little);
}

let res = builder.ins().bitcast(rets[0], memflags, from_val);
builder.def_var(to_var, res);
Expand Down Expand Up @@ -454,15 +460,15 @@ fn valid_for_target(triple: &Triple, op: Opcode, args: &[Type], rets: &[Type]) -
assert_eq!(rets.len(), 1);

let arg = args[0];
let ret = args[0];
let ret = rets[0];

// Vector arguments must produce vector results, and scalar arguments must produce
// scalar results.
if arg.is_vector() != ret.is_vector() {
return false;
}

if arg.is_vector() && arg.is_vector() {
if arg.is_vector() && ret.is_vector() {
// Vector conversions must have the same number of lanes, and the lanes must be the
// same bit-width.
if arg.lane_count() != ret.lane_count() {
Expand All @@ -475,6 +481,20 @@ fn valid_for_target(triple: &Triple, op: Opcode, args: &[Type], rets: &[Type]) -
}
}

Opcode::Bitcast => {
assert_eq!(args.len(), 1);
assert_eq!(rets.len(), 1);

let arg = args[0];
let ret = rets[0];

// The opcode generator still allows bitcasts between different sized types, but these
// are rejected in the verifier.
if arg.bits() != ret.bits() {
return false;
}
}

_ => {}
}

Expand Down Expand Up @@ -570,6 +590,7 @@ fn valid_for_target(triple: &Triple, op: Opcode, args: &[Type], rets: &[Type]) -
Opcode::Umax | Opcode::Smax | Opcode::Umin | Opcode::Smin,
&[I64X2, I64X2]
),
// https://github.com/bytecodealliance/wasmtime/issues/6104
(Opcode::Bitcast, &[I128], &[_]),
(Opcode::Bitcast, &[_], &[I128]),
(Opcode::Uunarrow),
Expand Down Expand Up @@ -648,6 +669,9 @@ fn valid_for_target(triple: &Triple, op: Opcode, args: &[Type], rets: &[Type]) -
// Nothing wrong with this select. But we have an isle rule that can optimize it
// into a `min`/`max` instructions, which we don't have implemented yet.
(Opcode::Select, &[I8, I128, I128]),
// https://github.com/bytecodealliance/wasmtime/issues/6104
(Opcode::Bitcast, &[I128], &[_]),
(Opcode::Bitcast, &[_], &[I128]),
)
}

Expand Down Expand Up @@ -687,6 +711,9 @@ fn valid_for_target(triple: &Triple, op: Opcode, args: &[Type], rets: &[Type]) -
&[F32 | F64]
),
(Opcode::SsubSat | Opcode::SaddSat, &[I64X2, I64X2]),
// https://github.com/bytecodealliance/wasmtime/issues/6104
(Opcode::Bitcast, &[I128], &[_]),
(Opcode::Bitcast, &[_], &[I128]),
)
}

Expand Down Expand Up @@ -731,6 +758,9 @@ fn valid_for_target(triple: &Triple, op: Opcode, args: &[Type], rets: &[Type]) -
&[I128],
&[F32 | F64]
),
// https://github.com/bytecodealliance/wasmtime/issues/6104
(Opcode::Bitcast, &[I128], &[_]),
(Opcode::Bitcast, &[_], &[I128]),
)
}

Expand Down Expand Up @@ -1146,171 +1176,6 @@ static OPCODE_SIGNATURES: Lazy<Vec<OpcodeSignature>> = Lazy::new(|| {
(Opcode::Fmax, &[F64X2, F64X2], &[F64X2]),
(Opcode::FmaxPseudo, &[F32X4, F32X4], &[F32X4]),
(Opcode::FmaxPseudo, &[F64X2, F64X2], &[F64X2]),
(Opcode::Bitcast, &[I8], &[I8]),
(Opcode::Bitcast, &[I16], &[I8]),
(Opcode::Bitcast, &[I32], &[I8]),
(Opcode::Bitcast, &[I64], &[I8]),
(Opcode::Bitcast, &[I128], &[I8]),
(Opcode::Bitcast, &[F32], &[I8]),
(Opcode::Bitcast, &[F64], &[I8]),
(Opcode::Bitcast, &[I8X16], &[I8]),
(Opcode::Bitcast, &[I16X8], &[I8]),
(Opcode::Bitcast, &[I32X4], &[I8]),
(Opcode::Bitcast, &[I64X2], &[I8]),
(Opcode::Bitcast, &[F32X4], &[I8]),
(Opcode::Bitcast, &[F64X2], &[I8]),
(Opcode::Bitcast, &[I8], &[I16]),
(Opcode::Bitcast, &[I16], &[I16]),
(Opcode::Bitcast, &[I32], &[I16]),
(Opcode::Bitcast, &[I64], &[I16]),
(Opcode::Bitcast, &[I128], &[I16]),
(Opcode::Bitcast, &[F32], &[I16]),
(Opcode::Bitcast, &[F64], &[I16]),
(Opcode::Bitcast, &[I8X16], &[I16]),
(Opcode::Bitcast, &[I16X8], &[I16]),
(Opcode::Bitcast, &[I32X4], &[I16]),
(Opcode::Bitcast, &[I64X2], &[I16]),
(Opcode::Bitcast, &[F32X4], &[I16]),
(Opcode::Bitcast, &[F64X2], &[I16]),
(Opcode::Bitcast, &[I8], &[I32]),
(Opcode::Bitcast, &[I16], &[I32]),
(Opcode::Bitcast, &[I32], &[I32]),
(Opcode::Bitcast, &[I64], &[I32]),
(Opcode::Bitcast, &[I128], &[I32]),
(Opcode::Bitcast, &[F64], &[I32]),
(Opcode::Bitcast, &[I8X16], &[I32]),
(Opcode::Bitcast, &[I16X8], &[I32]),
(Opcode::Bitcast, &[I32X4], &[I32]),
(Opcode::Bitcast, &[I64X2], &[I32]),
(Opcode::Bitcast, &[F32X4], &[I32]),
(Opcode::Bitcast, &[F64X2], &[I32]),
(Opcode::Bitcast, &[I8], &[I64]),
(Opcode::Bitcast, &[I16], &[I64]),
(Opcode::Bitcast, &[I32], &[I64]),
(Opcode::Bitcast, &[I64], &[I64]),
(Opcode::Bitcast, &[I128], &[I64]),
(Opcode::Bitcast, &[F32], &[I64]),
(Opcode::Bitcast, &[I8X16], &[I64]),
(Opcode::Bitcast, &[I16X8], &[I64]),
(Opcode::Bitcast, &[I32X4], &[I64]),
(Opcode::Bitcast, &[I64X2], &[I64]),
(Opcode::Bitcast, &[F32X4], &[I64]),
(Opcode::Bitcast, &[F64X2], &[I64]),
(Opcode::Bitcast, &[I8], &[I128]),
(Opcode::Bitcast, &[I16], &[I128]),
(Opcode::Bitcast, &[I32], &[I128]),
(Opcode::Bitcast, &[I64], &[I128]),
(Opcode::Bitcast, &[I128], &[I128]),
(Opcode::Bitcast, &[F32], &[I128]),
(Opcode::Bitcast, &[F64], &[I128]),
(Opcode::Bitcast, &[I8X16], &[I128]),
(Opcode::Bitcast, &[I16X8], &[I128]),
(Opcode::Bitcast, &[I32X4], &[I128]),
(Opcode::Bitcast, &[I64X2], &[I128]),
(Opcode::Bitcast, &[F32X4], &[I128]),
(Opcode::Bitcast, &[F64X2], &[I128]),
(Opcode::Bitcast, &[I8], &[F32]),
(Opcode::Bitcast, &[I16], &[F32]),
(Opcode::Bitcast, &[I64], &[F32]),
(Opcode::Bitcast, &[I128], &[F32]),
(Opcode::Bitcast, &[F32], &[F32]),
(Opcode::Bitcast, &[F64], &[F32]),
(Opcode::Bitcast, &[I8X16], &[F32]),
(Opcode::Bitcast, &[I16X8], &[F32]),
(Opcode::Bitcast, &[I32X4], &[F32]),
(Opcode::Bitcast, &[I64X2], &[F32]),
(Opcode::Bitcast, &[F32X4], &[F32]),
(Opcode::Bitcast, &[F64X2], &[F32]),
(Opcode::Bitcast, &[I8], &[F64]),
(Opcode::Bitcast, &[I16], &[F64]),
(Opcode::Bitcast, &[I32], &[F64]),
(Opcode::Bitcast, &[I128], &[F64]),
(Opcode::Bitcast, &[F32], &[F64]),
(Opcode::Bitcast, &[F64], &[F64]),
(Opcode::Bitcast, &[I8X16], &[F64]),
(Opcode::Bitcast, &[I16X8], &[F64]),
(Opcode::Bitcast, &[I32X4], &[F64]),
(Opcode::Bitcast, &[I64X2], &[F64]),
(Opcode::Bitcast, &[F32X4], &[F64]),
(Opcode::Bitcast, &[F64X2], &[F64]),
(Opcode::Bitcast, &[I8], &[I8X16]),
(Opcode::Bitcast, &[I16], &[I8X16]),
(Opcode::Bitcast, &[I32], &[I8X16]),
(Opcode::Bitcast, &[I64], &[I8X16]),
(Opcode::Bitcast, &[I128], &[I8X16]),
(Opcode::Bitcast, &[F32], &[I8X16]),
(Opcode::Bitcast, &[F64], &[I8X16]),
(Opcode::Bitcast, &[I8X16], &[I8X16]),
(Opcode::Bitcast, &[I16X8], &[I8X16]),
(Opcode::Bitcast, &[I32X4], &[I8X16]),
(Opcode::Bitcast, &[I64X2], &[I8X16]),
(Opcode::Bitcast, &[F32X4], &[I8X16]),
(Opcode::Bitcast, &[F64X2], &[I8X16]),
(Opcode::Bitcast, &[I8], &[I16X8]),
(Opcode::Bitcast, &[I16], &[I16X8]),
(Opcode::Bitcast, &[I32], &[I16X8]),
(Opcode::Bitcast, &[I64], &[I16X8]),
(Opcode::Bitcast, &[I128], &[I16X8]),
(Opcode::Bitcast, &[F32], &[I16X8]),
(Opcode::Bitcast, &[F64], &[I16X8]),
(Opcode::Bitcast, &[I8X16], &[I16X8]),
(Opcode::Bitcast, &[I16X8], &[I16X8]),
(Opcode::Bitcast, &[I32X4], &[I16X8]),
(Opcode::Bitcast, &[I64X2], &[I16X8]),
(Opcode::Bitcast, &[F32X4], &[I16X8]),
(Opcode::Bitcast, &[F64X2], &[I16X8]),
(Opcode::Bitcast, &[I8], &[I32X4]),
(Opcode::Bitcast, &[I16], &[I32X4]),
(Opcode::Bitcast, &[I32], &[I32X4]),
(Opcode::Bitcast, &[I64], &[I32X4]),
(Opcode::Bitcast, &[I128], &[I32X4]),
(Opcode::Bitcast, &[F32], &[I32X4]),
(Opcode::Bitcast, &[F64], &[I32X4]),
(Opcode::Bitcast, &[I8X16], &[I32X4]),
(Opcode::Bitcast, &[I16X8], &[I32X4]),
(Opcode::Bitcast, &[I32X4], &[I32X4]),
(Opcode::Bitcast, &[I64X2], &[I32X4]),
(Opcode::Bitcast, &[F32X4], &[I32X4]),
(Opcode::Bitcast, &[F64X2], &[I32X4]),
(Opcode::Bitcast, &[I8], &[I64X2]),
(Opcode::Bitcast, &[I16], &[I64X2]),
(Opcode::Bitcast, &[I32], &[I64X2]),
(Opcode::Bitcast, &[I64], &[I64X2]),
(Opcode::Bitcast, &[I128], &[I64X2]),
(Opcode::Bitcast, &[F32], &[I64X2]),
(Opcode::Bitcast, &[F64], &[I64X2]),
(Opcode::Bitcast, &[I8X16], &[I64X2]),
(Opcode::Bitcast, &[I16X8], &[I64X2]),
(Opcode::Bitcast, &[I32X4], &[I64X2]),
(Opcode::Bitcast, &[I64X2], &[I64X2]),
(Opcode::Bitcast, &[F32X4], &[I64X2]),
(Opcode::Bitcast, &[F64X2], &[I64X2]),
(Opcode::Bitcast, &[I8], &[F32X4]),
(Opcode::Bitcast, &[I16], &[F32X4]),
(Opcode::Bitcast, &[I32], &[F32X4]),
(Opcode::Bitcast, &[I64], &[F32X4]),
(Opcode::Bitcast, &[I128], &[F32X4]),
(Opcode::Bitcast, &[F32], &[F32X4]),
(Opcode::Bitcast, &[F64], &[F32X4]),
(Opcode::Bitcast, &[I8X16], &[F32X4]),
(Opcode::Bitcast, &[I16X8], &[F32X4]),
(Opcode::Bitcast, &[I32X4], &[F32X4]),
(Opcode::Bitcast, &[I64X2], &[F32X4]),
(Opcode::Bitcast, &[F32X4], &[F32X4]),
(Opcode::Bitcast, &[F64X2], &[F32X4]),
(Opcode::Bitcast, &[I8], &[F64X2]),
(Opcode::Bitcast, &[I16], &[F64X2]),
(Opcode::Bitcast, &[I32], &[F64X2]),
(Opcode::Bitcast, &[I64], &[F64X2]),
(Opcode::Bitcast, &[I128], &[F64X2]),
(Opcode::Bitcast, &[F32], &[F64X2]),
(Opcode::Bitcast, &[F64], &[F64X2]),
(Opcode::Bitcast, &[I8X16], &[F64X2]),
(Opcode::Bitcast, &[I16X8], &[F64X2]),
(Opcode::Bitcast, &[I32X4], &[F64X2]),
(Opcode::Bitcast, &[I64X2], &[F64X2]),
(Opcode::Bitcast, &[F32X4], &[F64X2]),
(Opcode::Bitcast, &[F64X2], &[F64X2]),
(Opcode::FcvtToUintSat, &[F32X4], &[I8]),
(Opcode::FcvtToUintSat, &[F64X2], &[I8]),
(Opcode::FcvtToUintSat, &[F32X4], &[I16]),
Expand Down

0 comments on commit fe69c04

Please sign in to comment.