1; RUN: llc -mtriple=s390x-linux-gnu -mcpu=z13 -mattr=soft-float -O3 < %s | FileCheck %s 2; 3; Test that arguments and return values of fp/vector types are always handled 4; with gprs with soft-float. 5 6define double @f1(double %arg) { 7; CHECK-LABEL: f1: 8; CHECK-NOT: %r2 9; CHECK-NOT: %{{[fv]}} 10; CHECK: llihh %r3, 16368 11; CHECK-NEXT: brasl %r14, __adddf3@PLT 12; CHECK-NEXT: lmg %r14, %r15, 272(%r15) 13; CHECK-NEXT: br %r14 14 %res = fadd double %arg, 1.0 15 ret double %res 16} 17 18define float @f2(float %arg) { 19; CHECK-LABEL: f2: 20; CHECK-NOT: %r2 21; CHECK-NOT: %{{[fv]}} 22; CHECK: llgfr %r2, %r2 23; CHECK-NEXT: llilh %r3, 16256 24; CHECK-NEXT: brasl %r14, __addsf3@PLT 25; CHECK-NEXT: # kill: def $r2l killed $r2l killed $r2d 26; CHECK-NEXT: lmg %r14, %r15, 272(%r15) 27; CHECK-NEXT: br %r14 28 %res = fadd float %arg, 1.0 29 ret float %res 30} 31 32define fp128 @f2_fp128(fp128 %arg) { 33; CHECK-LABEL: f2_fp128: 34; CHECK-NOT: %{{[fv]}} 35; CHECK: aghi %r15, -208 36; CHECK-NEXT: .cfi_def_cfa_offset 368 37; CHECK-NEXT: lg %r0, 0(%r2) 38; CHECK-NEXT: lg %r1, 8(%r2) 39; CHECK-NEXT: llihf %r2, 1073823744 40; CHECK-NEXT: stg %r2, 160(%r15) 41; CHECK-NEXT: la %r2, 192(%r15) 42; CHECK-NEXT: la %r3, 176(%r15) 43; CHECK-NEXT: la %r4, 160(%r15) 44; CHECK-NEXT: stg %r1, 184(%r15) 45; CHECK-NEXT: stg %r0, 176(%r15) 46; CHECK-NEXT: mvghi 168(%r15), 0 47; CHECK-NEXT: brasl %r14, __addtf3@PLT 48; CHECK-NEXT: lg %r2, 192(%r15) 49; CHECK-NEXT: lg %r3, 200(%r15) 50; CHECK-NEXT: lmg %r14, %r15, 320(%r15) 51; CHECK-NEXT: br %r14 52 %res = fadd fp128 %arg, 0xL00000000000000004001400000000000 53 ret fp128 %res 54} 55 56define <2 x double> @f3(<2 x double> %arg) { 57; CHECK-LABEL: f3: 58; CHECK-NOT: %{{[fv]}} 59; CHECK: lg %r13, 8(%r2) 60; CHECK-NEXT: lg %r2, 0(%r2) 61; CHECK-NEXT: llihh %r3, 16368 62; CHECK-NEXT: brasl %r14, __adddf3@PLT 63; CHECK-NEXT: lgr %r12, %r2 64; CHECK-NEXT: lgr %r2, %r13 65; CHECK-NEXT: llihh %r3, 16368 66; CHECK-NEXT: brasl %r14, __adddf3@PLT 67; CHECK-NEXT: lgr %r3, %r2 68; CHECK-NEXT: lgr %r2, %r12 69; CHECK-NEXT: lmg %r12, %r15, 256(%r15) 70; CHECK-NEXT: br %r14 71 %res = fadd <2 x double> %arg, <double 1.000000e+00, double 1.000000e+00> 72 ret <2 x double> %res 73} 74 75define <2 x float> @f4(<2 x float> %arg) { 76; CHECK-LABEL: f4: 77; CHECK-NOT: %{{[fv]}} 78; CHECK: lr %r13, %r3 79; CHECK-NEXT: llgfr %r2, %r2 80; CHECK-NEXT: llilh %r3, 16256 81; CHECK-NEXT: brasl %r14, __addsf3@PLT 82; CHECK-NEXT: lgr %r12, %r2 83; CHECK-NEXT: llgfr %r2, %r13 84; CHECK-NEXT: llilh %r3, 16256 85; CHECK-NEXT: brasl %r14, __addsf3@PLT 86; CHECK-NEXT: lgr %r3, %r2 87; CHECK-NEXT: lr %r2, %r12 88; CHECK-NEXT: # kill: def $r3l killed $r3l killed $r3d 89; CHECK-NEXT: lmg %r12, %r15, 256(%r15) 90; CHECK-NEXT: br %r14 91 %res = fadd <2 x float> %arg, <float 1.000000e+00, float 1.000000e+00> 92 ret <2 x float> %res 93} 94 95define <2 x i64> @f5(<2 x i64> %arg) { 96; CHECK-LABEL: f5: 97; CHECK-NOT: %{{[fv]}} 98; CHECK: lghi %r0, 1 99; CHECK-NEXT: ag %r0, 0(%r2) 100; CHECK-NEXT: lghi %r3, 1 101; CHECK-NEXT: ag %r3, 8(%r2) 102; CHECK-NEXT: lgr %r2, %r0 103; CHECK-NEXT: br %r14 104 %res = add <2 x i64> %arg, <i64 1, i64 1> 105 ret <2 x i64> %res 106} 107 108define <2 x i32> @f6(<2 x i32> %arg) { 109; CHECK-LABEL: f6: 110; CHECK-NOT: %{{[fv]}} 111; CHECK: ahi %r2, 1 112; CHECK-NEXT: ahi %r3, 1 113; CHECK-NEXT: br %r14 114 %res = add <2 x i32> %arg, <i32 1, i32 1> 115 ret <2 x i32> %res 116} 117 118;; Stack arguments 119 120define double @f7(double %A, double %B, double %C, double %D, double %E, 121 double %F) { 122; CHECK-LABEL: f7: 123; CHECK-NOT: %{{[fv]}} 124; CHECK: aghi %r15, -160 125; CHECK-NEXT: .cfi_def_cfa_offset 320 126; CHECK-NEXT: lg %r3, 320(%r15) 127; CHECK-NEXT: brasl %r14, __adddf3@PLT 128; CHECK-NEXT: lmg %r14, %r15, 272(%r15) 129; CHECK-NEXT: br %r14 130 131 %res = fadd double %A, %F 132 ret double %res 133} 134 135define float @f8(float %A, float %B, float %C, float %D, float %E, 136 float %F) { 137; CHECK-LABEL: f8: 138; CHECK-NOT: %{{[fv]}} 139; CHECK: aghi %r15, -160 140; CHECK-NEXT: .cfi_def_cfa_offset 320 141; CHECK-NEXT: llgf %r3, 324(%r15) 142; CHECK-NEXT: llgfr %r2, %r2 143; CHECK-NEXT: brasl %r14, __addsf3@PLT 144; CHECK-NEXT: # kill: def $r2l killed $r2l killed $r2d 145; CHECK-NEXT: lmg %r14, %r15, 272(%r15) 146; CHECK-NEXT: br %r14 147 %res = fadd float %A, %F 148 ret float %res 149} 150 151define <2 x double> @f9(<2 x double> %A, <2 x double> %B, <2 x double> %C, 152 <2 x double> %D, <2 x double> %E, <2 x double> %F, 153 <2 x double> %G, <2 x double> %H, <2 x double> %I) { 154; CHECK-LABEL: f9: 155; CHECK-NOT: %{{[fv]}} 156; CHECK: aghi %r15, -160 157; CHECK-NEXT: .cfi_def_cfa_offset 320 158; CHECK-NEXT: lg %r1, 344(%r15) 159; CHECK-NEXT: lg %r13, 8(%r2) 160; CHECK-NEXT: lg %r2, 0(%r2) 161; CHECK-NEXT: lg %r3, 0(%r1) 162; CHECK-NEXT: lg %r12, 8(%r1) 163; CHECK-NEXT: brasl %r14, __adddf3@PLT 164; CHECK-NEXT: lgr %r11, %r2 165; CHECK-NEXT: lgr %r2, %r13 166; CHECK-NEXT: lgr %r3, %r12 167; CHECK-NEXT: brasl %r14, __adddf3@PLT 168; CHECK-NEXT: lgr %r3, %r2 169; CHECK-NEXT: lgr %r2, %r11 170; CHECK-NEXT: lmg %r11, %r15, 248(%r15) 171; CHECK-NEXT: br %r14 172 %res = fadd <2 x double> %A, %I 173 ret <2 x double> %res 174} 175 176define <2 x float> @f10(<2 x float> %A, <2 x float> %B, <2 x float> %C, 177 <2 x float> %D, <2 x float> %E, <2 x float> %F, 178 <2 x float> %G, <2 x float> %H, <2 x float> %I) { 179; CHECK-LABEL: f10: 180; CHECK-NOT: %{{[fv]}} 181; CHECK: aghi %r15, -160 182; CHECK-NEXT: .cfi_def_cfa_offset 320 183; CHECK-NEXT: lr %r13, %r3 184; CHECK-NEXT: llgf %r3, 412(%r15) 185; CHECK-NEXT: llgf %r12, 420(%r15) 186; CHECK-NEXT: llgfr %r2, %r2 187; CHECK-NEXT: brasl %r14, __addsf3@PLT 188; CHECK-NEXT: lgr %r11, %r2 189; CHECK-NEXT: llgfr %r2, %r13 190; CHECK-NEXT: lgr %r3, %r12 191; CHECK-NEXT: brasl %r14, __addsf3@PLT 192; CHECK-NEXT: lgr %r3, %r2 193; CHECK-NEXT: lr %r2, %r11 194; CHECK-NEXT: # kill: def $r3l killed $r3l killed $r3d 195; CHECK-NEXT: lmg %r11, %r15, 248(%r15) 196; CHECK-NEXT: br %r14 197 198 %res = fadd <2 x float> %A, %I 199 ret <2 x float> %res 200} 201 202define <2 x i64> @f11(<2 x i64> %A, <2 x i64> %B, <2 x i64> %C, 203 <2 x i64> %D, <2 x i64> %E, <2 x i64> %F, 204 <2 x i64> %G, <2 x i64> %H, <2 x i64> %I) { 205; CHECK-LABEL: f11: 206; CHECK-NOT: %{{[fv]}} 207; CHECK: lg %r1, 184(%r15) 208; CHECK-NEXT: lg %r3, 8(%r2) 209; CHECK-NEXT: lg %r2, 0(%r2) 210; CHECK-NEXT: ag %r2, 0(%r1) 211; CHECK-NEXT: ag %r3, 8(%r1) 212; CHECK-NEXT: br %r14 213 %res = add <2 x i64> %A, %I 214 ret <2 x i64> %res 215} 216 217;; calls 218 219declare double @bar_double(double %arg); 220define double @f12(double %arg, double %arg2) { 221; CHECK-LABEL: f12: 222; CHECK-NOT: %{{[fv]}} 223; CHECK-NOT: %r{{[23]}} 224; CHECK: lgr %r2, %r3 225; CHECK-NEXT: brasl %r14, bar_double@PLT 226; CHECK-NEXT: lmg %r14, %r15, 272(%r15) 227; CHECK-NEXT: br %r14 228 %res = call double @bar_double(double %arg2) 229 ret double %res 230} 231 232declare float @bar_float(float %arg); 233define float @f13(float %arg, float %arg2) { 234; CHECK-LABEL: f13: 235; CHECK-NOT: %{{[fv]}} 236; CHECK-NOT: %r{{[23]}} 237; CHECK: lr %r2, %r3 238; CHECK-NEXT: brasl %r14, bar_float@PLT 239; CHECK-NEXT: lmg %r14, %r15, 272(%r15) 240; CHECK-NEXT: br %r14 241 %res = call float @bar_float(float %arg2) 242 ret float %res 243} 244 245declare fp128 @bar_fp128(fp128 %arg); 246define fp128 @f14(fp128 %arg, fp128 %arg2) { 247; CHECK-LABEL: f14: 248; CHECK-NOT: %{{[fv]}} 249; CHECK-NOT: %r3 250; CHECK: lg %r0, 0(%r3) 251; CHECK-NEXT: lg %r1, 8(%r3) 252; CHECK-NEXT: la %r2, 160(%r15) 253; CHECK-NEXT: stg %r1, 168(%r15) 254; CHECK-NEXT: stg %r0, 160(%r15) 255; CHECK-NEXT: brasl %r14, bar_fp128@PLT 256; CHECK-NEXT: lmg %r14, %r15, 288(%r15) 257; CHECK-NEXT: br %r14 258 %res = call fp128 @bar_fp128(fp128 %arg2) 259 ret fp128 %res 260} 261 262declare <2 x double> @bar_v2f64(<2 x double> %arg); 263define <2 x double> @f15(<2 x double> %arg, <2 x double> %arg2) { 264; CHECK-LABEL: f15: 265; CHECK-NOT: %{{[fv]}} 266; CHECK-NOT: %r3 267; CHECK: lg %r0, 0(%r3) 268; CHECK-NEXT: lg %r1, 8(%r3) 269; CHECK-NEXT: la %r2, 160(%r15) 270; CHECK-NEXT: stg %r1, 168(%r15) 271; CHECK-NEXT: stg %r0, 160(%r15) 272; CHECK-NEXT: brasl %r14, bar_v2f64@PLT 273; CHECK-NEXT: lmg %r14, %r15, 288(%r15) 274; CHECK-NEXT: br %r14 275 %res = call <2 x double> @bar_v2f64(<2 x double> %arg2) 276 ret <2 x double> %res 277} 278 279declare <2 x float> @bar_v2f32(<2 x float> %arg); 280define <2 x float> @f16(<2 x float> %arg, <2 x float> %arg2) { 281; CHECK-LABEL: f16: 282; CHECK-NOT: %{{[fv]}} 283; CHECK-NOT: %r{{[2345]}} 284; CHECK: lr %r3, %r5 285; CHECK-NEXT: lr %r2, %r4 286; CHECK-NEXT: brasl %r14, bar_v2f32@PLT 287; CHECK-NEXT: lmg %r14, %r15, 272(%r15) 288; CHECK-NEXT: br %r14 289 %res = call <2 x float> @bar_v2f32(<2 x float> %arg2) 290 ret <2 x float> %res 291} 292 293declare <2 x i64> @bar_v2i64(<2 x i64> %arg); 294define <2 x i64> @f17(<2 x i64> %arg, <2 x i64> %arg2) { 295; CHECK-LABEL: f17: 296; CHECK-NOT: %{{[fv]}} 297; CHECK-NOT: %r3 298; CHECK: lg %r0, 0(%r3) 299; CHECK-NEXT: lg %r1, 8(%r3) 300; CHECK-NEXT: la %r2, 160(%r15) 301; CHECK-NEXT: stg %r1, 168(%r15) 302; CHECK-NEXT: stg %r0, 160(%r15) 303; CHECK-NEXT: brasl %r14, bar_v2i64@PLT 304; CHECK-NEXT: lmg %r14, %r15, 288(%r15) 305; CHECK-NEXT: br %r14 306 %res = call <2 x i64> @bar_v2i64(<2 x i64> %arg2) 307 ret <2 x i64> %res 308} 309