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
5 define void @func0() { ret void }
7 declare void @extfunc()
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
17 # Check various LOH variants. Remember that the algorithms walks the basic
19 # CHECK-LABEL: ********** AArch64 Collect LOH **********
20 # CHECK-LABEL: Looking in function func0
22 tracksRegLiveness: true
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
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
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
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
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
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
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
100 ; CHECK-NOT: Adding MCLOH_AdrpLdrGot:
101 ; Loading a float value from a GOT table makes no sense so this should not
103 $x11 = ADRP target-flags(aarch64-page, aarch64-got) @g5
104 $s11 = LDRSui $x11, target-flags(aarch64-pageoff, aarch64-got) @g5
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
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
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
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
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
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
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
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
173 ; CHECK-NOT: MCLOH_AdrpAdrp
174 ; CHECK: Adding MCLOH_AdrpAddLdr
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
181 $x9 = ADRP target-flags(aarch64-page, aarch64-got) @g5
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
192 $x12 = ADDXri $x10, target-flags(aarch64-pageoff) @g0, 0
195 ; Should not produce a LOH when reg is clobbered by bundled regmask
196 ; CHECK-NOT: MCLOH_AdrpAdrp
197 $x8 = ADRP target-flags(aarch64-page) @g0
199 BL @extfunc, csr_aarch64_aapcs
201 $x8 = ADRP target-flags(aarch64-page) @g1