The current values for PrivateGlobalPrefix and PrivateLabelPrefix (@@ and @ respectively) are, in hindsight, poor choices for multiple reasons: First, there exist externally visible routines from the language environment that begin with @@. These functions are certainly not local/private by any means and they should not share a prefix with private globals. Secondly, both private globals and private labels should be handled the same way by GOFF, so it doesn't make much sense for them to have separate prefixes. GOFF remains the only file format where these are different and there is no reason for that to be the case
357 lines
10 KiB
LLVM
357 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:
|
|
; 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: 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: 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: 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: 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: 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:
|
|
; 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
|
|
; 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: 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
|
|
; 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
|
|
; 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
|
|
; 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
|
|
; 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
|
|
; 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
|
|
; 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:
|
|
; 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: 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: 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:
|
|
; 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, ...)
|