77
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1 ; RUN: llc -mtriple=arm64-apple-ios -O2 -aarch64-collect-loh -aarch64-collect-loh-bb-only=false < %s -o - | FileCheck %s
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
2 ; RUN: llc -mtriple=arm64-linux-gnu -O2 -aarch64-collect-loh -aarch64-collect-loh-bb-only=false < %s -o - | FileCheck %s --check-prefix=CHECK-ELF
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
3
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
4 ; CHECK-ELF-NOT: .loh
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
5 ; CHECK-ELF-NOT: AdrpAdrp
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
6 ; CHECK-ELF-NOT: AdrpAdd
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
7 ; CHECK-ELF-NOT: AdrpLdrGot
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
8
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
9 @a = internal unnamed_addr global i32 0, align 4
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
10 @b = external global i32
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
11
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
12 ; Function Attrs: noinline nounwind ssp
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
13 define void @foo(i32 %t) {
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
14 entry:
|
95
|
15 %tmp = load i32, i32* @a, align 4
|
77
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
16 %add = add nsw i32 %tmp, %t
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
17 store i32 %add, i32* @a, align 4
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
18 ret void
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
19 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
20
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
21 ; Function Attrs: nounwind ssp
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
22 ; Testcase for <rdar://problem/15438605>, AdrpAdrp reuse is valid only when the first adrp
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
23 ; dominates the second.
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
24 ; The first adrp comes from the loading of 'a' and the second the loading of 'b'.
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
25 ; 'a' is loaded in if.then, 'b' in if.end4, if.then does not dominates if.end4.
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
26 ; CHECK-LABEL: _test
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
27 ; CHECK: ret
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
28 ; CHECK-NOT: .loh AdrpAdrp
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
29 define i32 @test(i32 %t) {
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
30 entry:
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
31 %cmp = icmp sgt i32 %t, 5
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
32 br i1 %cmp, label %if.then, label %if.end4
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
33
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
34 if.then: ; preds = %entry
|
95
|
35 %tmp = load i32, i32* @a, align 4
|
77
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
36 %add = add nsw i32 %tmp, %t
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
37 %cmp1 = icmp sgt i32 %add, 12
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
38 br i1 %cmp1, label %if.then2, label %if.end4
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
39
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
40 if.then2: ; preds = %if.then
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
41 tail call void @foo(i32 %add)
|
95
|
42 %tmp1 = load i32, i32* @a, align 4
|
77
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
43 br label %if.end4
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
44
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
45 if.end4: ; preds = %if.then2, %if.then, %entry
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
46 %t.addr.0 = phi i32 [ %tmp1, %if.then2 ], [ %t, %if.then ], [ %t, %entry ]
|
95
|
47 %tmp2 = load i32, i32* @b, align 4
|
77
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
48 %add5 = add nsw i32 %tmp2, %t.addr.0
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
49 tail call void @foo(i32 %add5)
|
95
|
50 %tmp3 = load i32, i32* @b, align 4
|
77
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
51 %add6 = add nsw i32 %tmp3, %t.addr.0
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
52 ret i32 %add6
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
53 }
|
95
|
54
|
|
55 @C = common global i32 0, align 4
|
|
56
|
|
57 ; Check that we catch AdrpLdrGotLdr case when we have a simple chain:
|
|
58 ; adrp -> ldrgot -> ldr.
|
|
59 ; CHECK-LABEL: _getC
|
|
60 ; CHECK: [[ADRP_LABEL:Lloh[0-9]+]]:
|
|
61 ; CHECK-NEXT: adrp [[ADRP_REG:x[0-9]+]], _C@GOTPAGE
|
|
62 ; CHECK-NEXT: [[LDRGOT_LABEL:Lloh[0-9]+]]:
|
|
63 ; CHECK-NEXT: ldr [[LDRGOT_REG:x[0-9]+]], {{\[}}[[ADRP_REG]], _C@GOTPAGEOFF]
|
|
64 ; CHECK-NEXT: [[LDR_LABEL:Lloh[0-9]+]]:
|
|
65 ; CHECK-NEXT: ldr w0, {{\[}}[[LDRGOT_REG]]]
|
|
66 ; CHECK-NEXT: ret
|
|
67 ; CHECK: .loh AdrpLdrGotLdr [[ADRP_LABEL]], [[LDRGOT_LABEL]], [[LDR_LABEL]]
|
|
68 define i32 @getC() {
|
|
69 %res = load i32, i32* @C, align 4
|
|
70 ret i32 %res
|
|
71 }
|
|
72
|
|
73 ; LDRSW supports loading from a literal.
|
|
74 ; Make sure we emit AdrpLdrGotLdr for those.
|
|
75 ; CHECK-LABEL: _getSExtC
|
|
76 ; CHECK: [[ADRP_LABEL:Lloh[0-9]+]]:
|
|
77 ; CHECK-NEXT: adrp [[ADRP_REG:x[0-9]+]], _C@GOTPAGE
|
|
78 ; CHECK-NEXT: [[LDRGOT_LABEL:Lloh[0-9]+]]:
|
|
79 ; CHECK-NEXT: ldr [[LDRGOT_REG:x[0-9]+]], {{\[}}[[ADRP_REG]], _C@GOTPAGEOFF]
|
|
80 ; CHECK-NEXT: [[LDR_LABEL:Lloh[0-9]+]]:
|
|
81 ; CHECK-NEXT: ldrsw x0, {{\[}}[[LDRGOT_REG]]]
|
|
82 ; CHECK-NEXT: ret
|
|
83 ; CHECK: .loh AdrpLdrGotLdr [[ADRP_LABEL]], [[LDRGOT_LABEL]], [[LDR_LABEL]]
|
|
84 define i64 @getSExtC() {
|
|
85 %res = load i32, i32* @C, align 4
|
|
86 %sextres = sext i32 %res to i64
|
|
87 ret i64 %sextres
|
|
88 }
|
|
89
|
|
90 ; It may not be safe to fold the literal in the load if the address is
|
|
91 ; used several times.
|
|
92 ; Make sure we emit AdrpLdrGot for those.
|
|
93 ; CHECK-LABEL: _getSeveralC
|
|
94 ; CHECK: [[ADRP_LABEL:Lloh[0-9]+]]:
|
|
95 ; CHECK-NEXT: adrp [[ADRP_REG:x[0-9]+]], _C@GOTPAGE
|
|
96 ; CHECK-NEXT: [[LDRGOT_LABEL:Lloh[0-9]+]]:
|
|
97 ; CHECK-NEXT: ldr [[LDRGOT_REG:x[0-9]+]], {{\[}}[[ADRP_REG]], _C@GOTPAGEOFF]
|
|
98 ; CHECK-NEXT: ldr [[LOAD:w[0-9]+]], {{\[}}[[LDRGOT_REG]]]
|
|
99 ; CHECK-NEXT: add [[ADD:w[0-9]+]], [[LOAD]], w0
|
|
100 ; CHECK-NEXT: str [[ADD]], {{\[}}[[LDRGOT_REG]]]
|
|
101 ; CHECK-NEXT: ret
|
|
102 ; CHECK: .loh AdrpLdrGot [[ADRP_LABEL]], [[LDRGOT_LABEL]]
|
|
103 define void @getSeveralC(i32 %t) {
|
|
104 entry:
|
|
105 %tmp = load i32, i32* @C, align 4
|
|
106 %add = add nsw i32 %tmp, %t
|
|
107 store i32 %add, i32* @C, align 4
|
|
108 ret void
|
|
109 }
|
|
110
|
|
111 ; Make sure we catch that:
|
|
112 ; adrp -> ldrgot -> str.
|
|
113 ; CHECK-LABEL: _setC
|
|
114 ; CHECK: [[ADRP_LABEL:Lloh[0-9]+]]:
|
|
115 ; CHECK-NEXT: adrp [[ADRP_REG:x[0-9]+]], _C@GOTPAGE
|
|
116 ; CHECK-NEXT: [[LDRGOT_LABEL:Lloh[0-9]+]]:
|
|
117 ; CHECK-NEXT: ldr [[LDRGOT_REG:x[0-9]+]], {{\[}}[[ADRP_REG]], _C@GOTPAGEOFF]
|
|
118 ; CHECK-NEXT: [[LDR_LABEL:Lloh[0-9]+]]:
|
|
119 ; CHECK-NEXT: str w0, {{\[}}[[LDRGOT_REG]]]
|
|
120 ; CHECK-NEXT: ret
|
|
121 ; CHECK: .loh AdrpLdrGotStr [[ADRP_LABEL]], [[LDRGOT_LABEL]], [[LDR_LABEL]]
|
|
122 define void @setC(i32 %t) {
|
|
123 entry:
|
|
124 store i32 %t, i32* @C, align 4
|
|
125 ret void
|
|
126 }
|
|
127
|
|
128 ; Perform the same tests for internal global and a displacement
|
|
129 ; in the addressing mode.
|
|
130 ; Indeed we will get an ADD for those instead of LOADGot.
|
|
131 @InternalC = internal global i32 0, align 4
|
|
132
|
|
133 ; Check that we catch AdrpAddLdr case when we have a simple chain:
|
|
134 ; adrp -> add -> ldr.
|
|
135 ; CHECK-LABEL: _getInternalCPlus4
|
|
136 ; CHECK: [[ADRP_LABEL:Lloh[0-9]+]]:
|
|
137 ; CHECK-NEXT: adrp [[ADRP_REG:x[0-9]+]], _InternalC@PAGE
|
|
138 ; CHECK-NEXT: [[ADDGOT_LABEL:Lloh[0-9]+]]:
|
|
139 ; CHECK-NEXT: add [[ADDGOT_REG:x[0-9]+]], [[ADRP_REG]], _InternalC@PAGEOFF
|
|
140 ; CHECK-NEXT: [[LDR_LABEL:Lloh[0-9]+]]:
|
|
141 ; CHECK-NEXT: ldr w0, {{\[}}[[ADDGOT_REG]], #16]
|
|
142 ; CHECK-NEXT: ret
|
|
143 ; CHECK: .loh AdrpAddLdr [[ADRP_LABEL]], [[ADDGOT_LABEL]], [[LDR_LABEL]]
|
|
144 define i32 @getInternalCPlus4() {
|
|
145 %addr = getelementptr i32, i32* @InternalC, i32 4
|
|
146 %res = load i32, i32* %addr, align 4
|
|
147 ret i32 %res
|
|
148 }
|
|
149
|
|
150 ; LDRSW supports loading from a literal.
|
|
151 ; Make sure we emit AdrpLdrGotLdr for those.
|
|
152 ; CHECK-LABEL: _getSExtInternalCPlus4
|
|
153 ; CHECK: [[ADRP_LABEL:Lloh[0-9]+]]:
|
|
154 ; CHECK-NEXT: adrp [[ADRP_REG:x[0-9]+]], _InternalC@PAGE
|
|
155 ; CHECK-NEXT: [[ADDGOT_LABEL:Lloh[0-9]+]]:
|
|
156 ; CHECK-NEXT: add [[ADDGOT_REG:x[0-9]+]], [[ADRP_REG]], _InternalC@PAGEOFF
|
|
157 ; CHECK-NEXT: [[LDR_LABEL:Lloh[0-9]+]]:
|
|
158 ; CHECK-NEXT: ldrsw x0, {{\[}}[[ADDGOT_REG]], #16]
|
|
159 ; CHECK-NEXT: ret
|
|
160 ; CHECK: .loh AdrpAddLdr [[ADRP_LABEL]], [[ADDGOT_LABEL]], [[LDR_LABEL]]
|
|
161 define i64 @getSExtInternalCPlus4() {
|
|
162 %addr = getelementptr i32, i32* @InternalC, i32 4
|
|
163 %res = load i32, i32* %addr, align 4
|
|
164 %sextres = sext i32 %res to i64
|
|
165 ret i64 %sextres
|
|
166 }
|
|
167
|
|
168 ; It may not be safe to fold the literal in the load if the address is
|
|
169 ; used several times.
|
|
170 ; Make sure we emit AdrpAdd for those.
|
|
171 ; CHECK-LABEL: _getSeveralInternalCPlus4
|
|
172 ; CHECK: [[ADRP_LABEL:Lloh[0-9]+]]:
|
|
173 ; CHECK-NEXT: adrp [[ADRP_REG:x[0-9]+]], _InternalC@PAGE
|
|
174 ; CHECK-NEXT: [[ADDGOT_LABEL:Lloh[0-9]+]]:
|
|
175 ; CHECK-NEXT: add [[ADDGOT_REG:x[0-9]+]], [[ADRP_REG]], _InternalC@PAGEOFF
|
|
176 ; CHECK-NEXT: ldr [[LOAD:w[0-9]+]], {{\[}}[[ADDGOT_REG]], #16]
|
|
177 ; CHECK-NEXT: add [[ADD:w[0-9]+]], [[LOAD]], w0
|
|
178 ; CHECK-NEXT: str [[ADD]], {{\[}}[[ADDGOT_REG]], #16]
|
|
179 ; CHECK-NEXT: ret
|
|
180 ; CHECK: .loh AdrpAdd [[ADRP_LABEL]], [[ADDGOT_LABEL]]
|
|
181 define void @getSeveralInternalCPlus4(i32 %t) {
|
|
182 entry:
|
|
183 %addr = getelementptr i32, i32* @InternalC, i32 4
|
|
184 %tmp = load i32, i32* %addr, align 4
|
|
185 %add = add nsw i32 %tmp, %t
|
|
186 store i32 %add, i32* %addr, align 4
|
|
187 ret void
|
|
188 }
|
|
189
|
|
190 ; Make sure we catch that:
|
|
191 ; adrp -> add -> str.
|
|
192 ; CHECK-LABEL: _setInternalCPlus4
|
|
193 ; CHECK: [[ADRP_LABEL:Lloh[0-9]+]]:
|
|
194 ; CHECK-NEXT: adrp [[ADRP_REG:x[0-9]+]], _InternalC@PAGE
|
|
195 ; CHECK-NEXT: [[ADDGOT_LABEL:Lloh[0-9]+]]:
|
|
196 ; CHECK-NEXT: add [[ADDGOT_REG:x[0-9]+]], [[ADRP_REG]], _InternalC@PAGEOFF
|
|
197 ; CHECK-NEXT: [[LDR_LABEL:Lloh[0-9]+]]:
|
|
198 ; CHECK-NEXT: str w0, {{\[}}[[ADDGOT_REG]], #16]
|
|
199 ; CHECK-NEXT: ret
|
|
200 ; CHECK: .loh AdrpAddStr [[ADRP_LABEL]], [[ADDGOT_LABEL]], [[LDR_LABEL]]
|
|
201 define void @setInternalCPlus4(i32 %t) {
|
|
202 entry:
|
|
203 %addr = getelementptr i32, i32* @InternalC, i32 4
|
|
204 store i32 %t, i32* %addr, align 4
|
|
205 ret void
|
|
206 }
|
|
207
|
|
208 ; Check that we catch AdrpAddLdr case when we have a simple chain:
|
|
209 ; adrp -> ldr.
|
|
210 ; CHECK-LABEL: _getInternalC
|
|
211 ; CHECK: [[ADRP_LABEL:Lloh[0-9]+]]:
|
|
212 ; CHECK-NEXT: adrp [[ADRP_REG:x[0-9]+]], _InternalC@PAGE
|
|
213 ; CHECK-NEXT: [[LDR_LABEL:Lloh[0-9]+]]:
|
|
214 ; CHECK-NEXT: ldr w0, {{\[}}[[ADRP_REG]], _InternalC@PAGEOFF]
|
|
215 ; CHECK-NEXT: ret
|
|
216 ; CHECK: .loh AdrpLdr [[ADRP_LABEL]], [[LDR_LABEL]]
|
|
217 define i32 @getInternalC() {
|
|
218 %res = load i32, i32* @InternalC, align 4
|
|
219 ret i32 %res
|
|
220 }
|
|
221
|
|
222 ; LDRSW supports loading from a literal.
|
|
223 ; Make sure we emit AdrpLdrGotLdr for those.
|
|
224 ; CHECK-LABEL: _getSExtInternalC
|
|
225 ; CHECK: [[ADRP_LABEL:Lloh[0-9]+]]:
|
|
226 ; CHECK-NEXT: adrp [[ADRP_REG:x[0-9]+]], _InternalC@PAGE
|
|
227 ; CHECK-NEXT: [[LDR_LABEL:Lloh[0-9]+]]:
|
|
228 ; CHECK-NEXT: ldrsw x0, {{\[}}[[ADRP_REG]], _InternalC@PAGEOFF]
|
|
229 ; CHECK-NEXT: ret
|
|
230 ; CHECK: .loh AdrpLdr [[ADRP_LABEL]], [[LDR_LABEL]]
|
|
231 define i64 @getSExtInternalC() {
|
|
232 %res = load i32, i32* @InternalC, align 4
|
|
233 %sextres = sext i32 %res to i64
|
|
234 ret i64 %sextres
|
|
235 }
|
|
236
|
|
237 ; It may not be safe to fold the literal in the load if the address is
|
|
238 ; used several times.
|
|
239 ; Make sure we do not catch anything here. We have a adrp alone,
|
|
240 ; there is not much we can do about it.
|
|
241 ; CHECK-LABEL: _getSeveralInternalC
|
|
242 ; CHECK: adrp [[ADRP_REG:x[0-9]+]], _InternalC@PAGE
|
|
243 ; CHECK-NEXT: ldr [[LOAD:w[0-9]+]], {{\[}}[[ADRP_REG]], _InternalC@PAGEOFF]
|
|
244 ; CHECK-NEXT: add [[ADD:w[0-9]+]], [[LOAD]], w0
|
|
245 ; CHECK-NEXT: str [[ADD]], {{\[}}[[ADRP_REG]], _InternalC@PAGEOFF]
|
|
246 ; CHECK-NEXT: ret
|
|
247 define void @getSeveralInternalC(i32 %t) {
|
|
248 entry:
|
|
249 %tmp = load i32, i32* @InternalC, align 4
|
|
250 %add = add nsw i32 %tmp, %t
|
|
251 store i32 %add, i32* @InternalC, align 4
|
|
252 ret void
|
|
253 }
|
|
254
|
|
255 ; Make sure we do not catch anything when:
|
|
256 ; adrp -> str.
|
|
257 ; We cannot fold anything in the str at this point.
|
|
258 ; Indeed, strs do not support litterals.
|
|
259 ; CHECK-LABEL: _setInternalC
|
|
260 ; CHECK: adrp [[ADRP_REG:x[0-9]+]], _InternalC@PAGE
|
|
261 ; CHECK-NEXT: str w0, {{\[}}[[ADRP_REG]], _InternalC@PAGEOFF]
|
|
262 ; CHECK-NEXT: ret
|
|
263 define void @setInternalC(i32 %t) {
|
|
264 entry:
|
|
265 store i32 %t, i32* @InternalC, align 4
|
|
266 ret void
|
|
267 }
|
|
268
|
|
269 ; Now check other variant of loads/stores.
|
|
270
|
|
271 @D = common global i8 0, align 4
|
|
272
|
|
273 ; LDRB does not support loading from a literal.
|
|
274 ; Make sure we emit AdrpLdrGot and not AdrpLdrGotLdr for those.
|
|
275 ; CHECK-LABEL: _getD
|
|
276 ; CHECK: [[ADRP_LABEL:Lloh[0-9]+]]:
|
|
277 ; CHECK-NEXT: adrp [[ADRP_REG:x[0-9]+]], _D@GOTPAGE
|
|
278 ; CHECK-NEXT: [[LDRGOT_LABEL:Lloh[0-9]+]]:
|
|
279 ; CHECK-NEXT: ldr [[LDRGOT_REG:x[0-9]+]], {{\[}}[[ADRP_REG]], _D@GOTPAGEOFF]
|
|
280 ; CHECK-NEXT: ldrb w0, {{\[}}[[LDRGOT_REG]]]
|
|
281 ; CHECK-NEXT: ret
|
|
282 ; CHECK: .loh AdrpLdrGot [[ADRP_LABEL]], [[LDRGOT_LABEL]]
|
|
283 define i8 @getD() {
|
|
284 %res = load i8, i8* @D, align 4
|
|
285 ret i8 %res
|
|
286 }
|
|
287
|
|
288 ; CHECK-LABEL: _setD
|
|
289 ; CHECK: [[ADRP_LABEL:Lloh[0-9]+]]:
|
|
290 ; CHECK-NEXT: adrp [[ADRP_REG:x[0-9]+]], _D@GOTPAGE
|
|
291 ; CHECK-NEXT: [[LDRGOT_LABEL:Lloh[0-9]+]]:
|
|
292 ; CHECK-NEXT: ldr [[LDRGOT_REG:x[0-9]+]], {{\[}}[[ADRP_REG]], _D@GOTPAGEOFF]
|
|
293 ; CHECK-NEXT: [[STR_LABEL:Lloh[0-9]+]]:
|
|
294 ; CHECK-NEXT: strb w0, {{\[}}[[LDRGOT_REG]]]
|
|
295 ; CHECK-NEXT: ret
|
|
296 ; CHECK: .loh AdrpLdrGotStr [[ADRP_LABEL]], [[LDRGOT_LABEL]], [[STR_LABEL]]
|
|
297 define void @setD(i8 %t) {
|
|
298 store i8 %t, i8* @D, align 4
|
|
299 ret void
|
|
300 }
|
|
301
|
|
302 ; LDRSB supports loading from a literal.
|
|
303 ; Make sure we emit AdrpLdrGotLdr for those.
|
|
304 ; CHECK-LABEL: _getSExtD
|
|
305 ; CHECK: [[ADRP_LABEL:Lloh[0-9]+]]:
|
|
306 ; CHECK-NEXT: adrp [[ADRP_REG:x[0-9]+]], _D@GOTPAGE
|
|
307 ; CHECK-NEXT: [[LDRGOT_LABEL:Lloh[0-9]+]]:
|
|
308 ; CHECK-NEXT: ldr [[LDRGOT_REG:x[0-9]+]], {{\[}}[[ADRP_REG]], _D@GOTPAGEOFF]
|
|
309 ; CHECK-NEXT: [[LDR_LABEL:Lloh[0-9]+]]:
|
|
310 ; CHECK-NEXT: ldrsb w0, {{\[}}[[LDRGOT_REG]]]
|
|
311 ; CHECK-NEXT: ret
|
|
312 ; CHECK: .loh AdrpLdrGotLdr [[ADRP_LABEL]], [[LDRGOT_LABEL]], [[LDR_LABEL]]
|
|
313 define i32 @getSExtD() {
|
|
314 %res = load i8, i8* @D, align 4
|
|
315 %sextres = sext i8 %res to i32
|
|
316 ret i32 %sextres
|
|
317 }
|
|
318
|
|
319 ; LDRSB supports loading from a literal.
|
|
320 ; Make sure we emit AdrpLdrGotLdr for those.
|
|
321 ; CHECK-LABEL: _getSExt64D
|
|
322 ; CHECK: [[ADRP_LABEL:Lloh[0-9]+]]:
|
|
323 ; CHECK-NEXT: adrp [[ADRP_REG:x[0-9]+]], _D@GOTPAGE
|
|
324 ; CHECK-NEXT: [[LDRGOT_LABEL:Lloh[0-9]+]]:
|
|
325 ; CHECK-NEXT: ldr [[LDRGOT_REG:x[0-9]+]], {{\[}}[[ADRP_REG]], _D@GOTPAGEOFF]
|
|
326 ; CHECK-NEXT: [[LDR_LABEL:Lloh[0-9]+]]:
|
|
327 ; CHECK-NEXT: ldrsb x0, {{\[}}[[LDRGOT_REG]]]
|
|
328 ; CHECK-NEXT: ret
|
|
329 ; CHECK: .loh AdrpLdrGotLdr [[ADRP_LABEL]], [[LDRGOT_LABEL]], [[LDR_LABEL]]
|
|
330 define i64 @getSExt64D() {
|
|
331 %res = load i8, i8* @D, align 4
|
|
332 %sextres = sext i8 %res to i64
|
|
333 ret i64 %sextres
|
|
334 }
|
|
335
|
|
336 @E = common global i16 0, align 4
|
|
337
|
|
338 ; LDRH does not support loading from a literal.
|
|
339 ; Make sure we emit AdrpLdrGot and not AdrpLdrGotLdr for those.
|
|
340 ; CHECK-LABEL: _getE
|
|
341 ; CHECK: [[ADRP_LABEL:Lloh[0-9]+]]:
|
|
342 ; CHECK-NEXT: adrp [[ADRP_REG:x[0-9]+]], _E@GOTPAGE
|
|
343 ; CHECK-NEXT: [[LDRGOT_LABEL:Lloh[0-9]+]]:
|
|
344 ; CHECK-NEXT: ldr [[LDRGOT_REG:x[0-9]+]], {{\[}}[[ADRP_REG]], _E@GOTPAGEOFF]
|
|
345 ; CHECK-NEXT: ldrh w0, {{\[}}[[LDRGOT_REG]]]
|
|
346 ; CHECK-NEXT: ret
|
|
347 ; CHECK: .loh AdrpLdrGot [[ADRP_LABEL]], [[LDRGOT_LABEL]]
|
|
348 define i16 @getE() {
|
|
349 %res = load i16, i16* @E, align 4
|
|
350 ret i16 %res
|
|
351 }
|
|
352
|
|
353 ; LDRSH supports loading from a literal.
|
|
354 ; Make sure we emit AdrpLdrGotLdr for those.
|
|
355 ; CHECK-LABEL: _getSExtE
|
|
356 ; CHECK: [[ADRP_LABEL:Lloh[0-9]+]]:
|
|
357 ; CHECK-NEXT: adrp [[ADRP_REG:x[0-9]+]], _E@GOTPAGE
|
|
358 ; CHECK-NEXT: [[LDRGOT_LABEL:Lloh[0-9]+]]:
|
|
359 ; CHECK-NEXT: ldr [[LDRGOT_REG:x[0-9]+]], {{\[}}[[ADRP_REG]], _E@GOTPAGEOFF]
|
|
360 ; CHECK-NEXT: [[LDR_LABEL:Lloh[0-9]+]]:
|
|
361 ; CHECK-NEXT: ldrsh w0, {{\[}}[[LDRGOT_REG]]]
|
|
362 ; CHECK-NEXT: ret
|
|
363 ; CHECK: .loh AdrpLdrGotLdr [[ADRP_LABEL]], [[LDRGOT_LABEL]], [[LDR_LABEL]]
|
|
364 define i32 @getSExtE() {
|
|
365 %res = load i16, i16* @E, align 4
|
|
366 %sextres = sext i16 %res to i32
|
|
367 ret i32 %sextres
|
|
368 }
|
|
369
|
|
370 ; CHECK-LABEL: _setE
|
|
371 ; CHECK: [[ADRP_LABEL:Lloh[0-9]+]]:
|
|
372 ; CHECK-NEXT: adrp [[ADRP_REG:x[0-9]+]], _E@GOTPAGE
|
|
373 ; CHECK-NEXT: [[LDRGOT_LABEL:Lloh[0-9]+]]:
|
|
374 ; CHECK-NEXT: ldr [[LDRGOT_REG:x[0-9]+]], {{\[}}[[ADRP_REG]], _E@GOTPAGEOFF]
|
|
375 ; CHECK-NEXT: [[STR_LABEL:Lloh[0-9]+]]:
|
|
376 ; CHECK-NEXT: strh w0, {{\[}}[[LDRGOT_REG]]]
|
|
377 ; CHECK-NEXT: ret
|
|
378 ; CHECK: .loh AdrpLdrGotStr [[ADRP_LABEL]], [[LDRGOT_LABEL]], [[STR_LABEL]]
|
|
379 define void @setE(i16 %t) {
|
|
380 store i16 %t, i16* @E, align 4
|
|
381 ret void
|
|
382 }
|
|
383
|
|
384 ; LDRSH supports loading from a literal.
|
|
385 ; Make sure we emit AdrpLdrGotLdr for those.
|
|
386 ; CHECK-LABEL: _getSExt64E
|
|
387 ; CHECK: [[ADRP_LABEL:Lloh[0-9]+]]:
|
|
388 ; CHECK-NEXT: adrp [[ADRP_REG:x[0-9]+]], _E@GOTPAGE
|
|
389 ; CHECK-NEXT: [[LDRGOT_LABEL:Lloh[0-9]+]]:
|
|
390 ; CHECK-NEXT: ldr [[LDRGOT_REG:x[0-9]+]], {{\[}}[[ADRP_REG]], _E@GOTPAGEOFF]
|
|
391 ; CHECK-NEXT: [[LDR_LABEL:Lloh[0-9]+]]:
|
|
392 ; CHECK-NEXT: ldrsh x0, {{\[}}[[LDRGOT_REG]]]
|
|
393 ; CHECK-NEXT: ret
|
|
394 ; CHECK: .loh AdrpLdrGotLdr [[ADRP_LABEL]], [[LDRGOT_LABEL]], [[LDR_LABEL]]
|
|
395 define i64 @getSExt64E() {
|
|
396 %res = load i16, i16* @E, align 4
|
|
397 %sextres = sext i16 %res to i64
|
|
398 ret i64 %sextres
|
|
399 }
|
|
400
|
|
401 @F = common global i64 0, align 4
|
|
402
|
|
403 ; LDR supports loading from a literal.
|
|
404 ; Make sure we emit AdrpLdrGotLdr for those.
|
|
405 ; CHECK-LABEL: _getF
|
|
406 ; CHECK: [[ADRP_LABEL:Lloh[0-9]+]]:
|
|
407 ; CHECK-NEXT: adrp [[ADRP_REG:x[0-9]+]], _F@GOTPAGE
|
|
408 ; CHECK-NEXT: [[LDRGOT_LABEL:Lloh[0-9]+]]:
|
|
409 ; CHECK-NEXT: ldr [[LDRGOT_REG:x[0-9]+]], {{\[}}[[ADRP_REG]], _F@GOTPAGEOFF]
|
|
410 ; CHECK-NEXT: [[LDR_LABEL:Lloh[0-9]+]]:
|
|
411 ; CHECK-NEXT: ldr x0, {{\[}}[[LDRGOT_REG]]]
|
|
412 ; CHECK-NEXT: ret
|
|
413 ; CHECK: .loh AdrpLdrGotLdr [[ADRP_LABEL]], [[LDRGOT_LABEL]], [[LDR_LABEL]]
|
|
414 define i64 @getF() {
|
|
415 %res = load i64, i64* @F, align 4
|
|
416 ret i64 %res
|
|
417 }
|
|
418
|
|
419 ; CHECK-LABEL: _setF
|
|
420 ; CHECK: [[ADRP_LABEL:Lloh[0-9]+]]:
|
|
421 ; CHECK-NEXT: adrp [[ADRP_REG:x[0-9]+]], _F@GOTPAGE
|
|
422 ; CHECK-NEXT: [[LDRGOT_LABEL:Lloh[0-9]+]]:
|
|
423 ; CHECK-NEXT: ldr [[LDRGOT_REG:x[0-9]+]], {{\[}}[[ADRP_REG]], _F@GOTPAGEOFF]
|
|
424 ; CHECK-NEXT: [[STR_LABEL:Lloh[0-9]+]]:
|
|
425 ; CHECK-NEXT: str x0, {{\[}}[[LDRGOT_REG]]]
|
|
426 ; CHECK-NEXT: ret
|
|
427 ; CHECK: .loh AdrpLdrGotStr [[ADRP_LABEL]], [[LDRGOT_LABEL]], [[STR_LABEL]]
|
|
428 define void @setF(i64 %t) {
|
|
429 store i64 %t, i64* @F, align 4
|
|
430 ret void
|
|
431 }
|
|
432
|
|
433 @G = common global float 0.0, align 4
|
|
434
|
|
435 ; LDR float supports loading from a literal.
|
|
436 ; Make sure we emit AdrpLdrGotLdr for those.
|
|
437 ; CHECK-LABEL: _getG
|
|
438 ; CHECK: [[ADRP_LABEL:Lloh[0-9]+]]:
|
|
439 ; CHECK-NEXT: adrp [[ADRP_REG:x[0-9]+]], _G@GOTPAGE
|
|
440 ; CHECK-NEXT: [[LDRGOT_LABEL:Lloh[0-9]+]]:
|
|
441 ; CHECK-NEXT: ldr [[LDRGOT_REG:x[0-9]+]], {{\[}}[[ADRP_REG]], _G@GOTPAGEOFF]
|
|
442 ; CHECK-NEXT: [[LDR_LABEL:Lloh[0-9]+]]:
|
|
443 ; CHECK-NEXT: ldr s0, {{\[}}[[LDRGOT_REG]]]
|
|
444 ; CHECK-NEXT: ret
|
|
445 ; CHECK: .loh AdrpLdrGotLdr [[ADRP_LABEL]], [[LDRGOT_LABEL]], [[LDR_LABEL]]
|
|
446 define float @getG() {
|
|
447 %res = load float, float* @G, align 4
|
|
448 ret float %res
|
|
449 }
|
|
450
|
|
451 ; CHECK-LABEL: _setG
|
|
452 ; CHECK: [[ADRP_LABEL:Lloh[0-9]+]]:
|
|
453 ; CHECK-NEXT: adrp [[ADRP_REG:x[0-9]+]], _G@GOTPAGE
|
|
454 ; CHECK-NEXT: [[LDRGOT_LABEL:Lloh[0-9]+]]:
|
|
455 ; CHECK-NEXT: ldr [[LDRGOT_REG:x[0-9]+]], {{\[}}[[ADRP_REG]], _G@GOTPAGEOFF]
|
|
456 ; CHECK-NEXT: [[STR_LABEL:Lloh[0-9]+]]:
|
|
457 ; CHECK-NEXT: str s0, {{\[}}[[LDRGOT_REG]]]
|
|
458 ; CHECK-NEXT: ret
|
|
459 ; CHECK: .loh AdrpLdrGotStr [[ADRP_LABEL]], [[LDRGOT_LABEL]], [[STR_LABEL]]
|
|
460 define void @setG(float %t) {
|
|
461 store float %t, float* @G, align 4
|
|
462 ret void
|
|
463 }
|
|
464
|
|
465 @H = common global half 0.0, align 4
|
|
466
|
|
467 ; LDR half supports loading from a literal.
|
|
468 ; Make sure we emit AdrpLdrGotLdr for those.
|
|
469 ; CHECK-LABEL: _getH
|
|
470 ; CHECK: [[ADRP_LABEL:Lloh[0-9]+]]:
|
|
471 ; CHECK-NEXT: adrp [[ADRP_REG:x[0-9]+]], _H@GOTPAGE
|
|
472 ; CHECK-NEXT: [[LDRGOT_LABEL:Lloh[0-9]+]]:
|
|
473 ; CHECK-NEXT: ldr [[LDRGOT_REG:x[0-9]+]], {{\[}}[[ADRP_REG]], _H@GOTPAGEOFF]
|
|
474 ; CHECK-NEXT: [[LDR_LABEL:Lloh[0-9]+]]:
|
|
475 ; CHECK-NEXT: ldr h0, {{\[}}[[LDRGOT_REG]]]
|
|
476 ; CHECK-NEXT: ret
|
|
477 ; CHECK: .loh AdrpLdrGotLdr [[ADRP_LABEL]], [[LDRGOT_LABEL]], [[LDR_LABEL]]
|
|
478 define half @getH() {
|
|
479 %res = load half, half* @H, align 4
|
|
480 ret half %res
|
|
481 }
|
|
482
|
|
483 ; CHECK-LABEL: _setH
|
|
484 ; CHECK: [[ADRP_LABEL:Lloh[0-9]+]]:
|
|
485 ; CHECK-NEXT: adrp [[ADRP_REG:x[0-9]+]], _H@GOTPAGE
|
|
486 ; CHECK-NEXT: [[LDRGOT_LABEL:Lloh[0-9]+]]:
|
|
487 ; CHECK-NEXT: ldr [[LDRGOT_REG:x[0-9]+]], {{\[}}[[ADRP_REG]], _H@GOTPAGEOFF]
|
|
488 ; CHECK-NEXT: [[STR_LABEL:Lloh[0-9]+]]:
|
|
489 ; CHECK-NEXT: str h0, {{\[}}[[LDRGOT_REG]]]
|
|
490 ; CHECK-NEXT: ret
|
|
491 ; CHECK: .loh AdrpLdrGotStr [[ADRP_LABEL]], [[LDRGOT_LABEL]], [[STR_LABEL]]
|
|
492 define void @setH(half %t) {
|
|
493 store half %t, half* @H, align 4
|
|
494 ret void
|
|
495 }
|
|
496
|
|
497 @I = common global double 0.0, align 4
|
|
498
|
|
499 ; LDR double supports loading from a literal.
|
|
500 ; Make sure we emit AdrpLdrGotLdr for those.
|
|
501 ; CHECK-LABEL: _getI
|
|
502 ; CHECK: [[ADRP_LABEL:Lloh[0-9]+]]:
|
|
503 ; CHECK-NEXT: adrp [[ADRP_REG:x[0-9]+]], _I@GOTPAGE
|
|
504 ; CHECK-NEXT: [[LDRGOT_LABEL:Lloh[0-9]+]]:
|
|
505 ; CHECK-NEXT: ldr [[LDRGOT_REG:x[0-9]+]], {{\[}}[[ADRP_REG]], _I@GOTPAGEOFF]
|
|
506 ; CHECK-NEXT: [[LDR_LABEL:Lloh[0-9]+]]:
|
|
507 ; CHECK-NEXT: ldr d0, {{\[}}[[LDRGOT_REG]]]
|
|
508 ; CHECK-NEXT: ret
|
|
509 ; CHECK: .loh AdrpLdrGotLdr [[ADRP_LABEL]], [[LDRGOT_LABEL]], [[LDR_LABEL]]
|
|
510 define double @getI() {
|
|
511 %res = load double, double* @I, align 4
|
|
512 ret double %res
|
|
513 }
|
|
514
|
|
515 ; CHECK-LABEL: _setI
|
|
516 ; CHECK: [[ADRP_LABEL:Lloh[0-9]+]]:
|
|
517 ; CHECK-NEXT: adrp [[ADRP_REG:x[0-9]+]], _I@GOTPAGE
|
|
518 ; CHECK-NEXT: [[LDRGOT_LABEL:Lloh[0-9]+]]:
|
|
519 ; CHECK-NEXT: ldr [[LDRGOT_REG:x[0-9]+]], {{\[}}[[ADRP_REG]], _I@GOTPAGEOFF]
|
|
520 ; CHECK-NEXT: [[STR_LABEL:Lloh[0-9]+]]:
|
|
521 ; CHECK-NEXT: str d0, {{\[}}[[LDRGOT_REG]]]
|
|
522 ; CHECK-NEXT: ret
|
|
523 ; CHECK: .loh AdrpLdrGotStr [[ADRP_LABEL]], [[LDRGOT_LABEL]], [[STR_LABEL]]
|
|
524 define void @setI(double %t) {
|
|
525 store double %t, double* @I, align 4
|
|
526 ret void
|
|
527 }
|
|
528
|
|
529 @J = common global <2 x i32> <i32 0, i32 0>, align 4
|
|
530
|
|
531 ; LDR 64-bit vector supports loading from a literal.
|
|
532 ; Make sure we emit AdrpLdrGotLdr for those.
|
|
533 ; CHECK-LABEL: _getJ
|
|
534 ; CHECK: [[ADRP_LABEL:Lloh[0-9]+]]:
|
|
535 ; CHECK-NEXT: adrp [[ADRP_REG:x[0-9]+]], _J@GOTPAGE
|
|
536 ; CHECK-NEXT: [[LDRGOT_LABEL:Lloh[0-9]+]]:
|
|
537 ; CHECK-NEXT: ldr [[LDRGOT_REG:x[0-9]+]], {{\[}}[[ADRP_REG]], _J@GOTPAGEOFF]
|
|
538 ; CHECK-NEXT: [[LDR_LABEL:Lloh[0-9]+]]:
|
|
539 ; CHECK-NEXT: ldr d0, {{\[}}[[LDRGOT_REG]]]
|
|
540 ; CHECK-NEXT: ret
|
|
541 ; CHECK: .loh AdrpLdrGotLdr [[ADRP_LABEL]], [[LDRGOT_LABEL]], [[LDR_LABEL]]
|
|
542 define <2 x i32> @getJ() {
|
|
543 %res = load <2 x i32>, <2 x i32>* @J, align 4
|
|
544 ret <2 x i32> %res
|
|
545 }
|
|
546
|
|
547 ; CHECK-LABEL: _setJ
|
|
548 ; CHECK: [[ADRP_LABEL:Lloh[0-9]+]]:
|
|
549 ; CHECK-NEXT: adrp [[ADRP_REG:x[0-9]+]], _J@GOTPAGE
|
|
550 ; CHECK-NEXT: [[LDRGOT_LABEL:Lloh[0-9]+]]:
|
|
551 ; CHECK-NEXT: ldr [[LDRGOT_REG:x[0-9]+]], {{\[}}[[ADRP_REG]], _J@GOTPAGEOFF]
|
|
552 ; CHECK-NEXT: [[STR_LABEL:Lloh[0-9]+]]:
|
|
553 ; CHECK-NEXT: str d0, {{\[}}[[LDRGOT_REG]]]
|
|
554 ; CHECK-NEXT: ret
|
|
555 ; CHECK: .loh AdrpLdrGotStr [[ADRP_LABEL]], [[LDRGOT_LABEL]], [[STR_LABEL]]
|
|
556 define void @setJ(<2 x i32> %t) {
|
|
557 store <2 x i32> %t, <2 x i32>* @J, align 4
|
|
558 ret void
|
|
559 }
|
|
560
|
|
561 @K = common global <4 x i32> <i32 0, i32 0, i32 0, i32 0>, align 4
|
|
562
|
|
563 ; LDR 128-bit vector supports loading from a literal.
|
|
564 ; Make sure we emit AdrpLdrGotLdr for those.
|
|
565 ; CHECK-LABEL: _getK
|
|
566 ; CHECK: [[ADRP_LABEL:Lloh[0-9]+]]:
|
|
567 ; CHECK-NEXT: adrp [[ADRP_REG:x[0-9]+]], _K@GOTPAGE
|
|
568 ; CHECK-NEXT: [[LDRGOT_LABEL:Lloh[0-9]+]]:
|
|
569 ; CHECK-NEXT: ldr [[LDRGOT_REG:x[0-9]+]], {{\[}}[[ADRP_REG]], _K@GOTPAGEOFF]
|
|
570 ; CHECK-NEXT: [[LDR_LABEL:Lloh[0-9]+]]:
|
|
571 ; CHECK-NEXT: ldr q0, {{\[}}[[LDRGOT_REG]]]
|
|
572 ; CHECK-NEXT: ret
|
|
573 ; CHECK: .loh AdrpLdrGotLdr [[ADRP_LABEL]], [[LDRGOT_LABEL]], [[LDR_LABEL]]
|
|
574 define <4 x i32> @getK() {
|
|
575 %res = load <4 x i32>, <4 x i32>* @K, align 4
|
|
576 ret <4 x i32> %res
|
|
577 }
|
|
578
|
|
579 ; CHECK-LABEL: _setK
|
|
580 ; CHECK: [[ADRP_LABEL:Lloh[0-9]+]]:
|
|
581 ; CHECK-NEXT: adrp [[ADRP_REG:x[0-9]+]], _K@GOTPAGE
|
|
582 ; CHECK-NEXT: [[LDRGOT_LABEL:Lloh[0-9]+]]:
|
|
583 ; CHECK-NEXT: ldr [[LDRGOT_REG:x[0-9]+]], {{\[}}[[ADRP_REG]], _K@GOTPAGEOFF]
|
|
584 ; CHECK-NEXT: [[STR_LABEL:Lloh[0-9]+]]:
|
|
585 ; CHECK-NEXT: str q0, {{\[}}[[LDRGOT_REG]]]
|
|
586 ; CHECK-NEXT: ret
|
|
587 ; CHECK: .loh AdrpLdrGotStr [[ADRP_LABEL]], [[LDRGOT_LABEL]], [[STR_LABEL]]
|
|
588 define void @setK(<4 x i32> %t) {
|
|
589 store <4 x i32> %t, <4 x i32>* @K, align 4
|
|
590 ret void
|
|
591 }
|
|
592
|
|
593 @L = common global <1 x i8> <i8 0>, align 4
|
|
594
|
|
595 ; LDR 8-bit vector supports loading from a literal.
|
|
596 ; Make sure we emit AdrpLdrGotLdr for those.
|
|
597 ; CHECK-LABEL: _getL
|
|
598 ; CHECK: [[ADRP_LABEL:Lloh[0-9]+]]:
|
|
599 ; CHECK-NEXT: adrp [[ADRP_REG:x[0-9]+]], _L@GOTPAGE
|
|
600 ; CHECK-NEXT: [[LDRGOT_LABEL:Lloh[0-9]+]]:
|
|
601 ; CHECK-NEXT: ldr [[LDRGOT_REG:x[0-9]+]], {{\[}}[[ADRP_REG]], _L@GOTPAGEOFF]
|
|
602 ; CHECK-NEXT: [[LDR_LABEL:Lloh[0-9]+]]:
|
|
603 ; CHECK-NEXT: ldr b0, {{\[}}[[LDRGOT_REG]]]
|
|
604 ; CHECK-NEXT: ret
|
|
605 ; CHECK: .loh AdrpLdrGotLdr [[ADRP_LABEL]], [[LDRGOT_LABEL]], [[LDR_LABEL]]
|
|
606 define <1 x i8> @getL() {
|
|
607 %res = load <1 x i8>, <1 x i8>* @L, align 4
|
|
608 ret <1 x i8> %res
|
|
609 }
|
|
610
|
|
611 ; CHECK-LABEL: _setL
|
|
612 ; CHECK: [[ADRP_LABEL:Lloh[0-9]+]]:
|
|
613 ; CHECK-NEXT: adrp [[ADRP_REG:x[0-9]+]], _L@GOTPAGE
|
|
614 ; CHECK-NEXT: [[LDRGOT_LABEL:Lloh[0-9]+]]:
|
|
615 ; CHECK-NEXT: ldr [[LDRGOT_REG:x[0-9]+]], {{\[}}[[ADRP_REG]], _L@GOTPAGEOFF]
|
|
616 ; Ultimately we should generate str b0, but right now, we match the vector
|
|
617 ; variant which does not allow to fold the immediate into the store.
|
|
618 ; CHECK-NEXT: st1.b { v0 }[0], {{\[}}[[LDRGOT_REG]]]
|
|
619 ; CHECK-NEXT: ret
|
|
620 ; CHECK: .loh AdrpLdrGot [[ADRP_LABEL]], [[LDRGOT_LABEL]]
|
|
621 define void @setL(<1 x i8> %t) {
|
|
622 store <1 x i8> %t, <1 x i8>* @L, align 4
|
|
623 ret void
|
|
624 }
|
|
625
|
|
626 ; Make sure we do not assert when we do not track
|
|
627 ; all the aliases of a tuple register.
|
|
628 ; Indeed the tuple register can be tracked because of
|
|
629 ; one of its element, but the other elements of the tuple
|
|
630 ; do not need to be tracked and we used to assert on that.
|
|
631 ; Note: The test case is fragile in the sense that we need
|
|
632 ; a tuple register to appear in the lowering. Thus, the target
|
|
633 ; cpu is required to have the problem reproduced.
|
|
634 ; CHECK-LABEL: _uninterestingSub
|
|
635 ; CHECK: adrp [[ADRP_REG:x[0-9]+]], [[CONSTPOOL:lCPI[0-9]+_[0-9]+]]@PAGE
|
|
636 ; CHECK-NEXT: ldr q[[IDX:[0-9]+]], {{\[}}[[ADRP_REG]], [[CONSTPOOL]]@PAGEOFF]
|
|
637 ; The tuple comes from the next instruction.
|
|
638 ; CHECK-NEXT: tbl.16b v{{[0-9]+}}, { v{{[0-9]+}}, v{{[0-9]+}} }, v[[IDX]]
|
|
639 ; CHECK: ret
|
|
640 define void @uninterestingSub(i8* nocapture %row) #0 {
|
|
641 %tmp = bitcast i8* %row to <16 x i8>*
|
|
642 %tmp1 = load <16 x i8>, <16 x i8>* %tmp, align 16
|
|
643 %vext43 = shufflevector <16 x i8> <i8 undef, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0>, <16 x i8> %tmp1, <16 x i32> <i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15, i32 16>
|
|
644 %add.i.414 = add <16 x i8> zeroinitializer, %vext43
|
|
645 store <16 x i8> %add.i.414, <16 x i8>* %tmp, align 16
|
|
646 %add.ptr51 = getelementptr inbounds i8, i8* %row, i64 16
|
|
647 %tmp2 = bitcast i8* %add.ptr51 to <16 x i8>*
|
|
648 %tmp3 = load <16 x i8>, <16 x i8>* %tmp2, align 16
|
|
649 %tmp4 = bitcast i8* undef to <16 x i8>*
|
|
650 %tmp5 = load <16 x i8>, <16 x i8>* %tmp4, align 16
|
|
651 %vext157 = shufflevector <16 x i8> %tmp3, <16 x i8> %tmp5, <16 x i32> <i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15, i32 16>
|
|
652 %add.i.402 = add <16 x i8> zeroinitializer, %vext157
|
|
653 store <16 x i8> %add.i.402, <16 x i8>* %tmp4, align 16
|
|
654 ret void
|
|
655 }
|
|
656
|
|
657 attributes #0 = { "target-cpu"="cyclone" }
|