diff options
| author | Amara Emerson <aemerson@apple.com> | 2020-02-07 10:10:43 -0800 |
|---|---|---|
| committer | Amara Emerson <aemerson@apple.com> | 2020-02-07 15:32:54 -0800 |
| commit | 35c63d66aaae65a7004d94e0a6668ff19612ba5e (patch) | |
| tree | e7a4e8fbc9fda22e4f90339432bdf9cc96600f05 /llvm/lib | |
| parent | fbb4d1e43d0db9f8d1514a0209bb01f56e49d75f (diff) | |
| download | llvm-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.cpp | 14 |
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()) |
