blob: 60bff508d93a795f7fd83d414d2b0e72ff5f9608 [file] [log] [blame]
Ulrich Weigand9e3577f2013-05-06 16:17:29 +00001; Test the handling of base + 12-bit displacement addresses for large frames,
2; in cases where no 20-bit form exists.
3;
4; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck -check-prefix=CHECK-NOFP %s
5; RUN: llc < %s -mtriple=s390x-linux-gnu -disable-fp-elim | FileCheck -check-prefix=CHECK-FP %s
6
7; This file tests what happens when a displacement is converted from
8; being relative to the start of a frame object to being relative to
9; the frame itself. In some cases the test is only possible if two
10; objects are allocated.
11;
12; Rather than rely on a particular order for those objects, the tests
13; instead allocate two objects of the same size and apply the test to
14; both of them. For consistency, all tests follow this model, even if
15; one object would actually be enough.
16
17; First check the highest in-range offset after conversion, which is 4092
18; for word-addressing instructions like MVHI.
19;
Richard Sandiford23943222013-07-05 13:11:52 +000020; The last in-range doubleword offset is 4088. Since the frame has two
21; emergency spill slots at 160(%r15), the amount that we need to allocate
22; in order to put another object at offset 4088 is (4088 - 176) / 4 = 978
Ulrich Weigand9e3577f2013-05-06 16:17:29 +000023; words.
24define void @f1() {
Stephen Lind24ab202013-07-14 06:24:09 +000025; CHECK-NOFP-LABEL: f1:
Ulrich Weigand9e3577f2013-05-06 16:17:29 +000026; CHECK-NOFP: mvhi 4092(%r15), 42
27; CHECK-NOFP: br %r14
28;
Stephen Lind24ab202013-07-14 06:24:09 +000029; CHECK-FP-LABEL: f1:
Ulrich Weigand9e3577f2013-05-06 16:17:29 +000030; CHECK-FP: mvhi 4092(%r11), 42
31; CHECK-FP: br %r14
Richard Sandiford23943222013-07-05 13:11:52 +000032 %region1 = alloca [978 x i32], align 8
33 %region2 = alloca [978 x i32], align 8
34 %ptr1 = getelementptr inbounds [978 x i32]* %region1, i64 0, i64 1
35 %ptr2 = getelementptr inbounds [978 x i32]* %region2, i64 0, i64 1
Ulrich Weigand9e3577f2013-05-06 16:17:29 +000036 store volatile i32 42, i32 *%ptr1
37 store volatile i32 42, i32 *%ptr2
38 ret void
39}
40
41; Test the first out-of-range offset. We cannot use an index register here.
42define void @f2() {
Stephen Lind24ab202013-07-14 06:24:09 +000043; CHECK-NOFP-LABEL: f2:
Ulrich Weigand9e3577f2013-05-06 16:17:29 +000044; CHECK-NOFP: lay %r1, 4096(%r15)
45; CHECK-NOFP: mvhi 0(%r1), 42
46; CHECK-NOFP: br %r14
47;
Stephen Lind24ab202013-07-14 06:24:09 +000048; CHECK-FP-LABEL: f2:
Ulrich Weigand9e3577f2013-05-06 16:17:29 +000049; CHECK-FP: lay %r1, 4096(%r11)
50; CHECK-FP: mvhi 0(%r1), 42
51; CHECK-FP: br %r14
Richard Sandiford23943222013-07-05 13:11:52 +000052 %region1 = alloca [978 x i32], align 8
53 %region2 = alloca [978 x i32], align 8
54 %ptr1 = getelementptr inbounds [978 x i32]* %region1, i64 0, i64 2
55 %ptr2 = getelementptr inbounds [978 x i32]* %region2, i64 0, i64 2
Ulrich Weigand9e3577f2013-05-06 16:17:29 +000056 store volatile i32 42, i32 *%ptr1
57 store volatile i32 42, i32 *%ptr2
58 ret void
59}
60
61; Test the next offset after that.
62define void @f3() {
Stephen Lind24ab202013-07-14 06:24:09 +000063; CHECK-NOFP-LABEL: f3:
Ulrich Weigand9e3577f2013-05-06 16:17:29 +000064; CHECK-NOFP: lay %r1, 4096(%r15)
65; CHECK-NOFP: mvhi 4(%r1), 42
66; CHECK-NOFP: br %r14
67;
Stephen Lind24ab202013-07-14 06:24:09 +000068; CHECK-FP-LABEL: f3:
Ulrich Weigand9e3577f2013-05-06 16:17:29 +000069; CHECK-FP: lay %r1, 4096(%r11)
70; CHECK-FP: mvhi 4(%r1), 42
71; CHECK-FP: br %r14
Richard Sandiford23943222013-07-05 13:11:52 +000072 %region1 = alloca [978 x i32], align 8
73 %region2 = alloca [978 x i32], align 8
74 %ptr1 = getelementptr inbounds [978 x i32]* %region1, i64 0, i64 3
75 %ptr2 = getelementptr inbounds [978 x i32]* %region2, i64 0, i64 3
Ulrich Weigand9e3577f2013-05-06 16:17:29 +000076 store volatile i32 42, i32 *%ptr1
77 store volatile i32 42, i32 *%ptr2
78 ret void
79}
80
81; Add 4096 bytes (1024 words) to the size of each object and repeat.
82define void @f4() {
Stephen Lind24ab202013-07-14 06:24:09 +000083; CHECK-NOFP-LABEL: f4:
Ulrich Weigand9e3577f2013-05-06 16:17:29 +000084; CHECK-NOFP: lay %r1, 4096(%r15)
85; CHECK-NOFP: mvhi 4092(%r1), 42
86; CHECK-NOFP: br %r14
87;
Stephen Lind24ab202013-07-14 06:24:09 +000088; CHECK-FP-LABEL: f4:
Ulrich Weigand9e3577f2013-05-06 16:17:29 +000089; CHECK-FP: lay %r1, 4096(%r11)
90; CHECK-FP: mvhi 4092(%r1), 42
91; CHECK-FP: br %r14
Richard Sandiford23943222013-07-05 13:11:52 +000092 %region1 = alloca [2002 x i32], align 8
93 %region2 = alloca [2002 x i32], align 8
94 %ptr1 = getelementptr inbounds [2002 x i32]* %region1, i64 0, i64 1
95 %ptr2 = getelementptr inbounds [2002 x i32]* %region2, i64 0, i64 1
Ulrich Weigand9e3577f2013-05-06 16:17:29 +000096 store volatile i32 42, i32 *%ptr1
97 store volatile i32 42, i32 *%ptr2
98 ret void
99}
100
101; ...as above.
102define void @f5() {
Stephen Lind24ab202013-07-14 06:24:09 +0000103; CHECK-NOFP-LABEL: f5:
Ulrich Weigand9e3577f2013-05-06 16:17:29 +0000104; CHECK-NOFP: lay %r1, 8192(%r15)
105; CHECK-NOFP: mvhi 0(%r1), 42
106; CHECK-NOFP: br %r14
107;
Stephen Lind24ab202013-07-14 06:24:09 +0000108; CHECK-FP-LABEL: f5:
Ulrich Weigand9e3577f2013-05-06 16:17:29 +0000109; CHECK-FP: lay %r1, 8192(%r11)
110; CHECK-FP: mvhi 0(%r1), 42
111; CHECK-FP: br %r14
Richard Sandiford23943222013-07-05 13:11:52 +0000112 %region1 = alloca [2002 x i32], align 8
113 %region2 = alloca [2002 x i32], align 8
114 %ptr1 = getelementptr inbounds [2002 x i32]* %region1, i64 0, i64 2
115 %ptr2 = getelementptr inbounds [2002 x i32]* %region2, i64 0, i64 2
Ulrich Weigand9e3577f2013-05-06 16:17:29 +0000116 store volatile i32 42, i32 *%ptr1
117 store volatile i32 42, i32 *%ptr2
118 ret void
119}
120
121; ...as above.
122define void @f6() {
Stephen Lind24ab202013-07-14 06:24:09 +0000123; CHECK-NOFP-LABEL: f6:
Ulrich Weigand9e3577f2013-05-06 16:17:29 +0000124; CHECK-NOFP: lay %r1, 8192(%r15)
125; CHECK-NOFP: mvhi 4(%r1), 42
126; CHECK-NOFP: br %r14
127;
Stephen Lind24ab202013-07-14 06:24:09 +0000128; CHECK-FP-LABEL: f6:
Ulrich Weigand9e3577f2013-05-06 16:17:29 +0000129; CHECK-FP: lay %r1, 8192(%r11)
130; CHECK-FP: mvhi 4(%r1), 42
131; CHECK-FP: br %r14
Richard Sandiford23943222013-07-05 13:11:52 +0000132 %region1 = alloca [2002 x i32], align 8
133 %region2 = alloca [2002 x i32], align 8
134 %ptr1 = getelementptr inbounds [2002 x i32]* %region1, i64 0, i64 3
135 %ptr2 = getelementptr inbounds [2002 x i32]* %region2, i64 0, i64 3
Ulrich Weigand9e3577f2013-05-06 16:17:29 +0000136 store volatile i32 42, i32 *%ptr1
137 store volatile i32 42, i32 *%ptr2
138 ret void
139}
140
141; Now try an offset of 4092 from the start of the object, with the object
Richard Sandiford23943222013-07-05 13:11:52 +0000142; being at offset 8192. This time we need objects of (8192 - 176) / 4 = 2004
Ulrich Weigand9e3577f2013-05-06 16:17:29 +0000143; words.
144define void @f7() {
Stephen Lind24ab202013-07-14 06:24:09 +0000145; CHECK-NOFP-LABEL: f7:
Ulrich Weigand9e3577f2013-05-06 16:17:29 +0000146; CHECK-NOFP: lay %r1, 8192(%r15)
147; CHECK-NOFP: mvhi 4092(%r1), 42
148; CHECK-NOFP: br %r14
149;
Stephen Lind24ab202013-07-14 06:24:09 +0000150; CHECK-FP-LABEL: f7:
Ulrich Weigand9e3577f2013-05-06 16:17:29 +0000151; CHECK-FP: lay %r1, 8192(%r11)
152; CHECK-FP: mvhi 4092(%r1), 42
153; CHECK-FP: br %r14
Richard Sandiford23943222013-07-05 13:11:52 +0000154 %region1 = alloca [2004 x i32], align 8
155 %region2 = alloca [2004 x i32], align 8
156 %ptr1 = getelementptr inbounds [2004 x i32]* %region1, i64 0, i64 1023
157 %ptr2 = getelementptr inbounds [2004 x i32]* %region2, i64 0, i64 1023
Ulrich Weigand9e3577f2013-05-06 16:17:29 +0000158 store volatile i32 42, i32 *%ptr1
159 store volatile i32 42, i32 *%ptr2
160 ret void
161}
162
163; Keep the object-relative offset the same but bump the size of the
164; objects by one doubleword.
165define void @f8() {
Stephen Lind24ab202013-07-14 06:24:09 +0000166; CHECK-NOFP-LABEL: f8:
Ulrich Weigand9e3577f2013-05-06 16:17:29 +0000167; CHECK-NOFP: lay %r1, 12288(%r15)
168; CHECK-NOFP: mvhi 4(%r1), 42
169; CHECK-NOFP: br %r14
170;
Stephen Lind24ab202013-07-14 06:24:09 +0000171; CHECK-FP-LABEL: f8:
Ulrich Weigand9e3577f2013-05-06 16:17:29 +0000172; CHECK-FP: lay %r1, 12288(%r11)
173; CHECK-FP: mvhi 4(%r1), 42
174; CHECK-FP: br %r14
Richard Sandiford23943222013-07-05 13:11:52 +0000175 %region1 = alloca [2006 x i32], align 8
176 %region2 = alloca [2006 x i32], align 8
177 %ptr1 = getelementptr inbounds [2006 x i32]* %region1, i64 0, i64 1023
178 %ptr2 = getelementptr inbounds [2006 x i32]* %region2, i64 0, i64 1023
Ulrich Weigand9e3577f2013-05-06 16:17:29 +0000179 store volatile i32 42, i32 *%ptr1
180 store volatile i32 42, i32 *%ptr2
181 ret void
182}
183
184; Check a case where the original displacement is out of range. The backend
Richard Sandiforda481f582013-08-23 11:18:53 +0000185; should force STY to be used instead.
Ulrich Weigand9e3577f2013-05-06 16:17:29 +0000186define void @f9() {
Stephen Lind24ab202013-07-14 06:24:09 +0000187; CHECK-NOFP-LABEL: f9:
Richard Sandiforda481f582013-08-23 11:18:53 +0000188; CHECK-NOFP: lhi [[TMP:%r[0-5]]], 42
189; CHECK-NOFP: sty [[TMP]], 12296(%r15)
Ulrich Weigand9e3577f2013-05-06 16:17:29 +0000190; CHECK-NOFP: br %r14
191;
Stephen Lind24ab202013-07-14 06:24:09 +0000192; CHECK-FP-LABEL: f9:
Richard Sandiforda481f582013-08-23 11:18:53 +0000193; CHECK-FP: lhi [[TMP:%r[0-5]]], 42
194; CHECK-FP: sty [[TMP]], 12296(%r11)
Ulrich Weigand9e3577f2013-05-06 16:17:29 +0000195; CHECK-FP: br %r14
Richard Sandiford23943222013-07-05 13:11:52 +0000196 %region1 = alloca [2006 x i32], align 8
197 %region2 = alloca [2006 x i32], align 8
198 %ptr1 = getelementptr inbounds [2006 x i32]* %region1, i64 0, i64 1024
199 %ptr2 = getelementptr inbounds [2006 x i32]* %region2, i64 0, i64 1024
Ulrich Weigand9e3577f2013-05-06 16:17:29 +0000200 store volatile i32 42, i32 *%ptr1
201 store volatile i32 42, i32 *%ptr2
202 ret void
203}
204
Richard Sandiford23943222013-07-05 13:11:52 +0000205; Repeat f2 in a case that needs the emergency spill slots (because all
Ulrich Weigand9e3577f2013-05-06 16:17:29 +0000206; call-clobbered registers are live and no call-saved ones have been
207; allocated).
208define void @f10(i32 *%vptr) {
Stephen Lind24ab202013-07-14 06:24:09 +0000209; CHECK-NOFP-LABEL: f10:
Richard Sandiford23943222013-07-05 13:11:52 +0000210; CHECK-NOFP: stg [[REGISTER:%r[1-9][0-4]?]], [[OFFSET:160|168]](%r15)
Ulrich Weigand9e3577f2013-05-06 16:17:29 +0000211; CHECK-NOFP: lay [[REGISTER]], 4096(%r15)
212; CHECK-NOFP: mvhi 0([[REGISTER]]), 42
Richard Sandiford23943222013-07-05 13:11:52 +0000213; CHECK-NOFP: lg [[REGISTER]], [[OFFSET]](%r15)
Ulrich Weigand9e3577f2013-05-06 16:17:29 +0000214; CHECK-NOFP: br %r14
215;
Stephen Lind24ab202013-07-14 06:24:09 +0000216; CHECK-FP-LABEL: f10:
Richard Sandiford23943222013-07-05 13:11:52 +0000217; CHECK-FP: stg [[REGISTER:%r[1-9][0-4]?]], [[OFFSET:160|168]](%r11)
Ulrich Weigand9e3577f2013-05-06 16:17:29 +0000218; CHECK-FP: lay [[REGISTER]], 4096(%r11)
219; CHECK-FP: mvhi 0([[REGISTER]]), 42
Richard Sandiford23943222013-07-05 13:11:52 +0000220; CHECK-FP: lg [[REGISTER]], [[OFFSET]](%r11)
Ulrich Weigand9e3577f2013-05-06 16:17:29 +0000221; CHECK-FP: br %r14
222 %i0 = load volatile i32 *%vptr
223 %i1 = load volatile i32 *%vptr
224 %i3 = load volatile i32 *%vptr
225 %i4 = load volatile i32 *%vptr
226 %i5 = load volatile i32 *%vptr
Richard Sandiford23943222013-07-05 13:11:52 +0000227 %region1 = alloca [978 x i32], align 8
228 %region2 = alloca [978 x i32], align 8
229 %ptr1 = getelementptr inbounds [978 x i32]* %region1, i64 0, i64 2
230 %ptr2 = getelementptr inbounds [978 x i32]* %region2, i64 0, i64 2
Ulrich Weigand9e3577f2013-05-06 16:17:29 +0000231 store volatile i32 42, i32 *%ptr1
232 store volatile i32 42, i32 *%ptr2
233 store volatile i32 %i0, i32 *%vptr
234 store volatile i32 %i1, i32 *%vptr
235 store volatile i32 %i3, i32 *%vptr
236 store volatile i32 %i4, i32 *%vptr
237 store volatile i32 %i5, i32 *%vptr
238 ret void
239}
240
Richard Sandiford23943222013-07-05 13:11:52 +0000241; And again with maximum register pressure. The only spill slots that the
242; NOFP case needs are the emergency ones, so the offsets are the same as for f2.
Ulrich Weigand9e3577f2013-05-06 16:17:29 +0000243; However, the FP case uses %r11 as the frame pointer and must therefore
244; spill a second register. This leads to an extra displacement of 8.
245define void @f11(i32 *%vptr) {
Stephen Lind24ab202013-07-14 06:24:09 +0000246; CHECK-NOFP-LABEL: f11:
Ulrich Weigand9e3577f2013-05-06 16:17:29 +0000247; CHECK-NOFP: stmg %r6, %r15,
Richard Sandiford23943222013-07-05 13:11:52 +0000248; CHECK-NOFP: stg [[REGISTER:%r[1-9][0-4]?]], [[OFFSET:160|168]](%r15)
Ulrich Weigand9e3577f2013-05-06 16:17:29 +0000249; CHECK-NOFP: lay [[REGISTER]], 4096(%r15)
250; CHECK-NOFP: mvhi 0([[REGISTER]]), 42
Richard Sandiford23943222013-07-05 13:11:52 +0000251; CHECK-NOFP: lg [[REGISTER]], [[OFFSET]](%r15)
Ulrich Weigand9e3577f2013-05-06 16:17:29 +0000252; CHECK-NOFP: lmg %r6, %r15,
253; CHECK-NOFP: br %r14
254;
Stephen Lind24ab202013-07-14 06:24:09 +0000255; CHECK-FP-LABEL: f11:
Ulrich Weigand9e3577f2013-05-06 16:17:29 +0000256; CHECK-FP: stmg %r6, %r15,
Richard Sandiford23943222013-07-05 13:11:52 +0000257; CHECK-FP: stg [[REGISTER:%r[1-9][0-4]?]], [[OFFSET:160|168]](%r11)
Ulrich Weigand9e3577f2013-05-06 16:17:29 +0000258; CHECK-FP: lay [[REGISTER]], 4096(%r11)
259; CHECK-FP: mvhi 8([[REGISTER]]), 42
Richard Sandiford23943222013-07-05 13:11:52 +0000260; CHECK-FP: lg [[REGISTER]], [[OFFSET]](%r11)
Ulrich Weigand9e3577f2013-05-06 16:17:29 +0000261; CHECK-FP: lmg %r6, %r15,
262; CHECK-FP: br %r14
263 %i0 = load volatile i32 *%vptr
264 %i1 = load volatile i32 *%vptr
265 %i3 = load volatile i32 *%vptr
266 %i4 = load volatile i32 *%vptr
267 %i5 = load volatile i32 *%vptr
268 %i6 = load volatile i32 *%vptr
269 %i7 = load volatile i32 *%vptr
270 %i8 = load volatile i32 *%vptr
271 %i9 = load volatile i32 *%vptr
272 %i10 = load volatile i32 *%vptr
273 %i11 = load volatile i32 *%vptr
274 %i12 = load volatile i32 *%vptr
275 %i13 = load volatile i32 *%vptr
276 %i14 = load volatile i32 *%vptr
Richard Sandiford23943222013-07-05 13:11:52 +0000277 %region1 = alloca [978 x i32], align 8
278 %region2 = alloca [978 x i32], align 8
279 %ptr1 = getelementptr inbounds [978 x i32]* %region1, i64 0, i64 2
280 %ptr2 = getelementptr inbounds [978 x i32]* %region2, i64 0, i64 2
Ulrich Weigand9e3577f2013-05-06 16:17:29 +0000281 store volatile i32 42, i32 *%ptr1
282 store volatile i32 42, i32 *%ptr2
283 store volatile i32 %i0, i32 *%vptr
284 store volatile i32 %i1, i32 *%vptr
285 store volatile i32 %i3, i32 *%vptr
286 store volatile i32 %i4, i32 *%vptr
287 store volatile i32 %i5, i32 *%vptr
288 store volatile i32 %i6, i32 *%vptr
289 store volatile i32 %i7, i32 *%vptr
290 store volatile i32 %i8, i32 *%vptr
291 store volatile i32 %i9, i32 *%vptr
292 store volatile i32 %i10, i32 *%vptr
293 store volatile i32 %i11, i32 *%vptr
294 store volatile i32 %i12, i32 *%vptr
295 store volatile i32 %i13, i32 *%vptr
296 store volatile i32 %i14, i32 *%vptr
297 ret void
298}