1 # NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
2 # RUN: llc -mtriple aarch64-apple-darwin -run-pass=aarch64-prelegalizer-combiner -verify-machineinstrs %s -o - | FileCheck %s
5 @g = external hidden global i32
8 @unsized = external hidden global %opaque
9 @thread_local = thread_local global i32 0
11 define void @one_ptr_add() { ret void }
12 define void @add_to_offset() { ret void }
13 define void @two_ptr_adds_same_offset() { ret void }
14 define void @two_ptr_adds_different_offset() { ret void }
15 define void @ptr_add_chain() { ret void }
17 define void @dont_fold_negative_offset() { ret void }
18 define void @dont_min_offset_less_than_curr_offset() { ret void }
19 define void @dont_fold_max_offset() { ret void }
20 define void @dont_fold_offset_larger_than_type_alloc() { ret void }
21 define void @dont_fold_unsized_type() { ret void }
22 define void @dont_fold_thread_local() { ret void }
24 # We should fold the offset 1 into the G_GLOBAL_VALUE.
28 tracksRegLiveness: true
29 machineFunctionInfo: {}
34 ; CHECK-LABEL: name: one_ptr_add
37 ; CHECK-NEXT: [[GV:%[0-9]+]]:_(p0) = G_GLOBAL_VALUE @g + 1
38 ; CHECK-NEXT: $x0 = COPY [[GV]](p0)
39 ; CHECK-NEXT: RET_ReallyLR implicit $x0
40 %global:_(p0) = G_GLOBAL_VALUE @g
41 %offset:_(s64) = G_CONSTANT i64 1
42 %ptr_add:_(p0) = G_PTR_ADD %global, %offset(s64)
44 RET_ReallyLR implicit $x0
47 # We should fold the offset 1 into the G_GLOBAL_VALUE, resulting in a
52 tracksRegLiveness: true
53 machineFunctionInfo: {}
58 ; CHECK-LABEL: name: add_to_offset
61 ; CHECK-NEXT: [[GV:%[0-9]+]]:_(p0) = G_GLOBAL_VALUE @g + 4
62 ; CHECK-NEXT: $x0 = COPY [[GV]](p0)
63 ; CHECK-NEXT: RET_ReallyLR implicit $x0
64 %global:_(p0) = G_GLOBAL_VALUE @g + 3
65 %offset:_(s64) = G_CONSTANT i64 1
66 %ptr_add:_(p0) = G_PTR_ADD %global, %offset(s64)
68 RET_ReallyLR implicit $x0
71 # We're allowed to have more than one G_PTR_ADD use. We should fold 1 into
72 # the G_GLOBAL_VALUE's offset.
74 name: two_ptr_adds_same_offset
76 tracksRegLiveness: true
77 machineFunctionInfo: {}
82 ; CHECK-LABEL: name: two_ptr_adds_same_offset
83 ; CHECK: liveins: $x0, $x1
85 ; CHECK-NEXT: %val1:_(s64) = COPY $x0
86 ; CHECK-NEXT: %val2:_(s64) = COPY $x1
87 ; CHECK-NEXT: [[GV:%[0-9]+]]:_(p0) = G_GLOBAL_VALUE @g + 1
88 ; CHECK-NEXT: G_STORE %val1(s64), [[GV]](p0) :: (store (s64))
89 ; CHECK-NEXT: G_STORE %val2(s64), [[GV]](p0) :: (store (s64))
90 ; CHECK-NEXT: RET_ReallyLR implicit $x0
91 %val1:_(s64) = COPY $x0
92 %val2:_(s64) = COPY $x1
93 %global:_(p0) = G_GLOBAL_VALUE @g
94 %offset:_(s64) = G_CONSTANT i64 1
95 %ptr_add1:_(p0) = G_PTR_ADD %global, %offset(s64)
96 %ptr_add2:_(p0) = G_PTR_ADD %global, %offset(s64)
97 G_STORE %val1:_(s64), %ptr_add1 :: (store (s64))
98 G_STORE %val2:_(s64), %ptr_add2 :: (store (s64))
99 RET_ReallyLR implicit $x0
102 # The lowest offset G_PTR_ADD (2) should be folded into the G_GLOBAL_VALUE.
104 # The other G_PTR_ADD should have its offset decremented by 2.
106 name: two_ptr_adds_different_offset
108 tracksRegLiveness: true
109 machineFunctionInfo: {}
114 ; CHECK-LABEL: name: two_ptr_adds_different_offset
115 ; CHECK: liveins: $x0, $x1
117 ; CHECK-NEXT: %val1:_(s64) = COPY $x0
118 ; CHECK-NEXT: %val2:_(s64) = COPY $x1
119 ; CHECK-NEXT: [[GV:%[0-9]+]]:_(p0) = G_GLOBAL_VALUE @g + 2
120 ; CHECK-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 8
121 ; CHECK-NEXT: %ptr_add2:_(p0) = G_PTR_ADD [[GV]], [[C]](s64)
122 ; CHECK-NEXT: G_STORE %val1(s64), [[GV]](p0) :: (store (s64))
123 ; CHECK-NEXT: G_STORE %val2(s64), %ptr_add2(p0) :: (store (s64))
124 ; CHECK-NEXT: RET_ReallyLR implicit $x0
125 %val1:_(s64) = COPY $x0
126 %val2:_(s64) = COPY $x1
127 %global:_(p0) = G_GLOBAL_VALUE @g
128 %offset1:_(s64) = G_CONSTANT i64 2
129 %offset2:_(s64) = G_CONSTANT i64 10
130 %ptr_add1:_(p0) = G_PTR_ADD %global, %offset1(s64)
131 %ptr_add2:_(p0) = G_PTR_ADD %global, %offset2(s64)
132 G_STORE %val1:_(s64), %ptr_add1 :: (store (s64))
133 G_STORE %val2:_(s64), %ptr_add2 :: (store (s64))
134 RET_ReallyLR implicit $x0
137 # We should be able to fold all of the G_PTR_ADDs, except for the last one
138 # into the G_GLOBAL_VALUE.
140 # (TypeAllocSize = 4, so the offset on the G_GLOBAL_VALUE can't go above
145 tracksRegLiveness: true
146 machineFunctionInfo: {}
151 ; CHECK-LABEL: name: ptr_add_chain
152 ; CHECK: liveins: $x0
154 ; CHECK-NEXT: [[GV:%[0-9]+]]:_(p0) = G_GLOBAL_VALUE @g + 1
155 ; CHECK-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 4
156 ; CHECK-NEXT: %dont_fold_me:_(p0) = G_PTR_ADD [[GV]], [[C]](s64)
157 ; CHECK-NEXT: $x0 = COPY %dont_fold_me(p0)
158 ; CHECK-NEXT: RET_ReallyLR implicit $x0
159 %global:_(p0) = G_GLOBAL_VALUE @g
160 %offset:_(s64) = G_CONSTANT i64 1
161 %ptr_add1:_(p0) = G_PTR_ADD %global, %offset(s64)
162 %ptr_add2:_(p0) = G_PTR_ADD %ptr_add1, %offset(s64)
163 %ptr_add3:_(p0) = G_PTR_ADD %ptr_add2, %offset(s64)
164 %ptr_add4:_(p0) = G_PTR_ADD %ptr_add3, %offset(s64)
165 %dont_fold_me:_(p0) = G_PTR_ADD %ptr_add4, %offset(s64)
166 $x0 = COPY %dont_fold_me
167 RET_ReallyLR implicit $x0
170 # Do not add negative offsets to G_GLOBAL_VALUE.
172 name: dont_fold_negative_offset
174 tracksRegLiveness: true
175 machineFunctionInfo: {}
180 ; CHECK-LABEL: name: dont_fold_negative_offset
181 ; CHECK: liveins: $x0
183 ; CHECK-NEXT: %global:_(p0) = G_GLOBAL_VALUE @g
184 ; CHECK-NEXT: %offset:_(s64) = G_CONSTANT i64 -1
185 ; CHECK-NEXT: %ptr_add:_(p0) = G_PTR_ADD %global, %offset(s64)
186 ; CHECK-NEXT: $x0 = COPY %ptr_add(p0)
187 ; CHECK-NEXT: RET_ReallyLR implicit $x0
188 %global:_(p0) = G_GLOBAL_VALUE @g
189 %offset:_(s64) = G_CONSTANT i64 -1
190 %ptr_add:_(p0) = G_PTR_ADD %global, %offset(s64)
192 RET_ReallyLR implicit $x0
195 # Do not create smaller offsets. Ensures combine termination.
197 name: dont_min_offset_less_than_curr_offset
199 tracksRegLiveness: true
200 machineFunctionInfo: {}
205 ; CHECK-LABEL: name: dont_min_offset_less_than_curr_offset
206 ; CHECK: liveins: $x0
208 ; CHECK-NEXT: %global:_(p0) = G_GLOBAL_VALUE @g + 3
209 ; CHECK-NEXT: %offset:_(s64) = G_CONSTANT i64 -1
210 ; CHECK-NEXT: %ptr_add:_(p0) = G_PTR_ADD %global, %offset(s64)
211 ; CHECK-NEXT: $x0 = COPY %ptr_add(p0)
212 ; CHECK-NEXT: RET_ReallyLR implicit $x0
213 %global:_(p0) = G_GLOBAL_VALUE @g + 3
214 %offset:_(s64) = G_CONSTANT i64 -1
215 %ptr_add:_(p0) = G_PTR_ADD %global, %offset(s64)
217 RET_ReallyLR implicit $x0
220 # 1 << 21 is the largest offset expressible in all object formats.
223 name: dont_fold_max_offset
225 tracksRegLiveness: true
226 machineFunctionInfo: {}
231 ; CHECK-LABEL: name: dont_fold_max_offset
232 ; CHECK: liveins: $x0
234 ; CHECK-NEXT: %global:_(p0) = G_GLOBAL_VALUE @g
235 ; CHECK-NEXT: %offset:_(s64) = G_CONSTANT i64 4292870144
236 ; CHECK-NEXT: %ptr_add:_(p0) = G_PTR_ADD %global, %offset(s64)
237 ; CHECK-NEXT: $x0 = COPY %ptr_add(p0)
238 ; CHECK-NEXT: RET_ReallyLR implicit $x0
239 %global:_(p0) = G_GLOBAL_VALUE @g
240 %offset:_(s64) = G_CONSTANT i64 4292870144 ; 1 << 21
241 %ptr_add:_(p0) = G_PTR_ADD %global, %offset(s64)
243 RET_ReallyLR implicit $x0
246 # Type alloc size = 4, offset = 16. Don't fold.
248 name: dont_fold_offset_larger_than_type_alloc
250 tracksRegLiveness: true
251 machineFunctionInfo: {}
255 ; CHECK-LABEL: name: dont_fold_offset_larger_than_type_alloc
256 ; CHECK: %global:_(p0) = G_GLOBAL_VALUE @g
257 ; CHECK-NEXT: %offset:_(s64) = G_CONSTANT i64 16
258 ; CHECK-NEXT: %ptr_add:_(p0) = G_PTR_ADD %global, %offset(s64)
259 ; CHECK-NEXT: $x0 = COPY %ptr_add(p0)
260 ; CHECK-NEXT: RET_ReallyLR implicit $x0
261 %global:_(p0) = G_GLOBAL_VALUE @g
262 %offset:_(s64) = G_CONSTANT i64 16
263 %ptr_add:_(p0) = G_PTR_ADD %global, %offset(s64)
264 $x0 = COPY %ptr_add(p0)
265 RET_ReallyLR implicit $x0
268 # Check that we don't touch unsized globals.
270 name: dont_fold_unsized_type
272 tracksRegLiveness: true
273 machineFunctionInfo: {}
277 ; CHECK-LABEL: name: dont_fold_unsized_type
278 ; CHECK: %global:_(p0) = G_GLOBAL_VALUE @unsized
279 ; CHECK-NEXT: %offset:_(s64) = G_CONSTANT i64 16
280 ; CHECK-NEXT: %ptr_add:_(p0) = G_PTR_ADD %global, %offset(s64)
281 ; CHECK-NEXT: $x0 = COPY %ptr_add(p0)
282 ; CHECK-NEXT: RET_ReallyLR implicit $x0
283 %global:_(p0) = G_GLOBAL_VALUE @unsized
284 %offset:_(s64) = G_CONSTANT i64 16
285 %ptr_add:_(p0) = G_PTR_ADD %global, %offset(s64)
286 $x0 = COPY %ptr_add(p0)
287 RET_ReallyLR implicit $x0
290 # Check that we don't touch thread-local globals.
292 name: dont_fold_thread_local
294 tracksRegLiveness: true
295 machineFunctionInfo: {}
299 ; CHECK-LABEL: name: dont_fold_thread_local
300 ; CHECK: %global:_(p0) = G_GLOBAL_VALUE @thread_local
301 ; CHECK-NEXT: %offset:_(s64) = G_CONSTANT i64 16
302 ; CHECK-NEXT: %ptr_add:_(p0) = G_PTR_ADD %global, %offset(s64)
303 ; CHECK-NEXT: $x0 = COPY %ptr_add(p0)
304 ; CHECK-NEXT: RET_ReallyLR implicit $x0
305 %global:_(p0) = G_GLOBAL_VALUE @thread_local
306 %offset:_(s64) = G_CONSTANT i64 16
307 %ptr_add:_(p0) = G_PTR_ADD %global, %offset(s64)
308 $x0 = COPY %ptr_add(p0)
309 RET_ReallyLR implicit $x0