llvm-project/llvm/test/CodeGen/SystemZ/call-zos-vararg.ll
Kai Nacke 648bd564d0
[SystemZ][z/OS] Migrate most test case to use HLASM syntax (#181222)
This PR migrates all but two test cases to use HLASM syntax. It also
flips the default for the command line option, making HLASM output the
default.
The missing test cases requires some more support in the HLASM streamer,
which I will add separately.
2026-02-13 14:44:44 -05:00

358 lines
10 KiB
LLVM

; 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 DS 0H
; 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 DS 0H
; 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 DS 0H
; 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 DS 0H
; 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
}
;; TODO: The extra COPY after LGDR is unnecessary (machine-scheduler introduces the overlap).
; CHECK-LABEL: call_vararg_both0 DS 0H
; 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 0,0
; CHECK-NEXT: lgr 2,1
; CHECK-NEXT: lgr 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 DS 0H
; CHECK: stmg 6,7,1872(4)
; CHECK-NEXT: aghi 4,-192
; CHECK-NEXT: larl 1,L#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 DS 0H
; 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)
ret i64 %retval
}
; CHECK-LABEL: call_vararg_long_double2 DS 0H
; 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 DS 0H
; 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)
ret i64 %retval
}
; ARCH12-LABEL: call_vec_vararg_test0 DS 0H
; ARCH12: vlgvg 3,24,1
; ARCH12: vlgvg 2,24,0
; ARCH12: lghi 1,1
define void @call_vec_vararg_test0(<2 x double> %v) {
%retval = call i64(i64, ...) @pass_vararg2(i64 1, <2 x double> %v)
ret void
}
; ARCH12-LABEL: call_vec_vararg_test1 DS 0H
; ARCH12: larl 1,L#CPI10_0
; ARCH12: vl 0,0(1),3
; ARCH12: vlgvg 3,24,0
; ARCH12: vrepg 2,0,1
; ARCH12: vst 25,2208(4),3
; ARCH12: vst 24,2192(4),3
define void @call_vec_vararg_test1(<4 x i32> %v, <2 x i64> %w) {
%retval = call i64(fp128, ...) @pass_vararg1(fp128 0xLE0FC1518450562CD4000921FB5444261, <4 x i32> %v, <2 x i64> %w)
ret void
}
; ARCH12-LABEL: call_vec_char_vararg_straddle DS 0H
; ARCH12: vlgvg 3,24,0
; ARCH12: lghi 1,1
; ARCH12: lghi 2,2
; ARCH12: vst 24,2192(4),3
define void @call_vec_char_vararg_straddle(<16 x i8> %v) {
%retval = call i64(i64, i64, ...) @pass_vararg0(i64 1, i64 2, <16 x i8> %v)
ret void
}
; ARCH12-LABEL: call_vec_short_vararg_straddle DS 0H
; ARCH12: vlgvg 3,24,0
; ARCH12: lghi 1,1
; ARCH12: lghi 2,2
; ARCH12: vst 24,2192(4),3
define void @call_vec_short_vararg_straddle(<8 x i16> %v) {
%retval = call i64(i64, i64, ...) @pass_vararg0(i64 1, i64 2, <8 x i16> %v)
ret void
}
; ARCH12-LABEL: call_vec_int_vararg_straddle DS 0H
; ARCH12: vlgvg 3,24,0
; ARCH12: lghi 1,1
; ARCH12: lghi 2,2
; ARCH12: vst 24,2192(4),3
define void @call_vec_int_vararg_straddle(<4 x i32> %v) {
%retval = call i64(i64, i64, ...) @pass_vararg0(i64 1, i64 2, <4 x i32> %v)
ret void
}
; ARCH12-LABEL: call_vec_double_vararg_straddle DS 0H
; ARCH12: vlgvg 3,24,0
; ARCH12: lghi 1,1
; ARCH12: lghi 2,2
; ARCH12: vst 24,2192(4),3
define void @call_vec_double_vararg_straddle(<2 x double> %v) {
%retval = call i64(i64, i64, ...) @pass_vararg0(i64 1, i64 2, <2 x double> %v)
ret void
}
; CHECK-LABEL: call_vararg_integral0 DS 0H
; 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 DS 0H
; 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 DS 0H
; 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,L#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)
ret i64 %retval
}
; Derived from C source:
; #define _VARARG_EXT_
; #include <stdarg.h>
;
; long pass(long x, ...) {
; va_list va;
; va_start(va, x);
; long ret = va_arg(va, long);
; va_end(va);
; return ret;
; }
;
; CHECK-LABEL: pass_vararg DS 0H
; 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
call void @llvm.va_start(ptr %va)
%argp.cur = load ptr, ptr %va, align 8
%argp.next = getelementptr inbounds i8, ptr %argp.cur, i64 8
store ptr %argp.next, ptr %va, align 8
%ret = load i64, ptr %argp.cur, align 8
call void @llvm.va_end(ptr %va)
ret i64 %ret
}
declare void @llvm.va_start(ptr)
declare void @llvm.va_end(ptr)
declare i64 @pass_vararg0(i64 %arg0, i64 %arg1, ...)
declare i64 @pass_vararg1(fp128 %arg0, ...)
declare i64 @pass_vararg2(i64 %arg0, ...)
declare i64 @pass_vararg3(...)
declare i64 @pass_vararg4(float, ...)