GlobalISel: Fix out of bounds crashes in verifier
llvm-svn: 351769
This commit is contained in:
parent
23e60c7893
commit
c19e17dd90
@ -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<LLT, 4> 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())
|
||||
|
||||
28
llvm/test/Verifier/test_g_add.mir
Normal file
28
llvm/test/Verifier/test_g_add.mir
Normal file
@ -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
|
||||
|
||||
...
|
||||
23
llvm/test/Verifier/test_g_trunc.mir
Normal file
23
llvm/test/Verifier/test_g_trunc.mir
Normal file
@ -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
|
||||
|
||||
...
|
||||
Loading…
x
Reference in New Issue
Block a user