aboutsummaryrefslogtreecommitdiff
path: root/llvm/utils
diff options
context:
space:
mode:
authorjyli0116 <yu.li@arm.com>2025-06-09 09:02:56 +0100
committerGitHub <noreply@github.com>2025-06-09 09:02:56 +0100
commitf3ffee601c1746eafa9a6684541e90d182c9126e (patch)
treee964933542e6bef4f5d383f05185f8846e14f3be /llvm/utils
parent2f15637e04f51e3ef435c0c0d39aab0e8b933023 (diff)
downloadllvm-f3ffee601c1746eafa9a6684541e90d182c9126e.zip
llvm-f3ffee601c1746eafa9a6684541e90d182c9126e.tar.gz
llvm-f3ffee601c1746eafa9a6684541e90d182c9126e.tar.bz2
[GISel][AArch64] Allow PatLeafs to be imported in GISel which were previously causing warnings (#140935)
Previously PatLeafs could not be imported, causing the following warnings to be emitted when running tblgen with `-warn-on-skipped-patterns:` ``` /work/clean/llvm/lib/Target/AArch64/AArch64InstrInfo.td:2631:1: warning: Skipped pattern: Src pattern child has unsupported predicate def : Pat<(i64 (mul top32Zero:$Rn, top32Zero:$Rm)), ^ ``` These changes allow the patterns to now be imported successfully.
Diffstat (limited to 'llvm/utils')
-rw-r--r--llvm/utils/TableGen/Common/CodeGenDAGPatterns.cpp21
-rw-r--r--llvm/utils/TableGen/Common/CodeGenDAGPatterns.h5
-rw-r--r--llvm/utils/TableGen/Common/GlobalISel/GlobalISelMatchTable.cpp15
-rw-r--r--llvm/utils/TableGen/Common/GlobalISel/GlobalISelMatchTable.h21
-rw-r--r--llvm/utils/TableGen/Common/GlobalISel/GlobalISelMatchTableExecutorEmitter.cpp4
-rw-r--r--llvm/utils/TableGen/Common/GlobalISel/GlobalISelMatchTableExecutorEmitter.h36
-rw-r--r--llvm/utils/TableGen/GlobalISelCombinerEmitter.cpp7
-rw-r--r--llvm/utils/TableGen/GlobalISelEmitter.cpp33
8 files changed, 132 insertions, 10 deletions
diff --git a/llvm/utils/TableGen/Common/CodeGenDAGPatterns.cpp b/llvm/utils/TableGen/Common/CodeGenDAGPatterns.cpp
index a87aa8b..d33c0db 100644
--- a/llvm/utils/TableGen/Common/CodeGenDAGPatterns.cpp
+++ b/llvm/utils/TableGen/Common/CodeGenDAGPatterns.cpp
@@ -899,6 +899,11 @@ TreePredicateFn::TreePredicateFn(TreePattern *N) : PatFragRec(N) {
assert(
(!hasPredCode() || !hasImmCode()) &&
".td file corrupt: can't have a node predicate *and* an imm predicate");
+
+ if (hasGISelPredicateCode() && hasGISelLeafPredicateCode())
+ PrintFatalError(getOrigPatFragRecord()->getRecord()->getLoc(),
+ ".td file corrupt: can't have GISelPredicateCode *and* "
+ "GISelLeafPredicateCode");
}
bool TreePredicateFn::hasPredCode() const {
@@ -1293,8 +1298,20 @@ bool TreePredicateFn::hasGISelPredicateCode() const {
}
std::string TreePredicateFn::getGISelPredicateCode() const {
- return std::string(
- PatFragRec->getRecord()->getValueAsString("GISelPredicateCode"));
+ return PatFragRec->getRecord()->getValueAsString("GISelPredicateCode").str();
+}
+
+bool TreePredicateFn::hasGISelLeafPredicateCode() const {
+ return PatFragRec->getRecord()
+ ->getValueAsOptionalString("GISelLeafPredicateCode")
+ .has_value();
+}
+
+std::string TreePredicateFn::getGISelLeafPredicateCode() const {
+ return PatFragRec->getRecord()
+ ->getValueAsOptionalString("GISelLeafPredicateCode")
+ .value_or(StringRef())
+ .str();
}
StringRef TreePredicateFn::getImmType() const {
diff --git a/llvm/utils/TableGen/Common/CodeGenDAGPatterns.h b/llvm/utils/TableGen/Common/CodeGenDAGPatterns.h
index 725414f..a5aadf2 100644
--- a/llvm/utils/TableGen/Common/CodeGenDAGPatterns.h
+++ b/llvm/utils/TableGen/Common/CodeGenDAGPatterns.h
@@ -590,6 +590,11 @@ public:
bool hasGISelPredicateCode() const;
std::string getGISelPredicateCode() const;
+ // If true, indicates that GlobalISel-based C++ code was supplied for checking
+ // register operands.
+ bool hasGISelLeafPredicateCode() const;
+ std::string getGISelLeafPredicateCode() const;
+
private:
bool hasPredCode() const;
bool hasImmCode() const;
diff --git a/llvm/utils/TableGen/Common/GlobalISel/GlobalISelMatchTable.cpp b/llvm/utils/TableGen/Common/GlobalISel/GlobalISelMatchTable.cpp
index 2cb3579..327ac5f 100644
--- a/llvm/utils/TableGen/Common/GlobalISel/GlobalISelMatchTable.cpp
+++ b/llvm/utils/TableGen/Common/GlobalISel/GlobalISelMatchTable.cpp
@@ -33,6 +33,8 @@ Error failUnsupported(const Twine &Reason) {
std::string getEnumNameForPredicate(const TreePredicateFn &Predicate) {
if (Predicate.hasGISelPredicateCode())
return "GICXXPred_MI_" + Predicate.getFnName();
+ if (Predicate.hasGISelLeafPredicateCode())
+ return "GICXXPred_MO_" + Predicate.getFnName();
return "GICXXPred_" + Predicate.getImmTypeIdentifier().str() + "_" +
Predicate.getFnName();
}
@@ -1326,6 +1328,19 @@ void OperandImmPredicateMatcher::emitPredicateOpcodes(MatchTable &Table,
<< MatchTable::LineBreak;
}
+//===- OperandLeafPredicateMatcher
+//-----------------------------------------===//
+
+void OperandLeafPredicateMatcher::emitPredicateOpcodes(
+ MatchTable &Table, RuleMatcher &Rule) const {
+ Table << MatchTable::Opcode("GIM_CheckLeafOperandPredicate")
+ << MatchTable::Comment("MI") << MatchTable::ULEB128Value(InsnVarID)
+ << MatchTable::Comment("MO") << MatchTable::ULEB128Value(OpIdx)
+ << MatchTable::Comment("Predicate")
+ << MatchTable::NamedValue(2, getEnumNameForPredicate(Predicate))
+ << MatchTable::LineBreak;
+}
+
//===- OperandMatcher -----------------------------------------------------===//
std::string OperandMatcher::getOperandExpr(unsigned InsnVarID) const {
diff --git a/llvm/utils/TableGen/Common/GlobalISel/GlobalISelMatchTable.h b/llvm/utils/TableGen/Common/GlobalISel/GlobalISelMatchTable.h
index fd24459..6647257 100644
--- a/llvm/utils/TableGen/Common/GlobalISel/GlobalISelMatchTable.h
+++ b/llvm/utils/TableGen/Common/GlobalISel/GlobalISelMatchTable.h
@@ -824,6 +824,7 @@ public:
IPM_OneUse,
IPM_GenericPredicate,
IPM_MIFlags,
+ OPM_LeafPredicate,
OPM_SameOperand,
OPM_ComplexPattern,
OPM_IntrinsicID,
@@ -1255,6 +1256,26 @@ public:
RuleMatcher &Rule) const override;
};
+/// Generates code to check that this operand is a register whose value meets
+/// the predicate.
+class OperandLeafPredicateMatcher : public OperandPredicateMatcher {
+protected:
+ TreePredicateFn Predicate;
+
+public:
+ OperandLeafPredicateMatcher(unsigned InsnVarID, unsigned OpIdx,
+ const TreePredicateFn &Predicate)
+ : OperandPredicateMatcher(OPM_LeafPredicate, InsnVarID, OpIdx),
+ Predicate(Predicate) {}
+
+ static bool classof(const PredicateMatcher *P) {
+ return P->getKind() == OPM_LeafPredicate;
+ }
+
+ void emitPredicateOpcodes(MatchTable &Table,
+ RuleMatcher &Rule) const override;
+};
+
/// Generates code to check that a set of predicates match for a particular
/// operand.
class OperandMatcher : public PredicateListMatcher<OperandPredicateMatcher> {
diff --git a/llvm/utils/TableGen/Common/GlobalISel/GlobalISelMatchTableExecutorEmitter.cpp b/llvm/utils/TableGen/Common/GlobalISel/GlobalISelMatchTableExecutorEmitter.cpp
index ffab2fd..333d956 100644
--- a/llvm/utils/TableGen/Common/GlobalISel/GlobalISelMatchTableExecutorEmitter.cpp
+++ b/llvm/utils/TableGen/Common/GlobalISel/GlobalISelMatchTableExecutorEmitter.cpp
@@ -182,6 +182,7 @@ void GlobalISelMatchTableExecutorEmitter::emitExecutorImpl(
emitSubtargetFeatureBitsetImpl(OS, Rules);
emitComplexPredicates(OS, ComplexOperandMatchers);
emitMIPredicateFns(OS);
+ emitLeafPredicateFns(OS);
emitI64ImmPredicateFns(OS);
emitAPFloatImmPredicateFns(OS);
emitAPIntImmPredicateFns(OS);
@@ -234,6 +235,9 @@ void GlobalISelMatchTableExecutorEmitter::emitTemporariesDecl(
<< " bool testMIPredicate_MI(unsigned PredicateID, const MachineInstr &MI"
", const MatcherState &State) "
"const override;\n"
+ << " bool testMOPredicate_MO(unsigned PredicateID, const MachineOperand "
+ "&MO, const MatcherState &State) "
+ "const override;\n"
<< " bool testSimplePredicate(unsigned PredicateID) const override;\n"
<< " bool runCustomAction(unsigned FnID, const MatcherState &State, "
"NewMIVector &OutMIs) "
diff --git a/llvm/utils/TableGen/Common/GlobalISel/GlobalISelMatchTableExecutorEmitter.h b/llvm/utils/TableGen/Common/GlobalISel/GlobalISelMatchTableExecutorEmitter.h
index 862f1e8..1f66d73 100644
--- a/llvm/utils/TableGen/Common/GlobalISel/GlobalISelMatchTableExecutorEmitter.h
+++ b/llvm/utils/TableGen/Common/GlobalISel/GlobalISelMatchTableExecutorEmitter.h
@@ -79,8 +79,8 @@ class GlobalISelMatchTableExecutorEmitter {
raw_ostream &OS, StringRef TypeIdentifier, StringRef ArgType,
StringRef ArgName, StringRef AdditionalArgs,
StringRef AdditionalDeclarations, ArrayRef<PredicateObject> Predicates,
- std::function<StringRef(PredicateObject)> GetPredEnumName,
- std::function<StringRef(PredicateObject)> GetPredCode,
+ llvm::function_ref<StringRef(PredicateObject)> GetPredEnumName,
+ llvm::function_ref<StringRef(PredicateObject)> GetPredCode,
StringRef Comment) {
if (!Comment.empty())
OS << "// " << Comment << "\n";
@@ -135,14 +135,34 @@ protected:
void emitMIPredicateFnsImpl(
raw_ostream &OS, StringRef AdditionalDecls,
ArrayRef<PredicateObject> Predicates,
- std::function<StringRef(PredicateObject)> GetPredEnumName,
- std::function<StringRef(PredicateObject)> GetPredCode,
+ llvm::function_ref<StringRef(PredicateObject)> GetPredEnumName,
+ llvm::function_ref<StringRef(PredicateObject)> GetPredCode,
StringRef Comment = "") {
return emitCxxPredicateFns(
OS, "MI", "const MachineInstr &", "MI", ", const MatcherState &State",
AdditionalDecls, Predicates, GetPredEnumName, GetPredCode, Comment);
}
+ /// Emits `testMOPredicate_MO`.
+ /// \tparam PredicateObject An object representing a predicate to emit.
+ /// \param OS Output stream.
+ /// \param AdditionalDecls Additional C++ variable declarations.
+ /// \param Predicates Predicates to emit.
+ /// \param GetPredEnumName Returns an enum name for a given predicate.
+ /// \param GetPredCode Returns the C++ code of a given predicate.
+ /// \param Comment Optional comment for the enum declaration.
+ template <typename PredicateObject>
+ void emitLeafPredicateFnsImpl(
+ raw_ostream &OS, StringRef AdditionalDecls,
+ ArrayRef<PredicateObject> Predicates,
+ llvm::function_ref<StringRef(PredicateObject)> GetPredEnumName,
+ llvm::function_ref<StringRef(PredicateObject)> GetPredCode,
+ StringRef Comment = "") {
+ return emitCxxPredicateFns(
+ OS, "MO", "const MachineOperand &", "MO", ", const MatcherState &State",
+ AdditionalDecls, Predicates, GetPredEnumName, GetPredCode, Comment);
+ }
+
/// Helper function to emit the following executor functions:
/// * testImmPredicate_I64 (TypeIdentifier=I64)
/// * testImmPredicate_APInt (TypeIdentifier=APInt)
@@ -160,8 +180,8 @@ protected:
void emitImmPredicateFnsImpl(
raw_ostream &OS, StringRef TypeIdentifier, StringRef ArgType,
ArrayRef<PredicateObject> Predicates,
- std::function<StringRef(PredicateObject)> GetPredEnumName,
- std::function<StringRef(PredicateObject)> GetPredCode,
+ llvm::function_ref<StringRef(PredicateObject)> GetPredEnumName,
+ llvm::function_ref<StringRef(PredicateObject)> GetPredCode,
StringRef Comment = "") {
return emitCxxPredicateFns(OS, TypeIdentifier, ArgType, "Imm", "", "",
Predicates, GetPredEnumName, GetPredCode,
@@ -189,6 +209,10 @@ public:
/// Note: `emitMIPredicateFnsImpl` can be used to do most of the work.
virtual void emitMIPredicateFns(raw_ostream &OS) = 0;
+ /// Emit the `testLeafPredicate` function
+ /// Note `emitLeafPredicateFnsImpl` can be used to do most of the work.
+ virtual void emitLeafPredicateFns(raw_ostream &OS) = 0;
+
/// Emit the `testImmPredicate_I64` function.
/// Note: `emitImmPredicateFnsImpl` can be used to do most of the work.
virtual void emitI64ImmPredicateFns(raw_ostream &OS) = 0;
diff --git a/llvm/utils/TableGen/GlobalISelCombinerEmitter.cpp b/llvm/utils/TableGen/GlobalISelCombinerEmitter.cpp
index afaf050..f62b265 100644
--- a/llvm/utils/TableGen/GlobalISelCombinerEmitter.cpp
+++ b/llvm/utils/TableGen/GlobalISelCombinerEmitter.cpp
@@ -2414,6 +2414,7 @@ class GICombinerEmitter final : public GlobalISelMatchTableExecutorEmitter {
void emitAdditionalImpl(raw_ostream &OS) override;
void emitMIPredicateFns(raw_ostream &OS) override;
+ void emitLeafPredicateFns(raw_ostream &OS) override;
void emitI64ImmPredicateFns(raw_ostream &OS) override;
void emitAPFloatImmPredicateFns(raw_ostream &OS) override;
void emitAPIntImmPredicateFns(raw_ostream &OS) override;
@@ -2581,6 +2582,12 @@ void GICombinerEmitter::emitMIPredicateFns(raw_ostream &OS) {
[](const CXXPredicateCode *C) -> StringRef { return C->Code; });
}
+void GICombinerEmitter::emitLeafPredicateFns(raw_ostream &OS) {
+ // Unused, but still needs to be called.
+ emitLeafPredicateFnsImpl<unsigned>(
+ OS, "", {}, [](unsigned) { return ""; }, [](unsigned) { return ""; });
+}
+
void GICombinerEmitter::emitI64ImmPredicateFns(raw_ostream &OS) {
// Unused, but still needs to be called.
emitImmPredicateFnsImpl<unsigned>(
diff --git a/llvm/utils/TableGen/GlobalISelEmitter.cpp b/llvm/utils/TableGen/GlobalISelEmitter.cpp
index 55f60db..5b61d6e 100644
--- a/llvm/utils/TableGen/GlobalISelEmitter.cpp
+++ b/llvm/utils/TableGen/GlobalISelEmitter.cpp
@@ -321,6 +321,7 @@ public:
void emitAdditionalImpl(raw_ostream &OS) override;
void emitMIPredicateFns(raw_ostream &OS) override;
+ void emitLeafPredicateFns(raw_ostream &OS) override;
void emitI64ImmPredicateFns(raw_ostream &OS) override;
void emitAPFloatImmPredicateFns(raw_ostream &OS) override;
void emitAPIntImmPredicateFns(raw_ostream &OS) override;
@@ -1110,8 +1111,16 @@ Error GlobalISelEmitter::importChildMatcher(
return Error::success();
}
- if (SrcChild.hasAnyPredicate())
- return failedImport("Src pattern child has unsupported predicate");
+ if (SrcChild.hasAnyPredicate()) {
+ for (const TreePredicateCall &Call : SrcChild.getPredicateCalls()) {
+ const TreePredicateFn &Predicate = Call.Fn;
+
+ if (!Predicate.hasGISelLeafPredicateCode())
+ return failedImport("Src pattern child has unsupported predicate");
+ OM.addPredicate<OperandLeafPredicateMatcher>(Predicate);
+ }
+ return Error::success();
+ }
// Check for constant immediates.
if (auto *ChildInt = dyn_cast<IntInit>(SrcChild.getLeafValue())) {
@@ -2293,6 +2302,26 @@ void GlobalISelEmitter::emitMIPredicateFns(raw_ostream &OS) {
"PatFrag predicates.");
}
+void GlobalISelEmitter::emitLeafPredicateFns(raw_ostream &OS) {
+ std::vector<const Record *> MatchedRecords;
+ llvm::copy_if(AllPatFrags, std::back_inserter(MatchedRecords),
+ [](const Record *R) {
+ return (!R->getValueAsOptionalString("GISelLeafPredicateCode")
+ .value_or(std::string())
+ .empty());
+ });
+ emitLeafPredicateFnsImpl<const Record *>(
+ OS,
+ " const auto &Operands = State.RecordedOperands;\n"
+ " Register Reg = MO.getReg();\n"
+ " (void)Operands;",
+ ArrayRef<const Record *>(MatchedRecords), &getPatFragPredicateEnumName,
+ [](const Record *R) {
+ return R->getValueAsString("GISelLeafPredicateCode");
+ },
+ "PatFrag predicates.");
+}
+
void GlobalISelEmitter::emitI64ImmPredicateFns(raw_ostream &OS) {
std::vector<const Record *> MatchedRecords;
llvm::copy_if(AllPatFrags, std::back_inserter(MatchedRecords),