-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[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
base: main
Are you sure you want to change the base?
Conversation
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)
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. |
@llvm/pr-subscribers-llvm-analysis Author: Rahul Joshi (jurahul) ChangesAdd a pass that will print unknown intrinsics, which is a function whose name starts with This can help debug issues such as Full diff: https://github.com/llvm/llvm-project/pull/145985.diff 6 Files Affected:
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
|
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)