aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib
diff options
context:
space:
mode:
authorAmara Emerson <aemerson@apple.com>2020-02-07 10:10:43 -0800
committerAmara Emerson <aemerson@apple.com>2020-02-07 15:32:54 -0800
commit35c63d66aaae65a7004d94e0a6668ff19612ba5e (patch)
treee7a4e8fbc9fda22e4f90339432bdf9cc96600f05 /llvm/lib
parentfbb4d1e43d0db9f8d1514a0209bb01f56e49d75f (diff)
downloadllvm-35c63d66aaae65a7004d94e0a6668ff19612ba5e.zip
llvm-35c63d66aaae65a7004d94e0a6668ff19612ba5e.tar.gz
llvm-35c63d66aaae65a7004d94e0a6668ff19612ba5e.tar.bz2
[GlobalISel][CallLowering] Look through bitcasts from constant function pointers.
Calls to ObjC's objc_msgSend function are done by bitcasting the function global to the required function type signature. This patch looks through this bitcast so that we can do a direct call with bl on arm64 instead of using an indirect blr. Differential Revision: https://reviews.llvm.org/D74241
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/CodeGen/GlobalISel/CallLowering.cpp14
1 files changed, 12 insertions, 2 deletions
diff --git a/llvm/lib/CodeGen/GlobalISel/CallLowering.cpp b/llvm/lib/CodeGen/GlobalISel/CallLowering.cpp
index 294e089..752f26b 100644
--- a/llvm/lib/CodeGen/GlobalISel/CallLowering.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/CallLowering.cpp
@@ -52,8 +52,18 @@ bool CallLowering::lowerCall(MachineIRBuilder &MIRBuilder, ImmutableCallSite CS,
if (const Function *F = CS.getCalledFunction())
Info.Callee = MachineOperand::CreateGA(F, 0);
- else
- Info.Callee = MachineOperand::CreateReg(GetCalleeReg(), false);
+ else {
+ // Try looking through a bitcast from one function type to another.
+ // Commonly happens with calls to objc_msgSend().
+ const Value *CalleeV = CS.getCalledValue();
+ if (auto *BC = dyn_cast<ConstantExpr>(CalleeV)) {
+ if (const auto *F = dyn_cast<Function>(BC->getOperand(0))) {
+ Info.Callee = MachineOperand::CreateGA(F, 0);
+ }
+ } else {
+ Info.Callee = MachineOperand::CreateReg(GetCalleeReg(), false);
+ }
+ }
Info.OrigRet = ArgInfo{ResRegs, CS.getType(), ISD::ArgFlagsTy{}};
if (!Info.OrigRet.Ty->isVoidTy())