[llvm] 49f55dd - [SystemZ] Improve verification of MachineOperands.

Jonas Paulsson via llvm-commits llvm-commits at lists.llvm.org
Mon Dec 16 09:53:02 PST 2019


Author: Jonas Paulsson
Date: 2019-12-16T09:51:54-08:00
New Revision: 49f55dda011ba80abeece9c44d667415eaf9ccb4

URL: https://github.com/llvm/llvm-project/commit/49f55dda011ba80abeece9c44d667415eaf9ccb4
DIFF: https://github.com/llvm/llvm-project/commit/49f55dda011ba80abeece9c44d667415eaf9ccb4.diff

LOG: [SystemZ]  Improve verification of MachineOperands.

Now that the machine verifier will check for cases of register/immediate
MachineOperands and their correspondence to the MC instruction descriptor,
this patch adds the operand types to the descriptors where they were
previously missing. All MCOI::OPERAND_UNKNOWN operand types have been handled
to get a known type, except for G_... (global isel) instructions.

Review: Ulrich Weigand
https://reviews.llvm.org/D71494

Added: 
    llvm/test/CodeGen/SystemZ/mverify-optypes.mir

Modified: 
    llvm/lib/Target/SystemZ/SystemZInstrInfo.cpp
    llvm/lib/Target/SystemZ/SystemZInstrInfo.h
    llvm/lib/Target/SystemZ/SystemZOperands.td

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/SystemZ/SystemZInstrInfo.cpp b/llvm/lib/Target/SystemZ/SystemZInstrInfo.cpp
index 785f1c81dfb8..181a50786a24 100644
--- a/llvm/lib/Target/SystemZ/SystemZInstrInfo.cpp
+++ b/llvm/lib/Target/SystemZ/SystemZInstrInfo.cpp
@@ -1748,6 +1748,28 @@ void SystemZInstrInfo::loadImmediate(MachineBasicBlock &MBB,
   BuildMI(MBB, MBBI, DL, get(Opcode), Reg).addImm(Value);
 }
 
