Skip to content

[LLVM][Analysis] Add a pass to print unknown intrinsics #145985

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

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

jurahul
Copy link
Contributor

@jurahul jurahul commented Jun 26, 2025

Add a pass that will print unknown intrinsics, which is a function whose name starts with llvm. but is not a intrinsic recognized by LLVM.

This can help debug issues such as
StanfordLegion/legion#1865 (comment) (by running this pass on the libdevice.10.bc file that ships with the CUDA Toolkit)

Add a pass that will print unknown intrinsics, which is a function
whose name starts with `llvm.` but is not a intrinsic regonized by
LLVM.

This can help debug issues such as
StanfordLegion/legion#1865 (comment)
@jurahul
Copy link
Contributor Author

jurahul commented Jun 26, 2025

Since using libdevice that ships with CUDA Toolkit with the LLVM upstream NVPTX backend is a common use case for projects like XLA/Triton/Legion, this pass can be helpful to detect any mismatch between the intrinsics supported by upstream LLVM vs what is present in libdevice shipped with CUDA Toollkit. Apart from this specific use case, it seems this pass can have general utility and is simple enough, hence creating this PR for committing it upstream.

@jurahul jurahul marked this pull request as ready for review June 26, 2025 23:27
@jurahul jurahul requested a review from ssahasra June 26, 2025 23:27
@llvmbot llvmbot added the llvm:analysis Includes value tracking, cost tables and constant folding label Jun 26, 2025
@jurahul jurahul requested a review from AlexMaclean June 26, 2025 23:28
@llvmbot
Copy link
Member

llvmbot commented Jun 26, 2025

@llvm/pr-subscribers-llvm-analysis

Author: Rahul Joshi (jurahul)

Changes

Add a pass that will print unknown intrinsics, which is a function whose name starts with llvm. but is not a intrinsic regonized by LLVM.

This can help debug issues such as
StanfordLegion/legion#1865 (comment) (by running this pass on the libdevice.10.bc file that ships with the CUDA Toolkit)


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

6 Files Affected:

  • (added) llvm/include/llvm/Analysis/UnknownIntrinsicPrinter.h (+26)
  • (modified) llvm/lib/Analysis/CMakeLists.txt (+1)
  • (added) llvm/lib/Analysis/UnknownIntrinsicPrinter.cpp (+25)
  • (modified) llvm/lib/Passes/PassBuilder.cpp (+1)
  • (modified) llvm/lib/Passes/PassRegistry.def (+1)
  • (added) llvm/test/Analysis/UnknownIntrinsicPrinter/unknown.ll (+25)
