Skip to content

Commit e0458a2

Browse files
authored
[LLVM][TableGen] Add error check for duplicate intrinsic names (#109226)
Check for duplicate intrinsic names in the intrinsic emitter backend and issue a fatal error if we find one.
1 parent bc3dfe7 commit e0458a2

File tree

3 files changed

+46
-3
lines changed

3 files changed

+46
-3
lines changed
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
// RUN: not llvm-tblgen -gen-intrinsic-impl -I %p/../../include %s -DTEST_INTRINSICS_SUPPRESS_DEFS 2>&1 | FileCheck %s -DFILE=%s
2+
3+
include "llvm/IR/Intrinsics.td"
4+
5+
def int_foo0 : Intrinsic<[llvm_anyint_ty], [], [], "llvm.foo">;
6+
7+
// CHECK: [[FILE]]:[[@LINE+2]]:5: error: Intrinsic `llvm.foo` is already defined
8+
// CHECK: [[FILE]]:[[@LINE-3]]:5: note: Previous definition here
9+
def int_foo1 : Intrinsic<[llvm_anyint_ty], [], [], "llvm.foo">;

llvm/utils/TableGen/Basic/CodeGenIntrinsics.cpp

Lines changed: 34 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,20 +47,51 @@ CodeGenIntrinsicTable::CodeGenIntrinsicTable(const RecordKeeper &RC) {
4747
Intrinsics.reserve(Defs.size());
4848

4949
for (const Record *Def : Defs)
50-
Intrinsics.push_back(CodeGenIntrinsic(Def, Ctx));
50+
Intrinsics.emplace_back(CodeGenIntrinsic(Def, Ctx));
5151

52+
// To ensure deterministic sorted order when duplicates are present, use
53+
// record ID as a tie-breaker similar to sortAndReportDuplicates in Utils.cpp.
5254
llvm::sort(Intrinsics,
5355
[](const CodeGenIntrinsic &LHS, const CodeGenIntrinsic &RHS) {
54-
return std::tie(LHS.TargetPrefix, LHS.Name) <
55-
std::tie(RHS.TargetPrefix, RHS.Name);
56+
unsigned LhsID = LHS.TheDef->getID();
57+
unsigned RhsID = RHS.TheDef->getID();
58+
return std::tie(LHS.TargetPrefix, LHS.Name, LhsID) <
59+
std::tie(RHS.TargetPrefix, RHS.Name, RhsID);
5660
});
61+
5762
Targets.push_back({"", 0, 0});
5863
for (size_t I = 0, E = Intrinsics.size(); I < E; ++I)
5964
if (Intrinsics[I].TargetPrefix != Targets.back().Name) {
6065
Targets.back().Count = I - Targets.back().Offset;
6166
Targets.push_back({Intrinsics[I].TargetPrefix, I, 0});
6267
}
6368
Targets.back().Count = Intrinsics.size() - Targets.back().Offset;
69+
70+
CheckDuplicateIntrinsics();
71+
}
72+
73+
// Check for duplicate intrinsic names.
74+
void CodeGenIntrinsicTable::CheckDuplicateIntrinsics() const {
75+
// Since the Intrinsics vector is already sorted by name, if there are 2 or
76+
// more intrinsics with duplicate names, they will appear adjacent in sorted
77+
// order. Note that if the intrinsic name was derived from the record name
78+
// there cannot be be duplicate as TableGen parser would have flagged that.
79+
// However, if the name was specified in the intrinsic definition, then its
80+
// possible to have duplicate names.
81+
auto I = std::adjacent_find(
82+
Intrinsics.begin(), Intrinsics.end(),
83+
[](const CodeGenIntrinsic &Int1, const CodeGenIntrinsic &Int2) {
84+
return Int1.Name == Int2.Name;
85+
});
86+
if (I == Intrinsics.end())
87+
return;
88+
89+
// Found a duplicate intrinsics.
90+
const CodeGenIntrinsic &First = *I;
91+
const CodeGenIntrinsic &Second = *(I + 1);
92+
PrintError(Second.TheDef,
93+
Twine("Intrinsic `") + First.Name + "` is already defined");
94+
PrintFatalNote(First.TheDef, "Previous definition here");
6495
}
6596

6697
CodeGenIntrinsic &CodeGenIntrinsicMap::operator[](const Record *Record) {

llvm/utils/TableGen/Basic/CodeGenIntrinsics.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,9 @@ class CodeGenIntrinsicTable {
189189
const CodeGenIntrinsic &operator[](size_t Pos) const {
190190
return Intrinsics[Pos];
191191
}
192+
193+
private:
194+
void CheckDuplicateIntrinsics() const;
192195
};
193196

194197
// This class builds `CodeGenIntrinsic` on demand for a given Def.

0 commit comments

Comments
 (0)