+bool SystemZInstrInfo::verifyInstruction(const MachineInstr &MI,
+                                         StringRef &ErrInfo) const {
+  const MCInstrDesc &MCID = MI.getDesc();
+  for (unsigned I = 0, E = MI.getNumOperands(); I != E; ++I) {
+    if (I >= MCID.getNumOperands())
+      break;
+    const MachineOperand &Op = MI.getOperand(I);
+    const MCOperandInfo &MCOI = MCID.OpInfo[I];
+    // Addressing modes have register and immediate operands. Op should be a
+    // register (or frame index) operand if MCOI.RegClass contains a valid
+    // register class, or an immediate otherwise.
+    if (MCOI.OperandType == MCOI::OPERAND_MEMORY &&
+        ((MCOI.RegClass != -1 && !Op.isReg() && !Op.isFI()) ||
+         (MCOI.RegClass == -1 && !Op.isImm()))) {
+      ErrInfo = "Addressing mode operands corrupt!";
+      return false;
+    }
+  }
+
+  return true;
+}
+
 bool SystemZInstrInfo::
 areMemAccessesTriviallyDisjoint(const MachineInstr &MIa,
                                 const MachineInstr &MIb) const {

diff  --git a/llvm/lib/Target/SystemZ/SystemZInstrInfo.h b/llvm/lib/Target/SystemZ/SystemZInstrInfo.h
index 6c6a074bb831..4b4cfab1f8f2 100644
--- a/llvm/lib/Target/SystemZ/SystemZInstrInfo.h
+++ b/llvm/lib/Target/SystemZ/SystemZInstrInfo.h
@@ -322,6 +322,10 @@ class SystemZInstrInfo : public SystemZGenInstrInfo {
                      MachineBasicBlock::iterator MBBI,
                      unsigned Reg, uint64_t Value) const;
 
+  // Perform target specific instruction verification.
+  bool verifyInstruction(const MachineInstr &MI,
+                         StringRef &ErrInfo) const override;
+
   // Sometimes, it is possible for the target to tell, even without
   // aliasing information, that two MIs access 
diff erent memory
   // addresses. This function returns true if two MIs access 
diff erent

diff  --git a/llvm/lib/Target/SystemZ/SystemZOperands.td b/llvm/lib/Target/SystemZ/SystemZOperands.td
index b2bab68a6274..bd40f6d7bf40 100644
--- a/llvm/lib/Target/SystemZ/SystemZOperands.td
+++ b/llvm/lib/Target/SystemZ/SystemZOperands.td
@@ -25,6 +25,7 @@ class ImmediateOp<ValueType vt, string asmop> : Operand<vt> {
   let PrintMethod = "print"##asmop##"Operand";
   let DecoderMethod = "decode"##asmop##"Operand";
   let ParserMatchClass = !cast<AsmOperandClass>(asmop);
+  let OperandType = "OPERAND_IMMEDIATE";
 }
 
 class ImmOpWithPattern<ValueType vt, string asmop, code pred, SDNodeXForm xform,
@@ -63,13 +64,15 @@ class PCRelTLSAsmOperand<string size>
 
 // Constructs an operand for a PC-relative address with address type VT.
 // ASMOP is the associated asm operand.
-class PCRelOperand<ValueType vt, AsmOperandClass asmop> : Operand<vt> {
-  let PrintMethod = "printPCRelOperand";
-  let ParserMatchClass = asmop;
-}
-class PCRelTLSOperand<ValueType vt, AsmOperandClass asmop> : Operand<vt> {
-  let PrintMethod = "printPCRelTLSOperand";
-  let ParserMatchClass = asmop;
+let OperandType = "OPERAND_PCREL" in {
+  class PCRelOperand<ValueType vt, AsmOperandClass asmop> : Operand<vt> {
+    let PrintMethod = "printPCRelOperand";
+    let ParserMatchClass = asmop;
+  }
+  class PCRelTLSOperand<ValueType vt, AsmOperandClass asmop> : Operand<vt> {
+    let PrintMethod = "printPCRelTLSOperand";
+    let ParserMatchClass = asmop;
+  }
 }
 
 // Constructs both a DAG pattern and instruction operand for a PC-relative
@@ -105,6 +108,7 @@ class AddressOperand<string bitsize, string dispsize, string length,
   let EncoderMethod = "get"##format##dispsize##length##"Encoding";
   let DecoderMethod =
     "decode"##format##bitsize##"Disp"##dispsize##length##"Operand";
+  let OperandType = "OPERAND_MEMORY";
   let MIOperandInfo = operands;
   let ParserMatchClass =
     !cast<AddressAsmOperand>(format##bitsize##"Disp"##dispsize##length);
@@ -508,7 +512,8 @@ defm imm64zx48 : Immediate<i64, [{
   return isUInt<64>(N->getZExtValue());
 }], UIMM48, "U48Imm">;
 
-def imm64 : ImmLeaf<i64, [{}]>, Operand<i64>;
+let OperandType = "OPERAND_IMMEDIATE" in
+  def imm64 : ImmLeaf<i64, [{}]>, Operand<i64>;
 
 //===----------------------------------------------------------------------===//
 // Floating-point immediates
@@ -657,4 +662,5 @@ def bdvaddr12only     : BDVMode<            "64", "12">;
 def cond4 : PatLeaf<(i32 timm), [{ return (N->getZExtValue() < 16); }]>,
             Operand<i32> {
   let PrintMethod = "printCond4Operand";
+  let OperandType = "OPERAND_IMMEDIATE";
 }

diff  --git a/llvm/test/CodeGen/SystemZ/mverify-optypes.mir b/llvm/test/CodeGen/SystemZ/mverify-optypes.mir
new file mode 100644
index 000000000000..aebafd395623
--- /dev/null
+++ b/llvm/test/CodeGen/SystemZ/mverify-optypes.mir
@@ -0,0 +1,72 @@
+# RUN: not llc -mtriple=s390x-linux-gnu -mcpu=z14 -run-pass=none -o - %s \
+# RUN:  2>&1 | FileCheck %s
+# REQUIRES: asserts
+#
+# Test that the machine verifier catches wrong operand types.
+
+--- |
+  define anyregcc i64 @fun() { ret i64 0  }
+  @gsrc = global i16 2
+...
+---
+name:            fun
+alignment:       16
+tracksRegLiveness: true
+registers:
+  - { id: 0, class: gr64bit }
+frameInfo:
+  maxAlignment:    1
+machineFunctionInfo: {}
+body:             |
+  bb.0 (%ir-block.0):
+    liveins: $r2l
+    %0:gr64bit = LGHI $r2l
+    %1:addr64bit = LLILL $r2l
+    %2:addr64bit = LGFI $r2l
+    %3:addr64bit = LGFI 0
+
+    %3:addr64bit = AG %3, %1, 0, %2, implicit-def dead $cc
+    %3:addr64bit = AG %3, %1, %0, %2, implicit-def dead $cc
+    %3:addr64bit = AG %3, %1, 0, 2, implicit-def dead $cc
+
+    %4:addr64bit = LARL @gsrc
+    %4:addr64bit = LARL $r2l
+
+    MVCLoop %4, 0, %3, 0, 1680, %0, implicit-def $cc
+    MVCLoop %4, 0, %3, 0, %1, %0, implicit-def $cc
+
+    BCR 0, 0, $r2d, implicit $cc
+    BCR 0, $r2d, $r2d, implicit $cc
+    Return implicit $r2d
+
+...
+
+# CHECK: *** Bad machine code: Expected a non-register operand. ***
+# CHECK: - instruction: %0:gr64bit = LGHI $r2l
+# CHECK: - operand 1:   $r2l
+
+# CHECK: *** Bad machine code: Expected a non-register operand. ***
+# CHECK: - instruction: %1:addr64bit = LLILL $r2l
+# CHECK: - operand 1:   $r2l
+
+# CHECK: *** Bad machine code: Expected a non-register operand. ***
+# CHECK: - instruction: %2:addr64bit = LGFI $r2l
+# CHECK: - operand 1:   $r2l
+
+# CHECK: *** Bad machine code: Addressing mode operands corrupt! ***
+# CHECK: - instruction: %3:addr64bit = AG %3:addr64bit(tied-def 0), %1:addr64bit, %0:gr64bit, %2:addr64bit, implicit-def dead $cc
+
+# CHECK: *** Bad machine code: Addressing mode operands corrupt! ***
+# CHECK: - instruction: %3:addr64bit = AG %3:addr64bit(tied-def 0), %1:addr64bit, 0, 2, implicit-def dead $cc
+
+# CHECK: *** Bad machine code: Expected a non-register operand. ***
+# CHECK: - instruction: %4:addr64bit = LARL $r2l
+# CHECK: - operand 1:   $r2l
+
+# CHECK: *** Bad machine code: Expected a non-register operand. ***
+# CHECK: - instruction: MVCLoop %4:addr64bit, 0, %3:addr64bit, 0, %1:addr64bit, %0:gr64bit, implicit-def $cc
+# CHECK: - operand 4:   %1:addr64bit
+
+# CHECK: *** Bad machine code: Expected a non-register operand. ***
+# CHECK: - instruction: BCR 0, $r2d, $r2d, implicit $cc
+# CHECK: - operand 1:   $r2d


        


More information about the llvm-commits mailing list