[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