[llvm] MachineVerifier: Reject extra non-register operands on instructions (PR #73758)

Matt Arsenault via llvm-commits llvm-commits at lists.llvm.org
Thu Nov 30 05:12:27 PST 2023


https://github.com/arsenm updated https://github.com/llvm/llvm-project/pull/73758

>From 89b240cb2330fa550d43ea287a1c3abd80d7a357 Mon Sep 17 00:00:00 2001
From: Matt Arsenault <Matthew.Arsenault at amd.com>
Date: Wed, 29 Nov 2023 14:45:59 +0900
Subject: [PATCH 1/2] MachineVerifier: Reject extra non-register operands on
 instructions

We were allowing extra immediate arguments, and only bothering to
check if registers were implicit or not.

Also consolidate extra operand checks in verifier, to make this
testable. We had 3 different places checking if you were trying
to build an instruction with more operands than allowed by the
definition. We had an assertion in addOperand, a direct check in the
MIRParser to avoid the assertion, and the machine verifier checks.
Remove the assert and parser check so the verifier can provide
a consistent verification experience, which will also handle instructions
modified in place.
---
 llvm/lib/CodeGen/MIRParser/MIParser.cpp       | 15 ++--------
 llvm/lib/CodeGen/MachineInstr.cpp             |  4 ---
 llvm/lib/CodeGen/MachineVerifier.cpp          |  4 +--
 llvm/lib/Target/MSP430/MSP430RegisterInfo.cpp |  1 +
 .../CodeGen/MIR/AMDGPU/extra-imm-operand.mir  | 13 --------
 .../CodeGen/MIR/AMDGPU/extra-reg-operand.mir  | 13 --------
 .../MachineVerifier/verify-implicit-def.mir   | 30 +++++++++++++++++++
 7 files changed, 36 insertions(+), 44 deletions(-)
 delete mode 100644 llvm/test/CodeGen/MIR/AMDGPU/extra-imm-operand.mir
 delete mode 100644 llvm/test/CodeGen/MIR/AMDGPU/extra-reg-operand.mir
 create mode 100644 llvm/test/MachineVerifier/verify-implicit-def.mir

diff --git a/llvm/lib/CodeGen/MIRParser/MIParser.cpp b/llvm/lib/CodeGen/MIRParser/MIParser.cpp
index f5d80b2ae27c233..f300b05727f7905 100644
--- a/llvm/lib/CodeGen/MIRParser/MIParser.cpp
+++ b/llvm/lib/CodeGen/MIRParser/MIParser.cpp
@@ -1175,19 +1175,10 @@ bool MIParser::parse(MachineInstr *&MI) {
   MI = MF.CreateMachineInstr(MCID, DebugLocation, /*NoImplicit=*/true);
   MI->setFlags(Flags);
 
-  unsigned NumExplicitOps = 0;
-  for (const auto &Operand : Operands) {
-    bool IsImplicitOp = Operand.Operand.isReg() && Operand.Operand.isImplicit();
-    if (!IsImplicitOp) {
-      if (!MCID.isVariadic() && NumExplicitOps >= MCID.getNumOperands() &&
-          !Operand.Operand.isValidExcessOperand())
-        return error(Operand.Begin, "too many operands for instruction");
-
-      ++NumExplicitOps;
-    }
-
+  // Don't check the operands make sense, let the verifier catch any
+  // improprieties.
+  for (const auto &Operand : Operands)
     MI->addOperand(MF, Operand.Operand);
-  }
 
   if (assignRegisterTies(*MI, Operands))
     return true;
diff --git a/llvm/lib/CodeGen/MachineInstr.cpp b/llvm/lib/CodeGen/MachineInstr.cpp
index 9e7b4df2576feee..27eae372f8ad764 100644
--- a/llvm/lib/CodeGen/MachineInstr.cpp
+++ b/llvm/lib/CodeGen/MachineInstr.cpp
@@ -231,10 +231,6 @@ void MachineInstr::addOperand(MachineFunction &MF, const MachineOperand &Op) {
   // OpNo now points as the desired insertion point.  Unless this is a variadic
   // instruction, only implicit regs are allowed beyond MCID->getNumOperands().
   // RegMask operands go between the explicit and implicit operands.
-  assert((MCID->isVariadic() || OpNo < MCID->getNumOperands() ||
-          Op.isValidExcessOperand()) &&
-         "Trying to add an operand to a machine instr that is already done!");
-
   MachineRegisterInfo *MRI = getRegInfo();
 
   // Determine if the Operands array needs to be reallocated.
diff --git a/llvm/lib/CodeGen/MachineVerifier.cpp b/llvm/lib/CodeGen/MachineVerifier.cpp
index 729dfc67491ee14..aaf9bd740d1379d 100644
--- a/llvm/lib/CodeGen/MachineVerifier.cpp
+++ b/llvm/lib/CodeGen/MachineVerifier.cpp
@@ -2126,9 +2126,9 @@ MachineVerifier::visitMachineOperand(const MachineOperand *MO, unsigned MONum) {
       }
     } else if (MO->isReg() && MO->isTied())
       report("Explicit operand should not be tied", MO, MONum);
-  } else {
+  } else if (!MI->isVariadic()) {
     // ARM adds %reg0 operands to indicate predicates. We'll allow that.
-    if (MO->isReg() && !MO->isImplicit() && !MI->isVariadic() && MO->getReg())
+    if (!MO->isValidExcessOperand())
       report("Extra explicit operand on non-variadic instruction", MO, MONum);
   }
 
diff --git a/llvm/lib/Target/MSP430/MSP430RegisterInfo.cpp b/llvm/lib/Target/MSP430/MSP430RegisterInfo.cpp
index 4ee40f47b8c19ec..f3900c990469ffc 100644
--- a/llvm/lib/Target/MSP430/MSP430RegisterInfo.cpp
+++ b/llvm/lib/Target/MSP430/MSP430RegisterInfo.cpp
@@ -134,6 +134,7 @@ MSP430RegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
 
     MI.setDesc(TII.get(MSP430::MOV16rr));
     MI.getOperand(FIOperandNum).ChangeToRegister(BasePtr, false);
+    MI.removeOperand(FIOperandNum + 1);
 
     if (Offset == 0)
       return false;
diff --git a/llvm/test/CodeGen/MIR/AMDGPU/extra-imm-operand.mir b/llvm/test/CodeGen/MIR/AMDGPU/extra-imm-operand.mir
deleted file mode 100644
index 65cb32cdd9aebfe..000000000000000
--- a/llvm/test/CodeGen/MIR/AMDGPU/extra-imm-operand.mir
+++ /dev/null
@@ -1,13 +0,0 @@
-# RUN: not llc -march=amdgcn -run-pass=none -o /dev/null %s 2>&1 | \
-# RUN:   FileCheck --strict-whitespace %s
-
----
-name: extra_imm_operand
-body: |
-  bb.0:
-    ; CHECK: [[@LINE+3]]:17: too many operands for instruction
-    ; CHECK-NEXT: {{^}}    S_ENDPGM 0, 0
-    ; CHECK-NEXT: {{^}}                ^
-    S_ENDPGM 0, 0
-
-...
diff --git a/llvm/test/CodeGen/MIR/AMDGPU/extra-reg-operand.mir b/llvm/test/CodeGen/MIR/AMDGPU/extra-reg-operand.mir
deleted file mode 100644
index d6b2522542a82dd..000000000000000
--- a/llvm/test/CodeGen/MIR/AMDGPU/extra-reg-operand.mir
+++ /dev/null
@@ -1,13 +0,0 @@
-# RUN: not llc -march=amdgcn -run-pass=none -o /dev/null %s 2>&1 | \
-# RUN:   FileCheck --strict-whitespace %s
-
----
-name: extra_reg_operand
-body: |
-  bb.0:
-    ; CHECK: [[@LINE+3]]:17: too many operands for instruction
-    ; CHECK-NEXT: {{^}}    S_ENDPGM 0, undef $vgpr0
-    ; CHECK-NEXT: {{^}}                ^
-    S_ENDPGM 0, undef $vgpr0
-
-...
diff --git a/llvm/test/MachineVerifier/verify-implicit-def.mir b/llvm/test/MachineVerifier/verify-implicit-def.mir
new file mode 100644
index 000000000000000..8ca6f2dc75c01de
--- /dev/null
+++ b/llvm/test/MachineVerifier/verify-implicit-def.mir
@@ -0,0 +1,30 @@
+# REQUIRES: amdgpu-registered-target
+# RUN: not --crash llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx900 -run-pass=none -o /dev/null %s 2>&1 | FileCheck %s
+
+---
+name: invalid_reg_sequence
+tracksRegLiveness: true
+body:             |
+  bb.0:
+    ; CHECK:   *** Bad machine code: Too few operands ***
+    IMPLICIT_DEF
+
+    ; FIXME: Error message misleading
+    ; CHECK: *** Bad machine code: Explicit definition must be a register ***
+    IMPLICIT_DEF 0
+
+    ; CHECK: *** Bad machine code: Extra explicit operand on non-variadic instruction ***
+    %1:vgpr_32 = IMPLICIT_DEF 0
+
+    ; CHECK: *** Bad machine code: Extra explicit operand on non-variadic instruction ***
+    ; CHECK: *** Bad machine code: Extra explicit operand on non-variadic instruction ***
+    %2:vgpr_32 = IMPLICIT_DEF 0, 1
+
+    ; CHECK: *** Bad machine code: Extra explicit operand on non-variadic instruction ***
+    %3:vgpr_32 = IMPLICIT_DEF %1
+
+    ; CHECK-NOT: Bad machine code
+    %4:vgpr_32 = IMPLICIT_DEF implicit %1
+...
+
+

>From 046d8490232d863eea7ace1725fbc9d18eac1ade Mon Sep 17 00:00:00 2001
From: Matt Arsenault <Matthew.Arsenault at amd.com>
Date: Thu, 30 Nov 2023 22:10:58 +0900
Subject: [PATCH 2/2] Add comment

---
 llvm/lib/Target/MSP430/MSP430RegisterInfo.cpp | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/llvm/lib/Target/MSP430/MSP430RegisterInfo.cpp b/llvm/lib/Target/MSP430/MSP430RegisterInfo.cpp
index f3900c990469ffc..9cbc20e45179b71 100644
--- a/llvm/lib/Target/MSP430/MSP430RegisterInfo.cpp
+++ b/llvm/lib/Target/MSP430/MSP430RegisterInfo.cpp
@@ -134,6 +134,8 @@ MSP430RegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
 
     MI.setDesc(TII.get(MSP430::MOV16rr));
     MI.getOperand(FIOperandNum).ChangeToRegister(BasePtr, false);
+
+    // Remove the now unused Offset operand.
     MI.removeOperand(FIOperandNum + 1);
 
     if (Offset == 0)



More information about the llvm-commits mailing list