Add verifier check to ensure each SIMD lane index is within bounds, fixes #1016

This commit is contained in:
Andrew Brown
2019-09-13 16:41:46 -07:00
parent 863ac809d9
commit 9b852fde09
3 changed files with 83 additions and 16 deletions

View File

@@ -1775,21 +1775,47 @@ impl<'a> Verifier<'a> {
) -> VerifierStepResult<()> {
let inst_data = &self.func.dfg[inst];
// If this is some sort of a store instruction, get the memflags, else, just return.
let memflags = match *inst_data {
match *inst_data {
ir::InstructionData::Store { flags, .. }
| ir::InstructionData::StoreComplex { flags, .. } => flags,
_ => return Ok(()),
};
if memflags.readonly() {
fatal!(
errors,
inst,
"A store instruction cannot have the `readonly` MemFlag"
)
} else {
Ok(())
| ir::InstructionData::StoreComplex { flags, .. } => {
if flags.readonly() {
fatal!(
errors,
inst,
"A store instruction cannot have the `readonly` MemFlag"
)
} else {
Ok(())
}
}
ir::InstructionData::ExtractLane {
opcode: ir::instructions::Opcode::Extractlane,
lane,
arg,
..
}
| ir::InstructionData::InsertLane {
opcode: ir::instructions::Opcode::Insertlane,
lane,
args: [arg, _],
..
} => {
// We must be specific about the opcodes above because other instructions are using
// the ExtractLane/InsertLane formats.
let ty = self.func.dfg.value_type(arg);
if u16::from(lane) >= ty.lane_count() {
fatal!(
errors,
inst,
"The lane {} does not index into the type {}",
lane,
ty
)
} else {
Ok(())
}
}
_ => Ok(()),
}
}

View File

@@ -2,8 +2,8 @@ test binemit
set enable_simd
target x86_64 haswell
; for extractlane, floats are legalized differently than integers and booleans; integers and booleans use x86_pextr
; which is manually placed in the IR so that it can be binemit-tested
; for extractlane, floats are legalized differently than integers and booleans; integers and
; booleans use x86_pextr which is manually placed in the IR so that it can be binemit-tested
function %test_extractlane_b8() {
ebb0:

View File

@@ -0,0 +1,41 @@
test verifier
set enable_simd
target x86_64
function %insertlane_i32x4() {
ebb0:
v0 = vconst.i32x4 [0 0 0 0]
v1 = iconst.i32 42
v2 = insertlane v0, 4, v1 ; error: The lane 4 does not index into the type i32x4
return
}
function %insertlane_b16x8() {
ebb0:
v0 = vconst.b16x8 [false false false false false false false false]
v1 = bconst.b16 true
v2 = insertlane v0, 8, v1 ; error: The lane 8 does not index into the type b16x8
return
}
function %insertlane_f64x2() {
ebb0:
v0 = vconst.f64x2 0x00
v1 = f64const 0x0.1
v2 = insertlane v0, 2, v1 ; error: The lane 2 does not index into the type f64x2
return
}
function %extractlane_i32x4() {
ebb0:
v0 = vconst.i32x4 [0 0 0 0]
v1 = extractlane v0, 4 ; error: The lane 4 does not index into the type i32x4
return
}
function %extractlane_b8x16() {
ebb0:
v0 = vconst.b8x16 0x00
v1 = extractlane v0, 16 ; error: The lane 16 does not index into the type b8x16
return
}