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 }
27 tracksRegLiveness: true
28 machineFunctionInfo: {}
33 ; We should fold the offset 1 into the G_GLOBAL_VALUE.
35 ; CHECK-LABEL: name: one_ptr_add
37 ; CHECK: [[GV:%[0-9]+]]:_(p0) = G_GLOBAL_VALUE @g + 1
38 ; CHECK: $x0 = COPY [[GV]](p0)
39 ; CHECK: 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
50 tracksRegLiveness: true
51 machineFunctionInfo: {}
56 ; We should fold the offset 1 into the G_GLOBAL_VALUE, resulting in a
59 ; CHECK-LABEL: name: add_to_offset
61 ; CHECK: [[GV:%[0-9]+]]:_(p0) = G_GLOBAL_VALUE @g + 4
62 ; CHECK: $x0 = COPY [[GV]](p0)
63 ; CHECK: 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
72 name: two_ptr_adds_same_offset
74 tracksRegLiveness: true
75 machineFunctionInfo: {}
80 ; We're allowed to have more than one G_PTR_ADD use. We should fold 1 into
81 ; the G_GLOBAL_VALUE's offset.
83 ; CHECK-LABEL: name: two_ptr_adds_same_offset
84 ; CHECK: liveins: $x0, $x1
85 ; CHECK: %val1:_(s64) = COPY $x0
86 ; CHECK: %val2:_(s64) = COPY $x1
87 ; CHECK: [[GV:%[0-9]+]]:_(p0) = G_GLOBAL_VALUE @g + 1
88 ; CHECK: G_STORE %val1(s64), [[GV]](p0) :: (store (s64))
89 ; CHECK: G_STORE %val2(s64), [[GV]](p0) :: (store (s64))
90 ; CHECK: 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
103 name: two_ptr_adds_different_offset
105 tracksRegLiveness: true
106 machineFunctionInfo: {}
110 ; The lowest offset G_PTR_ADD (2) should be folded into the G_GLOBAL_VALUE.
112 ; The other G_PTR_ADD should have its offset decremented by 2.
114 ; CHECK-LABEL: name: two_ptr_adds_different_offset
115 ; CHECK: liveins: $x0, $x1
116 ; CHECK: %val1:_(s64) = COPY $x0
117 ; CHECK: %val2:_(s64) = COPY $x1
118 ; CHECK: [[GV:%[0-9]+]]:_(p0) = G_GLOBAL_VALUE @g + 2
119 ; CHECK: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 8
120 ; CHECK: %ptr_add2:_(p0) = G_PTR_ADD [[GV]], [[C]](s64)
121 ; CHECK: G_STORE %val1(s64), [[GV]](p0) :: (store (s64))
122 ; CHECK: G_STORE %val2(s64), %ptr_add2(p0) :: (store (s64))
123 ; CHECK: RET_ReallyLR implicit $x0
124 %val1:_(s64) = COPY $x0
125 %val2:_(s64) = COPY $x1
126 %global:_(p0) = G_GLOBAL_VALUE @g
127 %offset1:_(s64) = G_CONSTANT i64 2
128 %offset2:_(s64) = G_CONSTANT i64 10
129 %ptr_add1:_(p0) = G_PTR_ADD %global, %offset1(s64)
130 %ptr_add2:_(p0) = G_PTR_ADD %global, %offset2(s64)
131 G_STORE %val1:_(s64), %ptr_add1 :: (store (s64))
132 G_STORE %val2:_(s64), %ptr_add2 :: (store (s64))
133 RET_ReallyLR implicit $x0
139 tracksRegLiveness: true
140 machineFunctionInfo: {}
144 ; We should be able to fold all of the G_PTR_ADDs, except for the last one
145 ; into the G_GLOBAL_VALUE.
147 ; (TypeAllocSize = 4, so the offset on the G_GLOBAL_VALUE can't go above
150 ; CHECK-LABEL: name: ptr_add_chain
151 ; CHECK: liveins: $x0
152 ; CHECK: [[GV:%[0-9]+]]:_(p0) = G_GLOBAL_VALUE @g + 1
153 ; CHECK: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 4
154 ; CHECK: %dont_fold_me:_(p0) = G_PTR_ADD [[GV]], [[C]](s64)
155 ; CHECK: $x0 = COPY %dont_fold_me(p0)
156 ; CHECK: RET_ReallyLR implicit $x0
157 %global:_(p0) = G_GLOBAL_VALUE @g
158 %offset:_(s64) = G_CONSTANT i64 1
159 %ptr_add1:_(p0) = G_PTR_ADD %global, %offset(s64)
160 %ptr_add2:_(p0) = G_PTR_ADD %ptr_add1, %offset(s64)
161 %ptr_add3:_(p0) = G_PTR_ADD %ptr_add2, %offset(s64)
162 %ptr_add4:_(p0) = G_PTR_ADD %ptr_add3, %offset(s64)
163 %dont_fold_me:_(p0) = G_PTR_ADD %ptr_add4, %offset(s64)
164 $x0 = COPY %dont_fold_me
165 RET_ReallyLR implicit $x0
169 name: dont_fold_negative_offset
171 tracksRegLiveness: true
172 machineFunctionInfo: {}
177 ; Do not add negative offsets to G_GLOBAL_VALUE.
179 ; CHECK-LABEL: name: dont_fold_negative_offset
180 ; CHECK: liveins: $x0
181 ; CHECK: %global:_(p0) = G_GLOBAL_VALUE @g
182 ; CHECK: %offset:_(s64) = G_CONSTANT i64 -1
183 ; CHECK: %ptr_add:_(p0) = G_PTR_ADD %global, %offset(s64)
184 ; CHECK: $x0 = COPY %ptr_add(p0)
185 ; CHECK: RET_ReallyLR implicit $x0
186 %global:_(p0) = G_GLOBAL_VALUE @g
187 %offset:_(s64) = G_CONSTANT i64 -1
188 %ptr_add:_(p0) = G_PTR_ADD %global, %offset(s64)
190 RET_ReallyLR implicit $x0
194 name: dont_min_offset_less_than_curr_offset
196 tracksRegLiveness: true
197 machineFunctionInfo: {}
202 ; Do not create smaller offsets. Ensures combine termination.
204 ; CHECK-LABEL: name: dont_min_offset_less_than_curr_offset
205 ; CHECK: liveins: $x0
206 ; CHECK: %global:_(p0) = G_GLOBAL_VALUE @g + 3
207 ; CHECK: %offset:_(s64) = G_CONSTANT i64 -1
208 ; CHECK: %ptr_add:_(p0) = G_PTR_ADD %global, %offset(s64)
209 ; CHECK: $x0 = COPY %ptr_add(p0)
210 ; CHECK: RET_ReallyLR implicit $x0
211 %global:_(p0) = G_GLOBAL_VALUE @g + 3
212 %offset:_(s64) = G_CONSTANT i64 -1
213 %ptr_add:_(p0) = G_PTR_ADD %global, %offset(s64)
215 RET_ReallyLR implicit $x0
219 name: dont_fold_max_offset
221 tracksRegLiveness: true
222 machineFunctionInfo: {}
227 ; 1 << 21 is the largest offset expressible in all object formats.
230 ; CHECK-LABEL: name: dont_fold_max_offset
231 ; CHECK: liveins: $x0
232 ; CHECK: %global:_(p0) = G_GLOBAL_VALUE @g
233 ; CHECK: %offset:_(s64) = G_CONSTANT i64 4292870144
234 ; CHECK: %ptr_add:_(p0) = G_PTR_ADD %global, %offset(s64)
235 ; CHECK: $x0 = COPY %ptr_add(p0)
236 ; CHECK: RET_ReallyLR implicit $x0
237 %global:_(p0) = G_GLOBAL_VALUE @g
238 %offset:_(s64) = G_CONSTANT i64 4292870144 ; 1 << 21
239 %ptr_add:_(p0) = G_PTR_ADD %global, %offset(s64)
241 RET_ReallyLR implicit $x0
245 name: dont_fold_offset_larger_than_type_alloc
247 tracksRegLiveness: true
248 machineFunctionInfo: {}
252 ; Type alloc size = 4, offset = 16. Don't fold.
254 ; CHECK-LABEL: name: dont_fold_offset_larger_than_type_alloc
255 ; CHECK: %global:_(p0) = G_GLOBAL_VALUE @g
256 ; CHECK: %offset:_(s64) = G_CONSTANT i64 16
257 ; CHECK: %ptr_add:_(p0) = G_PTR_ADD %global, %offset(s64)
258 ; CHECK: $x0 = COPY %ptr_add(p0)
259 ; CHECK: RET_ReallyLR implicit $x0
260 %global:_(p0) = G_GLOBAL_VALUE @g
261 %offset:_(s64) = G_CONSTANT i64 16
262 %ptr_add:_(p0) = G_PTR_ADD %global, %offset(s64)
263 $x0 = COPY %ptr_add(p0)
264 RET_ReallyLR implicit $x0
268 name: dont_fold_unsized_type
270 tracksRegLiveness: true
271 machineFunctionInfo: {}
274 ; Check that we don't touch unsized globals.
276 ; CHECK-LABEL: name: dont_fold_unsized_type
277 ; CHECK: %global:_(p0) = G_GLOBAL_VALUE @unsized
278 ; CHECK: %offset:_(s64) = G_CONSTANT i64 16
279 ; CHECK: %ptr_add:_(p0) = G_PTR_ADD %global, %offset(s64)
280 ; CHECK: $x0 = COPY %ptr_add(p0)
281 ; CHECK: RET_ReallyLR implicit $x0
282 %global:_(p0) = G_GLOBAL_VALUE @unsized
283 %offset:_(s64) = G_CONSTANT i64 16
284 %ptr_add:_(p0) = G_PTR_ADD %global, %offset(s64)
285 $x0 = COPY %ptr_add(p0)
286 RET_ReallyLR implicit $x0
290 name: dont_fold_thread_local
292 tracksRegLiveness: true
293 machineFunctionInfo: {}
296 ; Check that we don't touch thread-local globals.
298 ; CHECK-LABEL: name: dont_fold_thread_local
299 ; CHECK: %global:_(p0) = G_GLOBAL_VALUE @thread_local
300 ; CHECK: %offset:_(s64) = G_CONSTANT i64 16
301 ; CHECK: %ptr_add:_(p0) = G_PTR_ADD %global, %offset(s64)
302 ; CHECK: $x0 = COPY %ptr_add(p0)
303 ; CHECK: RET_ReallyLR implicit $x0
304 %global:_(p0) = G_GLOBAL_VALUE @thread_local
305 %offset:_(s64) = G_CONSTANT i64 16
306 %ptr_add:_(p0) = G_PTR_ADD %global, %offset(s64)
307 $x0 = COPY %ptr_add(p0)
308 RET_ReallyLR implicit $x0