[llvm] 6cf41ad - [SystemZ][z/OS] Add vararg support to z/OS (#68834)

via llvm-commits llvm-commits at lists.llvm.org
Thu Oct 12 03:43:00 PDT 2023


Author: Yusra Syeda
Date: 2023-10-12T12:42:55+02:00
New Revision: 6cf41ada44c812cbd58f5907f15df8a8ce1f3a74

URL: https://github.com/llvm/llvm-project/commit/6cf41ada44c812cbd58f5907f15df8a8ce1f3a74
DIFF: https://github.com/llvm/llvm-project/commit/6cf41ada44c812cbd58f5907f15df8a8ce1f3a74.diff

LOG: [SystemZ][z/OS] Add vararg support to z/OS (#68834)

This PR adds vararg support to z/OS and updates the call-zos-vararg.ll
lit test.

Co-authored-by: Yusra Syeda <yusra.syeda at ibm.com>

Added: 
    

Modified: 
    llvm/lib/Target/SystemZ/SystemZFrameLowering.cpp
    llvm/lib/Target/SystemZ/SystemZISelLowering.cpp
    llvm/test/CodeGen/SystemZ/call-zos-vararg.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/SystemZ/SystemZFrameLowering.cpp b/llvm/lib/Target/SystemZ/SystemZFrameLowering.cpp
index 75a37060a8d06af..bfd31709eb3e0bc 100644
--- a/llvm/lib/Target/SystemZ/SystemZFrameLowering.cpp
+++ b/llvm/lib/Target/SystemZ/SystemZFrameLowering.cpp
@@ -1275,6 +1275,30 @@ void SystemZXPLINKFrameLowering::emitPrologue(MachineFunction &MF,
     for (MachineBasicBlock &B : llvm::drop_begin(MF))
       B.addLiveIn(Regs.getFramePointerRegister());
   }
+
+  // Save GPRs used for varargs, if any.
+  const TargetInstrInfo *TII = Subtarget.getInstrInfo();
+  bool IsVarArg = MF.getFunction().isVarArg();
+
+  if (IsVarArg) {
+    // FixedRegs is the number of used registers, accounting for shadow
+    // registers.
+    unsigned FixedRegs = ZFI->getVarArgsFirstGPR() + ZFI->getVarArgsFirstFPR();
+    auto &GPRs = SystemZ::XPLINK64ArgGPRs;
+    for (unsigned I = FixedRegs; I < SystemZ::XPLINK64NumArgGPRs; I++) {
+      uint64_t StartOffset = MFFrame.getOffsetAdjustment() +
+                             MFFrame.getStackSize() + Regs.getCallFrameSize() +
+                             getOffsetOfLocalArea() + I * 8;
+      unsigned Reg = GPRs[I];
+      BuildMI(MBB, MBBI, DL, TII->get(SystemZ::STG))
+          .addReg(Reg)
+          .addReg(Regs.getStackPointerRegister())
+          .addImm(StartOffset)
+          .addReg(0);
+      if (!MBB.isLiveIn(Reg))
+        MBB.addLiveIn(Reg);
+    }
+  }
 }
 
 void SystemZXPLINKFrameLowering::emitEpilogue(MachineFunction &MF,

diff  --git a/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp b/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp
index 5c5cb964bd28db8..f88bd9b45aee601 100644
--- a/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp
+++ b/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp
@@ -1613,7 +1613,23 @@ SDValue SystemZTargetLowering::LowerFormalArguments(
       InVals.push_back(convertLocVTToValVT(DAG, DL, VA, Chain, ArgValue));
   }
 
-  // FIXME: Add support for lowering varargs for XPLINK64 in a later patch.
+  if (IsVarArg && Subtarget.isTargetXPLINK64()) {
+    // Save the number of non-varargs registers for later use by va_start, etc.
+    FuncInfo->setVarArgsFirstGPR(NumFixedGPRs);
+    FuncInfo->setVarArgsFirstFPR(NumFixedFPRs);
+
+    auto *Regs = static_cast<SystemZXPLINK64Registers *>(
+        Subtarget.getSpecialRegisters());
+
+    // Likewise the address (in the form of a frame index) of where the
+    // first stack vararg would be.  The 1-byte size here is arbitrary.
+    // FIXME: Pre-include call frame size in the offset, should not
+    // need to manually add it here.
+    int64_t VarArgOffset = CCInfo.getStackSize() + Regs->getCallFrameSize();
+    int FI = MFI.CreateFixedObject(1, VarArgOffset, true);
+    FuncInfo->setVarArgsFrameIndex(FI);
+  }
+
   if (IsVarArg && Subtarget.isTargetELF()) {
     // Save the number of non-varargs registers for later use by va_start, etc.
     FuncInfo->setVarArgsFirstGPR(NumFixedGPRs);

diff  --git a/llvm/test/CodeGen/SystemZ/call-zos-vararg.ll b/llvm/test/CodeGen/SystemZ/call-zos-vararg.ll
index ac157e5fa67f62c..bde59a6be782277 100644
--- a/llvm/test/CodeGen/SystemZ/call-zos-vararg.ll
+++ b/llvm/test/CodeGen/SystemZ/call-zos-vararg.ll
@@ -1,88 +1,149 @@
 ; Test passing variable argument lists in 64-bit calls on z/OS.
 ; RUN: llc < %s -mtriple=s390x-ibm-zos -mcpu=z10 | FileCheck %s
 ; RUN: llc < %s -mtriple=s390x-ibm-zos -mcpu=z14 | FileCheck %s -check-prefix=ARCH12
-; CHECK-LABEL: call_vararg_double0
-; CHECK:       llihf 3, 1074118262
-; CHECK-NEXT:  oilf  3, 3367254360
-; CHECK:       lghi  1, 1
-; CHECK:       lghi  2, 2
+; CHECK-LABEL: call_vararg_double0:
+; CHECK:         stmg 6, 7, 1872(4)
+; CHECK-NEXT:    aghi 4, -192
+; CHECK-NEXT:    lg 6, 8(5)
+; CHECK-NEXT:    lg 5, 0(5)
+; CHECK-NEXT:    llihf 3, 1074118262
+; CHECK-NEXT:    oilf 3, 3367254360
+; CHECK-NEXT:    lghi 1, 1
+; CHECK-NEXT:    lghi 2, 2
+; CHECK-NEXT:    basr 7, 6
+; CHECK-NEXT:    bcr 0, 0
+; CHECK-NEXT:    lg 7, 2072(4)
+; CHECK-NEXT:    aghi 4, 192
+; CHECK-NEXT:    b 2(7)
 define i64 @call_vararg_double0() {
 entry:
   %retval = call i64 (i64, i64, ...) @pass_vararg0(i64 1, i64 2, double 2.718000e+00)
   ret i64 %retval
 }
 
-; CHECK-LABEL:  call_vararg_double1
-; CHECK:        llihf 0, 1074118262
-; CHECK-NEXT:   oilf  0, 3367254360
-; CHECK:        llihf 3, 1074340036
-; CHECK-NEXT:   oilf  3, 2611340116
-; CHECK:        lghi  1, 1
-; CHECK:        lghi  2, 2
-; CHECK:        stg 0, 2200(4)
+; CHECK-LABEL: call_vararg_double1:
+; CHECK:         stmg 6, 7, 1872(4)
+; CHECK-NEXT:    aghi 4, -192
+; CHECK-NEXT:    llihf 0, 1074118262
+; CHECK-NEXT:    oilf 0, 3367254360
+; CHECK-NEXT:    lg 6, 8(5)
+; CHECK-NEXT:    lg 5, 0(5)
+; CHECK-NEXT:    llihf 3, 1074340036
+; CHECK-NEXT:    oilf 3, 2611340116
+; CHECK-NEXT:    lghi 1, 1
+; CHECK-NEXT:    lghi 2, 2
+; CHECK-NEXT:    stg 0, 2200(4)
+; CHECK-NEXT:    basr 7, 6
+; CHECK-NEXT:    bcr 0, 0
+; CHECK-NEXT:    lg 7, 2072(4)
+; CHECK-NEXT:    aghi 4, 192
+; CHECK-NEXT:    b 2(7)
 define i64 @call_vararg_double1() {
 entry:
   %retval = call i64 (i64, i64, ...) @pass_vararg0(i64 1, i64 2, double 3.141000e+00, double 2.718000e+00)
   ret i64 %retval
 }
 
-; CHECK-LABEL: call_vararg_double2
-; CHECK-NOT:   llihf 0
-; CHECK-NOT:   oilf 0
-; CHECK:       llihf 2, 1074118262
-; CHECK-NEXT:  oilf  2, 3367254360
-; CHECK:       lghi  1, 8200
+; CHECK-LABEL: call_vararg_double2:
+; CHECK:         stmg 6, 7, 1872(4)
+; CHECK-NEXT:    aghi 4, -192
+; CHECK-NEXT:    lg 6, 24(5)
+; CHECK-NEXT:    lg 5, 16(5)
+; CHECK-NEXT:    llihf 2, 1074118262
+; CHECK-NEXT:    oilf 2, 3367254360
+; CHECK-NEXT:    lghi 1, 8200
+; CHECK-NEXT:    basr 7, 6
+; CHECK-NEXT:    bcr 0, 0
+; CHECK-NEXT:    lg 7, 2072(4)
+; CHECK-NEXT:    aghi 4, 192
+; CHECK-NEXT:    b 2(7)
 define i64 @call_vararg_double2() {
 entry:
   %retval = call i64 (i64, ...) @pass_vararg2(i64 8200, double 2.718000e+00)
   ret i64 %retval
 }
 
-; CHECK-LABEL: call_vararg_double3
-; CHECK:       llihf   0, 1072703839
-; CHECK-NEXT:  oilf    0, 2861204133
-; CHECK:       llihf   1, 1074118262
-; CHECK-NEXT:  oilf    1, 3367254360
-; CHECK:       llihf   2, 1074340036
-; CHECK-NEXT:  oilf    2, 2611340116
-; CHECK:       llihf   3, 1073127358
-; CHECK-NEXT:  oilf    3, 1992864825
-; CHECK:       stg     0, 2200(4)
+; CHECK-LABEL: call_vararg_double3:
+; CHECK:         stmg 6, 7, 1872(4)
+; CHECK-NEXT:    aghi 4, -192
+; CHECK-NEXT:    llihf 0, 1072703839
+; CHECK-NEXT:    oilf 0, 2861204133
+; CHECK-NEXT:    lg 6, 40(5)
+; CHECK-NEXT:    lg 5, 32(5)
+; CHECK-NEXT:    llihf 1, 1074118262
+; CHECK-NEXT:    oilf 1, 3367254360
+; CHECK-NEXT:    llihf 2, 1074340036
+; CHECK-NEXT:    oilf 2, 2611340116
+; CHECK-NEXT:    llihf 3, 1073127358
+; CHECK-NEXT:    oilf 3, 1992864825
+; CHECK-NEXT:    stg 0, 2200(4)
+; CHECK-NEXT:    basr 7, 6
+; CHECK-NEXT:    bcr 0, 0
+; CHECK-NEXT:    lg 7, 2072(4)
+; CHECK-NEXT:    aghi 4, 192
+; CHECK-NEXT:    b 2(7)
 define i64 @call_vararg_double3() {
 entry:
   %retval = call i64 (...) @pass_vararg3(double 2.718000e+00, double 3.141000e+00, double 1.414000e+00, double 1.010101e+00)
   ret i64 %retval
 }
 
-; CHECK-LABEL: call_vararg_both0
-; CHECK:       lgr   2, 1
-; CHECK:       lgdr  1, 0
+; CHECK-LABEL: call_vararg_both0:
+; CHECK:         stmg 6, 7, 1872(4)
+; CHECK-NEXT:    aghi 4, -192
+; CHECK-NEXT:    lg 6, 40(5)
+; CHECK-NEXT:    lg 5, 32(5)
+; CHECK-NEXT:    lgr 2, 1
+; CHECK-NEXT:    lgdr 1, 0
+; CHECK-NEXT:    basr 7, 6
+; CHECK-NEXT:    bcr 0, 0
+; CHECK-NEXT:    lg 7, 2072(4)
+; CHECK-NEXT:    aghi 4, 192
+; CHECK-NEXT:    b 2(7)
 define i64 @call_vararg_both0(i64 %arg0, double %arg1) {
   %retval  = call i64(...) @pass_vararg3(double %arg1, i64 %arg0)
   ret i64 %retval
 }
 
-; CHECK-LABEL: call_vararg_long_double0
-; CHECK:       larl  1, @CPI5_0
-; CHECK-NEXT:  ld    0, 0(1)
-; CHECK-NEXT:  ld    2, 8(1)
-; CHECK:       lgdr  3, 0
-; CHECK:       lghi  1, 1
-; CHECK:       lghi  2, 2
-; CHECK:       std   0, 2192(4)
-; CHECK-NEXT:  std   2, 2200(4)
+; CHECK-LABEL: call_vararg_long_double0:
+; CHECK:         stmg 6, 7, 1872(4)
+; CHECK-NEXT:    aghi 4, -192
+; CHECK-NEXT:    larl 1, @CPI5_0
+; CHECK-NEXT:    ld 0, 0(1)
+; CHECK-NEXT:    ld 2, 8(1)
+; CHECK-NEXT:    lg 6, 8(5)
+; CHECK-NEXT:    lg 5, 0(5)
+; CHECK-NEXT:    lgdr 3, 0
+; CHECK-NEXT:    lghi 1, 1
+; CHECK-NEXT:    lghi 2, 2
+; CHECK-NEXT:    std 0, 2192(4)
+; CHECK-NEXT:    std 2, 2200(4)
+; CHECK-NEXT:    basr 7, 6
+; CHECK-NEXT:    bcr 0, 0
+; CHECK-NEXT:    lg 7, 2072(4)
+; CHECK-NEXT:    aghi 4, 192
+; CHECK-NEXT:    b 2(7)
 define i64 @call_vararg_long_double0() {
 entry:
   %retval = call i64 (i64, i64, ...) @pass_vararg0(i64 1, i64 2, fp128 0xLE0FC1518450562CD4000921FB5444261)
   ret i64 %retval
 }
 
-; CHECK-LABEL: call_vararg_long_double1
-; CHECK:       lgdr  3, 0
-; CHECK:       lghi  1, 1
-; CHECK:       lghi  2, 2
-; CHECK:       std   0, 2192(4)
-; CHECK-NEXT:  std   2, 2200(4)
+; CHECK-LABEL: call_vararg_long_double1:
+; CHECK:         stmg 6, 7, 1872(4)
+; CHECK-NEXT:    aghi 4, -192
+; CHECK-NEXT:    lg 6, 8(5)
+; CHECK-NEXT:    lg 5, 0(5)
+; CHECK-NEXT:    lgdr 3, 0
+; CHECK-NEXT:    lghi 1, 1
+; CHECK-NEXT:    lghi 2, 2
+; CHECK-NEXT:    std 0, 2192(4)
+; CHECK-NEXT:    std 2, 2200(4)
+; CHECK-NEXT:    basr 7, 6
+; CHECK-NEXT:    bcr 0, 0
+; CHECK-NEXT:    lg 7, 2072(4)
+; CHECK-NEXT:    aghi 4, 192
+; CHECK-NEXT:    b 2(7)
 define i64 @call_vararg_long_double1(fp128 %arg0) {
 entry:
   %retval = call i64 (i64, i64, ...) @pass_vararg0(i64 1, i64 2, fp128 %arg0)
@@ -90,22 +151,41 @@ entry:
 }
 
 ; CHECK-LABEL: call_vararg_long_double2
-; CHECK:      std   4, 2208(4)
-; CHECK-NEXT: std   6, 2216(4)
-; CHECK:      lgdr  3, 0
-; CHECK:      lghi  1, 1
-; CHECK:      lghi  2, 2
-; CHECK:      std   0, 2192(4)
-; CHECK-NEXT: std   2, 2200(4)
+; CHECK-LABEL: call_vararg_long_double2:
+; CHECK:         stmg 6, 7, 1872(4)
+; CHECK-NEXT:    aghi 4, -192
+; CHECK-NEXT:    std 4, 2208(4)
+; CHECK-NEXT:    std 6, 2216(4)
+; CHECK-NEXT:    lg 6, 8(5)
+; CHECK-NEXT:    lg 5, 0(5)
+; CHECK-NEXT:    lgdr 3, 0
+; CHECK-NEXT:    lghi 1, 1
+; CHECK-NEXT:    lghi 2, 2
+; CHECK-NEXT:    std 0, 2192(4)
+; CHECK-NEXT:    std 2, 2200(4)
+; CHECK-NEXT:    basr 7, 6
+; CHECK-NEXT:    bcr 0, 0
+; CHECK-NEXT:    lg 7, 2072(4)
+; CHECK-NEXT:    aghi 4, 192
+; CHECK-NEXT:    b 2(7)
 define i64 @call_vararg_long_double2(fp128 %arg0, fp128 %arg1) {
 entry:
   %retval = call i64 (i64, i64, ...) @pass_vararg0(i64 1, i64 2, fp128 %arg0, fp128 %arg1)
   ret i64 %retval
 }
 
-; CHECK-LABEL: call_vararg_long_double3
-; CHECK:       lgdr 3, 2
-; CHECK-NEXT:  lgdr 2, 0
+; CHECK-LABEL: call_vararg_long_double3:
+; CHECK:         stmg 6, 7, 1872(4)
+; CHECK-NEXT:    aghi 4, -192
+; CHECK-NEXT:    lg 6, 40(5)
+; CHECK-NEXT:    lg 5, 32(5)
+; CHECK-NEXT:    lgdr 3, 2
+; CHECK-NEXT:    lgdr 2, 0
+; CHECK-NEXT:    basr 7, 6
+; CHECK-NEXT:    bcr 0, 0
+; CHECK-NEXT:    lg 7, 2072(4)
+; CHECK-NEXT:    aghi 4, 192
+; CHECK-NEXT:    b 2(7)
 define i64 @call_vararg_long_double3(fp128 %arg0) {
 entry:
   %retval = call i64 (...) @pass_vararg3(fp128 %arg0)
@@ -173,38 +253,58 @@ define void @call_vec_double_vararg_straddle(<2 x double> %v) {
   ret void
 }
 
-; CHECK-LABEL: call_vararg_integral0
-; Since arguments 0, 1, and 2 are already in the correct
-; registers, we should have no loads of any sort into
-; GPRs 1, 2, and 3.
-; CHECK-NOT: lg  1
-; CHECK-NOT: lgr  1
-; CHECK-NOT: lg  2
-; CHECK-NOT: lgr  2
-; CHECK-NOT: lg  3
-; CHECK-NOT: lgr  3
+; CHECK-LABEL: call_vararg_integral0:
+; CHECK:         stmg 6, 7, 1872(4)
+; CHECK-NEXT:    aghi 4, -192
+; CHECK-NEXT:    lg 0, 2392(4)
+; CHECK-NEXT:    lg 6, 40(5)
+; CHECK-NEXT:    lg 5, 32(5)
+; CHECK-NEXT:    stg 0, 2200(4)
+; CHECK-NEXT:    basr 7, 6
+; CHECK-NEXT:    bcr 0, 0
+; CHECK-NEXT:    lg 7, 2072(4)
+; CHECK-NEXT:    aghi 4, 192
+; CHECK-NEXT:    b 2(7)
 define i64 @call_vararg_integral0(i32 signext %arg0, i16 signext %arg1, i64 signext %arg2, i8 signext %arg3) {
 entry:
   %retval = call i64(...) @pass_vararg3(i32 signext %arg0, i16 signext %arg1, i64 signext %arg2, i8 signext %arg3)
   ret i64 %retval
 }
 
-; CHECK-LABEL: call_vararg_float0
-; CHECK:       lghi  1, 1
-; CHECK:       llihf 2, 1073692672
+; CHECK-LABEL: call_vararg_float0:
+; CHECK:         stmg 6, 7, 1872(4)
+; CHECK-NEXT:    aghi 4, -192
+; CHECK-NEXT:    lg 6, 24(5)
+; CHECK-NEXT:    lg 5, 16(5)
+; CHECK-NEXT:    lghi 1, 1
+; CHECK-NEXT:    llihf 2, 1073692672
+; CHECK-NEXT:    basr 7, 6
+; CHECK-NEXT:    bcr 0, 0
+; CHECK-NEXT:    lg 7, 2072(4)
+; CHECK-NEXT:    aghi 4, 192
+; CHECK-NEXT:    b 2(7)
 define i64 @call_vararg_float0() {
 entry:
   %retval = call i64 (i64, ...) @pass_vararg2(i64 1, float 1.953125)
   ret i64 %retval
 }
 
-; CHECK-LABEL: call_vararg_float1
-; CHECK:       larl  1, @CPI17_0
-; CHECK:       le  0, 0(1)
-; CHECK:       llihf 0, 1073692672
-; CHECK:       llihh 2, 16384
-; CHECK:       llihh 3, 16392
-; CHECK:       stg  0, 2200(4)
+; CHECK-LABEL: call_vararg_float1:
+; CHECK:         stmg 6, 7, 1872(4)
+; CHECK-NEXT:    aghi 4, -192
+; CHECK-NEXT:    lg 6, 72(5)
+; CHECK-NEXT:    lg 5, 64(5)
+; CHECK-NEXT:    larl 1, @CPI17_0
+; CHECK-NEXT:    le 0, 0(1)
+; CHECK-NEXT:    llihf 0, 1073692672
+; CHECK-NEXT:    llihh 2, 16384
+; CHECK-NEXT:    llihh 3, 16392
+; CHECK-NEXT:    stg 0, 2200(4)
+; CHECK-NEXT:    basr 7, 6
+; CHECK-NEXT:    bcr 0, 0
+; CHECK-NEXT:    lg 7, 2072(4)
+; CHECK-NEXT:    aghi 4, 192
+; CHECK-NEXT:    b 2(7)
 define i64 @call_vararg_float1() {
 entry:
   %retval = call i64 (float, ...) @pass_vararg4(float 1.0, float 2.0, float 3.0, float 1.953125)
@@ -224,9 +324,16 @@ entry:
 ; }
 ;
 ; CHECK-LABEL: pass_vararg:
-; CHECK: aghi    4, -160
-; CHECK: la      0, 2208(4)
-; CHECK: stg     0, 2200(4)
+; CHECK:         stmg 6, 7, 1904(4)
+; CHECK-NEXT:    aghi 4, -160
+; CHECK-NEXT:    stg 2, 2344(4)
+; CHECK-NEXT:    stg 3, 2352(4)
+; CHECK-NEXT:    la 0, 2352(4)
+; CHECK-NEXT:    stg 0, 2200(4)
+; CHECK-NEXT:    lg 3, 2344(4)
+; CHECK-NEXT:    lg 7, 2072(4)
+; CHECK-NEXT:    aghi 4, 160
+; CHECK-NEXT:    b 2(7)
 define hidden i64 @pass_vararg(i64 %x, ...) {
 entry:
   %va = alloca ptr, align 8


        


More information about the llvm-commits mailing list