Skip to content

Commit 0c61dce

Browse files
alexcrichtonabrown
andauthored
Support i8x16.shuffle in wasm-mutate (bytecodealliance#1881)
* Support `i8x16.shuffle` in `wasm-mutate` Support another SIMD instruction in `wasm-mutate` to assist with shrinking functions which might contain this instruction. * Update crates/wasm-mutate/src/mutators/peephole/eggsy/lang.rs Co-authored-by: Andrew Brown <[email protected]> --------- Co-authored-by: Andrew Brown <[email protected]>
1 parent adbc32f commit 0c61dce

File tree

5 files changed

+59
-1
lines changed

5 files changed

+59
-1
lines changed

crates/wasm-mutate/src/mutators/peephole.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1595,4 +1595,18 @@ mod tests {
15951595
mutator.rules = Some(rules);
15961596
config.match_mutation(original, mutator, expected);
15971597
}
1598+
1599+
#[test]
1600+
fn i8x16_shuffle_handled() {
1601+
test_default_peephole_mutator(
1602+
"(module (func (param v128 v128)
1603+
local.get 0
1604+
local.get 1
1605+
i8x16.shuffle 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
1606+
drop)
1607+
)",
1608+
"(module (func (param v128 v128)))",
1609+
4,
1610+
);
1611+
}
15981612
}

crates/wasm-mutate/src/mutators/peephole/dfg.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
44
use super::eggsy::encoder::rebuild::build_expr;
55
use crate::mutators::peephole::{
6-
Lang, MemArg, MemArgLane, MemoryCopy, MemoryInit, RefType, TableCopy, TableInit,
6+
Lang, MemArg, MemArgLane, MemoryCopy, MemoryInit, RefType, Shuffle, TableCopy, TableInit,
77
};
88
use crate::mutators::OperatorAndByteOffset;
99
use crate::{ModuleInfo, WasmMutate};
@@ -865,6 +865,11 @@ impl<'a> DFGBuilder {
865865
}
866866

867867
Operator::I8x16Swizzle => self.binop(idx, Lang::I8x16Swizzle),
868+
Operator::I8x16Shuffle { lanes } => {
869+
let a = Id::from(self.pop_operand(idx, false));
870+
let b = Id::from(self.pop_operand(idx, false));
871+
self.push_node(Lang::I8x16Shuffle(Shuffle { indices: *lanes }, [b, a]), idx);
872+
}
868873
Operator::I8x16Splat => self.unop(idx, Lang::I8x16Splat),
869874
Operator::I16x8Splat => self.unop(idx, Lang::I16x8Splat),
870875
Operator::I32x4Splat => self.unop(idx, Lang::I32x4Splat),

crates/wasm-mutate/src/mutators/peephole/eggsy/analysis.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -347,6 +347,7 @@ impl PeepholeMutationAnalysis {
347347
Lang::F64x2ReplaceLane(..) => Ok(PrimitiveTypeInfo::V128),
348348

349349
Lang::I8x16Swizzle(_) => Ok(PrimitiveTypeInfo::V128),
350+
Lang::I8x16Shuffle(..) => Ok(PrimitiveTypeInfo::V128),
350351
Lang::I8x16Splat(_) => Ok(PrimitiveTypeInfo::V128),
351352
Lang::I16x8Splat(_) => Ok(PrimitiveTypeInfo::V128),
352353
Lang::I32x4Splat(_) => Ok(PrimitiveTypeInfo::V128),

crates/wasm-mutate/src/mutators/peephole/eggsy/encoder/expr2wasm.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -525,6 +525,9 @@ pub fn expr2wasm(
525525
Lang::F64x2ReplaceLane(lane, _) => insn(Instruction::F64x2ReplaceLane(*lane)),
526526

527527
Lang::I8x16Swizzle(_) => insn(Instruction::I8x16Swizzle),
528+
Lang::I8x16Shuffle(indices, _) => {
529+
insn(Instruction::I8x16Shuffle(indices.indices))
530+
}
528531
Lang::I8x16Splat(_) => insn(Instruction::I8x16Splat),
529532
Lang::I16x8Splat(_) => insn(Instruction::I16x8Splat),
530533
Lang::I32x4Splat(_) => insn(Instruction::I32x4Splat),

crates/wasm-mutate/src/mutators/peephole/eggsy/lang.rs

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -714,6 +714,7 @@ lang! {
714714
F64x2ReplaceLane(u8, [Id; 2]) = "f64x2.replace_lane",
715715

716716
I8x16Swizzle([Id; 2]) = "i8x16.swizzle",
717+
I8x16Shuffle(Shuffle, [Id; 2]) = "i8x16.shuffle",
717718
I8x16Splat([Id; 1]) = "i8x16.splat",
718719
I16x8Splat([Id; 1]) = "i16x8.splat",
719720
I32x4Splat([Id; 1]) = "i32x4.splat",
@@ -1188,6 +1189,40 @@ impl FromStr for MemArgLane {
11881189
}
11891190
}
11901191

1192+
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Clone)]
1193+
pub struct Shuffle {
1194+
pub indices: [u8; 16],
1195+
}
1196+
1197+
impl fmt::Display for Shuffle {
1198+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1199+
for (i, idx) in self.indices.iter().enumerate() {
1200+
if i != 0 {
1201+
write!(f, ".")?;
1202+
}
1203+
write!(f, "{idx}")?;
1204+
}
1205+
Ok(())
1206+
}
1207+
}
1208+
1209+
impl FromStr for Shuffle {
1210+
type Err = String;
1211+
fn from_str(s: &str) -> Result<Shuffle, String> {
1212+
let indices = s
1213+
.split('.')
1214+
.map(|part| part.parse::<u8>())
1215+
.collect::<Result<Vec<_>, _>>()
1216+
.map_err(|_| format!("failed to parse integer"))?;
1217+
let indices: &[u8; 16] = indices
1218+
.as_slice()
1219+
.try_into()
1220+
.map_err(|_| format!("wrong number of lanes"))?;
1221+
1222+
Ok(Shuffle { indices: *indices })
1223+
}
1224+
}
1225+
11911226
trait Children: Sized {
11921227
fn from(list: Vec<Id>) -> Result<Self, String>;
11931228
fn as_slice(&self) -> &[Id];

0 commit comments

Comments
 (0)