; RUN: llc -mtriple=s390x-linux-gnu -mcpu=z13 -mattr=soft-float -O3 < %s | FileCheck %s ; ; Test that arguments and return values of fp/vector types are always handled ; with gprs with soft-float. define double @f1(double %arg) { ; CHECK-LABEL: f1: ; CHECK-NOT: %r2 ; CHECK-NOT: %{{[fv]}} ; CHECK: llihh %r3, 16368 ; CHECK-NEXT: brasl %r14, __adddf3@PLT ; CHECK-NEXT: lmg %r14, %r15, 272(%r15) ; CHECK-NEXT: br %r14 %res = fadd double %arg, 1.0 ret double %res } define float @f2(float %arg) { ; CHECK-LABEL: f2: ; CHECK-NOT: %r2 ; CHECK-NOT: %{{[fv]}} ; CHECK: llgfr %r2, %r2 ; CHECK-NEXT: llilh %r3, 16256 ; CHECK-NEXT: brasl %r14, __addsf3@PLT ; CHECK-NEXT: # kill: def $r2l killed $r2l killed $r2d ; CHECK-NEXT: lmg %r14, %r15, 272(%r15) ; CHECK-NEXT: br %r14 %res = fadd float %arg, 1.0 ret float %res } define fp128 @f2_fp128(fp128 %arg) { ; CHECK-LABEL: f2_fp128: ; CHECK-NOT: %{{[fv]}} ; CHECK: aghi %r15, -208 ; CHECK-NEXT: .cfi_def_cfa_offset 368 ; CHECK-NEXT: lg %r0, 0(%r2) ; CHECK-NEXT: lg %r1, 8(%r2) ; CHECK-NEXT: llihf %r2, 1073823744 ; CHECK-NEXT: stg %r2, 160(%r15) ; CHECK-NEXT: la %r2, 192(%r15) ; CHECK-NEXT: la %r3, 176(%r15) ; CHECK-NEXT: la %r4, 160(%r15) ; CHECK-NEXT: stg %r1, 184(%r15) ; CHECK-NEXT: stg %r0, 176(%r15) ; CHECK-NEXT: mvghi 168(%r15), 0 ; CHECK-NEXT: brasl %r14, __addtf3@PLT ; CHECK-NEXT: lg %r2, 192(%r15) ; CHECK-NEXT: lg %r3, 200(%r15) ; CHECK-NEXT: lmg %r14, %r15, 320(%r15) ; CHECK-NEXT: br %r14 %res = fadd fp128 %arg, 0xL00000000000000004001400000000000 ret fp128 %res } define <2 x double> @f3(<2 x double> %arg) { ; CHECK-LABEL: f3: ; CHECK-NOT: %{{[fv]}} ; CHECK: lg %r13, 8(%r2) ; CHECK-NEXT: lg %r2, 0(%r2) ; CHECK-NEXT: llihh %r3, 16368 ; CHECK-NEXT: brasl %r14, __adddf3@PLT ; CHECK-NEXT: lgr %r12, %r2 ; CHECK-NEXT: lgr %r2, %r13 ; CHECK-NEXT: llihh %r3, 16368 ; CHECK-NEXT: brasl %r14, __adddf3@PLT ; CHECK-NEXT: lgr %r3, %r2 ; CHECK-NEXT: lgr %r2, %r12 ; CHECK-NEXT: lmg %r12, %r15, 256(%r15) ; CHECK-NEXT: br %r14 %res = fadd <2 x double> %arg, <double 1.000000e+00, double 1.000000e+00> ret <2 x double> %res } define <2 x float> @f4(<2 x float> %arg) { ; CHECK-LABEL: f4: ; CHECK-NOT: %{{[fv]}} ; CHECK: lr %r13, %r3 ; CHECK-NEXT: llgfr %r2, %r2 ; CHECK-NEXT: llilh %r3, 16256 ; CHECK-NEXT: brasl %r14, __addsf3@PLT ; CHECK-NEXT: lgr %r12, %r2 ; CHECK-NEXT: llgfr %r2, %r13 ; CHECK-NEXT: llilh %r3, 16256 ; CHECK-NEXT: brasl %r14, __addsf3@PLT ; CHECK-NEXT: lgr %r3, %r2 ; CHECK-NEXT: lr %r2, %r12 ; CHECK-NEXT: # kill: def $r3l killed $r3l killed $r3d ; CHECK-NEXT: lmg %r12, %r15, 256(%r15) ; CHECK-NEXT: br %r14 %res = fadd <2 x float> %arg, <float 1.000000e+00, float 1.000000e+00> ret <2 x float> %res } define <2 x i64> @f5(<2 x i64> %arg) { ; CHECK-LABEL: f5: ; CHECK-NOT: %{{[fv]}} ; CHECK: lghi %r0, 1 ; CHECK-NEXT: ag %r0, 0(%r2) ; CHECK-NEXT: lghi %r3, 1 ; CHECK-NEXT: ag %r3, 8(%r2) ; CHECK-NEXT: lgr %r2, %r0 ; CHECK-NEXT: br %r14 %res = add <2 x i64> %arg, <i64 1, i64 1> ret <2 x i64> %res } define <2 x i32> @f6(<2 x i32> %arg) { ; CHECK-LABEL: f6: ; CHECK-NOT: %{{[fv]}} ; CHECK: ahi %r2, 1 ; CHECK-NEXT: ahi %r3, 1 ; CHECK-NEXT: br %r14 %res = add <2 x i32> %arg, <i32 1, i32 1> ret <2 x i32> %res } ;; Stack arguments define double @f7(double %A, double %B, double %C, double %D, double %E, double %F) { ; CHECK-LABEL: f7: ; CHECK-NOT: %{{[fv]}} ; CHECK: aghi %r15, -160 ; CHECK-NEXT: .cfi_def_cfa_offset 320 ; CHECK-NEXT: lg %r3, 320(%r15) ; CHECK-NEXT: brasl %r14, __adddf3@PLT ; CHECK-NEXT: lmg %r14, %r15, 272(%r15) ; CHECK-NEXT: br %r14 %res = fadd double %A, %F ret double %res } define float @f8(float %A, float %B, float %C, float %D, float %E, float %F) { ; CHECK-LABEL: f8: ; CHECK-NOT: %{{[fv]}} ; CHECK: aghi %r15, -160 ; CHECK-NEXT: .cfi_def_cfa_offset 320 ; CHECK-NEXT: llgf %r3, 324(%r15) ; CHECK-NEXT: llgfr %r2, %r2 ; CHECK-NEXT: brasl %r14, __addsf3@PLT ; CHECK-NEXT: # kill: def $r2l killed $r2l killed $r2d ; CHECK-NEXT: lmg %r14, %r15, 272(%r15) ; CHECK-NEXT: br %r14 %res = fadd float %A, %F ret float %res } define <2 x double> @f9(<2 x double> %A, <2 x double> %B, <2 x double> %C, <2 x double> %D, <2 x double> %E, <2 x double> %F, <2 x double> %G, <2 x double> %H, <2 x double> %I) { ; CHECK-LABEL: f9: ; CHECK-NOT: %{{[fv]}} ; CHECK: aghi %r15, -160 ; CHECK-NEXT: .cfi_def_cfa_offset 320 ; CHECK-NEXT: lg %r1, 344(%r15) ; CHECK-NEXT: lg %r13, 8(%r2) ; CHECK-NEXT: lg %r2, 0(%r2) ; CHECK-NEXT: lg %r3, 0(%r1) ; CHECK-NEXT: lg %r12, 8(%r1) ; CHECK-NEXT: brasl %r14, __adddf3@PLT ; CHECK-NEXT: lgr %r11, %r2 ; CHECK-NEXT: lgr %r2, %r13 ; CHECK-NEXT: lgr %r3, %r12 ; CHECK-NEXT: brasl %r14, __adddf3@PLT ; CHECK-NEXT: lgr %r3, %r2 ; CHECK-NEXT: lgr %r2, %r11 ; CHECK-NEXT: lmg %r11, %r15, 248(%r15) ; CHECK-NEXT: br %r14 %res = fadd <2 x double> %A, %I ret <2 x double> %res } define <2 x float> @f10(<2 x float> %A, <2 x float> %B, <2 x float> %C, <2 x float> %D, <2 x float> %E, <2 x float> %F, <2 x float> %G, <2 x float> %H, <2 x float> %I) { ; CHECK-LABEL: f10: ; CHECK-NOT: %{{[fv]}} ; CHECK: aghi %r15, -160 ; CHECK-NEXT: .cfi_def_cfa_offset 320 ; CHECK-NEXT: lr %r13, %r3 ; CHECK-NEXT: llgf %r3, 412(%r15) ; CHECK-NEXT: llgf %r12, 420(%r15) ; CHECK-NEXT: llgfr %r2, %r2 ; CHECK-NEXT: brasl %r14, __addsf3@PLT ; CHECK-NEXT: lgr %r11, %r2 ; CHECK-NEXT: llgfr %r2, %r13 ; CHECK-NEXT: lgr %r3, %r12 ; CHECK-NEXT: brasl %r14, __addsf3@PLT ; CHECK-NEXT: lgr %r3, %r2 ; CHECK-NEXT: lr %r2, %r11 ; CHECK-NEXT: # kill: def $r3l killed $r3l killed $r3d ; CHECK-NEXT: lmg %r11, %r15, 248(%r15) ; CHECK-NEXT: br %r14 %res = fadd <2 x float> %A, %I ret <2 x float> %res } define <2 x i64> @f11(<2 x i64> %A, <2 x i64> %B, <2 x i64> %C, <2 x i64> %D, <2 x i64> %E, <2 x i64> %F, <2 x i64> %G, <2 x i64> %H, <2 x i64> %I) { ; CHECK-LABEL: f11: ; CHECK-NOT: %{{[fv]}} ; CHECK: lg %r1, 184(%r15) ; CHECK-NEXT: lg %r3, 8(%r2) ; CHECK-NEXT: lg %r2, 0(%r2) ; CHECK-NEXT: ag %r2, 0(%r1) ; CHECK-NEXT: ag %r3, 8(%r1) ; CHECK-NEXT: br %r14 %res = add <2 x i64> %A, %I ret <2 x i64> %res } ;; calls declare double @bar_double(double %arg); define double @f12(double %arg, double %arg2) { ; CHECK-LABEL: f12: ; CHECK-NOT: %{{[fv]}} ; CHECK-NOT: %r{{[23]}} ; CHECK: lgr %r2, %r3 ; CHECK-NEXT: brasl %r14, bar_double@PLT ; CHECK-NEXT: lmg %r14, %r15, 272(%r15) ; CHECK-NEXT: br %r14 %res = call double @bar_double(double %arg2) ret double %res } declare float @bar_float(float %arg); define float @f13(float %arg, float %arg2) { ; CHECK-LABEL: f13: ; CHECK-NOT: %{{[fv]}} ; CHECK-NOT: %r{{[23]}} ; CHECK: lr %r2, %r3 ; CHECK-NEXT: brasl %r14, bar_float@PLT ; CHECK-NEXT: lmg %r14, %r15, 272(%r15) ; CHECK-NEXT: br %r14 %res = call float @bar_float(float %arg2) ret float %res } declare fp128 @bar_fp128(fp128 %arg); define fp128 @f14(fp128 %arg, fp128 %arg2) { ; CHECK-LABEL: f14: ; CHECK-NOT: %{{[fv]}} ; CHECK-NOT: %r3 ; CHECK: lg %r0, 0(%r3) ; CHECK-NEXT: lg %r1, 8(%r3) ; CHECK-NEXT: la %r2, 160(%r15) ; CHECK-NEXT: stg %r1, 168(%r15) ; CHECK-NEXT: stg %r0, 160(%r15) ; CHECK-NEXT: brasl %r14, bar_fp128@PLT ; CHECK-NEXT: lmg %r14, %r15, 288(%r15) ; CHECK-NEXT: br %r14 %res = call fp128 @bar_fp128(fp128 %arg2) ret fp128 %res } declare <2 x double> @bar_v2f64(<2 x double> %arg); define <2 x double> @f15(<2 x double> %arg, <2 x double> %arg2) { ; CHECK-LABEL: f15: ; CHECK-NOT: %{{[fv]}} ; CHECK-NOT: %r3 ; CHECK: lg %r0, 0(%r3) ; CHECK-NEXT: lg %r1, 8(%r3) ; CHECK-NEXT: la %r2, 160(%r15) ; CHECK-NEXT: stg %r1, 168(%r15) ; CHECK-NEXT: stg %r0, 160(%r15) ; CHECK-NEXT: brasl %r14, bar_v2f64@PLT ; CHECK-NEXT: lmg %r14, %r15, 288(%r15) ; CHECK-NEXT: br %r14 %res = call <2 x double> @bar_v2f64(<2 x double> %arg2) ret <2 x double> %res } declare <2 x float> @bar_v2f32(<2 x float> %arg); define <2 x float> @f16(<2 x float> %arg, <2 x float> %arg2) { ; CHECK-LABEL: f16: ; CHECK-NOT: %{{[fv]}} ; CHECK-NOT: %r{{[2345]}} ; CHECK: lr %r3, %r5 ; CHECK-NEXT: lr %r2, %r4 ; CHECK-NEXT: brasl %r14, bar_v2f32@PLT ; CHECK-NEXT: lmg %r14, %r15, 272(%r15) ; CHECK-NEXT: br %r14 %res = call <2 x float> @bar_v2f32(<2 x float> %arg2) ret <2 x float> %res } declare <2 x i64> @bar_v2i64(<2 x i64> %arg); define <2 x i64> @f17(<2 x i64> %arg, <2 x i64> %arg2) { ; CHECK-LABEL: f17: ; CHECK-NOT: %{{[fv]}} ; CHECK-NOT: %r3 ; CHECK: lg %r0, 0(%r3) ; CHECK-NEXT: lg %r1, 8(%r3) ; CHECK-NEXT: la %r2, 160(%r15) ; CHECK-NEXT: stg %r1, 168(%r15) ; CHECK-NEXT: stg %r0, 160(%r15) ; CHECK-NEXT: brasl %r14, bar_v2i64@PLT ; CHECK-NEXT: lmg %r14, %r15, 288(%r15) ; CHECK-NEXT: br %r14 %res = call <2 x i64> @bar_v2i64(<2 x i64> %arg2) ret <2 x i64> %res }