Verify that constant values are the correct size

Since we now allow constants of any size, we have to verify that `vconst` (currently the only user of the constant pool) is accessing constants that match its controlling type.
This commit is contained in:
Andrew Brown
2020-03-20 14:10:04 -07:00
parent 0672d1dc0f
commit fa35d88878
2 changed files with 41 additions and 4 deletions

View File

@@ -65,8 +65,9 @@ use crate::ir;
use crate::ir::entities::AnyEntity; use crate::ir::entities::AnyEntity;
use crate::ir::instructions::{BranchInfo, CallInfo, InstructionFormat, ResolvedConstraint}; use crate::ir::instructions::{BranchInfo, CallInfo, InstructionFormat, ResolvedConstraint};
use crate::ir::{ use crate::ir::{
types, ArgumentLoc, Block, FuncRef, Function, GlobalValue, Inst, InstructionData, JumpTable, types, ArgumentLoc, Block, Constant, FuncRef, Function, GlobalValue, Inst, InstructionData,
Opcode, SigRef, StackSlot, StackSlotKind, Type, Value, ValueDef, ValueList, ValueLoc, JumpTable, Opcode, SigRef, StackSlot, StackSlotKind, Type, Value, ValueDef, ValueList,
ValueLoc,
}; };
use crate::isa::TargetIsa; use crate::isa::TargetIsa;
use crate::iterators::IteratorExtras; use crate::iterators::IteratorExtras;
@@ -733,16 +734,23 @@ impl<'a> Verifier<'a> {
)); ));
} }
} }
Unary { Unary {
opcode: Opcode::Bitcast, opcode: Opcode::Bitcast,
arg, arg,
} => { } => {
self.verify_bitcast(inst, arg, errors)?; self.verify_bitcast(inst, arg, errors)?;
} }
UnaryConst {
opcode: Opcode::Vconst,
constant_handle,
..
} => {
self.verify_constant_size(inst, constant_handle, errors)?;
}
// Exhaustive list so we can't forget to add new formats // Exhaustive list so we can't forget to add new formats
Unary { .. } Unary { .. }
| UnaryConst { .. }
| UnaryImm { .. } | UnaryImm { .. }
| UnaryIeee32 { .. } | UnaryIeee32 { .. }
| UnaryIeee64 { .. } | UnaryIeee64 { .. }
@@ -752,7 +760,6 @@ impl<'a> Verifier<'a> {
| Ternary { .. } | Ternary { .. }
| InsertLane { .. } | InsertLane { .. }
| ExtractLane { .. } | ExtractLane { .. }
| UnaryConst { .. }
| Shuffle { .. } | Shuffle { .. }
| IntCompare { .. } | IntCompare { .. }
| IntCompareImm { .. } | IntCompareImm { .. }
@@ -1075,6 +1082,27 @@ impl<'a> Verifier<'a> {
} }
} }
fn verify_constant_size(
&self,
inst: Inst,
constant: Constant,
errors: &mut VerifierErrors,
) -> VerifierStepResult<()> {
let type_size = self.func.dfg.ctrl_typevar(inst).bytes() as usize;
let constant_size = self.func.dfg.constants.get(constant).len();
if type_size != constant_size {
errors.fatal((
inst,
format!(
"The instruction expects {} to have a size of {} bytes but it has {}",
constant, type_size, constant_size
),
))
} else {
Ok(())
}
}
fn domtree_integrity( fn domtree_integrity(
&self, &self,
domtree: &DominatorTree, domtree: &DominatorTree,

View File

@@ -0,0 +1,9 @@
test verifier
set enable_simd
function %incorrect_constant_size() {
const13 = [1 2 3 4 5] ; this constant has 5 bytes
block0:
v0 = vconst.i32x4 const13 ; error: The instruction expects const13 to have a size of 16 bytes but it has 5
return
}