1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-10-19 11:02:59 +02:00

Fix a bug in Dead Argument Elimination.

If a function seen at compile time is not necessarily the one linked to
the binary being built, it is illegal to change the actual arguments
passing to it. 

  e.g. 
   --------------------------
   void foo(int lol) {
     // foo() has linkage satisifying isWeakForLinker()
     // "lol" is not used at all.
   }

   void bar(int lo2) {
      // xform to foo(undef) is illegal, as compiler dose not know which
      // instance of foo() will be linked to the the binary being built.
      foo(lol2); 
   }
  -----------------------------

  Such functions can be captured by isWeakForLinker(). NOTE that
mayBeOverridden() is insufficient for this purpose as it dosen't include
linkage types like AvailableExternallyLinkage and LinkOnceODRLinkage.
Take link_odr* as an example, it indicates a set of *EQUIVALENT* globals
that can be merged at link-time. However, the semantic of 
*EQUIVALENT*-functions includes parameters. Changing parameters breaks
the assumption.

  Thank John McCall for help, especially for the explanation of subtle
difference between linkage types.

  rdar://11546243

llvm-svn: 192302
This commit is contained in:
Shuxin Yang 2013-10-09 17:21:44 +00:00
parent f0991565b5
commit 708f0cc2e4
2 changed files with 34 additions and 0 deletions

View File

@ -357,6 +357,19 @@ bool DAE::RemoveDeadArgumentsFromCallers(Function &Fn)
if (Fn.hasLocalLinkage() && !Fn.getFunctionType()->isVarArg())
return false;
// If a function seen at compile time is not necessarily the one linked to
// the binary being built, it is illegal to change the actual arguments
// passing to it. These functions can be captured by isWeakForLinker().
// *NOTE* that mayBeOverridden() is insufficient for this purpose as it
// dosen't include linkage types like AvailableExternallyLinkage and
// LinkOnceODRLinkage. Take link_odr* as an example, it indicates a set of
// *EQUIVALENT* globals that can be merged at link-time. However, the
// semantic of *EQUIVALENT*-functions includes parameters. Changing
// parameters breaks the assumption.
//
if (Fn.isWeakForLinker())
return false;
if (Fn.use_empty())
return false;

View File

@ -0,0 +1,21 @@
; RUN: opt < %s -deadargelim -S | FileCheck %s
; rdar://11546243
%struct.A = type { i8 }
define available_externally void @_Z17externallyDefinedP1A(%struct.A* %a) {
entry:
call void @_Z3foov()
ret void
}
declare void @_Z3foov()
define void @_Z4testP1A(%struct.A* %a) {
; CHECK: @_Z4testP1A
; CHECK: @_Z17externallyDefinedP1A(%struct.A* %a)
entry:
call void @_Z17externallyDefinedP1A(%struct.A* %a)
ret void
}