Skip to content

Commit edf5782

Browse files
authored
[TableGen] Check for duplicate register tuple definitions. (#95725)
Currently TableGen does not directly detect duplicate synthesized registers as can happen in this example: def GPR128 : RegisterTuples<[sub0, sub1, sub2, sub3], [(decimate (shl GPR32, 0), 1), (decimate (shl GPR32, 1), 1), (decimate (shl GPR32, 2), 1), (decimate (shl GPR32, 3), 1)]>; def GPR128_Aligned : RegisterTuples<[sub0, sub1, sub2, sub3], [(decimate (shl GPR32, 0), 4), (decimate (shl GPR32, 1), 4), (decimate (shl GPR32, 2), 4), (decimate (shl GPR32, 3), 4)]>; TableGen does fail, but with an unrelated and difficult to understand error that happens downstream of tuple expansion: "error: No SubRegIndex for R0_R1_R2_R3 in R0_R1_R2_R3". This patch detects the problem directly during expansion and emits an error pointing the user to the actual issue: "error: Register tuple redefines register 'R0_R1_R2_R3'".
1 parent 7e59b20 commit edf5782

File tree

2 files changed

+20
-0
lines changed

2 files changed

+20
-0
lines changed
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
// RUN: not llvm-tblgen -gen-register-info -I %p/../../include -I %p/Common %s 2>&1 | FileCheck %s
2+
3+
include "reg-with-subregs-common.td"
4+
5+
// CHECK: error: Register tuple redefines register 'R0_R1_R2_R3'
6+
def GPR128_Aligned : RegisterTuples<[sub0, sub1, sub2, sub3],
7+
[(decimate (shl GPR32, 0), 4),
8+
(decimate (shl GPR32, 1), 4),
9+
(decimate (shl GPR32, 2), 4),
10+
(decimate (shl GPR32, 3), 4)]>;

llvm/utils/TableGen/Common/CodeGenRegisters.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include "llvm/ADT/SmallSet.h"
2323
#include "llvm/ADT/SmallVector.h"
2424
#include "llvm/ADT/StringRef.h"
25+
#include "llvm/ADT/StringSet.h"
2526
#include "llvm/ADT/Twine.h"
2627
#include "llvm/Support/Debug.h"
2728
#include "llvm/Support/raw_ostream.h"
@@ -618,6 +619,9 @@ struct TupleExpander : SetTheory::Expander {
618619
// the synthesized definitions for their lifetime.
619620
std::vector<std::unique_ptr<Record>> &SynthDefs;
620621

622+
// Track all synthesized tuple names in order to detect duplicate definitions.
623+
llvm::StringSet<> TupleNames;
624+
621625
TupleExpander(std::vector<std::unique_ptr<Record>> &SynthDefs)
622626
: SynthDefs(SynthDefs) {}
623627

@@ -684,6 +688,12 @@ struct TupleExpander : SetTheory::Expander {
684688
Record *NewReg = SynthDefs.back().get();
685689
Elts.insert(NewReg);
686690

691+
// Detect duplicates among synthesized registers.
692+
const auto Res = TupleNames.insert(NewReg->getName());
693+
if (!Res.second)
694+
PrintFatalError(Def->getLoc(),
695+
"Register tuple redefines register '" + Name + "'.");
696+
687697
// Copy Proto super-classes.
688698
ArrayRef<std::pair<Record *, SMRange>> Supers = Proto->getSuperClasses();
689699
for (const auto &SuperPair : Supers)

0 commit comments

Comments
 (0)