mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-30 04:35:00 +00: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 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@192302 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
1a525e8c80
commit
e0409098ae
@ -357,6 +357,19 @@ bool DAE::RemoveDeadArgumentsFromCallers(Function &Fn)
|
|||||||
if (Fn.hasLocalLinkage() && !Fn.getFunctionType()->isVarArg())
|
if (Fn.hasLocalLinkage() && !Fn.getFunctionType()->isVarArg())
|
||||||
return false;
|
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())
|
if (Fn.use_empty())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
21
test/Transforms/DeadArgElim/linkage.ll
Normal file
21
test/Transforms/DeadArgElim/linkage.ll
Normal 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
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user