[llvm] [RISCV] Disable zcmp push/pop for variadic functions. (PR #65302)

Yeting Kuo via llvm-commits llvm-commits at lists.llvm.org
Tue Sep 5 00:00:52 PDT 2023


https://github.com/yetingk created https://github.com/llvm/llvm-project/pull/65302:

Variadic function needs a save region for variable arguement and the region is possible to be overlaped with the region of zcmp push/pop used.

>From bc43cf2a035b76c110f3f90ebb0c24b41d6082dc Mon Sep 17 00:00:00 2001
From: Yeting Kuo <yeting.kuo at sifive.com>
Date: Thu, 31 Aug 2023 20:29:14 +0800
Subject: [PATCH] [RISCV] Disable zcmp push/pop for variadic functions.

Variadic function needs a save region for variable arguement and the region is
possible to be overlaped with the region of zcmp push/pop used.
---
 .../Target/RISCV/RISCVMachineFunctionInfo.h   |   9 +-
 llvm/test/CodeGen/RISCV/callee-saved-gprs.ll  | 176 ++++++++++++++++++
 2 files changed, 182 insertions(+), 3 deletions(-)

diff --git a/llvm/lib/Target/RISCV/RISCVMachineFunctionInfo.h b/llvm/lib/Target/RISCV/RISCVMachineFunctionInfo.h
index 9a534ee4e2a2f16..15098f207d5a30d 100644
--- a/llvm/lib/Target/RISCV/RISCVMachineFunctionInfo.h
+++ b/llvm/lib/Target/RISCV/RISCVMachineFunctionInfo.h
@@ -128,9 +128,12 @@ class RISCVMachineFunctionInfo : public MachineFunctionInfo {
   void setCalleeSavedStackSize(unsigned Size) { CalleeSavedStackSize = Size; }
 
   bool isPushable(const MachineFunction &MF) const {
-    return (!useSaveRestoreLibCalls(MF) &&
-            MF.getSubtarget<RISCVSubtarget>().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<RISCVSubtarget>().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
index 7013c27e0f33dc1..30374c13d60fecf 100644
--- a/llvm/test/CodeGen/RISCV/callee-saved-gprs.ll
+++ b/llvm/test/CodeGen/RISCV/callee-saved-gprs.ll
@@ -2127,3 +2127,179 @@ entry:
   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 at 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 at 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 at 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 at 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 at 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 at 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 at 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 at 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
+}



More information about the llvm-commits mailing list