1; Test passing variable argument lists in 64-bit calls on z/OS. 2; RUN: llc < %s -mtriple=s390x-ibm-zos -mcpu=z10 | FileCheck %s 3; RUN: llc < %s -mtriple=s390x-ibm-zos -mcpu=z14 | FileCheck %s -check-prefix=ARCH12 4; CHECK-LABEL: call_vararg_double0: 5; CHECK: stmg 6,7,1872(4) 6; CHECK-NEXT: aghi 4,-192 7; CHECK-NEXT: lg 6,8(5) 8; CHECK-NEXT: lg 5,0(5) 9; CHECK-NEXT: llihf 3,1074118262 10; CHECK-NEXT: oilf 3,3367254360 11; CHECK-NEXT: lghi 1,1 12; CHECK-NEXT: lghi 2,2 13; CHECK-NEXT: basr 7,6 14; CHECK-NEXT: bcr 0,0 15; CHECK-NEXT: lg 7,2072(4) 16; CHECK-NEXT: aghi 4,192 17; CHECK-NEXT: b 2(7) 18define i64 @call_vararg_double0() { 19entry: 20 %retval = call i64 (i64, i64, ...) @pass_vararg0(i64 1, i64 2, double 2.718000e+00) 21 ret i64 %retval 22} 23 24; CHECK-LABEL: call_vararg_double1: 25; CHECK: stmg 6,7,1872(4) 26; CHECK-NEXT: aghi 4,-192 27; CHECK-NEXT: llihf 0,1074118262 28; CHECK-NEXT: oilf 0,3367254360 29; CHECK-NEXT: lg 6,8(5) 30; CHECK-NEXT: lg 5,0(5) 31; CHECK-NEXT: llihf 3,1074340036 32; CHECK-NEXT: oilf 3,2611340116 33; CHECK-NEXT: lghi 1,1 34; CHECK-NEXT: lghi 2,2 35; CHECK-NEXT: stg 0,2200(4) 36; CHECK-NEXT: basr 7,6 37; CHECK-NEXT: bcr 0,0 38; CHECK-NEXT: lg 7,2072(4) 39; CHECK-NEXT: aghi 4,192 40; CHECK-NEXT: b 2(7) 41define i64 @call_vararg_double1() { 42entry: 43 %retval = call i64 (i64, i64, ...) @pass_vararg0(i64 1, i64 2, double 3.141000e+00, double 2.718000e+00) 44 ret i64 %retval 45} 46 47; CHECK-LABEL: call_vararg_double2: 48; CHECK: stmg 6,7,1872(4) 49; CHECK-NEXT: aghi 4,-192 50; CHECK-NEXT: lg 6,24(5) 51; CHECK-NEXT: lg 5,16(5) 52; CHECK-NEXT: llihf 2,1074118262 53; CHECK-NEXT: oilf 2,3367254360 54; CHECK-NEXT: lghi 1,8200 55; CHECK-NEXT: basr 7,6 56; CHECK-NEXT: bcr 0,0 57; CHECK-NEXT: lg 7,2072(4) 58; CHECK-NEXT: aghi 4,192 59; CHECK-NEXT: b 2(7) 60define i64 @call_vararg_double2() { 61entry: 62 %retval = call i64 (i64, ...) @pass_vararg2(i64 8200, double 2.718000e+00) 63 ret i64 %retval 64} 65 66; CHECK-LABEL: call_vararg_double3: 67; CHECK: stmg 6,7,1872(4) 68; CHECK-NEXT: aghi 4,-192 69; CHECK-NEXT: llihf 0,1072703839 70; CHECK-NEXT: oilf 0,2861204133 71; CHECK-NEXT: lg 6,40(5) 72; CHECK-NEXT: lg 5,32(5) 73; CHECK-NEXT: llihf 1,1074118262 74; CHECK-NEXT: oilf 1,3367254360 75; CHECK-NEXT: llihf 2,1074340036 76; CHECK-NEXT: oilf 2,2611340116 77; CHECK-NEXT: llihf 3,1073127358 78; CHECK-NEXT: oilf 3,1992864825 79; CHECK-NEXT: stg 0,2200(4) 80; CHECK-NEXT: basr 7,6 81; CHECK-NEXT: bcr 0,0 82; CHECK-NEXT: lg 7,2072(4) 83; CHECK-NEXT: aghi 4,192 84; CHECK-NEXT: b 2(7) 85define i64 @call_vararg_double3() { 86entry: 87 %retval = call i64 (...) @pass_vararg3(double 2.718000e+00, double 3.141000e+00, double 1.414000e+00, double 1.010101e+00) 88 ret i64 %retval 89} 90 91;; TODO: The extra COPY after LGDR is unnecessary (machine-scheduler introduces the overlap). 92; CHECK-LABEL: call_vararg_both0: 93; CHECK: stmg 6,7,1872(4) 94; CHECK-NEXT: aghi 4,-192 95; CHECK-NEXT: lg 6,40(5) 96; CHECK-NEXT: lg 5,32(5) 97; CHECK-NEXT: lgdr 0,0 98; CHECK-NEXT: lgr 2,1 99; CHECK-NEXT: lgr 1,0 100; CHECK-NEXT: basr 7,6 101; CHECK-NEXT: bcr 0,0 102; CHECK-NEXT: lg 7,2072(4) 103; CHECK-NEXT: aghi 4,192 104; CHECK-NEXT: b 2(7) 105define i64 @call_vararg_both0(i64 %arg0, double %arg1) { 106 %retval = call i64(...) @pass_vararg3(double %arg1, i64 %arg0) 107 ret i64 %retval 108} 109 110; CHECK-LABEL: call_vararg_long_double0: 111; CHECK: stmg 6,7,1872(4) 112; CHECK-NEXT: aghi 4,-192 113; CHECK-NEXT: larl 1,L#CPI5_0 114; CHECK-NEXT: ld 0,0(1) 115; CHECK-NEXT: ld 2,8(1) 116; CHECK-NEXT: lg 6,8(5) 117; CHECK-NEXT: lg 5,0(5) 118; CHECK-NEXT: lgdr 3,0 119; CHECK-NEXT: lghi 1,1 120; CHECK-NEXT: lghi 2,2 121; CHECK-NEXT: std 0,2192(4) 122; CHECK-NEXT: std 2,2200(4) 123; CHECK-NEXT: basr 7,6 124; CHECK-NEXT: bcr 0,0 125; CHECK-NEXT: lg 7,2072(4) 126; CHECK-NEXT: aghi 4,192 127; CHECK-NEXT: b 2(7) 128define i64 @call_vararg_long_double0() { 129entry: 130 %retval = call i64 (i64, i64, ...) @pass_vararg0(i64 1, i64 2, fp128 0xLE0FC1518450562CD4000921FB5444261) 131 ret i64 %retval 132} 133 134; CHECK-LABEL: call_vararg_long_double1: 135; CHECK: stmg 6,7,1872(4) 136; CHECK-NEXT: aghi 4,-192 137; CHECK-NEXT: lg 6,8(5) 138; CHECK-NEXT: lg 5,0(5) 139; CHECK-NEXT: lgdr 3,0 140; CHECK-NEXT: lghi 1,1 141; CHECK-NEXT: lghi 2,2 142; CHECK-NEXT: std 0,2192(4) 143; CHECK-NEXT: std 2,2200(4) 144; CHECK-NEXT: basr 7,6 145; CHECK-NEXT: bcr 0,0 146; CHECK-NEXT: lg 7,2072(4) 147; CHECK-NEXT: aghi 4,192 148; CHECK-NEXT: b 2(7) 149define i64 @call_vararg_long_double1(fp128 %arg0) { 150entry: 151 %retval = call i64 (i64, i64, ...) @pass_vararg0(i64 1, i64 2, fp128 %arg0) 152 ret i64 %retval 153} 154 155; CHECK-LABEL: call_vararg_long_double2 156; CHECK-LABEL: call_vararg_long_double2: 157; CHECK: stmg 6,7,1872(4) 158; CHECK-NEXT: aghi 4,-192 159; CHECK-NEXT: std 4,2208(4) 160; CHECK-NEXT: std 6,2216(4) 161; CHECK-NEXT: lg 6,8(5) 162; CHECK-NEXT: lg 5,0(5) 163; CHECK-NEXT: lgdr 3,0 164; CHECK-NEXT: lghi 1,1 165; CHECK-NEXT: lghi 2,2 166; CHECK-NEXT: std 0,2192(4) 167; CHECK-NEXT: std 2,2200(4) 168; CHECK-NEXT: basr 7,6 169; CHECK-NEXT: bcr 0,0 170; CHECK-NEXT: lg 7,2072(4) 171; CHECK-NEXT: aghi 4,192 172; CHECK-NEXT: b 2(7) 173define i64 @call_vararg_long_double2(fp128 %arg0, fp128 %arg1) { 174entry: 175 %retval = call i64 (i64, i64, ...) @pass_vararg0(i64 1, i64 2, fp128 %arg0, fp128 %arg1) 176 ret i64 %retval 177} 178 179; CHECK-LABEL: call_vararg_long_double3: 180; CHECK: stmg 6,7,1872(4) 181; CHECK-NEXT: aghi 4,-192 182; CHECK-NEXT: lg 6,40(5) 183; CHECK-NEXT: lg 5,32(5) 184; CHECK-NEXT: lgdr 3,2 185; CHECK-NEXT: lgdr 2,0 186; CHECK-NEXT: basr 7,6 187; CHECK-NEXT: bcr 0,0 188; CHECK-NEXT: lg 7,2072(4) 189; CHECK-NEXT: aghi 4,192 190; CHECK-NEXT: b 2(7) 191define i64 @call_vararg_long_double3(fp128 %arg0) { 192entry: 193 %retval = call i64 (...) @pass_vararg3(fp128 %arg0) 194 ret i64 %retval 195} 196 197; ARCH12-LABEL: call_vec_vararg_test0 198; ARCH12: vlgvg 3,24,1 199; ARCH12: vlgvg 2,24,0 200; ARCH12: lghi 1,1 201define void @call_vec_vararg_test0(<2 x double> %v) { 202 %retval = call i64(i64, ...) @pass_vararg2(i64 1, <2 x double> %v) 203 ret void 204} 205 206; ARCH12-LABEL: call_vec_vararg_test1 207; ARCH12: larl 1,L#CPI10_0 208; ARCH12: vl 0,0(1),3 209; ARCH12: vlgvg 3,24,0 210; ARCH12: vrepg 2,0,1 211; ARCH12: vst 25,2208(4),3 212; ARCH12: vst 24,2192(4),3 213define void @call_vec_vararg_test1(<4 x i32> %v, <2 x i64> %w) { 214 %retval = call i64(fp128, ...) @pass_vararg1(fp128 0xLE0FC1518450562CD4000921FB5444261, <4 x i32> %v, <2 x i64> %w) 215 ret void 216} 217 218; ARCH12-LABEL: call_vec_char_vararg_straddle 219; ARCH12: vlgvg 3,24,0 220; ARCH12: lghi 1,1 221; ARCH12: lghi 2,2 222; ARCH12: vst 24,2192(4),3 223define void @call_vec_char_vararg_straddle(<16 x i8> %v) { 224 %retval = call i64(i64, i64, ...) @pass_vararg0(i64 1, i64 2, <16 x i8> %v) 225 ret void 226} 227 228; ARCH12-LABEL: call_vec_short_vararg_straddle 229; ARCH12: vlgvg 3,24,0 230; ARCH12: lghi 1,1 231; ARCH12: lghi 2,2 232; ARCH12: vst 24,2192(4),3 233define void @call_vec_short_vararg_straddle(<8 x i16> %v) { 234 %retval = call i64(i64, i64, ...) @pass_vararg0(i64 1, i64 2, <8 x i16> %v) 235 ret void 236} 237 238; ARCH12-LABEL: call_vec_int_vararg_straddle 239; ARCH12: vlgvg 3,24,0 240; ARCH12: lghi 1,1 241; ARCH12: lghi 2,2 242; ARCH12: vst 24,2192(4),3 243define void @call_vec_int_vararg_straddle(<4 x i32> %v) { 244 %retval = call i64(i64, i64, ...) @pass_vararg0(i64 1, i64 2, <4 x i32> %v) 245 ret void 246} 247 248; ARCH12-LABEL: call_vec_double_vararg_straddle 249; ARCH12: vlgvg 3,24,0 250; ARCH12: lghi 1,1 251; ARCH12: lghi 2,2 252; ARCH12: vst 24,2192(4),3 253define void @call_vec_double_vararg_straddle(<2 x double> %v) { 254 %retval = call i64(i64, i64, ...) @pass_vararg0(i64 1, i64 2, <2 x double> %v) 255 ret void 256} 257 258; CHECK-LABEL: call_vararg_integral0: 259; CHECK: stmg 6,7,1872(4) 260; CHECK-NEXT: aghi 4,-192 261; CHECK-NEXT: lg 0,2392(4) 262; CHECK-NEXT: lg 6,40(5) 263; CHECK-NEXT: lg 5,32(5) 264; CHECK-NEXT: stg 0,2200(4) 265; CHECK-NEXT: basr 7,6 266; CHECK-NEXT: bcr 0,0 267; CHECK-NEXT: lg 7,2072(4) 268; CHECK-NEXT: aghi 4,192 269; CHECK-NEXT: b 2(7) 270define i64 @call_vararg_integral0(i32 signext %arg0, i16 signext %arg1, i64 signext %arg2, i8 signext %arg3) { 271entry: 272 %retval = call i64(...) @pass_vararg3(i32 signext %arg0, i16 signext %arg1, i64 signext %arg2, i8 signext %arg3) 273 ret i64 %retval 274} 275 276; CHECK-LABEL: call_vararg_float0: 277; CHECK: stmg 6,7,1872(4) 278; CHECK-NEXT: aghi 4,-192 279; CHECK-NEXT: lg 6,24(5) 280; CHECK-NEXT: lg 5,16(5) 281; CHECK-NEXT: lghi 1,1 282; CHECK-NEXT: llihf 2,1073692672 283; CHECK-NEXT: basr 7,6 284; CHECK-NEXT: bcr 0,0 285; CHECK-NEXT: lg 7,2072(4) 286; CHECK-NEXT: aghi 4,192 287; CHECK-NEXT: b 2(7) 288define i64 @call_vararg_float0() { 289entry: 290 %retval = call i64 (i64, ...) @pass_vararg2(i64 1, float 1.953125) 291 ret i64 %retval 292} 293 294; CHECK-LABEL: call_vararg_float1: 295; CHECK: stmg 6,7,1872(4) 296; CHECK-NEXT: aghi 4,-192 297; CHECK-NEXT: lg 6,72(5) 298; CHECK-NEXT: lg 5,64(5) 299; CHECK-NEXT: larl 1,L#CPI17_0 300; CHECK-NEXT: le 0,0(1) 301; CHECK-NEXT: llihf 0,1073692672 302; CHECK-NEXT: llihh 2,16384 303; CHECK-NEXT: llihh 3,16392 304; CHECK-NEXT: stg 0,2200(4) 305; CHECK-NEXT: basr 7,6 306; CHECK-NEXT: bcr 0,0 307; CHECK-NEXT: lg 7,2072(4) 308; CHECK-NEXT: aghi 4,192 309; CHECK-NEXT: b 2(7) 310define i64 @call_vararg_float1() { 311entry: 312 %retval = call i64 (float, ...) @pass_vararg4(float 1.0, float 2.0, float 3.0, float 1.953125) 313 ret i64 %retval 314} 315 316; Derived from C source: 317; #define _VARARG_EXT_ 318; #include <stdarg.h> 319; 320; long pass(long x, ...) { 321; va_list va; 322; va_start(va, x); 323; long ret = va_arg(va, long); 324; va_end(va); 325; return ret; 326; } 327; 328; CHECK-LABEL: pass_vararg: 329; CHECK: stmg 6,7,1904(4) 330; CHECK-NEXT: aghi 4,-160 331; CHECK-NEXT: stg 2,2344(4) 332; CHECK-NEXT: stg 3,2352(4) 333; CHECK-NEXT: la 0,2352(4) 334; CHECK-NEXT: stg 0,2200(4) 335; CHECK-NEXT: lg 3,2344(4) 336; CHECK-NEXT: lg 7,2072(4) 337; CHECK-NEXT: aghi 4,160 338; CHECK-NEXT: b 2(7) 339define hidden i64 @pass_vararg(i64 %x, ...) { 340entry: 341 %va = alloca ptr, align 8 342 call void @llvm.va_start(ptr %va) 343 %argp.cur = load ptr, ptr %va, align 8 344 %argp.next = getelementptr inbounds i8, ptr %argp.cur, i64 8 345 store ptr %argp.next, ptr %va, align 8 346 %ret = load i64, ptr %argp.cur, align 8 347 call void @llvm.va_end(ptr %va) 348 ret i64 %ret 349} 350 351declare void @llvm.va_start(ptr) 352declare void @llvm.va_end(ptr) 353 354declare i64 @pass_vararg0(i64 %arg0, i64 %arg1, ...) 355declare i64 @pass_vararg1(fp128 %arg0, ...) 356declare i64 @pass_vararg2(i64 %arg0, ...) 357declare i64 @pass_vararg3(...) 358declare i64 @pass_vararg4(float, ...) 359