[llvm] [TableGen] Use PrintFatalError in ParseTreePattern when DAG has zero operands, so that llvm-tblgen doesn't crash (PR #161417)
Prerona Chaudhuri via llvm-commits
llvm-commits at lists.llvm.org
Thu Oct 9 00:12:32 PDT 2025
https://github.com/pchaudhuri-nv updated https://github.com/llvm/llvm-project/pull/161417
>From ac4fd45ada23ab936c3890e802d99f8f825ae4d5 Mon Sep 17 00:00:00 2001
From: pchaudhuri-nv <prerona.chaudhuri16 at vit.edu>
Date: Tue, 30 Sep 2025 18:30:56 +0000
Subject: [PATCH] fic
---
llvm/test/TableGen/invalid_typecast_assert.td | 50 +++++++++++++++++++
.../TableGen/Common/CodeGenDAGPatterns.cpp | 30 ++++++++---
2 files changed, 74 insertions(+), 6 deletions(-)
create mode 100644 llvm/test/TableGen/invalid_typecast_assert.td
diff --git a/llvm/test/TableGen/invalid_typecast_assert.td b/llvm/test/TableGen/invalid_typecast_assert.td
new file mode 100644
index 0000000000000..22591851f224e
--- /dev/null
+++ b/llvm/test/TableGen/invalid_typecast_assert.td
@@ -0,0 +1,50 @@
+// The test incorrect classifies the pattern as a typecast and it ends up with
+// typecast DAG with zero arguements, leading to llvm-tblgen crash.
+// This test will check if the error is gracefully handled without any crash.
+
+// RUN: not llvm-tblgen -gen-dag-isel -I %p/../../include %s 2>&1 | FileCheck -check-prefix=ERROR-CHK %s
+
+include "llvm/Target/Target.td"
+
+class MyReg<string n>
+ : Register<n> {
+ let Namespace = "MyTarget";
+}
+
+def X0 : MyReg<"x0">;
+def X1 : MyReg<"x1">;
+
+def XRegs : RegisterClass<"MyTarget", [i64], 64, (add X0, X1)>;
+
+class TestInstruction : Instruction {
+ let Size = 2;
+ let Namespace = "MyTarget";
+ let hasSideEffects = false;
+ let hasExtraSrcRegAllocReq = false;
+ let hasExtraDefRegAllocReq = false;
+
+ field bits<16> Inst;
+ bits<3> dst;
+ bits<3> src;
+ bits<3> opcode;
+
+ let Inst{2-0} = dst;
+ let Inst{5-3} = src;
+ let Inst{7-5} = opcode;
+}
+
+def MY_LOAD : TestInstruction {
+ let OutOperandList = (outs XRegs:$dst);
+ let InOperandList = (ins ptr_rc:$ptr);
+ let AsmString = "my_load $dst, $ptr";
+ let opcode = 0;
+}
+
+// ERROR-CHK: [[@LINE+1]]:1: error: {{.*}} This type cast has zero arguments. It takes only one operand!
+def : Pat<
+ (i64 (load (iPTR:$src))),
+ (MY_LOAD $val, $src)
+>;
+
+def MyTargetISA : InstrInfo;
+def MyTarget : Target { let InstructionSet = MyTargetISA; }
diff --git a/llvm/utils/TableGen/Common/CodeGenDAGPatterns.cpp b/llvm/utils/TableGen/Common/CodeGenDAGPatterns.cpp
index 75bea77faba42..e30e459ca919d 100644
--- a/llvm/utils/TableGen/Common/CodeGenDAGPatterns.cpp
+++ b/llvm/utils/TableGen/Common/CodeGenDAGPatterns.cpp
@@ -3012,7 +3012,14 @@ TreePatternNodePtr TreePattern::ParseTreePattern(const Init *TheInit,
return nullptr;
}
- auto ParseCastOperand = [this](const DagInit *Dag, StringRef OpName) {
+ auto ParseCastOperand =
+ [this](const DagInit *Dag,
+ StringRef OpName) -> std::optional<TreePatternNodePtr> {
+ if (Dag->getNumArgs() == 0) {
+ error("This type cast has zero arguments. It takes only one operand!");
+ return std::nullopt;
+ }
+
if (Dag->getNumArgs() != 1)
error("Type cast only takes one operand!");
@@ -3025,7 +3032,10 @@ TreePatternNodePtr TreePattern::ParseTreePattern(const Init *TheInit,
if (const 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);
+ auto MaybeNew = ParseCastOperand(Dag, OpName);
+ if (!MaybeNew)
+ return nullptr;
+ TreePatternNodePtr New = *MaybeNew;
size_t NumTypes = New->getNumTypes();
if (LI->empty() || LI->size() != NumTypes)
@@ -3050,7 +3060,10 @@ TreePatternNodePtr TreePattern::ParseTreePattern(const Init *TheInit,
if (Operator->isSubClassOf("ValueType")) {
// If the operator is a ValueType, then this must be "type cast" of a leaf
// node.
- TreePatternNodePtr New = ParseCastOperand(Dag, OpName);
+ auto MaybeNew = ParseCastOperand(Dag, OpName);
+ if (!MaybeNew)
+ return nullptr;
+ TreePatternNodePtr New = *MaybeNew;
if (New->getNumTypes() != 1)
error("ValueType cast can only have one type!");
@@ -3608,10 +3621,15 @@ void CodeGenDAGPatterns::FindPatternInputsAndOutputs(
// If this is not a set, verify that the children nodes are not void typed,
// and recurse.
for (unsigned i = 0, e = Pat->getNumChildren(); i != e; ++i) {
- if (Pat->getChild(i).getNumTypes() == 0)
+ TreePatternNodePtr Child = Pat->getChildShared(i);
+ if (!Child) {
+ I.error("Child node at index " + Twine(i) + " is null!");
+ continue;
+ }
+ if (Child->getNumTypes() == 0)
I.error("Cannot have void nodes inside of patterns!");
- FindPatternInputsAndOutputs(I, Pat->getChildShared(i), InstInputs,
- InstResults, InstImpResults);
+ FindPatternInputsAndOutputs(I, Child, InstInputs, InstResults,
+ InstImpResults);
}
// If this is a non-leaf node with no children, treat it basically as if
More information about the llvm-commits
mailing list