From: Matt Arsenault Date: Tue, 22 Jan 2019 00:29:37 +0000 (+0000) Subject: GlobalISel: Fix out of bounds crashes in verifier X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=b771a49ffaf44a3b85a5c5af5e1ac112d9a2a515;p=llvm GlobalISel: Fix out of bounds crashes in verifier git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@351769 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/CodeGen/MachineVerifier.cpp b/lib/CodeGen/MachineVerifier.cpp index cc8f77e823d..b7e0f575406 100644 --- a/lib/CodeGen/MachineVerifier.cpp +++ b/lib/CodeGen/MachineVerifier.cpp @@ -940,9 +940,12 @@ void MachineVerifier::visitMachineInstrBefore(const MachineInstr *MI) { if (isFunctionSelected) report("Unexpected generic instruction in a Selected function", MI); + unsigned NumOps = MI->getNumOperands(); + // Check types. SmallVector Types; - for (unsigned I = 0; I < MCID.getNumOperands(); ++I) { + for (unsigned I = 0, E = std::min(MCID.getNumOperands(), NumOps); + I != E; ++I) { if (!MCID.OpInfo[I].isGenericType()) continue; // Generic instructions specify type equality constraints between some of @@ -973,6 +976,10 @@ void MachineVerifier::visitMachineInstrBefore(const MachineInstr *MI) { if (MO->isReg() && TargetRegisterInfo::isPhysicalRegister(MO->getReg())) report("Generic instruction cannot have physical register", MO, I); } + + // Avoid out of bounds in checks below. This was already reported earlier. + if (MI->getNumOperands() < MCID.getNumOperands()) + return; } StringRef ErrorInfo; @@ -1033,8 +1040,6 @@ void MachineVerifier::visitMachineInstrBefore(const MachineInstr *MI) { // instructions aren't guaranteed to have the right number of operands or // types attached to them at this point assert(MCID.getNumOperands() == 2 && "Expected 2 operands G_*{EXT,TRUNC}"); - if (MI->getNumOperands() < MCID.getNumOperands()) - break; LLT DstTy = MRI->getType(MI->getOperand(0).getReg()); LLT SrcTy = MRI->getType(MI->getOperand(1).getReg()); if (!DstTy.isValid() || !SrcTy.isValid()) diff --git a/test/Verifier/test_g_add.mir b/test/Verifier/test_g_add.mir new file mode 100644 index 00000000000..54c470adc8a --- /dev/null +++ b/test/Verifier/test_g_add.mir @@ -0,0 +1,28 @@ +#RUN: not llc -o - -global-isel -run-pass=none -verify-machineinstrs %s 2>&1 | FileCheck %s +# REQUIRES: global-isel, aarch64-registered-target + +--- +name: test_add +legalized: true +regBankSelected: false +selected: false +tracksRegLiveness: true +liveins: +body: | + bb.0: + + %0:_(s32) = G_CONSTANT i32 0 + %1:_(s32) = G_CONSTANT i32 1 + + ; CHECK: Bad machine code: Too few operands + %2:_(s32) = G_ADD + + ; CHECK: Bad machine code: Too few operands + %3:_(s32) = G_ADD %0 + %4:_(s32) = G_ADD %0, %1 + + ; CHECK: Bad machine code: Too few operands + ; CHECK: Bad machine code: Explicit definition marked as use + G_ADD %0, %1 + +... diff --git a/test/Verifier/test_g_trunc.mir b/test/Verifier/test_g_trunc.mir new file mode 100644 index 00000000000..3a196bb7bbd --- /dev/null +++ b/test/Verifier/test_g_trunc.mir @@ -0,0 +1,23 @@ +# RUN: not llc -o - -global-isel -run-pass=none -verify-machineinstrs %s 2>&1 | FileCheck %s +# REQUIRES: global-isel, aarch64-registered-target + +--- +name: test_trunc +legalized: true +regBankSelected: false +selected: false +tracksRegLiveness: true +liveins: +body: | + bb.0: + + ; CHECK: Bad machine code: Too few operands + %0:_(s32) = G_TRUNC + + %1:_(s64) = G_IMPLICIT_DEF + + ; CHECK: Bad machine code: Too few operands + ; CHECK: Bad machine code: Explicit definition marked as use + G_TRUNC %1 + +...