1# RUN: llc -o /dev/null %s -mtriple=aarch64-apple-ios -run-pass=aarch64-collect-loh -debug-only=aarch64-collect-loh 2>&1 | FileCheck %s
2# RUN: llc -debugify-and-strip-all-safe -o /dev/null %s -mtriple=aarch64-apple-ios -run-pass=aarch64-collect-loh -debug-only=aarch64-collect-loh 2>&1 | FileCheck %s
3# REQUIRES: asserts
4--- |
5  define void @func0() { ret void }
6
7  declare void @extfunc()
8
9  @g0 = external global i32
10  @g1 = external global i32
11  @g2 = external global i32
12  @g3 = external global i32
13  @g4 = external global i32
14  @g5 = external global i32
15...
16---
17# Check various LOH variants. Remember that the algorithms walks the basic
18# blocks backwards.
19# CHECK-LABEL: ********** AArch64 Collect LOH **********
20# CHECK-LABEL: Looking in function func0
21name: func0
22tracksRegLiveness: true
23body: |
24  bb.0:
25    ; CHECK: Adding MCLOH_AdrpAdrp:
26    ; CHECK-NEXT: $x1 = ADRP target-flags(aarch64-page) @g3
27    ; CHECK-NEXT: $x1 = ADRP target-flags(aarch64-page) @g4
28    ; CHECK-NEXT: Adding MCLOH_AdrpAdrp:
29    ; CHECK-NEXT: $x1 = ADRP target-flags(aarch64-page) @g2
30    ; CHECK-NEXT: $x1 = ADRP target-flags(aarch64-page) @g3
31    ; CHECK-NEXT: Adding MCLOH_AdrpAdrp:
32    ; CHECK-NEXT: $x0 = ADRP target-flags(aarch64-page) @g0
33    ; CHECK-NEXT: $x0 = ADRP target-flags(aarch64-page) @g1
34    $x0 = ADRP target-flags(aarch64-page) @g0
35    $x0 = ADRP target-flags(aarch64-page) @g1
36    $x1 = ADRP target-flags(aarch64-page) @g2
37    $x1 = ADRP target-flags(aarch64-page) @g3
38    $x1 = ADRP target-flags(aarch64-page) @g4
39
40  bb.1:
41    ; CHECK-NEXT: Adding MCLOH_AdrpAdd:
42    ; CHECK-NEXT: $x20 = ADRP target-flags(aarch64-page) @g0
43    ; CHECK-NEXT: $x3 = ADDXri $x20, target-flags(aarch64-pageoff) @g0
44    ; CHECK-NEXT: Adding MCLOH_AdrpAdd:
45    ; CHECK-NEXT: $x1 = ADRP target-flags(aarch64-page) @g0
46    ; CHECK-NEXT: $x1 = ADDXri $x1, target-flags(aarch64-pageoff) @g0
47    $x1 = ADRP target-flags(aarch64-page) @g0
48    $x9 = SUBXri undef $x11, 5, 0 ; should not affect MCLOH formation
49    $x1 = ADDXri $x1, target-flags(aarch64-pageoff) @g0, 0
50    $x20 = ADRP target-flags(aarch64-page) @g0
51    BL @extfunc, csr_aarch64_aapcs ; should not clobber X20
52    $x3 = ADDXri $x20, target-flags(aarch64-pageoff) @g0, 0
53
54  bb.2:
55    ; CHECK-NOT: MCLOH_AdrpAdd
56    $x9 = ADRP target-flags(aarch64-page) @g0
57    BL @extfunc, csr_aarch64_aapcs ; clobbers x9
58    ; Verification requires the use of 'undef' in front of the clobbered $x9
59    $x9 = ADDXri undef $x9, target-flags(aarch64-pageoff) @g0, 0
60
61  bb.3:
62    ; CHECK-NOT: MCLOH_AdrpAdd
63    $x10 = ADRP target-flags(aarch64-page) @g0
64    HINT 0, implicit def $x10 ; clobbers x10
65    $x10 = ADDXri $x10, target-flags(aarch64-pageoff) @g0, 0
66
67  bb.4:
68    ; Cannot produce a LOH for multiple users
69    ; CHECK-NOT: MCLOH_AdrpAdd
70    $x10 = ADRP target-flags(aarch64-page) @g0
71    HINT 0, implicit def $x10 ; clobbers x10
72    $x11 = ADDXri $x10, target-flags(aarch64-pageoff) @g0, 0
73    $x12 = ADDXri $x10, target-flags(aarch64-pageoff) @g0, 0
74
75  bb.5:
76    ; CHECK-NEXT: Adding MCLOH_AdrpLdr:
77    ; CHECK-NEXT: $x5 = ADRP target-flags(aarch64-page) @g2
78    ; CHECK-NEXT: $s6 = LDRSui $x5, target-flags(aarch64-pageoff) @g2
79    ; CHECK-NEXT: Adding MCLOH_AdrpLdr:
80    ; CHECK-NEXT: $x4 = ADRP target-flags(aarch64-page) @g2
81    ; CHECK-NEXT: $x4 = LDRXui $x4, target-flags(aarch64-pageoff) @g2
82    $x4 = ADRP target-flags(aarch64-page) @g2
83    $x4 = LDRXui $x4, target-flags(aarch64-pageoff) @g2
84    $x5 = ADRP target-flags(aarch64-page) @g2
85    $s6 = LDRSui $x5, target-flags(aarch64-pageoff) @g2
86
87  bb.6:
88    ; CHECK-NEXT: Adding MCLOH_AdrpLdrGot:
89    ; CHECK-NEXT: $x5 = ADRP target-flags(aarch64-page, aarch64-got) @g2
90    ; CHECK-NEXT: $x6 = LDRXui $x5, target-flags(aarch64-pageoff, aarch64-got) @g2
91    ; CHECK-NEXT: Adding MCLOH_AdrpLdrGot:
92    ; CHECK-NEXT: $x4 = ADRP target-flags(aarch64-page, aarch64-got) @g2
93    ; CHECK-NEXT: $x4 = LDRXui $x4, target-flags(aarch64-pageoff, aarch64-got) @g2
94    $x4 = ADRP target-flags(aarch64-page, aarch64-got) @g2
95    $x4 = LDRXui $x4, target-flags(aarch64-pageoff, aarch64-got) @g2
96    $x5 = ADRP target-flags(aarch64-page, aarch64-got) @g2
97    $x6 = LDRXui $x5, target-flags(aarch64-pageoff, aarch64-got) @g2
98
99  bb.7:
100    ; CHECK-NOT: Adding MCLOH_AdrpLdrGot:
101    ; Loading a float value from a GOT table makes no sense so this should not
102    ; produce an LOH.
103    $x11 = ADRP target-flags(aarch64-page, aarch64-got) @g5
104    $s11 = LDRSui $x11, target-flags(aarch64-pageoff, aarch64-got) @g5
105
106  bb.8:
107    ; CHECK-NEXT: Adding MCLOH_AdrpAddLdr:
108    ; CHECK-NEXT: $x7 = ADRP target-flags(aarch64-page) @g3
109    ; CHECK-NEXT: $x8 = ADDXri $x7, target-flags(aarch64-pageoff) @g3
110    ; CHECK-NEXT: $d1 = LDRDui $x8, 8
111    $x7 = ADRP target-flags(aarch64-page) @g3
112    $x8 = ADDXri $x7, target-flags(aarch64-pageoff) @g3, 0
113    $d1 = LDRDui $x8, 8
114
115  bb.9:
116    ; CHECK-NEXT: Adding MCLOH_AdrpAdd:
117    ; CHECK-NEXT: $x3 = ADRP target-flags(aarch64-page) @g3
118    ; CHECK-NEXT: $x3 = ADDXri $x3, target-flags(aarch64-pageoff) @g3
119    ; CHECK-NEXT: Adding MCLOH_AdrpAdd:
120    ; CHECK-NEXT: $x5 = ADRP target-flags(aarch64-page) @g3
121    ; CHECK-NEXT: $x2 = ADDXri $x5, target-flags(aarch64-pageoff) @g3
122    ; CHECK-NEXT: Adding MCLOH_AdrpAddStr:
123    ; CHECK-NEXT: $x1 = ADRP target-flags(aarch64-page) @g3
124    ; CHECK-NEXT: $x1 = ADDXri $x1, target-flags(aarch64-pageoff) @g3
125    ; CHECK-NEXT: STRXui $xzr, $x1, 16
126    $x1 = ADRP target-flags(aarch64-page) @g3
127    $x1 = ADDXri $x1, target-flags(aarch64-pageoff) @g3, 0
128    STRXui $xzr, $x1, 16
129
130    ; This sequence should just produce an AdrpAdd (not AdrpAddStr)
131    $x5 = ADRP target-flags(aarch64-page) @g3
132    $x2 = ADDXri $x5, target-flags(aarch64-pageoff) @g3, 0
133    STRXui $x2, undef $x11, 16
134
135    ; This sequence should just produce an AdrpAdd (not AdrpAddStr)
136    $x3 = ADRP target-flags(aarch64-page) @g3
137    $x3 = ADDXri $x3, target-flags(aarch64-pageoff) @g3, 0
138    STRXui $x3, $x3, 16
139
140  bb.10:
141    ; CHECK-NEXT: Adding MCLOH_AdrpLdr:
142    ; CHECK-NEXT: $x2 = ADRP target-flags(aarch64-page) @g3
143    ; CHECK-NEXT: $x2 = LDRXui $x2, target-flags(aarch64-pageoff) @g3
144    ; CHECK-NEXT: Adding MCLOH_AdrpLdrGotLdr:
145    ; CHECK-NEXT: $x1 = ADRP target-flags(aarch64-page, aarch64-got) @g4
146    ; CHECK-NEXT: $x1 = LDRXui $x1, target-flags(aarch64-pageoff, aarch64-got) @g4
147    ; CHECK-NEXT: $x1 = LDRXui $x1, 24
148    $x1 = ADRP target-flags(aarch64-page, aarch64-got) @g4
149    $x1 = LDRXui $x1, target-flags(aarch64-pageoff, aarch64-got) @g4
150    $x1 = LDRXui $x1, 24
151    ; Should just produce a MCLOH_AdrpLdr (not MCLOH_AdrpLdrGotLdr)
152    $x2 = ADRP target-flags(aarch64-page) @g3
153    $x2 = LDRXui $x2, target-flags(aarch64-pageoff) @g3
154    $x2 = LDRXui $x2, 24
155
156  bb.11:
157    ; CHECK-NEXT: Adding MCLOH_AdrpLdr
158    ; CHECK-NEXT: $x5 = ADRP target-flags(aarch64-page) @g1
159    ; CHECK-NEXT: $x5 = LDRXui $x5, target-flags(aarch64-pageoff) @g1
160    ; CHECK-NEXT: Adding MCLOH_AdrpLdrGotStr:
161    ; CHECK-NEXT: $x1 = ADRP target-flags(aarch64-page, aarch64-got) @g4
162    ; CHECK-NEXT: $x1 = LDRXui $x1, target-flags(aarch64-pageoff, aarch64-got) @g4
163    ; CHECK-NEXT: STRXui $xzr, $x1, 32
164    $x1 = ADRP target-flags(aarch64-page, aarch64-got) @g4
165    $x1 = LDRXui $x1, target-flags(aarch64-pageoff, aarch64-got) @g4
166    STRXui $xzr, $x1, 32
167    ; Should just produce a MCLOH_AdrpLdr (not MCLOH_AdrpLdrGotStr)
168    $x5 = ADRP target-flags(aarch64-page) @g1
169    $x5 = LDRXui $x5, target-flags(aarch64-pageoff) @g1
170    STRXui undef $x11, $x5, 32
171
172  bb.12:
173    ; CHECK-NOT: MCLOH_AdrpAdrp
174    ; CHECK: Adding MCLOH_AdrpAddLdr
175    ; $x9 = ADRP @g4
176    ; $x9 = ADDXri $x9, @g4
177    ; $x5 = LDRXui $x9, 0
178    $x9 = ADRP target-flags(aarch64-page, aarch64-got) @g4
179    $x9 = ADDXri $x9, target-flags(aarch64-pageoff, aarch64-got) @g4, 0
180    $x5 = LDRXui $x9, 0
181    $x9 = ADRP target-flags(aarch64-page, aarch64-got) @g5
182
183  bb.13:
184    ; Cannot produce a LOH for multiple users
185    ; CHECK-NOT: MCLOH_AdrpAdd
186    $x10 = ADRP target-flags(aarch64-page) @g0
187    $x11 = ADDXri $x10, target-flags(aarch64-pageoff) @g0, 0
188    B %bb.14
189
190  bb.14:
191    liveins: $x10
192    $x12 = ADDXri $x10, target-flags(aarch64-pageoff) @g0, 0
193...
194