@@ -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
6697CodeGenIntrinsic &CodeGenIntrinsicMap::operator [](const Record *Record) {
0 commit comments