diff --git a/llvm/lib/Target/RISCV/RISCVMachineFunctionInfo.h b/llvm/lib/Target/RISCV/RISCVMachineFunctionInfo.h --- a/llvm/lib/Target/RISCV/RISCVMachineFunctionInfo.h +++ b/llvm/lib/Target/RISCV/RISCVMachineFunctionInfo.h @@ -128,9 +128,12 @@ void setCalleeSavedStackSize(unsigned Size) { CalleeSavedStackSize = Size; } bool isPushable(const MachineFunction &MF) const { - return (!useSaveRestoreLibCalls(MF) && - MF.getSubtarget().hasStdExtZcmp() && - !MF.getTarget().Options.DisableFramePointerElim(MF)); + // We cannot use fixed locations for the callee saved spill slots if the + // function uses a varargs save area. + return !useSaveRestoreLibCalls(MF) && + MF.getSubtarget().hasStdExtZcmp() && + !MF.getTarget().Options.DisableFramePointerElim(MF) && + VarArgsSaveSize == 0; } int getRVPushRlist() const { return RVPushRlist; } diff --git a/llvm/test/CodeGen/RISCV/callee-saved-gprs.ll b/llvm/test/CodeGen/RISCV/callee-saved-gprs.ll --- a/llvm/test/CodeGen/RISCV/callee-saved-gprs.ll +++ b/llvm/test/CodeGen/RISCV/callee-saved-gprs.ll @@ -2127,3 +2127,179 @@ tail call void asm sideeffect "li s4, 0", "~{s4}"() ret void } + +define void @varargs(...) { +; RV32I-LABEL: varargs: +; RV32I: # %bb.0: +; RV32I-NEXT: addi sp, sp, -48 +; RV32I-NEXT: .cfi_def_cfa_offset 48 +; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill +; RV32I-NEXT: .cfi_offset ra, -36 +; RV32I-NEXT: sw a7, 44(sp) +; RV32I-NEXT: sw a6, 40(sp) +; RV32I-NEXT: sw a5, 36(sp) +; RV32I-NEXT: sw a4, 32(sp) +; RV32I-NEXT: sw a3, 28(sp) +; RV32I-NEXT: sw a2, 24(sp) +; RV32I-NEXT: sw a1, 20(sp) +; RV32I-NEXT: sw a0, 16(sp) +; RV32I-NEXT: call callee@plt +; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload +; RV32I-NEXT: addi sp, sp, 48 +; RV32I-NEXT: ret +; +; RV32I-WITH-FP-LABEL: varargs: +; RV32I-WITH-FP: # %bb.0: +; RV32I-WITH-FP-NEXT: addi sp, sp, -48 +; RV32I-WITH-FP-NEXT: .cfi_def_cfa_offset 48 +; RV32I-WITH-FP-NEXT: sw ra, 12(sp) # 4-byte Folded Spill +; RV32I-WITH-FP-NEXT: sw s0, 8(sp) # 4-byte Folded Spill +; RV32I-WITH-FP-NEXT: .cfi_offset ra, -36 +; RV32I-WITH-FP-NEXT: .cfi_offset s0, -40 +; RV32I-WITH-FP-NEXT: addi s0, sp, 16 +; RV32I-WITH-FP-NEXT: .cfi_def_cfa s0, 32 +; RV32I-WITH-FP-NEXT: sw a7, 28(s0) +; RV32I-WITH-FP-NEXT: sw a6, 24(s0) +; RV32I-WITH-FP-NEXT: sw a5, 20(s0) +; RV32I-WITH-FP-NEXT: sw a4, 16(s0) +; RV32I-WITH-FP-NEXT: sw a3, 12(s0) +; RV32I-WITH-FP-NEXT: sw a2, 8(s0) +; RV32I-WITH-FP-NEXT: sw a1, 4(s0) +; RV32I-WITH-FP-NEXT: sw a0, 0(s0) +; RV32I-WITH-FP-NEXT: call callee@plt +; RV32I-WITH-FP-NEXT: lw ra, 12(sp) # 4-byte Folded Reload +; RV32I-WITH-FP-NEXT: lw s0, 8(sp) # 4-byte Folded Reload +; RV32I-WITH-FP-NEXT: addi sp, sp, 48 +; RV32I-WITH-FP-NEXT: ret +; +; RV32IZCMP-LABEL: varargs: +; RV32IZCMP: # %bb.0: +; RV32IZCMP-NEXT: addi sp, sp, -48 +; RV32IZCMP-NEXT: .cfi_def_cfa_offset 48 +; RV32IZCMP-NEXT: sw ra, 12(sp) # 4-byte Folded Spill +; RV32IZCMP-NEXT: .cfi_offset ra, -36 +; RV32IZCMP-NEXT: sw a7, 44(sp) +; RV32IZCMP-NEXT: sw a6, 40(sp) +; RV32IZCMP-NEXT: sw a5, 36(sp) +; RV32IZCMP-NEXT: sw a4, 32(sp) +; RV32IZCMP-NEXT: sw a3, 28(sp) +; RV32IZCMP-NEXT: sw a2, 24(sp) +; RV32IZCMP-NEXT: sw a1, 20(sp) +; RV32IZCMP-NEXT: sw a0, 16(sp) +; RV32IZCMP-NEXT: call callee@plt +; RV32IZCMP-NEXT: lw ra, 12(sp) # 4-byte Folded Reload +; RV32IZCMP-NEXT: addi sp, sp, 48 +; RV32IZCMP-NEXT: ret +; +; RV32IZCMP-WITH-FP-LABEL: varargs: +; RV32IZCMP-WITH-FP: # %bb.0: +; RV32IZCMP-WITH-FP-NEXT: addi sp, sp, -48 +; RV32IZCMP-WITH-FP-NEXT: .cfi_def_cfa_offset 48 +; RV32IZCMP-WITH-FP-NEXT: sw ra, 12(sp) # 4-byte Folded Spill +; RV32IZCMP-WITH-FP-NEXT: sw s0, 8(sp) # 4-byte Folded Spill +; RV32IZCMP-WITH-FP-NEXT: .cfi_offset ra, -36 +; RV32IZCMP-WITH-FP-NEXT: .cfi_offset s0, -40 +; RV32IZCMP-WITH-FP-NEXT: addi s0, sp, 16 +; RV32IZCMP-WITH-FP-NEXT: .cfi_def_cfa s0, 32 +; RV32IZCMP-WITH-FP-NEXT: sw a7, 28(s0) +; RV32IZCMP-WITH-FP-NEXT: sw a6, 24(s0) +; RV32IZCMP-WITH-FP-NEXT: sw a5, 20(s0) +; RV32IZCMP-WITH-FP-NEXT: sw a4, 16(s0) +; RV32IZCMP-WITH-FP-NEXT: sw a3, 12(s0) +; RV32IZCMP-WITH-FP-NEXT: sw a2, 8(s0) +; RV32IZCMP-WITH-FP-NEXT: sw a1, 4(s0) +; RV32IZCMP-WITH-FP-NEXT: sw a0, 0(s0) +; RV32IZCMP-WITH-FP-NEXT: call callee@plt +; RV32IZCMP-WITH-FP-NEXT: lw ra, 12(sp) # 4-byte Folded Reload +; RV32IZCMP-WITH-FP-NEXT: lw s0, 8(sp) # 4-byte Folded Reload +; RV32IZCMP-WITH-FP-NEXT: addi sp, sp, 48 +; RV32IZCMP-WITH-FP-NEXT: ret +; +; RV64I-LABEL: varargs: +; RV64I: # %bb.0: +; RV64I-NEXT: addi sp, sp, -80 +; RV64I-NEXT: .cfi_def_cfa_offset 80 +; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill +; RV64I-NEXT: .cfi_offset ra, -72 +; RV64I-NEXT: sd a7, 72(sp) +; RV64I-NEXT: sd a6, 64(sp) +; RV64I-NEXT: sd a5, 56(sp) +; RV64I-NEXT: sd a4, 48(sp) +; RV64I-NEXT: sd a3, 40(sp) +; RV64I-NEXT: sd a2, 32(sp) +; RV64I-NEXT: sd a1, 24(sp) +; RV64I-NEXT: sd a0, 16(sp) +; RV64I-NEXT: call callee@plt +; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload +; RV64I-NEXT: addi sp, sp, 80 +; RV64I-NEXT: ret +; +; RV64I-WITH-FP-LABEL: varargs: +; RV64I-WITH-FP: # %bb.0: +; RV64I-WITH-FP-NEXT: addi sp, sp, -80 +; RV64I-WITH-FP-NEXT: .cfi_def_cfa_offset 80 +; RV64I-WITH-FP-NEXT: sd ra, 8(sp) # 8-byte Folded Spill +; RV64I-WITH-FP-NEXT: sd s0, 0(sp) # 8-byte Folded Spill +; RV64I-WITH-FP-NEXT: .cfi_offset ra, -72 +; RV64I-WITH-FP-NEXT: .cfi_offset s0, -80 +; RV64I-WITH-FP-NEXT: addi s0, sp, 16 +; RV64I-WITH-FP-NEXT: .cfi_def_cfa s0, 64 +; RV64I-WITH-FP-NEXT: sd a7, 56(s0) +; RV64I-WITH-FP-NEXT: sd a6, 48(s0) +; RV64I-WITH-FP-NEXT: sd a5, 40(s0) +; RV64I-WITH-FP-NEXT: sd a4, 32(s0) +; RV64I-WITH-FP-NEXT: sd a3, 24(s0) +; RV64I-WITH-FP-NEXT: sd a2, 16(s0) +; RV64I-WITH-FP-NEXT: sd a1, 8(s0) +; RV64I-WITH-FP-NEXT: sd a0, 0(s0) +; RV64I-WITH-FP-NEXT: call callee@plt +; RV64I-WITH-FP-NEXT: ld ra, 8(sp) # 8-byte Folded Reload +; RV64I-WITH-FP-NEXT: ld s0, 0(sp) # 8-byte Folded Reload +; RV64I-WITH-FP-NEXT: addi sp, sp, 80 +; RV64I-WITH-FP-NEXT: ret +; +; RV64IZCMP-LABEL: varargs: +; RV64IZCMP: # %bb.0: +; RV64IZCMP-NEXT: addi sp, sp, -80 +; RV64IZCMP-NEXT: .cfi_def_cfa_offset 80 +; RV64IZCMP-NEXT: sd ra, 8(sp) # 8-byte Folded Spill +; RV64IZCMP-NEXT: .cfi_offset ra, -72 +; RV64IZCMP-NEXT: sd a7, 72(sp) +; RV64IZCMP-NEXT: sd a6, 64(sp) +; RV64IZCMP-NEXT: sd a5, 56(sp) +; RV64IZCMP-NEXT: sd a4, 48(sp) +; RV64IZCMP-NEXT: sd a3, 40(sp) +; RV64IZCMP-NEXT: sd a2, 32(sp) +; RV64IZCMP-NEXT: sd a1, 24(sp) +; RV64IZCMP-NEXT: sd a0, 16(sp) +; RV64IZCMP-NEXT: call callee@plt +; RV64IZCMP-NEXT: ld ra, 8(sp) # 8-byte Folded Reload +; RV64IZCMP-NEXT: addi sp, sp, 80 +; RV64IZCMP-NEXT: ret +; +; RV64IZCMP-WITH-FP-LABEL: varargs: +; RV64IZCMP-WITH-FP: # %bb.0: +; RV64IZCMP-WITH-FP-NEXT: addi sp, sp, -80 +; RV64IZCMP-WITH-FP-NEXT: .cfi_def_cfa_offset 80 +; RV64IZCMP-WITH-FP-NEXT: sd ra, 8(sp) # 8-byte Folded Spill +; RV64IZCMP-WITH-FP-NEXT: sd s0, 0(sp) # 8-byte Folded Spill +; RV64IZCMP-WITH-FP-NEXT: .cfi_offset ra, -72 +; RV64IZCMP-WITH-FP-NEXT: .cfi_offset s0, -80 +; RV64IZCMP-WITH-FP-NEXT: addi s0, sp, 16 +; RV64IZCMP-WITH-FP-NEXT: .cfi_def_cfa s0, 64 +; RV64IZCMP-WITH-FP-NEXT: sd a7, 56(s0) +; RV64IZCMP-WITH-FP-NEXT: sd a6, 48(s0) +; RV64IZCMP-WITH-FP-NEXT: sd a5, 40(s0) +; RV64IZCMP-WITH-FP-NEXT: sd a4, 32(s0) +; RV64IZCMP-WITH-FP-NEXT: sd a3, 24(s0) +; RV64IZCMP-WITH-FP-NEXT: sd a2, 16(s0) +; RV64IZCMP-WITH-FP-NEXT: sd a1, 8(s0) +; RV64IZCMP-WITH-FP-NEXT: sd a0, 0(s0) +; RV64IZCMP-WITH-FP-NEXT: call callee@plt +; RV64IZCMP-WITH-FP-NEXT: ld ra, 8(sp) # 8-byte Folded Reload +; RV64IZCMP-WITH-FP-NEXT: ld s0, 0(sp) # 8-byte Folded Reload +; RV64IZCMP-WITH-FP-NEXT: addi sp, sp, 80 +; RV64IZCMP-WITH-FP-NEXT: ret + call void @callee() + ret void +}