From fa35d888784bbf7886fae4e6e15de66b1325eb6c Mon Sep 17 00:00:00 2001 From: Andrew Brown Date: Fri, 20 Mar 2020 14:10:04 -0700 Subject: [PATCH] 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. --- cranelift/codegen/src/verifier/mod.rs | 36 ++++++++++++++++--- .../filetests/verifier/constant.clif | 9 +++++ 2 files changed, 41 insertions(+), 4 deletions(-) create mode 100644 cranelift/filetests/filetests/verifier/constant.clif diff --git a/cranelift/codegen/src/verifier/mod.rs b/cranelift/codegen/src/verifier/mod.rs index 39d89f6e9f..7f6953c7e5 100644 --- a/cranelift/codegen/src/verifier/mod.rs +++ b/cranelift/codegen/src/verifier/mod.rs @@ -65,8 +65,9 @@ use crate::ir; use crate::ir::entities::AnyEntity; use crate::ir::instructions::{BranchInfo, CallInfo, InstructionFormat, ResolvedConstraint}; use crate::ir::{ - types, ArgumentLoc, Block, FuncRef, Function, GlobalValue, Inst, InstructionData, JumpTable, - Opcode, SigRef, StackSlot, StackSlotKind, Type, Value, ValueDef, ValueList, ValueLoc, + types, ArgumentLoc, Block, Constant, FuncRef, Function, GlobalValue, Inst, InstructionData, + JumpTable, Opcode, SigRef, StackSlot, StackSlotKind, Type, Value, ValueDef, ValueList, + ValueLoc, }; use crate::isa::TargetIsa; use crate::iterators::IteratorExtras; @@ -733,16 +734,23 @@ impl<'a> Verifier<'a> { )); } } - Unary { opcode: Opcode::Bitcast, arg, } => { 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 Unary { .. } + | UnaryConst { .. } | UnaryImm { .. } | UnaryIeee32 { .. } | UnaryIeee64 { .. } @@ -752,7 +760,6 @@ impl<'a> Verifier<'a> { | Ternary { .. } | InsertLane { .. } | ExtractLane { .. } - | UnaryConst { .. } | Shuffle { .. } | IntCompare { .. } | 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( &self, domtree: &DominatorTree, diff --git a/cranelift/filetests/filetests/verifier/constant.clif b/cranelift/filetests/filetests/verifier/constant.clif new file mode 100644 index 0000000000..a93abb82d7 --- /dev/null +++ b/cranelift/filetests/filetests/verifier/constant.clif @@ -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 +}