Skip to content

[Core] Skip over target name in intrinsic name lookup #109971

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Sep 25, 2024

Conversation

jurahul
Copy link
Contributor

@jurahul jurahul commented Sep 25, 2024

When searching for an intrinsic name in a target specific slice of the intrinsic name table, skip over the target prefix. For such cases, currently the first loop iteration in lookupLLVMIntrinsicByName does nothing (i.e., Low and High stay unchanged and it does not shrink down the search window), so we can skip this useless first iteration by skipping over the target prefix.

@jurahul
Copy link
Contributor Author

jurahul commented Sep 25, 2024

The CI failure in "CodeGen/AMDGPU/GlobalISel/inst-select-unmerge-values.mir" seems unrelated.

@jurahul jurahul marked this pull request as ready for review September 25, 2024 14:28
@jurahul jurahul requested review from arsenm and nikic September 25, 2024 14:29
@jurahul jurahul requested a review from RKSimon September 25, 2024 14:29
@llvmbot
Copy link
Member

llvmbot commented Sep 25, 2024

@llvm/pr-subscribers-coroutines

Author: Rahul Joshi (jurahul)

Changes

When searching for an intrinsic name in a target specific slice of the intrinsic name table, skip over the target prefix. For such cases, currently the first loop iteration in lookupLLVMIntrinsicByName does nothing (i.e., Low and High stay unchanged and it does not shrink down the search window), so we can skip this useless first iteration by skipping over the target prefix.


Full diff: https://github.com/llvm/llvm-project/pull/109971.diff

5 Files Affected:

  • (modified) llvm/include/llvm/IR/Intrinsics.h (+1-1)
  • (modified) llvm/lib/IR/Function.cpp (+10-9)
  • (modified) llvm/lib/IR/IntrinsicInst.cpp (+6-1)
  • (modified) llvm/lib/Transforms/Coroutines/Coroutines.cpp (+2-1)
  • (modified) llvm/unittests/IR/IntrinsicsTest.cpp (+18-16)
diff --git a/llvm/include/llvm/IR/Intrinsics.h b/llvm/include/llvm/IR/Intrinsics.h
index 4bd7fda77f3132..0ec7e47812af44 100644
--- a/llvm/include/llvm/IR/Intrinsics.h
+++ b/llvm/include/llvm/IR/Intrinsics.h
@@ -95,7 +95,7 @@ namespace Intrinsic {
   /// match for Name or a prefix of Name followed by a dot, its index in
   /// NameTable is returned. Otherwise, -1 is returned.
   int lookupLLVMIntrinsicByName(ArrayRef<const char *> NameTable,
-                                StringRef Name);
+                                StringRef Name, StringRef Target = "");
 
   /// Map a Clang builtin name to an intrinsic ID.
   ID getIntrinsicForClangBuiltin(StringRef TargetPrefix, StringRef BuiltinName);
diff --git a/llvm/lib/IR/Function.cpp b/llvm/lib/IR/Function.cpp
index 8767c2971f62c8..863900c3f14b2b 100644
--- a/llvm/lib/IR/Function.cpp
+++ b/llvm/lib/IR/Function.cpp
@@ -940,8 +940,8 @@ void Function::setOnlyAccessesInaccessibleMemOrArgMem() {
 }
 
 /// Table of string intrinsic names indexed by enum value.
