summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/lib/Target/AArch64/AArch64CallLowering.cpp11
-rw-r--r--llvm/test/CodeGen/AArch64/GlobalISel/call-translator.ll4
2 files changed, 14 insertions, 1 deletions
diff --git a/llvm/lib/Target/AArch64/AArch64CallLowering.cpp b/llvm/lib/Target/AArch64/AArch64CallLowering.cpp
index 7efee8bf8c2..4f5b2886b1a 100644
--- a/llvm/lib/Target/AArch64/AArch64CallLowering.cpp
+++ b/llvm/lib/Target/AArch64/AArch64CallLowering.cpp
@@ -97,7 +97,7 @@ struct OutgoingArgHandler : public CallLowering::ValueHandler {
MachineInstrBuilder MIB, CCAssignFn *AssignFn,
CCAssignFn *AssignFnVarArg)
: ValueHandler(MIRBuilder, MRI, AssignFn), MIB(MIB),
- AssignFnVarArg(AssignFnVarArg) {}
+ AssignFnVarArg(AssignFnVarArg), StackSize(0) {}
unsigned getStackAddress(uint64_t Size, int64_t Offset,
MachinePointerInfo &MPO) override {
@@ -113,6 +113,7 @@ struct OutgoingArgHandler : public CallLowering::ValueHandler {
MIRBuilder.buildGEP(AddrReg, SPReg, OffsetReg);
MPO = MachinePointerInfo::getStack(MIRBuilder.getMF(), Offset);
+ StackSize = std::max(StackSize, Size + Offset);
return AddrReg;
}
@@ -141,6 +142,7 @@ struct OutgoingArgHandler : public CallLowering::ValueHandler {
MachineInstrBuilder MIB;
CCAssignFn *AssignFnVarArg;
+ uint64_t StackSize;
};
void AArch64CallLowering::splitToValueTypes(
@@ -275,6 +277,8 @@ bool AArch64CallLowering::lowerCall(MachineIRBuilder &MIRBuilder,
CCAssignFn *AssignFnVarArg =
TLI.CCAssignFnForCall(F.getCallingConv(), /*IsVarArg=*/true);
+ auto CallSeqStart = MIRBuilder.buildInstr(AArch64::ADJCALLSTACKDOWN);
+
// Create a temporarily-floating call instruction so we can add the implicit
// uses of arg registers.
auto MIB = MIRBuilder.buildInstrNoInsert(Callee.isReg() ? AArch64::BLR
@@ -329,5 +333,10 @@ bool AArch64CallLowering::lowerCall(MachineIRBuilder &MIRBuilder,
MIRBuilder.buildSequence(OrigRet.Reg, SplitRegs, RegOffsets);
}
+ CallSeqStart.addImm(Handler.StackSize);
+ MIRBuilder.buildInstr(AArch64::ADJCALLSTACKUP)
+ .addImm(Handler.StackSize)
+ .addImm(0);
+
return true;
}
diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/call-translator.ll b/llvm/test/CodeGen/AArch64/GlobalISel/call-translator.ll
index 7bedad38de1..f9c0fdb5bb2 100644
--- a/llvm/test/CodeGen/AArch64/GlobalISel/call-translator.ll
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/call-translator.ll
@@ -1,7 +1,9 @@
; RUN: llc -mtriple=aarch64-linux-gnu -O0 -stop-after=irtranslator -global-isel -verify-machineinstrs %s -o - 2>&1 | FileCheck %s
; CHECK-LABEL: name: test_trivial_call
+; CHECK: ADJCALLSTACKDOWN 0, implicit-def %sp, implicit %sp
; CHECK: BL @trivial_callee, csr_aarch64_aapcs, implicit-def %lr
+; CHECK: ADJCALLSTACKUP 0, 0, implicit-def %sp, implicit %sp
declare void @trivial_callee()
define void @test_trivial_call() {
call void @trivial_callee()
@@ -168,6 +170,7 @@ define void @test_stack_slots([8 x i64], i64 %lhs, i64 %rhs, i64* %addr) {
; CHECK: [[C42:%[0-9]+]](s64) = G_CONSTANT i64 42
; CHECK: [[C12:%[0-9]+]](s64) = G_CONSTANT i64 12
; CHECK: [[PTR:%[0-9]+]](p0) = G_CONSTANT i64 0
+; CHECK: ADJCALLSTACKDOWN 24, implicit-def %sp, implicit %sp
; CHECK: [[SP:%[0-9]+]](p0) = COPY %sp
; CHECK: [[C42_OFFS:%[0-9]+]](s64) = G_CONSTANT i64 0
; CHECK: [[C42_LOC:%[0-9]+]](p0) = G_GEP [[SP]], [[C42_OFFS]](s64)
@@ -181,6 +184,7 @@ define void @test_stack_slots([8 x i64], i64 %lhs, i64 %rhs, i64* %addr) {
; CHECK: [[PTR_LOC:%[0-9]+]](p0) = G_GEP [[SP]], [[PTR_OFFS]](s64)
; CHECK: G_STORE [[PTR]](p0), [[PTR_LOC]](p0) :: (store 8 into stack + 16, align 0)
; CHECK: BL @test_stack_slots
+; CHECK: ADJCALLSTACKUP 24, 0, implicit-def %sp, implicit %sp
define void @test_call_stack() {
call void @test_stack_slots([8 x i64] undef, i64 42, i64 12, i64* null)
ret void
OpenPOWER on IntegriCloud