]> granicus.if.org Git - llvm/commitdiff
GlobalISel: Fix out of bounds crashes in verifier
authorMatt Arsenault <Matthew.Arsenault@amd.com>
Tue, 22 Jan 2019 00:29:37 +0000 (00:29 +0000)
committerMatt Arsenault <Matthew.Arsenault@amd.com>
Tue, 22 Jan 2019 00:29:37 +0000 (00:29 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@351769 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/MachineVerifier.cpp
test/Verifier/test_g_add.mir [new file with mode: 0644]
test/Verifier/test_g_trunc.mir [new file with mode: 0644]

index cc8f77e823d69fff50ed4b6d66c49a68504b3dac..b7e0f5754062d97aa4cb2776bf1048747b06fcfd 100644 (file)
@@ -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())
diff --git a/test/Verifier/test_g_add.mir b/test/Verifier/test_g_add.mir
new file mode 100644 (file)
index 0000000..54c470a
--- /dev/null
@@ -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 (file)
index 0000000..3a196bb
--- /dev/null
@@ -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
+
+...