[llvm] r204934 - Prevent alias from pointing to weak aliases.

Rafael Espindola rafael.espindola at gmail.com
Thu Mar 27 08:26:58 PDT 2014


Author: rafael
Date: Thu Mar 27 10:26:56 2014
New Revision: 204934

URL: http://llvm.org/viewvc/llvm-project?rev=204934&view=rev
Log:
Prevent alias from pointing to weak aliases.

This adds back r204781.

Original message:

Aliases are just another name for a position in a file. As such, the
regular symbol resolutions are not applied. For example, given

define void @my_func() {
  ret void
}
@my_alias = alias weak void ()* @my_func
@my_alias2 = alias void ()* @my_alias

We produce without this patch:

        .weak   my_alias
my_alias = my_func
        .globl  my_alias2
my_alias2 = my_alias

That is, in the resulting ELF file my_alias, my_func and my_alias are
just 3 names pointing to offset 0 of .text. That is *not* the
semantics of IR linking. For example, linking in a

@my_alias = alias void ()* @other_func

would require the strong my_alias to override the weak one and
my_alias2 would end up pointing to other_func.

There is no way to represent that with aliases being just another
name, so the best solution seems to be to just disallow it, converting
a miscompile into an error.

Modified:
    llvm/trunk/docs/LangRef.rst
    llvm/trunk/include/llvm/IR/GlobalAlias.h
    llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
    llvm/trunk/lib/ExecutionEngine/JIT/JITEmitter.cpp
    llvm/trunk/lib/IR/Globals.cpp
    llvm/trunk/lib/IR/Verifier.cpp
    llvm/trunk/lib/Target/PowerPC/PPCAsmPrinter.cpp
    llvm/trunk/lib/Target/PowerPC/PPCFastISel.cpp
    llvm/trunk/lib/Target/PowerPC/PPCISelDAGToDAG.cpp
    llvm/trunk/lib/Target/TargetMachine.cpp
    llvm/trunk/lib/Target/X86/X86FastISel.cpp
    llvm/trunk/lib/Target/X86/X86ISelLowering.cpp
    llvm/trunk/lib/Target/XCore/XCoreISelLowering.cpp
    llvm/trunk/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp
    llvm/trunk/test/CodeGen/X86/dllexport-x86_64.ll
    llvm/trunk/test/CodeGen/X86/dllexport.ll
    llvm/trunk/test/Feature/aliases.ll
    llvm/trunk/test/Transforms/GlobalOpt/alias-resolve.ll

Modified: llvm/trunk/docs/LangRef.rst
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/LangRef.rst?rev=204934&r1=204933&r2=204934&view=diff
==============================================================================
--- llvm/trunk/docs/LangRef.rst (original)
+++ llvm/trunk/docs/LangRef.rst Thu Mar 27 10:26:56 2014
@@ -681,6 +681,10 @@ the aliasee.
 
 The aliasee must be a definition.
 
+Aliases are not allowed to point to aliases with linkages that can be
+overridden. Since they are only a second name, the possibility of the
+intermediate alias being overridden cannot be represented in an object file.
+
 .. _namedmetadatastructure:
 
 Named Metadata

Modified: llvm/trunk/include/llvm/IR/GlobalAlias.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/GlobalAlias.h?rev=204934&r1=204933&r2=204934&view=diff
==============================================================================
--- llvm/trunk/include/llvm/IR/GlobalAlias.h (original)
+++ llvm/trunk/include/llvm/IR/GlobalAlias.h Thu Mar 27 10:26:56 2014
@@ -64,23 +64,15 @@ public:
   Constant *getAliasee() {
     return getOperand(0);
   }
-  /// getAliasedGlobal() - Aliasee can be either global or bitcast of
-  /// global. This method retrives the global for both aliasee flavours.
+
+  /// This method tries to ultimately resolve the alias by going through the
+  /// aliasing chain and trying to find the very last global. Returns NULL if a
+  /// cycle was found.
   GlobalValue *getAliasedGlobal();
   const GlobalValue *getAliasedGlobal() const {
     return const_cast<GlobalAlias *>(this)->getAliasedGlobal();
   }
 
