Skip to content

Commit 8ec45c9

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

File tree

2 files changed

+68
-3
lines changed

2 files changed

+68
-3
lines changed
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
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+
def : Pat<
44+
(i64 (load (iPTR:$src))),
45+
(MY_LOAD $val, $src)
46+
>;
47+
48+
def MyTargetISA : InstrInfo;
49+
def MyTarget : Target { let InstructionSet = MyTargetISA; }
50+
51+
// ERROR-CHK: error: This type cast has zero arguments. It takes only one operand!

llvm/utils/TableGen/Common/CodeGenDAGPatterns.cpp

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3012,7 +3012,15 @@ 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+
PrintFatalError(
3020+
"This type cast has zero arguments. It takes only one operand!");
3021+
return std::nullopt;
3022+
}
3023+
30163024
if (Dag->getNumArgs() != 1)
30173025
error("Type cast only takes one operand!");
30183026

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

30303041
size_t NumTypes = New->getNumTypes();
30313042
if (LI->empty() || LI->size() != NumTypes)
@@ -3050,7 +3061,10 @@ TreePatternNodePtr TreePattern::ParseTreePattern(const Init *TheInit,
30503061
if (Operator->isSubClassOf("ValueType")) {
30513062
// If the operator is a ValueType, then this must be "type cast" of a leaf
30523063
// node.
3053-
TreePatternNodePtr New = ParseCastOperand(Dag, OpName);
3064+
auto MaybeNew = ParseCastOperand(Dag, OpName);
3065+
if (!MaybeNew)
3066+
return nullptr;
3067+
TreePatternNodePtr New = *MaybeNew;
30543068

30553069
if (New->getNumTypes() != 1)
30563070
error("ValueType cast can only have one type!");

0 commit comments

Comments
 (0)