-static const char * const IntrinsicNameTable[] = {
-  "not_intrinsic",
+static constexpr const char *const IntrinsicNameTable[] = {
+    "not_intrinsic",
 #define GET_INTRINSIC_NAME_TABLE
 #include "llvm/IR/IntrinsicImpl.inc"
 #undef GET_INTRINSIC_NAME_TABLE
@@ -963,8 +963,9 @@ bool Function::isTargetIntrinsic() const {
 /// Find the segment of \c IntrinsicNameTable for intrinsics with the same
 /// target as \c Name, or the generic table if \c Name is not target specific.
 ///
-/// Returns the relevant slice of \c IntrinsicNameTable
-static ArrayRef<const char *> findTargetSubtable(StringRef Name) {
+/// Returns the relevant slice of \c IntrinsicNameTable and the target name.
+static std::pair<ArrayRef<const char *>, StringRef>
+findTargetSubtable(StringRef Name) {
   assert(Name.starts_with("llvm."));
 
   ArrayRef<IntrinsicTargetInfo> Targets(TargetInfos);
@@ -976,14 +977,14 @@ static ArrayRef<const char *> findTargetSubtable(StringRef Name) {
   // We've either found the target or just fall back to the generic set, which
   // is always first.
   const auto &TI = It != Targets.end() && It->Name == Target ? *It : Targets[0];
-  return ArrayRef(&IntrinsicNameTable[1] + TI.Offset, TI.Count);
+  return {ArrayRef(&IntrinsicNameTable[1] + TI.Offset, TI.Count), TI.Name};
 }
 
-/// This does the actual lookup of an intrinsic ID which
-/// matches the given function name.
+/// This does the actual lookup of an intrinsic ID which matches the given
+/// function name.
 Intrinsic::ID Function::lookupIntrinsicID(StringRef Name) {
-  ArrayRef<const char *> NameTable = findTargetSubtable(Name);
-  int Idx = Intrinsic::lookupLLVMIntrinsicByName(NameTable, Name);
+  auto [NameTable, Target] = findTargetSubtable(Name);
+  int Idx = Intrinsic::lookupLLVMIntrinsicByName(NameTable, Name, Target);
   if (Idx == -1)
     return Intrinsic::not_intrinsic;
 
diff --git a/llvm/lib/IR/IntrinsicInst.cpp b/llvm/lib/IR/IntrinsicInst.cpp
index 7ed82c2ece464a..5654a3a3236c6d 100644
--- a/llvm/lib/IR/IntrinsicInst.cpp
+++ b/llvm/lib/IR/IntrinsicInst.cpp
@@ -237,8 +237,10 @@ void DbgAssignIntrinsic::setValue(Value *V) {
 }
 
 int llvm::Intrinsic::lookupLLVMIntrinsicByName(ArrayRef<const char *> NameTable,
-                                               StringRef Name) {
+                                               StringRef Name,
+                                               StringRef Target) {
   assert(Name.starts_with("llvm.") && "Unexpected intrinsic prefix");
+  assert(Name.drop_front(5).starts_with(Target) && "Unexpected target");
 
   // Do successive binary searches of the dotted name components. For
   // "llvm.gc.experimental.statepoint.p1i8.p1i32", we will find the range of
@@ -248,6 +250,9 @@ int llvm::Intrinsic::lookupLLVMIntrinsicByName(ArrayRef<const char *> NameTable,
   // identical. By using strncmp we consider names with differing suffixes to
   // be part of the equal range.
   size_t CmpEnd = 4; // Skip the "llvm" component.
+  if (!Target.empty())
+    CmpEnd += 1 + Target.size(); // skip the .target component.
+
   const char *const *Low = NameTable.begin();
   const char *const *High = NameTable.end();
   const char *const *LastLow = Low;
diff --git a/llvm/lib/Transforms/Coroutines/Coroutines.cpp b/llvm/lib/Transforms/Coroutines/Coroutines.cpp
index 10e2e410960982..453736912a8c5b 100644
--- a/llvm/lib/Transforms/Coroutines/Coroutines.cpp
+++ b/llvm/lib/Transforms/Coroutines/Coroutines.cpp
@@ -97,7 +97,8 @@ static const char *const CoroIntrinsics[] = {
 
 #ifndef NDEBUG
 static bool isCoroutineIntrinsicName(StringRef Name) {
-  return Intrinsic::lookupLLVMIntrinsicByName(CoroIntrinsics, Name) != -1;
+  return Intrinsic::lookupLLVMIntrinsicByName(CoroIntrinsics, Name, "coro") !=
+         -1;
 }
 #endif
 
diff --git a/llvm/unittests/IR/IntrinsicsTest.cpp b/llvm/unittests/IR/IntrinsicsTest.cpp
index 5916a194f76d48..a92ffe3cdeb7ec 100644
--- a/llvm/unittests/IR/IntrinsicsTest.cpp
+++ b/llvm/unittests/IR/IntrinsicsTest.cpp
@@ -31,10 +31,6 @@ using namespace llvm;
 
 namespace {
 
-static const char *const NameTable1[] = {
-    "llvm.foo", "llvm.foo.a", "llvm.foo.b", "llvm.foo.b.a", "llvm.foo.c",
-};
-
 class IntrinsicsTest : public ::testing::Test {
   LLVMContext Context;
   std::unique_ptr<Module> M;
@@ -67,18 +63,24 @@ class IntrinsicsTest : public ::testing::Test {
 };
 
 TEST(IntrinsicNameLookup, Basic) {
-  int I = Intrinsic::lookupLLVMIntrinsicByName(NameTable1, "llvm.foo");
-  EXPECT_EQ(0, I);
-  I = Intrinsic::lookupLLVMIntrinsicByName(NameTable1, "llvm.foo.f64");
-  EXPECT_EQ(0, I);
-  I = Intrinsic::lookupLLVMIntrinsicByName(NameTable1, "llvm.foo.b");
-  EXPECT_EQ(2, I);
-  I = Intrinsic::lookupLLVMIntrinsicByName(NameTable1, "llvm.foo.b.a");
-  EXPECT_EQ(3, I);
-  I = Intrinsic::lookupLLVMIntrinsicByName(NameTable1, "llvm.foo.c");
-  EXPECT_EQ(4, I);
-  I = Intrinsic::lookupLLVMIntrinsicByName(NameTable1, "llvm.foo.c.f64");
-  EXPECT_EQ(4, I);
+  static constexpr const char *const NameTable1[] = {
+      "llvm.foo", "llvm.foo.a", "llvm.foo.b", "llvm.foo.b.a", "llvm.foo.c",
+  };
+
+  static constexpr std::pair<const char *, int> Tests[] = {
+      {"llvm.foo", 0},     {"llvm.foo.f64", 0}, {"llvm.foo.b", 2},
+      {"llvm.foo.b.a", 3}, {"llvm.foo.c", 4},   {"llvm.foo.c.f64", 4},
+      {"llvm.bar", -1},
+  };
+
+  for (const auto &[Name, ExpectedIdx] : Tests) {
+    int Idx = Intrinsic::lookupLLVMIntrinsicByName(NameTable1, Name);
+    EXPECT_EQ(ExpectedIdx, Idx);
+    if (!StringRef(Name).starts_with("llvm.foo"))
+      continue;
+    Idx = Intrinsic::lookupLLVMIntrinsicByName(NameTable1, Name, "foo");
+    EXPECT_EQ(ExpectedIdx, Idx);
+  }
 }
 
 // Tests to verify getIntrinsicForClangBuiltin.

@llvmbot
Copy link
Member

llvmbot commented Sep 25, 2024

@llvm/pr-subscribers-llvm-transforms

Author: Rahul Joshi (jurahul)

Changes

When searching for an intrinsic name in a target specific slice of the intrinsic name table, skip over the target prefix. For such cases, currently the first loop iteration in lookupLLVMIntrinsicByName does nothing (i.e., Low and High stay unchanged and it does not shrink down the search window), so we can skip this useless first iteration by skipping over the target prefix.


Full diff: https://github.com/llvm/llvm-project/pull/109971.diff

5 Files Affected:

  • (modified) llvm/include/llvm/IR/Intrinsics.h (+1-1)
  • (modified) llvm/lib/IR/Function.cpp (+10-9)
  • (modified) llvm/lib/IR/IntrinsicInst.cpp (+6-1)
  • (modified) llvm/lib/Transforms/Coroutines/Coroutines.cpp (+2-1)
  • (modified) llvm/unittests/IR/IntrinsicsTest.cpp (+18-16)
diff --git a/llvm/include/llvm/IR/Intrinsics.h b/llvm/include/llvm/IR/Intrinsics.h
index 4bd7fda77f3132..0ec7e47812af44 100644
--- a/llvm/include/llvm/IR/Intrinsics.h
+++ b/llvm/include/llvm/IR/Intrinsics.h
@@ -95,7 +95,7 @@ namespace Intrinsic {
   /// match for Name or a prefix of Name followed by a dot, its index in
   /// NameTable is returned. Otherwise, -1 is returned.
   int lookupLLVMIntrinsicByName(ArrayRef<const char *> NameTable,
-                                StringRef Name);
+                                StringRef Name, StringRef Target = "");
 
   /// Map a Clang builtin name to an intrinsic ID.
   ID getIntrinsicForClangBuiltin(StringRef TargetPrefix, StringRef BuiltinName);
diff --git a/llvm/lib/IR/Function.cpp b/llvm/lib/IR/Function.cpp
index 8767c2971f62c8..863900c3f14b2b 100644
--- a/llvm/lib/IR/Function.cpp
+++ b/llvm/lib/IR/Function.cpp
@@ -940,8 +940,8 @@ void Function::setOnlyAccessesInaccessibleMemOrArgMem() {
 }
 
 /// Table of string intrinsic names indexed by enum value.
-static const char * const IntrinsicNameTable[] = {
-  "not_intrinsic",
+static constexpr const char *const IntrinsicNameTable[] = {
+    "not_intrinsic",
 #define GET_INTRINSIC_NAME_TABLE
 #include "llvm/IR/IntrinsicImpl.inc"
 #undef GET_INTRINSIC_NAME_TABLE
@@ -963,8 +963,9 @@ bool Function::isTargetIntrinsic() const {
 /// Find the segment of \c IntrinsicNameTable for intrinsics with the same
 /// target as \c Name, or the generic table if \c Name is not target specific.
 ///
-/// Returns the relevant slice of \c IntrinsicNameTable
-static ArrayRef<const char *> findTargetSubtable(StringRef Name) {
+/// Returns the relevant slice of \c IntrinsicNameTable and the target name.
+static std::pair<ArrayRef<const char *>, StringRef>
+findTargetSubtable(StringRef Name) {
   assert(Name.starts_with("llvm."));
 
   ArrayRef<IntrinsicTargetInfo> Targets(TargetInfos);
@@ -976,14 +977,14 @@ static ArrayRef<const char *> findTargetSubtable(StringRef Name) {
   // We've either found the target or just fall back to the generic set, which
   // is always first.
   const auto &TI = It != Targets.end() && It->Name == Target ? *It : Targets[0];
-  return ArrayRef(&IntrinsicNameTable[1] + TI.Offset, TI.Count);
+  return {ArrayRef(&IntrinsicNameTable[1] + TI.Offset, TI.Count), TI.Name};
 }
 
-/// This does the actual lookup of an intrinsic ID which
-/// matches the given function name.
+/// This does the actual lookup of an intrinsic ID which matches the given
+/// function name.
 Intrinsic::ID Function::lookupIntrinsicID(StringRef Name) {
-  ArrayRef<const char *> NameTable = findTargetSubtable(Name);
-  int Idx = Intrinsic::lookupLLVMIntrinsicByName(NameTable, Name);
+  auto [NameTable, Target] = findTargetSubtable(Name);
+  int Idx = Intrinsic::lookupLLVMIntrinsicByName(NameTable, Name, Target);
   if (Idx == -1)
     return Intrinsic::not_intrinsic;
 
diff --git a/llvm/lib/IR/IntrinsicInst.cpp b/llvm/lib/IR/IntrinsicInst.cpp
index 7ed82c2ece464a..5654a3a3236c6d 100644
--- a/llvm/lib/IR/IntrinsicInst.cpp
+++ b/llvm/lib/IR/IntrinsicInst.cpp
@@ -237,8 +237,10 @@ void DbgAssignIntrinsic::setValue(Value *V) {
 }
 
 int llvm::Intrinsic::lookupLLVMIntrinsicByName(ArrayRef<const char *> NameTable,
-                                               StringRef Name) {
+                                               StringRef Name,
+                                               StringRef Target) {
   assert(Name.starts_with("llvm.") && "Unexpected intrinsic prefix");
+  assert(Name.drop_front(5).starts_with(Target) && "Unexpected target");
 
   // Do successive binary searches of the dotted name components. For
   // "llvm.gc.experimental.statepoint.p1i8.p1i32", we will find the range of
@@ -248,6 +250,9 @@ int llvm::Intrinsic::lookupLLVMIntrinsicByName(ArrayRef<const char *> NameTable,
   // identical. By using strncmp we consider names with differing suffixes to
   // be part of the equal range.
   size_t CmpEnd = 4; // Skip the "llvm" component.
+  if (!Target.empty())
+    CmpEnd += 1 + Target.size(); // skip the .target component.
+
   const char *const *Low = NameTable.begin();
   const char *const *High = NameTable.end();
   const char *const *LastLow = Low;
diff --git a/llvm/lib/Transforms/Coroutines/Coroutines.cpp b/llvm/lib/Transforms/Coroutines/Coroutines.cpp
index 10e2e410960982..453736912a8c5b 100644
--- a/llvm/lib/Transforms/Coroutines/Coroutines.cpp
+++ b/llvm/lib/Transforms/Coroutines/Coroutines.cpp
@@ -97,7 +97,8 @@ static const char *const CoroIntrinsics[] = {
 
 #ifndef NDEBUG
 static bool isCoroutineIntrinsicName(StringRef Name) {
-  return Intrinsic::lookupLLVMIntrinsicByName(CoroIntrinsics, Name) != -1;
+  return Intrinsic::lookupLLVMIntrinsicByName(CoroIntrinsics, Name, "coro") !=
+         -1;
 }
 #endif
 
diff --git a/llvm/unittests/IR/IntrinsicsTest.cpp b/llvm/unittests/IR/IntrinsicsTest.cpp
index 5916a194f76d48..a92ffe3cdeb7ec 100644
--- a/llvm/unittests/IR/IntrinsicsTest.cpp
+++ b/llvm/unittests/IR/IntrinsicsTest.cpp
@@ -31,10 +31,6 @@ using namespace llvm;
 
 namespace {
 
-static const char *const NameTable1[] = {
-    "llvm.foo", "llvm.foo.a", "llvm.foo.b", "llvm.foo.b.a", "llvm.foo.c",
-};
-
 class IntrinsicsTest : public ::testing::Test {
   LLVMContext Context;
   std::unique_ptr<Module> M;
@@ -67,18 +63,24 @@ class IntrinsicsTest : public ::testing::Test {
 };
 
 TEST(IntrinsicNameLookup, Basic) {
-  int I = Intrinsic::lookupLLVMIntrinsicByName(NameTable1, "llvm.foo");
-  EXPECT_EQ(0, I);
-  I = Intrinsic::lookupLLVMIntrinsicByName(NameTable1, "llvm.foo.f64");
-  EXPECT_EQ(0, I);
-  I = Intrinsic::lookupLLVMIntrinsicByName(NameTable1, "llvm.foo.b");
-  EXPECT_EQ(2, I);
-  I = Intrinsic::lookupLLVMIntrinsicByName(NameTable1, "llvm.foo.b.a");
-  EXPECT_EQ(3, I);
-  I = Intrinsic::lookupLLVMIntrinsicByName(NameTable1, "llvm.foo.c");
-  EXPECT_EQ(4, I);
-  I = Intrinsic::lookupLLVMIntrinsicByName(NameTable1, "llvm.foo.c.f64");
-  EXPECT_EQ(4, I);
+  static constexpr const char *const NameTable1[] = {
+      "llvm.foo", "llvm.foo.a", "llvm.foo.b", "llvm.foo.b.a", "llvm.foo.c",
+  };
+
+  static constexpr std::pair<const char *, int> Tests[] = {
+      {"llvm.foo", 0},     {"llvm.foo.f64", 0}, {"llvm.foo.b", 2},
+      {"llvm.foo.b.a", 3}, {"llvm.foo.c", 4},   {"llvm.foo.c.f64", 4},
+      {"llvm.bar", -1},
+  };
+
+  for (const auto &[Name, ExpectedIdx] : Tests) {
+    int Idx = Intrinsic::lookupLLVMIntrinsicByName(NameTable1, Name);
+    EXPECT_EQ(ExpectedIdx, Idx);
+    if (!StringRef(Name).starts_with("llvm.foo"))
+      continue;
+    Idx = Intrinsic::lookupLLVMIntrinsicByName(NameTable1, Name, "foo");
+    EXPECT_EQ(ExpectedIdx, Idx);
+  }
 }
 
 // Tests to verify getIntrinsicForClangBuiltin.

@llvmbot
Copy link
Member

llvmbot commented Sep 25, 2024

@llvm/pr-subscribers-llvm-ir

Author: Rahul Joshi (jurahul)

Changes

When searching for an intrinsic name in a target specific slice of the intrinsic name table, skip over the target prefix. For such cases, currently the first loop iteration in lookupLLVMIntrinsicByName does nothing (i.e., Low and High stay unchanged and it does not shrink down the search window), so we can skip this useless first iteration by skipping over the target prefix.


Full diff: https://github.com/llvm/llvm-project/pull/109971.diff

5 Files Affected:

  • (modified) llvm/include/llvm/IR/Intrinsics.h (+1-1)
  • (modified) llvm/lib/IR/Function.cpp (+10-9)
  • (modified) llvm/lib/IR/IntrinsicInst.cpp (+6-1)
  • (modified) llvm/lib/Transforms/Coroutines/Coroutines.cpp (+2-1)
  • (modified) llvm/unittests/IR/IntrinsicsTest.cpp (+18-16)
diff --git a/llvm/include/llvm/IR/Intrinsics.h b/llvm/include/llvm/IR/Intrinsics.h
index 4bd7fda77f3132..0ec7e47812af44 100644
--- a/llvm/include/llvm/IR/Intrinsics.h
+++ b/llvm/include/llvm/IR/Intrinsics.h
@@ -95,7 +95,7 @@ namespace Intrinsic {
   /// match for Name or a prefix of Name followed by a dot, its index in
   /// NameTable is returned. Otherwise, -1 is returned.
   int lookupLLVMIntrinsicByName(ArrayRef<const char *> NameTable,
-                                StringRef Name);
+                                StringRef Name, StringRef Target = "");
 
   /// Map a Clang builtin name to an intrinsic ID.
   ID getIntrinsicForClangBuiltin(StringRef TargetPrefix, StringRef BuiltinName);
diff --git a/llvm/lib/IR/Function.cpp b/llvm/lib/IR/Function.cpp
index 8767c2971f62c8..863900c3f14b2b 100644
--- a/llvm/lib/IR/Function.cpp
+++ b/llvm/lib/IR/Function.cpp
@@ -940,8 +940,8 @@ void Function::setOnlyAccessesInaccessibleMemOrArgMem() {
 }
 
 /// Table of string intrinsic names indexed by enum value.
-static const char * const IntrinsicNameTable[] = {
-  "not_intrinsic",
+static constexpr const char *const IntrinsicNameTable[] = {
+    "not_intrinsic",
 #define GET_INTRINSIC_NAME_TABLE
 #include "llvm/IR/IntrinsicImpl.inc"
 #undef GET_INTRINSIC_NAME_TABLE
@@ -963,8 +963,9 @@ bool Function::isTargetIntrinsic() const {
 /// Find the segment of \c IntrinsicNameTable for intrinsics with the same
 /// target as \c Name, or the generic table if \c Name is not target specific.
 ///
-/// Returns the relevant slice of \c IntrinsicNameTable
-static ArrayRef<const char *> findTargetSubtable(StringRef Name) {
+/// Returns the relevant slice of \c IntrinsicNameTable and the target name.
+static std::pair<ArrayRef<const char *>, StringRef>
+findTargetSubtable(StringRef Name) {
   assert(Name.starts_with("llvm."));
 
   ArrayRef<IntrinsicTargetInfo> Targets(TargetInfos);
@@ -976,14 +977,14 @@ static ArrayRef<const char *> findTargetSubtable(StringRef Name) {
   // We've either found the target or just fall back to the generic set, which
   // is always first.
   const auto &TI = It != Targets.end() && It->Name == Target ? *It : Targets[0];
-  return ArrayRef(&IntrinsicNameTable[1] + TI.Offset, TI.Count);
+  return {ArrayRef(&IntrinsicNameTable[1] + TI.Offset, TI.Count), TI.Name};
 }
 
-/// This does the actual lookup of an intrinsic ID which
-/// matches the given function name.
+/// This does the actual lookup of an intrinsic ID which matches the given
+/// function name.
 Intrinsic::ID Function::lookupIntrinsicID(StringRef Name) {
-  ArrayRef<const char *> NameTable = findTargetSubtable(Name);
-  int Idx = Intrinsic::lookupLLVMIntrinsicByName(NameTable, Name);
+  auto [NameTable, Target] = findTargetSubtable(Name);
+  int Idx = Intrinsic::lookupLLVMIntrinsicByName(NameTable, Name, Target);
   if (Idx == -1)
     return Intrinsic::not_intrinsic;
 
diff --git a/llvm/lib/IR/IntrinsicInst.cpp b/llvm/lib/IR/IntrinsicInst.cpp
index 7ed82c2ece464a..5654a3a3236c6d 100644
--- a/llvm/lib/IR/IntrinsicInst.cpp
+++ b/llvm/lib/IR/IntrinsicInst.cpp
@@ -237,8 +237,10 @@ void DbgAssignIntrinsic::setValue(Value *V) {
 }
 
 int llvm::Intrinsic::lookupLLVMIntrinsicByName(ArrayRef<const char *> NameTable,
-                                               StringRef Name) {
+                                               StringRef Name,
+                                               StringRef Target) {
   assert(Name.starts_with("llvm.") && "Unexpected intrinsic prefix");
+  assert(Name.drop_front(5).starts_with(Target) && "Unexpected target");
 
   // Do successive binary searches of the dotted name components. For
   // "llvm.gc.experimental.statepoint.p1i8.p1i32", we will find the range of
@@ -248,6 +250,9 @@ int llvm::Intrinsic::lookupLLVMIntrinsicByName(ArrayRef<const char *> NameTable,
   // identical. By using strncmp we consider names with differing suffixes to
   // be part of the equal range.
   size_t CmpEnd = 4; // Skip the "llvm" component.
+  if (!Target.empty())
+    CmpEnd += 1 + Target.size(); // skip the .target component.
+
   const char *const *Low = NameTable.begin();
   const char *const *High = NameTable.end();
   const char *const *LastLow = Low;
diff --git a/llvm/lib/Transforms/Coroutines/Coroutines.cpp b/llvm/lib/Transforms/Coroutines/Coroutines.cpp
index 10e2e410960982..453736912a8c5b 100644
--- a/llvm/lib/Transforms/Coroutines/Coroutines.cpp
+++ b/llvm/lib/Transforms/Coroutines/Coroutines.cpp
@@ -97,7 +97,8 @@ static const char *const CoroIntrinsics[] = {
 
 #ifndef NDEBUG
 static bool isCoroutineIntrinsicName(StringRef Name) {
-  return Intrinsic::lookupLLVMIntrinsicByName(CoroIntrinsics, Name) != -1;
+  return Intrinsic::lookupLLVMIntrinsicByName(CoroIntrinsics, Name, "coro") !=
+         -1;
 }
 #endif
 
diff --git a/llvm/unittests/IR/IntrinsicsTest.cpp b/llvm/unittests/IR/IntrinsicsTest.cpp
index 5916a194f76d48..a92ffe3cdeb7ec 100644
--- a/llvm/unittests/IR/IntrinsicsTest.cpp
+++ b/llvm/unittests/IR/IntrinsicsTest.cpp
@@ -31,10 +31,6 @@ using namespace llvm;
 
 namespace {
 
-static const char *const NameTable1[] = {
-    "llvm.foo", "llvm.foo.a", "llvm.foo.b", "llvm.foo.b.a", "llvm.foo.c",
-};
-
 class IntrinsicsTest : public ::testing::Test {
   LLVMContext Context;
   std::unique_ptr<Module> M;
@@ -67,18 +63,24 @@ class IntrinsicsTest : public ::testing::Test {
 };
 
 TEST(IntrinsicNameLookup, Basic) {
-  int I = Intrinsic::lookupLLVMIntrinsicByName(NameTable1, "llvm.foo");
-  EXPECT_EQ(0, I);
-  I = Intrinsic::lookupLLVMIntrinsicByName(NameTable1, "llvm.foo.f64");
-  EXPECT_EQ(0, I);
-  I = Intrinsic::lookupLLVMIntrinsicByName(NameTable1, "llvm.foo.b");
-  EXPECT_EQ(2, I);
-  I = Intrinsic::lookupLLVMIntrinsicByName(NameTable1, "llvm.foo.b.a");
-  EXPECT_EQ(3, I);
-  I = Intrinsic::lookupLLVMIntrinsicByName(NameTable1, "llvm.foo.c");
-  EXPECT_EQ(4, I);
-  I = Intrinsic::lookupLLVMIntrinsicByName(NameTable1, "llvm.foo.c.f64");
-  EXPECT_EQ(4, I);
+  static constexpr const char *const NameTable1[] = {
+      "llvm.foo", "llvm.foo.a", "llvm.foo.b", "llvm.foo.b.a", "llvm.foo.c",
+  };
+
+  static constexpr std::pair<const char *, int> Tests[] = {
+      {"llvm.foo", 0},     {"llvm.foo.f64", 0}, {"llvm.foo.b", 2},
+      {"llvm.foo.b.a", 3}, {"llvm.foo.c", 4},   {"llvm.foo.c.f64", 4},
+      {"llvm.bar", -1},
+  };
+
+  for (const auto &[Name, ExpectedIdx] : Tests) {
+    int Idx = Intrinsic::lookupLLVMIntrinsicByName(NameTable1, Name);
+    EXPECT_EQ(ExpectedIdx, Idx);
+    if (!StringRef(Name).starts_with("llvm.foo"))
+      continue;
+    Idx = Intrinsic::lookupLLVMIntrinsicByName(NameTable1, Name, "foo");
+    EXPECT_EQ(ExpectedIdx, Idx);
+  }
 }
 
 // Tests to verify getIntrinsicForClangBuiltin.

When searching for an intrinsic name in a target specific slice of the
intrinsic name table, skip over the target prefix. For such cases,
currently the first loop iteration in `lookupLLVMIntrinsicByName` does
nothing (i.e., `Low` and `High` stay unchanged and it does not shrink
down the search window), so we can skip this useless first iteration by
skipping over the target prefix.
@jurahul jurahul force-pushed the skip_target_in_lookup_intrinsic_by_name branch from 436727f to 03a5f46 Compare September 25, 2024 16:56
@jurahul jurahul merged commit 6786928 into llvm:main Sep 25, 2024
8 checks passed
@jurahul jurahul deleted the skip_target_in_lookup_intrinsic_by_name branch September 25, 2024 19:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants