blob: cce8cb6d6d79fb55ac39834e7e18e14894ef3a9d [file] [log] [blame]
Richard Sandiford178273a2013-09-05 10:36:45 +00001; Test memory-to-memory ANDs.
2;
3; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s
4
Richard Sandiford067817e2013-09-27 15:29:20 +00005@g1src = global i8 1
6@g1dst = global i8 1
7@g2src = global i16 2
8@g2dst = global i16 2
Richard Sandiford178273a2013-09-05 10:36:45 +00009
10; Test the simple i8 case.
11define void @f1(i8 *%ptr1) {
12; CHECK-LABEL: f1:
13; CHECK: nc 1(1,%r2), 0(%r2)
14; CHECK: br %r14
David Blaikie79e6c742015-02-27 19:29:02 +000015 %ptr2 = getelementptr i8, i8 *%ptr1, i64 1
Ulrich Weigand9dd23b82018-07-20 12:12:10 +000016 %val = load i8, i8 *%ptr1
17 %old = load i8, i8 *%ptr2
Richard Sandiford178273a2013-09-05 10:36:45 +000018 %and = and i8 %val, %old
19 store i8 %and, i8 *%ptr2
20 ret void
21}
22
23; ...and again in reverse.
24define void @f2(i8 *%ptr1) {
25; CHECK-LABEL: f2:
26; CHECK: nc 1(1,%r2), 0(%r2)
27; CHECK: br %r14
David Blaikie79e6c742015-02-27 19:29:02 +000028 %ptr2 = getelementptr i8, i8 *%ptr1, i64 1
Ulrich Weigand9dd23b82018-07-20 12:12:10 +000029 %val = load i8, i8 *%ptr1
30 %old = load i8, i8 *%ptr2
Richard Sandiford178273a2013-09-05 10:36:45 +000031 %and = and i8 %old, %val
32 store i8 %and, i8 *%ptr2
33 ret void
34}
35
36; Test i8 cases where one value is zero-extended to 32 bits and the other
37; sign-extended.
38define void @f3(i8 *%ptr1) {
39; CHECK-LABEL: f3:
40; CHECK: nc 1(1,%r2), 0(%r2)
41; CHECK: br %r14
David Blaikie79e6c742015-02-27 19:29:02 +000042 %ptr2 = getelementptr i8, i8 *%ptr1, i64 1
Ulrich Weigand9dd23b82018-07-20 12:12:10 +000043 %val = load i8, i8 *%ptr1
Richard Sandiford178273a2013-09-05 10:36:45 +000044 %extval = zext i8 %val to i32
Ulrich Weigand9dd23b82018-07-20 12:12:10 +000045 %old = load i8, i8 *%ptr2
Richard Sandiford178273a2013-09-05 10:36:45 +000046 %extold = sext i8 %old to i32
47 %and = and i32 %extval, %extold
48 %trunc = trunc i32 %and to i8
49 store i8 %trunc, i8 *%ptr2
50 ret void
51}
52
53; ...and again with the extension types reversed.
54define void @f4(i8 *%ptr1) {
55; CHECK-LABEL: f4:
56; CHECK: nc 1(1,%r2), 0(%r2)
57; CHECK: br %r14
David Blaikie79e6c742015-02-27 19:29:02 +000058 %ptr2 = getelementptr i8, i8 *%ptr1, i64 1
Ulrich Weigand9dd23b82018-07-20 12:12:10 +000059 %val = load i8, i8 *%ptr1
Richard Sandiford178273a2013-09-05 10:36:45 +000060 %extval = sext i8 %val to i32
Ulrich Weigand9dd23b82018-07-20 12:12:10 +000061 %old = load i8, i8 *%ptr2
Richard Sandiford178273a2013-09-05 10:36:45 +000062 %extold = zext i8 %old to i32
63 %and = and i32 %extval, %extold
64 %trunc = trunc i32 %and to i8
65 store i8 %trunc, i8 *%ptr2
66 ret void
67}
68
69; ...and again with two sign extensions.
70define void @f5(i8 *%ptr1) {
71; CHECK-LABEL: f5:
72; CHECK: nc 1(1,%r2), 0(%r2)
73; CHECK: br %r14
David Blaikie79e6c742015-02-27 19:29:02 +000074 %ptr2 = getelementptr i8, i8 *%ptr1, i64 1
Ulrich Weigand9dd23b82018-07-20 12:12:10 +000075 %val = load i8, i8 *%ptr1
Richard Sandiford178273a2013-09-05 10:36:45 +000076 %extval = sext i8 %val to i32
Ulrich Weigand9dd23b82018-07-20 12:12:10 +000077 %old = load i8, i8 *%ptr2
Richard Sandiford178273a2013-09-05 10:36:45 +000078 %extold = sext i8 %old to i32
79 %and = and i32 %extval, %extold
80 %trunc = trunc i32 %and to i8
81 store i8 %trunc, i8 *%ptr2
82 ret void
83}
84
85; ...and again with two zero extensions.
86define void @f6(i8 *%ptr1) {
87; CHECK-LABEL: f6:
88; CHECK: nc 1(1,%r2), 0(%r2)
89; CHECK: br %r14
David Blaikie79e6c742015-02-27 19:29:02 +000090 %ptr2 = getelementptr i8, i8 *%ptr1, i64 1
Ulrich Weigand9dd23b82018-07-20 12:12:10 +000091 %val = load i8, i8 *%ptr1
Richard Sandiford178273a2013-09-05 10:36:45 +000092 %extval = zext i8 %val to i32
Ulrich Weigand9dd23b82018-07-20 12:12:10 +000093 %old = load i8, i8 *%ptr2
Richard Sandiford178273a2013-09-05 10:36:45 +000094 %extold = zext i8 %old to i32
95 %and = and i32 %extval, %extold
96 %trunc = trunc i32 %and to i8
97 store i8 %trunc, i8 *%ptr2
98 ret void
99}
100
101; Test i8 cases where the value is extended to 64 bits (just one case
102; this time).
103define void @f7(i8 *%ptr1) {
104; CHECK-LABEL: f7:
105; CHECK: nc 1(1,%r2), 0(%r2)
106; CHECK: br %r14
David Blaikie79e6c742015-02-27 19:29:02 +0000107 %ptr2 = getelementptr i8, i8 *%ptr1, i64 1
Ulrich Weigand9dd23b82018-07-20 12:12:10 +0000108 %val = load i8, i8 *%ptr1
Richard Sandiford178273a2013-09-05 10:36:45 +0000109 %extval = sext i8 %val to i64
Ulrich Weigand9dd23b82018-07-20 12:12:10 +0000110 %old = load i8, i8 *%ptr2
Richard Sandiford178273a2013-09-05 10:36:45 +0000111 %extold = zext i8 %old to i64
112 %and = and i64 %extval, %extold
113 %trunc = trunc i64 %and to i8
114 store i8 %trunc, i8 *%ptr2
115 ret void
116}
117
118; Test the simple i16 case.
119define void @f8(i16 *%ptr1) {
120; CHECK-LABEL: f8:
121; CHECK: nc 2(2,%r2), 0(%r2)
122; CHECK: br %r14
David Blaikie79e6c742015-02-27 19:29:02 +0000123 %ptr2 = getelementptr i16, i16 *%ptr1, i64 1
Ulrich Weigand9dd23b82018-07-20 12:12:10 +0000124 %val = load i16, i16 *%ptr1
125 %old = load i16, i16 *%ptr2
Richard Sandiford178273a2013-09-05 10:36:45 +0000126 %and = and i16 %val, %old
127 store i16 %and, i16 *%ptr2
128 ret void
129}
130
131; Test i16 cases where the value is extended to 32 bits.
132define void @f9(i16 *%ptr1) {
133; CHECK-LABEL: f9:
134; CHECK: nc 2(2,%r2), 0(%r2)
135; CHECK: br %r14
David Blaikie79e6c742015-02-27 19:29:02 +0000136 %ptr2 = getelementptr i16, i16 *%ptr1, i64 1
Ulrich Weigand9dd23b82018-07-20 12:12:10 +0000137 %val = load i16, i16 *%ptr1
Richard Sandiford178273a2013-09-05 10:36:45 +0000138 %extval = zext i16 %val to i32
Ulrich Weigand9dd23b82018-07-20 12:12:10 +0000139 %old = load i16, i16 *%ptr2
Richard Sandiford178273a2013-09-05 10:36:45 +0000140 %extold = sext i16 %old to i32
141 %and = and i32 %extval, %extold
142 %trunc = trunc i32 %and to i16
143 store i16 %trunc, i16 *%ptr2
144 ret void
145}
146
147; Test i16 cases where the value is extended to 64 bits.
148define void @f10(i16 *%ptr1) {
149; CHECK-LABEL: f10:
150; CHECK: nc 2(2,%r2), 0(%r2)
151; CHECK: br %r14
David Blaikie79e6c742015-02-27 19:29:02 +0000152 %ptr2 = getelementptr i16, i16 *%ptr1, i64 1
Ulrich Weigand9dd23b82018-07-20 12:12:10 +0000153 %val = load i16, i16 *%ptr1
Richard Sandiford178273a2013-09-05 10:36:45 +0000154 %extval = sext i16 %val to i64
Ulrich Weigand9dd23b82018-07-20 12:12:10 +0000155 %old = load i16, i16 *%ptr2
Richard Sandiford178273a2013-09-05 10:36:45 +0000156 %extold = zext i16 %old to i64
157 %and = and i64 %extval, %extold
158 %trunc = trunc i64 %and to i16
159 store i16 %trunc, i16 *%ptr2
160 ret void
161}
162
163; Test the simple i32 case.
164define void @f11(i32 *%ptr1) {
165; CHECK-LABEL: f11:
166; CHECK: nc 4(4,%r2), 0(%r2)
167; CHECK: br %r14
David Blaikie79e6c742015-02-27 19:29:02 +0000168 %ptr2 = getelementptr i32, i32 *%ptr1, i64 1
Ulrich Weigand9dd23b82018-07-20 12:12:10 +0000169 %val = load i32, i32 *%ptr1
170 %old = load i32, i32 *%ptr2
Richard Sandiford178273a2013-09-05 10:36:45 +0000171 %and = and i32 %old, %val
172 store i32 %and, i32 *%ptr2
173 ret void
174}
175
176; Test i32 cases where the value is extended to 64 bits.
177define void @f12(i32 *%ptr1) {
178; CHECK-LABEL: f12:
179; CHECK: nc 4(4,%r2), 0(%r2)
180; CHECK: br %r14
David Blaikie79e6c742015-02-27 19:29:02 +0000181 %ptr2 = getelementptr i32, i32 *%ptr1, i64 1
Ulrich Weigand9dd23b82018-07-20 12:12:10 +0000182 %val = load i32, i32 *%ptr1
Richard Sandiford178273a2013-09-05 10:36:45 +0000183 %extval = sext i32 %val to i64
Ulrich Weigand9dd23b82018-07-20 12:12:10 +0000184 %old = load i32, i32 *%ptr2
Richard Sandiford178273a2013-09-05 10:36:45 +0000185 %extold = zext i32 %old to i64
186 %and = and i64 %extval, %extold
187 %trunc = trunc i64 %and to i32
188 store i32 %trunc, i32 *%ptr2
189 ret void
190}
191
192; Test the i64 case.
193define void @f13(i64 *%ptr1) {
194; CHECK-LABEL: f13:
195; CHECK: nc 8(8,%r2), 0(%r2)
196; CHECK: br %r14
David Blaikie79e6c742015-02-27 19:29:02 +0000197 %ptr2 = getelementptr i64, i64 *%ptr1, i64 1
Ulrich Weigand9dd23b82018-07-20 12:12:10 +0000198 %val = load i64, i64 *%ptr1
199 %old = load i64, i64 *%ptr2
Richard Sandiford178273a2013-09-05 10:36:45 +0000200 %and = and i64 %old, %val
201 store i64 %and, i64 *%ptr2
202 ret void
203}
204
205; Make sure that we don't use NC if the first load is volatile.
206define void @f14(i64 *%ptr1) {
207; CHECK-LABEL: f14:
208; CHECK-NOT: nc
209; CHECK: br %r14
David Blaikie79e6c742015-02-27 19:29:02 +0000210 %ptr2 = getelementptr i64, i64 *%ptr1, i64 1
Ulrich Weigand9dd23b82018-07-20 12:12:10 +0000211 %val = load volatile i64, i64 *%ptr1
212 %old = load i64, i64 *%ptr2
Richard Sandiford178273a2013-09-05 10:36:45 +0000213 %and = and i64 %old, %val
214 store i64 %and, i64 *%ptr2
215 ret void
216}
217
218; ...likewise the second.
219define void @f15(i64 *%ptr1) {
220; CHECK-LABEL: f15:
221; CHECK-NOT: nc
222; CHECK: br %r14
David Blaikie79e6c742015-02-27 19:29:02 +0000223 %ptr2 = getelementptr i64, i64 *%ptr1, i64 1
Ulrich Weigand9dd23b82018-07-20 12:12:10 +0000224 %val = load i64, i64 *%ptr1
225 %old = load volatile i64, i64 *%ptr2
Richard Sandiford178273a2013-09-05 10:36:45 +0000226 %and = and i64 %old, %val
227 store i64 %and, i64 *%ptr2
228 ret void
229}
230
231; ...likewise the store.
232define void @f16(i64 *%ptr1) {
233; CHECK-LABEL: f16:
234; CHECK-NOT: nc
235; CHECK: br %r14
David Blaikie79e6c742015-02-27 19:29:02 +0000236 %ptr2 = getelementptr i64, i64 *%ptr1, i64 1
Ulrich Weigand9dd23b82018-07-20 12:12:10 +0000237 %val = load i64, i64 *%ptr1
238 %old = load i64, i64 *%ptr2
Richard Sandiford178273a2013-09-05 10:36:45 +0000239 %and = and i64 %old, %val
240 store volatile i64 %and, i64 *%ptr2
241 ret void
242}
243
Richard Sandiford067817e2013-09-27 15:29:20 +0000244; Test that NC is not used for aligned loads and stores if there is
245; no way of telling whether they alias. We don't want to use NC in
246; cases where the addresses could be equal.
Richard Sandiford178273a2013-09-05 10:36:45 +0000247define void @f17(i64 *%ptr1, i64 *%ptr2) {
248; CHECK-LABEL: f17:
Richard Sandiford067817e2013-09-27 15:29:20 +0000249; CHECK-NOT: nc
Richard Sandiford178273a2013-09-05 10:36:45 +0000250; CHECK: br %r14
Ulrich Weigand9dd23b82018-07-20 12:12:10 +0000251 %val = load i64, i64 *%ptr1
252 %old = load i64, i64 *%ptr2
Richard Sandiford178273a2013-09-05 10:36:45 +0000253 %and = and i64 %old, %val
254 store i64 %and, i64 *%ptr2
255 ret void
256}
257
258; ...but if one of the loads isn't aligned, we can't be sure.
259define void @f18(i64 *%ptr1, i64 *%ptr2) {
260; CHECK-LABEL: f18:
261; CHECK-NOT: nc
262; CHECK: br %r14
Ulrich Weigand9dd23b82018-07-20 12:12:10 +0000263 %val = load i64, i64 *%ptr1, align 2
264 %old = load i64, i64 *%ptr2
Richard Sandiford178273a2013-09-05 10:36:45 +0000265 %and = and i64 %old, %val
266 store i64 %and, i64 *%ptr2
267 ret void
268}
269
270; Repeat the previous test with the operands in the opposite order.
271define void @f19(i64 *%ptr1, i64 *%ptr2) {
272; CHECK-LABEL: f19:
273; CHECK-NOT: nc
274; CHECK: br %r14
Ulrich Weigand9dd23b82018-07-20 12:12:10 +0000275 %val = load i64, i64 *%ptr1, align 2
276 %old = load i64, i64 *%ptr2
Richard Sandiford178273a2013-09-05 10:36:45 +0000277 %and = and i64 %val, %old
278 store i64 %and, i64 *%ptr2
279 ret void
280}
281
282; ...and again with the other operand being unaligned.
283define void @f20(i64 *%ptr1, i64 *%ptr2) {
284; CHECK-LABEL: f20:
285; CHECK-NOT: nc
286; CHECK: br %r14
Ulrich Weigand9dd23b82018-07-20 12:12:10 +0000287 %val = load i64, i64 *%ptr1
288 %old = load i64, i64 *%ptr2, align 2
Richard Sandiford178273a2013-09-05 10:36:45 +0000289 %and = and i64 %val, %old
290 store i64 %and, i64 *%ptr2, align 2
291 ret void
292}
293
294; Test a case where there is definite overlap.
295define void @f21(i64 %base) {
296; CHECK-LABEL: f21:
297; CHECK-NOT: nc
298; CHECK: br %r14
299 %add = add i64 %base, 1
300 %ptr1 = inttoptr i64 %base to i64 *
301 %ptr2 = inttoptr i64 %add to i64 *
Ulrich Weigand9dd23b82018-07-20 12:12:10 +0000302 %val = load i64, i64 *%ptr1
303 %old = load i64, i64 *%ptr2, align 1
Richard Sandiford178273a2013-09-05 10:36:45 +0000304 %and = and i64 %old, %val
305 store i64 %and, i64 *%ptr2, align 1
306 ret void
307}
308
309; Test that we can use NC for global addresses for i8.
310define void @f22(i8 *%ptr) {
311; CHECK-LABEL: f22:
Richard Sandiford067817e2013-09-27 15:29:20 +0000312; CHECK-DAG: larl [[SRC:%r[0-5]]], g1src
313; CHECK-DAG: larl [[DST:%r[0-5]]], g1dst
314; CHECK: nc 0(1,[[DST]]), 0([[SRC]])
Richard Sandiford178273a2013-09-05 10:36:45 +0000315; CHECK: br %r14
Ulrich Weigand9dd23b82018-07-20 12:12:10 +0000316 %val = load i8, i8 *@g1src
317 %old = load i8, i8 *@g1dst
Richard Sandiford178273a2013-09-05 10:36:45 +0000318 %and = and i8 %val, %old
Richard Sandiford067817e2013-09-27 15:29:20 +0000319 store i8 %and, i8 *@g1dst
Richard Sandiford178273a2013-09-05 10:36:45 +0000320 ret void
321}
322
323; Test that we use NC even where LHRL and STHRL are available.
Richard Sandiford067817e2013-09-27 15:29:20 +0000324define void @f23(i16 *%ptr) {
325; CHECK-LABEL: f23:
326; CHECK-DAG: larl [[SRC:%r[0-5]]], g2src
327; CHECK-DAG: larl [[DST:%r[0-5]]], g2dst
328; CHECK: nc 0(2,[[DST]]), 0([[SRC]])
Richard Sandiford178273a2013-09-05 10:36:45 +0000329; CHECK: br %r14
Ulrich Weigand9dd23b82018-07-20 12:12:10 +0000330 %val = load i16, i16 *@g2src
331 %old = load i16, i16 *@g2dst
Richard Sandiford178273a2013-09-05 10:36:45 +0000332 %and = and i16 %val, %old
Richard Sandiford067817e2013-09-27 15:29:20 +0000333 store i16 %and, i16 *@g2dst
Richard Sandiford178273a2013-09-05 10:36:45 +0000334 ret void
335}
336
337; Test a case where offset disambiguation is enough.
Richard Sandiford067817e2013-09-27 15:29:20 +0000338define void @f24(i64 *%ptr1) {
339; CHECK-LABEL: f24:
Richard Sandiford178273a2013-09-05 10:36:45 +0000340; CHECK: nc 8(8,%r2), 0(%r2)
341; CHECK: br %r14
David Blaikie79e6c742015-02-27 19:29:02 +0000342 %ptr2 = getelementptr i64, i64 *%ptr1, i64 1
Ulrich Weigand9dd23b82018-07-20 12:12:10 +0000343 %val = load i64, i64 *%ptr1, align 1
344 %old = load i64, i64 *%ptr2, align 1
Richard Sandiford178273a2013-09-05 10:36:45 +0000345 %and = and i64 %old, %val
346 store i64 %and, i64 *%ptr2, align 1
347 ret void
348}
349
350; Test a case where TBAA tells us there is no alias.
Richard Sandiford067817e2013-09-27 15:29:20 +0000351define void @f25(i64 *%ptr1, i64 *%ptr2) {
352; CHECK-LABEL: f25:
Richard Sandiford178273a2013-09-05 10:36:45 +0000353; CHECK: nc 0(8,%r3), 0(%r2)
354; CHECK: br %r14
Ulrich Weigand9dd23b82018-07-20 12:12:10 +0000355 %val = load i64, i64 *%ptr1, align 2, !tbaa !3
356 %old = load i64, i64 *%ptr2, align 2, !tbaa !4
Richard Sandiford178273a2013-09-05 10:36:45 +0000357 %and = and i64 %old, %val
Manman Renadf4cc12013-09-30 18:17:55 +0000358 store i64 %and, i64 *%ptr2, align 2, !tbaa !4
Richard Sandiford178273a2013-09-05 10:36:45 +0000359 ret void
360}
361
362; Test a case where TBAA information is present but doesn't help.
Richard Sandiford067817e2013-09-27 15:29:20 +0000363define void @f26(i64 *%ptr1, i64 *%ptr2) {
364; CHECK-LABEL: f26:
Richard Sandiford178273a2013-09-05 10:36:45 +0000365; CHECK-NOT: nc
366; CHECK: br %r14
Ulrich Weigand9dd23b82018-07-20 12:12:10 +0000367 %val = load i64, i64 *%ptr1, align 2, !tbaa !3
368 %old = load i64, i64 *%ptr2, align 2, !tbaa !3
Richard Sandiford178273a2013-09-05 10:36:45 +0000369 %and = and i64 %old, %val
Manman Renadf4cc12013-09-30 18:17:55 +0000370 store i64 %and, i64 *%ptr2, align 2, !tbaa !3
Richard Sandiford178273a2013-09-05 10:36:45 +0000371 ret void
372}
373
Duncan P. N. Exon Smithbe7ea192014-12-15 19:07:53 +0000374!0 = !{ !"root" }
375!1 = !{ !"set1", !0 }
376!2 = !{ !"set2", !0 }
377!3 = !{ !1, !1, i64 0}
378!4 = !{ !2, !2, i64 0}