aboutsummaryrefslogtreecommitdiff
path: root/llvm/utils/TableGen/Common/CodeGenDAGPatterns.cpp
diff options
context:
space:
mode:
authorStephen Chou <stephenchouca@users.noreply.github.com>2024-10-01 00:17:00 -0700
committerGitHub <noreply@github.com>2024-10-01 11:17:00 +0400
commitec61311e77b39fc7f9b45ffdb8a29b2d96f67265 (patch)
treeaddce6c6aaec31adb7fd6a5d160ef3eb9b70d4ef /llvm/utils/TableGen/Common/CodeGenDAGPatterns.cpp
parent2da417e7f6149f0f1079a8162fb25161b8a80332 (diff)
downloadllvm-ec61311e77b39fc7f9b45ffdb8a29b2d96f67265.zip
llvm-ec61311e77b39fc7f9b45ffdb8a29b2d96f67265.tar.gz
llvm-ec61311e77b39fc7f9b45ffdb8a29b2d96f67265.tar.bz2
[LLVM][TableGen] Support type casts of nodes with multiple results (#109728)
Currently, type casts can only be used to pattern match for intrinsics with a single overloaded return value. For instance: ``` def int_foo : Intrinsic<[llvm_anyint_ty], []>; def : Pat<(i32 (int_foo)), ...>; ``` This patch extends type casts to support matching intrinsics with multiple overloaded return values. As an example, the following defines a pattern that matches only if the overloaded intrinsic call returns an `i16` for the first result and an `i32` for the second result: ``` def int_bar : Intrinsic<[llvm_anyint_ty, llvm_anyint_ty], []>; def : Pat<([i16, i32] (int_bar)), ...>; ```
Diffstat (limited to 'llvm/utils/TableGen/Common/CodeGenDAGPatterns.cpp')
-rw-r--r--llvm/utils/TableGen/Common/CodeGenDAGPatterns.cpp44
1 files changed, 35 insertions, 9 deletions
diff --git a/llvm/utils/TableGen/Common/CodeGenDAGPatterns.cpp b/llvm/utils/TableGen/Common/CodeGenDAGPatterns.cpp
index e8cf7e3..dd728da 100644
--- a/llvm/utils/TableGen/Common/CodeGenDAGPatterns.cpp
+++ b/llvm/utils/TableGen/Common/CodeGenDAGPatterns.cpp
@@ -2886,6 +2886,35 @@ TreePatternNodePtr TreePattern::ParseTreePattern(Init *TheInit,
error("Pattern has unexpected init kind!");
return nullptr;
}
+
+ auto ParseCastOperand = [this](DagInit *Dag, StringRef OpName) {
+ if (Dag->getNumArgs() != 1)
+ error("Type cast only takes one operand!");
+
+ if (!OpName.empty())
+ error("Type cast should not have a name!");
+
+ return ParseTreePattern(Dag->getArg(0), Dag->getArgNameStr(0));
+ };
+
+ if (ListInit *LI = dyn_cast<ListInit>(Dag->getOperator())) {
+ // If the operator is a list (of value types), then this must be "type cast"
+ // of a leaf node with multiple results.
+ TreePatternNodePtr New = ParseCastOperand(Dag, OpName);
+
+ size_t NumTypes = New->getNumTypes();
+ if (LI->empty() || LI->size() != NumTypes)
+ error("Invalid number of type casts!");
+
+ // Apply the type casts.
+ const CodeGenHwModes &CGH = getDAGPatterns().getTargetInfo().getHwModes();
+ for (unsigned i = 0; i < std::min(NumTypes, LI->size()); ++i)
+ New->UpdateNodeType(
+ i, getValueTypeByHwMode(LI->getElementAsRecord(i), CGH), *this);
+
+ return New;
+ }
+
DefInit *OpDef = dyn_cast<DefInit>(Dag->getOperator());
if (!OpDef) {
error("Pattern has unexpected operator type!");
@@ -2896,20 +2925,15 @@ TreePatternNodePtr TreePattern::ParseTreePattern(Init *TheInit,
if (Operator->isSubClassOf("ValueType")) {
// If the operator is a ValueType, then this must be "type cast" of a leaf
// node.
- if (Dag->getNumArgs() != 1)
- error("Type cast only takes one operand!");
+ TreePatternNodePtr New = ParseCastOperand(Dag, OpName);
- TreePatternNodePtr New =
- ParseTreePattern(Dag->getArg(0), Dag->getArgNameStr(0));
+ if (New->getNumTypes() != 1)
+ error("ValueType cast can only have one type!");
// Apply the type cast.
- if (New->getNumTypes() != 1)
- error("Type cast can only have one type!");
const CodeGenHwModes &CGH = getDAGPatterns().getTargetInfo().getHwModes();
New->UpdateNodeType(0, getValueTypeByHwMode(Operator, CGH), *this);
- if (!OpName.empty())
- error("ValueType cast should not have a name!");
return New;
}
@@ -4223,8 +4247,10 @@ void CodeGenDAGPatterns::ParseOnePattern(
Pattern.InlinePatternFragments();
Result.InlinePatternFragments();
- if (Result.getNumTrees() != 1)
+ if (Result.getNumTrees() != 1) {
Result.error("Cannot use multi-alternative fragments in result pattern!");
+ return;
+ }
// Infer types.
bool IterateInference;