blob: 5bcfed0cd4a7a8083e40174fbfa4bbdc842bca27 [file] [log] [blame]
Richard Sandifordb86a8342013-06-27 09:27:40 +00001; Test f32 conditional stores that are presented as selects.
2;
3; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s
4
5declare void @foo(float *)
6
7; Test with the loaded value first.
8define void @f1(float *%ptr, float %alt, i32 %limit) {
9; CHECK: f1:
10; CHECK-NOT: %r2
11; CHECK: jl [[LABEL:[^ ]*]]
12; CHECK-NOT: %r2
13; CHECK: ste %f0, 0(%r2)
14; CHECK: [[LABEL]]:
15; CHECK: br %r14
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
20 ret void
21}
22
23; ...and with the loaded value second
24define void @f2(float *%ptr, float %alt, i32 %limit) {
25; CHECK: f2:
26; CHECK-NOT: %r2
27; CHECK: jnl [[LABEL:[^ ]*]]
28; CHECK-NOT: %r2
29; CHECK: ste %f0, 0(%r2)
30; CHECK: [[LABEL]]:
31; CHECK: br %r14
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
36 ret void
37}
38
39; Check the high end of the aligned STE range.
40define void @f3(float *%base, float %alt, i32 %limit) {
41; CHECK: f3:
42; CHECK-NOT: %r2
43; CHECK: jl [[LABEL:[^ ]*]]
44; CHECK-NOT: %r2
45; CHECK: ste %f0, 4092(%r2)
46; CHECK: [[LABEL]]:
47; CHECK: br %r14
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
53 ret void
54}
55
56; Check the next word up, which should use STEY instead of STE.
57define void @f4(float *%base, float %alt, i32 %limit) {
58; CHECK: f4:
59; CHECK-NOT: %r2
60; CHECK: jl [[LABEL:[^ ]*]]
61; CHECK-NOT: %r2
62; CHECK: stey %f0, 4096(%r2)
63; CHECK: [[LABEL]]:
64; CHECK: br %r14
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
70 ret void
71}
72
73; Check the high end of the aligned STEY range.
74define void @f5(float *%base, float %alt, i32 %limit) {
75; CHECK: f5:
76; CHECK-NOT: %r2
77; CHECK: jl [[LABEL:[^ ]*]]
78; CHECK-NOT: %r2
79; CHECK: stey %f0, 524284(%r2)
80; CHECK: [[LABEL]]:
81; CHECK: br %r14
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
87 ret void
88}
89
90; Check the next word up, which needs separate address logic.
91; Other sequences besides this one would be OK.
92define void @f6(float *%base, float %alt, i32 %limit) {
93; CHECK: f6:
94; CHECK-NOT: %r2
95; CHECK: jl [[LABEL:[^ ]*]]
96; CHECK-NOT: %r2
97; CHECK: agfi %r2, 524288
98; CHECK: ste %f0, 0(%r2)
99; CHECK: [[LABEL]]:
100; CHECK: br %r14
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
106 ret void
107}
108
109; Check the low end of the STEY range.
110define void @f7(float *%base, float %alt, i32 %limit) {
111; CHECK: f7:
112; CHECK-NOT: %r2
113; CHECK: jl [[LABEL:[^ ]*]]
114; CHECK-NOT: %r2
115; CHECK: stey %f0, -524288(%r2)
116; CHECK: [[LABEL]]:
117; CHECK: br %r14
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
123 ret void
124}
125
126; Check the next word down, which needs separate address logic.
127; Other sequences besides this one would be OK.
128define void @f8(float *%base, float %alt, i32 %limit) {
129; CHECK: f8:
130; CHECK-NOT: %r2
131; CHECK: jl [[LABEL:[^ ]*]]
132; CHECK-NOT: %r2
133; CHECK: agfi %r2, -524292
134; CHECK: ste %f0, 0(%r2)
135; CHECK: [[LABEL]]:
136; CHECK: br %r14
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
142 ret void
143}
144
145; Check that STEY allows an index.
146define void @f9(i64 %base, i64 %index, float %alt, i32 %limit) {
147; CHECK: f9:
148; CHECK-NOT: %r2
149; CHECK: jl [[LABEL:[^ ]*]]
150; CHECK-NOT: %r2
151; CHECK: stey %f0, 4096(%r3,%r2)
152; CHECK: [[LABEL]]:
153; CHECK: br %r14
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
161 ret void
162}
163
164; Check that volatile loads are not matched.
165define void @f10(float *%ptr, float %alt, i32 %limit) {
166; CHECK: f10:
167; CHECK: le {{%f[0-5]}}, 0(%r2)
168; CHECK: {{jl|jnl}} [[LABEL:[^ ]*]]
169; CHECK: [[LABEL]]:
170; CHECK: ste {{%f[0-5]}}, 0(%r2)
171; CHECK: br %r14
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
176 ret void
177}
178
179; ...likewise stores. In this case we should have a conditional load into %f0.
180define void @f11(float *%ptr, float %alt, i32 %limit) {
181; CHECK: f11:
182; CHECK: jnl [[LABEL:[^ ]*]]
183; CHECK: le %f0, 0(%r2)
184; CHECK: [[LABEL]]:
185; CHECK: ste %f0, 0(%r2)
186; CHECK: br %r14
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
191 ret void
192}
193
194; Try a frame index base.
195define void @f12(float %alt, i32 %limit) {
196; CHECK: f12:
197; CHECK: brasl %r14, foo@PLT
198; CHECK-NOT: %r15
199; CHECK: jl [[LABEL:[^ ]*]]
200; CHECK-NOT: %r15
201; CHECK: ste {{%f[0-9]+}}, {{[0-9]+}}(%r15)
202; CHECK: [[LABEL]]:
203; CHECK: brasl %r14, foo@PLT
204; CHECK: br %r14
205 %ptr = alloca float
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)
212 ret void
213}