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 @@ -65,6 +65,11 @@ bool canUseAsPrologue(const MachineBasicBlock &MBB) const override; bool canUseAsEpilogue(const MachineBasicBlock &MBB) const override; + /// targetHandlesStackFrameRounding - Returns true if the target is + /// responsible for rounding up the stack frame (probably at emitPrologue + /// time). + bool targetHandlesStackFrameRounding() const override { return true; } + protected: const RISCVSubtarget &STI; 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 @@ -240,6 +240,13 @@ // Get the number of bytes to allocate from the FrameInfo. uint64_t FrameSize = MFI.getStackSize(); + // targetHandlesStackFrameRounding() will return true and handle the alignment + // here. + // MaxCallFrameSize is defined through ADJCALLSTACKDOWN. + // Reserve frame space for out going arguments of caller. + if (MFI.adjustsStack() && hasReservedCallFrame(MF)) + FrameSize += MFI.getMaxCallFrameSize(); + // Get the alignment. Align StackAlign = getStackAlign(); if (RI->needsStackRealignment(MF)) { diff --git a/llvm/test/CodeGen/RISCV/stack-realignment.ll b/llvm/test/CodeGen/RISCV/stack-realignment.ll --- a/llvm/test/CodeGen/RISCV/stack-realignment.ll +++ b/llvm/test/CodeGen/RISCV/stack-realignment.ll @@ -249,32 +249,32 @@ define void @caller512() nounwind { ; RV32I-LABEL: caller512: ; RV32I: # %bb.0: -; RV32I-NEXT: addi sp, sp, -1536 -; RV32I-NEXT: sw ra, 1532(sp) # 4-byte Folded Spill -; RV32I-NEXT: sw s0, 1528(sp) # 4-byte Folded Spill -; RV32I-NEXT: addi s0, sp, 1536 +; RV32I-NEXT: addi sp, sp, -1024 +; RV32I-NEXT: sw ra, 1020(sp) # 4-byte Folded Spill +; RV32I-NEXT: sw s0, 1016(sp) # 4-byte Folded Spill +; RV32I-NEXT: addi s0, sp, 1024 ; RV32I-NEXT: andi sp, sp, -512 -; RV32I-NEXT: addi a0, sp, 1024 +; RV32I-NEXT: addi a0, sp, 512 ; RV32I-NEXT: call callee@plt -; RV32I-NEXT: addi sp, s0, -1536 -; RV32I-NEXT: lw s0, 1528(sp) # 4-byte Folded Reload -; RV32I-NEXT: lw ra, 1532(sp) # 4-byte Folded Reload -; RV32I-NEXT: addi sp, sp, 1536 +; RV32I-NEXT: addi sp, s0, -1024 +; RV32I-NEXT: lw s0, 1016(sp) # 4-byte Folded Reload +; RV32I-NEXT: lw ra, 1020(sp) # 4-byte Folded Reload +; RV32I-NEXT: addi sp, sp, 1024 ; RV32I-NEXT: ret ; ; RV64I-LABEL: caller512: ; RV64I: # %bb.0: -; RV64I-NEXT: addi sp, sp, -1536 -; RV64I-NEXT: sd ra, 1528(sp) # 8-byte Folded Spill -; RV64I-NEXT: sd s0, 1520(sp) # 8-byte Folded Spill -; RV64I-NEXT: addi s0, sp, 1536 +; RV64I-NEXT: addi sp, sp, -1024 +; RV64I-NEXT: sd ra, 1016(sp) # 8-byte Folded Spill +; RV64I-NEXT: sd s0, 1008(sp) # 8-byte Folded Spill +; RV64I-NEXT: addi s0, sp, 1024 ; RV64I-NEXT: andi sp, sp, -512 -; RV64I-NEXT: addi a0, sp, 1024 +; RV64I-NEXT: addi a0, sp, 512 ; RV64I-NEXT: call callee@plt -; RV64I-NEXT: addi sp, s0, -1536 -; RV64I-NEXT: ld s0, 1520(sp) # 8-byte Folded Reload -; RV64I-NEXT: ld ra, 1528(sp) # 8-byte Folded Reload -; RV64I-NEXT: addi sp, sp, 1536 +; RV64I-NEXT: addi sp, s0, -1024 +; RV64I-NEXT: ld s0, 1008(sp) # 8-byte Folded Reload +; RV64I-NEXT: ld ra, 1016(sp) # 8-byte Folded Reload +; RV64I-NEXT: addi sp, sp, 1024 ; RV64I-NEXT: ret %1 = alloca i8, align 512 call void @callee(i8* %1) @@ -313,17 +313,12 @@ ; RV32I-NEXT: sw ra, 2028(sp) # 4-byte Folded Spill ; RV32I-NEXT: sw s0, 2024(sp) # 4-byte Folded Spill ; RV32I-NEXT: addi s0, sp, 2032 -; RV32I-NEXT: addi sp, sp, -1040 +; RV32I-NEXT: addi sp, sp, -16 ; RV32I-NEXT: andi sp, sp, -1024 -; RV32I-NEXT: lui a0, 1 -; RV32I-NEXT: addi a0, a0, -2048 -; RV32I-NEXT: add a0, sp, a0 -; RV32I-NEXT: mv a0, a0 +; RV32I-NEXT: addi a0, sp, 1024 ; RV32I-NEXT: call callee@plt -; RV32I-NEXT: lui a0, 1 -; RV32I-NEXT: addi a0, a0, -1024 -; RV32I-NEXT: sub sp, s0, a0 -; RV32I-NEXT: addi sp, sp, 1040 +; RV32I-NEXT: addi sp, s0, -2048 +; RV32I-NEXT: addi sp, sp, 16 ; RV32I-NEXT: lw s0, 2024(sp) # 4-byte Folded Reload ; RV32I-NEXT: lw ra, 2028(sp) # 4-byte Folded Reload ; RV32I-NEXT: addi sp, sp, 2032 @@ -335,17 +330,12 @@ ; RV64I-NEXT: sd ra, 2024(sp) # 8-byte Folded Spill ; RV64I-NEXT: sd s0, 2016(sp) # 8-byte Folded Spill ; RV64I-NEXT: addi s0, sp, 2032 -; RV64I-NEXT: addi sp, sp, -1040 +; RV64I-NEXT: addi sp, sp, -16 ; RV64I-NEXT: andi sp, sp, -1024 -; RV64I-NEXT: lui a0, 1 -; RV64I-NEXT: addiw a0, a0, -2048 -; RV64I-NEXT: add a0, sp, a0 -; RV64I-NEXT: mv a0, a0 +; RV64I-NEXT: addi a0, sp, 1024 ; RV64I-NEXT: call callee@plt -; RV64I-NEXT: lui a0, 1 -; RV64I-NEXT: addiw a0, a0, -1024 -; RV64I-NEXT: sub sp, s0, a0 -; RV64I-NEXT: addi sp, sp, 1040 +; RV64I-NEXT: addi sp, s0, -2048 +; RV64I-NEXT: addi sp, sp, 16 ; RV64I-NEXT: ld s0, 2016(sp) # 8-byte Folded Reload ; RV64I-NEXT: ld ra, 2024(sp) # 8-byte Folded Reload ; RV64I-NEXT: addi sp, sp, 2032 @@ -388,18 +378,18 @@ ; RV32I-NEXT: sw s0, 2024(sp) # 4-byte Folded Spill ; RV32I-NEXT: addi s0, sp, 2032 ; RV32I-NEXT: lui a0, 1 -; RV32I-NEXT: addi a0, a0, 16 +; RV32I-NEXT: addi a0, a0, -2032 ; RV32I-NEXT: sub sp, 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@plt -; RV32I-NEXT: lui a0, 2 -; RV32I-NEXT: addi a0, a0, -2048 +; RV32I-NEXT: lui a0, 1 ; RV32I-NEXT: sub sp, s0, a0 ; RV32I-NEXT: lui a0, 1 -; RV32I-NEXT: addi a0, a0, 16 +; RV32I-NEXT: addi a0, a0, -2032 ; RV32I-NEXT: add sp, sp, a0 ; RV32I-NEXT: lw s0, 2024(sp) # 4-byte Folded Reload ; RV32I-NEXT: lw ra, 2028(sp) # 4-byte Folded Reload @@ -413,18 +403,18 @@ ; RV64I-NEXT: sd s0, 2016(sp) # 8-byte Folded Spill ; RV64I-NEXT: addi s0, sp, 2032 ; RV64I-NEXT: lui a0, 1 -; RV64I-NEXT: addiw a0, a0, 16 +; RV64I-NEXT: addiw a0, a0, -2032 ; RV64I-NEXT: sub sp, sp, a0 ; RV64I-NEXT: andi sp, sp, -2048 ; RV64I-NEXT: lui a0, 1 +; RV64I-NEXT: addiw a0, a0, -2048 ; RV64I-NEXT: add a0, sp, a0 ; RV64I-NEXT: mv a0, a0 ; RV64I-NEXT: call callee@plt -; RV64I-NEXT: lui a0, 2 -; RV64I-NEXT: addiw a0, a0, -2048 +; RV64I-NEXT: lui a0, 1 ; RV64I-NEXT: sub sp, s0, a0 ; RV64I-NEXT: lui a0, 1 -; RV64I-NEXT: addiw a0, a0, 16 +; RV64I-NEXT: addiw a0, a0, -2032 ; RV64I-NEXT: add sp, sp, a0 ; RV64I-NEXT: ld s0, 2016(sp) # 8-byte Folded Reload ; RV64I-NEXT: ld ra, 2024(sp) # 8-byte Folded Reload @@ -467,18 +457,18 @@ ; RV32I-NEXT: sw ra, 2028(sp) # 4-byte Folded Spill ; RV32I-NEXT: sw s0, 2024(sp) # 4-byte Folded Spill ; RV32I-NEXT: addi s0, sp, 2032 -; RV32I-NEXT: lui a0, 3 +; RV32I-NEXT: lui a0, 2 ; RV32I-NEXT: addi a0, a0, -2032 ; RV32I-NEXT: sub sp, sp, a0 ; RV32I-NEXT: srli a0, sp, 12 ; RV32I-NEXT: slli sp, a0, 12 -; RV32I-NEXT: lui a0, 2 +; RV32I-NEXT: lui a0, 1 ; RV32I-NEXT: add a0, sp, a0 ; RV32I-NEXT: mv a0, a0 ; RV32I-NEXT: call callee@plt -; RV32I-NEXT: lui a0, 3 +; RV32I-NEXT: lui a0, 2 ; RV32I-NEXT: sub sp, s0, a0 -; RV32I-NEXT: lui a0, 3 +; RV32I-NEXT: lui a0, 2 ; RV32I-NEXT: addi a0, a0, -2032 ; RV32I-NEXT: add sp, sp, a0 ; RV32I-NEXT: lw s0, 2024(sp) # 4-byte Folded Reload @@ -492,18 +482,18 @@ ; RV64I-NEXT: sd ra, 2024(sp) # 8-byte Folded Spill ; RV64I-NEXT: sd s0, 2016(sp) # 8-byte Folded Spill ; RV64I-NEXT: addi s0, sp, 2032 -; RV64I-NEXT: lui a0, 3 +; RV64I-NEXT: lui a0, 2 ; RV64I-NEXT: addiw a0, a0, -2032 ; RV64I-NEXT: sub sp, sp, a0 ; RV64I-NEXT: srli a0, sp, 12 ; RV64I-NEXT: slli sp, a0, 12 -; RV64I-NEXT: lui a0, 2 +; RV64I-NEXT: lui a0, 1 ; RV64I-NEXT: add a0, sp, a0 ; RV64I-NEXT: mv a0, a0 ; RV64I-NEXT: call callee@plt -; RV64I-NEXT: lui a0, 3 +; RV64I-NEXT: lui a0, 2 ; RV64I-NEXT: sub sp, s0, a0 -; RV64I-NEXT: lui a0, 3 +; RV64I-NEXT: lui a0, 2 ; RV64I-NEXT: addiw a0, a0, -2032 ; RV64I-NEXT: add sp, sp, a0 ; RV64I-NEXT: ld s0, 2016(sp) # 8-byte Folded Reload