diff --git a/lib/Transforms/Utils/GlobalStatus.cpp b/lib/Transforms/Utils/GlobalStatus.cpp index 8fb79aa87b3..5f0a563ceec 100644 --- a/lib/Transforms/Utils/GlobalStatus.cpp +++ b/lib/Transforms/Utils/GlobalStatus.cpp @@ -11,6 +11,7 @@ #include "llvm/IR/BasicBlock.h" #include "llvm/IR/GlobalVariable.h" #include "llvm/IR/IntrinsicInst.h" +#include "llvm/Support/CallSite.h" #include "llvm/Transforms/Utils/GlobalStatus.h" using namespace llvm; @@ -148,6 +149,10 @@ static bool analyzeGlobalAux(const Value *V, GlobalStatus &GS, if (MSI->isVolatile()) return true; GS.StoredType = GlobalStatus::Stored; + } else if (ImmutableCallSite C = I) { + if (!C.isCallee(UI)) + return true; + GS.IsLoaded = true; } else { return true; // Any other non-load instruction might take address! } diff --git a/test/Transforms/Internalize/linkonce_odr_func.ll b/test/Transforms/Internalize/linkonce_odr_func.ll new file mode 100644 index 00000000000..c82acc0174a --- /dev/null +++ b/test/Transforms/Internalize/linkonce_odr_func.ll @@ -0,0 +1,37 @@ +; RUN: opt < %s -internalize -internalize-dso-list foo1,foo2,foo3,foo4 -S | FileCheck %s + +; CHECK: define internal void @foo1( +define linkonce_odr void @foo1() noinline { + ret void +} + +; CHECK: define linkonce_odr void @foo2( +define linkonce_odr void @foo2() noinline { + ret void +} + +; CHECK: define internal void @foo3( +define linkonce_odr void @foo3() noinline { + ret void +} + +; CHECK: define linkonce_odr void @foo4( +define linkonce_odr void @foo4() noinline { + ret void +} + +declare void @f(void()*) + +define void @bar() { +bb0: + call void @foo1() + call void @f(void()* @foo2) + invoke void @foo3() to label %bb1 unwind label %clean +bb1: + invoke void @f(void()* @foo4) to label %bb2 unwind label %clean +bb2: + ret void +clean: + landingpad i32 personality i8* null cleanup + ret void +}