diff --git a/lib/Transforms/IPO/DeadArgumentElimination.cpp b/lib/Transforms/IPO/DeadArgumentElimination.cpp index b42322116a9..4d1f7abdc32 100644 --- a/lib/Transforms/IPO/DeadArgumentElimination.cpp +++ b/lib/Transforms/IPO/DeadArgumentElimination.cpp @@ -294,7 +294,7 @@ bool DAE::DeleteDeadVarargs(Function &Fn) { /// instead. bool DAE::RemoveDeadArgumentsFromCallers(Function &Fn) { - if (Fn.isDeclaration()) + if (Fn.isDeclaration() || Fn.mayBeOverridden()) return false; // Functions with local linkage should already have been handled. diff --git a/test/Transforms/DeadArgElim/deadexternal.ll b/test/Transforms/DeadArgElim/deadexternal.ll index 5a80aba6e2d..84092613130 100644 --- a/test/Transforms/DeadArgElim/deadexternal.ll +++ b/test/Transforms/DeadArgElim/deadexternal.ll @@ -37,3 +37,16 @@ entry: call void @f(i32 %tmp) ret void } + +; Check that callers are not transformed for weak definitions. +define weak i32 @weak_f(i32 %x) nounwind { +entry: + ret i32 0 +} +define void @weak_f_caller() nounwind { +entry: +; CHECK: call i32 @weak_f(i32 10) + %call = tail call i32 @weak_f(i32 10) + ret void +} +