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