[llvm] 90ad3e3 - [IR] Allow available_externally GlobalAlias
Fangrui Song via llvm-commits
llvm-commits at lists.llvm.org
Mon Nov 7 09:03:28 PST 2022
Author: Fangrui Song
Date: 2022-11-07T09:03:23-08:00
New Revision: 90ad3e3c02e92cabfc7cf1f0b552ddca73d54cc8
URL: https://github.com/llvm/llvm-project/commit/90ad3e3c02e92cabfc7cf1f0b552ddca73d54cc8
DIFF: https://github.com/llvm/llvm-project/commit/90ad3e3c02e92cabfc7cf1f0b552ddca73d54cc8.diff
LOG: [IR] Allow available_externally GlobalAlias
GlobalVariable and Function can be available_externally. GlobalAlias is used
similarly. Allowing available_externally is a natural extension and helps
ThinLTO discard GlobalAlias in a non-prevailing COMDAT (see D135427).
For now, available_externally GlobalAlias must point to an
available_externally GlobalValue (not ConstantExpr).
Differential Revision: https://reviews.llvm.org/D137441
Added:
Modified:
llvm/docs/LangRef.rst
llvm/include/llvm/IR/GlobalAlias.h
llvm/lib/IR/Verifier.cpp
llvm/test/Verifier/alias.ll
Removed:
################################################################################
diff --git a/llvm/docs/LangRef.rst b/llvm/docs/LangRef.rst
index 5d5916abbfef1..0006dab9b2d29 100644
--- a/llvm/docs/LangRef.rst
+++ b/llvm/docs/LangRef.rst
@@ -886,8 +886,9 @@ Syntax::
[, partition "name"]
The linkage must be one of ``private``, ``internal``, ``linkonce``, ``weak``,
-``linkonce_odr``, ``weak_odr``, ``external``. Note that some system linkers
-might not correctly handle dropping a weak symbol that is aliased.
+``linkonce_odr``, ``weak_odr``, ``external``, ``available_externally``. Note
+that some system linkers might not correctly handle dropping a weak symbol that
+is aliased.
Aliases that are not ``unnamed_addr`` are guaranteed to have the same address as
the aliasee expression. ``unnamed_addr`` ones are only guaranteed to point
@@ -906,8 +907,10 @@ some can only be checked when producing an object file:
intermediate alias being overridden cannot be represented in an
object file.
-* No global value in the expression can be a declaration, since that
- would require a relocation, which is not possible.
+* If the alias has the ``available_externally`` linkage, the aliasee must be an
+ ``available_externally`` global value; otherwise the aliasee can be an
+ expression but no global value in the expression can be a declaration, since
+ that would require a relocation, which is not possible.
* If either the alias or the aliasee may be replaced by a symbol outside the
module at link time or runtime, any optimization cannot replace the alias with
diff --git a/llvm/include/llvm/IR/GlobalAlias.h b/llvm/include/llvm/IR/GlobalAlias.h
index 01134448a8fa7..de405da5ca231 100644
--- a/llvm/include/llvm/IR/GlobalAlias.h
+++ b/llvm/include/llvm/IR/GlobalAlias.h
@@ -93,8 +93,8 @@ class GlobalAlias : public GlobalValue, public ilist_node<GlobalAlias> {
}
static bool isValidLinkage(LinkageTypes L) {
- return isExternalLinkage(L) || isLocalLinkage(L) ||
- isWeakLinkage(L) || isLinkOnceLinkage(L);
+ return isExternalLinkage(L) || isLocalLinkage(L) || isWeakLinkage(L) ||
+ isLinkOnceLinkage(L) || isAvailableExternallyLinkage(L);
}
// Methods for support type inquiry through isa, cast, and dyn_cast:
diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp
index 5e41fb1261575..002b5210830fe 100644
--- a/llvm/lib/IR/Verifier.cpp
+++ b/llvm/lib/IR/Verifier.cpp
@@ -817,9 +817,18 @@ void Verifier::visitAliaseeSubExpr(const GlobalAlias &GA, const Constant &C) {
void Verifier::visitAliaseeSubExpr(SmallPtrSetImpl<const GlobalAlias*> &Visited,
const GlobalAlias &GA, const Constant &C) {
- if (const auto *GV = dyn_cast<GlobalValue>(&C)) {
- Check(!GV->isDeclarationForLinker(), "Alias must point to a definition",
+ if (GA.hasAvailableExternallyLinkage()) {
+ Check(isa<GlobalValue>(C) &&
+ cast<GlobalValue>(C).hasAvailableExternallyLinkage(),
+ "available_externally alias must point to available_externally "
+ "global value",
&GA);
+ }
+ if (const auto *GV = dyn_cast<GlobalValue>(&C)) {
+ if (!GA.hasAvailableExternallyLinkage()) {
+ Check(!GV->isDeclarationForLinker(), "Alias must point to a definition",
+ &GA);
+ }
if (const auto *GA2 = dyn_cast<GlobalAlias>(GV)) {
Check(Visited.insert(GA2).second, "Aliases cannot form a cycle", &GA);
@@ -848,7 +857,7 @@ void Verifier::visitAliaseeSubExpr(SmallPtrSetImpl<const GlobalAlias*> &Visited,
void Verifier::visitGlobalAlias(const GlobalAlias &GA) {
Check(GlobalAlias::isValidLinkage(GA.getLinkage()),
"Alias should have private, internal, linkonce, weak, linkonce_odr, "
- "weak_odr, or external linkage!",
+ "weak_odr, external, or available_externally linkage!",
&GA);
const Constant *Aliasee = GA.getAliasee();
Check(Aliasee, "Aliasee cannot be NULL!", &GA);
diff --git a/llvm/test/Verifier/alias.ll b/llvm/test/Verifier/alias.ll
index e14406550dbbd..b7675a18c0ed1 100644
--- a/llvm/test/Verifier/alias.ll
+++ b/llvm/test/Verifier/alias.ll
@@ -1,4 +1,4 @@
-; RUN: not llvm-as %s -o /dev/null 2>&1 | FileCheck %s
+; RUN: not llvm-as %s -o /dev/null 2>&1 | FileCheck %s --implicit-check-not=alias --implicit-check-not=Alias
declare void @f()
@@ -31,3 +31,15 @@ define available_externally void @f2() {
@test3_c = alias i32, i32* @test3_b
; CHECK: Alias cannot point to an interposable alias
; CHECK-NEXT: i32* @test3_c
+
+ at test4_a = available_externally global i32 42
+ at test4_b = available_externally alias i32, i32* @test4_a
+ at test4_c = available_externally alias void(), void()* @f2
+ at test4_d = available_externally alias i32, i32* @test4_b
+
+ at test4_e = available_externally alias i32, i32* @test3_a
+ at test4_f = available_externally alias i32, inttoptr (i64 sub (i64 ptrtoint (i32* @test4_a to i64), i64 ptrtoint (i32* @test4_a to i64)) to i32*)
+; CHECK: available_externally alias must point to available_externally global value
+; CHECK-NEXT: i32* @test4_e
+; CHECK: available_externally alias must point to available_externally global value
+; CHECK-NEXT: i32* @test4_f
More information about the llvm-commits
mailing list