CCState &CCInfo, CallLoweringInfo &CLI, MachineFunction &MF,
const SmallVector<CCValAssign, 16> &ArgLocs) const {
- auto &Callee = CLI.Callee;
auto CalleeCC = CLI.CallConv;
auto &Outs = CLI.Outs;
auto &Caller = MF.getFunction();
if (IsCallerStructRet || IsCalleeStructRet)
return false;
- // Externally-defined functions with weak linkage should not be
- // tail-called. The behaviour of branch instructions in this situation (as
- // used for tail calls) is implementation-defined, so we cannot rely on the
- // linker replacing the tail call with a return.
- if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee)) {
- const GlobalValue *GV = G->getGlobal();
- if (GV->hasExternalWeakLinkage())
- return false;
- }
-
// The callee has to preserve all registers the caller needs to preserve.
const RISCVRegisterInfo *TRI = Subtarget.getRegisterInfo();
const uint32_t *CallerPreserved = TRI->getCallPreservedMask(MF, CallerCC);
ret void
}
-; Externally-defined functions with weak linkage should not be tail-called.
-; The behaviour of branch instructions in this situation (as used for tail
-; calls) is implementation-defined, so we cannot rely on the linker replacing
-; the tail call with a return.
+; Perform tail call optimization for external weak symbol.
declare extern_weak void @callee_weak()
define void @caller_weak() nounwind {
; CHECK-LABEL: caller_weak
-; CHECK-NOT: tail callee_weak
-; CHECK: call callee_weak
+; CHECK: tail callee_weak
entry:
tail call void @callee_weak()
ret void