diff --git a/llvm/include/llvm/Analysis/UnknownIntrinsicPrinter.h b/llvm/include/llvm/Analysis/UnknownIntrinsicPrinter.h
new file mode 100644
index 0000000000000..d81047545ab4d
--- /dev/null
+++ b/llvm/include/llvm/Analysis/UnknownIntrinsicPrinter.h
@@ -0,0 +1,26 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ANALYSIS_UNKNOWNINTRINSICPRINTER_H
+#define LLVM_ANALYSIS_UNKNOWNINTRINSICPRINTER_H
+
+#include "llvm/IR/PassManager.h"
+
+namespace llvm {
+class UnknownIntrinsicPrinterPass
+    : public PassInfoMixin<UnknownIntrinsicPrinterPass> {
+  raw_ostream &OS;
+
+public:
+  UnknownIntrinsicPrinterPass(raw_ostream &OS) : OS(OS) {}
+  PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
+  static bool isRequired() { return true; }
+};
+} // namespace llvm
+
+#endif // LLVM_ANALYSIS_UNKNOWNINTRINSICPRINTER_H
diff --git a/llvm/lib/Analysis/CMakeLists.txt b/llvm/lib/Analysis/CMakeLists.txt
index cfde787b17790..a35d6ccd35437 100644
--- a/llvm/lib/Analysis/CMakeLists.txt
+++ b/llvm/lib/Analysis/CMakeLists.txt
@@ -155,6 +155,7 @@ add_llvm_component_library(LLVMAnalysis
   TypeBasedAliasAnalysis.cpp
   TypeMetadataUtils.cpp
   UniformityAnalysis.cpp
+  UnknownIntrinsicPrinter.cpp
   ScopedNoAliasAA.cpp
   ValueLattice.cpp
   ValueLatticeUtils.cpp
diff --git a/llvm/lib/Analysis/UnknownIntrinsicPrinter.cpp b/llvm/lib/Analysis/UnknownIntrinsicPrinter.cpp
new file mode 100644
index 0000000000000..f04efa07cd6c4
--- /dev/null
+++ b/llvm/lib/Analysis/UnknownIntrinsicPrinter.cpp
@@ -0,0 +1,25 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Analysis/UnknownIntrinsicPrinter.h"
+#include "llvm/IR/Function.h"
+#include "llvm/IR/Intrinsics.h"
+#include "llvm/IR/Module.h"
+
+using namespace llvm;
+
+PreservedAnalyses UnknownIntrinsicPrinterPass::run(Module &M,
+                                                   ModuleAnalysisManager &) {
+  for (const Function &F : M.functions()) {
+    // An unknown intrinsic is a function that begins with "llvm." but is not
+    // a recognized intrinsic (i.e., it's IntrinsicID is not_intrinsic).
+    if (F.isIntrinsic() && F.getIntrinsicID() == Intrinsic::not_intrinsic)
+      OS << "Unknown intrinsic : " << F.getName() << '\n';
+  }
+  return PreservedAnalyses::all();
+}
diff --git a/llvm/lib/Passes/PassBuilder.cpp b/llvm/lib/Passes/PassBuilder.cpp
index 4603eaff8ade9..7676295f3b183 100644
--- a/llvm/lib/Passes/PassBuilder.cpp
+++ b/llvm/lib/Passes/PassBuilder.cpp
@@ -77,6 +77,7 @@
 #include "llvm/Analysis/TargetTransformInfo.h"
 #include "llvm/Analysis/TypeBasedAliasAnalysis.h"
 #include "llvm/Analysis/UniformityAnalysis.h"
+#include "llvm/Analysis/UnknownIntrinsicPrinter.h"
 #include "llvm/CodeGen/AssignmentTrackingAnalysis.h"
 #include "llvm/CodeGen/AtomicExpand.h"
 #include "llvm/CodeGen/BasicBlockSectionsProfileReader.h"
diff --git a/llvm/lib/Passes/PassRegistry.def b/llvm/lib/Passes/PassRegistry.def
index ec14c6a9211d9..af5ef2bd88fdb 100644
--- a/llvm/lib/Passes/PassRegistry.def
+++ b/llvm/lib/Passes/PassRegistry.def
@@ -138,6 +138,7 @@ MODULE_PASS("print<inline-advisor>", InlineAdvisorAnalysisPrinterPass(errs()))
 MODULE_PASS("print<ir2vec>", IR2VecPrinterPass(errs()))
 MODULE_PASS("print<module-debuginfo>", ModuleDebugInfoPrinterPass(errs()))
 MODULE_PASS("print<reg-usage>", PhysicalRegisterUsageInfoPrinterPass(errs()))
+MODULE_PASS("print-unknown-intrinsics", UnknownIntrinsicPrinterPass(errs()))
 MODULE_PASS("pseudo-probe", SampleProfileProbePass(TM))
 MODULE_PASS("pseudo-probe-update", PseudoProbeUpdatePass())
 MODULE_PASS("recompute-globalsaa", RecomputeGlobalsAAPass())
diff --git a/llvm/test/Analysis/UnknownIntrinsicPrinter/unknown.ll b/llvm/test/Analysis/UnknownIntrinsicPrinter/unknown.ll
new file mode 100644
index 0000000000000..941caf1a36bb7
--- /dev/null
+++ b/llvm/test/Analysis/UnknownIntrinsicPrinter/unknown.ll
@@ -0,0 +1,25 @@
+; RUN: opt -disable-output -passes=print-unknown-intrinsics %s 2>&1 | FileCheck %s
+
+; ------------------------------------------------------------------------------
+; Add several known intrinsics.
+declare i8 @llvm.ctpop.i8(i8)
+declare double @llvm.sqrt.f64(double)
+
+; Note, the next two are known intrinsics because automatic remanging of
+; intrinsics will convert them to the "correct" name.
+
+; Remangled to llvm.sqrt.f64(double).
+declare double @llvm.sqrt.foo(double)
+
+; Remangled to llvm.ctpop.i8(i8).
+declare i8 @llvm.ctpop.unknown.i8(i8)
+
+; ------------------------------------------------------------------------------
+; Add several unknown intrinsics.
+declare i1 @llvm.isunordered.f32(float, float)
+declare i8 @llvm.foo.unknown.i8(i8)
+declare i8 @llvm.unknown.i8(i8)
+
+; CHECK: Unknown intrinsic : llvm.isunordered.f32
+; CHECK: Unknown intrinsic : llvm.foo.unknown.i8
+; CHECK: Unknown intrinsic : llvm.unknown.i8

@jurahul jurahul requested review from optimisan and Artem-B June 26, 2025 23:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
llvm:analysis Includes value tracking, cost tables and constant folding
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants