309 lines
9.1 KiB
LLVM
309 lines
9.1 KiB
LLVM
; 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
|
|
}
|