diff --git a/cranelift/codegen/src/verifier/mod.rs b/cranelift/codegen/src/verifier/mod.rs index 2244947f0f..c76090e57d 100644 --- a/cranelift/codegen/src/verifier/mod.rs +++ b/cranelift/codegen/src/verifier/mod.rs @@ -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(()), } } diff --git a/cranelift/filetests/filetests/isa/x86/extractlane-binemit.clif b/cranelift/filetests/filetests/isa/x86/extractlane-binemit.clif index 0a3b776a99..86f16315cf 100644 --- a/cranelift/filetests/filetests/isa/x86/extractlane-binemit.clif +++ b/cranelift/filetests/filetests/isa/x86/extractlane-binemit.clif @@ -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: diff --git a/cranelift/filetests/filetests/verifier/simd-lane-index.clif b/cranelift/filetests/filetests/verifier/simd-lane-index.clif new file mode 100644 index 0000000000..064254c0e2 --- /dev/null +++ b/cranelift/filetests/filetests/verifier/simd-lane-index.clif @@ -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 +}