Skip to content

Commit a35334d

Browse files
author
pchaudhuri-nv
committed
fic
1 parent 70970d0 commit a35334d

File tree

2 files changed

+71
-5
lines changed

2 files changed

+71
-5
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: {{.*}} type cast should not have zero arguments!
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: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1820,7 +1820,8 @@ bool TreePatternNode::UpdateNodeTypeFromInst(unsigned ResNo,
18201820
TreePattern &TP) {
18211821
// The 'unknown' operand indicates that types should be inferred from the
18221822
// context.
1823-
if (Operand->isSubClassOf("unknown_class"))
1823+
if (Operand->isSubClassOf("unknown_class") ||
1824+
Operand->isSubClassOf("PointerLikeRegClass"))
18241825
return false;
18251826

18261827
// The Operand class specifies a type directly.
@@ -3020,7 +3021,13 @@ TreePatternNodePtr TreePattern::ParseTreePattern(const Init *TheInit,
30203021
return nullptr;
30213022
}
30223023

3023-
auto ParseCastOperand = [this](const DagInit *Dag, StringRef OpName) {
3024+
auto ParseCastOperand = [this](const DagInit *Dag,
3025+
StringRef OpName) -> TreePatternNodePtr {
3026+
if (Dag->getNumArgs() == 0) {
3027+
error("type cast should not have zero arguments!");
3028+
return nullptr;
3029+
}
3030+
30243031
if (Dag->getNumArgs() != 1)
30253032
error("Type cast only takes one operand!");
30263033

@@ -3034,6 +3041,8 @@ TreePatternNodePtr TreePattern::ParseTreePattern(const Init *TheInit,
30343041
// If the operator is a list (of value types), then this must be "type cast"
30353042
// of a leaf node with multiple results.
30363043
TreePatternNodePtr New = ParseCastOperand(Dag, OpName);
3044+
if (!New)
3045+
return nullptr;
30373046

30383047
size_t NumTypes = New->getNumTypes();
30393048
if (LI->empty() || LI->size() != NumTypes)
@@ -3059,6 +3068,8 @@ TreePatternNodePtr TreePattern::ParseTreePattern(const Init *TheInit,
30593068
// If the operator is a ValueType, then this must be "type cast" of a leaf
30603069
// node.
30613070
TreePatternNodePtr New = ParseCastOperand(Dag, OpName);
3071+
if (!New)
3072+
return nullptr;
30623073

30633074
if (New->getNumTypes() != 1)
30643075
error("ValueType cast can only have one type!");
@@ -3608,10 +3619,15 @@ void CodeGenDAGPatterns::FindPatternInputsAndOutputs(
36083619
// If this is not a set, verify that the children nodes are not void typed,
36093620
// and recurse.
36103621
for (unsigned i = 0, e = Pat->getNumChildren(); i != e; ++i) {
3611-
if (Pat->getChild(i).getNumTypes() == 0)
3622+
TreePatternNodePtr Child = Pat->getChildShared(i);
3623+
if (!Child) {
3624+
I.error("child node at index " + Twine(i) + " is null!");
3625+
continue;
3626+
}
3627+
if (Child->getNumTypes() == 0)
36123628
I.error("Cannot have void nodes inside of patterns!");
3613-
FindPatternInputsAndOutputs(I, Pat->getChildShared(i), InstInputs,
3614-
InstResults, InstImpResults);
3629+
FindPatternInputsAndOutputs(I, Child, InstInputs, InstResults,
3630+
InstImpResults);
36153631
}
36163632

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

0 commit comments

Comments
 (0)