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:
@@ -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,
|
||||||
|
|||||||
9
cranelift/filetests/filetests/verifier/constant.clif
Normal file
9
cranelift/filetests/filetests/verifier/constant.clif
Normal 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
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user