xref: /aosp_15_r20/external/llvm/test/CodeGen/SystemZ/cond-store-02.ll (revision 9880d6810fe72a1726cb53787c6711e909410d58)
1*9880d681SAndroid Build Coastguard Worker; Test 16-bit conditional stores that are presented as selects.  The volatile
2*9880d681SAndroid Build Coastguard Worker; tests require z10, which use a branch instead of a LOCR.
3*9880d681SAndroid Build Coastguard Worker;
4*9880d681SAndroid Build Coastguard Worker; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z10 | FileCheck %s
5*9880d681SAndroid Build Coastguard Worker
6*9880d681SAndroid Build Coastguard Workerdeclare void @foo(i16 *)
7*9880d681SAndroid Build Coastguard Worker
8*9880d681SAndroid Build Coastguard Worker; Test the simple case, with the loaded value first.
9*9880d681SAndroid Build Coastguard Workerdefine void @f1(i16 *%ptr, i16 %alt, i32 %limit) {
10*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f1:
11*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: %r2
12*9880d681SAndroid Build Coastguard Worker; CHECK: blr %r14
13*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: %r2
14*9880d681SAndroid Build Coastguard Worker; CHECK: sth %r3, 0(%r2)
15*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14
16*9880d681SAndroid Build Coastguard Worker  %cond = icmp ult i32 %limit, 420
17*9880d681SAndroid Build Coastguard Worker  %orig = load i16 , i16 *%ptr
18*9880d681SAndroid Build Coastguard Worker  %res = select i1 %cond, i16 %orig, i16 %alt
19*9880d681SAndroid Build Coastguard Worker  store i16 %res, i16 *%ptr
20*9880d681SAndroid Build Coastguard Worker  ret void
21*9880d681SAndroid Build Coastguard Worker}
22*9880d681SAndroid Build Coastguard Worker
23*9880d681SAndroid Build Coastguard Worker; ...and with the loaded value second
24*9880d681SAndroid Build Coastguard Workerdefine void @f2(i16 *%ptr, i16 %alt, i32 %limit) {
25*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f2:
26*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: %r2
27*9880d681SAndroid Build Coastguard Worker; CHECK: bher %r14
28*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: %r2
29*9880d681SAndroid Build Coastguard Worker; CHECK: sth %r3, 0(%r2)
30*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14
31*9880d681SAndroid Build Coastguard Worker  %cond = icmp ult i32 %limit, 420
32*9880d681SAndroid Build Coastguard Worker  %orig = load i16 , i16 *%ptr
33*9880d681SAndroid Build Coastguard Worker  %res = select i1 %cond, i16 %alt, i16 %orig
34*9880d681SAndroid Build Coastguard Worker  store i16 %res, i16 *%ptr
35*9880d681SAndroid Build Coastguard Worker  ret void
36*9880d681SAndroid Build Coastguard Worker}
37*9880d681SAndroid Build Coastguard Worker
38*9880d681SAndroid Build Coastguard Worker; Test cases where the value is explicitly sign-extended to 32 bits, with the
39*9880d681SAndroid Build Coastguard Worker; loaded value first.
40*9880d681SAndroid Build Coastguard Workerdefine void @f3(i16 *%ptr, i32 %alt, i32 %limit) {
41*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f3:
42*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: %r2
43*9880d681SAndroid Build Coastguard Worker; CHECK: blr %r14
44*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: %r2
45*9880d681SAndroid Build Coastguard Worker; CHECK: sth %r3, 0(%r2)
46*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14
47*9880d681SAndroid Build Coastguard Worker  %cond = icmp ult i32 %limit, 420
48*9880d681SAndroid Build Coastguard Worker  %orig = load i16 , i16 *%ptr
49*9880d681SAndroid Build Coastguard Worker  %ext = sext i16 %orig to i32
50*9880d681SAndroid Build Coastguard Worker  %res = select i1 %cond, i32 %ext, i32 %alt
51*9880d681SAndroid Build Coastguard Worker  %trunc = trunc i32 %res to i16
52*9880d681SAndroid Build Coastguard Worker  store i16 %trunc, i16 *%ptr
53*9880d681SAndroid Build Coastguard Worker  ret void
54*9880d681SAndroid Build Coastguard Worker}
55*9880d681SAndroid Build Coastguard Worker
56*9880d681SAndroid Build Coastguard Worker; ...and with the loaded value second
57*9880d681SAndroid Build Coastguard Workerdefine void @f4(i16 *%ptr, i32 %alt, i32 %limit) {
58*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f4:
59*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: %r2
60*9880d681SAndroid Build Coastguard Worker; CHECK: bher %r14
61*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: %r2
62*9880d681SAndroid Build Coastguard Worker; CHECK: sth %r3, 0(%r2)
63*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14
64*9880d681SAndroid Build Coastguard Worker  %cond = icmp ult i32 %limit, 420
65*9880d681SAndroid Build Coastguard Worker  %orig = load i16 , i16 *%ptr
66*9880d681SAndroid Build Coastguard Worker  %ext = sext i16 %orig to i32
67*9880d681SAndroid Build Coastguard Worker  %res = select i1 %cond, i32 %alt, i32 %ext
68*9880d681SAndroid Build Coastguard Worker  %trunc = trunc i32 %res to i16
69*9880d681SAndroid Build Coastguard Worker  store i16 %trunc, i16 *%ptr
70*9880d681SAndroid Build Coastguard Worker  ret void
71*9880d681SAndroid Build Coastguard Worker}
72*9880d681SAndroid Build Coastguard Worker
73*9880d681SAndroid Build Coastguard Worker; Test cases where the value is explicitly zero-extended to 32 bits, with the
74*9880d681SAndroid Build Coastguard Worker; loaded value first.
75*9880d681SAndroid Build Coastguard Workerdefine void @f5(i16 *%ptr, i32 %alt, i32 %limit) {
76*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f5:
77*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: %r2
78*9880d681SAndroid Build Coastguard Worker; CHECK: blr %r14
79*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: %r2
80*9880d681SAndroid Build Coastguard Worker; CHECK: sth %r3, 0(%r2)
81*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14
82*9880d681SAndroid Build Coastguard Worker  %cond = icmp ult i32 %limit, 420
83*9880d681SAndroid Build Coastguard Worker  %orig = load i16 , i16 *%ptr
84*9880d681SAndroid Build Coastguard Worker  %ext = zext i16 %orig to i32
85*9880d681SAndroid Build Coastguard Worker  %res = select i1 %cond, i32 %ext, i32 %alt
86*9880d681SAndroid Build Coastguard Worker  %trunc = trunc i32 %res to i16
87*9880d681SAndroid Build Coastguard Worker  store i16 %trunc, i16 *%ptr
88*9880d681SAndroid Build Coastguard Worker  ret void
89*9880d681SAndroid Build Coastguard Worker}
90*9880d681SAndroid Build Coastguard Worker
91*9880d681SAndroid Build Coastguard Worker; ...and with the loaded value second
92*9880d681SAndroid Build Coastguard Workerdefine void @f6(i16 *%ptr, i32 %alt, i32 %limit) {
93*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f6:
94*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: %r2
95*9880d681SAndroid Build Coastguard Worker; CHECK: bher %r14
96*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: %r2
97*9880d681SAndroid Build Coastguard Worker; CHECK: sth %r3, 0(%r2)
98*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14
99*9880d681SAndroid Build Coastguard Worker  %cond = icmp ult i32 %limit, 420
100*9880d681SAndroid Build Coastguard Worker  %orig = load i16 , i16 *%ptr
101*9880d681SAndroid Build Coastguard Worker  %ext = zext i16 %orig to i32
102*9880d681SAndroid Build Coastguard Worker  %res = select i1 %cond, i32 %alt, i32 %ext
103*9880d681SAndroid Build Coastguard Worker  %trunc = trunc i32 %res to i16
104*9880d681SAndroid Build Coastguard Worker  store i16 %trunc, i16 *%ptr
105*9880d681SAndroid Build Coastguard Worker  ret void
106*9880d681SAndroid Build Coastguard Worker}
107*9880d681SAndroid Build Coastguard Worker
108*9880d681SAndroid Build Coastguard Worker; Test cases where the value is explicitly sign-extended to 64 bits, with the
109*9880d681SAndroid Build Coastguard Worker; loaded value first.
110*9880d681SAndroid Build Coastguard Workerdefine void @f7(i16 *%ptr, i64 %alt, i32 %limit) {
111*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f7:
112*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: %r2
113*9880d681SAndroid Build Coastguard Worker; CHECK: blr %r14
114*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: %r2
115*9880d681SAndroid Build Coastguard Worker; CHECK: sth %r3, 0(%r2)
116*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14
117*9880d681SAndroid Build Coastguard Worker  %cond = icmp ult i32 %limit, 420
118*9880d681SAndroid Build Coastguard Worker  %orig = load i16 , i16 *%ptr
119*9880d681SAndroid Build Coastguard Worker  %ext = sext i16 %orig to i64
120*9880d681SAndroid Build Coastguard Worker  %res = select i1 %cond, i64 %ext, i64 %alt
121*9880d681SAndroid Build Coastguard Worker  %trunc = trunc i64 %res to i16
122*9880d681SAndroid Build Coastguard Worker  store i16 %trunc, i16 *%ptr
123*9880d681SAndroid Build Coastguard Worker  ret void
124*9880d681SAndroid Build Coastguard Worker}
125*9880d681SAndroid Build Coastguard Worker
126*9880d681SAndroid Build Coastguard Worker; ...and with the loaded value second
127*9880d681SAndroid Build Coastguard Workerdefine void @f8(i16 *%ptr, i64 %alt, i32 %limit) {
128*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f8:
129*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: %r2
130*9880d681SAndroid Build Coastguard Worker; CHECK: bher %r14
131*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: %r2
132*9880d681SAndroid Build Coastguard Worker; CHECK: sth %r3, 0(%r2)
133*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14
134*9880d681SAndroid Build Coastguard Worker  %cond = icmp ult i32 %limit, 420
135*9880d681SAndroid Build Coastguard Worker  %orig = load i16 , i16 *%ptr
136*9880d681SAndroid Build Coastguard Worker  %ext = sext i16 %orig to i64
137*9880d681SAndroid Build Coastguard Worker  %res = select i1 %cond, i64 %alt, i64 %ext
138*9880d681SAndroid Build Coastguard Worker  %trunc = trunc i64 %res to i16
139*9880d681SAndroid Build Coastguard Worker  store i16 %trunc, i16 *%ptr
140*9880d681SAndroid Build Coastguard Worker  ret void
141*9880d681SAndroid Build Coastguard Worker}
142*9880d681SAndroid Build Coastguard Worker
143*9880d681SAndroid Build Coastguard Worker; Test cases where the value is explicitly zero-extended to 64 bits, with the
144*9880d681SAndroid Build Coastguard Worker; loaded value first.
145*9880d681SAndroid Build Coastguard Workerdefine void @f9(i16 *%ptr, i64 %alt, i32 %limit) {
146*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f9:
147*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: %r2
148*9880d681SAndroid Build Coastguard Worker; CHECK: blr %r14
149*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: %r2
150*9880d681SAndroid Build Coastguard Worker; CHECK: sth %r3, 0(%r2)
151*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14
152*9880d681SAndroid Build Coastguard Worker  %cond = icmp ult i32 %limit, 420
153*9880d681SAndroid Build Coastguard Worker  %orig = load i16 , i16 *%ptr
154*9880d681SAndroid Build Coastguard Worker  %ext = zext i16 %orig to i64
155*9880d681SAndroid Build Coastguard Worker  %res = select i1 %cond, i64 %ext, i64 %alt
156*9880d681SAndroid Build Coastguard Worker  %trunc = trunc i64 %res to i16
157*9880d681SAndroid Build Coastguard Worker  store i16 %trunc, i16 *%ptr
158*9880d681SAndroid Build Coastguard Worker  ret void
159*9880d681SAndroid Build Coastguard Worker}
160*9880d681SAndroid Build Coastguard Worker
161*9880d681SAndroid Build Coastguard Worker; ...and with the loaded value second
162*9880d681SAndroid Build Coastguard Workerdefine void @f10(i16 *%ptr, i64 %alt, i32 %limit) {
163*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f10:
164*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: %r2
165*9880d681SAndroid Build Coastguard Worker; CHECK: bher %r14
166*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: %r2
167*9880d681SAndroid Build Coastguard Worker; CHECK: sth %r3, 0(%r2)
168*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14
169*9880d681SAndroid Build Coastguard Worker  %cond = icmp ult i32 %limit, 420
170*9880d681SAndroid Build Coastguard Worker  %orig = load i16 , i16 *%ptr
171*9880d681SAndroid Build Coastguard Worker  %ext = zext i16 %orig to i64
172*9880d681SAndroid Build Coastguard Worker  %res = select i1 %cond, i64 %alt, i64 %ext
173*9880d681SAndroid Build Coastguard Worker  %trunc = trunc i64 %res to i16
174*9880d681SAndroid Build Coastguard Worker  store i16 %trunc, i16 *%ptr
175*9880d681SAndroid Build Coastguard Worker  ret void
176*9880d681SAndroid Build Coastguard Worker}
177*9880d681SAndroid Build Coastguard Worker
178*9880d681SAndroid Build Coastguard Worker; Check the high end of the aligned STH range.
179*9880d681SAndroid Build Coastguard Workerdefine void @f11(i16 *%base, i16 %alt, i32 %limit) {
180*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f11:
181*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: %r2
182*9880d681SAndroid Build Coastguard Worker; CHECK: blr %r14
183*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: %r2
184*9880d681SAndroid Build Coastguard Worker; CHECK: sth %r3, 4094(%r2)
185*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14
186*9880d681SAndroid Build Coastguard Worker  %ptr = getelementptr i16, i16 *%base, i64 2047
187*9880d681SAndroid Build Coastguard Worker  %cond = icmp ult i32 %limit, 420
188*9880d681SAndroid Build Coastguard Worker  %orig = load i16 , i16 *%ptr
189*9880d681SAndroid Build Coastguard Worker  %res = select i1 %cond, i16 %orig, i16 %alt
190*9880d681SAndroid Build Coastguard Worker  store i16 %res, i16 *%ptr
191*9880d681SAndroid Build Coastguard Worker  ret void
192*9880d681SAndroid Build Coastguard Worker}
193*9880d681SAndroid Build Coastguard Worker
194*9880d681SAndroid Build Coastguard Worker; Check the next halfword up, which should use STHY instead of STH.
195*9880d681SAndroid Build Coastguard Workerdefine void @f12(i16 *%base, i16 %alt, i32 %limit) {
196*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f12:
197*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: %r2
198*9880d681SAndroid Build Coastguard Worker; CHECK: blr %r14
199*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: %r2
200*9880d681SAndroid Build Coastguard Worker; CHECK: sthy %r3, 4096(%r2)
201*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14
202*9880d681SAndroid Build Coastguard Worker  %ptr = getelementptr i16, i16 *%base, i64 2048
203*9880d681SAndroid Build Coastguard Worker  %cond = icmp ult i32 %limit, 420
204*9880d681SAndroid Build Coastguard Worker  %orig = load i16 , i16 *%ptr
205*9880d681SAndroid Build Coastguard Worker  %res = select i1 %cond, i16 %orig, i16 %alt
206*9880d681SAndroid Build Coastguard Worker  store i16 %res, i16 *%ptr
207*9880d681SAndroid Build Coastguard Worker  ret void
208*9880d681SAndroid Build Coastguard Worker}
209*9880d681SAndroid Build Coastguard Worker
210*9880d681SAndroid Build Coastguard Worker; Check the high end of the aligned STHY range.
211*9880d681SAndroid Build Coastguard Workerdefine void @f13(i16 *%base, i16 %alt, i32 %limit) {
212*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f13:
213*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: %r2
214*9880d681SAndroid Build Coastguard Worker; CHECK: blr %r14
215*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: %r2
216*9880d681SAndroid Build Coastguard Worker; CHECK: sthy %r3, 524286(%r2)
217*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14
218*9880d681SAndroid Build Coastguard Worker  %ptr = getelementptr i16, i16 *%base, i64 262143
219*9880d681SAndroid Build Coastguard Worker  %cond = icmp ult i32 %limit, 420
220*9880d681SAndroid Build Coastguard Worker  %orig = load i16 , i16 *%ptr
221*9880d681SAndroid Build Coastguard Worker  %res = select i1 %cond, i16 %orig, i16 %alt
222*9880d681SAndroid Build Coastguard Worker  store i16 %res, i16 *%ptr
223*9880d681SAndroid Build Coastguard Worker  ret void
224*9880d681SAndroid Build Coastguard Worker}
225*9880d681SAndroid Build Coastguard Worker
226*9880d681SAndroid Build Coastguard Worker; Check the next halfword up, which needs separate address logic.
227*9880d681SAndroid Build Coastguard Worker; Other sequences besides this one would be OK.
228*9880d681SAndroid Build Coastguard Workerdefine void @f14(i16 *%base, i16 %alt, i32 %limit) {
229*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f14:
230*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: %r2
231*9880d681SAndroid Build Coastguard Worker; CHECK: blr %r14
232*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: %r2
233*9880d681SAndroid Build Coastguard Worker; CHECK: agfi %r2, 524288
234*9880d681SAndroid Build Coastguard Worker; CHECK: sth %r3, 0(%r2)
235*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14
236*9880d681SAndroid Build Coastguard Worker  %ptr = getelementptr i16, i16 *%base, i64 262144
237*9880d681SAndroid Build Coastguard Worker  %cond = icmp ult i32 %limit, 420
238*9880d681SAndroid Build Coastguard Worker  %orig = load i16 , i16 *%ptr
239*9880d681SAndroid Build Coastguard Worker  %res = select i1 %cond, i16 %orig, i16 %alt
240*9880d681SAndroid Build Coastguard Worker  store i16 %res, i16 *%ptr
241*9880d681SAndroid Build Coastguard Worker  ret void
242*9880d681SAndroid Build Coastguard Worker}
243*9880d681SAndroid Build Coastguard Worker
244*9880d681SAndroid Build Coastguard Worker; Check the low end of the STHY range.
245*9880d681SAndroid Build Coastguard Workerdefine void @f15(i16 *%base, i16 %alt, i32 %limit) {
246*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f15:
247*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: %r2
248*9880d681SAndroid Build Coastguard Worker; CHECK: blr %r14
249*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: %r2
250*9880d681SAndroid Build Coastguard Worker; CHECK: sthy %r3, -524288(%r2)
251*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14
252*9880d681SAndroid Build Coastguard Worker  %ptr = getelementptr i16, i16 *%base, i64 -262144
253*9880d681SAndroid Build Coastguard Worker  %cond = icmp ult i32 %limit, 420
254*9880d681SAndroid Build Coastguard Worker  %orig = load i16 , i16 *%ptr
255*9880d681SAndroid Build Coastguard Worker  %res = select i1 %cond, i16 %orig, i16 %alt
256*9880d681SAndroid Build Coastguard Worker  store i16 %res, i16 *%ptr
257*9880d681SAndroid Build Coastguard Worker  ret void
258*9880d681SAndroid Build Coastguard Worker}
259*9880d681SAndroid Build Coastguard Worker
260*9880d681SAndroid Build Coastguard Worker; Check the next halfword down, which needs separate address logic.
261*9880d681SAndroid Build Coastguard Worker; Other sequences besides this one would be OK.
262*9880d681SAndroid Build Coastguard Workerdefine void @f16(i16 *%base, i16 %alt, i32 %limit) {
263*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f16:
264*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: %r2
265*9880d681SAndroid Build Coastguard Worker; CHECK: blr %r14
266*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: %r2
267*9880d681SAndroid Build Coastguard Worker; CHECK: agfi %r2, -524290
268*9880d681SAndroid Build Coastguard Worker; CHECK: sth %r3, 0(%r2)
269*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14
270*9880d681SAndroid Build Coastguard Worker  %ptr = getelementptr i16, i16 *%base, i64 -262145
271*9880d681SAndroid Build Coastguard Worker  %cond = icmp ult i32 %limit, 420
272*9880d681SAndroid Build Coastguard Worker  %orig = load i16 , i16 *%ptr
273*9880d681SAndroid Build Coastguard Worker  %res = select i1 %cond, i16 %orig, i16 %alt
274*9880d681SAndroid Build Coastguard Worker  store i16 %res, i16 *%ptr
275*9880d681SAndroid Build Coastguard Worker  ret void
276*9880d681SAndroid Build Coastguard Worker}
277*9880d681SAndroid Build Coastguard Worker
278*9880d681SAndroid Build Coastguard Worker; Check that STHY allows an index.
279*9880d681SAndroid Build Coastguard Workerdefine void @f17(i64 %base, i64 %index, i16 %alt, i32 %limit) {
280*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f17:
281*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: %r2
282*9880d681SAndroid Build Coastguard Worker; CHECK: blr %r14
283*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: %r2
284*9880d681SAndroid Build Coastguard Worker; CHECK: sthy %r4, 4096(%r3,%r2)
285*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14
286*9880d681SAndroid Build Coastguard Worker  %add1 = add i64 %base, %index
287*9880d681SAndroid Build Coastguard Worker  %add2 = add i64 %add1, 4096
288*9880d681SAndroid Build Coastguard Worker  %ptr = inttoptr i64 %add2 to i16 *
289*9880d681SAndroid Build Coastguard Worker  %cond = icmp ult i32 %limit, 420
290*9880d681SAndroid Build Coastguard Worker  %orig = load i16 , i16 *%ptr
291*9880d681SAndroid Build Coastguard Worker  %res = select i1 %cond, i16 %orig, i16 %alt
292*9880d681SAndroid Build Coastguard Worker  store i16 %res, i16 *%ptr
293*9880d681SAndroid Build Coastguard Worker  ret void
294*9880d681SAndroid Build Coastguard Worker}
295*9880d681SAndroid Build Coastguard Worker
296*9880d681SAndroid Build Coastguard Worker; Check that volatile loads are not matched.
297*9880d681SAndroid Build Coastguard Workerdefine void @f18(i16 *%ptr, i16 %alt, i32 %limit) {
298*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f18:
299*9880d681SAndroid Build Coastguard Worker; CHECK: lh {{%r[0-5]}}, 0(%r2)
300*9880d681SAndroid Build Coastguard Worker; CHECK: {{jl|jnl}} [[LABEL:[^ ]*]]
301*9880d681SAndroid Build Coastguard Worker; CHECK: [[LABEL]]:
302*9880d681SAndroid Build Coastguard Worker; CHECK: sth {{%r[0-5]}}, 0(%r2)
303*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14
304*9880d681SAndroid Build Coastguard Worker  %cond = icmp ult i32 %limit, 420
305*9880d681SAndroid Build Coastguard Worker  %orig = load volatile i16 , i16 *%ptr
306*9880d681SAndroid Build Coastguard Worker  %res = select i1 %cond, i16 %orig, i16 %alt
307*9880d681SAndroid Build Coastguard Worker  store i16 %res, i16 *%ptr
308*9880d681SAndroid Build Coastguard Worker  ret void
309*9880d681SAndroid Build Coastguard Worker}
310*9880d681SAndroid Build Coastguard Worker
311*9880d681SAndroid Build Coastguard Worker; ...likewise stores.  In this case we should have a conditional load into %r3.
312*9880d681SAndroid Build Coastguard Workerdefine void @f19(i16 *%ptr, i16 %alt, i32 %limit) {
313*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f19:
314*9880d681SAndroid Build Coastguard Worker; CHECK: jhe [[LABEL:[^ ]*]]
315*9880d681SAndroid Build Coastguard Worker; CHECK: lh %r3, 0(%r2)
316*9880d681SAndroid Build Coastguard Worker; CHECK: [[LABEL]]:
317*9880d681SAndroid Build Coastguard Worker; CHECK: sth %r3, 0(%r2)
318*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14
319*9880d681SAndroid Build Coastguard Worker  %cond = icmp ult i32 %limit, 420
320*9880d681SAndroid Build Coastguard Worker  %orig = load i16 , i16 *%ptr
321*9880d681SAndroid Build Coastguard Worker  %res = select i1 %cond, i16 %orig, i16 %alt
322*9880d681SAndroid Build Coastguard Worker  store volatile i16 %res, i16 *%ptr
323*9880d681SAndroid Build Coastguard Worker  ret void
324*9880d681SAndroid Build Coastguard Worker}
325*9880d681SAndroid Build Coastguard Worker
326*9880d681SAndroid Build Coastguard Worker; Check that atomic loads are not matched.  The transformation is OK for
327*9880d681SAndroid Build Coastguard Worker; the "unordered" case tested here, but since we don't try to handle atomic
328*9880d681SAndroid Build Coastguard Worker; operations at all in this context, it seems better to assert that than
329*9880d681SAndroid Build Coastguard Worker; to restrict the test to a stronger ordering.
330*9880d681SAndroid Build Coastguard Workerdefine void @f20(i16 *%ptr, i16 %alt, i32 %limit) {
331*9880d681SAndroid Build Coastguard Worker; FIXME: should use a normal load instead of CS.
332*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f20:
333*9880d681SAndroid Build Coastguard Worker; CHECK: lh {{%r[0-9]+}}, 0(%r2)
334*9880d681SAndroid Build Coastguard Worker; CHECK: {{jl|jnl}} [[LABEL:[^ ]*]]
335*9880d681SAndroid Build Coastguard Worker; CHECK: [[LABEL]]:
336*9880d681SAndroid Build Coastguard Worker; CHECK: sth {{%r[0-9]+}}, 0(%r2)
337*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14
338*9880d681SAndroid Build Coastguard Worker  %cond = icmp ult i32 %limit, 420
339*9880d681SAndroid Build Coastguard Worker  %orig = load atomic i16 , i16 *%ptr unordered, align 2
340*9880d681SAndroid Build Coastguard Worker  %res = select i1 %cond, i16 %orig, i16 %alt
341*9880d681SAndroid Build Coastguard Worker  store i16 %res, i16 *%ptr
342*9880d681SAndroid Build Coastguard Worker  ret void
343*9880d681SAndroid Build Coastguard Worker}
344*9880d681SAndroid Build Coastguard Worker
345*9880d681SAndroid Build Coastguard Worker; ...likewise stores.
346*9880d681SAndroid Build Coastguard Workerdefine void @f21(i16 *%ptr, i16 %alt, i32 %limit) {
347*9880d681SAndroid Build Coastguard Worker; FIXME: should use a normal store instead of CS.
348*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f21:
349*9880d681SAndroid Build Coastguard Worker; CHECK: jhe [[LABEL:[^ ]*]]
350*9880d681SAndroid Build Coastguard Worker; CHECK: lh %r3, 0(%r2)
351*9880d681SAndroid Build Coastguard Worker; CHECK: [[LABEL]]:
352*9880d681SAndroid Build Coastguard Worker; CHECK: sth %r3, 0(%r2)
353*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14
354*9880d681SAndroid Build Coastguard Worker  %cond = icmp ult i32 %limit, 420
355*9880d681SAndroid Build Coastguard Worker  %orig = load i16 , i16 *%ptr
356*9880d681SAndroid Build Coastguard Worker  %res = select i1 %cond, i16 %orig, i16 %alt
357*9880d681SAndroid Build Coastguard Worker  store atomic i16 %res, i16 *%ptr unordered, align 2
358*9880d681SAndroid Build Coastguard Worker  ret void
359*9880d681SAndroid Build Coastguard Worker}
360*9880d681SAndroid Build Coastguard Worker
361*9880d681SAndroid Build Coastguard Worker; Try a frame index base.
362*9880d681SAndroid Build Coastguard Workerdefine void @f22(i16 %alt, i32 %limit) {
363*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: f22:
364*9880d681SAndroid Build Coastguard Worker; CHECK: brasl %r14, foo@PLT
365*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: %r15
366*9880d681SAndroid Build Coastguard Worker; CHECK: jl [[LABEL:[^ ]*]]
367*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: %r15
368*9880d681SAndroid Build Coastguard Worker; CHECK: sth {{%r[0-9]+}}, {{[0-9]+}}(%r15)
369*9880d681SAndroid Build Coastguard Worker; CHECK: [[LABEL]]:
370*9880d681SAndroid Build Coastguard Worker; CHECK: brasl %r14, foo@PLT
371*9880d681SAndroid Build Coastguard Worker; CHECK: br %r14
372*9880d681SAndroid Build Coastguard Worker  %ptr = alloca i16
373*9880d681SAndroid Build Coastguard Worker  call void @foo(i16 *%ptr)
374*9880d681SAndroid Build Coastguard Worker  %cond = icmp ult i32 %limit, 420
375*9880d681SAndroid Build Coastguard Worker  %orig = load i16 , i16 *%ptr
376*9880d681SAndroid Build Coastguard Worker  %res = select i1 %cond, i16 %orig, i16 %alt
377*9880d681SAndroid Build Coastguard Worker  store i16 %res, i16 *%ptr
378*9880d681SAndroid Build Coastguard Worker  call void @foo(i16 *%ptr)
379*9880d681SAndroid Build Coastguard Worker  ret void
380*9880d681SAndroid Build Coastguard Worker}
381