[llvm] [GlobalISel] Add GIM_CheckMachineOperandType for matching metadata operands (PR #191389)

Sameer Sahasrabuddhe via llvm-commits llvm-commits at lists.llvm.org
Thu Apr 23 00:16:54 PDT 2026


https://github.com/ssahasra updated https://github.com/llvm/llvm-project/pull/191389

>From 4d7615b8615fc68a64f1ae696e37f4ca9c9cbcbc Mon Sep 17 00:00:00 2001
From: Sameer Sahasrabuddhe <sameer.sahasrabuddhe at amd.com>
Date: Fri, 10 Apr 2026 14:24:34 +0530
Subject: [PATCH 1/3] [GlobalISel] Add GIM_CheckMachineOperandType for matching
 metadata operands

Add a new match table opcode GIM_CheckMachineOperandType and a
corresponding MachineOperandTypeMatcher class to support matching
operands by their MachineOperand type. This enables GlobalISel pattern
matching for intrinsics that have metadata operands (MVT::Metadata),
which previously could not be matched in the generated selector.

This is patch was extracted from #172090.

Co-authored-by: macurtis-amd <macurtis at amd.com>
Assisted-by: Claude Opus 4.6
---
 .../CodeGen/GlobalISel/GIMatchTableExecutor.h  |  6 ++++++
 .../GlobalISel/GIMatchTableExecutorImpl.h      |  9 +++++++++
 .../Common/GlobalISel/GlobalISelMatchTable.cpp | 17 +++++++++++++++++
 .../Common/GlobalISel/GlobalISelMatchTable.h   | 18 ++++++++++++++++++
 4 files changed, 50 insertions(+)

diff --git a/llvm/include/llvm/CodeGen/GlobalISel/GIMatchTableExecutor.h b/llvm/include/llvm/CodeGen/GlobalISel/GIMatchTableExecutor.h
index 3a2509345b776..f21923827039c 100644
--- a/llvm/include/llvm/CodeGen/GlobalISel/GIMatchTableExecutor.h
+++ b/llvm/include/llvm/CodeGen/GlobalISel/GIMatchTableExecutor.h
@@ -246,6 +246,12 @@ enum {
   /// - SizeInBits(ULEB128) - The size of the pointer value in bits.
   GIM_CheckPointerToAny,
 
+  /// Check the machine type of the specified operand
+  /// - InsnID(ULEB128) - Instruction ID
+  /// - OpIdx(ULEB128) - Operand index
+  /// - MachineOperandType(ULEB128) - Expected type
+  GIM_CheckMachineOperandType,
+
   /// Check the register bank for the specified operand
   /// - InsnID(ULEB128) - Instruction ID
   /// - OpIdx(ULEB128) - Operand index
diff --git a/llvm/include/llvm/CodeGen/GlobalISel/GIMatchTableExecutorImpl.h b/llvm/include/llvm/CodeGen/GlobalISel/GIMatchTableExecutorImpl.h
index 8f6586e79d78a..3d6dd9e62f963 100644
--- a/llvm/include/llvm/CodeGen/GlobalISel/GIMatchTableExecutorImpl.h
+++ b/llvm/include/llvm/CodeGen/GlobalISel/GIMatchTableExecutorImpl.h
@@ -768,6 +768,15 @@ bool GIMatchTableExecutor::executeMatchTable(
 
       break;
     }
+    case GIM_CheckMachineOperandType: {
+      uint64_t InsnID = readULEB();
+      uint64_t OpIdx = readULEB();
+      uint64_t MOTy = readULEB();
+      MachineOperand &MO = State.MIs[InsnID]->getOperand(OpIdx);
+      if (MO.getType() != MOTy)
+        return false;
+      break;
+    }
     case GIM_RecordNamedOperand: {
       uint64_t InsnID = readULEB();
       uint64_t OpIdx = readULEB();
diff --git a/llvm/utils/TableGen/Common/GlobalISel/GlobalISelMatchTable.cpp b/llvm/utils/TableGen/Common/GlobalISel/GlobalISelMatchTable.cpp
index 1968097f91983..b642a5fe70d63 100644
--- a/llvm/utils/TableGen/Common/GlobalISel/GlobalISelMatchTable.cpp
+++ b/llvm/utils/TableGen/Common/GlobalISel/GlobalISelMatchTable.cpp
@@ -1493,6 +1493,12 @@ Error OperandMatcher::addTypeCheckPredicate(const TypeSetByHwMode &VTy,
     return Error::success();
   }
 
+  llvm::MVT::SimpleValueType STy = VTy.getMachineValueType().SimpleTy;
+  if (STy == MVT::Metadata) {
+    addPredicate<MachineOperandTypeMatcher>(MachineOperand::MO_Metadata);
+    return Error::success();
+  }
+
   auto OpTyOrNone = MVTToLLT(VTy.getMachineValueType().SimpleTy);
   if (!OpTyOrNone)
     return failUnsupported("unsupported type");
@@ -1958,6 +1964,17 @@ bool InstructionOperandMatcher::isHigherPriorityThan(
   return false;
 }
 
+//===- MachineOperandTypeMatcher -----------------------------------------===//
+
+void MachineOperandTypeMatcher::emitPredicateOpcodes(MatchTable &Table,
+                                                     RuleMatcher &Rule) const {
+  Table << MatchTable::Opcode("GIM_CheckMachineOperandType")
+        << MatchTable::Comment("MI") << MatchTable::ULEB128Value(InsnVarID)
+        << MatchTable::Comment("Op") << MatchTable::ULEB128Value(OpIdx)
+        << MatchTable::Comment("Ty") << MatchTable::ULEB128Value(MOTy)
+        << MatchTable::LineBreak;
+}
+
 //===- OperandRenderer ----------------------------------------------------===//
 
 OperandRenderer::~OperandRenderer() = default;
diff --git a/llvm/utils/TableGen/Common/GlobalISel/GlobalISelMatchTable.h b/llvm/utils/TableGen/Common/GlobalISel/GlobalISelMatchTable.h
index 4749139049861..d58e7a603f651 100644
--- a/llvm/utils/TableGen/Common/GlobalISel/GlobalISelMatchTable.h
+++ b/llvm/utils/TableGen/Common/GlobalISel/GlobalISelMatchTable.h
@@ -23,6 +23,7 @@
 #include "llvm/ADT/SmallPtrSet.h"
 #include "llvm/ADT/StringMap.h"
 #include "llvm/ADT/StringRef.h"
+#include "llvm/CodeGen/MachineOperand.h"
 #include "llvm/CodeGenTypes/LowLevelType.h"
 #include "llvm/Support/Error.h"
 #include "llvm/Support/SaveAndRestore.h"
@@ -860,6 +861,7 @@ class PredicateMatcher {
     OPM_MBB,
     OPM_RecordNamedOperand,
     OPM_RecordRegType,
+    OPM_MOType,
   };
 
 protected:
@@ -1963,6 +1965,22 @@ class InstructionOperandMatcher : public OperandPredicateMatcher {
   }
 };
 
+class MachineOperandTypeMatcher : public OperandPredicateMatcher {
+  const MachineOperand::MachineOperandType MOTy;
+
+public:
+  MachineOperandTypeMatcher(unsigned InsnVarID, unsigned OpIdx,
+                            MachineOperand::MachineOperandType MOTy)
+      : OperandPredicateMatcher(OPM_MOType, InsnVarID, OpIdx), MOTy(MOTy) {}
+
+  static bool classof(const PredicateMatcher *P) {
+    return P->getKind() == OPM_MOType;
+  }
+
+  void emitPredicateOpcodes(MatchTable &Table,
+                            RuleMatcher &Rule) const override;
+};
+
 //===- Actions ------------------------------------------------------------===//
 class OperandRenderer {
 public:

>From 1eb568a36cb446f338c0ead9891eb81361848974 Mon Sep 17 00:00:00 2001
From: Sameer Sahasrabuddhe <sameer.sahasrabuddhe at amd.com>
Date: Thu, 23 Apr 2026 12:35:31 +0530
Subject: [PATCH 2/3] Revert "[GlobalISel] Add GIM_CheckMachineOperandType for
 matching metadata operands"

This reverts commit 4d7615b8615fc68a64f1ae696e37f4ca9c9cbcbc.
---
 .../CodeGen/GlobalISel/GIMatchTableExecutor.h  |  6 ------
 .../GlobalISel/GIMatchTableExecutorImpl.h      |  9 ---------
 .../Common/GlobalISel/GlobalISelMatchTable.cpp | 17 -----------------
 .../Common/GlobalISel/GlobalISelMatchTable.h   | 18 ------------------
 4 files changed, 50 deletions(-)

diff --git a/llvm/include/llvm/CodeGen/GlobalISel/GIMatchTableExecutor.h b/llvm/include/llvm/CodeGen/GlobalISel/GIMatchTableExecutor.h
index f21923827039c..3a2509345b776 100644
--- a/llvm/include/llvm/CodeGen/GlobalISel/GIMatchTableExecutor.h
+++ b/llvm/include/llvm/CodeGen/GlobalISel/GIMatchTableExecutor.h
@@ -246,12 +246,6 @@ enum {
   /// - SizeInBits(ULEB128) - The size of the pointer value in bits.
   GIM_CheckPointerToAny,
 
-  /// Check the machine type of the specified operand
-  /// - InsnID(ULEB128) - Instruction ID
-  /// - OpIdx(ULEB128) - Operand index
-  /// - MachineOperandType(ULEB128) - Expected type
-  GIM_CheckMachineOperandType,
-
   /// Check the register bank for the specified operand
   /// - InsnID(ULEB128) - Instruction ID
   /// - OpIdx(ULEB128) - Operand index
diff --git a/llvm/include/llvm/CodeGen/GlobalISel/GIMatchTableExecutorImpl.h b/llvm/include/llvm/CodeGen/GlobalISel/GIMatchTableExecutorImpl.h
index 3d6dd9e62f963..8f6586e79d78a 100644
--- a/llvm/include/llvm/CodeGen/GlobalISel/GIMatchTableExecutorImpl.h
+++ b/llvm/include/llvm/CodeGen/GlobalISel/GIMatchTableExecutorImpl.h
@@ -768,15 +768,6 @@ bool GIMatchTableExecutor::executeMatchTable(
 
       break;
     }
-    case GIM_CheckMachineOperandType: {
-      uint64_t InsnID = readULEB();
-      uint64_t OpIdx = readULEB();
-      uint64_t MOTy = readULEB();
-      MachineOperand &MO = State.MIs[InsnID]->getOperand(OpIdx);
-      if (MO.getType() != MOTy)
-        return false;
-      break;
-    }
     case GIM_RecordNamedOperand: {
       uint64_t InsnID = readULEB();
       uint64_t OpIdx = readULEB();
diff --git a/llvm/utils/TableGen/Common/GlobalISel/GlobalISelMatchTable.cpp b/llvm/utils/TableGen/Common/GlobalISel/GlobalISelMatchTable.cpp
index b642a5fe70d63..1968097f91983 100644
--- a/llvm/utils/TableGen/Common/GlobalISel/GlobalISelMatchTable.cpp
+++ b/llvm/utils/TableGen/Common/GlobalISel/GlobalISelMatchTable.cpp
@@ -1493,12 +1493,6 @@ Error OperandMatcher::addTypeCheckPredicate(const TypeSetByHwMode &VTy,
     return Error::success();
   }
 
-  llvm::MVT::SimpleValueType STy = VTy.getMachineValueType().SimpleTy;
-  if (STy == MVT::Metadata) {
-    addPredicate<MachineOperandTypeMatcher>(MachineOperand::MO_Metadata);
-    return Error::success();
-  }
-
   auto OpTyOrNone = MVTToLLT(VTy.getMachineValueType().SimpleTy);
   if (!OpTyOrNone)
     return failUnsupported("unsupported type");
@@ -1964,17 +1958,6 @@ bool InstructionOperandMatcher::isHigherPriorityThan(
   return false;
 }
 
-//===- MachineOperandTypeMatcher -----------------------------------------===//
-
-void MachineOperandTypeMatcher::emitPredicateOpcodes(MatchTable &Table,
-                                                     RuleMatcher &Rule) const {
-  Table << MatchTable::Opcode("GIM_CheckMachineOperandType")
-        << MatchTable::Comment("MI") << MatchTable::ULEB128Value(InsnVarID)
-        << MatchTable::Comment("Op") << MatchTable::ULEB128Value(OpIdx)
-        << MatchTable::Comment("Ty") << MatchTable::ULEB128Value(MOTy)
-        << MatchTable::LineBreak;
-}
-
 //===- OperandRenderer ----------------------------------------------------===//
 
 OperandRenderer::~OperandRenderer() = default;
diff --git a/llvm/utils/TableGen/Common/GlobalISel/GlobalISelMatchTable.h b/llvm/utils/TableGen/Common/GlobalISel/GlobalISelMatchTable.h
index d58e7a603f651..4749139049861 100644
--- a/llvm/utils/TableGen/Common/GlobalISel/GlobalISelMatchTable.h
+++ b/llvm/utils/TableGen/Common/GlobalISel/GlobalISelMatchTable.h
@@ -23,7 +23,6 @@
 #include "llvm/ADT/SmallPtrSet.h"
 #include "llvm/ADT/StringMap.h"
 #include "llvm/ADT/StringRef.h"
-#include "llvm/CodeGen/MachineOperand.h"
 #include "llvm/CodeGenTypes/LowLevelType.h"
 #include "llvm/Support/Error.h"
 #include "llvm/Support/SaveAndRestore.h"
@@ -861,7 +860,6 @@ class PredicateMatcher {
     OPM_MBB,
     OPM_RecordNamedOperand,
     OPM_RecordRegType,
-    OPM_MOType,
   };
 
 protected:
@@ -1965,22 +1963,6 @@ class InstructionOperandMatcher : public OperandPredicateMatcher {
   }
 };
 
-class MachineOperandTypeMatcher : public OperandPredicateMatcher {
-  const MachineOperand::MachineOperandType MOTy;
-
-public:
-  MachineOperandTypeMatcher(unsigned InsnVarID, unsigned OpIdx,
-                            MachineOperand::MachineOperandType MOTy)
-      : OperandPredicateMatcher(OPM_MOType, InsnVarID, OpIdx), MOTy(MOTy) {}
-
-  static bool classof(const PredicateMatcher *P) {
-    return P->getKind() == OPM_MOType;
-  }
-
-  void emitPredicateOpcodes(MatchTable &Table,
-                            RuleMatcher &Rule) const override;
-};
-
 //===- Actions ------------------------------------------------------------===//
 class OperandRenderer {
 public:

>From a9180cc77b847ab07421ce2567e35958c49e2c3c Mon Sep 17 00:00:00 2001
From: Sameer Sahasrabuddhe <sameer.sahasrabuddhe at amd.com>
Date: Thu, 23 Apr 2026 12:46:02 +0530
Subject: [PATCH 3/3] [GlobalISel] skip type check when matching metadata
 operand

---
 .../GlobalISelEmitter/metadata-operand.td     | 32 +++++++++++++++++++
 .../GlobalISel/GlobalISelMatchTable.cpp       |  6 ++++
 2 files changed, 38 insertions(+)
 create mode 100644 llvm/test/TableGen/GlobalISelEmitter/metadata-operand.td

diff --git a/llvm/test/TableGen/GlobalISelEmitter/metadata-operand.td b/llvm/test/TableGen/GlobalISelEmitter/metadata-operand.td
new file mode 100644
index 0000000000000..aee05d98dda4b
--- /dev/null
+++ b/llvm/test/TableGen/GlobalISelEmitter/metadata-operand.td
@@ -0,0 +1,32 @@
+// RUN: llvm-tblgen -gen-global-isel -warn-on-skipped-patterns -I %p/../../../include -I %p/../Common %s | FileCheck %s
+
+include "llvm/Target/Target.td"
+include "GlobalISelEmitterCommon.td"
+
+// No type check for a metadata operand matched via srcvalue.
+
+def int_tgt_metadata_intrinsic : Intrinsic<
+  [llvm_i32_ty],
+  [llvm_ptr_ty, llvm_metadata_ty],
+  []>;
+
+def metadata_intrin_pat : PatFrag<
+  (ops node:$ptr),
+  (int_tgt_metadata_intrinsic $ptr, srcvalue)>;
+
+def LOAD : I<(outs GPR32:$dst), (ins GPR32Op:$src), []>;
+
+// CHECK: GIM_CheckOpcode, /*MI*/0, GIMT_Encode2(TargetOpcode::G_INTRINSIC_W_SIDE_EFFECTS),
+// CHECK-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/4,
+// CHECK-NEXT: GIM_CheckIntrinsicID, /*MI*/0, /*Op*/1, GIMT_Encode2(Intrinsic::tgt_metadata_intrinsic),
+// CHECK-NEXT: GIM_RootCheckType, /*Op*/0, /*Type*/GILLT_s32,
+// CHECK-NEXT: GIM_RootCheckRegBankForClass, /*Op*/0, /*RC*/GIMT_Encode2(MyTarget::GPR32RegClassID),
+// CHECK-NEXT: // MIs[0] src
+// CHECK-NEXT: GIM_CheckPointerToAny, /*MI*/0, /*Op*/2, /*SizeInBits*/32,
+// CHECK-NEXT: // MIs[0] Operand 3
+// No type check for the metadata operand
+// CHECK-NEXT: // No operand predicates
+def : Pat<
+  (i32 (metadata_intrin_pat p0:$src)),
+  (LOAD GPR32:$src)
+>;
diff --git a/llvm/utils/TableGen/Common/GlobalISel/GlobalISelMatchTable.cpp b/llvm/utils/TableGen/Common/GlobalISel/GlobalISelMatchTable.cpp
index faf58f9aab835..4ce1565b4c387 100644
--- a/llvm/utils/TableGen/Common/GlobalISel/GlobalISelMatchTable.cpp
+++ b/llvm/utils/TableGen/Common/GlobalISel/GlobalISelMatchTable.cpp
@@ -1547,6 +1547,12 @@ Error OperandMatcher::addTypeCheckPredicate(const TypeSetByHwMode &VTy,
     return Error::success();
   }
 
+  // Metadata operands have no LLT representation and no runtime type check is
+  // needed — they are guaranteed to be MO_Metadata by the IRTranslator. This
+  // mirrors how srcvalue is handled in importChildMatcher.
+  if (VTy.getMachineValueType() == MVT::Metadata)
+    return Error::success();
+
   auto OpTyOrNone = MVTToLLT(VTy.getMachineValueType().SimpleTy);
   if (!OpTyOrNone)
     return failUnsupported("unsupported type");



More information about the llvm-commits mailing list