blob: 4fbcdaba51036c97030adbdb5437d150ef5b1eee [file] [log] [blame]
Richard Sandifordf834ea12013-10-31 12:14:17 +00001; Test 16-bit conditional stores that are presented as selects. The volatile
2; tests require z10, which use a branch instead of a LOCR.
Richard Sandifordb86a8342013-06-27 09:27:40 +00003;
Richard Sandifordf834ea12013-10-31 12:14:17 +00004; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z10 | FileCheck %s
Richard Sandifordb86a8342013-06-27 09:27:40 +00005
6declare void @foo(i16 *)
7
8; Test the simple case, with the loaded value first.
9define void @f1(i16 *%ptr, i16 %alt, i32 %limit) {
Stephen Lind24ab202013-07-14 06:24:09 +000010; CHECK-LABEL: f1:
Richard Sandifordb86a8342013-06-27 09:27:40 +000011; CHECK-NOT: %r2
12; CHECK: jl [[LABEL:[^ ]*]]
13; CHECK-NOT: %r2
14; CHECK: sth %r3, 0(%r2)
15; CHECK: [[LABEL]]:
16; CHECK: br %r14
Richard Sandiford93183ee2013-09-18 09:56:40 +000017 %cond = icmp ult i32 %limit, 420
Richard Sandifordb86a8342013-06-27 09:27:40 +000018 %orig = load i16 *%ptr
19 %res = select i1 %cond, i16 %orig, i16 %alt
20 store i16 %res, i16 *%ptr
21 ret void
22}
23
24; ...and with the loaded value second
25define void @f2(i16 *%ptr, i16 %alt, i32 %limit) {
Stephen Lind24ab202013-07-14 06:24:09 +000026; CHECK-LABEL: f2:
Richard Sandifordb86a8342013-06-27 09:27:40 +000027; CHECK-NOT: %r2
Richard Sandiford3d768e32013-07-31 12:30:20 +000028; CHECK: jhe [[LABEL:[^ ]*]]
Richard Sandifordb86a8342013-06-27 09:27:40 +000029; CHECK-NOT: %r2
30; CHECK: sth %r3, 0(%r2)
31; CHECK: [[LABEL]]:
32; CHECK: br %r14
Richard Sandiford93183ee2013-09-18 09:56:40 +000033 %cond = icmp ult i32 %limit, 420
Richard Sandifordb86a8342013-06-27 09:27:40 +000034 %orig = load i16 *%ptr
35 %res = select i1 %cond, i16 %alt, i16 %orig
36 store i16 %res, i16 *%ptr
37 ret void
38}
39
40; Test cases where the value is explicitly sign-extended to 32 bits, with the
41; loaded value first.
42define void @f3(i16 *%ptr, i32 %alt, i32 %limit) {
Stephen Lind24ab202013-07-14 06:24:09 +000043; CHECK-LABEL: f3:
Richard Sandifordb86a8342013-06-27 09:27:40 +000044; CHECK-NOT: %r2
45; CHECK: jl [[LABEL:[^ ]*]]
46; CHECK-NOT: %r2
47; CHECK: sth %r3, 0(%r2)
48; CHECK: [[LABEL]]:
49; CHECK: br %r14
Richard Sandiford93183ee2013-09-18 09:56:40 +000050 %cond = icmp ult i32 %limit, 420
Richard Sandifordb86a8342013-06-27 09:27:40 +000051 %orig = load i16 *%ptr
52 %ext = sext i16 %orig to i32
53 %res = select i1 %cond, i32 %ext, i32 %alt
54 %trunc = trunc i32 %res to i16
55 store i16 %trunc, i16 *%ptr
56 ret void
57}
58
59; ...and with the loaded value second
60define void @f4(i16 *%ptr, i32 %alt, i32 %limit) {
Stephen Lind24ab202013-07-14 06:24:09 +000061; CHECK-LABEL: f4:
Richard Sandifordb86a8342013-06-27 09:27:40 +000062; CHECK-NOT: %r2
Richard Sandiford3d768e32013-07-31 12:30:20 +000063; CHECK: jhe [[LABEL:[^ ]*]]
Richard Sandifordb86a8342013-06-27 09:27:40 +000064; CHECK-NOT: %r2
65; CHECK: sth %r3, 0(%r2)
66; CHECK: [[LABEL]]:
67; CHECK: br %r14
Richard Sandiford93183ee2013-09-18 09:56:40 +000068 %cond = icmp ult i32 %limit, 420
Richard Sandifordb86a8342013-06-27 09:27:40 +000069 %orig = load i16 *%ptr
70 %ext = sext i16 %orig to i32
71 %res = select i1 %cond, i32 %alt, i32 %ext
72 %trunc = trunc i32 %res to i16
73 store i16 %trunc, i16 *%ptr
74 ret void
75}
76
77; Test cases where the value is explicitly zero-extended to 32 bits, with the
78; loaded value first.
79define void @f5(i16 *%ptr, i32 %alt, i32 %limit) {
Stephen Lind24ab202013-07-14 06:24:09 +000080; CHECK-LABEL: f5:
Richard Sandifordb86a8342013-06-27 09:27:40 +000081; CHECK-NOT: %r2
82; CHECK: jl [[LABEL:[^ ]*]]
83; CHECK-NOT: %r2
84; CHECK: sth %r3, 0(%r2)
85; CHECK: [[LABEL]]:
86; CHECK: br %r14
Richard Sandiford93183ee2013-09-18 09:56:40 +000087 %cond = icmp ult i32 %limit, 420
Richard Sandifordb86a8342013-06-27 09:27:40 +000088 %orig = load i16 *%ptr
89 %ext = zext i16 %orig to i32
90 %res = select i1 %cond, i32 %ext, i32 %alt
91 %trunc = trunc i32 %res to i16
92 store i16 %trunc, i16 *%ptr
93 ret void
94}
95
96; ...and with the loaded value second
97define void @f6(i16 *%ptr, i32 %alt, i32 %limit) {
Stephen Lind24ab202013-07-14 06:24:09 +000098; CHECK-LABEL: f6:
Richard Sandifordb86a8342013-06-27 09:27:40 +000099; CHECK-NOT: %r2
Richard Sandiford3d768e32013-07-31 12:30:20 +0000100; CHECK: jhe [[LABEL:[^ ]*]]
Richard Sandifordb86a8342013-06-27 09:27:40 +0000101; CHECK-NOT: %r2
102; CHECK: sth %r3, 0(%r2)
103; CHECK: [[LABEL]]:
104; CHECK: br %r14
Richard Sandiford93183ee2013-09-18 09:56:40 +0000105 %cond = icmp ult i32 %limit, 420
Richard Sandifordb86a8342013-06-27 09:27:40 +0000106 %orig = load i16 *%ptr
107 %ext = zext i16 %orig to i32
108 %res = select i1 %cond, i32 %alt, i32 %ext
109 %trunc = trunc i32 %res to i16
110 store i16 %trunc, i16 *%ptr
111 ret void
112}
113
114; Test cases where the value is explicitly sign-extended to 64 bits, with the
115; loaded value first.
116define void @f7(i16 *%ptr, i64 %alt, i32 %limit) {
Stephen Lind24ab202013-07-14 06:24:09 +0000117; CHECK-LABEL: f7:
Richard Sandifordb86a8342013-06-27 09:27:40 +0000118; CHECK-NOT: %r2
119; CHECK: jl [[LABEL:[^ ]*]]
120; CHECK-NOT: %r2
121; CHECK: sth %r3, 0(%r2)
122; CHECK: [[LABEL]]:
123; CHECK: br %r14
Richard Sandiford93183ee2013-09-18 09:56:40 +0000124 %cond = icmp ult i32 %limit, 420
Richard Sandifordb86a8342013-06-27 09:27:40 +0000125 %orig = load i16 *%ptr
126 %ext = sext i16 %orig to i64
127 %res = select i1 %cond, i64 %ext, i64 %alt
128 %trunc = trunc i64 %res to i16
129 store i16 %trunc, i16 *%ptr
130 ret void
131}
132
133; ...and with the loaded value second
134define void @f8(i16 *%ptr, i64 %alt, i32 %limit) {
Stephen Lind24ab202013-07-14 06:24:09 +0000135; CHECK-LABEL: f8:
Richard Sandifordb86a8342013-06-27 09:27:40 +0000136; CHECK-NOT: %r2
Richard Sandiford3d768e32013-07-31 12:30:20 +0000137; CHECK: jhe [[LABEL:[^ ]*]]
Richard Sandifordb86a8342013-06-27 09:27:40 +0000138; CHECK-NOT: %r2
139; CHECK: sth %r3, 0(%r2)
140; CHECK: [[LABEL]]:
141; CHECK: br %r14
Richard Sandiford93183ee2013-09-18 09:56:40 +0000142 %cond = icmp ult i32 %limit, 420
Richard Sandifordb86a8342013-06-27 09:27:40 +0000143 %orig = load i16 *%ptr
144 %ext = sext i16 %orig to i64
145 %res = select i1 %cond, i64 %alt, i64 %ext
146 %trunc = trunc i64 %res to i16
147 store i16 %trunc, i16 *%ptr
148 ret void
149}
150
151; Test cases where the value is explicitly zero-extended to 64 bits, with the
152; loaded value first.
153define void @f9(i16 *%ptr, i64 %alt, i32 %limit) {
Stephen Lind24ab202013-07-14 06:24:09 +0000154; CHECK-LABEL: f9:
Richard Sandifordb86a8342013-06-27 09:27:40 +0000155; CHECK-NOT: %r2
156; CHECK: jl [[LABEL:[^ ]*]]
157; CHECK-NOT: %r2
158; CHECK: sth %r3, 0(%r2)
159; CHECK: [[LABEL]]:
160; CHECK: br %r14
Richard Sandiford93183ee2013-09-18 09:56:40 +0000161 %cond = icmp ult i32 %limit, 420
Richard Sandifordb86a8342013-06-27 09:27:40 +0000162 %orig = load i16 *%ptr
163 %ext = zext i16 %orig to i64
164 %res = select i1 %cond, i64 %ext, i64 %alt
165 %trunc = trunc i64 %res to i16
166 store i16 %trunc, i16 *%ptr
167 ret void
168}
169
170; ...and with the loaded value second
171define void @f10(i16 *%ptr, i64 %alt, i32 %limit) {
Stephen Lind24ab202013-07-14 06:24:09 +0000172; CHECK-LABEL: f10:
Richard Sandifordb86a8342013-06-27 09:27:40 +0000173; CHECK-NOT: %r2
Richard Sandiford3d768e32013-07-31 12:30:20 +0000174; CHECK: jhe [[LABEL:[^ ]*]]
Richard Sandifordb86a8342013-06-27 09:27:40 +0000175; CHECK-NOT: %r2
176; CHECK: sth %r3, 0(%r2)
177; CHECK: [[LABEL]]:
178; CHECK: br %r14
Richard Sandiford93183ee2013-09-18 09:56:40 +0000179 %cond = icmp ult i32 %limit, 420
Richard Sandifordb86a8342013-06-27 09:27:40 +0000180 %orig = load i16 *%ptr
181 %ext = zext i16 %orig to i64
182 %res = select i1 %cond, i64 %alt, i64 %ext
183 %trunc = trunc i64 %res to i16
184 store i16 %trunc, i16 *%ptr
185 ret void
186}
187
188; Check the high end of the aligned STH range.
189define void @f11(i16 *%base, i16 %alt, i32 %limit) {
Stephen Lind24ab202013-07-14 06:24:09 +0000190; CHECK-LABEL: f11:
Richard Sandifordb86a8342013-06-27 09:27:40 +0000191; CHECK-NOT: %r2
192; CHECK: jl [[LABEL:[^ ]*]]
193; CHECK-NOT: %r2
194; CHECK: sth %r3, 4094(%r2)
195; CHECK: [[LABEL]]:
196; CHECK: br %r14
197 %ptr = getelementptr i16 *%base, i64 2047
Richard Sandiford93183ee2013-09-18 09:56:40 +0000198 %cond = icmp ult i32 %limit, 420
Richard Sandifordb86a8342013-06-27 09:27:40 +0000199 %orig = load i16 *%ptr
200 %res = select i1 %cond, i16 %orig, i16 %alt
201 store i16 %res, i16 *%ptr
202 ret void
203}
204
205; Check the next halfword up, which should use STHY instead of STH.
206define void @f12(i16 *%base, i16 %alt, i32 %limit) {
Stephen Lind24ab202013-07-14 06:24:09 +0000207; CHECK-LABEL: f12:
Richard Sandifordb86a8342013-06-27 09:27:40 +0000208; CHECK-NOT: %r2
209; CHECK: jl [[LABEL:[^ ]*]]
210; CHECK-NOT: %r2
211; CHECK: sthy %r3, 4096(%r2)
212; CHECK: [[LABEL]]:
213; CHECK: br %r14
214 %ptr = getelementptr i16 *%base, i64 2048
Richard Sandiford93183ee2013-09-18 09:56:40 +0000215 %cond = icmp ult i32 %limit, 420
Richard Sandifordb86a8342013-06-27 09:27:40 +0000216 %orig = load i16 *%ptr
217 %res = select i1 %cond, i16 %orig, i16 %alt
218 store i16 %res, i16 *%ptr
219 ret void
220}
221
222; Check the high end of the aligned STHY range.
223define void @f13(i16 *%base, i16 %alt, i32 %limit) {
Stephen Lind24ab202013-07-14 06:24:09 +0000224; CHECK-LABEL: f13:
Richard Sandifordb86a8342013-06-27 09:27:40 +0000225; CHECK-NOT: %r2
226; CHECK: jl [[LABEL:[^ ]*]]
227; CHECK-NOT: %r2
228; CHECK: sthy %r3, 524286(%r2)
229; CHECK: [[LABEL]]:
230; CHECK: br %r14
231 %ptr = getelementptr i16 *%base, i64 262143
Richard Sandiford93183ee2013-09-18 09:56:40 +0000232 %cond = icmp ult i32 %limit, 420
Richard Sandifordb86a8342013-06-27 09:27:40 +0000233 %orig = load i16 *%ptr
234 %res = select i1 %cond, i16 %orig, i16 %alt
235 store i16 %res, i16 *%ptr
236 ret void
237}
238
239; Check the next halfword up, which needs separate address logic.
240; Other sequences besides this one would be OK.
241define void @f14(i16 *%base, i16 %alt, i32 %limit) {
Stephen Lind24ab202013-07-14 06:24:09 +0000242; CHECK-LABEL: f14:
Richard Sandifordb86a8342013-06-27 09:27:40 +0000243; CHECK-NOT: %r2
244; CHECK: jl [[LABEL:[^ ]*]]
245; CHECK-NOT: %r2
246; CHECK: agfi %r2, 524288
247; CHECK: sth %r3, 0(%r2)
248; CHECK: [[LABEL]]:
249; CHECK: br %r14
250 %ptr = getelementptr i16 *%base, i64 262144
Richard Sandiford93183ee2013-09-18 09:56:40 +0000251 %cond = icmp ult i32 %limit, 420
Richard Sandifordb86a8342013-06-27 09:27:40 +0000252 %orig = load i16 *%ptr
253 %res = select i1 %cond, i16 %orig, i16 %alt
254 store i16 %res, i16 *%ptr
255 ret void
256}
257
258; Check the low end of the STHY range.
259define void @f15(i16 *%base, i16 %alt, i32 %limit) {
Stephen Lind24ab202013-07-14 06:24:09 +0000260; CHECK-LABEL: f15:
Richard Sandifordb86a8342013-06-27 09:27:40 +0000261; CHECK-NOT: %r2
262; CHECK: jl [[LABEL:[^ ]*]]
263; CHECK-NOT: %r2
264; CHECK: sthy %r3, -524288(%r2)
265; CHECK: [[LABEL]]:
266; CHECK: br %r14
267 %ptr = getelementptr i16 *%base, i64 -262144
Richard Sandiford93183ee2013-09-18 09:56:40 +0000268 %cond = icmp ult i32 %limit, 420
Richard Sandifordb86a8342013-06-27 09:27:40 +0000269 %orig = load i16 *%ptr
270 %res = select i1 %cond, i16 %orig, i16 %alt
271 store i16 %res, i16 *%ptr
272 ret void
273}
274
275; Check the next halfword down, which needs separate address logic.
276; Other sequences besides this one would be OK.
277define void @f16(i16 *%base, i16 %alt, i32 %limit) {
Stephen Lind24ab202013-07-14 06:24:09 +0000278; CHECK-LABEL: f16:
Richard Sandifordb86a8342013-06-27 09:27:40 +0000279; CHECK-NOT: %r2
280; CHECK: jl [[LABEL:[^ ]*]]
281; CHECK-NOT: %r2
282; CHECK: agfi %r2, -524290
283; CHECK: sth %r3, 0(%r2)
284; CHECK: [[LABEL]]:
285; CHECK: br %r14
286 %ptr = getelementptr i16 *%base, i64 -262145
Richard Sandiford93183ee2013-09-18 09:56:40 +0000287 %cond = icmp ult i32 %limit, 420
Richard Sandifordb86a8342013-06-27 09:27:40 +0000288 %orig = load i16 *%ptr
289 %res = select i1 %cond, i16 %orig, i16 %alt
290 store i16 %res, i16 *%ptr
291 ret void
292}
293
294; Check that STHY allows an index.
295define void @f17(i64 %base, i64 %index, i16 %alt, i32 %limit) {
Stephen Lind24ab202013-07-14 06:24:09 +0000296; CHECK-LABEL: f17:
Richard Sandifordb86a8342013-06-27 09:27:40 +0000297; CHECK-NOT: %r2
298; CHECK: jl [[LABEL:[^ ]*]]
299; CHECK-NOT: %r2
300; CHECK: sthy %r4, 4096(%r3,%r2)
301; CHECK: [[LABEL]]:
302; CHECK: br %r14
303 %add1 = add i64 %base, %index
304 %add2 = add i64 %add1, 4096
305 %ptr = inttoptr i64 %add2 to i16 *
Richard Sandiford93183ee2013-09-18 09:56:40 +0000306 %cond = icmp ult i32 %limit, 420
Richard Sandifordb86a8342013-06-27 09:27:40 +0000307 %orig = load i16 *%ptr
308 %res = select i1 %cond, i16 %orig, i16 %alt
309 store i16 %res, i16 *%ptr
310 ret void
311}
312
313; Check that volatile loads are not matched.
314define void @f18(i16 *%ptr, i16 %alt, i32 %limit) {
Stephen Lind24ab202013-07-14 06:24:09 +0000315; CHECK-LABEL: f18:
Richard Sandifordb86a8342013-06-27 09:27:40 +0000316; CHECK: lh {{%r[0-5]}}, 0(%r2)
317; CHECK: {{jl|jnl}} [[LABEL:[^ ]*]]
318; CHECK: [[LABEL]]:
319; CHECK: sth {{%r[0-5]}}, 0(%r2)
320; CHECK: br %r14
Richard Sandiford93183ee2013-09-18 09:56:40 +0000321 %cond = icmp ult i32 %limit, 420
Richard Sandifordb86a8342013-06-27 09:27:40 +0000322 %orig = load volatile i16 *%ptr
323 %res = select i1 %cond, i16 %orig, i16 %alt
324 store i16 %res, i16 *%ptr
325 ret void
326}
327
328; ...likewise stores. In this case we should have a conditional load into %r3.
329define void @f19(i16 *%ptr, i16 %alt, i32 %limit) {
Stephen Lind24ab202013-07-14 06:24:09 +0000330; CHECK-LABEL: f19:
Richard Sandiford3d768e32013-07-31 12:30:20 +0000331; CHECK: jhe [[LABEL:[^ ]*]]
Richard Sandifordb86a8342013-06-27 09:27:40 +0000332; CHECK: lh %r3, 0(%r2)
333; CHECK: [[LABEL]]:
334; CHECK: sth %r3, 0(%r2)
335; CHECK: br %r14
Richard Sandiford93183ee2013-09-18 09:56:40 +0000336 %cond = icmp ult i32 %limit, 420
Richard Sandifordb86a8342013-06-27 09:27:40 +0000337 %orig = load i16 *%ptr
338 %res = select i1 %cond, i16 %orig, i16 %alt
339 store volatile i16 %res, i16 *%ptr
340 ret void
341}
342
343; Check that atomic loads are not matched. The transformation is OK for
344; the "unordered" case tested here, but since we don't try to handle atomic
345; operations at all in this context, it seems better to assert that than
346; to restrict the test to a stronger ordering.
347define void @f20(i16 *%ptr, i16 %alt, i32 %limit) {
348; FIXME: should use a normal load instead of CS.
Stephen Lind24ab202013-07-14 06:24:09 +0000349; CHECK-LABEL: f20:
Richard Sandifordbef3d7a2013-12-10 10:49:34 +0000350; CHECK: lh {{%r[0-9]+}}, 0(%r2)
Richard Sandifordb86a8342013-06-27 09:27:40 +0000351; CHECK: {{jl|jnl}} [[LABEL:[^ ]*]]
352; CHECK: [[LABEL]]:
Richard Sandifordbef3d7a2013-12-10 10:49:34 +0000353; CHECK: sth {{%r[0-9]+}}, 0(%r2)
Richard Sandifordb86a8342013-06-27 09:27:40 +0000354; CHECK: br %r14
Richard Sandiford93183ee2013-09-18 09:56:40 +0000355 %cond = icmp ult i32 %limit, 420
Richard Sandifordb86a8342013-06-27 09:27:40 +0000356 %orig = load atomic i16 *%ptr unordered, align 2
357 %res = select i1 %cond, i16 %orig, i16 %alt
358 store i16 %res, i16 *%ptr
359 ret void
360}
361
362; ...likewise stores.
363define void @f21(i16 *%ptr, i16 %alt, i32 %limit) {
364; FIXME: should use a normal store instead of CS.
Stephen Lind24ab202013-07-14 06:24:09 +0000365; CHECK-LABEL: f21:
Richard Sandiford3d768e32013-07-31 12:30:20 +0000366; CHECK: jhe [[LABEL:[^ ]*]]
Richard Sandifordb86a8342013-06-27 09:27:40 +0000367; CHECK: lh %r3, 0(%r2)
368; CHECK: [[LABEL]]:
Richard Sandifordbef3d7a2013-12-10 10:49:34 +0000369; CHECK: sth %r3, 0(%r2)
Richard Sandifordb86a8342013-06-27 09:27:40 +0000370; CHECK: br %r14
Richard Sandiford93183ee2013-09-18 09:56:40 +0000371 %cond = icmp ult i32 %limit, 420
Richard Sandifordb86a8342013-06-27 09:27:40 +0000372 %orig = load i16 *%ptr
373 %res = select i1 %cond, i16 %orig, i16 %alt
374 store atomic i16 %res, i16 *%ptr unordered, align 2
375 ret void
376}
377
378; Try a frame index base.
379define void @f22(i16 %alt, i32 %limit) {
Stephen Lind24ab202013-07-14 06:24:09 +0000380; CHECK-LABEL: f22:
Richard Sandifordb86a8342013-06-27 09:27:40 +0000381; CHECK: brasl %r14, foo@PLT
382; CHECK-NOT: %r15
383; CHECK: jl [[LABEL:[^ ]*]]
384; CHECK-NOT: %r15
385; CHECK: sth {{%r[0-9]+}}, {{[0-9]+}}(%r15)
386; CHECK: [[LABEL]]:
387; CHECK: brasl %r14, foo@PLT
388; CHECK: br %r14
389 %ptr = alloca i16
390 call void @foo(i16 *%ptr)
Richard Sandiford93183ee2013-09-18 09:56:40 +0000391 %cond = icmp ult i32 %limit, 420
Richard Sandifordb86a8342013-06-27 09:27:40 +0000392 %orig = load i16 *%ptr
393 %res = select i1 %cond, i16 %orig, i16 %alt
394 store i16 %res, i16 *%ptr
395 call void @foo(i16 *%ptr)
396 ret void
397}