[llvm] 5cc87b4 - [AsmParser] Add missing globals declarations in incomplete IR mode (#79855)
via llvm-commits
llvm-commits at lists.llvm.org
Wed Jan 31 03:24:38 PST 2024
Author: Nikita Popov
Date: 2024-01-31T12:24:35+01:00
New Revision: 5cc87b424be87db4247f34ae5477be8b09a573e9
URL: https://github.com/llvm/llvm-project/commit/5cc87b424be87db4247f34ae5477be8b09a573e9
DIFF: https://github.com/llvm/llvm-project/commit/5cc87b424be87db4247f34ae5477be8b09a573e9.diff
LOG: [AsmParser] Add missing globals declarations in incomplete IR mode (#79855)
If `-allow-incomplete-ir` is enabled, automatically insert declarations
for missing globals.
If a global is only used in calls with the same function type, insert a
function declaration with that type.
Otherwise, insert a dummy i8 global. The fallback case could be extended
with various heuristics (e.g. we could look at load/store types), but
I've chosen to keep it simple for now, because I'm unsure to what degree
this would really useful without more experience. I expect that in most
cases the declaration type doesn't really matter (note that the type of
an external global specifies a *minimum* size only, not a precise size).
This is a followup to https://github.com/llvm/llvm-project/pull/78421.
Added:
llvm/test/Assembler/incomplete-ir-declarations.ll
Modified:
llvm/lib/AsmParser/LLParser.cpp
Removed:
################################################################################
diff --git a/llvm/lib/AsmParser/LLParser.cpp b/llvm/lib/AsmParser/LLParser.cpp
index d6c5993797de1..e111ca9c7e6b5 100644
--- a/llvm/lib/AsmParser/LLParser.cpp
+++ b/llvm/lib/AsmParser/LLParser.cpp
@@ -303,15 +303,7 @@ bool LLParser::validateEndOfModule(bool UpgradeDebugInfo) {
"use of undefined comdat '$" +
ForwardRefComdats.begin()->first + "'");
- // Automatically create declarations for intrinsics. Intrinsics can only be
- // called directly, so the call function type directly determines the
- // declaration function type.
for (const auto &[Name, Info] : make_early_inc_range(ForwardRefVals)) {
- if (!StringRef(Name).starts_with("llvm."))
- continue;
-
- // Don't do anything if the intrinsic is called with
diff erent function
- // types. This would result in a verifier error anyway.
auto GetCommonFunctionType = [](Value *V) -> FunctionType * {
FunctionType *FTy = nullptr;
for (User *U : V->users()) {
@@ -322,10 +314,38 @@ bool LLParser::validateEndOfModule(bool UpgradeDebugInfo) {
}
return FTy;
};
- if (FunctionType *FTy = GetCommonFunctionType(Info.first)) {
- Function *Fn =
- Function::Create(FTy, GlobalValue::ExternalLinkage, Name, M);
- Info.first->replaceAllUsesWith(Fn);
+
+ auto GetDeclarationType = [&](StringRef Name, Value *V) -> Type * {
+ // Automatically create declarations for intrinsics. Intrinsics can only
+ // be called directly, so the call function type directly determines the
+ // declaration function type.
+ if (Name.starts_with("llvm."))
+ // Don't do anything if the intrinsic is called with
diff erent function
+ // types. This would result in a verifier error anyway.
+ return GetCommonFunctionType(V);
+
+ if (AllowIncompleteIR) {
+ // If incomplete IR is allowed, also add declarations for
+ // non-intrinsics. First check whether this global is only used in
+ // calls with the same type, in which case we'll insert a function.
+ if (auto *Ty = GetCommonFunctionType(V))
+ return Ty;
+
+ // Otherwise, fall back to using a dummy i8 type.
+ return Type::getInt8Ty(Context);
+ }
+ return nullptr;
+ };
+
+ if (Type *Ty = GetDeclarationType(Name, Info.first)) {
+ GlobalValue *GV;
+ if (auto *FTy = dyn_cast<FunctionType>(Ty))
+ GV = Function::Create(FTy, GlobalValue::ExternalLinkage, Name, M);
+ else
+ GV = new GlobalVariable(*M, Ty, /*isConstant*/ false,
+ GlobalValue::ExternalLinkage,
+ /*Initializer*/ nullptr, Name);
+ Info.first->replaceAllUsesWith(GV);
Info.first->eraseFromParent();
ForwardRefVals.erase(Name);
}
diff --git a/llvm/test/Assembler/incomplete-ir-declarations.ll b/llvm/test/Assembler/incomplete-ir-declarations.ll
new file mode 100644
index 0000000000000..6cdff80883c27
--- /dev/null
+++ b/llvm/test/Assembler/incomplete-ir-declarations.ll
@@ -0,0 +1,20 @@
+; RUN: opt -S -allow-incomplete-ir < %s | FileCheck %s
+
+; CHECK: @fn2 = external global i8
+; CHECK: @g1 = external global i8
+; CHECK: @g2 = external global i8
+; CHECK: @g3 = external global i8
+
+; CHECK: declare void @fn1(i32)
+
+define ptr @test() {
+ call void @fn1(i32 0)
+ call void @fn1(i32 1)
+ call void @fn2(i32 2)
+ call void @fn2(i32 2, i32 3)
+ load i32, ptr @g1
+ store i32 0, ptr @g1
+ load i32, ptr @g1
+ load i64, ptr @g2
+ ret ptr @g3
+}
More information about the llvm-commits
mailing list