1 // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py
2 // RUN: %clang_cc1 -ffreestanding -triple armv8a-none-eabi -target-feature +crc -target-feature +dsp -O0 -disable-O0-optnone -fexperimental-new-pass-manager -S -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s -check-prefixes=ARM,AArch32
3 // RUN: %clang_cc1 -ffreestanding -triple aarch64-none-eabi -target-feature +neon -target-feature +crc -target-feature +crypto -O0 -disable-O0-optnone -fexperimental-new-pass-manager -S -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s -check-prefixes=ARM,AArch64
4 // RUN: %clang_cc1 -ffreestanding -triple aarch64-none-eabi -target-feature +v8.3a -O0 -disable-O0-optnone -fexperimental-new-pass-manager -S -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s -check-prefixes=ARM,AArch64,AArch6483
5 // RUN: %clang_cc1 -ffreestanding -triple aarch64-none-eabi -target-feature +v8.5a -target-feature +rand -O0 -disable-O0-optnone -fexperimental-new-pass-manager -S -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s -check-prefixes=ARM,AArch64,AArch6483,AArch6485
6 
7 #include <arm_acle.h>
8 
9 // REQUIRES: arm-registered-target,aarch64-registered-target
10 
11 /* 8 SYNCHRONIZATION, BARRIER AND HINT INTRINSICS */
12 /* 8.3 Memory Barriers */
13 
14 // AArch32-LABEL: @test_dmb(
15 // AArch32-NEXT:  entry:
16 // AArch32-NEXT:    call void @llvm.arm.dmb(i32 1)
17 // AArch32-NEXT:    ret void
18 //
19 // AArch64-LABEL: @test_dmb(
20 // AArch64-NEXT:  entry:
21 // AArch64-NEXT:    call void @llvm.aarch64.dmb(i32 1)
22 // AArch64-NEXT:    ret void
23 //
24 void test_dmb(void) {
25   __dmb(1);
26 }
27 
28 // AArch32-LABEL: @test_dsb(
29 // AArch32-NEXT:  entry:
30 // AArch32-NEXT:    call void @llvm.arm.dsb(i32 2)
31 // AArch32-NEXT:    ret void
32 //
33 // AArch64-LABEL: @test_dsb(
34 // AArch64-NEXT:  entry:
35 // AArch64-NEXT:    call void @llvm.aarch64.dsb(i32 2)
36 // AArch64-NEXT:    ret void
37 //
38 void test_dsb(void) {
39   __dsb(2);
40 }
41 
42 // AArch32-LABEL: @test_isb(
43 // AArch32-NEXT:  entry:
44 // AArch32-NEXT:    call void @llvm.arm.isb(i32 3)
45 // AArch32-NEXT:    ret void
46 //
47 // AArch64-LABEL: @test_isb(
48 // AArch64-NEXT:  entry:
49 // AArch64-NEXT:    call void @llvm.aarch64.isb(i32 3)
50 // AArch64-NEXT:    ret void
51 //
52 void test_isb(void) {
53   __isb(3);
54 }
55 
56 /* 8.4 Hints */
57 // AArch32-LABEL: @test_yield(
58 // AArch32-NEXT:  entry:
59 // AArch32-NEXT:    call void @llvm.arm.hint(i32 1) [[ATTR1:#.*]]
60 // AArch32-NEXT:    ret void
61 //
62 // AArch64-LABEL: @test_yield(
63 // AArch64-NEXT:  entry:
64 // AArch64-NEXT:    call void @llvm.aarch64.hint(i32 1) [[ATTR3:#.*]]
65 // AArch64-NEXT:    ret void
66 //
67 void test_yield(void) {
68   __yield();
69 }
70 
71 // AArch32-LABEL: @test_wfe(
72 // AArch32-NEXT:  entry:
73 // AArch32-NEXT:    call void @llvm.arm.hint(i32 2) [[ATTR1]]
74 // AArch32-NEXT:    ret void
75 //
76 // AArch64-LABEL: @test_wfe(
77 // AArch64-NEXT:  entry:
78 // AArch64-NEXT:    call void @llvm.aarch64.hint(i32 2) [[ATTR3]]
79 // AArch64-NEXT:    ret void
80 //
81 void test_wfe(void) {
82   __wfe();
83 }
84 
85 // AArch32-LABEL: @test_wfi(
86 // AArch32-NEXT:  entry:
87 // AArch32-NEXT:    call void @llvm.arm.hint(i32 3) [[ATTR1]]
88 // AArch32-NEXT:    ret void
89 //
90 // AArch64-LABEL: @test_wfi(
91 // AArch64-NEXT:  entry:
92 // AArch64-NEXT:    call void @llvm.aarch64.hint(i32 3) [[ATTR3]]
93 // AArch64-NEXT:    ret void
94 //
95 void test_wfi(void) {
96   __wfi();
97 }
98 
99 // AArch32-LABEL: @test_sev(
100 // AArch32-NEXT:  entry:
101 // AArch32-NEXT:    call void @llvm.arm.hint(i32 4) [[ATTR1]]
102 // AArch32-NEXT:    ret void
103 //
104 // AArch64-LABEL: @test_sev(
105 // AArch64-NEXT:  entry:
106 // AArch64-NEXT:    call void @llvm.aarch64.hint(i32 4) [[ATTR3]]
107 // AArch64-NEXT:    ret void
108 //
109 void test_sev(void) {
110   __sev();
111 }
112 
113 // AArch32-LABEL: @test_sevl(
114 // AArch32-NEXT:  entry:
115 // AArch32-NEXT:    call void @llvm.arm.hint(i32 5) [[ATTR1]]
116 // AArch32-NEXT:    ret void
117 //
118 // AArch64-LABEL: @test_sevl(
119 // AArch64-NEXT:  entry:
120 // AArch64-NEXT:    call void @llvm.aarch64.hint(i32 5) [[ATTR3]]
121 // AArch64-NEXT:    ret void
122 //
123 void test_sevl(void) {
124   __sevl();
125 }
126 
127 #if __ARM_32BIT_STATE
128 // AArch32-LABEL: @test_dbg(
129 // AArch32-NEXT:  entry:
130 // AArch32-NEXT:    call void @llvm.arm.dbg(i32 0)
131 // AArch32-NEXT:    ret void
132 //
133 void test_dbg(void) {
134   __dbg(0);
135 }
136 #endif
137 
138 /* 8.5 Swap */
139 // AArch32-LABEL: @test_swp(
140 // AArch32-NEXT:  entry:
141 // AArch32-NEXT:    [[TMP0:%.*]] = bitcast i8* [[P:%.*]] to i32*
142 // AArch32-NEXT:    br label [[DO_BODY_I:%.*]]
143 // AArch32:       do.body.i:
144 // AArch32-NEXT:    [[LDREX_I:%.*]] = call i32 @llvm.arm.ldrex.p0i32(i32* [[TMP0]]) [[ATTR1]]
145 // AArch32-NEXT:    [[STREX_I:%.*]] = call i32 @llvm.arm.strex.p0i32(i32 [[X:%.*]], i32* [[TMP0]]) [[ATTR1]]
146 // AArch32-NEXT:    [[TOBOOL_I:%.*]] = icmp ne i32 [[STREX_I]], 0
147 // AArch32-NEXT:    br i1 [[TOBOOL_I]], label [[DO_BODY_I]], label [[__SWP_EXIT:%.*]], [[LOOP3:!llvm.loop !.*]]
148 // AArch32:       __swp.exit:
149 // AArch32-NEXT:    ret void
150 //
151 // AArch64-LABEL: @test_swp(
152 // AArch64-NEXT:  entry:
153 // AArch64-NEXT:    [[TMP0:%.*]] = bitcast i8* [[P:%.*]] to i32*
154 // AArch64-NEXT:    br label [[DO_BODY_I:%.*]]
155 // AArch64:       do.body.i:
156 // AArch64-NEXT:    [[LDXR_I:%.*]] = call i64 @llvm.aarch64.ldxr.p0i32(i32* [[TMP0]]) [[ATTR3]]
157 // AArch64-NEXT:    [[TMP1:%.*]] = trunc i64 [[LDXR_I]] to i32
158 // AArch64-NEXT:    [[TMP2:%.*]] = zext i32 [[X:%.*]] to i64
159 // AArch64-NEXT:    [[STXR_I:%.*]] = call i32 @llvm.aarch64.stxr.p0i32(i64 [[TMP2]], i32* [[TMP0]]) [[ATTR3]]
160 // AArch64-NEXT:    [[TOBOOL_I:%.*]] = icmp ne i32 [[STXR_I]], 0
161 // AArch64-NEXT:    br i1 [[TOBOOL_I]], label [[DO_BODY_I]], label [[__SWP_EXIT:%.*]], [[LOOP6:!llvm.loop !.*]]
162 // AArch64:       __swp.exit:
163 // AArch64-NEXT:    ret void
164 //
165 void test_swp(uint32_t x, volatile void *p) {
166   __swp(x, p);
167 }
168 
169 /* 8.6 Memory prefetch intrinsics */
170 /* 8.6.1 Data prefetch */
171 // ARM-LABEL: @test_pld(
172 // ARM-NEXT:  entry:
173 // ARM-NEXT:    call void @llvm.prefetch.p0i8(i8* null, i32 0, i32 3, i32 1)
174 // ARM-NEXT:    ret void
175 //
176 void test_pld() {
177   __pld(0);
178 }
179 
180 // AArch32-LABEL: @test_pldx(
181 // AArch32-NEXT:  entry:
182 // AArch32-NEXT:    call void @llvm.prefetch.p0i8(i8* null, i32 1, i32 3, i32 1)
183 // AArch32-NEXT:    ret void
184 //
185 // AArch64-LABEL: @test_pldx(
186 // AArch64-NEXT:  entry:
187 // AArch64-NEXT:    call void @llvm.prefetch.p0i8(i8* null, i32 1, i32 1, i32 1)
188 // AArch64-NEXT:    ret void
189 //
190 void test_pldx() {
191   __pldx(1, 2, 0, 0);
192 }
193 
194 /* 8.6.2 Instruction prefetch */
195 // ARM-LABEL: @test_pli(
196 // ARM-NEXT:  entry:
197 // ARM-NEXT:    call void @llvm.prefetch.p0i8(i8* null, i32 0, i32 3, i32 0)
198 // ARM-NEXT:    ret void
199 //
200 void test_pli() {
201   __pli(0);
202 }
203 
204 // AArch32-LABEL: @test_plix(
205 // AArch32-NEXT:  entry:
206 // AArch32-NEXT:    call void @llvm.prefetch.p0i8(i8* null, i32 0, i32 3, i32 0)
207 // AArch32-NEXT:    ret void
208 //
209 // AArch64-LABEL: @test_plix(
210 // AArch64-NEXT:  entry:
211 // AArch64-NEXT:    call void @llvm.prefetch.p0i8(i8* null, i32 0, i32 1, i32 0)
212 // AArch64-NEXT:    ret void
213 //
214 void test_plix() {
215   __plix(2, 0, 0);
216 }
217 
218 /* 8.7 NOP */
219 // AArch32-LABEL: @test_nop(
220 // AArch32-NEXT:  entry:
221 // AArch32-NEXT:    call void @llvm.arm.hint(i32 0) [[ATTR1]]
222 // AArch32-NEXT:    ret void
223 //
224 // AArch64-LABEL: @test_nop(
225 // AArch64-NEXT:  entry:
226 // AArch64-NEXT:    call void @llvm.aarch64.hint(i32 0) [[ATTR3]]
227 // AArch64-NEXT:    ret void
228 //
229 void test_nop(void) {
230   __nop();
231 }
232 
233 /* 9 DATA-PROCESSING INTRINSICS */
234 
235 /* 9.2 Miscellaneous data-processing intrinsics */
236 // ARM-LABEL: @test_ror(
237 // ARM-NEXT:  entry:
238 // ARM-NEXT:    [[REM_I:%.*]] = urem i32 [[Y:%.*]], 32
239 // ARM-NEXT:    [[CMP_I:%.*]] = icmp eq i32 [[REM_I]], 0
240 // ARM-NEXT:    br i1 [[CMP_I]], label [[IF_THEN_I:%.*]], label [[IF_END_I:%.*]]
241 // ARM:       if.then.i:
242 // ARM-NEXT:    br label [[__ROR_EXIT:%.*]]
243 // ARM:       if.end.i:
244 // ARM-NEXT:    [[SHR_I:%.*]] = lshr i32 [[X:%.*]], [[REM_I]]
245 // ARM-NEXT:    [[SUB_I:%.*]] = sub i32 32, [[REM_I]]
246 // ARM-NEXT:    [[SHL_I:%.*]] = shl i32 [[X]], [[SUB_I]]
247 // ARM-NEXT:    [[OR_I:%.*]] = or i32 [[SHR_I]], [[SHL_I]]
248 // ARM-NEXT:    br label [[__ROR_EXIT]]
249 // ARM:       __ror.exit:
250 // ARM-NEXT:    [[RETVAL_I_0:%.*]] = phi i32 [ [[X]], [[IF_THEN_I]] ], [ [[OR_I]], [[IF_END_I]] ]
251 // ARM-NEXT:    ret i32 [[RETVAL_I_0]]
252 //
253 uint32_t test_ror(uint32_t x, uint32_t y) {
254   return __ror(x, y);
255 }
256 
257 // AArch32-LABEL: @test_rorl(
258 // AArch32-NEXT:  entry:
259 // AArch32-NEXT:    [[REM_I_I:%.*]] = urem i32 [[Y:%.*]], 32
260 // AArch32-NEXT:    [[CMP_I_I:%.*]] = icmp eq i32 [[REM_I_I]], 0
261 // AArch32-NEXT:    br i1 [[CMP_I_I]], label [[IF_THEN_I_I:%.*]], label [[IF_END_I_I:%.*]]
262 // AArch32:       if.then.i.i:
263 // AArch32-NEXT:    br label [[__RORL_EXIT:%.*]]
264 // AArch32:       if.end.i.i:
265 // AArch32-NEXT:    [[SHR_I_I:%.*]] = lshr i32 [[X:%.*]], [[REM_I_I]]
266 // AArch32-NEXT:    [[SUB_I_I:%.*]] = sub i32 32, [[REM_I_I]]
267 // AArch32-NEXT:    [[SHL_I_I:%.*]] = shl i32 [[X]], [[SUB_I_I]]
268 // AArch32-NEXT:    [[OR_I_I:%.*]] = or i32 [[SHR_I_I]], [[SHL_I_I]]
269 // AArch32-NEXT:    br label [[__RORL_EXIT]]
270 // AArch32:       __rorl.exit:
271 // AArch32-NEXT:    [[RETVAL_I_I_0:%.*]] = phi i32 [ [[X]], [[IF_THEN_I_I]] ], [ [[OR_I_I]], [[IF_END_I_I]] ]
272 // AArch32-NEXT:    ret i32 [[RETVAL_I_I_0]]
273 //
274 // AArch64-LABEL: @test_rorl(
275 // AArch64-NEXT:  entry:
276 // AArch64-NEXT:    [[REM_I:%.*]] = urem i32 [[Y:%.*]], 64
277 // AArch64-NEXT:    [[CMP_I:%.*]] = icmp eq i32 [[REM_I]], 0
278 // AArch64-NEXT:    br i1 [[CMP_I]], label [[IF_THEN_I:%.*]], label [[IF_END_I:%.*]]
279 // AArch64:       if.then.i:
280 // AArch64-NEXT:    br label [[__RORLL_EXIT:%.*]]
281 // AArch64:       if.end.i:
282 // AArch64-NEXT:    [[SH_PROM_I:%.*]] = zext i32 [[REM_I]] to i64
283 // AArch64-NEXT:    [[SHR_I:%.*]] = lshr i64 [[X:%.*]], [[SH_PROM_I]]
284 // AArch64-NEXT:    [[SUB_I:%.*]] = sub i32 64, [[REM_I]]
285 // AArch64-NEXT:    [[SH_PROM1_I:%.*]] = zext i32 [[SUB_I]] to i64
286 // AArch64-NEXT:    [[SHL_I:%.*]] = shl i64 [[X]], [[SH_PROM1_I]]
287 // AArch64-NEXT:    [[OR_I:%.*]] = or i64 [[SHR_I]], [[SHL_I]]
288 // AArch64-NEXT:    br label [[__RORLL_EXIT]]
289 // AArch64:       __rorll.exit:
290 // AArch64-NEXT:    [[RETVAL_I_0:%.*]] = phi i64 [ [[X]], [[IF_THEN_I]] ], [ [[OR_I]], [[IF_END_I]] ]
291 // AArch64-NEXT:    ret i64 [[RETVAL_I_0]]
292 //
293 unsigned long test_rorl(unsigned long x, uint32_t y) {
294   return __rorl(x, y);
295 }
296 
297 // ARM-LABEL: @test_rorll(
298 // ARM-NEXT:  entry:
299 // ARM-NEXT:    [[REM_I:%.*]] = urem i32 [[Y:%.*]], 64
300 // ARM-NEXT:    [[CMP_I:%.*]] = icmp eq i32 [[REM_I]], 0
301 // ARM-NEXT:    br i1 [[CMP_I]], label [[IF_THEN_I:%.*]], label [[IF_END_I:%.*]]
302 // ARM:       if.then.i:
303 // ARM-NEXT:    br label [[__RORLL_EXIT:%.*]]
304 // ARM:       if.end.i:
305 // ARM-NEXT:    [[SH_PROM_I:%.*]] = zext i32 [[REM_I]] to i64
306 // ARM-NEXT:    [[SHR_I:%.*]] = lshr i64 [[X:%.*]], [[SH_PROM_I]]
307 // ARM-NEXT:    [[SUB_I:%.*]] = sub i32 64, [[REM_I]]
308 // ARM-NEXT:    [[SH_PROM1_I:%.*]] = zext i32 [[SUB_I]] to i64
309 // ARM-NEXT:    [[SHL_I:%.*]] = shl i64 [[X]], [[SH_PROM1_I]]
310 // ARM-NEXT:    [[OR_I:%.*]] = or i64 [[SHR_I]], [[SHL_I]]
311 // ARM-NEXT:    br label [[__RORLL_EXIT]]
312 // ARM:       __rorll.exit:
313 // ARM-NEXT:    [[RETVAL_I_0:%.*]] = phi i64 [ [[X]], [[IF_THEN_I]] ], [ [[OR_I]], [[IF_END_I]] ]
314 // ARM-NEXT:    ret i64 [[RETVAL_I_0]]
315 //
316 uint64_t test_rorll(uint64_t x, uint32_t y) {
317   return __rorll(x, y);
318 }
319 
320 // AArch32-LABEL: @test_clz(
321 // AArch32-NEXT:  entry:
322 // AArch32-NEXT:    [[TMP0:%.*]] = call i32 @llvm.ctlz.i32(i32 [[T:%.*]], i1 false) [[ATTR1]]
323 // AArch32-NEXT:    ret i32 [[TMP0]]
324 //
325 // AArch64-LABEL: @test_clz(
326 // AArch64-NEXT:  entry:
327 // AArch64-NEXT:    [[TMP0:%.*]] = call i32 @llvm.ctlz.i32(i32 [[T:%.*]], i1 false) [[ATTR3]]
328 // AArch64-NEXT:    ret i32 [[TMP0]]
329 //
330 uint32_t test_clz(uint32_t t) {
331   return __clz(t);
332 }
333 
334 // AArch32-LABEL: @test_clzl(
335 // AArch32-NEXT:  entry:
336 // AArch32-NEXT:    [[TMP0:%.*]] = call i32 @llvm.ctlz.i32(i32 [[T:%.*]], i1 false) [[ATTR1]]
337 // AArch32-NEXT:    ret i32 [[TMP0]]
338 //
339 // AArch64-LABEL: @test_clzl(
340 // AArch64-NEXT:  entry:
341 // AArch64-NEXT:    [[TMP0:%.*]] = call i64 @llvm.ctlz.i64(i64 [[T:%.*]], i1 false) [[ATTR3]]
342 // AArch64-NEXT:    [[CAST_I:%.*]] = trunc i64 [[TMP0]] to i32
343 // AArch64-NEXT:    [[CONV_I:%.*]] = sext i32 [[CAST_I]] to i64
344 // AArch64-NEXT:    ret i64 [[CONV_I]]
345 //
346 long test_clzl(long t) {
347   return __clzl(t);
348 }
349 
350 // AArch32-LABEL: @test_clzll(
351 // AArch32-NEXT:  entry:
352 // AArch32-NEXT:    [[TMP0:%.*]] = call i64 @llvm.ctlz.i64(i64 [[T:%.*]], i1 false) [[ATTR1]]
353 // AArch32-NEXT:    [[CAST_I:%.*]] = trunc i64 [[TMP0]] to i32
354 // AArch32-NEXT:    [[CONV_I:%.*]] = sext i32 [[CAST_I]] to i64
355 // AArch32-NEXT:    ret i64 [[CONV_I]]
356 //
357 // AArch64-LABEL: @test_clzll(
358 // AArch64-NEXT:  entry:
359 // AArch64-NEXT:    [[TMP0:%.*]] = call i64 @llvm.ctlz.i64(i64 [[T:%.*]], i1 false) [[ATTR3]]
360 // AArch64-NEXT:    [[CAST_I:%.*]] = trunc i64 [[TMP0]] to i32
361 // AArch64-NEXT:    [[CONV_I:%.*]] = sext i32 [[CAST_I]] to i64
362 // AArch64-NEXT:    ret i64 [[CONV_I]]
363 //
364 uint64_t test_clzll(uint64_t t) {
365   return __clzll(t);
366 }
367 
368 // AArch32-LABEL: @test_cls(
369 // AArch32-NEXT:  entry:
370 // AArch32-NEXT:    [[CLS_I:%.*]] = call i32 @llvm.arm.cls(i32 [[T:%.*]]) [[ATTR1]]
371 // AArch32-NEXT:    ret i32 [[CLS_I]]
372 //
373 // AArch64-LABEL: @test_cls(
374 // AArch64-NEXT:  entry:
375 // AArch64-NEXT:    [[CLS_I:%.*]] = call i32 @llvm.aarch64.cls(i32 [[T:%.*]]) [[ATTR3]]
376 // AArch64-NEXT:    ret i32 [[CLS_I]]
377 //
378 unsigned test_cls(uint32_t t) {
379   return __cls(t);
380 }
381 
382 // AArch32-LABEL: @test_clsl(
383 // AArch32-NEXT:  entry:
384 // AArch32-NEXT:    [[CLS_I:%.*]] = call i32 @llvm.arm.cls(i32 [[T:%.*]]) [[ATTR1]]
385 // AArch32-NEXT:    ret i32 [[CLS_I]]
386 //
387 // AArch64-LABEL: @test_clsl(
388 // AArch64-NEXT:  entry:
389 // AArch64-NEXT:    [[CLS_I:%.*]] = call i32 @llvm.aarch64.cls64(i64 [[T:%.*]]) [[ATTR3]]
390 // AArch64-NEXT:    ret i32 [[CLS_I]]
391 //
392 unsigned test_clsl(unsigned long t) {
393   return __clsl(t);
394 }
395 
396 // AArch32-LABEL: @test_clsll(
397 // AArch32-NEXT:  entry:
398 // AArch32-NEXT:    [[CLS_I:%.*]] = call i32 @llvm.arm.cls64(i64 [[T:%.*]]) [[ATTR1]]
399 // AArch32-NEXT:    ret i32 [[CLS_I]]
400 //
401 // AArch64-LABEL: @test_clsll(
402 // AArch64-NEXT:  entry:
403 // AArch64-NEXT:    [[CLS_I:%.*]] = call i32 @llvm.aarch64.cls64(i64 [[T:%.*]]) [[ATTR3]]
404 // AArch64-NEXT:    ret i32 [[CLS_I]]
405 //
406 unsigned test_clsll(uint64_t t) {
407   return __clsll(t);
408 }
409 
410 // AArch32-LABEL: @test_rev(
411 // AArch32-NEXT:  entry:
412 // AArch32-NEXT:    [[TMP0:%.*]] = call i32 @llvm.bswap.i32(i32 [[T:%.*]]) [[ATTR1]]
413 // AArch32-NEXT:    ret i32 [[TMP0]]
414 //
415 // AArch64-LABEL: @test_rev(
416 // AArch64-NEXT:  entry:
417 // AArch64-NEXT:    [[TMP0:%.*]] = call i32 @llvm.bswap.i32(i32 [[T:%.*]]) [[ATTR3]]
418 // AArch64-NEXT:    ret i32 [[TMP0]]
419 //
420 uint32_t test_rev(uint32_t t) {
421   return __rev(t);
422 }
423 
424 // AArch32-LABEL: @test_revl(
425 // AArch32-NEXT:  entry:
426 // AArch32-NEXT:    [[TMP0:%.*]] = call i32 @llvm.bswap.i32(i32 [[T:%.*]]) [[ATTR1]]
427 // AArch32-NEXT:    ret i32 [[TMP0]]
428 //
429 // AArch64-LABEL: @test_revl(
430 // AArch64-NEXT:  entry:
431 // AArch64-NEXT:    [[TMP0:%.*]] = call i64 @llvm.bswap.i64(i64 [[T:%.*]]) [[ATTR3]]
432 // AArch64-NEXT:    ret i64 [[TMP0]]
433 //
434 long test_revl(long t) {
435   return __revl(t);
436 }
437 
438 // AArch32-LABEL: @test_revll(
439 // AArch32-NEXT:  entry:
440 // AArch32-NEXT:    [[TMP0:%.*]] = call i64 @llvm.bswap.i64(i64 [[T:%.*]]) [[ATTR1]]
441 // AArch32-NEXT:    ret i64 [[TMP0]]
442 //
443 // AArch64-LABEL: @test_revll(
444 // AArch64-NEXT:  entry:
445 // AArch64-NEXT:    [[TMP0:%.*]] = call i64 @llvm.bswap.i64(i64 [[T:%.*]]) [[ATTR3]]
446 // AArch64-NEXT:    ret i64 [[TMP0]]
447 //
448 uint64_t test_revll(uint64_t t) {
449   return __revll(t);
450 }
451 
452 // AArch32-LABEL: @test_rev16(
453 // AArch32-NEXT:  entry:
454 // AArch32-NEXT:    [[TMP0:%.*]] = call i32 @llvm.bswap.i32(i32 [[T:%.*]]) [[ATTR1]]
455 // AArch32-NEXT:    [[REM_I_I:%.*]] = urem i32 16, 32
456 // AArch32-NEXT:    [[CMP_I_I:%.*]] = icmp eq i32 [[REM_I_I]], 0
457 // AArch32-NEXT:    br i1 [[CMP_I_I]], label [[IF_THEN_I_I:%.*]], label [[IF_END_I_I:%.*]]
458 // AArch32:       if.then.i.i:
459 // AArch32-NEXT:    br label [[__REV16_EXIT:%.*]]
460 // AArch32:       if.end.i.i:
461 // AArch32-NEXT:    [[SHR_I_I:%.*]] = lshr i32 [[TMP0]], [[REM_I_I]]
462 // AArch32-NEXT:    [[SUB_I_I:%.*]] = sub i32 32, [[REM_I_I]]
463 // AArch32-NEXT:    [[SHL_I_I:%.*]] = shl i32 [[TMP0]], [[SUB_I_I]]
464 // AArch32-NEXT:    [[OR_I_I:%.*]] = or i32 [[SHR_I_I]], [[SHL_I_I]]
465 // AArch32-NEXT:    br label [[__REV16_EXIT]]
466 // AArch32:       __rev16.exit:
467 // AArch32-NEXT:    [[RETVAL_I_I_0:%.*]] = phi i32 [ [[TMP0]], [[IF_THEN_I_I]] ], [ [[OR_I_I]], [[IF_END_I_I]] ]
468 // AArch32-NEXT:    ret i32 [[RETVAL_I_I_0]]
469 //
470 // AArch64-LABEL: @test_rev16(
471 // AArch64-NEXT:  entry:
472 // AArch64-NEXT:    [[TMP0:%.*]] = call i32 @llvm.bswap.i32(i32 [[T:%.*]]) [[ATTR3]]
473 // AArch64-NEXT:    [[REM_I_I:%.*]] = urem i32 16, 32
474 // AArch64-NEXT:    [[CMP_I_I:%.*]] = icmp eq i32 [[REM_I_I]], 0
475 // AArch64-NEXT:    br i1 [[CMP_I_I]], label [[IF_THEN_I_I:%.*]], label [[IF_END_I_I:%.*]]
476 // AArch64:       if.then.i.i:
477 // AArch64-NEXT:    br label [[__REV16_EXIT:%.*]]
478 // AArch64:       if.end.i.i:
479 // AArch64-NEXT:    [[SHR_I_I:%.*]] = lshr i32 [[TMP0]], [[REM_I_I]]
480 // AArch64-NEXT:    [[SUB_I_I:%.*]] = sub i32 32, [[REM_I_I]]
481 // AArch64-NEXT:    [[SHL_I_I:%.*]] = shl i32 [[TMP0]], [[SUB_I_I]]
482 // AArch64-NEXT:    [[OR_I_I:%.*]] = or i32 [[SHR_I_I]], [[SHL_I_I]]
483 // AArch64-NEXT:    br label [[__REV16_EXIT]]
484 // AArch64:       __rev16.exit:
485 // AArch64-NEXT:    [[RETVAL_I_I_0:%.*]] = phi i32 [ [[TMP0]], [[IF_THEN_I_I]] ], [ [[OR_I_I]], [[IF_END_I_I]] ]
486 // AArch64-NEXT:    ret i32 [[RETVAL_I_I_0]]
487 //
488 uint32_t test_rev16(uint32_t t) {
489   return __rev16(t);
490 }
491 
492 // AArch32-LABEL: @test_rev16l(
493 // AArch32-NEXT:  entry:
494 // AArch32-NEXT:    [[TMP0:%.*]] = call i32 @llvm.bswap.i32(i32 [[T:%.*]]) [[ATTR1]]
495 // AArch32-NEXT:    [[REM_I_I_I:%.*]] = urem i32 16, 32
496 // AArch32-NEXT:    [[CMP_I_I_I:%.*]] = icmp eq i32 [[REM_I_I_I]], 0
497 // AArch32-NEXT:    br i1 [[CMP_I_I_I]], label [[IF_THEN_I_I_I:%.*]], label [[IF_END_I_I_I:%.*]]
498 // AArch32:       if.then.i.i.i:
499 // AArch32-NEXT:    br label [[__REV16L_EXIT:%.*]]
500 // AArch32:       if.end.i.i.i:
501 // AArch32-NEXT:    [[SHR_I_I_I:%.*]] = lshr i32 [[TMP0]], [[REM_I_I_I]]
502 // AArch32-NEXT:    [[SUB_I_I_I:%.*]] = sub i32 32, [[REM_I_I_I]]
503 // AArch32-NEXT:    [[SHL_I_I_I:%.*]] = shl i32 [[TMP0]], [[SUB_I_I_I]]
504 // AArch32-NEXT:    [[OR_I_I_I:%.*]] = or i32 [[SHR_I_I_I]], [[SHL_I_I_I]]
505 // AArch32-NEXT:    br label [[__REV16L_EXIT]]
506 // AArch32:       __rev16l.exit:
507 // AArch32-NEXT:    [[RETVAL_I_I_I_0:%.*]] = phi i32 [ [[TMP0]], [[IF_THEN_I_I_I]] ], [ [[OR_I_I_I]], [[IF_END_I_I_I]] ]
508 // AArch32-NEXT:    ret i32 [[RETVAL_I_I_I_0]]
509 //
510 // AArch64-LABEL: @test_rev16l(
511 // AArch64-NEXT:  entry:
512 // AArch64-NEXT:    [[SHR_I:%.*]] = lshr i64 [[T:%.*]], 32
513 // AArch64-NEXT:    [[CONV_I:%.*]] = trunc i64 [[SHR_I]] to i32
514 // AArch64-NEXT:    [[TMP0:%.*]] = call i32 @llvm.bswap.i32(i32 [[CONV_I]]) [[ATTR3]]
515 // AArch64-NEXT:    [[REM_I_I10_I:%.*]] = urem i32 16, 32
516 // AArch64-NEXT:    [[CMP_I_I11_I:%.*]] = icmp eq i32 [[REM_I_I10_I]], 0
517 // AArch64-NEXT:    br i1 [[CMP_I_I11_I]], label [[IF_THEN_I_I12_I:%.*]], label [[IF_END_I_I17_I:%.*]]
518 // AArch64:       if.then.i.i12.i:
519 // AArch64-NEXT:    br label [[__REV16_EXIT18_I:%.*]]
520 // AArch64:       if.end.i.i17.i:
521 // AArch64-NEXT:    [[SHR_I_I13_I:%.*]] = lshr i32 [[TMP0]], [[REM_I_I10_I]]
522 // AArch64-NEXT:    [[SUB_I_I14_I:%.*]] = sub i32 32, [[REM_I_I10_I]]
523 // AArch64-NEXT:    [[SHL_I_I15_I:%.*]] = shl i32 [[TMP0]], [[SUB_I_I14_I]]
524 // AArch64-NEXT:    [[OR_I_I16_I:%.*]] = or i32 [[SHR_I_I13_I]], [[SHL_I_I15_I]]
525 // AArch64-NEXT:    br label [[__REV16_EXIT18_I]]
526 // AArch64:       __rev16.exit18.i:
527 // AArch64-NEXT:    [[RETVAL_I_I6_I_0:%.*]] = phi i32 [ [[TMP0]], [[IF_THEN_I_I12_I]] ], [ [[OR_I_I16_I]], [[IF_END_I_I17_I]] ]
528 // AArch64-NEXT:    [[CONV1_I:%.*]] = zext i32 [[RETVAL_I_I6_I_0]] to i64
529 // AArch64-NEXT:    [[SHL_I:%.*]] = shl i64 [[CONV1_I]], 32
530 // AArch64-NEXT:    [[CONV2_I:%.*]] = trunc i64 [[T]] to i32
531 // AArch64-NEXT:    [[TMP1:%.*]] = call i32 @llvm.bswap.i32(i32 [[CONV2_I]]) [[ATTR3]]
532 // AArch64-NEXT:    [[REM_I_I_I:%.*]] = urem i32 16, 32
533 // AArch64-NEXT:    [[CMP_I_I_I:%.*]] = icmp eq i32 [[REM_I_I_I]], 0
534 // AArch64-NEXT:    br i1 [[CMP_I_I_I]], label [[IF_THEN_I_I_I:%.*]], label [[IF_END_I_I_I:%.*]]
535 // AArch64:       if.then.i.i.i:
536 // AArch64-NEXT:    br label [[__REV16LL_EXIT:%.*]]
537 // AArch64:       if.end.i.i.i:
538 // AArch64-NEXT:    [[SHR_I_I_I:%.*]] = lshr i32 [[TMP1]], [[REM_I_I_I]]
539 // AArch64-NEXT:    [[SUB_I_I_I:%.*]] = sub i32 32, [[REM_I_I_I]]
540 // AArch64-NEXT:    [[SHL_I_I_I:%.*]] = shl i32 [[TMP1]], [[SUB_I_I_I]]
541 // AArch64-NEXT:    [[OR_I_I_I:%.*]] = or i32 [[SHR_I_I_I]], [[SHL_I_I_I]]
542 // AArch64-NEXT:    br label [[__REV16LL_EXIT]]
543 // AArch64:       __rev16ll.exit:
544 // AArch64-NEXT:    [[RETVAL_I_I_I_0:%.*]] = phi i32 [ [[TMP1]], [[IF_THEN_I_I_I]] ], [ [[OR_I_I_I]], [[IF_END_I_I_I]] ]
545 // AArch64-NEXT:    [[CONV4_I:%.*]] = zext i32 [[RETVAL_I_I_I_0]] to i64
546 // AArch64-NEXT:    [[OR_I:%.*]] = or i64 [[SHL_I]], [[CONV4_I]]
547 // AArch64-NEXT:    ret i64 [[OR_I]]
548 //
549 long test_rev16l(long t) {
550   return __rev16l(t);
551 }
552 
553 // AArch32-LABEL: @test_rev16ll(
554 // AArch32-NEXT:  entry:
555 // AArch32-NEXT:    [[SHR_I:%.*]] = lshr i64 [[T:%.*]], 32
556 // AArch32-NEXT:    [[CONV_I:%.*]] = trunc i64 [[SHR_I]] to i32
557 // AArch32-NEXT:    [[TMP0:%.*]] = call i32 @llvm.bswap.i32(i32 [[CONV_I]]) [[ATTR1]]
558 // AArch32-NEXT:    [[REM_I_I10_I:%.*]] = urem i32 16, 32
559 // AArch32-NEXT:    [[CMP_I_I11_I:%.*]] = icmp eq i32 [[REM_I_I10_I]], 0
560 // AArch32-NEXT:    br i1 [[CMP_I_I11_I]], label [[IF_THEN_I_I12_I:%.*]], label [[IF_END_I_I17_I:%.*]]
561 // AArch32:       if.then.i.i12.i:
562 // AArch32-NEXT:    br label [[__REV16_EXIT18_I:%.*]]
563 // AArch32:       if.end.i.i17.i:
564 // AArch32-NEXT:    [[SHR_I_I13_I:%.*]] = lshr i32 [[TMP0]], [[REM_I_I10_I]]
565 // AArch32-NEXT:    [[SUB_I_I14_I:%.*]] = sub i32 32, [[REM_I_I10_I]]
566 // AArch32-NEXT:    [[SHL_I_I15_I:%.*]] = shl i32 [[TMP0]], [[SUB_I_I14_I]]
567 // AArch32-NEXT:    [[OR_I_I16_I:%.*]] = or i32 [[SHR_I_I13_I]], [[SHL_I_I15_I]]
568 // AArch32-NEXT:    br label [[__REV16_EXIT18_I]]
569 // AArch32:       __rev16.exit18.i:
570 // AArch32-NEXT:    [[RETVAL_I_I6_I_0:%.*]] = phi i32 [ [[TMP0]], [[IF_THEN_I_I12_I]] ], [ [[OR_I_I16_I]], [[IF_END_I_I17_I]] ]
571 // AArch32-NEXT:    [[CONV1_I:%.*]] = zext i32 [[RETVAL_I_I6_I_0]] to i64
572 // AArch32-NEXT:    [[SHL_I:%.*]] = shl i64 [[CONV1_I]], 32
573 // AArch32-NEXT:    [[CONV2_I:%.*]] = trunc i64 [[T]] to i32
574 // AArch32-NEXT:    [[TMP1:%.*]] = call i32 @llvm.bswap.i32(i32 [[CONV2_I]]) [[ATTR1]]
575 // AArch32-NEXT:    [[REM_I_I_I:%.*]] = urem i32 16, 32
576 // AArch32-NEXT:    [[CMP_I_I_I:%.*]] = icmp eq i32 [[REM_I_I_I]], 0
577 // AArch32-NEXT:    br i1 [[CMP_I_I_I]], label [[IF_THEN_I_I_I:%.*]], label [[IF_END_I_I_I:%.*]]
578 // AArch32:       if.then.i.i.i:
579 // AArch32-NEXT:    br label [[__REV16LL_EXIT:%.*]]
580 // AArch32:       if.end.i.i.i:
581 // AArch32-NEXT:    [[SHR_I_I_I:%.*]] = lshr i32 [[TMP1]], [[REM_I_I_I]]
582 // AArch32-NEXT:    [[SUB_I_I_I:%.*]] = sub i32 32, [[REM_I_I_I]]
583 // AArch32-NEXT:    [[SHL_I_I_I:%.*]] = shl i32 [[TMP1]], [[SUB_I_I_I]]
584 // AArch32-NEXT:    [[OR_I_I_I:%.*]] = or i32 [[SHR_I_I_I]], [[SHL_I_I_I]]
585 // AArch32-NEXT:    br label [[__REV16LL_EXIT]]
586 // AArch32:       __rev16ll.exit:
587 // AArch32-NEXT:    [[RETVAL_I_I_I_0:%.*]] = phi i32 [ [[TMP1]], [[IF_THEN_I_I_I]] ], [ [[OR_I_I_I]], [[IF_END_I_I_I]] ]
588 // AArch32-NEXT:    [[CONV4_I:%.*]] = zext i32 [[RETVAL_I_I_I_0]] to i64
589 // AArch32-NEXT:    [[OR_I:%.*]] = or i64 [[SHL_I]], [[CONV4_I]]
590 // AArch32-NEXT:    ret i64 [[OR_I]]
591 //
592 // AArch64-LABEL: @test_rev16ll(
593 // AArch64-NEXT:  entry:
594 // AArch64-NEXT:    [[SHR_I:%.*]] = lshr i64 [[T:%.*]], 32
595 // AArch64-NEXT:    [[CONV_I:%.*]] = trunc i64 [[SHR_I]] to i32
596 // AArch64-NEXT:    [[TMP0:%.*]] = call i32 @llvm.bswap.i32(i32 [[CONV_I]]) [[ATTR3]]
597 // AArch64-NEXT:    [[REM_I_I10_I:%.*]] = urem i32 16, 32
598 // AArch64-NEXT:    [[CMP_I_I11_I:%.*]] = icmp eq i32 [[REM_I_I10_I]], 0
599 // AArch64-NEXT:    br i1 [[CMP_I_I11_I]], label [[IF_THEN_I_I12_I:%.*]], label [[IF_END_I_I17_I:%.*]]
600 // AArch64:       if.then.i.i12.i:
601 // AArch64-NEXT:    br label [[__REV16_EXIT18_I:%.*]]
602 // AArch64:       if.end.i.i17.i:
603 // AArch64-NEXT:    [[SHR_I_I13_I:%.*]] = lshr i32 [[TMP0]], [[REM_I_I10_I]]
604 // AArch64-NEXT:    [[SUB_I_I14_I:%.*]] = sub i32 32, [[REM_I_I10_I]]
605 // AArch64-NEXT:    [[SHL_I_I15_I:%.*]] = shl i32 [[TMP0]], [[SUB_I_I14_I]]
606 // AArch64-NEXT:    [[OR_I_I16_I:%.*]] = or i32 [[SHR_I_I13_I]], [[SHL_I_I15_I]]
607 // AArch64-NEXT:    br label [[__REV16_EXIT18_I]]
608 // AArch64:       __rev16.exit18.i:
609 // AArch64-NEXT:    [[RETVAL_I_I6_I_0:%.*]] = phi i32 [ [[TMP0]], [[IF_THEN_I_I12_I]] ], [ [[OR_I_I16_I]], [[IF_END_I_I17_I]] ]
610 // AArch64-NEXT:    [[CONV1_I:%.*]] = zext i32 [[RETVAL_I_I6_I_0]] to i64
611 // AArch64-NEXT:    [[SHL_I:%.*]] = shl i64 [[CONV1_I]], 32
612 // AArch64-NEXT:    [[CONV2_I:%.*]] = trunc i64 [[T]] to i32
613 // AArch64-NEXT:    [[TMP1:%.*]] = call i32 @llvm.bswap.i32(i32 [[CONV2_I]]) [[ATTR3]]
614 // AArch64-NEXT:    [[REM_I_I_I:%.*]] = urem i32 16, 32
615 // AArch64-NEXT:    [[CMP_I_I_I:%.*]] = icmp eq i32 [[REM_I_I_I]], 0
616 // AArch64-NEXT:    br i1 [[CMP_I_I_I]], label [[IF_THEN_I_I_I:%.*]], label [[IF_END_I_I_I:%.*]]
617 // AArch64:       if.then.i.i.i:
618 // AArch64-NEXT:    br label [[__REV16LL_EXIT:%.*]]
619 // AArch64:       if.end.i.i.i:
620 // AArch64-NEXT:    [[SHR_I_I_I:%.*]] = lshr i32 [[TMP1]], [[REM_I_I_I]]
621 // AArch64-NEXT:    [[SUB_I_I_I:%.*]] = sub i32 32, [[REM_I_I_I]]
622 // AArch64-NEXT:    [[SHL_I_I_I:%.*]] = shl i32 [[TMP1]], [[SUB_I_I_I]]
623 // AArch64-NEXT:    [[OR_I_I_I:%.*]] = or i32 [[SHR_I_I_I]], [[SHL_I_I_I]]
624 // AArch64-NEXT:    br label [[__REV16LL_EXIT]]
625 // AArch64:       __rev16ll.exit:
626 // AArch64-NEXT:    [[RETVAL_I_I_I_0:%.*]] = phi i32 [ [[TMP1]], [[IF_THEN_I_I_I]] ], [ [[OR_I_I_I]], [[IF_END_I_I_I]] ]
627 // AArch64-NEXT:    [[CONV4_I:%.*]] = zext i32 [[RETVAL_I_I_I_0]] to i64
628 // AArch64-NEXT:    [[OR_I:%.*]] = or i64 [[SHL_I]], [[CONV4_I]]
629 // AArch64-NEXT:    ret i64 [[OR_I]]
630 //
631 uint64_t test_rev16ll(uint64_t t) {
632   return __rev16ll(t);
633 }
634 
635 // AArch32-LABEL: @test_revsh(
636 // AArch32-NEXT:  entry:
637 // AArch32-NEXT:    [[TMP0:%.*]] = call i16 @llvm.bswap.i16(i16 [[T:%.*]]) [[ATTR1]]
638 // AArch32-NEXT:    ret i16 [[TMP0]]
639 //
640 // AArch64-LABEL: @test_revsh(
641 // AArch64-NEXT:  entry:
642 // AArch64-NEXT:    [[TMP0:%.*]] = call i16 @llvm.bswap.i16(i16 [[T:%.*]]) [[ATTR3]]
643 // AArch64-NEXT:    ret i16 [[TMP0]]
644 //
645 int16_t test_revsh(int16_t t) {
646   return __revsh(t);
647 }
648 
649 // AArch32-LABEL: @test_rbit(
650 // AArch32-NEXT:  entry:
651 // AArch32-NEXT:    [[RBIT_I:%.*]] = call i32 @llvm.bitreverse.i32(i32 [[T:%.*]]) [[ATTR1]]
652 // AArch32-NEXT:    ret i32 [[RBIT_I]]
653 //
654 // AArch64-LABEL: @test_rbit(
655 // AArch64-NEXT:  entry:
656 // AArch64-NEXT:    [[RBIT_I:%.*]] = call i32 @llvm.bitreverse.i32(i32 [[T:%.*]]) [[ATTR3]]
657 // AArch64-NEXT:    ret i32 [[RBIT_I]]
658 //
659 uint32_t test_rbit(uint32_t t) {
660   return __rbit(t);
661 }
662 
663 // AArch32-LABEL: @test_rbitl(
664 // AArch32-NEXT:  entry:
665 // AArch32-NEXT:    [[RBIT_I_I:%.*]] = call i32 @llvm.bitreverse.i32(i32 [[T:%.*]]) [[ATTR1]]
666 // AArch32-NEXT:    ret i32 [[RBIT_I_I]]
667 //
668 // AArch64-LABEL: @test_rbitl(
669 // AArch64-NEXT:  entry:
670 // AArch64-NEXT:    [[RBIT_I:%.*]] = call i64 @llvm.bitreverse.i64(i64 [[T:%.*]]) [[ATTR3]]
671 // AArch64-NEXT:    ret i64 [[RBIT_I]]
672 //
673 long test_rbitl(long t) {
674   return __rbitl(t);
675 }
676 
677 // AArch32-LABEL: @test_rbitll(
678 // AArch32-NEXT:  entry:
679 // AArch32-NEXT:    [[CONV_I:%.*]] = trunc i64 [[T:%.*]] to i32
680 // AArch32-NEXT:    [[RBIT_I:%.*]] = call i32 @llvm.bitreverse.i32(i32 [[CONV_I]]) [[ATTR1]]
681 // AArch32-NEXT:    [[CONV1_I:%.*]] = zext i32 [[RBIT_I]] to i64
682 // AArch32-NEXT:    [[SHL_I:%.*]] = shl i64 [[CONV1_I]], 32
683 // AArch32-NEXT:    [[SHR_I:%.*]] = lshr i64 [[T]], 32
684 // AArch32-NEXT:    [[CONV2_I:%.*]] = trunc i64 [[SHR_I]] to i32
685 // AArch32-NEXT:    [[RBIT3_I:%.*]] = call i32 @llvm.bitreverse.i32(i32 [[CONV2_I]]) [[ATTR1]]
686 // AArch32-NEXT:    [[CONV4_I:%.*]] = zext i32 [[RBIT3_I]] to i64
687 // AArch32-NEXT:    [[OR_I:%.*]] = or i64 [[SHL_I]], [[CONV4_I]]
688 // AArch32-NEXT:    ret i64 [[OR_I]]
689 //
690 // AArch64-LABEL: @test_rbitll(
691 // AArch64-NEXT:  entry:
692 // AArch64-NEXT:    [[RBIT_I:%.*]] = call i64 @llvm.bitreverse.i64(i64 [[T:%.*]]) [[ATTR3]]
693 // AArch64-NEXT:    ret i64 [[RBIT_I]]
694 //
695 uint64_t test_rbitll(uint64_t t) {
696   return __rbitll(t);
697 }
698 
699 /* 9.4 Saturating intrinsics */
700 #ifdef __ARM_FEATURE_SAT
701 /* 9.4.1 Width-specified saturation intrinsics */
702 // AArch32-LABEL: @test_ssat(
703 // AArch32-NEXT:  entry:
704 // AArch32-NEXT:    [[TMP0:%.*]] = call i32 @llvm.arm.ssat(i32 [[T:%.*]], i32 1)
705 // AArch32-NEXT:    ret i32 [[TMP0]]
706 //
707 int32_t test_ssat(int32_t t) {
708   return __ssat(t, 1);
709 }
710 
711 // AArch32-LABEL: @test_usat(
712 // AArch32-NEXT:  entry:
713 // AArch32-NEXT:    [[TMP0:%.*]] = call i32 @llvm.arm.usat(i32 [[T:%.*]], i32 2)
714 // AArch32-NEXT:    ret i32 [[TMP0]]
715 //
716 uint32_t test_usat(int32_t t) {
717   return __usat(t, 2);
718 }
719 #endif
720 
721 /* 9.4.2 Saturating addition and subtraction intrinsics */
722 #ifdef __ARM_FEATURE_DSP
723 // AArch32-LABEL: @test_qadd(
724 // AArch32-NEXT:  entry:
725 // AArch32-NEXT:    [[TMP0:%.*]] = call i32 @llvm.arm.qadd(i32 [[A:%.*]], i32 [[B:%.*]]) [[ATTR1]]
726 // AArch32-NEXT:    ret i32 [[TMP0]]
727 //
728 int32_t test_qadd(int32_t a, int32_t b) {
729   return __qadd(a, b);
730 }
731 
732 // AArch32-LABEL: @test_qsub(
733 // AArch32-NEXT:  entry:
734 // AArch32-NEXT:    [[TMP0:%.*]] = call i32 @llvm.arm.qsub(i32 [[A:%.*]], i32 [[B:%.*]]) [[ATTR1]]
735 // AArch32-NEXT:    ret i32 [[TMP0]]
736 //
737 int32_t test_qsub(int32_t a, int32_t b) {
738   return __qsub(a, b);
739 }
740 
741 extern int32_t f();
742 // AArch32-LABEL: @test_qdbl(
743 // AArch32-NEXT:  entry:
744 // AArch32-NEXT:    [[CALL:%.*]] = call i32 bitcast (i32 (...)* @f to i32 ()*)() [[ATTR7:#.*]]
745 // AArch32-NEXT:    [[TMP0:%.*]] = call i32 @llvm.arm.qadd(i32 [[CALL]], i32 [[CALL]]) [[ATTR1]]
746 // AArch32-NEXT:    ret i32 [[TMP0]]
747 //
748 int32_t test_qdbl() {
749   return __qdbl(f());
750 }
751 #endif
752 
753 /*
754  * 9.3 16-bit multiplications
755  */
756 #if __ARM_FEATURE_DSP
757 // AArch32-LABEL: @test_smulbb(
758 // AArch32-NEXT:  entry:
759 // AArch32-NEXT:    [[TMP0:%.*]] = call i32 @llvm.arm.smulbb(i32 [[A:%.*]], i32 [[B:%.*]]) [[ATTR1]]
760 // AArch32-NEXT:    ret i32 [[TMP0]]
761 //
762 int32_t test_smulbb(int32_t a, int32_t b) {
763   return __smulbb(a, b);
764 }
765 
766 // AArch32-LABEL: @test_smulbt(
767 // AArch32-NEXT:  entry:
768 // AArch32-NEXT:    [[TMP0:%.*]] = call i32 @llvm.arm.smulbt(i32 [[A:%.*]], i32 [[B:%.*]]) [[ATTR1]]
769 // AArch32-NEXT:    ret i32 [[TMP0]]
770 //
771 int32_t test_smulbt(int32_t a, int32_t b) {
772   return __smulbt(a, b);
773 }
774 
775 // AArch32-LABEL: @test_smultb(
776 // AArch32-NEXT:  entry:
777 // AArch32-NEXT:    [[TMP0:%.*]] = call i32 @llvm.arm.smultb(i32 [[A:%.*]], i32 [[B:%.*]]) [[ATTR1]]
778 // AArch32-NEXT:    ret i32 [[TMP0]]
779 //
780 int32_t test_smultb(int32_t a, int32_t b) {
781   return __smultb(a, b);
782 }
783 
784 // AArch32-LABEL: @test_smultt(
785 // AArch32-NEXT:  entry:
786 // AArch32-NEXT:    [[TMP0:%.*]] = call i32 @llvm.arm.smultt(i32 [[A:%.*]], i32 [[B:%.*]]) [[ATTR1]]
787 // AArch32-NEXT:    ret i32 [[TMP0]]
788 //
789 int32_t test_smultt(int32_t a, int32_t b) {
790   return __smultt(a, b);
791 }
792 
793 // AArch32-LABEL: @test_smulwb(
794 // AArch32-NEXT:  entry:
795 // AArch32-NEXT:    [[TMP0:%.*]] = call i32 @llvm.arm.smulwb(i32 [[A:%.*]], i32 [[B:%.*]]) [[ATTR1]]
796 // AArch32-NEXT:    ret i32 [[TMP0]]
797 //
798 int32_t test_smulwb(int32_t a, int32_t b) {
799   return __smulwb(a, b);
800 }
801 
802 // AArch32-LABEL: @test_smulwt(
803 // AArch32-NEXT:  entry:
804 // AArch32-NEXT:    [[TMP0:%.*]] = call i32 @llvm.arm.smulwt(i32 [[A:%.*]], i32 [[B:%.*]]) [[ATTR1]]
805 // AArch32-NEXT:    ret i32 [[TMP0]]
806 //
807 int32_t test_smulwt(int32_t a, int32_t b) {
808   return __smulwt(a, b);
809 }
810 #endif
811 
812 /* 9.4.3 Accumultating multiplications */
813 #if __ARM_FEATURE_DSP
814 // AArch32-LABEL: @test_smlabb(
815 // AArch32-NEXT:  entry:
816 // AArch32-NEXT:    [[TMP0:%.*]] = call i32 @llvm.arm.smlabb(i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) [[ATTR1]]
817 // AArch32-NEXT:    ret i32 [[TMP0]]
818 //
819 int32_t test_smlabb(int32_t a, int32_t b, int32_t c) {
820   return __smlabb(a, b, c);
821 }
822 
823 // AArch32-LABEL: @test_smlabt(
824 // AArch32-NEXT:  entry:
825 // AArch32-NEXT:    [[TMP0:%.*]] = call i32 @llvm.arm.smlabt(i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) [[ATTR1]]
826 // AArch32-NEXT:    ret i32 [[TMP0]]
827 //
828 int32_t test_smlabt(int32_t a, int32_t b, int32_t c) {
829   return __smlabt(a, b, c);
830 }
831 
832 // AArch32-LABEL: @test_smlatb(
833 // AArch32-NEXT:  entry:
834 // AArch32-NEXT:    [[TMP0:%.*]] = call i32 @llvm.arm.smlatb(i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) [[ATTR1]]
835 // AArch32-NEXT:    ret i32 [[TMP0]]
836 //
837 int32_t test_smlatb(int32_t a, int32_t b, int32_t c) {
838   return __smlatb(a, b, c);
839 }
840 
841 // AArch32-LABEL: @test_smlatt(
842 // AArch32-NEXT:  entry:
843 // AArch32-NEXT:    [[TMP0:%.*]] = call i32 @llvm.arm.smlatt(i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) [[ATTR1]]
844 // AArch32-NEXT:    ret i32 [[TMP0]]
845 //
846 int32_t test_smlatt(int32_t a, int32_t b, int32_t c) {
847   return __smlatt(a, b, c);
848 }
849 
850 // AArch32-LABEL: @test_smlawb(
851 // AArch32-NEXT:  entry:
852 // AArch32-NEXT:    [[TMP0:%.*]] = call i32 @llvm.arm.smlawb(i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) [[ATTR1]]
853 // AArch32-NEXT:    ret i32 [[TMP0]]
854 //
855 int32_t test_smlawb(int32_t a, int32_t b, int32_t c) {
856   return __smlawb(a, b, c);
857 }
858 
859 // AArch32-LABEL: @test_smlawt(
860 // AArch32-NEXT:  entry:
861 // AArch32-NEXT:    [[TMP0:%.*]] = call i32 @llvm.arm.smlawt(i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) [[ATTR1]]
862 // AArch32-NEXT:    ret i32 [[TMP0]]
863 //
864 int32_t test_smlawt(int32_t a, int32_t b, int32_t c) {
865   return __smlawt(a, b, c);
866 }
867 #endif
868 
869 /* 9.5.4 Parallel 16-bit saturation */
870 #if __ARM_FEATURE_SIMD32
871 // AArch32-LABEL: @test_ssat16(
872 // AArch32-NEXT:  entry:
873 // AArch32-NEXT:    [[TMP0:%.*]] = call i32 @llvm.arm.ssat16(i32 [[A:%.*]], i32 15)
874 // AArch32-NEXT:    ret i32 [[TMP0]]
875 //
876 int16x2_t test_ssat16(int16x2_t a) {
877   return __ssat16(a, 15);
878 }
879 
880 // AArch32-LABEL: @test_usat16(
881 // AArch32-NEXT:  entry:
882 // AArch32-NEXT:    [[TMP0:%.*]] = call i32 @llvm.arm.usat16(i32 [[A:%.*]], i32 15)
883 // AArch32-NEXT:    ret i32 [[TMP0]]
884 //
885 uint16x2_t test_usat16(int16x2_t a) {
886   return __usat16(a, 15);
887 }
888 #endif
889 
890 /* 9.5.5 Packing and unpacking */
891 #if __ARM_FEATURE_SIMD32
892 // AArch32-LABEL: @test_sxtab16(
893 // AArch32-NEXT:  entry:
894 // AArch32-NEXT:    [[TMP0:%.*]] = call i32 @llvm.arm.sxtab16(i32 [[A:%.*]], i32 [[B:%.*]]) [[ATTR1]]
895 // AArch32-NEXT:    ret i32 [[TMP0]]
896 //
897 int16x2_t test_sxtab16(int16x2_t a, int8x4_t b) {
898   return __sxtab16(a, b);
899 }
900 
901 // AArch32-LABEL: @test_sxtb16(
902 // AArch32-NEXT:  entry:
903 // AArch32-NEXT:    [[TMP0:%.*]] = call i32 @llvm.arm.sxtb16(i32 [[A:%.*]]) [[ATTR1]]
904 // AArch32-NEXT:    ret i32 [[TMP0]]
905 //
906 int16x2_t test_sxtb16(int8x4_t a) {
907   return __sxtb16(a);
908 }
909 
910 // AArch32-LABEL: @test_uxtab16(
911 // AArch32-NEXT:  entry:
912 // AArch32-NEXT:    [[TMP0:%.*]] = call i32 @llvm.arm.uxtab16(i32 [[A:%.*]], i32 [[B:%.*]]) [[ATTR1]]
913 // AArch32-NEXT:    ret i32 [[TMP0]]
914 //
915 int16x2_t test_uxtab16(int16x2_t a, int8x4_t b) {
916   return __uxtab16(a, b);
917 }
918 
919 // AArch32-LABEL: @test_uxtb16(
920 // AArch32-NEXT:  entry:
921 // AArch32-NEXT:    [[TMP0:%.*]] = call i32 @llvm.arm.uxtb16(i32 [[A:%.*]]) [[ATTR1]]
922 // AArch32-NEXT:    ret i32 [[TMP0]]
923 //
924 int16x2_t test_uxtb16(int8x4_t a) {
925   return __uxtb16(a);
926 }
927 #endif
928 
929 /* 9.5.6 Parallel selection */
930 #if __ARM_FEATURE_SIMD32
931 // AArch32-LABEL: @test_sel(
932 // AArch32-NEXT:  entry:
933 // AArch32-NEXT:    [[TMP0:%.*]] = call i32 @llvm.arm.sel(i32 [[A:%.*]], i32 [[B:%.*]]) [[ATTR1]]
934 // AArch32-NEXT:    ret i32 [[TMP0]]
935 //
936 uint8x4_t test_sel(uint8x4_t a, uint8x4_t b) {
937   return __sel(a, b);
938 }
939 #endif
940 
941 /* 9.5.7 Parallel 8-bit addition and subtraction */
942 #if __ARM_FEATURE_SIMD32
943 // AArch32-LABEL: @test_qadd8(
944 // AArch32-NEXT:  entry:
945 // AArch32-NEXT:    [[TMP0:%.*]] = call i32 @llvm.arm.qadd8(i32 [[A:%.*]], i32 [[B:%.*]]) [[ATTR1]]
946 // AArch32-NEXT:    ret i32 [[TMP0]]
947 //
948 int16x2_t test_qadd8(int8x4_t a, int8x4_t b) {
949   return __qadd8(a, b);
950 }
951 
952 // AArch32-LABEL: @test_qsub8(
953 // AArch32-NEXT:  entry:
954 // AArch32-NEXT:    [[TMP0:%.*]] = call i32 @llvm.arm.qsub8(i32 [[A:%.*]], i32 [[B:%.*]]) [[ATTR1]]
955 // AArch32-NEXT:    ret i32 [[TMP0]]
956 //
957 int8x4_t test_qsub8(int8x4_t a, int8x4_t b) {
958   return __qsub8(a, b);
959 }
960 
961 // AArch32-LABEL: @test_sadd8(
962 // AArch32-NEXT:  entry:
963 // AArch32-NEXT:    [[TMP0:%.*]] = call i32 @llvm.arm.sadd8(i32 [[A:%.*]], i32 [[B:%.*]]) [[ATTR1]]
964 // AArch32-NEXT:    ret i32 [[TMP0]]
965 //
966 int8x4_t test_sadd8(int8x4_t a, int8x4_t b) {
967   return __sadd8(a, b);
968 }
969 
970 // AArch32-LABEL: @test_shadd8(
971 // AArch32-NEXT:  entry:
972 // AArch32-NEXT:    [[TMP0:%.*]] = call i32 @llvm.arm.shadd8(i32 [[A:%.*]], i32 [[B:%.*]]) [[ATTR1]]
973 // AArch32-NEXT:    ret i32 [[TMP0]]
974 //
975 int8x4_t test_shadd8(int8x4_t a, int8x4_t b) {
976   return __shadd8(a, b);
977 }
978 
979 // AArch32-LABEL: @test_shsub8(
980 // AArch32-NEXT:  entry:
981 // AArch32-NEXT:    [[TMP0:%.*]] = call i32 @llvm.arm.shsub8(i32 [[A:%.*]], i32 [[B:%.*]]) [[ATTR1]]
982 // AArch32-NEXT:    ret i32 [[TMP0]]
983 //
984 int8x4_t test_shsub8(int8x4_t a, int8x4_t b) {
985   return __shsub8(a, b);
986 }
987 
988 // AArch32-LABEL: @test_ssub8(
989 // AArch32-NEXT:  entry:
990 // AArch32-NEXT:    [[TMP0:%.*]] = call i32 @llvm.arm.ssub8(i32 [[A:%.*]], i32 [[B:%.*]]) [[ATTR1]]
991 // AArch32-NEXT:    ret i32 [[TMP0]]
992 //
993 int8x4_t test_ssub8(int8x4_t a, int8x4_t b) {
994   return __ssub8(a, b);
995 }
996 
997 // AArch32-LABEL: @test_uadd8(
998 // AArch32-NEXT:  entry:
999 // AArch32-NEXT:    [[TMP0:%.*]] = call i32 @llvm.arm.uadd8(i32 [[A:%.*]], i32 [[B:%.*]]) [[ATTR1]]
1000 // AArch32-NEXT:    ret i32 [[TMP0]]
1001 //
1002 uint8x4_t test_uadd8(uint8x4_t a, uint8x4_t b) {
1003   return __uadd8(a, b);
1004 }
1005 
1006 // AArch32-LABEL: @test_uhadd8(
1007 // AArch32-NEXT:  entry:
1008 // AArch32-NEXT:    [[TMP0:%.*]] = call i32 @llvm.arm.uhadd8(i32 [[A:%.*]], i32 [[B:%.*]]) [[ATTR1]]
1009 // AArch32-NEXT:    ret i32 [[TMP0]]
1010 //
1011 uint8x4_t test_uhadd8(uint8x4_t a, uint8x4_t b) {
1012   return __uhadd8(a, b);
1013 }
1014 
1015 // AArch32-LABEL: @test_uhsub8(
1016 // AArch32-NEXT:  entry:
1017 // AArch32-NEXT:    [[TMP0:%.*]] = call i32 @llvm.arm.uhsub8(i32 [[A:%.*]], i32 [[B:%.*]]) [[ATTR1]]
1018 // AArch32-NEXT:    ret i32 [[TMP0]]
1019 //
1020 uint8x4_t test_uhsub8(uint8x4_t a, uint8x4_t b) {
1021   return __uhsub8(a, b);
1022 }
1023 
1024 // AArch32-LABEL: @test_uqadd8(
1025 // AArch32-NEXT:  entry:
1026 // AArch32-NEXT:    [[TMP0:%.*]] = call i32 @llvm.arm.uqadd8(i32 [[A:%.*]], i32 [[B:%.*]]) [[ATTR1]]
1027 // AArch32-NEXT:    ret i32 [[TMP0]]
1028 //
1029 uint8x4_t test_uqadd8(uint8x4_t a, uint8x4_t b) {
1030   return __uqadd8(a, b);
1031 }
1032 
1033 // AArch32-LABEL: @test_uqsub8(
1034 // AArch32-NEXT:  entry:
1035 // AArch32-NEXT:    [[TMP0:%.*]] = call i32 @llvm.arm.uqsub8(i32 [[A:%.*]], i32 [[B:%.*]]) [[ATTR1]]
1036 // AArch32-NEXT:    ret i32 [[TMP0]]
1037 //
1038 uint8x4_t test_uqsub8(uint8x4_t a, uint8x4_t b) {
1039   return __uqsub8(a, b);
1040 }
1041 
1042 // AArch32-LABEL: @test_usub8(
1043 // AArch32-NEXT:  entry:
1044 // AArch32-NEXT:    [[TMP0:%.*]] = call i32 @llvm.arm.usub8(i32 [[A:%.*]], i32 [[B:%.*]]) [[ATTR1]]
1045 // AArch32-NEXT:    ret i32 [[TMP0]]
1046 //
1047 uint8x4_t test_usub8(uint8x4_t a, uint8x4_t b) {
1048   return __usub8(a, b);
1049 }
1050 #endif
1051 
1052 /* 9.5.8 Sum of 8-bit absolute differences */
1053 #if __ARM_FEATURE_SIMD32
1054 // AArch32-LABEL: @test_usad8(
1055 // AArch32-NEXT:  entry:
1056 // AArch32-NEXT:    [[TMP0:%.*]] = call i32 @llvm.arm.usad8(i32 [[A:%.*]], i32 [[B:%.*]]) [[ATTR1]]
1057 // AArch32-NEXT:    ret i32 [[TMP0]]
1058 //
1059 uint32_t test_usad8(uint8x4_t a, uint8x4_t b) {
1060   return __usad8(a, b);
1061 }
1062 
1063 // AArch32-LABEL: @test_usada8(
1064 // AArch32-NEXT:  entry:
1065 // AArch32-NEXT:    [[CONV:%.*]] = zext i8 [[A:%.*]] to i32
1066 // AArch32-NEXT:    [[CONV1:%.*]] = zext i8 [[B:%.*]] to i32
1067 // AArch32-NEXT:    [[CONV2:%.*]] = zext i8 [[C:%.*]] to i32
1068 // AArch32-NEXT:    [[TMP0:%.*]] = call i32 @llvm.arm.usada8(i32 [[CONV]], i32 [[CONV1]], i32 [[CONV2]]) [[ATTR1]]
1069 // AArch32-NEXT:    ret i32 [[TMP0]]
1070 //
1071 uint32_t test_usada8(uint8_t a, uint8_t b, uint8_t c) {
1072   return __usada8(a, b, c);
1073 }
1074 #endif
1075 
1076 /* 9.5.9 Parallel 16-bit addition and subtraction */
1077 #if __ARM_FEATURE_SIMD32
1078 // AArch32-LABEL: @test_qadd16(
1079 // AArch32-NEXT:  entry:
1080 // AArch32-NEXT:    [[TMP0:%.*]] = call i32 @llvm.arm.qadd16(i32 [[A:%.*]], i32 [[B:%.*]]) [[ATTR1]]
1081 // AArch32-NEXT:    ret i32 [[TMP0]]
1082 //
1083 int16x2_t test_qadd16(int16x2_t a, int16x2_t b) {
1084   return __qadd16(a, b);
1085 }
1086 
1087 // AArch32-LABEL: @test_qasx(
1088 // AArch32-NEXT:  entry:
1089 // AArch32-NEXT:    [[TMP0:%.*]] = call i32 @llvm.arm.qasx(i32 [[A:%.*]], i32 [[B:%.*]]) [[ATTR1]]
1090 // AArch32-NEXT:    ret i32 [[TMP0]]
1091 //
1092 int16x2_t test_qasx(int16x2_t a, int16x2_t b) {
1093   return __qasx(a, b);
1094 }
1095 
1096 // AArch32-LABEL: @test_qsax(
1097 // AArch32-NEXT:  entry:
1098 // AArch32-NEXT:    [[TMP0:%.*]] = call i32 @llvm.arm.qsax(i32 [[A:%.*]], i32 [[B:%.*]]) [[ATTR1]]
1099 // AArch32-NEXT:    ret i32 [[TMP0]]
1100 //
1101 int16x2_t test_qsax(int16x2_t a, int16x2_t b) {
1102   return __qsax(a, b);
1103 }
1104 
1105 // AArch32-LABEL: @test_qsub16(
1106 // AArch32-NEXT:  entry:
1107 // AArch32-NEXT:    [[TMP0:%.*]] = call i32 @llvm.arm.qsub16(i32 [[A:%.*]], i32 [[B:%.*]]) [[ATTR1]]
1108 // AArch32-NEXT:    ret i32 [[TMP0]]
1109 //
1110 int16x2_t test_qsub16(int16x2_t a, int16x2_t b) {
1111   return __qsub16(a, b);
1112 }
1113 
1114 // AArch32-LABEL: @test_sadd16(
1115 // AArch32-NEXT:  entry:
1116 // AArch32-NEXT:    [[TMP0:%.*]] = call i32 @llvm.arm.sadd16(i32 [[A:%.*]], i32 [[B:%.*]]) [[ATTR1]]
1117 // AArch32-NEXT:    ret i32 [[TMP0]]
1118 //
1119 int16x2_t test_sadd16(int16x2_t a, int16x2_t b) {
1120   return __sadd16(a, b);
1121 }
1122 
1123 // AArch32-LABEL: @test_sasx(
1124 // AArch32-NEXT:  entry:
1125 // AArch32-NEXT:    [[TMP0:%.*]] = call i32 @llvm.arm.sasx(i32 [[A:%.*]], i32 [[B:%.*]]) [[ATTR1]]
1126 // AArch32-NEXT:    ret i32 [[TMP0]]
1127 //
1128 int16x2_t test_sasx(int16x2_t a, int16x2_t b) {
1129   return __sasx(a, b);
1130 }
1131 
1132 // AArch32-LABEL: @test_shadd16(
1133 // AArch32-NEXT:  entry:
1134 // AArch32-NEXT:    [[TMP0:%.*]] = call i32 @llvm.arm.shadd16(i32 [[A:%.*]], i32 [[B:%.*]]) [[ATTR1]]
1135 // AArch32-NEXT:    ret i32 [[TMP0]]
1136 //
1137 int16x2_t test_shadd16(int16x2_t a, int16x2_t b) {
1138   return __shadd16(a, b);
1139 }
1140 
1141 // AArch32-LABEL: @test_shasx(
1142 // AArch32-NEXT:  entry:
1143 // AArch32-NEXT:    [[TMP0:%.*]] = call i32 @llvm.arm.shasx(i32 [[A:%.*]], i32 [[B:%.*]]) [[ATTR1]]
1144 // AArch32-NEXT:    ret i32 [[TMP0]]
1145 //
1146 int16x2_t test_shasx(int16x2_t a, int16x2_t b) {
1147   return __shasx(a, b);
1148 }
1149 
1150 // AArch32-LABEL: @test_shsax(
1151 // AArch32-NEXT:  entry:
1152 // AArch32-NEXT:    [[TMP0:%.*]] = call i32 @llvm.arm.shsax(i32 [[A:%.*]], i32 [[B:%.*]]) [[ATTR1]]
1153 // AArch32-NEXT:    ret i32 [[TMP0]]
1154 //
1155 int16x2_t test_shsax(int16x2_t a, int16x2_t b) {
1156   return __shsax(a, b);
1157 }
1158 
1159 // AArch32-LABEL: @test_shsub16(
1160 // AArch32-NEXT:  entry:
1161 // AArch32-NEXT:    [[TMP0:%.*]] = call i32 @llvm.arm.shsub16(i32 [[A:%.*]], i32 [[B:%.*]]) [[ATTR1]]
1162 // AArch32-NEXT:    ret i32 [[TMP0]]
1163 //
1164 int16x2_t test_shsub16(int16x2_t a, int16x2_t b) {
1165   return __shsub16(a, b);
1166 }
1167 
1168 // AArch32-LABEL: @test_ssax(
1169 // AArch32-NEXT:  entry:
1170 // AArch32-NEXT:    [[TMP0:%.*]] = call i32 @llvm.arm.ssax(i32 [[A:%.*]], i32 [[B:%.*]]) [[ATTR1]]
1171 // AArch32-NEXT:    ret i32 [[TMP0]]
1172 //
1173 int16x2_t test_ssax(int16x2_t a, int16x2_t b) {
1174   return __ssax(a, b);
1175 }
1176 
1177 // AArch32-LABEL: @test_ssub16(
1178 // AArch32-NEXT:  entry:
1179 // AArch32-NEXT:    [[TMP0:%.*]] = call i32 @llvm.arm.ssub16(i32 [[A:%.*]], i32 [[B:%.*]]) [[ATTR1]]
1180 // AArch32-NEXT:    ret i32 [[TMP0]]
1181 //
1182 int16x2_t test_ssub16(int16x2_t a, int16x2_t b) {
1183   return __ssub16(a, b);
1184 }
1185 
1186 // AArch32-LABEL: @test_uadd16(
1187 // AArch32-NEXT:  entry:
1188 // AArch32-NEXT:    [[TMP0:%.*]] = call i32 @llvm.arm.uadd16(i32 [[A:%.*]], i32 [[B:%.*]]) [[ATTR1]]
1189 // AArch32-NEXT:    ret i32 [[TMP0]]
1190 //
1191 uint16x2_t test_uadd16(uint16x2_t a, uint16x2_t b) {
1192   return __uadd16(a, b);
1193 }
1194 
1195 // AArch32-LABEL: @test_uasx(
1196 // AArch32-NEXT:  entry:
1197 // AArch32-NEXT:    [[TMP0:%.*]] = call i32 @llvm.arm.uasx(i32 [[A:%.*]], i32 [[B:%.*]]) [[ATTR1]]
1198 // AArch32-NEXT:    ret i32 [[TMP0]]
1199 //
1200 uint16x2_t test_uasx(uint16x2_t a, uint16x2_t b) {
1201   return __uasx(a, b);
1202 }
1203 
1204 // AArch32-LABEL: @test_uhadd16(
1205 // AArch32-NEXT:  entry:
1206 // AArch32-NEXT:    [[TMP0:%.*]] = call i32 @llvm.arm.uhadd16(i32 [[A:%.*]], i32 [[B:%.*]]) [[ATTR1]]
1207 // AArch32-NEXT:    ret i32 [[TMP0]]
1208 //
1209 uint16x2_t test_uhadd16(uint16x2_t a, uint16x2_t b) {
1210   return __uhadd16(a, b);
1211 }
1212 
1213 // AArch32-LABEL: @test_uhasx(
1214 // AArch32-NEXT:  entry:
1215 // AArch32-NEXT:    [[TMP0:%.*]] = call i32 @llvm.arm.uhasx(i32 [[A:%.*]], i32 [[B:%.*]]) [[ATTR1]]
1216 // AArch32-NEXT:    ret i32 [[TMP0]]
1217 //
1218 uint16x2_t test_uhasx(uint16x2_t a, uint16x2_t b) {
1219   return __uhasx(a, b);
1220 }
1221 
1222 // AArch32-LABEL: @test_uhsax(
1223 // AArch32-NEXT:  entry:
1224 // AArch32-NEXT:    [[TMP0:%.*]] = call i32 @llvm.arm.uhsax(i32 [[A:%.*]], i32 [[B:%.*]]) [[ATTR1]]
1225 // AArch32-NEXT:    ret i32 [[TMP0]]
1226 //
1227 uint16x2_t test_uhsax(uint16x2_t a, uint16x2_t b) {
1228   return __uhsax(a, b);
1229 }
1230 
1231 // AArch32-LABEL: @test_uhsub16(
1232 // AArch32-NEXT:  entry:
1233 // AArch32-NEXT:    [[TMP0:%.*]] = call i32 @llvm.arm.uhsub16(i32 [[A:%.*]], i32 [[B:%.*]]) [[ATTR1]]
1234 // AArch32-NEXT:    ret i32 [[TMP0]]
1235 //
1236 uint16x2_t test_uhsub16(uint16x2_t a, uint16x2_t b) {
1237   return __uhsub16(a, b);
1238 }
1239 
1240 // AArch32-LABEL: @test_uqadd16(
1241 // AArch32-NEXT:  entry:
1242 // AArch32-NEXT:    [[TMP0:%.*]] = call i32 @llvm.arm.uqadd16(i32 [[A:%.*]], i32 [[B:%.*]]) [[ATTR1]]
1243 // AArch32-NEXT:    ret i32 [[TMP0]]
1244 //
1245 uint16x2_t test_uqadd16(uint16x2_t a, uint16x2_t b) {
1246   return __uqadd16(a, b);
1247 }
1248 
1249 // AArch32-LABEL: @test_uqasx(
1250 // AArch32-NEXT:  entry:
1251 // AArch32-NEXT:    [[TMP0:%.*]] = call i32 @llvm.arm.uqasx(i32 [[A:%.*]], i32 [[B:%.*]]) [[ATTR1]]
1252 // AArch32-NEXT:    ret i32 [[TMP0]]
1253 //
1254 uint16x2_t test_uqasx(uint16x2_t a, uint16x2_t b) {
1255   return __uqasx(a, b);
1256 }
1257 
1258 // AArch32-LABEL: @test_uqsax(
1259 // AArch32-NEXT:  entry:
1260 // AArch32-NEXT:    [[TMP0:%.*]] = call i32 @llvm.arm.uqsax(i32 [[A:%.*]], i32 [[B:%.*]]) [[ATTR1]]
1261 // AArch32-NEXT:    ret i32 [[TMP0]]
1262 //
1263 uint16x2_t test_uqsax(uint16x2_t a, uint16x2_t b) {
1264   return __uqsax(a, b);
1265 }
1266 
1267 // AArch32-LABEL: @test_uqsub16(
1268 // AArch32-NEXT:  entry:
1269 // AArch32-NEXT:    [[TMP0:%.*]] = call i32 @llvm.arm.uqsub16(i32 [[A:%.*]], i32 [[B:%.*]]) [[ATTR1]]
1270 // AArch32-NEXT:    ret i32 [[TMP0]]
1271 //
1272 uint16x2_t test_uqsub16(uint16x2_t a, uint16x2_t b) {
1273   return __uqsub16(a, b);
1274 }
1275 
1276 // AArch32-LABEL: @test_usax(
1277 // AArch32-NEXT:  entry:
1278 // AArch32-NEXT:    [[TMP0:%.*]] = call i32 @llvm.arm.usax(i32 [[A:%.*]], i32 [[B:%.*]]) [[ATTR1]]
1279 // AArch32-NEXT:    ret i32 [[TMP0]]
1280 //
1281 uint16x2_t test_usax(uint16x2_t a, uint16x2_t b) {
1282   return __usax(a, b);
1283 }
1284 
1285 // AArch32-LABEL: @test_usub16(
1286 // AArch32-NEXT:  entry:
1287 // AArch32-NEXT:    [[TMP0:%.*]] = call i32 @llvm.arm.usub16(i32 [[A:%.*]], i32 [[B:%.*]]) [[ATTR1]]
1288 // AArch32-NEXT:    ret i32 [[TMP0]]
1289 //
1290 uint16x2_t test_usub16(uint16x2_t a, uint16x2_t b) {
1291   return __usub16(a, b);
1292 }
1293 #endif
1294 
1295 /* 9.5.10 Parallel 16-bit multiplications */
1296 #if __ARM_FEATURE_SIMD32
1297 // AArch32-LABEL: @test_smlad(
1298 // AArch32-NEXT:  entry:
1299 // AArch32-NEXT:    [[TMP0:%.*]] = call i32 @llvm.arm.smlad(i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) [[ATTR1]]
1300 // AArch32-NEXT:    ret i32 [[TMP0]]
1301 //
1302 int32_t test_smlad(int16x2_t a, int16x2_t b, int32_t c) {
1303   return __smlad(a, b, c);
1304 }
1305 
1306 // AArch32-LABEL: @test_smladx(
1307 // AArch32-NEXT:  entry:
1308 // AArch32-NEXT:    [[TMP0:%.*]] = call i32 @llvm.arm.smladx(i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) [[ATTR1]]
1309 // AArch32-NEXT:    ret i32 [[TMP0]]
1310 //
1311 int32_t test_smladx(int16x2_t a, int16x2_t b, int32_t c) {
1312   return __smladx(a, b, c);
1313 }
1314 
1315 // AArch32-LABEL: @test_smlald(
1316 // AArch32-NEXT:  entry:
1317 // AArch32-NEXT:    [[TMP0:%.*]] = call i64 @llvm.arm.smlald(i32 [[A:%.*]], i32 [[B:%.*]], i64 [[C:%.*]]) [[ATTR1]]
1318 // AArch32-NEXT:    ret i64 [[TMP0]]
1319 //
1320 int64_t test_smlald(int16x2_t a, int16x2_t b, int64_t c) {
1321   return __smlald(a, b, c);
1322 }
1323 
1324 // AArch32-LABEL: @test_smlaldx(
1325 // AArch32-NEXT:  entry:
1326 // AArch32-NEXT:    [[TMP0:%.*]] = call i64 @llvm.arm.smlaldx(i32 [[A:%.*]], i32 [[B:%.*]], i64 [[C:%.*]]) [[ATTR1]]
1327 // AArch32-NEXT:    ret i64 [[TMP0]]
1328 //
1329 int64_t test_smlaldx(int16x2_t a, int16x2_t b, int64_t c) {
1330   return __smlaldx(a, b, c);
1331 }
1332 
1333 // AArch32-LABEL: @test_smlsd(
1334 // AArch32-NEXT:  entry:
1335 // AArch32-NEXT:    [[TMP0:%.*]] = call i32 @llvm.arm.smlsd(i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) [[ATTR1]]
1336 // AArch32-NEXT:    ret i32 [[TMP0]]
1337 //
1338 int32_t test_smlsd(int16x2_t a, int16x2_t b, int32_t c) {
1339   return __smlsd(a, b, c);
1340 }
1341 
1342 // AArch32-LABEL: @test_smlsdx(
1343 // AArch32-NEXT:  entry:
1344 // AArch32-NEXT:    [[TMP0:%.*]] = call i32 @llvm.arm.smlsdx(i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) [[ATTR1]]
1345 // AArch32-NEXT:    ret i32 [[TMP0]]
1346 //
1347 int32_t test_smlsdx(int16x2_t a, int16x2_t b, int32_t c) {
1348   return __smlsdx(a, b, c);
1349 }
1350 
1351 // AArch32-LABEL: @test_smlsld(
1352 // AArch32-NEXT:  entry:
1353 // AArch32-NEXT:    [[TMP0:%.*]] = call i64 @llvm.arm.smlsld(i32 [[A:%.*]], i32 [[B:%.*]], i64 [[C:%.*]]) [[ATTR1]]
1354 // AArch32-NEXT:    ret i64 [[TMP0]]
1355 //
1356 int64_t test_smlsld(int16x2_t a, int16x2_t b, int64_t c) {
1357   return __smlsld(a, b, c);
1358 }
1359 
1360 // AArch32-LABEL: @test_smlsldx(
1361 // AArch32-NEXT:  entry:
1362 // AArch32-NEXT:    [[TMP0:%.*]] = call i64 @llvm.arm.smlsldx(i32 [[A:%.*]], i32 [[B:%.*]], i64 [[C:%.*]]) [[ATTR1]]
1363 // AArch32-NEXT:    ret i64 [[TMP0]]
1364 //
1365 int64_t test_smlsldx(int16x2_t a, int16x2_t b, int64_t c) {
1366   return __smlsldx(a, b, c);
1367 }
1368 
1369 // AArch32-LABEL: @test_smuad(
1370 // AArch32-NEXT:  entry:
1371 // AArch32-NEXT:    [[TMP0:%.*]] = call i32 @llvm.arm.smuad(i32 [[A:%.*]], i32 [[B:%.*]]) [[ATTR1]]
1372 // AArch32-NEXT:    ret i32 [[TMP0]]
1373 //
1374 int32_t test_smuad(int16x2_t a, int16x2_t b) {
1375   return __smuad(a, b);
1376 }
1377 
1378 // AArch32-LABEL: @test_smuadx(
1379 // AArch32-NEXT:  entry:
1380 // AArch32-NEXT:    [[TMP0:%.*]] = call i32 @llvm.arm.smuadx(i32 [[A:%.*]], i32 [[B:%.*]]) [[ATTR1]]
1381 // AArch32-NEXT:    ret i32 [[TMP0]]
1382 //
1383 int32_t test_smuadx(int16x2_t a, int16x2_t b) {
1384   return __smuadx(a, b);
1385 }
1386 
1387 // AArch32-LABEL: @test_smusd(
1388 // AArch32-NEXT:  entry:
1389 // AArch32-NEXT:    [[TMP0:%.*]] = call i32 @llvm.arm.smusd(i32 [[A:%.*]], i32 [[B:%.*]]) [[ATTR1]]
1390 // AArch32-NEXT:    ret i32 [[TMP0]]
1391 //
1392 int32_t test_smusd(int16x2_t a, int16x2_t b) {
1393   return __smusd(a, b);
1394 }
1395 
1396 // AArch32-LABEL: @test_smusdx(
1397 // AArch32-NEXT:  entry:
1398 // AArch32-NEXT:    [[TMP0:%.*]] = call i32 @llvm.arm.smusdx(i32 [[A:%.*]], i32 [[B:%.*]]) [[ATTR1]]
1399 // AArch32-NEXT:    ret i32 [[TMP0]]
1400 //
1401 int32_t test_smusdx(int16x2_t a, int16x2_t b) {
1402   return __smusdx(a, b);
1403 }
1404 #endif
1405 
1406 /* 9.7 CRC32 intrinsics */
1407 // AArch32-LABEL: @test_crc32b(
1408 // AArch32-NEXT:  entry:
1409 // AArch32-NEXT:    [[TMP0:%.*]] = zext i8 [[B:%.*]] to i32
1410 // AArch32-NEXT:    [[TMP1:%.*]] = call i32 @llvm.arm.crc32b(i32 [[A:%.*]], i32 [[TMP0]]) [[ATTR1]]
1411 // AArch32-NEXT:    ret i32 [[TMP1]]
1412 //
1413 // AArch64-LABEL: @test_crc32b(
1414 // AArch64-NEXT:  entry:
1415 // AArch64-NEXT:    [[TMP0:%.*]] = zext i8 [[B:%.*]] to i32
1416 // AArch64-NEXT:    [[TMP1:%.*]] = call i32 @llvm.aarch64.crc32b(i32 [[A:%.*]], i32 [[TMP0]]) [[ATTR3]]
1417 // AArch64-NEXT:    ret i32 [[TMP1]]
1418 //
1419 uint32_t test_crc32b(uint32_t a, uint8_t b) {
1420   return __crc32b(a, b);
1421 }
1422 
1423 // AArch32-LABEL: @test_crc32h(
1424 // AArch32-NEXT:  entry:
1425 // AArch32-NEXT:    [[TMP0:%.*]] = zext i16 [[B:%.*]] to i32
1426 // AArch32-NEXT:    [[TMP1:%.*]] = call i32 @llvm.arm.crc32h(i32 [[A:%.*]], i32 [[TMP0]]) [[ATTR1]]
1427 // AArch32-NEXT:    ret i32 [[TMP1]]
1428 //
1429 // AArch64-LABEL: @test_crc32h(
1430 // AArch64-NEXT:  entry:
1431 // AArch64-NEXT:    [[TMP0:%.*]] = zext i16 [[B:%.*]] to i32
1432 // AArch64-NEXT:    [[TMP1:%.*]] = call i32 @llvm.aarch64.crc32h(i32 [[A:%.*]], i32 [[TMP0]]) [[ATTR3]]
1433 // AArch64-NEXT:    ret i32 [[TMP1]]
1434 //
1435 uint32_t test_crc32h(uint32_t a, uint16_t b) {
1436   return __crc32h(a, b);
1437 }
1438 
1439 // AArch32-LABEL: @test_crc32w(
1440 // AArch32-NEXT:  entry:
1441 // AArch32-NEXT:    [[TMP0:%.*]] = call i32 @llvm.arm.crc32w(i32 [[A:%.*]], i32 [[B:%.*]]) [[ATTR1]]
1442 // AArch32-NEXT:    ret i32 [[TMP0]]
1443 //
1444 // AArch64-LABEL: @test_crc32w(
1445 // AArch64-NEXT:  entry:
1446 // AArch64-NEXT:    [[TMP0:%.*]] = call i32 @llvm.aarch64.crc32w(i32 [[A:%.*]], i32 [[B:%.*]]) [[ATTR3]]
1447 // AArch64-NEXT:    ret i32 [[TMP0]]
1448 //
1449 uint32_t test_crc32w(uint32_t a, uint32_t b) {
1450   return __crc32w(a, b);
1451 }
1452 
1453 // AArch32-LABEL: @test_crc32d(
1454 // AArch32-NEXT:  entry:
1455 // AArch32-NEXT:    [[TMP0:%.*]] = trunc i64 [[B:%.*]] to i32
1456 // AArch32-NEXT:    [[TMP1:%.*]] = lshr i64 [[B]], 32
1457 // AArch32-NEXT:    [[TMP2:%.*]] = trunc i64 [[TMP1]] to i32
1458 // AArch32-NEXT:    [[TMP3:%.*]] = call i32 @llvm.arm.crc32w(i32 [[A:%.*]], i32 [[TMP0]]) [[ATTR1]]
1459 // AArch32-NEXT:    [[TMP4:%.*]] = call i32 @llvm.arm.crc32w(i32 [[TMP3]], i32 [[TMP2]]) [[ATTR1]]
1460 // AArch32-NEXT:    ret i32 [[TMP4]]
1461 //
1462 // AArch64-LABEL: @test_crc32d(
1463 // AArch64-NEXT:  entry:
1464 // AArch64-NEXT:    [[TMP0:%.*]] = call i32 @llvm.aarch64.crc32x(i32 [[A:%.*]], i64 [[B:%.*]]) [[ATTR3]]
1465 // AArch64-NEXT:    ret i32 [[TMP0]]
1466 //
1467 uint32_t test_crc32d(uint32_t a, uint64_t b) {
1468   return __crc32d(a, b);
1469 }
1470 
1471 // AArch32-LABEL: @test_crc32cb(
1472 // AArch32-NEXT:  entry:
1473 // AArch32-NEXT:    [[TMP0:%.*]] = zext i8 [[B:%.*]] to i32
1474 // AArch32-NEXT:    [[TMP1:%.*]] = call i32 @llvm.arm.crc32cb(i32 [[A:%.*]], i32 [[TMP0]]) [[ATTR1]]
1475 // AArch32-NEXT:    ret i32 [[TMP1]]
1476 //
1477 // AArch64-LABEL: @test_crc32cb(
1478 // AArch64-NEXT:  entry:
1479 // AArch64-NEXT:    [[TMP0:%.*]] = zext i8 [[B:%.*]] to i32
1480 // AArch64-NEXT:    [[TMP1:%.*]] = call i32 @llvm.aarch64.crc32cb(i32 [[A:%.*]], i32 [[TMP0]]) [[ATTR3]]
1481 // AArch64-NEXT:    ret i32 [[TMP1]]
1482 //
1483 uint32_t test_crc32cb(uint32_t a, uint8_t b) {
1484   return __crc32cb(a, b);
1485 }
1486 
1487 // AArch32-LABEL: @test_crc32ch(
1488 // AArch32-NEXT:  entry:
1489 // AArch32-NEXT:    [[TMP0:%.*]] = zext i16 [[B:%.*]] to i32
1490 // AArch32-NEXT:    [[TMP1:%.*]] = call i32 @llvm.arm.crc32ch(i32 [[A:%.*]], i32 [[TMP0]]) [[ATTR1]]
1491 // AArch32-NEXT:    ret i32 [[TMP1]]
1492 //
1493 // AArch64-LABEL: @test_crc32ch(
1494 // AArch64-NEXT:  entry:
1495 // AArch64-NEXT:    [[TMP0:%.*]] = zext i16 [[B:%.*]] to i32
1496 // AArch64-NEXT:    [[TMP1:%.*]] = call i32 @llvm.aarch64.crc32ch(i32 [[A:%.*]], i32 [[TMP0]]) [[ATTR3]]
1497 // AArch64-NEXT:    ret i32 [[TMP1]]
1498 //
1499 uint32_t test_crc32ch(uint32_t a, uint16_t b) {
1500   return __crc32ch(a, b);
1501 }
1502 
1503 // AArch32-LABEL: @test_crc32cw(
1504 // AArch32-NEXT:  entry:
1505 // AArch32-NEXT:    [[TMP0:%.*]] = call i32 @llvm.arm.crc32cw(i32 [[A:%.*]], i32 [[B:%.*]]) [[ATTR1]]
1506 // AArch32-NEXT:    ret i32 [[TMP0]]
1507 //
1508 // AArch64-LABEL: @test_crc32cw(
1509 // AArch64-NEXT:  entry:
1510 // AArch64-NEXT:    [[TMP0:%.*]] = call i32 @llvm.aarch64.crc32cw(i32 [[A:%.*]], i32 [[B:%.*]]) [[ATTR3]]
1511 // AArch64-NEXT:    ret i32 [[TMP0]]
1512 //
1513 uint32_t test_crc32cw(uint32_t a, uint32_t b) {
1514   return __crc32cw(a, b);
1515 }
1516 
1517 // AArch32-LABEL: @test_crc32cd(
1518 // AArch32-NEXT:  entry:
1519 // AArch32-NEXT:    [[TMP0:%.*]] = trunc i64 [[B:%.*]] to i32
1520 // AArch32-NEXT:    [[TMP1:%.*]] = lshr i64 [[B]], 32
1521 // AArch32-NEXT:    [[TMP2:%.*]] = trunc i64 [[TMP1]] to i32
1522 // AArch32-NEXT:    [[TMP3:%.*]] = call i32 @llvm.arm.crc32cw(i32 [[A:%.*]], i32 [[TMP0]]) [[ATTR1]]
1523 // AArch32-NEXT:    [[TMP4:%.*]] = call i32 @llvm.arm.crc32cw(i32 [[TMP3]], i32 [[TMP2]]) [[ATTR1]]
1524 // AArch32-NEXT:    ret i32 [[TMP4]]
1525 //
1526 // AArch64-LABEL: @test_crc32cd(
1527 // AArch64-NEXT:  entry:
1528 // AArch64-NEXT:    [[TMP0:%.*]] = call i32 @llvm.aarch64.crc32cx(i32 [[A:%.*]], i64 [[B:%.*]]) [[ATTR3]]
1529 // AArch64-NEXT:    ret i32 [[TMP0]]
1530 //
1531 uint32_t test_crc32cd(uint32_t a, uint64_t b) {
1532   return __crc32cd(a, b);
1533 }
1534 
1535 /* 10.1 Special register intrinsics */
1536 // AArch32-LABEL: @test_rsr(
1537 // AArch32-NEXT:  entry:
1538 // AArch32-NEXT:    [[TMP0:%.*]] = call i32 @llvm.read_volatile_register.i32(metadata !5)
1539 // AArch32-NEXT:    ret i32 [[TMP0]]
1540 //
1541 // AArch64-LABEL: @test_rsr(
1542 // AArch64-NEXT:  entry:
1543 // AArch64-NEXT:    [[TMP0:%.*]] = call i64 @llvm.read_volatile_register.i64(metadata !8)
1544 // AArch64-NEXT:    [[TMP1:%.*]] = trunc i64 [[TMP0]] to i32
1545 // AArch64-NEXT:    ret i32 [[TMP1]]
1546 //
1547 uint32_t test_rsr() {
1548 #ifdef __ARM_32BIT_STATE
1549   return __arm_rsr("cp1:2:c3:c4:5");
1550 #else
1551   return __arm_rsr("1:2:3:4:5");
1552 #endif
1553 }
1554 
1555 // AArch32-LABEL: @test_rsr64(
1556 // AArch32-NEXT:  entry:
1557 // AArch32-NEXT:    [[TMP0:%.*]] = call i64 @llvm.read_volatile_register.i64(metadata !6)
1558 // AArch32-NEXT:    ret i64 [[TMP0]]
1559 //
1560 // AArch64-LABEL: @test_rsr64(
1561 // AArch64-NEXT:  entry:
1562 // AArch64-NEXT:    [[TMP0:%.*]] = call i64 @llvm.read_volatile_register.i64(metadata !8)
1563 // AArch64-NEXT:    ret i64 [[TMP0]]
1564 //
1565 uint64_t test_rsr64() {
1566 #ifdef __ARM_32BIT_STATE
1567   return __arm_rsr64("cp1:2:c3");
1568 #else
1569   return __arm_rsr64("1:2:3:4:5");
1570 #endif
1571 }
1572 
1573 // AArch32-LABEL: @test_rsrp(
1574 // AArch32-NEXT:  entry:
1575 // AArch32-NEXT:    [[TMP0:%.*]] = call i32 @llvm.read_volatile_register.i32(metadata !7)
1576 // AArch32-NEXT:    [[TMP1:%.*]] = inttoptr i32 [[TMP0]] to i8*
1577 // AArch32-NEXT:    ret i8* [[TMP1]]
1578 //
1579 // AArch64-LABEL: @test_rsrp(
1580 // AArch64-NEXT:  entry:
1581 // AArch64-NEXT:    [[TMP0:%.*]] = call i64 @llvm.read_volatile_register.i64(metadata !9)
1582 // AArch64-NEXT:    [[TMP1:%.*]] = inttoptr i64 [[TMP0]] to i8*
1583 // AArch64-NEXT:    ret i8* [[TMP1]]
1584 //
1585 void *test_rsrp() {
1586   return __arm_rsrp("sysreg");
1587 }
1588 
1589 // AArch32-LABEL: @test_wsr(
1590 // AArch32-NEXT:  entry:
1591 // AArch32-NEXT:    call void @llvm.write_register.i32(metadata !5, i32 [[V:%.*]])
1592 // AArch32-NEXT:    ret void
1593 //
1594 // AArch64-LABEL: @test_wsr(
1595 // AArch64-NEXT:  entry:
1596 // AArch64-NEXT:    [[TMP0:%.*]] = zext i32 [[V:%.*]] to i64
1597 // AArch64-NEXT:    call void @llvm.write_register.i64(metadata !8, i64 [[TMP0]])
1598 // AArch64-NEXT:    ret void
1599 //
1600 void test_wsr(uint32_t v) {
1601 #ifdef __ARM_32BIT_STATE
1602   __arm_wsr("cp1:2:c3:c4:5", v);
1603 #else
1604   __arm_wsr("1:2:3:4:5", v);
1605 #endif
1606 }
1607 
1608 // AArch32-LABEL: @test_wsr64(
1609 // AArch32-NEXT:  entry:
1610 // AArch32-NEXT:    call void @llvm.write_register.i64(metadata !6, i64 [[V:%.*]])
1611 // AArch32-NEXT:    ret void
1612 //
1613 // AArch64-LABEL: @test_wsr64(
1614 // AArch64-NEXT:  entry:
1615 // AArch64-NEXT:    call void @llvm.write_register.i64(metadata !8, i64 [[V:%.*]])
1616 // AArch64-NEXT:    ret void
1617 //
1618 void test_wsr64(uint64_t v) {
1619 #ifdef __ARM_32BIT_STATE
1620   __arm_wsr64("cp1:2:c3", v);
1621 #else
1622   __arm_wsr64("1:2:3:4:5", v);
1623 #endif
1624 }
1625 
1626 // AArch32-LABEL: @test_wsrp(
1627 // AArch32-NEXT:  entry:
1628 // AArch32-NEXT:    [[TMP0:%.*]] = ptrtoint i8* [[V:%.*]] to i32
1629 // AArch32-NEXT:    call void @llvm.write_register.i32(metadata !7, i32 [[TMP0]])
1630 // AArch32-NEXT:    ret void
1631 //
1632 // AArch64-LABEL: @test_wsrp(
1633 // AArch64-NEXT:  entry:
1634 // AArch64-NEXT:    [[TMP0:%.*]] = ptrtoint i8* [[V:%.*]] to i64
1635 // AArch64-NEXT:    call void @llvm.write_register.i64(metadata !9, i64 [[TMP0]])
1636 // AArch64-NEXT:    ret void
1637 //
1638 void test_wsrp(void *v) {
1639   __arm_wsrp("sysreg", v);
1640 }
1641 
1642 // AArch32-LABEL: @test_rsrf(
1643 // AArch32-NEXT:  entry:
1644 // AArch32-NEXT:    [[REF_TMP:%.*]] = alloca i32, align 4
1645 // AArch32-NEXT:    [[TMP0:%.*]] = call i32 @llvm.read_volatile_register.i32(metadata !5)
1646 // AArch32-NEXT:    store i32 [[TMP0]], i32* [[REF_TMP]], align 4
1647 // AArch32-NEXT:    [[TMP1:%.*]] = bitcast i32* [[REF_TMP]] to float*
1648 // AArch32-NEXT:    [[TMP2:%.*]] = load float, float* [[TMP1]], align 4
1649 // AArch32-NEXT:    ret float [[TMP2]]
1650 //
1651 // AArch64-LABEL: @test_rsrf(
1652 // AArch64-NEXT:  entry:
1653 // AArch64-NEXT:    [[REF_TMP:%.*]] = alloca i32, align 4
1654 // AArch64-NEXT:    [[TMP0:%.*]] = call i64 @llvm.read_volatile_register.i64(metadata !8)
1655 // AArch64-NEXT:    [[TMP1:%.*]] = trunc i64 [[TMP0]] to i32
1656 // AArch64-NEXT:    store i32 [[TMP1]], i32* [[REF_TMP]], align 4
1657 // AArch64-NEXT:    [[TMP2:%.*]] = bitcast i32* [[REF_TMP]] to float*
1658 // AArch64-NEXT:    [[TMP3:%.*]] = load float, float* [[TMP2]], align 4
1659 // AArch64-NEXT:    ret float [[TMP3]]
1660 //
1661 float test_rsrf() {
1662 #ifdef __ARM_32BIT_STATE
1663   return __arm_rsrf("cp1:2:c3:c4:5");
1664 #else
1665   return __arm_rsrf("1:2:3:4:5");
1666 #endif
1667 }
1668 
1669 // AArch32-LABEL: @test_rsrf64(
1670 // AArch32-NEXT:  entry:
1671 // AArch32-NEXT:    [[REF_TMP:%.*]] = alloca i64, align 8
1672 // AArch32-NEXT:    [[TMP0:%.*]] = call i64 @llvm.read_volatile_register.i64(metadata !6)
1673 // AArch32-NEXT:    store i64 [[TMP0]], i64* [[REF_TMP]], align 8
1674 // AArch32-NEXT:    [[TMP1:%.*]] = bitcast i64* [[REF_TMP]] to double*
1675 // AArch32-NEXT:    [[TMP2:%.*]] = load double, double* [[TMP1]], align 8
1676 // AArch32-NEXT:    ret double [[TMP2]]
1677 //
1678 // AArch64-LABEL: @test_rsrf64(
1679 // AArch64-NEXT:  entry:
1680 // AArch64-NEXT:    [[REF_TMP:%.*]] = alloca i64, align 8
1681 // AArch64-NEXT:    [[TMP0:%.*]] = call i64 @llvm.read_volatile_register.i64(metadata !8)
1682 // AArch64-NEXT:    store i64 [[TMP0]], i64* [[REF_TMP]], align 8
1683 // AArch64-NEXT:    [[TMP1:%.*]] = bitcast i64* [[REF_TMP]] to double*
1684 // AArch64-NEXT:    [[TMP2:%.*]] = load double, double* [[TMP1]], align 8
1685 // AArch64-NEXT:    ret double [[TMP2]]
1686 //
1687 double test_rsrf64() {
1688 #ifdef __ARM_32BIT_STATE
1689   return __arm_rsrf64("cp1:2:c3");
1690 #else
1691   return __arm_rsrf64("1:2:3:4:5");
1692 #endif
1693 }
1694 
1695 // AArch32-LABEL: @test_wsrf(
1696 // AArch32-NEXT:  entry:
1697 // AArch32-NEXT:    [[V_ADDR:%.*]] = alloca float, align 4
1698 // AArch32-NEXT:    store float [[V:%.*]], float* [[V_ADDR]], align 4
1699 // AArch32-NEXT:    [[TMP0:%.*]] = bitcast float* [[V_ADDR]] to i32*
1700 // AArch32-NEXT:    [[TMP1:%.*]] = load i32, i32* [[TMP0]], align 4
1701 // AArch32-NEXT:    call void @llvm.write_register.i32(metadata !5, i32 [[TMP1]])
1702 // AArch32-NEXT:    ret void
1703 //
1704 // AArch64-LABEL: @test_wsrf(
1705 // AArch64-NEXT:  entry:
1706 // AArch64-NEXT:    [[V_ADDR:%.*]] = alloca float, align 4
1707 // AArch64-NEXT:    store float [[V:%.*]], float* [[V_ADDR]], align 4
1708 // AArch64-NEXT:    [[TMP0:%.*]] = bitcast float* [[V_ADDR]] to i32*
1709 // AArch64-NEXT:    [[TMP1:%.*]] = load i32, i32* [[TMP0]], align 4
1710 // AArch64-NEXT:    [[TMP2:%.*]] = zext i32 [[TMP1]] to i64
1711 // AArch64-NEXT:    call void @llvm.write_register.i64(metadata !8, i64 [[TMP2]])
1712 // AArch64-NEXT:    ret void
1713 //
1714 void test_wsrf(float v) {
1715 #ifdef __ARM_32BIT_STATE
1716   __arm_wsrf("cp1:2:c3:c4:5", v);
1717 #else
1718   __arm_wsrf("1:2:3:4:5", v);
1719 #endif
1720 }
1721 
1722 // AArch32-LABEL: @test_wsrf64(
1723 // AArch32-NEXT:  entry:
1724 // AArch32-NEXT:    [[V_ADDR:%.*]] = alloca double, align 8
1725 // AArch32-NEXT:    store double [[V:%.*]], double* [[V_ADDR]], align 8
1726 // AArch32-NEXT:    [[TMP0:%.*]] = bitcast double* [[V_ADDR]] to i64*
1727 // AArch32-NEXT:    [[TMP1:%.*]] = load i64, i64* [[TMP0]], align 8
1728 // AArch32-NEXT:    call void @llvm.write_register.i64(metadata !6, i64 [[TMP1]])
1729 // AArch32-NEXT:    ret void
1730 //
1731 // AArch64-LABEL: @test_wsrf64(
1732 // AArch64-NEXT:  entry:
1733 // AArch64-NEXT:    [[V_ADDR:%.*]] = alloca double, align 8
1734 // AArch64-NEXT:    store double [[V:%.*]], double* [[V_ADDR]], align 8
1735 // AArch64-NEXT:    [[TMP0:%.*]] = bitcast double* [[V_ADDR]] to i64*
1736 // AArch64-NEXT:    [[TMP1:%.*]] = load i64, i64* [[TMP0]], align 8
1737 // AArch64-NEXT:    call void @llvm.write_register.i64(metadata !8, i64 [[TMP1]])
1738 // AArch64-NEXT:    ret void
1739 //
1740 void test_wsrf64(double v) {
1741 #ifdef __ARM_32BIT_STATE
1742   __arm_wsrf64("cp1:2:c3", v);
1743 #else
1744   __arm_wsrf64("1:2:3:4:5", v);
1745 #endif
1746 }
1747 
1748 #ifdef __ARM_64BIT_STATE
1749 // AArch6483-LABEL: @test_jcvt(
1750 // AArch6483-NEXT:  entry:
1751 // AArch6483-NEXT:    [[TMP0:%.*]] = call i32 @llvm.aarch64.fjcvtzs(double [[V:%.*]]) [[ATTR3:#.*]]
1752 // AArch6483-NEXT:    ret i32 [[TMP0]]
1753 //
1754 int32_t test_jcvt(double v) {
1755   return __jcvt(v);
1756 }
1757 #endif
1758 
1759 
1760 #if __ARM_64BIT_STATE && defined(__ARM_FEATURE_RNG)
1761 
1762 // AArch6485-LABEL: @test_rndr(
1763 // AArch6485-NEXT:  entry:
1764 // AArch6485-NEXT:    [[TMP0:%.*]] = call { i64, i1 } @llvm.aarch64.rndr() [[ATTR3:#.*]]
1765 // AArch6485-NEXT:    [[TMP1:%.*]] = extractvalue { i64, i1 } [[TMP0]], 0
1766 // AArch6485-NEXT:    [[TMP2:%.*]] = extractvalue { i64, i1 } [[TMP0]], 1
1767 // AArch6485-NEXT:    store i64 [[TMP1]], i64* [[__ADDR:%.*]], align 8
1768 // AArch6485-NEXT:    [[TMP3:%.*]] = zext i1 [[TMP2]] to i32
1769 // AArch6485-NEXT:    ret i32 [[TMP3]]
1770 //
1771 int test_rndr(uint64_t *__addr) {
1772   return __rndr(__addr);
1773 }
1774 
1775 // AArch6485-LABEL: @test_rndrrs(
1776 // AArch6485-NEXT:  entry:
1777 // AArch6485-NEXT:    [[TMP0:%.*]] = call { i64, i1 } @llvm.aarch64.rndrrs() [[ATTR3:#.*]]
1778 // AArch6485-NEXT:    [[TMP1:%.*]] = extractvalue { i64, i1 } [[TMP0]], 0
1779 // AArch6485-NEXT:    [[TMP2:%.*]] = extractvalue { i64, i1 } [[TMP0]], 1
1780 // AArch6485-NEXT:    store i64 [[TMP1]], i64* [[__ADDR:%.*]], align 8
1781 // AArch6485-NEXT:    [[TMP3:%.*]] = zext i1 [[TMP2]] to i32
1782 // AArch6485-NEXT:    ret i32 [[TMP3]]
1783 //
1784 int test_rndrrs(uint64_t *__addr) {
1785   return __rndrrs(__addr);
1786 }
1787 #endif
1788 
1789 // AArch32: !5 = !{!"cp1:2:c3:c4:5"}
1790 // AArch32: !6 = !{!"cp1:2:c3"}
1791 // AArch32: !7 = !{!"sysreg"}
1792 
1793 // AArch64: !8 = !{!"1:2:3:4:5"}
1794 // AArch64: !9 = !{!"sysreg"}
1795