[llvm] [LLVM][TableGen] Add error check for duplicate intrinsic names (PR #109226)

Rahul Joshi via llvm-commits llvm-commits at lists.llvm.org
Thu Sep 19 05:18:31 PDT 2024


https://github.com/jurahul updated https://github.com/llvm/llvm-project/pull/109226

>From 0a940851f87dadc4f200e47db91f41488e281bb8 Mon Sep 17 00:00:00 2001
From: Rahul Joshi <rjoshi at nvidia.com>
Date: Wed, 18 Sep 2024 18:17:57 -0700
Subject: [PATCH] [LLVM][TableGen] Add error check for duplicate intrinsic
 names

Check for duplicate intrinsic names in the intrinsic emitter backend
and issue a fatal error if we find one.
---
 .../test/TableGen/intrinsic-duplicate-name.td |  9 +++++
 .../TableGen/Basic/CodeGenIntrinsics.cpp      | 37 +++++++++++++++++--
 llvm/utils/TableGen/Basic/CodeGenIntrinsics.h |  3 ++
 3 files changed, 46 insertions(+), 3 deletions(-)
 create mode 100644 llvm/test/TableGen/intrinsic-duplicate-name.td

diff --git a/llvm/test/TableGen/intrinsic-duplicate-name.td b/llvm/test/TableGen/intrinsic-duplicate-name.td
new file mode 100644
index 00000000000000..64d94d3192541d
--- /dev/null
+++ b/llvm/test/TableGen/intrinsic-duplicate-name.td
@@ -0,0 +1,9 @@
+// RUN: not llvm-tblgen -gen-intrinsic-impl -I %p/../../include %s -DTEST_INTRINSICS_SUPPRESS_DEFS 2>&1 | FileCheck %s -DFILE=%s
+
+include "llvm/IR/Intrinsics.td"
+
+def int_foo0 : Intrinsic<[llvm_anyint_ty], [], [], "llvm.foo">;
+
+// CHECK: [[FILE]]:[[@LINE+2]]:5: error: Intrinsic `llvm.foo` is already defined
+// CHECK: [[FILE]]:[[@LINE-3]]:5: note: Previous definition here
+def int_foo1 : Intrinsic<[llvm_anyint_ty], [], [], "llvm.foo">;
diff --git a/llvm/utils/TableGen/Basic/CodeGenIntrinsics.cpp b/llvm/utils/TableGen/Basic/CodeGenIntrinsics.cpp
index 05104e938b8486..e566b7ceedf38e 100644
--- a/llvm/utils/TableGen/Basic/CodeGenIntrinsics.cpp
+++ b/llvm/utils/TableGen/Basic/CodeGenIntrinsics.cpp
@@ -47,13 +47,18 @@ CodeGenIntrinsicTable::CodeGenIntrinsicTable(const RecordKeeper &RC) {
   Intrinsics.reserve(Defs.size());
 
   for (const Record *Def : Defs)
-    Intrinsics.push_back(CodeGenIntrinsic(Def, Ctx));
+    Intrinsics.emplace_back(CodeGenIntrinsic(Def, Ctx));
 
+  // To ensure deterministic sorted order when duplicates are present, use
+  // record ID as a tie-breaker similar to sortAndReportDuplicates in Utils.cpp.
   llvm::sort(Intrinsics,
              [](const CodeGenIntrinsic &LHS, const CodeGenIntrinsic &RHS) {
-               return std::tie(LHS.TargetPrefix, LHS.Name) <
-                      std::tie(RHS.TargetPrefix, RHS.Name);
+               unsigned LhsID = LHS.TheDef->getID();
+               unsigned RhsID = RHS.TheDef->getID();
+               return std::tie(LHS.TargetPrefix, LHS.Name, LhsID) <
+                      std::tie(RHS.TargetPrefix, RHS.Name, RhsID);
              });
+
   Targets.push_back({"", 0, 0});
   for (size_t I = 0, E = Intrinsics.size(); I < E; ++I)
     if (Intrinsics[I].TargetPrefix != Targets.back().Name) {
@@ -61,6 +66,32 @@ CodeGenIntrinsicTable::CodeGenIntrinsicTable(const RecordKeeper &RC) {
       Targets.push_back({Intrinsics[I].TargetPrefix, I, 0});
     }
   Targets.back().Count = Intrinsics.size() - Targets.back().Offset;
+
+  CheckDuplicateIntrinsics();
+}
+
+// Check for duplicate intrinsic names.
+void CodeGenIntrinsicTable::CheckDuplicateIntrinsics() const {
+  // Since the Intrinsics vector is already sorted by name, if there are 2 or
+  // more intrinsics with duplicate names, they will appear adjacent in sorted
+  // order. Note that if the intrinsic name was derived from the record name
+  // there cannot be be duplicate as TableGen parser would have flagged that.
+  // However, if the name was specified in the intrinsic definition, then its
+  // possible to have duplicate names.
+  auto I = std::adjacent_find(
+      Intrinsics.begin(), Intrinsics.end(),
+      [](const CodeGenIntrinsic &Int1, const CodeGenIntrinsic &Int2) {
+        return Int1.Name == Int2.Name;
+      });
+  if (I == Intrinsics.end())
+    return;
+
+  // Found a duplicate intrinsics.
+  const CodeGenIntrinsic &First = *I;
+  const CodeGenIntrinsic &Second = *(I + 1);
+  PrintError(Second.TheDef,
+             Twine("Intrinsic `") + First.Name + "` is already defined");
+  PrintFatalNote(First.TheDef, "Previous definition here");
 }
 
 CodeGenIntrinsic &CodeGenIntrinsicMap::operator[](const Record *Record) {
diff --git a/llvm/utils/TableGen/Basic/CodeGenIntrinsics.h b/llvm/utils/TableGen/Basic/CodeGenIntrinsics.h
index 83282d18789b28..2df598da3f2507 100644
--- a/llvm/utils/TableGen/Basic/CodeGenIntrinsics.h
+++ b/llvm/utils/TableGen/Basic/CodeGenIntrinsics.h
@@ -189,6 +189,9 @@ class CodeGenIntrinsicTable {
   const CodeGenIntrinsic &operator[](size_t Pos) const {
     return Intrinsics[Pos];
   }
+
+private:
+  void CheckDuplicateIntrinsics() const;
 };
 
 // This class builds `CodeGenIntrinsic` on demand for a given Def.



More information about the llvm-commits mailing list