Skip to content

Commit ac4fd45

Browse files
author
pchaudhuri-nv
committed
fic
1 parent 0a0d497 commit ac4fd45

File tree

2 files changed

+74
-6
lines changed

2 files changed

+74
-6
lines changed
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
// The test incorrect classifies the pattern as a typecast and it ends up with
2+
// typecast DAG with zero arguements, leading to llvm-tblgen crash.
3+
// This test will check if the error is gracefully handled without any crash.
4+
5+
// RUN: not llvm-tblgen -gen-dag-isel -I %p/../../include %s 2>&1 | FileCheck -check-prefix=ERROR-CHK %s
6+
7+
include "llvm/Target/Target.td"
8+
9+
class MyReg<string n>
10+
: Register<n> {
11+
let Namespace = "MyTarget";
12+
}
13+
14+
def X0 : MyReg<"x0">;
15+
def X1 : MyReg<"x1">;
16+
17+
def XRegs : RegisterClass<"MyTarget", [i64], 64, (add X0, X1)>;
18+
19+
class TestInstruction : Instruction {
20+
let Size = 2;
21+
let Namespace = "MyTarget";
22+
let hasSideEffects = false;
23+
let hasExtraSrcRegAllocReq = false;
24+
let hasExtraDefRegAllocReq = false;
25+
26+
field bits<16> Inst;
27+
bits<3> dst;
28+
bits<3> src;
29+
bits<3> opcode;
30+
31+
let Inst{2-0} = dst;
32+
let Inst{5-3} = src;
33+
let Inst{7-5} = opcode;
34+
}
35+
36+
def MY_LOAD : TestInstruction {
37+
let OutOperandList = (outs XRegs:$dst);
38+
let InOperandList = (ins ptr_rc:$ptr);
39+
let AsmString = "my_load $dst, $ptr";
40+
let opcode = 0;
41+
}
42+
43+
// ERROR-CHK: [[@LINE+1]]:1: error: {{.*}} This type cast has zero arguments. It takes only one operand!
44+
def : Pat<
45+
(i64 (load (iPTR:$src))),
46+
(MY_LOAD $val, $src)
47+
>;
48+
49+
def MyTargetISA : InstrInfo;
50+
def MyTarget : Target { let InstructionSet = MyTargetISA; }

llvm/utils/TableGen/Common/CodeGenDAGPatterns.cpp

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3012,7 +3012,14 @@ TreePatternNodePtr TreePattern::ParseTreePattern(const Init *TheInit,
30123012
return nullptr;
30133013
}
30143014

3015-
auto ParseCastOperand = [this](const DagInit *Dag, StringRef OpName) {
3015+
auto ParseCastOperand =
3016+
[this](const DagInit *Dag,
3017+
StringRef OpName) -> std::optional<TreePatternNodePtr> {
3018+
if (Dag->getNumArgs() == 0) {
3019+
error("This type cast has zero arguments. It takes only one operand!");
3020+
return std::nullopt;
3021+
}
3022+
30163023
if (Dag->getNumArgs() != 1)
30173024
error("Type cast only takes one operand!");
30183025

@@ -3025,7 +3032,10 @@ TreePatternNodePtr TreePattern::ParseTreePattern(const Init *TheInit,
30253032
if (const ListInit *LI = dyn_cast<ListInit>(Dag->getOperator())) {
30263033
// If the operator is a list (of value types), then this must be "type cast"
30273034
// of a leaf node with multiple results.
3028-
TreePatternNodePtr New = ParseCastOperand(Dag, OpName);
3035+
auto MaybeNew = ParseCastOperand(Dag, OpName);
3036+
if (!MaybeNew)
3037+
return nullptr;
3038+
TreePatternNodePtr New = *MaybeNew;
30293039

30303040
size_t NumTypes = New->getNumTypes();
30313041
if (LI->empty() || LI->size() != NumTypes)
@@ -3050,7 +3060,10 @@ TreePatternNodePtr TreePattern::ParseTreePattern(const Init *TheInit,
30503060
if (Operator->isSubClassOf("ValueType")) {
30513061
// If the operator is a ValueType, then this must be "type cast" of a leaf
30523062
// node.
3053-
TreePatternNodePtr New = ParseCastOperand(Dag, OpName);
3063+
auto MaybeNew = ParseCastOperand(Dag, OpName);
3064+
if (!MaybeNew)
3065+
return nullptr;
3066+
TreePatternNodePtr New = *MaybeNew;
30543067

30553068
if (New->getNumTypes() != 1)
30563069
error("ValueType cast can only have one type!");
@@ -3608,10 +3621,15 @@ void CodeGenDAGPatterns::FindPatternInputsAndOutputs(
36083621
// If this is not a set, verify that the children nodes are not void typed,
36093622
// and recurse.
36103623
for (unsigned i = 0, e = Pat->getNumChildren(); i != e; ++i) {
3611-
if (Pat->getChild(i).getNumTypes() == 0)
3624+
TreePatternNodePtr Child = Pat->getChildShared(i);
3625+
if (!Child) {
3626+
I.error("Child node at index " + Twine(i) + " is null!");
3627+
continue;
3628+
}
3629+
if (Child->getNumTypes() == 0)
36123630
I.error("Cannot have void nodes inside of patterns!");
3613-
FindPatternInputsAndOutputs(I, Pat->getChildShared(i), InstInputs,
3614-
InstResults, InstImpResults);
3631+
FindPatternInputsAndOutputs(I, Child, InstInputs, InstResults,
3632+
InstImpResults);
36153633
}
36163634

36173635
// If this is a non-leaf node with no children, treat it basically as if

0 commit comments

Comments
 (0)