diff --git a/llvm/lib/Target/RISCV/RISCVFrameLowering.h b/llvm/lib/Target/RISCV/RISCVFrameLowering.h --- a/llvm/lib/Target/RISCV/RISCVFrameLowering.h +++ b/llvm/lib/Target/RISCV/RISCVFrameLowering.h @@ -40,6 +40,7 @@ bool hasFP(const MachineFunction &MF) const override; + bool targetHandlesStackFrameRounding() const override { return true; } bool hasReservedCallFrame(const MachineFunction &MF) const override; MachineBasicBlock::iterator eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB, diff --git a/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp b/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp --- a/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp +++ b/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp @@ -40,8 +40,16 @@ uint64_t FrameSize = MFI.getStackSize(); // Get the alignment. - uint64_t StackAlign = RI->needsStackRealignment(MF) ? MFI.getMaxAlignment() - : getStackAlignment(); + unsigned StackAlign = getStackAlignment(); + if (RI->needsStackRealignment(MF)) { + unsigned MaxStackAlign = std::max(StackAlign, MFI.getMaxAlignment()); + FrameSize += (MaxStackAlign - StackAlign); + StackAlign = MaxStackAlign; + } + + // Set Max Call Frame Size + uint64_t MaxCallSize = alignTo(MFI.getMaxCallFrameSize(), StackAlign); + MFI.setMaxCallFrameSize(MaxCallSize); // Make sure the frame is aligned. FrameSize = alignTo(FrameSize, StackAlign); @@ -101,6 +109,12 @@ const RISCVInstrInfo *TII = STI.getInstrInfo(); MachineBasicBlock::iterator MBBI = MBB.begin(); + if (RI->needsStackRealignment(MF) && MFI.hasVarSizedObjects()) { + report_fatal_error( + "RISC-V backend can't currently handle functions that need stack " + "realignment and have variable sized objects"); + } + unsigned FPReg = getFPReg(STI); unsigned SPReg = getSPReg(STI); @@ -158,6 +172,29 @@ nullptr, RI->getDwarfRegNum(FPReg, true), 0)); BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION)) .addCFIIndex(CFIIndex); + + // Realign Stack + const RISCVRegisterInfo *RI = STI.getRegisterInfo(); + if (RI->needsStackRealignment(MF)) { + unsigned MaxAlignment = MFI.getMaxAlignment(); + + const RISCVInstrInfo *TII = STI.getInstrInfo(); + if (isInt<12>(-(int)MaxAlignment)) { + BuildMI(MBB, MBBI, DL, TII->get(RISCV::ANDI), SPReg) + .addReg(SPReg) + .addImm(-(int)MaxAlignment); + } + else { + unsigned ShiftAmount = countTrailingZeros(MaxAlignment); + unsigned VR = MF.getRegInfo().createVirtualRegister(&RISCV::GPRRegClass); + BuildMI(MBB, MBBI, DL, TII->get(RISCV::SRLI), VR) + .addReg(SPReg) + .addImm(ShiftAmount); + BuildMI(MBB, MBBI, DL, TII->get(RISCV::SLLI), SPReg) + .addReg(VR) + .addImm(ShiftAmount); + } + } } } @@ -257,6 +294,13 @@ if (FI >= MinCSFI && FI <= MaxCSFI) { FrameReg = RISCV::X2; Offset += MF.getFrameInfo().getStackSize(); + } else if (RI->needsStackRealignment(MF)) { + assert(!MFI.hasVarSizedObjects() && + "Unexpected combination of stack realignment and varsized objects"); + // If the stack was realigned, the frame pointer is set in order to allow + // SP to be restored, but we still stack objects using SP. + FrameReg = RISCV::X2; + Offset += MF.getFrameInfo().getStackSize(); } else { FrameReg = RI->getFrameRegister(MF); if (hasFP(MF)) diff --git a/llvm/test/CodeGen/RISCV/calling-conv-ilp32-ilp32f-common.ll b/llvm/test/CodeGen/RISCV/calling-conv-ilp32-ilp32f-common.ll --- a/llvm/test/CodeGen/RISCV/calling-conv-ilp32-ilp32f-common.ll +++ b/llvm/test/CodeGen/RISCV/calling-conv-ilp32-ilp32f-common.ll @@ -143,8 +143,8 @@ ; should only be 4-byte aligned ; RV32I-FPELIM-LABEL: caller_aligned_stack: ; RV32I-FPELIM: # %bb.0: -; RV32I-FPELIM-NEXT: addi sp, sp, -64 -; RV32I-FPELIM-NEXT: sw ra, 60(sp) +; RV32I-FPELIM-NEXT: addi sp, sp, -32 +; RV32I-FPELIM-NEXT: sw ra, 28(sp) ; RV32I-FPELIM-NEXT: addi a0, zero, 18 ; RV32I-FPELIM-NEXT: sw a0, 24(sp) ; RV32I-FPELIM-NEXT: addi a0, zero, 17 @@ -161,19 +161,19 @@ ; RV32I-FPELIM-NEXT: sw a0, 0(sp) ; RV32I-FPELIM-NEXT: lui a0, 262153 ; RV32I-FPELIM-NEXT: addi a0, a0, 491 -; RV32I-FPELIM-NEXT: sw a0, 44(sp) +; RV32I-FPELIM-NEXT: sw a0, 12(sp) ; RV32I-FPELIM-NEXT: lui a0, 545260 ; RV32I-FPELIM-NEXT: addi a0, a0, -1967 -; RV32I-FPELIM-NEXT: sw a0, 40(sp) +; RV32I-FPELIM-NEXT: sw a0, 8(sp) ; RV32I-FPELIM-NEXT: lui a0, 964690 ; RV32I-FPELIM-NEXT: addi a0, a0, -328 -; RV32I-FPELIM-NEXT: sw a0, 36(sp) +; RV32I-FPELIM-NEXT: sw a0, 4(sp) ; RV32I-FPELIM-NEXT: lui a0, 335544 ; RV32I-FPELIM-NEXT: addi a0, a0, 1311 -; RV32I-FPELIM-NEXT: sw a0, 32(sp) +; RV32I-FPELIM-NEXT: sw a0, 0(sp) ; RV32I-FPELIM-NEXT: lui a0, 688509 ; RV32I-FPELIM-NEXT: addi a5, a0, -2048 -; RV32I-FPELIM-NEXT: addi a2, sp, 32 +; RV32I-FPELIM-NEXT: mv a2, sp ; RV32I-FPELIM-NEXT: addi a0, zero, 1 ; RV32I-FPELIM-NEXT: addi a1, zero, 11 ; RV32I-FPELIM-NEXT: addi a3, zero, 12 @@ -181,16 +181,16 @@ ; RV32I-FPELIM-NEXT: addi a6, zero, 4 ; RV32I-FPELIM-NEXT: addi a7, zero, 14 ; RV32I-FPELIM-NEXT: call callee_aligned_stack -; RV32I-FPELIM-NEXT: lw ra, 60(sp) -; RV32I-FPELIM-NEXT: addi sp, sp, 64 +; RV32I-FPELIM-NEXT: lw ra, 28(sp) +; RV32I-FPELIM-NEXT: addi sp, sp, 32 ; RV32I-FPELIM-NEXT: ret ; ; RV32I-WITHFP-LABEL: caller_aligned_stack: ; RV32I-WITHFP: # %bb.0: -; RV32I-WITHFP-NEXT: addi sp, sp, -64 -; RV32I-WITHFP-NEXT: sw ra, 60(sp) -; RV32I-WITHFP-NEXT: sw s0, 56(sp) -; RV32I-WITHFP-NEXT: addi s0, sp, 64 +; RV32I-WITHFP-NEXT: addi sp, sp, -32 +; RV32I-WITHFP-NEXT: sw ra, 28(sp) +; RV32I-WITHFP-NEXT: sw s0, 24(sp) +; RV32I-WITHFP-NEXT: addi s0, sp, 32 ; RV32I-WITHFP-NEXT: addi a0, zero, 18 ; RV32I-WITHFP-NEXT: sw a0, 24(sp) ; RV32I-WITHFP-NEXT: addi a0, zero, 17 @@ -227,9 +227,9 @@ ; RV32I-WITHFP-NEXT: addi a6, zero, 4 ; RV32I-WITHFP-NEXT: addi a7, zero, 14 ; RV32I-WITHFP-NEXT: call callee_aligned_stack -; RV32I-WITHFP-NEXT: lw s0, 56(sp) -; RV32I-WITHFP-NEXT: lw ra, 60(sp) -; RV32I-WITHFP-NEXT: addi sp, sp, 64 +; RV32I-WITHFP-NEXT: lw s0, 24(sp) +; RV32I-WITHFP-NEXT: lw ra, 28(sp) +; RV32I-WITHFP-NEXT: addi sp, sp, 32 ; RV32I-WITHFP-NEXT: ret %1 = call i32 @callee_aligned_stack(i32 1, i32 11, fp128 0xLEB851EB851EB851F400091EB851EB851, i32 12, i32 13, diff --git a/llvm/test/CodeGen/RISCV/calling-conv-ilp32-ilp32f-ilp32d-common.ll b/llvm/test/CodeGen/RISCV/calling-conv-ilp32-ilp32f-ilp32d-common.ll --- a/llvm/test/CodeGen/RISCV/calling-conv-ilp32-ilp32f-ilp32d-common.ll +++ b/llvm/test/CodeGen/RISCV/calling-conv-ilp32-ilp32f-ilp32d-common.ll @@ -353,23 +353,23 @@ define i32 @caller_large_scalars_exhausted_regs() nounwind { ; RV32I-FPELIM-LABEL: caller_large_scalars_exhausted_regs: ; RV32I-FPELIM: # %bb.0: -; RV32I-FPELIM-NEXT: addi sp, sp, -64 -; RV32I-FPELIM-NEXT: sw ra, 60(sp) -; RV32I-FPELIM-NEXT: addi a0, sp, 16 +; RV32I-FPELIM-NEXT: addi sp, sp, -48 +; RV32I-FPELIM-NEXT: sw ra, 44(sp) +; RV32I-FPELIM-NEXT: mv a0, sp ; RV32I-FPELIM-NEXT: sw a0, 4(sp) ; RV32I-FPELIM-NEXT: addi a0, zero, 9 ; RV32I-FPELIM-NEXT: sw a0, 0(sp) ; RV32I-FPELIM-NEXT: lui a0, 524272 -; RV32I-FPELIM-NEXT: sw a0, 28(sp) -; RV32I-FPELIM-NEXT: sw zero, 24(sp) -; RV32I-FPELIM-NEXT: sw zero, 20(sp) -; RV32I-FPELIM-NEXT: sw zero, 16(sp) -; RV32I-FPELIM-NEXT: sw zero, 52(sp) -; RV32I-FPELIM-NEXT: sw zero, 48(sp) -; RV32I-FPELIM-NEXT: sw zero, 44(sp) +; RV32I-FPELIM-NEXT: sw a0, 12(sp) +; RV32I-FPELIM-NEXT: sw zero, 8(sp) +; RV32I-FPELIM-NEXT: sw zero, 4(sp) +; RV32I-FPELIM-NEXT: sw zero, 0(sp) +; RV32I-FPELIM-NEXT: sw zero, 36(sp) +; RV32I-FPELIM-NEXT: sw zero, 32(sp) +; RV32I-FPELIM-NEXT: sw zero, 28(sp) ; RV32I-FPELIM-NEXT: addi a0, zero, 8 -; RV32I-FPELIM-NEXT: sw a0, 40(sp) -; RV32I-FPELIM-NEXT: addi a7, sp, 40 +; RV32I-FPELIM-NEXT: sw a0, 24(sp) +; RV32I-FPELIM-NEXT: addi a7, sp, 24 ; RV32I-FPELIM-NEXT: addi a0, zero, 1 ; RV32I-FPELIM-NEXT: addi a1, zero, 2 ; RV32I-FPELIM-NEXT: addi a2, zero, 3 @@ -378,16 +378,16 @@ ; RV32I-FPELIM-NEXT: addi a5, zero, 6 ; RV32I-FPELIM-NEXT: addi a6, zero, 7 ; RV32I-FPELIM-NEXT: call callee_large_scalars_exhausted_regs -; RV32I-FPELIM-NEXT: lw ra, 60(sp) -; RV32I-FPELIM-NEXT: addi sp, sp, 64 +; RV32I-FPELIM-NEXT: lw ra, 44(sp) +; RV32I-FPELIM-NEXT: addi sp, sp, 48 ; RV32I-FPELIM-NEXT: ret ; ; RV32I-WITHFP-LABEL: caller_large_scalars_exhausted_regs: ; RV32I-WITHFP: # %bb.0: -; RV32I-WITHFP-NEXT: addi sp, sp, -64 -; RV32I-WITHFP-NEXT: sw ra, 60(sp) -; RV32I-WITHFP-NEXT: sw s0, 56(sp) -; RV32I-WITHFP-NEXT: addi s0, sp, 64 +; RV32I-WITHFP-NEXT: addi sp, sp, -48 +; RV32I-WITHFP-NEXT: sw ra, 44(sp) +; RV32I-WITHFP-NEXT: sw s0, 40(sp) +; RV32I-WITHFP-NEXT: addi s0, sp, 48 ; RV32I-WITHFP-NEXT: addi a0, s0, -48 ; RV32I-WITHFP-NEXT: sw a0, 4(sp) ; RV32I-WITHFP-NEXT: addi a0, zero, 9 @@ -411,9 +411,9 @@ ; RV32I-WITHFP-NEXT: addi a5, zero, 6 ; RV32I-WITHFP-NEXT: addi a6, zero, 7 ; RV32I-WITHFP-NEXT: call callee_large_scalars_exhausted_regs -; RV32I-WITHFP-NEXT: lw s0, 56(sp) -; RV32I-WITHFP-NEXT: lw ra, 60(sp) -; RV32I-WITHFP-NEXT: addi sp, sp, 64 +; RV32I-WITHFP-NEXT: lw s0, 40(sp) +; RV32I-WITHFP-NEXT: lw ra, 44(sp) +; RV32I-WITHFP-NEXT: addi sp, sp, 48 ; RV32I-WITHFP-NEXT: ret %1 = call i32 @callee_large_scalars_exhausted_regs( i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i128 8, i32 9, @@ -667,8 +667,8 @@ ; should only be 4-byte aligned ; RV32I-FPELIM-LABEL: caller_aligned_stack: ; RV32I-FPELIM: # %bb.0: -; RV32I-FPELIM-NEXT: addi sp, sp, -64 -; RV32I-FPELIM-NEXT: sw ra, 60(sp) +; RV32I-FPELIM-NEXT: addi sp, sp, -32 +; RV32I-FPELIM-NEXT: sw ra, 28(sp) ; RV32I-FPELIM-NEXT: addi a0, zero, 19 ; RV32I-FPELIM-NEXT: sw a0, 24(sp) ; RV32I-FPELIM-NEXT: addi a0, zero, 18 @@ -682,19 +682,19 @@ ; RV32I-FPELIM-NEXT: sw a0, 0(sp) ; RV32I-FPELIM-NEXT: lui a0, 262153 ; RV32I-FPELIM-NEXT: addi a0, a0, 491 -; RV32I-FPELIM-NEXT: sw a0, 44(sp) +; RV32I-FPELIM-NEXT: sw a0, 12(sp) ; RV32I-FPELIM-NEXT: lui a0, 545260 ; RV32I-FPELIM-NEXT: addi a0, a0, -1967 -; RV32I-FPELIM-NEXT: sw a0, 40(sp) +; RV32I-FPELIM-NEXT: sw a0, 8(sp) ; RV32I-FPELIM-NEXT: lui a0, 964690 ; RV32I-FPELIM-NEXT: addi a0, a0, -328 -; RV32I-FPELIM-NEXT: sw a0, 36(sp) +; RV32I-FPELIM-NEXT: sw a0, 4(sp) ; RV32I-FPELIM-NEXT: lui a0, 335544 ; RV32I-FPELIM-NEXT: addi a0, a0, 1311 -; RV32I-FPELIM-NEXT: sw a0, 32(sp) +; RV32I-FPELIM-NEXT: sw a0, 0(sp) ; RV32I-FPELIM-NEXT: lui a0, 688509 ; RV32I-FPELIM-NEXT: addi a5, a0, -2048 -; RV32I-FPELIM-NEXT: addi a2, sp, 32 +; RV32I-FPELIM-NEXT: mv a2, sp ; RV32I-FPELIM-NEXT: addi a0, zero, 1 ; RV32I-FPELIM-NEXT: addi a1, zero, 11 ; RV32I-FPELIM-NEXT: addi a3, zero, 12 @@ -702,16 +702,16 @@ ; RV32I-FPELIM-NEXT: addi a6, zero, 4 ; RV32I-FPELIM-NEXT: addi a7, zero, 14 ; RV32I-FPELIM-NEXT: call callee_aligned_stack -; RV32I-FPELIM-NEXT: lw ra, 60(sp) -; RV32I-FPELIM-NEXT: addi sp, sp, 64 +; RV32I-FPELIM-NEXT: lw ra, 28(sp) +; RV32I-FPELIM-NEXT: addi sp, sp, 32 ; RV32I-FPELIM-NEXT: ret ; ; RV32I-WITHFP-LABEL: caller_aligned_stack: ; RV32I-WITHFP: # %bb.0: -; RV32I-WITHFP-NEXT: addi sp, sp, -64 -; RV32I-WITHFP-NEXT: sw ra, 60(sp) -; RV32I-WITHFP-NEXT: sw s0, 56(sp) -; RV32I-WITHFP-NEXT: addi s0, sp, 64 +; RV32I-WITHFP-NEXT: addi sp, sp, -32 +; RV32I-WITHFP-NEXT: sw ra, 28(sp) +; RV32I-WITHFP-NEXT: sw s0, 24(sp) +; RV32I-WITHFP-NEXT: addi s0, sp, 32 ; RV32I-WITHFP-NEXT: addi a0, zero, 19 ; RV32I-WITHFP-NEXT: sw a0, 24(sp) ; RV32I-WITHFP-NEXT: addi a0, zero, 18 @@ -745,9 +745,9 @@ ; RV32I-WITHFP-NEXT: addi a6, zero, 4 ; RV32I-WITHFP-NEXT: addi a7, zero, 14 ; RV32I-WITHFP-NEXT: call callee_aligned_stack -; RV32I-WITHFP-NEXT: lw s0, 56(sp) -; RV32I-WITHFP-NEXT: lw ra, 60(sp) -; RV32I-WITHFP-NEXT: addi sp, sp, 64 +; RV32I-WITHFP-NEXT: lw s0, 24(sp) +; RV32I-WITHFP-NEXT: lw ra, 28(sp) +; RV32I-WITHFP-NEXT: addi sp, sp, 32 ; RV32I-WITHFP-NEXT: ret %1 = call i32 @callee_aligned_stack(i32 1, i32 11, fp128 0xLEB851EB851EB851F400091EB851EB851, i32 12, i32 13, diff --git a/llvm/test/CodeGen/RISCV/calling-conv-lp64-lp64f-lp64d-common.ll b/llvm/test/CodeGen/RISCV/calling-conv-lp64-lp64f-lp64d-common.ll --- a/llvm/test/CodeGen/RISCV/calling-conv-lp64-lp64f-lp64d-common.ll +++ b/llvm/test/CodeGen/RISCV/calling-conv-lp64-lp64f-lp64d-common.ll @@ -81,8 +81,8 @@ define i32 @caller_many_scalars() nounwind { ; RV64I-LABEL: caller_many_scalars: ; RV64I: # %bb.0: -; RV64I-NEXT: addi sp, sp, -32 -; RV64I-NEXT: sd ra, 24(sp) +; RV64I-NEXT: addi sp, sp, -16 +; RV64I-NEXT: sd ra, 8(sp) ; RV64I-NEXT: addi a0, zero, 8 ; RV64I-NEXT: sd a0, 8(sp) ; RV64I-NEXT: sd zero, 0(sp) @@ -95,8 +95,8 @@ ; RV64I-NEXT: addi a6, zero, 6 ; RV64I-NEXT: addi a7, zero, 7 ; RV64I-NEXT: call callee_many_scalars -; RV64I-NEXT: ld ra, 24(sp) -; RV64I-NEXT: addi sp, sp, 32 +; RV64I-NEXT: ld ra, 8(sp) +; RV64I-NEXT: addi sp, sp, 16 ; RV64I-NEXT: ret %1 = call i32 @callee_many_scalars(i8 1, i16 2, i32 3, i128 4, i32 5, i32 6, i128 7, i32 8) ret i32 %1 @@ -187,23 +187,23 @@ define i64 @caller_large_scalars_exhausted_regs() nounwind { ; RV64I-LABEL: caller_large_scalars_exhausted_regs: ; RV64I: # %bb.0: -; RV64I-NEXT: addi sp, sp, -96 -; RV64I-NEXT: sd ra, 88(sp) -; RV64I-NEXT: addi a0, sp, 16 +; RV64I-NEXT: addi sp, sp, -80 +; RV64I-NEXT: sd ra, 72(sp) +; RV64I-NEXT: mv a0, sp ; RV64I-NEXT: sd a0, 8(sp) ; RV64I-NEXT: addi a0, zero, 9 ; RV64I-NEXT: sd a0, 0(sp) ; RV64I-NEXT: addi a0, zero, 10 -; RV64I-NEXT: sd a0, 16(sp) -; RV64I-NEXT: sd zero, 40(sp) -; RV64I-NEXT: sd zero, 32(sp) +; RV64I-NEXT: sd a0, 0(sp) ; RV64I-NEXT: sd zero, 24(sp) -; RV64I-NEXT: sd zero, 72(sp) -; RV64I-NEXT: sd zero, 64(sp) +; RV64I-NEXT: sd zero, 16(sp) +; RV64I-NEXT: sd zero, 8(sp) ; RV64I-NEXT: sd zero, 56(sp) +; RV64I-NEXT: sd zero, 48(sp) +; RV64I-NEXT: sd zero, 40(sp) ; RV64I-NEXT: addi a0, zero, 8 -; RV64I-NEXT: sd a0, 48(sp) -; RV64I-NEXT: addi a7, sp, 48 +; RV64I-NEXT: sd a0, 32(sp) +; RV64I-NEXT: addi a7, sp, 32 ; RV64I-NEXT: addi a0, zero, 1 ; RV64I-NEXT: addi a1, zero, 2 ; RV64I-NEXT: addi a2, zero, 3 @@ -212,8 +212,8 @@ ; RV64I-NEXT: addi a5, zero, 6 ; RV64I-NEXT: addi a6, zero, 7 ; RV64I-NEXT: call callee_large_scalars_exhausted_regs -; RV64I-NEXT: ld ra, 88(sp) -; RV64I-NEXT: addi sp, sp, 96 +; RV64I-NEXT: ld ra, 72(sp) +; RV64I-NEXT: addi sp, sp, 80 ; RV64I-NEXT: ret %1 = call i64 @callee_large_scalars_exhausted_regs( i64 1, i64 2, i64 3, i64 4, i64 5, i64 6, i64 7, i256 8, i64 9, @@ -358,8 +358,8 @@ ; should only be 8-byte aligned ; RV64I-LABEL: caller_aligned_stack: ; RV64I: # %bb.0: -; RV64I-NEXT: addi sp, sp, -64 -; RV64I-NEXT: sd ra, 56(sp) +; RV64I-NEXT: addi sp, sp, -16 +; RV64I-NEXT: sd ra, 8(sp) ; RV64I-NEXT: addi a0, zero, 12 ; RV64I-NEXT: sd a0, 48(sp) ; RV64I-NEXT: addi a0, zero, 11 @@ -380,8 +380,8 @@ ; RV64I-NEXT: mv a6, zero ; RV64I-NEXT: addi a7, zero, 7 ; RV64I-NEXT: call callee_aligned_stack -; RV64I-NEXT: ld ra, 56(sp) -; RV64I-NEXT: addi sp, sp, 64 +; RV64I-NEXT: ld ra, 8(sp) +; RV64I-NEXT: addi sp, sp, 16 ; RV64I-NEXT: ret %1 = call i64 @callee_aligned_stack(i64 1, i64 2, i64 3, i64 4, i64 5, i128 6, i64 7, i64 8, i128 9, i64 10, [2 x i64] [i64 11, i64 12]) diff --git a/llvm/test/CodeGen/RISCV/calling-conv-lp64.ll b/llvm/test/CodeGen/RISCV/calling-conv-lp64.ll --- a/llvm/test/CodeGen/RISCV/calling-conv-lp64.ll +++ b/llvm/test/CodeGen/RISCV/calling-conv-lp64.ll @@ -127,10 +127,10 @@ ; ; RV64I-WITHFP-LABEL: caller_float_on_stack: ; RV64I-WITHFP: # %bb.0: -; RV64I-WITHFP-NEXT: addi sp, sp, -32 -; RV64I-WITHFP-NEXT: sd ra, 24(sp) -; RV64I-WITHFP-NEXT: sd s0, 16(sp) -; RV64I-WITHFP-NEXT: addi s0, sp, 32 +; RV64I-WITHFP-NEXT: addi sp, sp, -16 +; RV64I-WITHFP-NEXT: sd ra, 8(sp) +; RV64I-WITHFP-NEXT: sd s0, 0(sp) +; RV64I-WITHFP-NEXT: addi s0, sp, 16 ; RV64I-WITHFP-NEXT: lui a0, 264704 ; RV64I-WITHFP-NEXT: sd a0, 0(sp) ; RV64I-WITHFP-NEXT: addi a0, zero, 1 @@ -142,9 +142,9 @@ ; RV64I-WITHFP-NEXT: addi a6, zero, 4 ; RV64I-WITHFP-NEXT: mv a7, zero ; RV64I-WITHFP-NEXT: call callee_float_on_stack -; RV64I-WITHFP-NEXT: ld s0, 16(sp) -; RV64I-WITHFP-NEXT: ld ra, 24(sp) -; RV64I-WITHFP-NEXT: addi sp, sp, 32 +; RV64I-WITHFP-NEXT: ld s0, 0(sp) +; RV64I-WITHFP-NEXT: ld ra, 8(sp) +; RV64I-WITHFP-NEXT: addi sp, sp, 16 ; RV64I-WITHFP-NEXT: ret %1 = call i64 @callee_float_on_stack(i128 1, i128 2, i128 3, i128 4, float 5.0) ret i64 %1 diff --git a/llvm/test/CodeGen/RISCV/double-calling-conv.ll b/llvm/test/CodeGen/RISCV/double-calling-conv.ll --- a/llvm/test/CodeGen/RISCV/double-calling-conv.ll +++ b/llvm/test/CodeGen/RISCV/double-calling-conv.ll @@ -115,8 +115,8 @@ define double @caller_double_stack() nounwind { ; RV32IFD-LABEL: caller_double_stack: ; RV32IFD: # %bb.0: -; RV32IFD-NEXT: addi sp, sp, -32 -; RV32IFD-NEXT: sw ra, 28(sp) +; RV32IFD-NEXT: addi sp, sp, -16 +; RV32IFD-NEXT: sw ra, 12(sp) ; RV32IFD-NEXT: lui a0, 262510 ; RV32IFD-NEXT: addi a0, a0, 327 ; RV32IFD-NEXT: sw a0, 4(sp) @@ -136,8 +136,8 @@ ; RV32IFD-NEXT: addi a6, zero, 4 ; RV32IFD-NEXT: mv a7, zero ; RV32IFD-NEXT: call callee_double_stack -; RV32IFD-NEXT: lw ra, 28(sp) -; RV32IFD-NEXT: addi sp, sp, 32 +; RV32IFD-NEXT: lw ra, 12(sp) +; RV32IFD-NEXT: addi sp, sp, 16 ; RV32IFD-NEXT: ret %1 = call double @callee_double_stack(i64 1, i64 2, i64 3, i64 4, double 5.72, double 6.72) ret double %1 diff --git a/llvm/test/CodeGen/RISCV/stack-realignment-unsupported.ll b/llvm/test/CodeGen/RISCV/stack-realignment-unsupported.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/RISCV/stack-realignment-unsupported.ll @@ -0,0 +1,13 @@ +; RUN: not llc -mtriple=riscv32 < %s 2>&1 | FileCheck %s +; RUN: not llc -mtriple=riscv64 < %s 2>&1 | FileCheck %s + +; CHECK: LLVM ERROR: RISC-V backend can't currently handle functions that need stack realignment and have variable sized objects + +declare void @callee(i8*, i32*) + +define void @caller(i32 %n) nounwind { + %1 = alloca i8, i32 %n + %2 = alloca i32, align 64 + call void @callee(i8* %1, i32 *%2) + ret void +} diff --git a/llvm/test/CodeGen/RISCV/stack-realignment.ll b/llvm/test/CodeGen/RISCV/stack-realignment.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/RISCV/stack-realignment.ll @@ -0,0 +1,589 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc -mtriple=riscv32 -verify-machineinstrs < %s \ +; RUN: | FileCheck %s -check-prefix=RV32I +; RUN: llc -mtriple=riscv64 -verify-machineinstrs < %s \ +; RUN: | FileCheck %s -check-prefix=RV64I + +declare void @callee(i8*) + +define void @caller32() nounwind { +; RV32I-LABEL: caller32: +; RV32I: # %bb.0: +; RV32I-NEXT: addi sp, sp, -64 +; RV32I-NEXT: sw ra, 60(sp) +; RV32I-NEXT: sw s0, 56(sp) +; RV32I-NEXT: addi s0, sp, 64 +; RV32I-NEXT: andi sp, sp, -32 +; RV32I-NEXT: addi a0, sp, 32 +; RV32I-NEXT: call callee +; RV32I-NEXT: addi sp, s0, -64 +; RV32I-NEXT: lw s0, 56(sp) +; RV32I-NEXT: lw ra, 60(sp) +; RV32I-NEXT: addi sp, sp, 64 +; RV32I-NEXT: ret +; +; RV64I-LABEL: caller32: +; RV64I: # %bb.0: +; RV64I-NEXT: addi sp, sp, -64 +; RV64I-NEXT: sd ra, 56(sp) +; RV64I-NEXT: sd s0, 48(sp) +; RV64I-NEXT: addi s0, sp, 64 +; RV64I-NEXT: andi sp, sp, -32 +; RV64I-NEXT: addi a0, sp, 32 +; RV64I-NEXT: call callee +; RV64I-NEXT: addi sp, s0, -64 +; RV64I-NEXT: ld s0, 48(sp) +; RV64I-NEXT: ld ra, 56(sp) +; RV64I-NEXT: addi sp, sp, 64 +; RV64I-NEXT: ret + %1 = alloca i8, align 32 + call void @callee(i8* %1) + ret void +} + +define void @caller_no_realign32() nounwind "no-realign-stack" { +; RV32I-LABEL: caller_no_realign32: +; RV32I: # %bb.0: +; RV32I-NEXT: addi sp, sp, -16 +; RV32I-NEXT: sw ra, 12(sp) +; RV32I-NEXT: mv a0, sp +; RV32I-NEXT: call callee +; RV32I-NEXT: lw ra, 12(sp) +; RV32I-NEXT: addi sp, sp, 16 +; RV32I-NEXT: ret +; +; RV64I-LABEL: caller_no_realign32: +; RV64I: # %bb.0: +; RV64I-NEXT: addi sp, sp, -16 +; RV64I-NEXT: sd ra, 8(sp) +; RV64I-NEXT: mv a0, sp +; RV64I-NEXT: call callee +; RV64I-NEXT: ld ra, 8(sp) +; RV64I-NEXT: addi sp, sp, 16 +; RV64I-NEXT: ret + %1 = alloca i8, align 32 + call void @callee(i8* %1) + ret void +} + +define void @caller64() nounwind { +; RV32I-LABEL: caller64: +; RV32I: # %bb.0: +; RV32I-NEXT: addi sp, sp, -128 +; RV32I-NEXT: sw ra, 124(sp) +; RV32I-NEXT: sw s0, 120(sp) +; RV32I-NEXT: addi s0, sp, 128 +; RV32I-NEXT: andi sp, sp, -64 +; RV32I-NEXT: addi a0, sp, 64 +; RV32I-NEXT: call callee +; RV32I-NEXT: addi sp, s0, -128 +; RV32I-NEXT: lw s0, 120(sp) +; RV32I-NEXT: lw ra, 124(sp) +; RV32I-NEXT: addi sp, sp, 128 +; RV32I-NEXT: ret +; +; RV64I-LABEL: caller64: +; RV64I: # %bb.0: +; RV64I-NEXT: addi sp, sp, -128 +; RV64I-NEXT: sd ra, 120(sp) +; RV64I-NEXT: sd s0, 112(sp) +; RV64I-NEXT: addi s0, sp, 128 +; RV64I-NEXT: andi sp, sp, -64 +; RV64I-NEXT: addi a0, sp, 64 +; RV64I-NEXT: call callee +; RV64I-NEXT: addi sp, s0, -128 +; RV64I-NEXT: ld s0, 112(sp) +; RV64I-NEXT: ld ra, 120(sp) +; RV64I-NEXT: addi sp, sp, 128 +; RV64I-NEXT: ret + %1 = alloca i8, align 64 + call void @callee(i8* %1) + ret void +} + +define void @caller_no_realign64() nounwind "no-realign-stack" { +; RV32I-LABEL: caller_no_realign64: +; RV32I: # %bb.0: +; RV32I-NEXT: addi sp, sp, -16 +; RV32I-NEXT: sw ra, 12(sp) +; RV32I-NEXT: mv a0, sp +; RV32I-NEXT: call callee +; RV32I-NEXT: lw ra, 12(sp) +; RV32I-NEXT: addi sp, sp, 16 +; RV32I-NEXT: ret +; +; RV64I-LABEL: caller_no_realign64: +; RV64I: # %bb.0: +; RV64I-NEXT: addi sp, sp, -16 +; RV64I-NEXT: sd ra, 8(sp) +; RV64I-NEXT: mv a0, sp +; RV64I-NEXT: call callee +; RV64I-NEXT: ld ra, 8(sp) +; RV64I-NEXT: addi sp, sp, 16 +; RV64I-NEXT: ret + %1 = alloca i8, align 64 + call void @callee(i8* %1) + ret void +} + +define void @caller128() nounwind { +; RV32I-LABEL: caller128: +; RV32I: # %bb.0: +; RV32I-NEXT: addi sp, sp, -256 +; RV32I-NEXT: sw ra, 252(sp) +; RV32I-NEXT: sw s0, 248(sp) +; RV32I-NEXT: addi s0, sp, 256 +; RV32I-NEXT: andi sp, sp, -128 +; RV32I-NEXT: addi a0, sp, 128 +; RV32I-NEXT: call callee +; RV32I-NEXT: addi sp, s0, -256 +; RV32I-NEXT: lw s0, 248(sp) +; RV32I-NEXT: lw ra, 252(sp) +; RV32I-NEXT: addi sp, sp, 256 +; RV32I-NEXT: ret +; +; RV64I-LABEL: caller128: +; RV64I: # %bb.0: +; RV64I-NEXT: addi sp, sp, -256 +; RV64I-NEXT: sd ra, 248(sp) +; RV64I-NEXT: sd s0, 240(sp) +; RV64I-NEXT: addi s0, sp, 256 +; RV64I-NEXT: andi sp, sp, -128 +; RV64I-NEXT: addi a0, sp, 128 +; RV64I-NEXT: call callee +; RV64I-NEXT: addi sp, s0, -256 +; RV64I-NEXT: ld s0, 240(sp) +; RV64I-NEXT: ld ra, 248(sp) +; RV64I-NEXT: addi sp, sp, 256 +; RV64I-NEXT: ret + %1 = alloca i8, align 128 + call void @callee(i8* %1) + ret void +} + +define void @caller_no_realign128() nounwind "no-realign-stack" { +; RV32I-LABEL: caller_no_realign128: +; RV32I: # %bb.0: +; RV32I-NEXT: addi sp, sp, -16 +; RV32I-NEXT: sw ra, 12(sp) +; RV32I-NEXT: mv a0, sp +; RV32I-NEXT: call callee +; RV32I-NEXT: lw ra, 12(sp) +; RV32I-NEXT: addi sp, sp, 16 +; RV32I-NEXT: ret +; +; RV64I-LABEL: caller_no_realign128: +; RV64I: # %bb.0: +; RV64I-NEXT: addi sp, sp, -16 +; RV64I-NEXT: sd ra, 8(sp) +; RV64I-NEXT: mv a0, sp +; RV64I-NEXT: call callee +; RV64I-NEXT: ld ra, 8(sp) +; RV64I-NEXT: addi sp, sp, 16 +; RV64I-NEXT: ret + %1 = alloca i8, align 128 + call void @callee(i8* %1) + ret void +} + +define void @caller256() nounwind { +; RV32I-LABEL: caller256: +; RV32I: # %bb.0: +; RV32I-NEXT: addi sp, sp, -512 +; RV32I-NEXT: sw ra, 508(sp) +; RV32I-NEXT: sw s0, 504(sp) +; RV32I-NEXT: addi s0, sp, 512 +; RV32I-NEXT: andi sp, sp, -256 +; RV32I-NEXT: addi a0, sp, 256 +; RV32I-NEXT: call callee +; RV32I-NEXT: addi sp, s0, -512 +; RV32I-NEXT: lw s0, 504(sp) +; RV32I-NEXT: lw ra, 508(sp) +; RV32I-NEXT: addi sp, sp, 512 +; RV32I-NEXT: ret +; +; RV64I-LABEL: caller256: +; RV64I: # %bb.0: +; RV64I-NEXT: addi sp, sp, -512 +; RV64I-NEXT: sd ra, 504(sp) +; RV64I-NEXT: sd s0, 496(sp) +; RV64I-NEXT: addi s0, sp, 512 +; RV64I-NEXT: andi sp, sp, -256 +; RV64I-NEXT: addi a0, sp, 256 +; RV64I-NEXT: call callee +; RV64I-NEXT: addi sp, s0, -512 +; RV64I-NEXT: ld s0, 496(sp) +; RV64I-NEXT: ld ra, 504(sp) +; RV64I-NEXT: addi sp, sp, 512 +; RV64I-NEXT: ret + %1 = alloca i8, align 256 + call void @callee(i8* %1) + ret void +} + +define void @caller_no_realign256() nounwind "no-realign-stack" { +; RV32I-LABEL: caller_no_realign256: +; RV32I: # %bb.0: +; RV32I-NEXT: addi sp, sp, -16 +; RV32I-NEXT: sw ra, 12(sp) +; RV32I-NEXT: mv a0, sp +; RV32I-NEXT: call callee +; RV32I-NEXT: lw ra, 12(sp) +; RV32I-NEXT: addi sp, sp, 16 +; RV32I-NEXT: ret +; +; RV64I-LABEL: caller_no_realign256: +; RV64I: # %bb.0: +; RV64I-NEXT: addi sp, sp, -16 +; RV64I-NEXT: sd ra, 8(sp) +; RV64I-NEXT: mv a0, sp +; RV64I-NEXT: call callee +; RV64I-NEXT: ld ra, 8(sp) +; RV64I-NEXT: addi sp, sp, 16 +; RV64I-NEXT: ret + %1 = alloca i8, align 256 + call void @callee(i8* %1) + ret void +} + +define void @caller512() nounwind { +; RV32I-LABEL: caller512: +; RV32I: # %bb.0: +; RV32I-NEXT: addi sp, sp, -1024 +; RV32I-NEXT: sw ra, 1020(sp) +; RV32I-NEXT: sw s0, 1016(sp) +; RV32I-NEXT: addi s0, sp, 1024 +; RV32I-NEXT: andi sp, sp, -512 +; RV32I-NEXT: addi a0, sp, 512 +; RV32I-NEXT: call callee +; RV32I-NEXT: addi sp, s0, -1024 +; RV32I-NEXT: lw s0, 1016(sp) +; RV32I-NEXT: lw ra, 1020(sp) +; RV32I-NEXT: addi sp, sp, 1024 +; RV32I-NEXT: ret +; +; RV64I-LABEL: caller512: +; RV64I: # %bb.0: +; RV64I-NEXT: addi sp, sp, -1024 +; RV64I-NEXT: sd ra, 1016(sp) +; RV64I-NEXT: sd s0, 1008(sp) +; RV64I-NEXT: addi s0, sp, 1024 +; RV64I-NEXT: andi sp, sp, -512 +; RV64I-NEXT: addi a0, sp, 512 +; RV64I-NEXT: call callee +; RV64I-NEXT: addi sp, s0, -1024 +; RV64I-NEXT: ld s0, 1008(sp) +; RV64I-NEXT: ld ra, 1016(sp) +; RV64I-NEXT: addi sp, sp, 1024 +; RV64I-NEXT: ret + %1 = alloca i8, align 512 + call void @callee(i8* %1) + ret void +} + +define void @caller_no_realign512() nounwind "no-realign-stack" { +; RV32I-LABEL: caller_no_realign512: +; RV32I: # %bb.0: +; RV32I-NEXT: addi sp, sp, -16 +; RV32I-NEXT: sw ra, 12(sp) +; RV32I-NEXT: mv a0, sp +; RV32I-NEXT: call callee +; RV32I-NEXT: lw ra, 12(sp) +; RV32I-NEXT: addi sp, sp, 16 +; RV32I-NEXT: ret +; +; RV64I-LABEL: caller_no_realign512: +; RV64I: # %bb.0: +; RV64I-NEXT: addi sp, sp, -16 +; RV64I-NEXT: sd ra, 8(sp) +; RV64I-NEXT: mv a0, sp +; RV64I-NEXT: call callee +; RV64I-NEXT: ld ra, 8(sp) +; RV64I-NEXT: addi sp, sp, 16 +; RV64I-NEXT: ret + %1 = alloca i8, align 512 + call void @callee(i8* %1) + ret void +} + +define void @caller1024() nounwind { +; RV32I-LABEL: caller1024: +; RV32I: # %bb.0: +; RV32I-NEXT: addi sp, sp, -2048 +; RV32I-NEXT: sw ra, 2044(sp) +; RV32I-NEXT: sw s0, 2040(sp) +; RV32I-NEXT: lui a0, 1 +; RV32I-NEXT: addi a0, a0, -2048 +; RV32I-NEXT: add s0, sp, a0 +; RV32I-NEXT: andi sp, sp, -1024 +; RV32I-NEXT: addi a0, sp, 1024 +; RV32I-NEXT: call callee +; RV32I-NEXT: addi sp, s0, -2048 +; RV32I-NEXT: lw s0, 2040(sp) +; RV32I-NEXT: lw ra, 2044(sp) +; RV32I-NEXT: lui a0, 1 +; RV32I-NEXT: addi a0, a0, -2048 +; RV32I-NEXT: add sp, sp, a0 +; RV32I-NEXT: ret +; +; RV64I-LABEL: caller1024: +; RV64I: # %bb.0: +; RV64I-NEXT: addi sp, sp, -2048 +; RV64I-NEXT: sd ra, 2040(sp) +; RV64I-NEXT: sd s0, 2032(sp) +; RV64I-NEXT: lui a0, 1 +; RV64I-NEXT: addi a0, a0, -2048 +; RV64I-NEXT: add s0, sp, a0 +; RV64I-NEXT: andi sp, sp, -1024 +; RV64I-NEXT: addi a0, sp, 1024 +; RV64I-NEXT: call callee +; RV64I-NEXT: addi sp, s0, -2048 +; RV64I-NEXT: ld s0, 2032(sp) +; RV64I-NEXT: ld ra, 2040(sp) +; RV64I-NEXT: lui a0, 1 +; RV64I-NEXT: addi a0, a0, -2048 +; RV64I-NEXT: add sp, sp, a0 +; RV64I-NEXT: ret + %1 = alloca i8, align 1024 + call void @callee(i8* %1) + ret void +} + +define void @caller_no_realign1024() nounwind "no-realign-stack" { +; RV32I-LABEL: caller_no_realign1024: +; RV32I: # %bb.0: +; RV32I-NEXT: addi sp, sp, -16 +; RV32I-NEXT: sw ra, 12(sp) +; RV32I-NEXT: mv a0, sp +; RV32I-NEXT: call callee +; RV32I-NEXT: lw ra, 12(sp) +; RV32I-NEXT: addi sp, sp, 16 +; RV32I-NEXT: ret +; +; RV64I-LABEL: caller_no_realign1024: +; RV64I: # %bb.0: +; RV64I-NEXT: addi sp, sp, -16 +; RV64I-NEXT: sd ra, 8(sp) +; RV64I-NEXT: mv a0, sp +; RV64I-NEXT: call callee +; RV64I-NEXT: ld ra, 8(sp) +; RV64I-NEXT: addi sp, sp, 16 +; RV64I-NEXT: ret + %1 = alloca i8, align 1024 + call void @callee(i8* %1) + ret void +} + +define void @caller2048() nounwind { +; RV32I-LABEL: caller2048: +; RV32I: # %bb.0: +; RV32I-NEXT: lui a0, 1 +; RV32I-NEXT: mv a0, a0 +; RV32I-NEXT: sub sp, sp, a0 +; RV32I-NEXT: lui a0, 1 +; RV32I-NEXT: addi a0, a0, -4 +; RV32I-NEXT: add a0, sp, a0 +; RV32I-NEXT: sw ra, 0(a0) +; RV32I-NEXT: lui a0, 1 +; RV32I-NEXT: addi a0, a0, -8 +; RV32I-NEXT: add a0, sp, a0 +; RV32I-NEXT: sw s0, 0(a0) +; RV32I-NEXT: lui a0, 1 +; RV32I-NEXT: mv a0, a0 +; RV32I-NEXT: add s0, sp, a0 +; RV32I-NEXT: andi sp, sp, -2048 +; RV32I-NEXT: lui a0, 1 +; RV32I-NEXT: addi a0, a0, -2048 +; RV32I-NEXT: add a0, sp, a0 +; RV32I-NEXT: mv a0, a0 +; RV32I-NEXT: call callee +; RV32I-NEXT: lui a0, 1 +; RV32I-NEXT: mv a0, a0 +; RV32I-NEXT: sub sp, s0, a0 +; RV32I-NEXT: lui a0, 1 +; RV32I-NEXT: addi a0, a0, -8 +; RV32I-NEXT: add a0, sp, a0 +; RV32I-NEXT: lw s0, 0(a0) +; RV32I-NEXT: lui a0, 1 +; RV32I-NEXT: addi a0, a0, -4 +; RV32I-NEXT: add a0, sp, a0 +; RV32I-NEXT: lw ra, 0(a0) +; RV32I-NEXT: lui a0, 1 +; RV32I-NEXT: mv a0, a0 +; RV32I-NEXT: add sp, sp, a0 +; RV32I-NEXT: ret +; +; RV64I-LABEL: caller2048: +; RV64I: # %bb.0: +; RV64I-NEXT: lui a0, 1 +; RV64I-NEXT: mv a0, a0 +; RV64I-NEXT: sub sp, sp, a0 +; RV64I-NEXT: lui a0, 1 +; RV64I-NEXT: addi a0, a0, -8 +; RV64I-NEXT: add a0, sp, a0 +; RV64I-NEXT: sd ra, 0(a0) +; RV64I-NEXT: lui a0, 1 +; RV64I-NEXT: addi a0, a0, -16 +; RV64I-NEXT: add a0, sp, a0 +; RV64I-NEXT: sd s0, 0(a0) +; RV64I-NEXT: lui a0, 1 +; RV64I-NEXT: mv a0, a0 +; RV64I-NEXT: add s0, sp, a0 +; RV64I-NEXT: andi sp, sp, -2048 +; RV64I-NEXT: lui a0, 1 +; RV64I-NEXT: addi a0, a0, -2048 +; RV64I-NEXT: add a0, sp, a0 +; RV64I-NEXT: mv a0, a0 +; RV64I-NEXT: call callee +; RV64I-NEXT: lui a0, 1 +; RV64I-NEXT: mv a0, a0 +; RV64I-NEXT: sub sp, s0, a0 +; RV64I-NEXT: lui a0, 1 +; RV64I-NEXT: addi a0, a0, -16 +; RV64I-NEXT: add a0, sp, a0 +; RV64I-NEXT: ld s0, 0(a0) +; RV64I-NEXT: lui a0, 1 +; RV64I-NEXT: addi a0, a0, -8 +; RV64I-NEXT: add a0, sp, a0 +; RV64I-NEXT: ld ra, 0(a0) +; RV64I-NEXT: lui a0, 1 +; RV64I-NEXT: mv a0, a0 +; RV64I-NEXT: add sp, sp, a0 +; RV64I-NEXT: ret + %1 = alloca i8, align 2048 + call void @callee(i8* %1) + ret void +} + +define void @caller_no_realign2048() nounwind "no-realign-stack" { +; RV32I-LABEL: caller_no_realign2048: +; RV32I: # %bb.0: +; RV32I-NEXT: addi sp, sp, -16 +; RV32I-NEXT: sw ra, 12(sp) +; RV32I-NEXT: mv a0, sp +; RV32I-NEXT: call callee +; RV32I-NEXT: lw ra, 12(sp) +; RV32I-NEXT: addi sp, sp, 16 +; RV32I-NEXT: ret +; +; RV64I-LABEL: caller_no_realign2048: +; RV64I: # %bb.0: +; RV64I-NEXT: addi sp, sp, -16 +; RV64I-NEXT: sd ra, 8(sp) +; RV64I-NEXT: mv a0, sp +; RV64I-NEXT: call callee +; RV64I-NEXT: ld ra, 8(sp) +; RV64I-NEXT: addi sp, sp, 16 +; RV64I-NEXT: ret + %1 = alloca i8, align 2048 + call void @callee(i8* %1) + ret void +} + +define void @caller4096() nounwind { +; RV32I-LABEL: caller4096: +; RV32I: # %bb.0: +; RV32I-NEXT: lui a0, 2 +; RV32I-NEXT: mv a0, a0 +; RV32I-NEXT: sub sp, sp, a0 +; RV32I-NEXT: lui a0, 2 +; RV32I-NEXT: addi a0, a0, -4 +; RV32I-NEXT: add a0, sp, a0 +; RV32I-NEXT: sw ra, 0(a0) +; RV32I-NEXT: lui a0, 2 +; RV32I-NEXT: addi a0, a0, -8 +; RV32I-NEXT: add a0, sp, a0 +; RV32I-NEXT: sw s0, 0(a0) +; RV32I-NEXT: lui a0, 2 +; RV32I-NEXT: mv a0, a0 +; RV32I-NEXT: add s0, sp, a0 +; RV32I-NEXT: srli a0, sp, 12 +; RV32I-NEXT: slli sp, a0, 12 +; RV32I-NEXT: lui a0, 1 +; RV32I-NEXT: mv a0, a0 +; RV32I-NEXT: add a0, sp, a0 +; RV32I-NEXT: mv a0, a0 +; RV32I-NEXT: call callee +; RV32I-NEXT: lui a0, 2 +; RV32I-NEXT: mv a0, a0 +; RV32I-NEXT: sub sp, s0, a0 +; RV32I-NEXT: lui a0, 2 +; RV32I-NEXT: addi a0, a0, -8 +; RV32I-NEXT: add a0, sp, a0 +; RV32I-NEXT: lw s0, 0(a0) +; RV32I-NEXT: lui a0, 2 +; RV32I-NEXT: addi a0, a0, -4 +; RV32I-NEXT: add a0, sp, a0 +; RV32I-NEXT: lw ra, 0(a0) +; RV32I-NEXT: lui a0, 2 +; RV32I-NEXT: mv a0, a0 +; RV32I-NEXT: add sp, sp, a0 +; RV32I-NEXT: ret +; +; RV64I-LABEL: caller4096: +; RV64I: # %bb.0: +; RV64I-NEXT: lui a0, 2 +; RV64I-NEXT: mv a0, a0 +; RV64I-NEXT: sub sp, sp, a0 +; RV64I-NEXT: lui a0, 2 +; RV64I-NEXT: addi a0, a0, -8 +; RV64I-NEXT: add a0, sp, a0 +; RV64I-NEXT: sd ra, 0(a0) +; RV64I-NEXT: lui a0, 2 +; RV64I-NEXT: addi a0, a0, -16 +; RV64I-NEXT: add a0, sp, a0 +; RV64I-NEXT: sd s0, 0(a0) +; RV64I-NEXT: lui a0, 2 +; RV64I-NEXT: mv a0, a0 +; RV64I-NEXT: add s0, sp, a0 +; RV64I-NEXT: srli a0, sp, 12 +; RV64I-NEXT: slli sp, a0, 12 +; RV64I-NEXT: lui a0, 1 +; RV64I-NEXT: mv a0, a0 +; RV64I-NEXT: add a0, sp, a0 +; RV64I-NEXT: mv a0, a0 +; RV64I-NEXT: call callee +; RV64I-NEXT: lui a0, 2 +; RV64I-NEXT: mv a0, a0 +; RV64I-NEXT: sub sp, s0, a0 +; RV64I-NEXT: lui a0, 2 +; RV64I-NEXT: addi a0, a0, -16 +; RV64I-NEXT: add a0, sp, a0 +; RV64I-NEXT: ld s0, 0(a0) +; RV64I-NEXT: lui a0, 2 +; RV64I-NEXT: addi a0, a0, -8 +; RV64I-NEXT: add a0, sp, a0 +; RV64I-NEXT: ld ra, 0(a0) +; RV64I-NEXT: lui a0, 2 +; RV64I-NEXT: mv a0, a0 +; RV64I-NEXT: add sp, sp, a0 +; RV64I-NEXT: ret + %1 = alloca i8, align 4096 + call void @callee(i8* %1) + ret void +} + +define void @caller_no_realign4096() nounwind "no-realign-stack" { +; RV32I-LABEL: caller_no_realign4096: +; RV32I: # %bb.0: +; RV32I-NEXT: addi sp, sp, -16 +; RV32I-NEXT: sw ra, 12(sp) +; RV32I-NEXT: mv a0, sp +; RV32I-NEXT: call callee +; RV32I-NEXT: lw ra, 12(sp) +; RV32I-NEXT: addi sp, sp, 16 +; RV32I-NEXT: ret +; +; RV64I-LABEL: caller_no_realign4096: +; RV64I: # %bb.0: +; RV64I-NEXT: addi sp, sp, -16 +; RV64I-NEXT: sd ra, 8(sp) +; RV64I-NEXT: mv a0, sp +; RV64I-NEXT: call callee +; RV64I-NEXT: ld ra, 8(sp) +; RV64I-NEXT: addi sp, sp, 16 +; RV64I-NEXT: ret + %1 = alloca i8, align 4096 + call void @callee(i8* %1) + ret void +} diff --git a/llvm/test/CodeGen/RISCV/vararg.ll b/llvm/test/CodeGen/RISCV/vararg.ll --- a/llvm/test/CodeGen/RISCV/vararg.ll +++ b/llvm/test/CodeGen/RISCV/vararg.ll @@ -1399,8 +1399,8 @@ ; should only be 4-byte aligned ; ILP32-ILP32F-FPELIM-LABEL: va5_aligned_stack_caller: ; ILP32-ILP32F-FPELIM: # %bb.0: -; ILP32-ILP32F-FPELIM-NEXT: addi sp, sp, -64 -; ILP32-ILP32F-FPELIM-NEXT: sw ra, 60(sp) +; ILP32-ILP32F-FPELIM-NEXT: addi sp, sp, -32 +; ILP32-ILP32F-FPELIM-NEXT: sw ra, 28(sp) ; ILP32-ILP32F-FPELIM-NEXT: addi a0, zero, 17 ; ILP32-ILP32F-FPELIM-NEXT: sw a0, 24(sp) ; ILP32-ILP32F-FPELIM-NEXT: addi a0, zero, 16 @@ -1417,35 +1417,35 @@ ; ILP32-ILP32F-FPELIM-NEXT: sw a0, 0(sp) ; ILP32-ILP32F-FPELIM-NEXT: lui a0, 262153 ; ILP32-ILP32F-FPELIM-NEXT: addi a0, a0, 491 -; ILP32-ILP32F-FPELIM-NEXT: sw a0, 44(sp) +; ILP32-ILP32F-FPELIM-NEXT: sw a0, 12(sp) ; ILP32-ILP32F-FPELIM-NEXT: lui a0, 545260 ; ILP32-ILP32F-FPELIM-NEXT: addi a0, a0, -1967 -; ILP32-ILP32F-FPELIM-NEXT: sw a0, 40(sp) +; ILP32-ILP32F-FPELIM-NEXT: sw a0, 8(sp) ; ILP32-ILP32F-FPELIM-NEXT: lui a0, 964690 ; ILP32-ILP32F-FPELIM-NEXT: addi a0, a0, -328 -; ILP32-ILP32F-FPELIM-NEXT: sw a0, 36(sp) +; ILP32-ILP32F-FPELIM-NEXT: sw a0, 4(sp) ; ILP32-ILP32F-FPELIM-NEXT: lui a0, 335544 ; ILP32-ILP32F-FPELIM-NEXT: addi a0, a0, 1311 -; ILP32-ILP32F-FPELIM-NEXT: sw a0, 32(sp) +; ILP32-ILP32F-FPELIM-NEXT: sw a0, 0(sp) ; ILP32-ILP32F-FPELIM-NEXT: lui a0, 688509 ; ILP32-ILP32F-FPELIM-NEXT: addi a6, a0, -2048 -; ILP32-ILP32F-FPELIM-NEXT: addi a2, sp, 32 +; ILP32-ILP32F-FPELIM-NEXT: mv a2, sp ; ILP32-ILP32F-FPELIM-NEXT: addi a0, zero, 1 ; ILP32-ILP32F-FPELIM-NEXT: addi a1, zero, 11 ; ILP32-ILP32F-FPELIM-NEXT: addi a3, zero, 12 ; ILP32-ILP32F-FPELIM-NEXT: addi a4, zero, 13 ; ILP32-ILP32F-FPELIM-NEXT: addi a7, zero, 4 ; ILP32-ILP32F-FPELIM-NEXT: call va5_aligned_stack_callee -; ILP32-ILP32F-FPELIM-NEXT: lw ra, 60(sp) -; ILP32-ILP32F-FPELIM-NEXT: addi sp, sp, 64 +; ILP32-ILP32F-FPELIM-NEXT: lw ra, 28(sp) +; ILP32-ILP32F-FPELIM-NEXT: addi sp, sp, 32 ; ILP32-ILP32F-FPELIM-NEXT: ret ; ; ILP32-ILP32F-WITHFP-LABEL: va5_aligned_stack_caller: ; ILP32-ILP32F-WITHFP: # %bb.0: -; ILP32-ILP32F-WITHFP-NEXT: addi sp, sp, -64 -; ILP32-ILP32F-WITHFP-NEXT: sw ra, 60(sp) -; ILP32-ILP32F-WITHFP-NEXT: sw s0, 56(sp) -; ILP32-ILP32F-WITHFP-NEXT: addi s0, sp, 64 +; ILP32-ILP32F-WITHFP-NEXT: addi sp, sp, -32 +; ILP32-ILP32F-WITHFP-NEXT: sw ra, 28(sp) +; ILP32-ILP32F-WITHFP-NEXT: sw s0, 24(sp) +; ILP32-ILP32F-WITHFP-NEXT: addi s0, sp, 32 ; ILP32-ILP32F-WITHFP-NEXT: addi a0, zero, 17 ; ILP32-ILP32F-WITHFP-NEXT: sw a0, 24(sp) ; ILP32-ILP32F-WITHFP-NEXT: addi a0, zero, 16 @@ -1481,15 +1481,15 @@ ; ILP32-ILP32F-WITHFP-NEXT: addi a4, zero, 13 ; ILP32-ILP32F-WITHFP-NEXT: addi a7, zero, 4 ; ILP32-ILP32F-WITHFP-NEXT: call va5_aligned_stack_callee -; ILP32-ILP32F-WITHFP-NEXT: lw s0, 56(sp) -; ILP32-ILP32F-WITHFP-NEXT: lw ra, 60(sp) -; ILP32-ILP32F-WITHFP-NEXT: addi sp, sp, 64 +; ILP32-ILP32F-WITHFP-NEXT: lw s0, 24(sp) +; ILP32-ILP32F-WITHFP-NEXT: lw ra, 28(sp) +; ILP32-ILP32F-WITHFP-NEXT: addi sp, sp, 32 ; ILP32-ILP32F-WITHFP-NEXT: ret ; ; RV32D-ILP32-ILP32F-ILP32D-FPELIM-LABEL: va5_aligned_stack_caller: ; RV32D-ILP32-ILP32F-ILP32D-FPELIM: # %bb.0: -; RV32D-ILP32-ILP32F-ILP32D-FPELIM-NEXT: addi sp, sp, -64 -; RV32D-ILP32-ILP32F-ILP32D-FPELIM-NEXT: sw ra, 60(sp) +; RV32D-ILP32-ILP32F-ILP32D-FPELIM-NEXT: addi sp, sp, -32 +; RV32D-ILP32-ILP32F-ILP32D-FPELIM-NEXT: sw ra, 28(sp) ; RV32D-ILP32-ILP32F-ILP32D-FPELIM-NEXT: lui a0, 262236 ; RV32D-ILP32-ILP32F-ILP32D-FPELIM-NEXT: addi a0, a0, 655 ; RV32D-ILP32-ILP32F-ILP32D-FPELIM-NEXT: sw a0, 12(sp) @@ -1506,33 +1506,33 @@ ; RV32D-ILP32-ILP32F-ILP32D-FPELIM-NEXT: sw a0, 0(sp) ; RV32D-ILP32-ILP32F-ILP32D-FPELIM-NEXT: lui a0, 262153 ; RV32D-ILP32-ILP32F-ILP32D-FPELIM-NEXT: addi a0, a0, 491 -; RV32D-ILP32-ILP32F-ILP32D-FPELIM-NEXT: sw a0, 44(sp) +; RV32D-ILP32-ILP32F-ILP32D-FPELIM-NEXT: sw a0, 12(sp) ; RV32D-ILP32-ILP32F-ILP32D-FPELIM-NEXT: lui a0, 545260 ; RV32D-ILP32-ILP32F-ILP32D-FPELIM-NEXT: addi a0, a0, -1967 -; RV32D-ILP32-ILP32F-ILP32D-FPELIM-NEXT: sw a0, 40(sp) +; RV32D-ILP32-ILP32F-ILP32D-FPELIM-NEXT: sw a0, 8(sp) ; RV32D-ILP32-ILP32F-ILP32D-FPELIM-NEXT: lui a0, 964690 ; RV32D-ILP32-ILP32F-ILP32D-FPELIM-NEXT: addi a0, a0, -328 -; RV32D-ILP32-ILP32F-ILP32D-FPELIM-NEXT: sw a0, 36(sp) +; RV32D-ILP32-ILP32F-ILP32D-FPELIM-NEXT: sw a0, 4(sp) ; RV32D-ILP32-ILP32F-ILP32D-FPELIM-NEXT: lui a0, 335544 ; RV32D-ILP32-ILP32F-ILP32D-FPELIM-NEXT: addi a0, a0, 1311 -; RV32D-ILP32-ILP32F-ILP32D-FPELIM-NEXT: sw a0, 32(sp) +; RV32D-ILP32-ILP32F-ILP32D-FPELIM-NEXT: sw a0, 0(sp) ; RV32D-ILP32-ILP32F-ILP32D-FPELIM-NEXT: lui a0, 688509 ; RV32D-ILP32-ILP32F-ILP32D-FPELIM-NEXT: addi a6, a0, -2048 -; RV32D-ILP32-ILP32F-ILP32D-FPELIM-NEXT: addi a2, sp, 32 +; RV32D-ILP32-ILP32F-ILP32D-FPELIM-NEXT: mv a2, sp ; RV32D-ILP32-ILP32F-ILP32D-FPELIM-NEXT: addi a0, zero, 1 ; RV32D-ILP32-ILP32F-ILP32D-FPELIM-NEXT: addi a1, zero, 11 ; RV32D-ILP32-ILP32F-ILP32D-FPELIM-NEXT: addi a3, zero, 12 ; RV32D-ILP32-ILP32F-ILP32D-FPELIM-NEXT: addi a4, zero, 13 ; RV32D-ILP32-ILP32F-ILP32D-FPELIM-NEXT: addi a7, zero, 4 ; RV32D-ILP32-ILP32F-ILP32D-FPELIM-NEXT: call va5_aligned_stack_callee -; RV32D-ILP32-ILP32F-ILP32D-FPELIM-NEXT: lw ra, 60(sp) -; RV32D-ILP32-ILP32F-ILP32D-FPELIM-NEXT: addi sp, sp, 64 +; RV32D-ILP32-ILP32F-ILP32D-FPELIM-NEXT: lw ra, 28(sp) +; RV32D-ILP32-ILP32F-ILP32D-FPELIM-NEXT: addi sp, sp, 32 ; RV32D-ILP32-ILP32F-ILP32D-FPELIM-NEXT: ret ; ; LP64-LP64F-LP64D-FPELIM-LABEL: va5_aligned_stack_caller: ; LP64-LP64F-LP64D-FPELIM: # %bb.0: -; LP64-LP64F-LP64D-FPELIM-NEXT: addi sp, sp, -48 -; LP64-LP64F-LP64D-FPELIM-NEXT: sd ra, 40(sp) +; LP64-LP64F-LP64D-FPELIM-NEXT: addi sp, sp, -16 +; LP64-LP64F-LP64D-FPELIM-NEXT: sd ra, 8(sp) ; LP64-LP64F-LP64D-FPELIM-NEXT: addi a0, zero, 17 ; LP64-LP64F-LP64D-FPELIM-NEXT: sd a0, 24(sp) ; LP64-LP64F-LP64D-FPELIM-NEXT: addi a0, zero, 16 @@ -1574,16 +1574,16 @@ ; LP64-LP64F-LP64D-FPELIM-NEXT: addi a5, zero, 13 ; LP64-LP64F-LP64D-FPELIM-NEXT: addi a7, zero, 14 ; LP64-LP64F-LP64D-FPELIM-NEXT: call va5_aligned_stack_callee -; LP64-LP64F-LP64D-FPELIM-NEXT: ld ra, 40(sp) -; LP64-LP64F-LP64D-FPELIM-NEXT: addi sp, sp, 48 +; LP64-LP64F-LP64D-FPELIM-NEXT: ld ra, 8(sp) +; LP64-LP64F-LP64D-FPELIM-NEXT: addi sp, sp, 16 ; LP64-LP64F-LP64D-FPELIM-NEXT: ret ; ; LP64-LP64F-LP64D-WITHFP-LABEL: va5_aligned_stack_caller: ; LP64-LP64F-LP64D-WITHFP: # %bb.0: -; LP64-LP64F-LP64D-WITHFP-NEXT: addi sp, sp, -48 -; LP64-LP64F-LP64D-WITHFP-NEXT: sd ra, 40(sp) -; LP64-LP64F-LP64D-WITHFP-NEXT: sd s0, 32(sp) -; LP64-LP64F-LP64D-WITHFP-NEXT: addi s0, sp, 48 +; LP64-LP64F-LP64D-WITHFP-NEXT: addi sp, sp, -16 +; LP64-LP64F-LP64D-WITHFP-NEXT: sd ra, 8(sp) +; LP64-LP64F-LP64D-WITHFP-NEXT: sd s0, 0(sp) +; LP64-LP64F-LP64D-WITHFP-NEXT: addi s0, sp, 16 ; LP64-LP64F-LP64D-WITHFP-NEXT: addi a0, zero, 17 ; LP64-LP64F-LP64D-WITHFP-NEXT: sd a0, 24(sp) ; LP64-LP64F-LP64D-WITHFP-NEXT: addi a0, zero, 16 @@ -1625,9 +1625,9 @@ ; LP64-LP64F-LP64D-WITHFP-NEXT: addi a5, zero, 13 ; LP64-LP64F-LP64D-WITHFP-NEXT: addi a7, zero, 14 ; LP64-LP64F-LP64D-WITHFP-NEXT: call va5_aligned_stack_callee -; LP64-LP64F-LP64D-WITHFP-NEXT: ld s0, 32(sp) -; LP64-LP64F-LP64D-WITHFP-NEXT: ld ra, 40(sp) -; LP64-LP64F-LP64D-WITHFP-NEXT: addi sp, sp, 48 +; LP64-LP64F-LP64D-WITHFP-NEXT: ld s0, 0(sp) +; LP64-LP64F-LP64D-WITHFP-NEXT: ld ra, 8(sp) +; LP64-LP64F-LP64D-WITHFP-NEXT: addi sp, sp, 16 ; LP64-LP64F-LP64D-WITHFP-NEXT: ret %1 = call i32 (i32, ...) @va5_aligned_stack_callee(i32 1, i32 11, fp128 0xLEB851EB851EB851F400091EB851EB851, i32 12, i32 13, i64 20000000000,