[InstCombine] Signed saturation patterns
[llvm-complete.git] / test / CodeGen / SystemZ / asm-18.ll
blob459dfd116658aaf4bf298afae902e0f1958d1f2f
1 ; Test high-word operations, using "h" constraints to force a high
2 ; register and "r" constraints to force a low register.
4 ; RUN: llc < %s -verify-machineinstrs -mtriple=s390x-linux-gnu -mcpu=z196 \
5 ; RUN:   -no-integrated-as | FileCheck %s
7 ; Test loads and stores involving mixtures of high and low registers.
8 define void @f1(i32 *%ptr1, i32 *%ptr2) {
9 ; CHECK-LABEL: f1:
10 ; CHECK-DAG: lfh [[REG1:%r[0-5]]], 0(%r2)
11 ; CHECK-DAG: l [[REG2:%r[0-5]]], 0(%r3)
12 ; CHECK-DAG: lfh [[REG3:%r[0-5]]], 4096(%r2)
13 ; CHECK-DAG: ly [[REG4:%r[0-5]]], 524284(%r3)
14 ; CHECK: blah [[REG1]], [[REG2]], [[REG3]], [[REG4]]
15 ; CHECK-DAG: stfh [[REG1]], 0(%r2)
16 ; CHECK-DAG: st [[REG2]], 0(%r3)
17 ; CHECK-DAG: stfh [[REG3]], 4096(%r2)
18 ; CHECK-DAG: sty [[REG4]], 524284(%r3)
19 ; CHECK: br %r14
20   %ptr3 = getelementptr i32, i32 *%ptr1, i64 1024
21   %ptr4 = getelementptr i32, i32 *%ptr2, i64 131071
22   %old1 = load i32, i32 *%ptr1
23   %old2 = load i32, i32 *%ptr2
24   %old3 = load i32, i32 *%ptr3
25   %old4 = load i32, i32 *%ptr4
26   %res = call { i32, i32, i32, i32 } asm "blah $0, $1, $2, $3",
27               "=h,=r,=h,=r,0,1,2,3"(i32 %old1, i32 %old2, i32 %old3, i32 %old4)
28   %new1 = extractvalue { i32, i32, i32, i32 } %res, 0
29   %new2 = extractvalue { i32, i32, i32, i32 } %res, 1
30   %new3 = extractvalue { i32, i32, i32, i32 } %res, 2
31   %new4 = extractvalue { i32, i32, i32, i32 } %res, 3
32   store i32 %new1, i32 *%ptr1
33   store i32 %new2, i32 *%ptr2
34   store i32 %new3, i32 *%ptr3
35   store i32 %new4, i32 *%ptr4
36   ret void
39 ; Test moves involving mixtures of high and low registers.
40 define i32 @f2(i32 %old) {
41 ; CHECK-LABEL: f2:
42 ; CHECK-DAG: risbhg [[REG1:%r[0-5]]], %r2, 0, 159, 32
43 ; CHECK-DAG: lr %r3, %r2
44 ; CHECK: stepa [[REG1]], %r2, %r3
45 ; CHECK: risbhg {{%r[0-5]}}, [[REG1]], 0, 159, 0
46 ; CHECK: stepb [[REG2:%r[0-5]]]
47 ; CHECK: risblg %r2, [[REG2]], 0, 159, 32
48 ; CHECK: br %r14
49   %tmp = call i32 asm "stepa $1, $2, $3",
50                       "=h,0,{r2},{r3}"(i32 %old, i32 %old, i32 %old)
51   %new = call i32 asm "stepb $1, $2", "=&h,0,h"(i32 %tmp, i32 %tmp)
52   ret i32 %new
55 ; Test sign-extending 8-bit loads into mixtures of high and low registers.
56 define void @f3(i8 *%ptr1, i8 *%ptr2) {
57 ; CHECK-LABEL: f3:
58 ; CHECK-DAG: lbh [[REG1:%r[0-5]]], 0(%r2)
59 ; CHECK-DAG: lb [[REG2:%r[0-5]]], 0(%r3)
60 ; CHECK-DAG: lbh [[REG3:%r[0-5]]], 4096(%r2)
61 ; CHECK-DAG: lb [[REG4:%r[0-5]]], 524287(%r3)
62 ; CHECK: blah [[REG1]], [[REG2]]
63 ; CHECK: br %r14
64   %ptr3 = getelementptr i8, i8 *%ptr1, i64 4096
65   %ptr4 = getelementptr i8, i8 *%ptr2, i64 524287
66   %val1 = load i8, i8 *%ptr1
67   %val2 = load i8, i8 *%ptr2
68   %val3 = load i8, i8 *%ptr3
69   %val4 = load i8, i8 *%ptr4
70   %ext1 = sext i8 %val1 to i32
71   %ext2 = sext i8 %val2 to i32
72   %ext3 = sext i8 %val3 to i32
73   %ext4 = sext i8 %val4 to i32
74   call void asm sideeffect "blah $0, $1, $2, $3",
75                            "h,r,h,r"(i32 %ext1, i32 %ext2, i32 %ext3, i32 %ext4)
76   ret void
79 ; Test sign-extending 16-bit loads into mixtures of high and low registers.
80 define void @f4(i16 *%ptr1, i16 *%ptr2) {
81 ; CHECK-LABEL: f4:
82 ; CHECK-DAG: lhh [[REG1:%r[0-5]]], 0(%r2)
83 ; CHECK-DAG: lh [[REG2:%r[0-5]]], 0(%r3)
84 ; CHECK-DAG: lhh [[REG3:%r[0-5]]], 4096(%r2)
85 ; CHECK-DAG: lhy [[REG4:%r[0-5]]], 524286(%r3)
86 ; CHECK: blah [[REG1]], [[REG2]]
87 ; CHECK: br %r14
88   %ptr3 = getelementptr i16, i16 *%ptr1, i64 2048
89   %ptr4 = getelementptr i16, i16 *%ptr2, i64 262143
90   %val1 = load i16, i16 *%ptr1
91   %val2 = load i16, i16 *%ptr2
92   %val3 = load i16, i16 *%ptr3
93   %val4 = load i16, i16 *%ptr4
94   %ext1 = sext i16 %val1 to i32
95   %ext2 = sext i16 %val2 to i32
96   %ext3 = sext i16 %val3 to i32
97   %ext4 = sext i16 %val4 to i32
98   call void asm sideeffect "blah $0, $1, $2, $3",
99                            "h,r,h,r"(i32 %ext1, i32 %ext2, i32 %ext3, i32 %ext4)
100   ret void
103 ; Test zero-extending 8-bit loads into mixtures of high and low registers.
104 define void @f5(i8 *%ptr1, i8 *%ptr2) {
105 ; CHECK-LABEL: f5:
106 ; CHECK-DAG: llch [[REG1:%r[0-5]]], 0(%r2)
107 ; CHECK-DAG: llc [[REG2:%r[0-5]]], 0(%r3)
108 ; CHECK-DAG: llch [[REG3:%r[0-5]]], 4096(%r2)
109 ; CHECK-DAG: llc [[REG4:%r[0-5]]], 524287(%r3)
110 ; CHECK: blah [[REG1]], [[REG2]]
111 ; CHECK: br %r14
112   %ptr3 = getelementptr i8, i8 *%ptr1, i64 4096
113   %ptr4 = getelementptr i8, i8 *%ptr2, i64 524287
114   %val1 = load i8, i8 *%ptr1
115   %val2 = load i8, i8 *%ptr2
116   %val3 = load i8, i8 *%ptr3
117   %val4 = load i8, i8 *%ptr4
118   %ext1 = zext i8 %val1 to i32
119   %ext2 = zext i8 %val2 to i32
120   %ext3 = zext i8 %val3 to i32
121   %ext4 = zext i8 %val4 to i32
122   call void asm sideeffect "blah $0, $1, $2, $3",
123                            "h,r,h,r"(i32 %ext1, i32 %ext2, i32 %ext3, i32 %ext4)
124   ret void
127 ; Test zero-extending 16-bit loads into mixtures of high and low registers.
128 define void @f6(i16 *%ptr1, i16 *%ptr2) {
129 ; CHECK-LABEL: f6:
130 ; CHECK-DAG: llhh [[REG1:%r[0-5]]], 0(%r2)
131 ; CHECK-DAG: llh [[REG2:%r[0-5]]], 0(%r3)
132 ; CHECK-DAG: llhh [[REG3:%r[0-5]]], 4096(%r2)
133 ; CHECK-DAG: llh [[REG4:%r[0-5]]], 524286(%r3)
134 ; CHECK: blah [[REG1]], [[REG2]]
135 ; CHECK: br %r14
136   %ptr3 = getelementptr i16, i16 *%ptr1, i64 2048
137   %ptr4 = getelementptr i16, i16 *%ptr2, i64 262143
138   %val1 = load i16, i16 *%ptr1
139   %val2 = load i16, i16 *%ptr2
140   %val3 = load i16, i16 *%ptr3
141   %val4 = load i16, i16 *%ptr4
142   %ext1 = zext i16 %val1 to i32
143   %ext2 = zext i16 %val2 to i32
144   %ext3 = zext i16 %val3 to i32
145   %ext4 = zext i16 %val4 to i32
146   call void asm sideeffect "blah $0, $1, $2, $3",
147                            "h,r,h,r"(i32 %ext1, i32 %ext2, i32 %ext3, i32 %ext4)
148   ret void
151 ; Test truncating stores of high and low registers into 8-bit memory.
152 define void @f7(i8 *%ptr1, i8 *%ptr2) {
153 ; CHECK-LABEL: f7:
154 ; CHECK: blah [[REG1:%r[0-5]]], [[REG2:%r[0-5]]]
155 ; CHECK-DAG: stch [[REG1]], 0(%r2)
156 ; CHECK-DAG: stc [[REG2]], 0(%r3)
157 ; CHECK-DAG: stch [[REG1]], 4096(%r2)
158 ; CHECK-DAG: stcy [[REG2]], 524287(%r3)
159 ; CHECK: br %r14
160   %res = call { i32, i32 } asm "blah $0, $1", "=h,=r"()
161   %res1 = extractvalue { i32, i32 } %res, 0
162   %res2 = extractvalue { i32, i32 } %res, 1
163   %trunc1 = trunc i32 %res1 to i8
164   %trunc2 = trunc i32 %res2 to i8
165   %ptr3 = getelementptr i8, i8 *%ptr1, i64 4096
166   %ptr4 = getelementptr i8, i8 *%ptr2, i64 524287
167   store i8 %trunc1, i8 *%ptr1
168   store i8 %trunc2, i8 *%ptr2
169   store i8 %trunc1, i8 *%ptr3
170   store i8 %trunc2, i8 *%ptr4
171   ret void
174 ; Test truncating stores of high and low registers into 16-bit memory.
175 define void @f8(i16 *%ptr1, i16 *%ptr2) {
176 ; CHECK-LABEL: f8:
177 ; CHECK: blah [[REG1:%r[0-5]]], [[REG2:%r[0-5]]]
178 ; CHECK-DAG: sthh [[REG1]], 0(%r2)
179 ; CHECK-DAG: sth [[REG2]], 0(%r3)
180 ; CHECK-DAG: sthh [[REG1]], 4096(%r2)
181 ; CHECK-DAG: sthy [[REG2]], 524286(%r3)
182 ; CHECK: br %r14
183   %res = call { i32, i32 } asm "blah $0, $1", "=h,=r"()
184   %res1 = extractvalue { i32, i32 } %res, 0
185   %res2 = extractvalue { i32, i32 } %res, 1
186   %trunc1 = trunc i32 %res1 to i16
187   %trunc2 = trunc i32 %res2 to i16
188   %ptr3 = getelementptr i16, i16 *%ptr1, i64 2048
189   %ptr4 = getelementptr i16, i16 *%ptr2, i64 262143
190   store i16 %trunc1, i16 *%ptr1
191   store i16 %trunc2, i16 *%ptr2
192   store i16 %trunc1, i16 *%ptr3
193   store i16 %trunc2, i16 *%ptr4
194   ret void
197 ; Test zero extensions from 8 bits between mixtures of high and low registers.
198 define i32 @f9(i8 %val1, i8 %val2) {
199 ; CHECK-LABEL: f9:
200 ; CHECK-DAG: risbhg [[REG1:%r[0-5]]], %r2, 24, 159, 32
201 ; CHECK-DAG: llcr [[REG2:%r[0-5]]], %r3
202 ; CHECK: stepa [[REG1]], [[REG2]]
203 ; CHECK: risbhg [[REG3:%r[0-5]]], [[REG1]], 24, 159, 0
204 ; CHECK: stepb [[REG3]]
205 ; CHECK: risblg %r2, [[REG3]], 24, 159, 32
206 ; CHECK: br %r14
207   %ext1 = zext i8 %val1 to i32
208   %ext2 = zext i8 %val2 to i32
209   %val3 = call i8 asm sideeffect "stepa $0, $1", "=h,0,r"(i32 %ext1, i32 %ext2)
210   %ext3 = zext i8 %val3 to i32
211   %val4 = call i8 asm sideeffect "stepb $0", "=h,0"(i32 %ext3)
212   %ext4 = zext i8 %val4 to i32
213   ret i32 %ext4
216 ; Test zero extensions from 16 bits between mixtures of high and low registers.
217 define i32 @f10(i16 %val1, i16 %val2) {
218 ; CHECK-LABEL: f10:
219 ; CHECK-DAG: risbhg [[REG1:%r[0-5]]], %r2, 16, 159, 32
220 ; CHECK-DAG: llhr [[REG2:%r[0-5]]], %r3
221 ; CHECK: stepa [[REG1]], [[REG2]]
222 ; CHECK: risbhg [[REG3:%r[0-5]]], [[REG1]], 16, 159, 0
223 ; CHECK: stepb [[REG3]]
224 ; CHECK: risblg %r2, [[REG3]], 16, 159, 32
225 ; CHECK: br %r14
226   %ext1 = zext i16 %val1 to i32
227   %ext2 = zext i16 %val2 to i32
228   %val3 = call i16 asm sideeffect "stepa $0, $1", "=h,0,r"(i32 %ext1, i32 %ext2)
229   %ext3 = zext i16 %val3 to i32
230   %val4 = call i16 asm sideeffect "stepb $0", "=h,0"(i32 %ext3)
231   %ext4 = zext i16 %val4 to i32
232   ret i32 %ext4
235 ; Test loads of 16-bit constants into mixtures of high and low registers.
236 define void @f11() {
237 ; CHECK-LABEL: f11:
238 ; CHECK-DAG: iihf [[REG1:%r[0-5]]], 4294934529
239 ; CHECK-DAG: lhi [[REG2:%r[0-5]]], -32768
240 ; CHECK-DAG: llihl [[REG3:%r[0-5]]], 32766
241 ; CHECK-DAG: lhi [[REG4:%r[0-5]]], 32767
242 ; CHECK: blah [[REG1]], [[REG2]], [[REG3]], [[REG4]]
243 ; CHECK: br %r14
244   call void asm sideeffect "blah $0, $1, $2, $3",
245                            "h,r,h,r"(i32 -32767, i32 -32768,
246                                      i32 32766, i32 32767)
247   ret void
250 ; Test loads of unsigned constants into mixtures of high and low registers.
251 ; For stepc, we expect the h and r operands to be paired by the register
252 ; allocator.  It doesn't really matter which comes first: LLILL/IIHF would
253 ; be just as good.
254 define void @f12() {
255 ; CHECK-LABEL: f12:
256 ; CHECK-DAG: llihl [[REG1:%r[0-5]]], 32768
257 ; CHECK-DAG: llihl [[REG2:%r[0-5]]], 65535
258 ; CHECK-DAG: llihh [[REG3:%r[0-5]]], 1
259 ; CHECK-DAG: llihh [[REG4:%r[0-5]]], 65535
260 ; CHECK: stepa [[REG1]], [[REG2]], [[REG3]], [[REG4]]
261 ; CHECK-DAG: llill [[REG1:%r[0-5]]], 32769
262 ; CHECK-DAG: llill [[REG2:%r[0-5]]], 65534
263 ; CHECK-DAG: llilh [[REG3:%r[0-5]]], 2
264 ; CHECK-DAG: llilh [[REG4:%r[0-5]]], 65534
265 ; CHECK: stepb [[REG1]], [[REG2]], [[REG3]], [[REG4]]
266 ; CHECK-DAG: llihl [[REG1:%r[0-5]]], 32770
267 ; CHECK-DAG: iilf [[REG1]], 65533
268 ; CHECK-DAG: llihh [[REG2:%r[0-5]]], 4
269 ; CHECK-DAG: iilf [[REG2]], 524288
270 ; CHECK: stepc [[REG1]], [[REG1]], [[REG2]], [[REG2]]
271 ; CHECK-DAG: iihf [[REG1:%r[0-5]]], 3294967296
272 ; CHECK-DAG: iilf [[REG2:%r[0-5]]], 4294567296
273 ; CHECK-DAG: iihf [[REG3:%r[0-5]]], 1000000000
274 ; CHECK-DAG: iilf [[REG4:%r[0-5]]], 400000
275 ; CHECK: stepd [[REG1]], [[REG2]], [[REG3]], [[REG4]]
276 ; CHECK: br %r14
277   call void asm sideeffect "stepa $0, $1, $2, $3",
278                            "h,h,h,h"(i32 32768, i32 65535,
279                                      i32 65536, i32 -65536)
280   call void asm sideeffect "stepb $0, $1, $2, $3",
281                            "r,r,r,r"(i32 32769, i32 65534,
282                                      i32 131072, i32 -131072)
283   call void asm sideeffect "stepc $0, $1, $2, $3",
284                            "h,r,h,r"(i32 32770, i32 65533,
285                                      i32 262144, i32 524288)
286   call void asm sideeffect "stepd $0, $1, $2, $3",
287                            "h,r,h,r"(i32 -1000000000, i32 -400000,
288                                      i32 1000000000, i32 400000)
289   ret void
292 ; Test selects involving high registers.
293 ; Note that we prefer to use a LOCR and move the result to a high register.
294 define void @f13(i32 %x, i32 %y) {
295 ; CHECK-LABEL: f13:
296 ; CHECK-DAG: chi %r2, 0
297 ; CHECK-DAG: iilf [[REG1:%r[0-5]]], 2102030405
298 ; CHECK-DAG: lhi [[REG2:%r[0-5]]], 0
299 ; CHECK: locre [[REG1]], [[REG2]]
300 ; CHECK: risbhg [[REG:%r[0-5]]], [[REG1]], 0, 159, 32
301 ; CHECK: blah [[REG]]
302 ; CHECK: br %r14
303   %cmp = icmp eq i32 %x, 0
304   %val = select i1 %cmp, i32 0, i32 2102030405
305   call void asm sideeffect "blah $0", "h"(i32 %val)
306   ret void
309 ; Test selects involving low registers.
310 define void @f14(i32 %x, i32 %y) {
311 ; CHECK-LABEL: f14:
312 ; CHECK-DAG: chi %r2, 0
313 ; CHECK-DAG: iilf [[REG:%r[0-5]]], 2102030405
314 ; CHECK-DAG: lhi [[REG1:%r[0-5]]], 0
315 ; CHECK: locre [[REG]], [[REG1]]
316 ; CHECK: blah [[REG]]
317 ; CHECK: br %r14
318   %cmp = icmp eq i32 %x, 0
319   %val = select i1 %cmp, i32 0, i32 2102030405
320   call void asm sideeffect "blah $0", "r"(i32 %val)
321   ret void
324 ; Test immediate insertion involving high registers.
325 define void @f15() {
326 ; CHECK-LABEL: f15:
327 ; CHECK: stepa [[REG:%r[0-5]]]
328 ; CHECK: iihh [[REG]], 4660
329 ; CHECK: stepb [[REG]]
330 ; CHECK: iihl [[REG]], 34661
331 ; CHECK: stepc [[REG]]
332 ; CHECK: br %r14
333   %res1 = call i32 asm "stepa $0", "=h"()
334   %and1 = and i32 %res1, 65535
335   %or1 = or i32 %and1, 305397760
336   %res2 = call i32 asm "stepb $0, $1", "=h,h"(i32 %or1)
337   %and2 = and i32 %res2, -65536
338   %or2 = or i32 %and2, 34661
339   call void asm sideeffect "stepc $0", "h"(i32 %or2)
340   ret void
343 ; Test immediate insertion involving low registers.
344 define void @f16() {
345 ; CHECK-LABEL: f16:
346 ; CHECK: stepa [[REG:%r[0-5]]]
347 ; CHECK: iilh [[REG]], 4660
348 ; CHECK: stepb [[REG]]
349 ; CHECK: iill [[REG]], 34661
350 ; CHECK: stepc [[REG]]
351 ; CHECK: br %r14
352   %res1 = call i32 asm "stepa $0", "=r"()
353   %and1 = and i32 %res1, 65535
354   %or1 = or i32 %and1, 305397760
355   %res2 = call i32 asm "stepb $0, $1", "=r,r"(i32 %or1)
356   %and2 = and i32 %res2, -65536
357   %or2 = or i32 %and2, 34661
358   call void asm sideeffect "stepc $0", "r"(i32 %or2)
359   ret void
362 ; Test immediate OR involving high registers.
363 define void @f17() {
364 ; CHECK-LABEL: f17:
365 ; CHECK: stepa [[REG:%r[0-5]]]
366 ; CHECK: oihh [[REG]], 4660
367 ; CHECK: stepb [[REG]]
368 ; CHECK: oihl [[REG]], 34661
369 ; CHECK: stepc [[REG]]
370 ; CHECK: oihf [[REG]], 12345678
371 ; CHECK: stepd [[REG]]
372 ; CHECK: br %r14
373   %res1 = call i32 asm "stepa $0", "=h"()
374   %or1 = or i32 %res1, 305397760
375   %res2 = call i32 asm "stepb $0, $1", "=h,h"(i32 %or1)
376   %or2 = or i32 %res2, 34661
377   %res3 = call i32 asm "stepc $0, $1", "=h,h"(i32 %or2)
378   %or3 = or i32 %res3, 12345678
379   call void asm sideeffect "stepd $0", "h"(i32 %or3)
380   ret void
383 ; Test immediate OR involving low registers.
384 define void @f18() {
385 ; CHECK-LABEL: f18:
386 ; CHECK: stepa [[REG:%r[0-5]]]
387 ; CHECK: oilh [[REG]], 4660
388 ; CHECK: stepb [[REG]]
389 ; CHECK: oill [[REG]], 34661
390 ; CHECK: stepc [[REG]]
391 ; CHECK: oilf [[REG]], 12345678
392 ; CHECK: stepd [[REG]]
393 ; CHECK: br %r14
394   %res1 = call i32 asm "stepa $0", "=r"()
395   %or1 = or i32 %res1, 305397760
396   %res2 = call i32 asm "stepb $0, $1", "=r,r"(i32 %or1)
397   %or2 = or i32 %res2, 34661
398   %res3 = call i32 asm "stepc $0, $1", "=r,r"(i32 %or2)
399   %or3 = or i32 %res3, 12345678
400   call void asm sideeffect "stepd $0", "r"(i32 %or3)
401   ret void
404 ; Test immediate XOR involving high registers.
405 define void @f19() {
406 ; CHECK-LABEL: f19:
407 ; CHECK: stepa [[REG:%r[0-5]]]
408 ; CHECK: xihf [[REG]], 305397760
409 ; CHECK: stepb [[REG]]
410 ; CHECK: xihf [[REG]], 34661
411 ; CHECK: stepc [[REG]]
412 ; CHECK: xihf [[REG]], 12345678
413 ; CHECK: stepd [[REG]]
414 ; CHECK: br %r14
415   %res1 = call i32 asm "stepa $0", "=h"()
416   %xor1 = xor i32 %res1, 305397760
417   %res2 = call i32 asm "stepb $0, $1", "=h,h"(i32 %xor1)
418   %xor2 = xor i32 %res2, 34661
419   %res3 = call i32 asm "stepc $0, $1", "=h,h"(i32 %xor2)
420   %xor3 = xor i32 %res3, 12345678
421   call void asm sideeffect "stepd $0", "h"(i32 %xor3)
422   ret void
425 ; Test immediate XOR involving low registers.
426 define void @f20() {
427 ; CHECK-LABEL: f20:
428 ; CHECK: stepa [[REG:%r[0-5]]]
429 ; CHECK: xilf [[REG]], 305397760
430 ; CHECK: stepb [[REG]]
431 ; CHECK: xilf [[REG]], 34661
432 ; CHECK: stepc [[REG]]
433 ; CHECK: xilf [[REG]], 12345678
434 ; CHECK: stepd [[REG]]
435 ; CHECK: br %r14
436   %res1 = call i32 asm "stepa $0", "=r"()
437   %xor1 = xor i32 %res1, 305397760
438   %res2 = call i32 asm "stepb $0, $1", "=r,r"(i32 %xor1)
439   %xor2 = xor i32 %res2, 34661
440   %res3 = call i32 asm "stepc $0, $1", "=r,r"(i32 %xor2)
441   %xor3 = xor i32 %res3, 12345678
442   call void asm sideeffect "stepd $0", "r"(i32 %xor3)
443   ret void
446 ; Test two-operand immediate AND involving high registers.
447 define void @f21() {
448 ; CHECK-LABEL: f21:
449 ; CHECK: stepa [[REG:%r[0-5]]]
450 ; CHECK: nihh [[REG]], 4096
451 ; CHECK: stepb [[REG]]
452 ; CHECK: nihl [[REG]], 57536
453 ; CHECK: stepc [[REG]]
454 ; CHECK: nihf [[REG]], 12345678
455 ; CHECK: stepd [[REG]]
456 ; CHECK: br %r14
457   %res1 = call i32 asm "stepa $0", "=h"()
458   %and1 = and i32 %res1, 268500991
459   %res2 = call i32 asm "stepb $0, $1", "=h,h"(i32 %and1)
460   %and2 = and i32 %res2, -8000
461   %res3 = call i32 asm "stepc $0, $1", "=h,h"(i32 %and2)
462   %and3 = and i32 %res3, 12345678
463   call void asm sideeffect "stepd $0", "h"(i32 %and3)
464   ret void
467 ; Test two-operand immediate AND involving low registers.
468 define void @f22() {
469 ; CHECK-LABEL: f22:
470 ; CHECK: stepa [[REG:%r[0-5]]]
471 ; CHECK: nilh [[REG]], 4096
472 ; CHECK: stepb [[REG]]
473 ; CHECK: nill [[REG]], 57536
474 ; CHECK: stepc [[REG]]
475 ; CHECK: nilf [[REG]], 12345678
476 ; CHECK: stepd [[REG]]
477 ; CHECK: br %r14
478   %res1 = call i32 asm "stepa $0", "=r"()
479   %and1 = and i32 %res1, 268500991
480   %res2 = call i32 asm "stepb $0, $1", "=r,r"(i32 %and1)
481   %and2 = and i32 %res2, -8000
482   %res3 = call i32 asm "stepc $0, $1", "=r,r"(i32 %and2)
483   %and3 = and i32 %res3, 12345678
484   call void asm sideeffect "stepd $0", "r"(i32 %and3)
485   ret void
488 ; Test three-operand immediate AND involving mixtures of low and high registers.
489 define i32 @f23(i32 %old) {
490 ; CHECK-LABEL: f23:
491 ; CHECK-DAG: risblg [[REG1:%r[0-5]]], %r2, 28, 158, 0
492 ; CHECK-DAG: risbhg [[REG2:%r[0-5]]], %r2, 24, 158, 32
493 ; CHECK: stepa %r2, [[REG1]], [[REG2]]
494 ; CHECK-DAG: risbhg [[REG3:%r[0-5]]], [[REG2]], 25, 159, 0
495 ; CHECK-DAG: risblg %r2, [[REG2]], 24, 152, 32
496 ; CHECK: stepb [[REG2]], [[REG3]], %r2
497 ; CHECK: br %r14
498   %and1 = and i32 %old, 14
499   %and2 = and i32 %old, 254
500   %res1 = call i32 asm "stepa $1, $2, $3",
501                        "=h,r,r,0"(i32 %old, i32 %and1, i32 %and2)
502   %and3 = and i32 %res1, 127
503   %and4 = and i32 %res1, 128
504   %res2 = call i32 asm "stepb $1, $2, $3",
505                        "=r,h,h,0"(i32 %res1, i32 %and3, i32 %and4)
506   ret i32 %res2
509 ; Test RISB[LH]G insertions involving mixtures of high and low registers.
510 define i32 @f24(i32 %old) {
511 ; CHECK-LABEL: f24:
512 ; CHECK-DAG: risblg [[REG1:%r[0-5]]], %r2, 28, 158, 1
513 ; CHECK-DAG: risbhg [[REG2:%r[0-5]]], %r2, 24, 158, 29
514 ; CHECK: stepa %r2, [[REG1]], [[REG2]]
515 ; CHECK-DAG: risbhg [[REG3:%r[0-5]]], [[REG2]], 25, 159, 62
516 ; CHECK-DAG: risblg %r2, [[REG2]], 24, 152, 37
517 ; CHECK: stepb [[REG2]], [[REG3]], %r2
518 ; CHECK: br %r14
519   %shift1 = shl i32 %old, 1
520   %and1 = and i32 %shift1, 14
521   %shift2 = lshr i32 %old, 3
522   %and2 = and i32 %shift2, 254
523   %res1 = call i32 asm "stepa $1, $2, $3",
524                        "=h,r,r,0"(i32 %old, i32 %and1, i32 %and2)
525   %shift3 = lshr i32 %res1, 2
526   %and3 = and i32 %shift3, 127
527   %shift4 = shl i32 %res1, 5
528   %and4 = and i32 %shift4, 128
529   %res2 = call i32 asm "stepb $1, $2, $3",
530                        "=r,h,h,0"(i32 %res1, i32 %and3, i32 %and4)
531   ret i32 %res2
534 ; Test TMxx involving mixtures of high and low registers.
535 define i32 @f25(i32 %old) {
536 ; CHECK-LABEL: f25:
537 ; CHECK-DAG: tmll %r2, 1
538 ; CHECK-DAG: tmlh %r2, 1
539 ; CHECK: stepa [[REG1:%r[0-5]]],
540 ; CHECK-DAG: tmhl [[REG1]], 1
541 ; CHECK-DAG: tmhh [[REG1]], 1
542 ; CHECK: stepb %r2,
543 ; CHECK: br %r14
544   %and1 = and i32 %old, 1
545   %and2 = and i32 %old, 65536
546   %cmp1 = icmp eq i32 %and1, 0
547   %cmp2 = icmp eq i32 %and2, 0
548   %sel1 = select i1 %cmp1, i32 100, i32 200
549   %sel2 = select i1 %cmp2, i32 100, i32 200
550   %res1 = call i32 asm "stepa $0, $1, $2",
551                        "=h,r,r"(i32 %sel1, i32 %sel2)
552   %and3 = and i32 %res1, 1
553   %and4 = and i32 %res1, 65536
554   %cmp3 = icmp eq i32 %and3, 0
555   %cmp4 = icmp eq i32 %and4, 0
556   %sel3 = select i1 %cmp3, i32 100, i32 200
557   %sel4 = select i1 %cmp4, i32 100, i32 200
558   %res2 = call i32 asm "stepb $0, $1, $2",
559                        "=r,h,h"(i32 %sel3, i32 %sel4)
560   ret i32 %res2
563 ; Test two-operand halfword immediate addition involving high registers.
564 define void @f26() {
565 ; CHECK-LABEL: f26:
566 ; CHECK: stepa [[REG:%r[0-5]]]
567 ; CHECK: aih [[REG]], -32768
568 ; CHECK: stepb [[REG]]
569 ; CHECK: aih [[REG]], 1
570 ; CHECK: stepc [[REG]]
571 ; CHECK: aih [[REG]], 32767
572 ; CHECK: stepd [[REG]]
573 ; CHECK: br %r14
574   %res1 = call i32 asm "stepa $0", "=h"()
575   %add1 = add i32 %res1, -32768
576   %res2 = call i32 asm "stepb $0, $1", "=h,h"(i32 %add1)
577   %add2 = add i32 %res2, 1
578   %res3 = call i32 asm "stepc $0, $1", "=h,h"(i32 %add2)
579   %add3 = add i32 %res3, 32767
580   call void asm sideeffect "stepd $0", "h"(i32 %add3)
581   ret void
584 ; Test two-operand halfword immediate addition involving low registers.
585 define void @f27() {
586 ; CHECK-LABEL: f27:
587 ; CHECK: stepa [[REG:%r[0-5]]]
588 ; CHECK: ahi [[REG]], -32768
589 ; CHECK: stepb [[REG]]
590 ; CHECK: ahi [[REG]], 1
591 ; CHECK: stepc [[REG]]
592 ; CHECK: ahi [[REG]], 32767
593 ; CHECK: stepd [[REG]]
594 ; CHECK: br %r14
595   %res1 = call i32 asm "stepa $0", "=r"()
596   %add1 = add i32 %res1, -32768
597   %res2 = call i32 asm "stepb $0, $1", "=r,r"(i32 %add1)
598   %add2 = add i32 %res2, 1
599   %res3 = call i32 asm "stepc $0, $1", "=r,r"(i32 %add2)
600   %add3 = add i32 %res3, 32767
601   call void asm sideeffect "stepd $0", "r"(i32 %add3)
602   ret void
605 ; Test three-operand halfword immediate addition involving mixtures of low
606 ; and high registers.  AHIK/RISBHG would be OK too, instead of RISBHG/AIH.
607 define i32 @f28(i32 %old) {
608 ; CHECK-LABEL: f28:
609 ; CHECK: ahik [[REG1:%r[0-5]]], %r2, 14
610 ; CHECK: stepa %r2, [[REG1]]
611 ; CHECK: risbhg  [[REG1]], [[REG1]], 0, 159, 32
612 ; CHECK: aih     [[REG1]], 254
613 ; CHECK: stepb [[REG1]], [[REG2]]
614 ; CHECK: risbhg [[REG3:%r[0-5]]], [[REG2]], 0, 159, 0
615 ; CHECK: aih [[REG3]], 127
616 ; CHECK: stepc [[REG2]], [[REG3]]
617 ; CHECK: risblg %r2, [[REG3]], 0, 159, 32
618 ; CHECK: ahi %r2, 128
619 ; CHECK: stepd [[REG3]], %r2
620 ; CHECK: br %r14
621   %add1 = add i32 %old, 14
622   %res1 = call i32 asm "stepa $1, $2",
623                        "=r,r,0"(i32 %old, i32 %add1)
624   %add2 = add i32 %res1, 254
625   %res2 = call i32 asm "stepb $1, $2",
626                        "=h,r,0"(i32 %res1, i32 %add2)
627   %add3 = add i32 %res2, 127
628   %res3 = call i32 asm "stepc $1, $2",
629                        "=h,h,0"(i32 %res2, i32 %add3)
630   %add4 = add i32 %res3, 128
631   %res4 = call i32 asm "stepd $1, $2",
632                        "=r,h,0"(i32 %res3, i32 %add4)
633   ret i32 %res4
636 ; Test large immediate addition involving high registers.
637 define void @f29() {
638 ; CHECK-LABEL: f29:
639 ; CHECK: stepa [[REG:%r[0-5]]]
640 ; CHECK: aih [[REG]], -32769
641 ; CHECK: stepb [[REG]]
642 ; CHECK: aih [[REG]], 32768
643 ; CHECK: stepc [[REG]]
644 ; CHECK: aih [[REG]], 1000000000
645 ; CHECK: stepd [[REG]]
646 ; CHECK: br %r14
647   %res1 = call i32 asm "stepa $0", "=h"()
648   %add1 = add i32 %res1, -32769
649   %res2 = call i32 asm "stepb $0, $1", "=h,h"(i32 %add1)
650   %add2 = add i32 %res2, 32768
651   %res3 = call i32 asm "stepc $0, $1", "=h,h"(i32 %add2)
652   %add3 = add i32 %res3, 1000000000
653   call void asm sideeffect "stepd $0", "h"(i32 %add3)
654   ret void
657 ; Test large immediate addition involving low registers.
658 define void @f30() {
659 ; CHECK-LABEL: f30:
660 ; CHECK: stepa [[REG:%r[0-5]]]
661 ; CHECK: afi [[REG]], -32769
662 ; CHECK: stepb [[REG]]
663 ; CHECK: afi [[REG]], 32768
664 ; CHECK: stepc [[REG]]
665 ; CHECK: afi [[REG]], 1000000000
666 ; CHECK: stepd [[REG]]
667 ; CHECK: br %r14
668   %res1 = call i32 asm "stepa $0", "=r"()
669   %add1 = add i32 %res1, -32769
670   %res2 = call i32 asm "stepb $0, $1", "=r,r"(i32 %add1)
671   %add2 = add i32 %res2, 32768
672   %res3 = call i32 asm "stepc $0, $1", "=r,r"(i32 %add2)
673   %add3 = add i32 %res3, 1000000000
674   call void asm sideeffect "stepd $0", "r"(i32 %add3)
675   ret void
678 ; Test large immediate comparison involving high registers.
679 define i32 @f31() {
680 ; CHECK-LABEL: f31:
681 ; CHECK: stepa [[REG1:%r[0-5]]]
682 ; CHECK: cih [[REG1]], 1000000000
683 ; CHECK: stepb [[REG2:%r[0-5]]]
684 ; CHECK: clih [[REG2]], 1000000000
685 ; CHECK: br %r14
686   %res1 = call i32 asm "stepa $0", "=h"()
687   %cmp1 = icmp sle i32 %res1, 1000000000
688   %sel1 = select i1 %cmp1, i32 0, i32 1
689   %res2 = call i32 asm "stepb $0, $1", "=h,r"(i32 %sel1)
690   %cmp2 = icmp ule i32 %res2, 1000000000
691   %sel2 = select i1 %cmp2, i32 0, i32 1
692   ret i32 %sel2
695 ; Test large immediate comparison involving low registers.
696 define i32 @f32() {
697 ; CHECK-LABEL: f32:
698 ; CHECK: stepa [[REG1:%r[0-5]]]
699 ; CHECK: cfi [[REG1]], 1000000000
700 ; CHECK: stepb [[REG2:%r[0-5]]]
701 ; CHECK: clfi [[REG2]], 1000000000
702 ; CHECK: br %r14
703   %res1 = call i32 asm "stepa $0", "=r"()
704   %cmp1 = icmp sle i32 %res1, 1000000000
705   %sel1 = select i1 %cmp1, i32 0, i32 1
706   %res2 = call i32 asm "stepb $0, $1", "=r,r"(i32 %sel1)
707   %cmp2 = icmp ule i32 %res2, 1000000000
708   %sel2 = select i1 %cmp2, i32 0, i32 1
709   ret i32 %sel2
712 ; Test memory comparison involving high registers.
713 define void @f33(i32 *%ptr1, i32 *%ptr2) {
714 ; CHECK-LABEL: f33:
715 ; CHECK: stepa [[REG1:%r[0-5]]]
716 ; CHECK: chf [[REG1]], 0(%r2)
717 ; CHECK: stepb [[REG2:%r[0-5]]]
718 ; CHECK: clhf [[REG2]], 0(%r3)
719 ; CHECK: br %r14
720   %res1 = call i32 asm "stepa $0", "=h"()
721   %load1 = load i32, i32 *%ptr1
722   %cmp1 = icmp sle i32 %res1, %load1
723   %sel1 = select i1 %cmp1, i32 0, i32 1
724   %res2 = call i32 asm "stepb $0, $1", "=h,r"(i32 %sel1)
725   %load2 = load i32, i32 *%ptr2
726   %cmp2 = icmp ule i32 %res2, %load2
727   %sel2 = select i1 %cmp2, i32 0, i32 1
728   store i32 %sel2, i32 *%ptr1
729   ret void
732 ; Test memory comparison involving low registers.
733 define void @f34(i32 *%ptr1, i32 *%ptr2) {
734 ; CHECK-LABEL: f34:
735 ; CHECK: stepa [[REG1:%r[0-5]]]
736 ; CHECK: c [[REG1]], 0(%r2)
737 ; CHECK: stepb [[REG2:%r[0-5]]]
738 ; CHECK: cl [[REG2]], 0(%r3)
739 ; CHECK: br %r14
740   %res1 = call i32 asm "stepa $0", "=r"()
741   %load1 = load i32, i32 *%ptr1
742   %cmp1 = icmp sle i32 %res1, %load1
743   %sel1 = select i1 %cmp1, i32 0, i32 1
744   %res2 = call i32 asm "stepb $0, $1", "=r,r"(i32 %sel1)
745   %load2 = load i32, i32 *%ptr2
746   %cmp2 = icmp ule i32 %res2, %load2
747   %sel2 = select i1 %cmp2, i32 0, i32 1
748   store i32 %sel2, i32 *%ptr1
749   ret void
752 ; Test immediate addition with overflow involving high registers.
753 define void @f35() {
754 ; CHECK-LABEL: f35:
755 ; CHECK: stepa [[REG:%r[0-5]]]
756 ; CHECK: aih [[REG]], -32768
757 ; CHECK: ipm [[REGCC:%r[0-5]]]
758 ; CHECK: afi [[REGCC]], 1342177280
759 ; CHECK: srl [[REGCC]], 31
760 ; CHECK: stepb [[REG]], [[REGCC]]
761 ; CHECK: aih [[REG]], 1
762 ; CHECK: ipm [[REGCC:%r[0-5]]]
763 ; CHECK: afi [[REGCC]], 1342177280
764 ; CHECK: srl [[REGCC]], 31
765 ; CHECK: stepc [[REG]], [[REGCC]]
766 ; CHECK: aih [[REG]], 32767
767 ; CHECK: ipm [[REGCC:%r[0-5]]]
768 ; CHECK: afi [[REGCC]], 1342177280
769 ; CHECK: srl [[REGCC]], 31
770 ; CHECK: stepd [[REG]], [[REGCC]]
771 ; CHECK: br %r14
772   %res1 = call i32 asm "stepa $0", "=h"()
773   %t1 = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %res1, i32 -32768)
774   %val1 = extractvalue {i32, i1} %t1, 0
775   %obit1 = extractvalue {i32, i1} %t1, 1
776   %res2 = call i32 asm "stepb $0, $2", "=h,h,d"(i32 %val1, i1 %obit1)
777   %t2 = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %res2, i32 1)
778   %val2 = extractvalue {i32, i1} %t2, 0
779   %obit2 = extractvalue {i32, i1} %t2, 1
780   %res3 = call i32 asm "stepc $0, $2", "=h,h,d"(i32 %val2, i1 %obit2)
781   %t3 = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %res3, i32 32767)
782   %val3 = extractvalue {i32, i1} %t3, 0
783   %obit3 = extractvalue {i32, i1} %t3, 1
784   call void asm sideeffect "stepd $0, $1", "h,d"(i32 %val3, i1 %obit3)
785   ret void
788 ; Test large immediate addition with overflow involving high registers.
789 define void @f36() {
790 ; CHECK-LABEL: f36:
791 ; CHECK: stepa [[REG:%r[0-5]]]
792 ; CHECK: aih [[REG]], -2147483648
793 ; CHECK: ipm [[REGCC:%r[0-5]]]
794 ; CHECK: afi [[REGCC]], 1342177280
795 ; CHECK: srl [[REGCC]], 31
796 ; CHECK: stepb [[REG]], [[REGCC]]
797 ; CHECK: aih [[REG]], 1
798 ; CHECK: ipm [[REGCC:%r[0-5]]]
799 ; CHECK: afi [[REGCC]], 1342177280
800 ; CHECK: srl [[REGCC]], 31
801 ; CHECK: stepc [[REG]], [[REGCC]]
802 ; CHECK: aih [[REG]], 2147483647
803 ; CHECK: ipm [[REGCC:%r[0-5]]]
804 ; CHECK: afi [[REGCC]], 1342177280
805 ; CHECK: srl [[REGCC]], 31
806 ; CHECK: stepd [[REG]], [[REGCC]]
807 ; CHECK: br %r14
808   %res1 = call i32 asm "stepa $0", "=h"()
809   %t1 = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %res1, i32 -2147483648)
810   %val1 = extractvalue {i32, i1} %t1, 0
811   %obit1 = extractvalue {i32, i1} %t1, 1
812   %res2 = call i32 asm "stepb $0, $2", "=h,h,d"(i32 %val1, i1 %obit1)
813   %t2 = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %res2, i32 1)
814   %val2 = extractvalue {i32, i1} %t2, 0
815   %obit2 = extractvalue {i32, i1} %t2, 1
816   %res3 = call i32 asm "stepc $0, $2", "=h,h,d"(i32 %val2, i1 %obit2)
817   %t3 = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %res3, i32 2147483647)
818   %val3 = extractvalue {i32, i1} %t3, 0
819   %obit3 = extractvalue {i32, i1} %t3, 1
820   call void asm sideeffect "stepd $0, $1", "h,d"(i32 %val3, i1 %obit3)
821   ret void
824 declare {i32, i1} @llvm.sadd.with.overflow.i32(i32, i32) nounwind readnone