[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