Change CLIF shuffle to validate lane indices (#5995)
* Change CLIF `shuffle` to validate lane indices Previously the CLIF `shuffle` instruction did not perform any validation on the lane shuffle mask and specified that out-of-bounds lanes always returned 0 as the value. This behavior though is not required by WebAssembly which validates that lane indices are always in-bounds. Additionally since these are static immediates even other code generators should be able to verify that the immediates are in-bounds. As a result this commit updates the definition of the `shuffle` instruction to specify that all byte immediates must be in-bounds in the range of [0, 32). The verifier has been updated and some test cases have been removed that were testing this functionality. Closes #5989 * Only generate valid shuffle immediates in fuzzer
This commit is contained in:
@@ -1422,7 +1422,7 @@ pub(crate) fn define(
|
||||
Shuffle two vectors using the given immediate bytes. For each of the 16 bytes of the
|
||||
immediate, a value i of 0-15 selects the i-th element of the first vector and a value i of
|
||||
16-31 selects the (i-16)th element of the second vector. Immediate values outside of the
|
||||
0-31 range place a 0 in the resulting vector lane.
|
||||
0-31 range are not valid.
|
||||
"#,
|
||||
&formats.shuffle,
|
||||
)
|
||||
|
||||
@@ -1685,6 +1685,28 @@ impl<'a> Verifier<'a> {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
ir::InstructionData::Shuffle {
|
||||
opcode: ir::instructions::Opcode::Shuffle,
|
||||
imm,
|
||||
..
|
||||
} => {
|
||||
let imm = self.func.dfg.immediates.get(imm).unwrap().as_slice();
|
||||
if imm.len() != 16 {
|
||||
errors.fatal((
|
||||
inst,
|
||||
self.context(inst),
|
||||
format!("the shuffle immediate wasn't 16-bytes long"),
|
||||
))
|
||||
} else if let Some(i) = imm.iter().find(|i| **i >= 32) {
|
||||
errors.fatal((
|
||||
inst,
|
||||
self.context(inst),
|
||||
format!("shuffle immediate index {i} is larger than the maximum 31"),
|
||||
))
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
_ => Ok(()),
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user