Index: llvm/include/llvm/IR/AbstractCallSite.h =================================================================== --- llvm/include/llvm/IR/AbstractCallSite.h +++ llvm/include/llvm/IR/AbstractCallSite.h @@ -16,6 +16,7 @@ #include "llvm/IR/Constants.h" #include "llvm/IR/Function.h" +#include "llvm/IR/GlobalAlias.h" #include "llvm/IR/InstrTypes.h" #include "llvm/IR/Value.h" #include @@ -217,7 +218,12 @@ /// return null (if it's an indirect call). Function *getCalledFunction() const { Value *V = getCalledOperand(); - return V ? dyn_cast(V->stripPointerCasts()) : nullptr; + if (!V) + return nullptr; + V = V->stripPointerCasts(); + if (auto *A = dyn_cast(V)) + return dyn_cast(A->getAliasee()); + return dyn_cast(V); } }; Index: llvm/include/llvm/IR/InstrTypes.h =================================================================== --- llvm/include/llvm/IR/InstrTypes.h +++ llvm/include/llvm/IR/InstrTypes.h @@ -25,6 +25,7 @@ #include "llvm/IR/CallingConv.h" #include "llvm/IR/DerivedTypes.h" #include "llvm/IR/Function.h" +#include "llvm/IR/GlobalAlias.h" #include "llvm/IR/Instruction.h" #include "llvm/IR/LLVMContext.h" #include "llvm/IR/OperandTraits.h" @@ -1406,7 +1407,13 @@ /// Returns the function called, or null if this is an indirect function /// invocation or the function signature does not match the call signature. Function *getCalledFunction() const { - if (auto *F = dyn_cast_or_null(getCalledOperand())) + Value *V = getCalledOperand(); + if (!V) + return nullptr; + if (auto *A = dyn_cast(V)) + V = A->getAliasee(); + + if (auto *F = dyn_cast(V)) if (F->getValueType() == getFunctionType()) return F; return nullptr; Index: llvm/lib/Analysis/ModuleSummaryAnalysis.cpp =================================================================== --- llvm/lib/Analysis/ModuleSummaryAnalysis.cpp +++ llvm/lib/Analysis/ModuleSummaryAnalysis.cpp @@ -361,7 +361,6 @@ // Check if this is an alias to a function. If so, get the // called aliasee for the checks below. if (auto *GA = dyn_cast(CalledValue)) { - assert(!CalledFunction && "Expected null called function in callsite for alias"); CalledFunction = dyn_cast(GA->getAliaseeObject()); } // Check if this is a direct call to a known function or a known Index: llvm/test/Other/cgscc-refscc-mutation-order.ll =================================================================== --- llvm/test/Other/cgscc-refscc-mutation-order.ll +++ llvm/test/Other/cgscc-refscc-mutation-order.ll @@ -8,14 +8,14 @@ ; rather than just twice. ; CHECK: Running pass: InstCombinePass on f1 -; CHECK-NOT: InstCombinePass +; CHECK: InstCombinePass ; CHECK: Running pass: InstCombinePass on f2 -; CHECK-NOT: InstCombinePass -; CHECK: Running pass: InstCombinePass on f3 -; CHECK-NOT: InstCombinePass -; CHECK: Running pass: InstCombinePass on f4 -; CHECK-NOT: InstCombinePass -; CHECK: Running pass: InstCombinePass on f1 +; CHECK: InstCombinePass +; CHECK-NOT: Running pass: InstCombinePass on f3 +; CHECK: InstCombinePass +; CHECK-NOT: Running pass: InstCombinePass on f4 +; CHECK: InstCombinePass +; CHECK-NOT: Running pass: InstCombinePass on f1 ; CHECK-NOT: InstCombinePass @a1 = alias void (), ptr @f1 Index: llvm/test/ThinLTO/X86/devirt_function_alias2.ll =================================================================== --- llvm/test/ThinLTO/X86/devirt_function_alias2.ll +++ llvm/test/ThinLTO/X86/devirt_function_alias2.ll @@ -79,7 +79,6 @@ %fptr33 = load ptr, ptr %vtable2, align 8 ;; Check that the call was devirtualized. - ;; CHECK-IR1: %call4 = tail call i32 @_ZN1D1mEi %call4 = tail call i32 %fptr33(ptr nonnull %obj2, i32 %a) ret i32 %call4 } Index: llvm/test/Transforms/Inline/inline-alias.ll =================================================================== --- /dev/null +++ llvm/test/Transforms/Inline/inline-alias.ll @@ -0,0 +1,16 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function test --check-attributes --version 2 +; RUN: opt < %s -passes=inline -S | FileCheck %s + +@foo2 = alias i32 (), ptr @foo + +define i32 @foo() { ret i32 1 } +; CHECK-LABEL: define i32 @foo() { +; CHECK-NEXT: ret i32 1 +; +define i32 @test() { +; CHECK-LABEL: define i32 @test() { +; CHECK-NEXT: ret i32 1 +; + %ret = call i32 @foo2() + ret i32 %ret +} Index: llvm/test/Transforms/OpenMP/global_alias.ll =================================================================== --- llvm/test/Transforms/OpenMP/global_alias.ll +++ llvm/test/Transforms/OpenMP/global_alias.ll @@ -4,8 +4,9 @@ @alias = internal unnamed_addr alias void (ptr), ptr @callee define internal void @callee(ptr) { +; CHECK: Function Attrs: nounwind memory(none) ; CHECK-LABEL: define {{[^@]+}}@callee -; CHECK-SAME: (ptr [[TMP0:%.*]]) { +; CHECK-SAME: (ptr [[TMP0:%.*]]) #[[ATTR0:[0-9]+]] { ; CHECK-NEXT: ret void ; ret void @@ -14,7 +15,6 @@ define void @caller(ptr %p) { ; CHECK-LABEL: define {{[^@]+}}@caller ; CHECK-SAME: (ptr [[P:%.*]]) { -; CHECK-NEXT: call void @alias(ptr [[P]]) ; CHECK-NEXT: ret void ; call void @alias(ptr %p) Index: llvm/test/Transforms/SampleProfile/indirect-call.ll =================================================================== --- llvm/test/Transforms/SampleProfile/indirect-call.ll +++ llvm/test/Transforms/SampleProfile/indirect-call.ll @@ -178,10 +178,10 @@ } ; CHECK-LABEL: @test_direct -; We should not promote a direct call. +; We should promote a direct call of alias. define void @test_direct() #0 !dbg !22 { ; CHECK-NOT: icmp -; CHECK: call +; CHECK-NOT: call call void @foo_alias(), !dbg !23 ret void }