-  /// resolveAliasedGlobal() - This method tries to ultimately resolve the alias
-  /// by going through the aliasing chain and trying to find the very last
-  /// global. Returns NULL if a cycle was found. If stopOnWeak is false, then
-  /// the whole chain aliasing chain is traversed, otherwise - only strong
-  /// aliases.
-  GlobalValue *resolveAliasedGlobal(bool stopOnWeak = true);
-  const GlobalValue *resolveAliasedGlobal(bool stopOnWeak = true) const {
-    return const_cast<GlobalAlias *>(this)->resolveAliasedGlobal(stopOnWeak);
-  }
-
   static bool isValidLinkage(LinkageTypes L) {
     return isExternalLinkage(L) || isLocalLinkage(L) ||
       isWeakLinkage(L) || isLinkOnceLinkage(L);

Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp?rev=204934&r1=204933&r2=204934&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Thu Mar 27 10:26:56 2014
@@ -1172,7 +1172,7 @@ SDValue SelectionDAG::getGlobalAddress(c
   if (!GVar) {
     // If GV is an alias then use the aliasee for determining thread-localness.
     if (const GlobalAlias *GA = dyn_cast<GlobalAlias>(GV))
-      GVar = dyn_cast_or_null<GlobalVariable>(GA->resolveAliasedGlobal(false));
+      GVar = dyn_cast_or_null<GlobalVariable>(GA->getAliasedGlobal());
   }
 
   unsigned Opc;

Modified: llvm/trunk/lib/ExecutionEngine/JIT/JITEmitter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/JIT/JITEmitter.cpp?rev=204934&r1=204933&r2=204934&view=diff
==============================================================================
--- llvm/trunk/lib/ExecutionEngine/JIT/JITEmitter.cpp (original)
+++ llvm/trunk/lib/ExecutionEngine/JIT/JITEmitter.cpp Thu Mar 27 10:26:56 2014
@@ -688,7 +688,7 @@ void *JITEmitter::getPointerToGlobal(Glo
     return TheJIT->getOrEmitGlobalVariable(GV);
 
   if (GlobalAlias *GA = dyn_cast<GlobalAlias>(V))
-    return TheJIT->getPointerToGlobal(GA->resolveAliasedGlobal(false));
+    return TheJIT->getPointerToGlobal(GA->getAliasedGlobal());
 
   // If we have already compiled the function, return a pointer to its body.
   Function *F = cast<Function>(V);

Modified: llvm/trunk/lib/IR/Globals.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/Globals.cpp?rev=204934&r1=204933&r2=204934&view=diff
==============================================================================
--- llvm/trunk/lib/IR/Globals.cpp (original)
+++ llvm/trunk/lib/IR/Globals.cpp Thu Mar 27 10:26:56 2014
@@ -236,10 +236,10 @@ void GlobalAlias::setAliasee(Constant *A
   setOperand(0, Aliasee);
 }
 
-GlobalValue *GlobalAlias::getAliasedGlobal() {
-  Constant *C = getAliasee();
-  if (C == 0) return 0;
-  
+static GlobalValue *getAliaseeGV(GlobalAlias *GA) {
+  Constant *C = GA->getAliasee();
+  assert(C && "Must alias something");
+
   if (GlobalValue *GV = dyn_cast<GlobalValue>(C))
     return GV;
 
@@ -248,30 +248,23 @@ GlobalValue *GlobalAlias::getAliasedGlob
           CE->getOpcode() == Instruction::AddrSpaceCast ||
           CE->getOpcode() == Instruction::GetElementPtr) &&
          "Unsupported aliasee");
-  
+
   return cast<GlobalValue>(CE->getOperand(0));
 }
 
-GlobalValue *GlobalAlias::resolveAliasedGlobal(bool stopOnWeak) {
+GlobalValue *GlobalAlias::getAliasedGlobal() {
   SmallPtrSet<GlobalValue*, 3> Visited;
 
-  // Check if we need to stop early.
-  if (stopOnWeak && mayBeOverridden())
-    return this;
-
-  GlobalValue *GV = getAliasedGlobal();
-  Visited.insert(GV);
-
-  // Iterate over aliasing chain, stopping on weak alias if necessary.
-  while (GlobalAlias *GA = dyn_cast<GlobalAlias>(GV)) {
-    if (stopOnWeak && GA->mayBeOverridden())
-      break;
-
-    GV = GA->getAliasedGlobal();
+  GlobalAlias *GA = this;
 
+  for (;;) {
+    GlobalValue *GV = getAliaseeGV(GA);
     if (!Visited.insert(GV))
       return 0;
-  }
 
-  return GV;
+    // Iterate over aliasing chain.
+    GA = dyn_cast<GlobalAlias>(GV);
+    if (!GA)
+      return GV;
+  }
 }

Modified: llvm/trunk/lib/IR/Verifier.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/Verifier.cpp?rev=204934&r1=204933&r2=204934&view=diff
==============================================================================
--- llvm/trunk/lib/IR/Verifier.cpp (original)
+++ llvm/trunk/lib/IR/Verifier.cpp Thu Mar 27 10:26:56 2014
@@ -502,10 +502,14 @@ void Verifier::visitGlobalAlias(const Gl
     }
   }
   Assert1(!GV->isDeclaration(), "Alias must point to a definition", &GA);
+  if (const GlobalAlias *GAAliasee = dyn_cast<GlobalAlias>(GV)) {
+    Assert1(!GAAliasee->mayBeOverridden(), "Alias cannot point to a weak alias",
+            &GA);
+  }
 
-  const GlobalValue* Resolved = GA.resolveAliasedGlobal(/*stopOnWeak*/ false);
-  Assert1(Resolved,
-          "Aliasing chain should end with function or global variable", &GA);
+  const GlobalValue *AG = GA.getAliasedGlobal();
+  Assert1(AG, "Aliasing chain should end with function or global variable",
+          &GA);
 
   visitGlobalValue(GA);
 }

Modified: llvm/trunk/lib/Target/PowerPC/PPCAsmPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCAsmPrinter.cpp?rev=204934&r1=204933&r2=204934&view=diff
==============================================================================
--- llvm/trunk/lib/Target/PowerPC/PPCAsmPrinter.cpp (original)
+++ llvm/trunk/lib/Target/PowerPC/PPCAsmPrinter.cpp Thu Mar 27 10:26:56 2014
@@ -381,8 +381,8 @@ void PPCAsmPrinter::EmitInstruction(cons
     if (MO.isGlobal()) {
       const GlobalValue *GValue = MO.getGlobal();
       const GlobalAlias *GAlias = dyn_cast<GlobalAlias>(GValue);
-      const GlobalValue *RealGValue = GAlias ?
-        GAlias->resolveAliasedGlobal(false) : GValue;
+      const GlobalValue *RealGValue =
+          GAlias ? GAlias->getAliasedGlobal() : GValue;
       MOSymbol = getSymbol(RealGValue);
       const GlobalVariable *GVar = dyn_cast<GlobalVariable>(RealGValue);
       IsExternal = GVar && !GVar->hasInitializer();
@@ -428,8 +428,8 @@ void PPCAsmPrinter::EmitInstruction(cons
     else if (MO.isGlobal()) {
       const GlobalValue *GValue = MO.getGlobal();
       const GlobalAlias *GAlias = dyn_cast<GlobalAlias>(GValue);
-      const GlobalValue *RealGValue = GAlias ?
-        GAlias->resolveAliasedGlobal(false) : GValue;
+      const GlobalValue *RealGValue =
+          GAlias ? GAlias->getAliasedGlobal() : GValue;
       MOSymbol = getSymbol(RealGValue);
       const GlobalVariable *GVar = dyn_cast<GlobalVariable>(RealGValue);
     
@@ -463,8 +463,8 @@ void PPCAsmPrinter::EmitInstruction(cons
     if (MO.isGlobal()) {
       const GlobalValue *GValue = MO.getGlobal();
       const GlobalAlias *GAlias = dyn_cast<GlobalAlias>(GValue);
-      const GlobalValue *RealGValue = GAlias ?
-        GAlias->resolveAliasedGlobal(false) : GValue;
+      const GlobalValue *RealGValue =
+          GAlias ? GAlias->getAliasedGlobal() : GValue;
       MOSymbol = getSymbol(RealGValue);
       const GlobalVariable *GVar = dyn_cast<GlobalVariable>(RealGValue);
       IsExternal = GVar && !GVar->hasInitializer();

Modified: llvm/trunk/lib/Target/PowerPC/PPCFastISel.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCFastISel.cpp?rev=204934&r1=204933&r2=204934&view=diff
==============================================================================
--- llvm/trunk/lib/Target/PowerPC/PPCFastISel.cpp (original)
+++ llvm/trunk/lib/Target/PowerPC/PPCFastISel.cpp Thu Mar 27 10:26:56 2014
@@ -1863,7 +1863,7 @@ unsigned PPCFastISel::PPCMaterializeGV(c
   if (!GVar) {
     // If GV is an alias, use the aliasee for determining thread-locality.
     if (const GlobalAlias *GA = dyn_cast<GlobalAlias>(GV))
-      GVar = dyn_cast_or_null<GlobalVariable>(GA->resolveAliasedGlobal(false));
+      GVar = dyn_cast_or_null<GlobalVariable>(GA->getAliasedGlobal());
   }
 
   // FIXME: We don't yet handle the complexity of TLS.

Modified: llvm/trunk/lib/Target/PowerPC/PPCISelDAGToDAG.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCISelDAGToDAG.cpp?rev=204934&r1=204933&r2=204934&view=diff
==============================================================================
--- llvm/trunk/lib/Target/PowerPC/PPCISelDAGToDAG.cpp (original)
+++ llvm/trunk/lib/Target/PowerPC/PPCISelDAGToDAG.cpp Thu Mar 27 10:26:56 2014
@@ -1463,8 +1463,8 @@ SDNode *PPCDAGToDAGISel::Select(SDNode *
     if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(GA)) {
       const GlobalValue *GValue = G->getGlobal();
       const GlobalAlias *GAlias = dyn_cast<GlobalAlias>(GValue);
-      const GlobalValue *RealGValue = GAlias ?
-        GAlias->resolveAliasedGlobal(false) : GValue;
+      const GlobalValue *RealGValue =
+          GAlias ? GAlias->getAliasedGlobal() : GValue;
       const GlobalVariable *GVar = dyn_cast<GlobalVariable>(RealGValue);
       assert((GVar || isa<Function>(RealGValue)) &&
              "Unexpected global value subclass!");

Modified: llvm/trunk/lib/Target/TargetMachine.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/TargetMachine.cpp?rev=204934&r1=204933&r2=204934&view=diff
==============================================================================
--- llvm/trunk/lib/Target/TargetMachine.cpp (original)
+++ llvm/trunk/lib/Target/TargetMachine.cpp Thu Mar 27 10:26:56 2014
@@ -129,7 +129,7 @@ TLSModel::Model TargetMachine::getTLSMod
   // If GV is an alias then use the aliasee for determining
   // thread-localness.
   if (const GlobalAlias *GA = dyn_cast<GlobalAlias>(GV))
-    GV = GA->resolveAliasedGlobal(false);
+    GV = GA->getAliasedGlobal();
   const GlobalVariable *Var = cast<GlobalVariable>(GV);
 
   bool isLocal = Var->hasLocalLinkage();

Modified: llvm/trunk/lib/Target/X86/X86FastISel.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86FastISel.cpp?rev=204934&r1=204933&r2=204934&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86FastISel.cpp (original)
+++ llvm/trunk/lib/Target/X86/X86FastISel.cpp Thu Mar 27 10:26:56 2014
@@ -363,7 +363,7 @@ bool X86FastISel::handleConstantAddresse
     // it works...).
     if (const GlobalAlias *GA = dyn_cast<GlobalAlias>(GV))
       if (const GlobalVariable *GVar =
-            dyn_cast_or_null<GlobalVariable>(GA->resolveAliasedGlobal(false)))
+              dyn_cast_or_null<GlobalVariable>(GA->getAliasedGlobal()))
         if (GVar->isThreadLocal())
           return false;
 

Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.cpp?rev=204934&r1=204933&r2=204934&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86ISelLowering.cpp (original)
+++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Thu Mar 27 10:26:56 2014
@@ -8509,7 +8509,7 @@ X86TargetLowering::LowerGlobalTLSAddress
     // If GV is an alias then use the aliasee for determining
     // thread-localness.
     if (const GlobalAlias *GA = dyn_cast<GlobalAlias>(GV))
-      GV = GA->resolveAliasedGlobal(false);
+      GV = GA->getAliasedGlobal();
     SDLoc dl(GA);
     SDValue Chain = DAG.getEntryNode();
 

Modified: llvm/trunk/lib/Target/XCore/XCoreISelLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/XCore/XCoreISelLowering.cpp?rev=204934&r1=204933&r2=204934&view=diff
==============================================================================
--- llvm/trunk/lib/Target/XCore/XCoreISelLowering.cpp (original)
+++ llvm/trunk/lib/Target/XCore/XCoreISelLowering.cpp Thu Mar 27 10:26:56 2014
@@ -277,7 +277,7 @@ getGlobalAddressWrapper(SDValue GA, cons
   const GlobalValue *UnderlyingGV = GV;
   // If GV is an alias then use the aliasee to determine the wrapper type
   if (const GlobalAlias *GA = dyn_cast<GlobalAlias>(GV))
-    UnderlyingGV = GA->resolveAliasedGlobal();
+    UnderlyingGV = GA->getAliasedGlobal();
   if (const GlobalVariable *GVar = dyn_cast<GlobalVariable>(UnderlyingGV)) {
     if (  ( GVar->isConstant() &&
             UnderlyingGV->isLocalLinkage(GV->getLinkage()) )

Modified: llvm/trunk/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp?rev=204934&r1=204933&r2=204934&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp (original)
+++ llvm/trunk/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp Thu Mar 27 10:26:56 2014
@@ -554,8 +554,7 @@ bool DataFlowSanitizer::runOnModule(Modu
     ++i;
     // Don't stop on weak.  We assume people aren't playing games with the
     // instrumentedness of overridden weak aliases.
-    if (Function *F = dyn_cast<Function>(
-            GA->resolveAliasedGlobal(/*stopOnWeak=*/false))) {
+    if (Function *F = dyn_cast<Function>(GA->getAliasedGlobal())) {
       bool GAInst = isInstrumented(GA), FInst = isInstrumented(F);
       if (GAInst && FInst) {
         addGlobalNamePrefix(GA);

Modified: llvm/trunk/test/CodeGen/X86/dllexport-x86_64.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/dllexport-x86_64.ll?rev=204934&r1=204933&r2=204934&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/X86/dllexport-x86_64.ll (original)
+++ llvm/trunk/test/CodeGen/X86/dllexport-x86_64.ll Thu Mar 27 10:26:56 2014
@@ -65,7 +65,7 @@ define weak_odr dllexport void @weak1()
 @alias2 = dllexport alias void()* @f1
 
 ; CHECK: .globl alias3
-; CHECK: alias3 = alias
+; CHECK: alias3 = notExported
 @alias3 = dllexport alias void()* @alias
 
 ; CHECK: .weak weak_alias

Modified: llvm/trunk/test/CodeGen/X86/dllexport.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/dllexport.ll?rev=204934&r1=204933&r2=204934&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/X86/dllexport.ll (original)
+++ llvm/trunk/test/CodeGen/X86/dllexport.ll Thu Mar 27 10:26:56 2014
@@ -80,7 +80,7 @@ define weak_odr dllexport void @weak1()
 @alias2 = dllexport alias void()* @f1
 
 ; CHECK: .globl _alias3
-; CHECK: _alias3 = _alias
+; CHECK: _alias3 = _notExported
 @alias3 = dllexport alias void()* @alias
 
 ; CHECK: .weak _weak_alias

Modified: llvm/trunk/test/Feature/aliases.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Feature/aliases.ll?rev=204934&r1=204933&r2=204934&view=diff
==============================================================================
--- llvm/trunk/test/Feature/aliases.ll (original)
+++ llvm/trunk/test/Feature/aliases.ll Thu Mar 27 10:26:56 2014
@@ -14,7 +14,7 @@
 define i32 @foo_f() {
   ret i32 0
 }
- at bar_f = alias weak %FunTy* @foo_f
+ at bar_f = alias weak_odr %FunTy* @foo_f
 @bar_ff = alias i32()* @bar_f
 
 @bar_i = alias internal i32* @bar

Modified: llvm/trunk/test/Transforms/GlobalOpt/alias-resolve.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/GlobalOpt/alias-resolve.ll?rev=204934&r1=204933&r2=204934&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/GlobalOpt/alias-resolve.ll (original)
+++ llvm/trunk/test/Transforms/GlobalOpt/alias-resolve.ll Thu Mar 27 10:26:56 2014
@@ -1,14 +1,17 @@
 ; RUN: opt < %s -globalopt -S | FileCheck %s
 
 @foo1 = alias void ()* @foo2
-; CHECK: @foo1 = alias void ()* @foo2
+; CHECK: @foo1 = alias void ()* @bar2
 
- at foo2 = alias weak void()* @bar1
-; CHECK: @foo2 = alias weak void ()* @bar2
+ at foo2 = alias void()* @bar1
+; CHECK: @foo2 = alias void ()* @bar2
 
 @bar1  = alias void ()* @bar2
 ; CHECK: @bar1 = alias void ()* @bar2
 
+ at weak1 = alias weak void ()* @bar2
+; CHECK: @weak1 = alias weak void ()* @bar2
+
 define void @bar2() {
   ret void
 }
@@ -17,14 +20,16 @@ define void @bar2() {
 define void @baz() {
 entry:
          call void @foo1()
-; CHECK: call void @foo2()
+; CHECK: call void @bar2()
 
          call void @foo2()
-; CHECK: call void @foo2()
+; CHECK: call void @bar2()
 
          call void @bar1()
 ; CHECK: call void @bar2()
 
+         call void @weak1()
+; CHECK: call void @weak1()
          ret void
 }
 





More information about the llvm-commits mailing list