diff --git a/lib/Transforms/Utils/Evaluator.cpp b/lib/Transforms/Utils/Evaluator.cpp index 264bc21d604..7fd9425efed 100644 --- a/lib/Transforms/Utils/Evaluator.cpp +++ b/lib/Transforms/Utils/Evaluator.cpp @@ -24,6 +24,7 @@ #include "llvm/IR/DataLayout.h" #include "llvm/IR/DerivedTypes.h" #include "llvm/IR/Function.h" +#include "llvm/IR/GlobalAlias.h" #include "llvm/IR/GlobalValue.h" #include "llvm/IR/GlobalVariable.h" #include "llvm/IR/InstrTypes.h" @@ -217,16 +218,26 @@ Constant *Evaluator::ComputeLoadResult(Constant *P) { return nullptr; // don't know how to evaluate. } +static Function *getFunction(Constant *C) { + if (auto *Fn = dyn_cast(C)) + return Fn; + + if (auto *Alias = dyn_cast(C)) + if (auto *Fn = dyn_cast(Alias->getAliasee())) + return Fn; + return nullptr; +} + Function * Evaluator::getCalleeWithFormalArgs(CallSite &CS, SmallVector &Formals) { auto *V = CS.getCalledValue(); - if (auto *Fn = dyn_cast(getVal(V))) + if (auto *Fn = getFunction(getVal(V))) return getFormalParams(CS, Fn, Formals) ? Fn : nullptr; auto *CE = dyn_cast(V); if (!CE || CE->getOpcode() != Instruction::BitCast || - !getFormalParams(CS, cast(CE->getOperand(0)), Formals)) + !getFormalParams(CS, getFunction(CE->getOperand(0)), Formals)) return nullptr; return dyn_cast( @@ -235,6 +246,9 @@ Evaluator::getCalleeWithFormalArgs(CallSite &CS, bool Evaluator::getFormalParams(CallSite &CS, Function *F, SmallVector &Formals) { + if (!F) + return false; + auto *FTy = F->getFunctionType(); if (FTy->getNumParams() > CS.getNumArgOperands()) { LLVM_DEBUG(dbgs() << "Too few arguments for function.\n"); diff --git a/test/Transforms/GlobalOpt/evaluate-call.ll b/test/Transforms/GlobalOpt/evaluate-call.ll index 27211007c6e..c0456740da4 100644 --- a/test/Transforms/GlobalOpt/evaluate-call.ll +++ b/test/Transforms/GlobalOpt/evaluate-call.ll @@ -28,10 +28,12 @@ target triple = "x86_64-apple-macosx10.12.0" @llvm.global_ctors = appending global [1 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 65535, void ()* @_GLOBAL__sub_I_main.cpp, i8* null }] define internal void @__cxx_global_var_init() section "__TEXT,__StaticInit,regular,pure_instructions" { - call void @_ZN1SC1Ev(%struct.S* @_s) + call void @_ZN1SC1Ev_alias(%struct.S* @_s) ret void } +@_ZN1SC1Ev_alias = linkonce_odr unnamed_addr alias void (%struct.S*), void (%struct.S*)* @_ZN1SC1Ev + define linkonce_odr void @_ZN1SC1Ev(%struct.S*) unnamed_addr align 2 { %2 = alloca %struct.S*, align 8 store %struct.S* %0, %struct.S** %2, align 8