1 ; Test f32 conditional stores that are presented as selects.
3 ; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s
5 declare void @foo(float *)
7 ; Test with the loaded value first.
8 define void @f1(float *%ptr, float %alt, i32 %limit) {
11 ; CHECK: jl [[LABEL:[^ ]*]]
13 ; CHECK: ste %f0, 0(%r2)
16 %cond = icmp ult i32 %limit, 42
17 %orig = load float *%ptr
18 %res = select i1 %cond, float %orig, float %alt
19 store float %res, float *%ptr
23 ; ...and with the loaded value second
24 define void @f2(float *%ptr, float %alt, i32 %limit) {
27 ; CHECK: jnl [[LABEL:[^ ]*]]
29 ; CHECK: ste %f0, 0(%r2)
32 %cond = icmp ult i32 %limit, 42
33 %orig = load float *%ptr
34 %res = select i1 %cond, float %alt, float %orig
35 store float %res, float *%ptr
39 ; Check the high end of the aligned STE range.
40 define void @f3(float *%base, float %alt, i32 %limit) {
43 ; CHECK: jl [[LABEL:[^ ]*]]
45 ; CHECK: ste %f0, 4092(%r2)
48 %ptr = getelementptr float *%base, i64 1023
49 %cond = icmp ult i32 %limit, 42
50 %orig = load float *%ptr
51 %res = select i1 %cond, float %orig, float %alt
52 store float %res, float *%ptr
56 ; Check the next word up, which should use STEY instead of STE.
57 define void @f4(float *%base, float %alt, i32 %limit) {
60 ; CHECK: jl [[LABEL:[^ ]*]]
62 ; CHECK: stey %f0, 4096(%r2)
65 %ptr = getelementptr float *%base, i64 1024
66 %cond = icmp ult i32 %limit, 42
67 %orig = load float *%ptr
68 %res = select i1 %cond, float %orig, float %alt
69 store float %res, float *%ptr
73 ; Check the high end of the aligned STEY range.
74 define void @f5(float *%base, float %alt, i32 %limit) {
77 ; CHECK: jl [[LABEL:[^ ]*]]
79 ; CHECK: stey %f0, 524284(%r2)
82 %ptr = getelementptr float *%base, i64 131071
83 %cond = icmp ult i32 %limit, 42
84 %orig = load float *%ptr
85 %res = select i1 %cond, float %orig, float %alt
86 store float %res, float *%ptr
90 ; Check the next word up, which needs separate address logic.
91 ; Other sequences besides this one would be OK.
92 define void @f6(float *%base, float %alt, i32 %limit) {
95 ; CHECK: jl [[LABEL:[^ ]*]]
97 ; CHECK: agfi %r2, 524288
98 ; CHECK: ste %f0, 0(%r2)
101 %ptr = getelementptr float *%base, i64 131072
102 %cond = icmp ult i32 %limit, 42
103 %orig = load float *%ptr
104 %res = select i1 %cond, float %orig, float %alt
105 store float %res, float *%ptr
109 ; Check the low end of the STEY range.
110 define void @f7(float *%base, float %alt, i32 %limit) {
113 ; CHECK: jl [[LABEL:[^ ]*]]
115 ; CHECK: stey %f0, -524288(%r2)
118 %ptr = getelementptr float *%base, i64 -131072
119 %cond = icmp ult i32 %limit, 42
120 %orig = load float *%ptr
121 %res = select i1 %cond, float %orig, float %alt
122 store float %res, float *%ptr
126 ; Check the next word down, which needs separate address logic.
127 ; Other sequences besides this one would be OK.
128 define void @f8(float *%base, float %alt, i32 %limit) {
131 ; CHECK: jl [[LABEL:[^ ]*]]
133 ; CHECK: agfi %r2, -524292
134 ; CHECK: ste %f0, 0(%r2)
137 %ptr = getelementptr float *%base, i64 -131073
138 %cond = icmp ult i32 %limit, 42
139 %orig = load float *%ptr
140 %res = select i1 %cond, float %orig, float %alt
141 store float %res, float *%ptr
145 ; Check that STEY allows an index.
146 define void @f9(i64 %base, i64 %index, float %alt, i32 %limit) {
149 ; CHECK: jl [[LABEL:[^ ]*]]
151 ; CHECK: stey %f0, 4096(%r3,%r2)
154 %add1 = add i64 %base, %index
155 %add2 = add i64 %add1, 4096
156 %ptr = inttoptr i64 %add2 to float *
157 %cond = icmp ult i32 %limit, 42
158 %orig = load float *%ptr
159 %res = select i1 %cond, float %orig, float %alt
160 store float %res, float *%ptr
164 ; Check that volatile loads are not matched.
165 define void @f10(float *%ptr, float %alt, i32 %limit) {
167 ; CHECK: le {{%f[0-5]}}, 0(%r2)
168 ; CHECK: {{jl|jnl}} [[LABEL:[^ ]*]]
170 ; CHECK: ste {{%f[0-5]}}, 0(%r2)
172 %cond = icmp ult i32 %limit, 42
173 %orig = load volatile float *%ptr
174 %res = select i1 %cond, float %orig, float %alt
175 store float %res, float *%ptr
179 ; ...likewise stores. In this case we should have a conditional load into %f0.
180 define void @f11(float *%ptr, float %alt, i32 %limit) {
182 ; CHECK: jnl [[LABEL:[^ ]*]]
183 ; CHECK: le %f0, 0(%r2)
185 ; CHECK: ste %f0, 0(%r2)
187 %cond = icmp ult i32 %limit, 42
188 %orig = load float *%ptr
189 %res = select i1 %cond, float %orig, float %alt
190 store volatile float %res, float *%ptr
194 ; Try a frame index base.
195 define void @f12(float %alt, i32 %limit) {
197 ; CHECK: brasl %r14, foo@PLT
199 ; CHECK: jl [[LABEL:[^ ]*]]
201 ; CHECK: ste {{%f[0-9]+}}, {{[0-9]+}}(%r15)
203 ; CHECK: brasl %r14, foo@PLT
206 call void @foo(float *%ptr)
207 %cond = icmp ult i32 %limit, 42
208 %orig = load float *%ptr
209 %res = select i1 %cond, float %orig, float %alt
210 store float %res, float *%ptr
211 call void @foo(float *%ptr)