diff --git a/llvm/lib/Target/X86/X86InstrInfo.h b/llvm/lib/Target/X86/X86InstrInfo.h --- a/llvm/lib/Target/X86/X86InstrInfo.h +++ b/llvm/lib/Target/X86/X86InstrInfo.h @@ -562,6 +562,8 @@ MachineBasicBlock::iterator &It, MachineFunction &MF, outliner::Candidate &C) const override; + bool verifyInstruction(const MachineInstr &MI, + StringRef &ErrInfo) const override; #define GET_INSTRINFO_HELPER_DECLS #include "X86GenInstrInfo.inc" diff --git a/llvm/lib/Target/X86/X86InstrInfo.cpp b/llvm/lib/Target/X86/X86InstrInfo.cpp --- a/llvm/lib/Target/X86/X86InstrInfo.cpp +++ b/llvm/lib/Target/X86/X86InstrInfo.cpp @@ -3619,6 +3619,33 @@ return AM; } +bool X86InstrInfo::verifyInstruction(const MachineInstr &MI, + StringRef &ErrInfo) const { + Optional AMOrNone = getAddrModeFromMemoryOp(MI, nullptr); + if (!AMOrNone) + return true; + + ExtAddrMode AM = *AMOrNone; + + switch (AM.Scale) { + case 1: + case 2: + case 4: + case 8: + break; + default: + ErrInfo = "Scale factor in address must be 1, 2, 4 or 8"; + return false; + } + if (!isInt<32>(AM.Displacement)) { + ErrInfo = "Displacement in address must fit into 32-bit signed " + "integer"; + return false; + } + + return true; +} + bool X86InstrInfo::getConstValDefinedInReg(const MachineInstr &MI, const Register Reg, int64_t &ImmVal) const { diff --git a/llvm/test/CodeGen/MIR/X86/machine-verifier-address.mir b/llvm/test/CodeGen/MIR/X86/machine-verifier-address.mir new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/MIR/X86/machine-verifier-address.mir @@ -0,0 +1,55 @@ +# RUN: not --crash llc -march=x86-64 -run-pass none -o /dev/null %s 2>&1 | FileCheck %s +# This test ensures that the address is checked in machine verifier. + +--- | + + %struct.widget = type { { double, double } } + + define void @baz(ptr %arg, <4 x i1> %arg1) #0 { + bb: + %tmp = shufflevector <2 x double> zeroinitializer, <2 x double> zeroinitializer, <4 x i32> zeroinitializer + br label %bb2 + + bb2: ; preds = %bb2, %bb + %tmp3 = fmul <4 x double> zeroinitializer, zeroinitializer + %tmp4 = getelementptr inbounds %struct.widget, ptr %arg, <4 x i64> undef + %tmp5 = call <4 x double> @llvm.masked.gather.v4f64.v4p0(<4 x ptr> %tmp4, i32 0, <4 x i1> %arg1, <4 x double> zeroinitializer) + %tmp6 = fadd <4 x double> zeroinitializer, zeroinitializer + %tmp7 = extractelement <4 x double> %tmp5, i64 0 + store double %tmp7, ptr null, align 8 + br label %bb2 + } + + declare <4 x double> @llvm.masked.gather.v4f64.v4p0(<4 x ptr>, i32 immarg, <4 x i1>, <4 x double>) #1 + + attributes #0 = { "target-cpu"="skylake" } + attributes #1 = { nocallback nofree nosync nounwind readonly willreturn } + +... +--- +name: baz +tracksRegLiveness: true +body: | + bb.0.bb: + successors: %bb.1(0x80000000) + liveins: $rdi, $xmm0 + + %1:vr128 = COPY $xmm0 + %0:gr64 = COPY $rdi + %2:vr128 = COPY %1 + + bb.1.bb2: + successors: %bb.1(0x80000000) + + %3:vr256 = AVX_SET0 + %4:vr128 = VPSLLDri %2, 31 + %5:vr256 = VPMOVSXDQYrr killed %4 + %8:vr256 = IMPLICIT_DEF + ; CHECK: *** Bad machine code: Scale factor in address must be 1, 2, 4 or 8 *** + %6:vr256, %7:vr256 = VGATHERQPDYrm %3, %0, 16, killed %8, 0, $noreg, %5 :: (load unknown-size, align 8) + %9:vr128 = COPY %6.sub_xmm + ; CHECK: *** Bad machine code: Displacement in address must fit into 32-bit signed integer *** + VMOVLPDmr $noreg, 1, $noreg, 1111111111111, $noreg, killed %9 :: (store (s64) into `ptr null`) + JMP_1 %bb.1 + +...