Revert r354244 "[DAGCombiner] Eliminate dead stores to stack."
[llvm-complete.git] / test / CodeGen / AArch64 / GlobalISel / arm64-irtranslator.ll
blob81505b8839096a6b9765704a2fa1f0a4fa8c1e02
1 ; RUN: llc -O0 -aarch64-enable-atomic-cfg-tidy=0 -stop-after=irtranslator -global-isel -verify-machineinstrs %s -o - 2>&1 | FileCheck %s
2 ; RUN: llc -O3 -aarch64-enable-atomic-cfg-tidy=0 -stop-after=irtranslator -global-isel -verify-machineinstrs %s -o - 2>&1 | FileCheck %s --check-prefix=O3
4 ; This file checks that the translation from llvm IR to generic MachineInstr
5 ; is correct.
6 target datalayout = "e-m:o-i64:64-i128:128-n32:64-S128"
7 target triple = "aarch64--"
9 ; Tests for add.
10 ; CHECK-LABEL: name: addi64
11 ; CHECK:      [[ARG1:%[0-9]+]]:_(s64) = COPY $x0
12 ; CHECK-NEXT: [[ARG2:%[0-9]+]]:_(s64) = COPY $x1
13 ; CHECK-NEXT: [[RES:%[0-9]+]]:_(s64) = G_ADD [[ARG1]], [[ARG2]]
14 ; CHECK-NEXT: $x0 = COPY [[RES]]
15 ; CHECK-NEXT: RET_ReallyLR implicit $x0
16 define i64 @addi64(i64 %arg1, i64 %arg2) {
17   %res = add i64 %arg1, %arg2
18   ret i64 %res
21 ; CHECK-LABEL: name: muli64
22 ; CHECK: [[ARG1:%[0-9]+]]:_(s64) = COPY $x0
23 ; CHECK-NEXT: [[ARG2:%[0-9]+]]:_(s64) = COPY $x1
24 ; CHECK-NEXT: [[RES:%[0-9]+]]:_(s64) = G_MUL [[ARG1]], [[ARG2]]
25 ; CHECK-NEXT: $x0 = COPY [[RES]]
26 ; CHECK-NEXT: RET_ReallyLR implicit $x0
27 define i64 @muli64(i64 %arg1, i64 %arg2) {
28   %res = mul i64 %arg1, %arg2
29   ret i64 %res
32 ; Tests for alloca
33 ; CHECK-LABEL: name: allocai64
34 ; CHECK: stack:
35 ; CHECK-NEXT:   - { id: 0, name: ptr1, type: default, offset: 0, size: 8, alignment: 8,
36 ; CHECK-NEXT:       stack-id: 0, callee-saved-register: '', callee-saved-restored: true,
37 ; CHECK-NEXT: debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
38 ; CHECK-NEXT:   - { id: 1, name: ptr2, type: default, offset: 0, size: 8, alignment: 1,
39 ; CHECK-NEXT:       stack-id: 0, callee-saved-register: '', callee-saved-restored: true,
40 ; CHECK-NEXT:       debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
41 ; CHECK-NEXT:   - { id: 2, name: ptr3, type: default, offset: 0, size: 128, alignment: 8,
42 ; CHECK-NEXT:       stack-id: 0, callee-saved-register: '', callee-saved-restored: true,
43 ; CHECK-NEXT:       debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
44 ; CHECK-NEXT:   - { id: 3, name: ptr4, type: default, offset: 0, size: 1, alignment: 8,
45 ; CHECK: %{{[0-9]+}}:_(p0) = G_FRAME_INDEX %stack.0.ptr1
46 ; CHECK: %{{[0-9]+}}:_(p0) = G_FRAME_INDEX %stack.1.ptr2
47 ; CHECK: %{{[0-9]+}}:_(p0) = G_FRAME_INDEX %stack.2.ptr3
48 ; CHECK: %{{[0-9]+}}:_(p0) = G_FRAME_INDEX %stack.3.ptr4
49 define void @allocai64() {
50   %ptr1 = alloca i64
51   %ptr2 = alloca i64, align 1
52   %ptr3 = alloca i64, i32 16
53   %ptr4 = alloca [0 x i64]
54   ret void
57 ; Tests for br.
58 ; CHECK-LABEL: name: uncondbr
59 ; CHECK: body:
61 ; ABI/constant lowering and IR-level entry basic block.
62 ; CHECK: bb.{{[0-9]+}}.{{[a-zA-Z0-9.]+}}:
64 ; Make sure we have one successor and only one.
65 ; CHECK-NEXT: successors: %[[BB2:bb.[0-9]+]](0x80000000)
67 ; Check that we emit the correct branch.
68 ; CHECK: G_BR %[[BB2]]
70 ; Check that end contains the return instruction.
71 ; CHECK: [[END:bb.[0-9]+]].{{[a-zA-Z0-9.]+}}:
72 ; CHECK-NEXT: RET_ReallyLR
74 ; CHECK: bb.{{[0-9]+}}.{{[a-zA-Z0-9.]+}}:
75 ; CHECK-NEXT: successors: %[[END]](0x80000000)
76 ; CHECK: G_BR %[[END]]
77 define void @uncondbr() {
78 entry:
79   br label %bb2
80 end:
81   ret void
82 bb2:
83   br label %end
86 ; CHECK-LABEL: name: uncondbr_fallthrough
87 ; CHECK: body:
88 ; CHECK: bb.{{[0-9]+}}.{{[a-zA-Z0-9.]+}}:
89 ; CHECK-NEXT: successors: %[[END:bb.[0-9]+]](0x80000000)
90 ; We don't emit a branch here, as we can fallthrough to the successor.
91 ; CHECK-NOT: G_BR
92 ; CHECK: [[END]].{{[a-zA-Z0-9.]+}}:
93 ; CHECK-NEXT: RET_ReallyLR
94 define void @uncondbr_fallthrough() {
95 entry:
96   br label %end
97 end:
98   ret void
101 ; Tests for conditional br.
102 ; CHECK-LABEL: name: condbr
103 ; CHECK: body:
105 ; ABI/constant lowering and IR-level entry basic block.
106 ; CHECK: bb.{{[0-9]+}} (%ir-block.{{[0-9]+}}):
107 ; Make sure we have two successors
108 ; CHECK-NEXT: successors: %[[TRUE:bb.[0-9]+]](0x40000000),
109 ; CHECK:                  %[[FALSE:bb.[0-9]+]](0x40000000)
111 ; CHECK: [[ADDR:%.*]]:_(p0) = COPY $x0
113 ; Check that we emit the correct branch.
114 ; CHECK: [[TST:%.*]]:_(s1) = G_LOAD [[ADDR]](p0)
115 ; CHECK: G_BRCOND [[TST]](s1), %[[TRUE]]
116 ; CHECK: G_BR %[[FALSE]]
118 ; Check that each successor contains the return instruction.
119 ; CHECK: [[TRUE]].{{[a-zA-Z0-9.]+}}:
120 ; CHECK-NEXT: RET_ReallyLR
121 ; CHECK: [[FALSE]].{{[a-zA-Z0-9.]+}}:
122 ; CHECK-NEXT: RET_ReallyLR
123 define void @condbr(i1* %tstaddr) {
124   %tst = load i1, i1* %tstaddr
125   br i1 %tst, label %true, label %false
126 true:
127   ret void
128 false:
129   ret void
132 ; Tests for switch.
133 ; This gets lowered to a very straightforward sequence of comparisons for now.
134 ; CHECK-LABEL: name: switch
135 ; CHECK: body:
137 ; CHECK: bb.{{[a-zA-Z0-9.]+}}:
138 ; CHECK-NEXT: successors: %[[BB_CASE100:bb.[0-9]+]](0x40000000), %[[BB_NOTCASE100_CHECKNEXT:bb.[0-9]+]](0x40000000)
139 ; CHECK: %0:_(s32) = COPY $w0
140 ; CHECK: %[[reg100:[0-9]+]]:_(s32) = G_CONSTANT i32 100
141 ; CHECK: %[[reg200:[0-9]+]]:_(s32) = G_CONSTANT i32 200
142 ; CHECK: %[[reg2:[0-9]+]]:_(s32) = G_CONSTANT i32 2
143 ; CHECK: %[[reg1:[0-9]+]]:_(s32) = G_CONSTANT i32 1
144 ; CHECK: %[[reg0:[0-9]+]]:_(s32) = G_CONSTANT i32 0
145 ; CHECK: %[[regicmp100:[0-9]+]]:_(s1) = G_ICMP intpred(eq), %[[reg100]](s32), %0
146 ; CHECK: G_BRCOND %[[regicmp100]](s1), %[[BB_CASE100]]
147 ; CHECK: G_BR %[[BB_NOTCASE100_CHECKNEXT]]
149 ; CHECK: [[BB_NOTCASE100_CHECKNEXT]].{{[a-zA-Z0-9.]+}}:
150 ; CHECK-NEXT: successors: %[[BB_CASE200:bb.[0-9]+]](0x40000000), %[[BB_NOTCASE200_CHECKNEXT:bb.[0-9]+]](0x40000000)
151 ; CHECK: %[[regicmp200:[0-9]+]]:_(s1) = G_ICMP intpred(eq), %[[reg200]](s32), %0
152 ; CHECK: G_BRCOND %[[regicmp200]](s1), %[[BB_CASE200]]
153 ; CHECK: G_BR %[[BB_NOTCASE200_CHECKNEXT]]
155 ; CHECK: [[BB_NOTCASE200_CHECKNEXT]].{{[a-zA-Z0-9.]+}}:
156 ; CHECK-NEXT: successors: %[[BB_DEFAULT:bb.[0-9]+]](0x80000000)
157 ; CHECK: G_BR %[[BB_DEFAULT]]
159 ; CHECK: [[BB_DEFAULT]].{{[a-zA-Z0-9.]+}}:
160 ; CHECK-NEXT: successors: %[[BB_RET:bb.[0-9]+]](0x80000000)
161 ; CHECK: %[[regretdefault:[0-9]+]]:_(s32) = G_ADD %0, %[[reg0]]
162 ; CHECK: G_BR %[[BB_RET]]
164 ; CHECK: [[BB_CASE100]].{{[a-zA-Z0-9.]+}}:
165 ; CHECK-NEXT: successors: %[[BB_RET:bb.[0-9]+]](0x80000000)
166 ; CHECK: %[[regretc100:[0-9]+]]:_(s32) = G_ADD %0, %[[reg1]]
167 ; CHECK: G_BR %[[BB_RET]]
169 ; CHECK: [[BB_CASE200]].{{[a-zA-Z0-9.]+}}:
170 ; CHECK-NEXT: successors: %[[BB_RET]](0x80000000)
171 ; CHECK: %[[regretc200:[0-9]+]]:_(s32) = G_ADD %0, %[[reg2]]
173 ; CHECK: [[BB_RET]].{{[a-zA-Z0-9.]+}}:
174 ; CHECK-NEXT: %[[regret:[0-9]+]]:_(s32) = G_PHI %[[regretdefault]](s32), %[[BB_DEFAULT]], %[[regretc100]](s32), %[[BB_CASE100]]
175 ; CHECK:  $w0 = COPY %[[regret]](s32)
176 ; CHECK:  RET_ReallyLR implicit $w0
178 define i32 @switch(i32 %argc) {
179 entry:
180   switch i32 %argc, label %default [
181     i32 100, label %case100
182     i32 200, label %case200
183   ]
185 default:
186   %tmp0 = add i32 %argc, 0
187   br label %return
189 case100:
190   %tmp1 = add i32 %argc, 1
191   br label %return
193 case200:
194   %tmp2 = add i32 %argc, 2
195   br label %return
197 return:
198   %res = phi i32 [ %tmp0, %default ], [ %tmp1, %case100 ], [ %tmp2, %case200 ]
199   ret i32 %res
202   ; The switch lowering code changes the CFG, which means that the original
203   ; %entry block is no longer a predecessor for the phi instruction. We need to
204   ; use the correct lowered MachineBasicBlock instead.
205 ; CHECK-LABEL: name: test_cfg_remap
206 ; CHECK: bb.{{[0-9]+.[a-zA-Z0-9.]+}}:
207 ; CHECK-NEXT: successors: %{{bb.[0-9]+}}(0x40000000), %[[NOTCASE1_BLOCK:bb.[0-9]+]](0x40000000)
208 ; CHECK: [[NOTCASE1_BLOCK]].{{[a-zA-Z0-9.]+}}:
209 ; CHECK-NEXT: successors: %{{bb.[0-9]+}}(0x40000000), %[[NOTCASE57_BLOCK:bb.[0-9]+]](0x40000000)
210 ; CHECK: [[NOTCASE57_BLOCK]].{{[a-zA-Z0-9.]+}}:
211 ; CHECK-NEXT: successors: %[[PHI_BLOCK:bb.[0-9]+]](0x80000000)
212 ; CHECK: G_BR %[[PHI_BLOCK]]
214 ; CHECK: [[PHI_BLOCK]].{{[a-zA-Z0-9.]+}}:
215 ; CHECK-NEXT: G_PHI %{{.*}}(s32), %[[NOTCASE57_BLOCK:bb.[0-9]+]], %{{.*}}(s32),
217 define i32 @test_cfg_remap(i32 %in) {
218 entry:
219   switch i32 %in, label %phi.block [i32 1, label %next
220                                     i32 57, label %other]
222 next:
223   br label %phi.block
225 other:
226   ret i32 undef
228 phi.block:
229   %res = phi i32 [1, %entry], [42, %next]
230   ret i32 %res
233 ; CHECK-LABEL: name: test_cfg_remap_multiple_preds
234 ; CHECK: G_PHI [[ENTRY:%.*]](s32), %bb.{{[0-9]+}}, [[ENTRY]](s32), %bb.{{[0-9]+}}
235 define i32 @test_cfg_remap_multiple_preds(i32 %in) {
236 entry:
237   switch i32 %in, label %odd [i32 1, label %next
238                               i32 57, label %other
239                               i32 128, label %phi.block
240                               i32 256, label %phi.block]
241 odd:
242   unreachable
244 next:
245   br label %phi.block
247 other:
248   ret i32 undef
250 phi.block:
251   %res = phi i32 [1, %entry], [1, %entry], [42, %next]
252   ret i32 12
255 ; Tests for indirect br.
256 ; CHECK-LABEL: name: indirectbr
257 ; CHECK: body:
259 ; ABI/constant lowering and IR-level entry basic block.
260 ; CHECK: bb.{{[0-9]+.[a-zA-Z0-9.]+}}:
261 ; Make sure we have one successor
262 ; CHECK-NEXT: successors: %[[BB_L1:bb.[0-9]+]](0x80000000)
263 ; CHECK-NOT: G_BR
265 ; Check basic block L1 has 2 successors: BBL1 and BBL2
266 ; CHECK: [[BB_L1]].{{[a-zA-Z0-9.]+}} (address-taken):
267 ; CHECK-NEXT: successors: %[[BB_L1]](0x40000000),
268 ; CHECK:                  %[[BB_L2:bb.[0-9]+]](0x40000000)
269 ; CHECK: G_BRINDIRECT %{{[0-9]+}}(p0)
271 ; Check basic block L2 is the return basic block
272 ; CHECK: [[BB_L2]].{{[a-zA-Z0-9.]+}} (address-taken):
273 ; CHECK-NEXT: RET_ReallyLR
275 @indirectbr.L = internal unnamed_addr constant [3 x i8*] [i8* blockaddress(@indirectbr, %L1), i8* blockaddress(@indirectbr, %L2), i8* null], align 8
277 define void @indirectbr() {
278 entry:
279   br label %L1
280 L1:                                               ; preds = %entry, %L1
281   %i = phi i32 [ 0, %entry ], [ %inc, %L1 ]
282   %inc = add i32 %i, 1
283   %idxprom = zext i32 %i to i64
284   %arrayidx = getelementptr inbounds [3 x i8*], [3 x i8*]* @indirectbr.L, i64 0, i64 %idxprom
285   %brtarget = load i8*, i8** %arrayidx, align 8
286   indirectbr i8* %brtarget, [label %L1, label %L2]
287 L2:                                               ; preds = %L1
288   ret void
291 ; Tests for or.
292 ; CHECK-LABEL: name: ori64
293 ; CHECK: [[ARG1:%[0-9]+]]:_(s64) = COPY $x0
294 ; CHECK-NEXT: [[ARG2:%[0-9]+]]:_(s64) = COPY $x1
295 ; CHECK-NEXT: [[RES:%[0-9]+]]:_(s64) = G_OR [[ARG1]], [[ARG2]]
296 ; CHECK-NEXT: $x0 = COPY [[RES]]
297 ; CHECK-NEXT: RET_ReallyLR implicit $x0
298 define i64 @ori64(i64 %arg1, i64 %arg2) {
299   %res = or i64 %arg1, %arg2
300   ret i64 %res
303 ; CHECK-LABEL: name: ori32
304 ; CHECK: [[ARG1:%[0-9]+]]:_(s32) = COPY $w0
305 ; CHECK-NEXT: [[ARG2:%[0-9]+]]:_(s32) = COPY $w1
306 ; CHECK-NEXT: [[RES:%[0-9]+]]:_(s32) = G_OR [[ARG1]], [[ARG2]]
307 ; CHECK-NEXT: $w0 = COPY [[RES]]
308 ; CHECK-NEXT: RET_ReallyLR implicit $w0
309 define i32 @ori32(i32 %arg1, i32 %arg2) {
310   %res = or i32 %arg1, %arg2
311   ret i32 %res
314 ; Tests for xor.
315 ; CHECK-LABEL: name: xori64
316 ; CHECK: [[ARG1:%[0-9]+]]:_(s64) = COPY $x0
317 ; CHECK-NEXT: [[ARG2:%[0-9]+]]:_(s64) = COPY $x1
318 ; CHECK-NEXT: [[RES:%[0-9]+]]:_(s64) = G_XOR [[ARG1]], [[ARG2]]
319 ; CHECK-NEXT: $x0 = COPY [[RES]]
320 ; CHECK-NEXT: RET_ReallyLR implicit $x0
321 define i64 @xori64(i64 %arg1, i64 %arg2) {
322   %res = xor i64 %arg1, %arg2
323   ret i64 %res
326 ; CHECK-LABEL: name: xori32
327 ; CHECK: [[ARG1:%[0-9]+]]:_(s32) = COPY $w0
328 ; CHECK-NEXT: [[ARG2:%[0-9]+]]:_(s32) = COPY $w1
329 ; CHECK-NEXT: [[RES:%[0-9]+]]:_(s32) = G_XOR [[ARG1]], [[ARG2]]
330 ; CHECK-NEXT: $w0 = COPY [[RES]]
331 ; CHECK-NEXT: RET_ReallyLR implicit $w0
332 define i32 @xori32(i32 %arg1, i32 %arg2) {
333   %res = xor i32 %arg1, %arg2
334   ret i32 %res
337 ; Tests for and.
338 ; CHECK-LABEL: name: andi64
339 ; CHECK: [[ARG1:%[0-9]+]]:_(s64) = COPY $x0
340 ; CHECK-NEXT: [[ARG2:%[0-9]+]]:_(s64) = COPY $x1
341 ; CHECK-NEXT: [[RES:%[0-9]+]]:_(s64) = G_AND [[ARG1]], [[ARG2]]
342 ; CHECK-NEXT: $x0 = COPY [[RES]]
343 ; CHECK-NEXT: RET_ReallyLR implicit $x0
344 define i64 @andi64(i64 %arg1, i64 %arg2) {
345   %res = and i64 %arg1, %arg2
346   ret i64 %res
349 ; CHECK-LABEL: name: andi32
350 ; CHECK: [[ARG1:%[0-9]+]]:_(s32) = COPY $w0
351 ; CHECK-NEXT: [[ARG2:%[0-9]+]]:_(s32) = COPY $w1
352 ; CHECK-NEXT: [[RES:%[0-9]+]]:_(s32) = G_AND [[ARG1]], [[ARG2]]
353 ; CHECK-NEXT: $w0 = COPY [[RES]]
354 ; CHECK-NEXT: RET_ReallyLR implicit $w0
355 define i32 @andi32(i32 %arg1, i32 %arg2) {
356   %res = and i32 %arg1, %arg2
357   ret i32 %res
360 ; Tests for sub.
361 ; CHECK-LABEL: name: subi64
362 ; CHECK: [[ARG1:%[0-9]+]]:_(s64) = COPY $x0
363 ; CHECK-NEXT: [[ARG2:%[0-9]+]]:_(s64) = COPY $x1
364 ; CHECK-NEXT: [[RES:%[0-9]+]]:_(s64) = G_SUB [[ARG1]], [[ARG2]]
365 ; CHECK-NEXT: $x0 = COPY [[RES]]
366 ; CHECK-NEXT: RET_ReallyLR implicit $x0
367 define i64 @subi64(i64 %arg1, i64 %arg2) {
368   %res = sub i64 %arg1, %arg2
369   ret i64 %res
372 ; CHECK-LABEL: name: subi32
373 ; CHECK: [[ARG1:%[0-9]+]]:_(s32) = COPY $w0
374 ; CHECK-NEXT: [[ARG2:%[0-9]+]]:_(s32) = COPY $w1
375 ; CHECK-NEXT: [[RES:%[0-9]+]]:_(s32) = G_SUB [[ARG1]], [[ARG2]]
376 ; CHECK-NEXT: $w0 = COPY [[RES]]
377 ; CHECK-NEXT: RET_ReallyLR implicit $w0
378 define i32 @subi32(i32 %arg1, i32 %arg2) {
379   %res = sub i32 %arg1, %arg2
380   ret i32 %res
383 ; CHECK-LABEL: name: ptrtoint
384 ; CHECK: [[ARG1:%[0-9]+]]:_(p0) = COPY $x0
385 ; CHECK: [[RES:%[0-9]+]]:_(s64) = G_PTRTOINT [[ARG1]]
386 ; CHECK: $x0 = COPY [[RES]]
387 ; CHECK: RET_ReallyLR implicit $x0
388 define i64 @ptrtoint(i64* %a) {
389   %val = ptrtoint i64* %a to i64
390   ret i64 %val
393 ; CHECK-LABEL: name: inttoptr
394 ; CHECK: [[ARG1:%[0-9]+]]:_(s64) = COPY $x0
395 ; CHECK: [[RES:%[0-9]+]]:_(p0) = G_INTTOPTR [[ARG1]]
396 ; CHECK: $x0 = COPY [[RES]]
397 ; CHECK: RET_ReallyLR implicit $x0
398 define i64* @inttoptr(i64 %a) {
399   %val = inttoptr i64 %a to i64*
400   ret i64* %val
403 ; CHECK-LABEL: name: trivial_bitcast
404 ; CHECK: [[ARG1:%[0-9]+]]:_(p0) = COPY $x0
405 ; CHECK: $x0 = COPY [[ARG1]]
406 ; CHECK: RET_ReallyLR implicit $x0
407 define i64* @trivial_bitcast(i8* %a) {
408   %val = bitcast i8* %a to i64*
409   ret i64* %val
412 ; CHECK-LABEL: name: trivial_bitcast_with_copy
413 ; CHECK:     [[A:%[0-9]+]]:_(p0) = COPY $x0
414 ; CHECK:     G_BR %[[CAST:bb\.[0-9]+]]
416 ; CHECK: [[END:bb\.[0-9]+]].{{[a-zA-Z0-9.]+}}:
417 ; CHECK:     $x0 = COPY [[A]]
419 ; CHECK: [[CAST]].{{[a-zA-Z0-9.]+}}:
420 ; CHECK:     G_BR %[[END]]
421 define i64* @trivial_bitcast_with_copy(i8* %a) {
422   br label %cast
424 end:
425   ret i64* %val
427 cast:
428   %val = bitcast i8* %a to i64*
429   br label %end
432 ; CHECK-LABEL: name: bitcast
433 ; CHECK: [[ARG1:%[0-9]+]]:_(s64) = COPY $x0
434 ; CHECK: [[RES1:%[0-9]+]]:_(<2 x s32>) = G_BITCAST [[ARG1]]
435 ; CHECK: [[RES2:%[0-9]+]]:_(s64) = G_BITCAST [[RES1]]
436 ; CHECK: $x0 = COPY [[RES2]]
437 ; CHECK: RET_ReallyLR implicit $x0
438 define i64 @bitcast(i64 %a) {
439   %res1 = bitcast i64 %a to <2 x i32>
440   %res2 = bitcast <2 x i32> %res1 to i64
441   ret i64 %res2
444 ; CHECK-LABEL: name: addrspacecast
445 ; CHECK: [[ARG1:%[0-9]+]]:_(p1) = COPY $x0
446 ; CHECK: [[RES1:%[0-9]+]]:_(p2) = G_ADDRSPACE_CAST [[ARG1]]
447 ; CHECK: [[RES2:%[0-9]+]]:_(p0) = G_ADDRSPACE_CAST [[RES1]]
448 ; CHECK: $x0 = COPY [[RES2]]
449 ; CHECK: RET_ReallyLR implicit $x0
450 define i64* @addrspacecast(i32 addrspace(1)* %a) {
451   %res1 = addrspacecast i32 addrspace(1)* %a to i64 addrspace(2)*
452   %res2 = addrspacecast i64 addrspace(2)* %res1 to i64*
453   ret i64* %res2
456 ; CHECK-LABEL: name: trunc
457 ; CHECK: [[ARG1:%[0-9]+]]:_(s64) = COPY $x0
458 ; CHECK: [[VEC:%[0-9]+]]:_(<4 x s32>) = G_LOAD
459 ; CHECK: [[RES1:%[0-9]+]]:_(s8) = G_TRUNC [[ARG1]]
460 ; CHECK: [[RES2:%[0-9]+]]:_(<4 x s16>) = G_TRUNC [[VEC]]
461 define void @trunc(i64 %a) {
462   %vecptr = alloca <4 x i32>
463   %vec = load <4 x i32>, <4 x i32>* %vecptr
464   %res1 = trunc i64 %a to i8
465   %res2 = trunc <4 x i32> %vec to <4 x i16>
466   ret void
469 ; CHECK-LABEL: name: load
470 ; CHECK: [[ADDR:%[0-9]+]]:_(p0) = COPY $x0
471 ; CHECK: [[ADDR42:%[0-9]+]]:_(p42) = COPY $x1
472 ; CHECK: [[VAL1:%[0-9]+]]:_(s64) = G_LOAD [[ADDR]](p0) :: (load 8 from %ir.addr, align 16)
473 ; CHECK: [[VAL2:%[0-9]+]]:_(s64) = G_LOAD [[ADDR42]](p42) :: (load 8 from %ir.addr42, addrspace 42)
474 ; CHECK: [[SUM2:%.*]]:_(s64) = G_ADD [[VAL1]], [[VAL2]]
475 ; CHECK: [[VAL3:%[0-9]+]]:_(s64) = G_LOAD [[ADDR]](p0) :: (volatile load 8 from %ir.addr)
476 ; CHECK: [[SUM3:%[0-9]+]]:_(s64) = G_ADD [[SUM2]], [[VAL3]]
477 ; CHECK: $x0 = COPY [[SUM3]]
478 ; CHECK: RET_ReallyLR implicit $x0
479 define i64 @load(i64* %addr, i64 addrspace(42)* %addr42) {
480   %val1 = load i64, i64* %addr, align 16
482   %val2 = load i64, i64 addrspace(42)* %addr42
483   %sum2 = add i64 %val1, %val2
485   %val3 = load volatile i64, i64* %addr
486   %sum3 = add i64 %sum2, %val3
487   ret i64 %sum3
490 ; CHECK-LABEL: name: store
491 ; CHECK: [[ADDR:%[0-9]+]]:_(p0) = COPY $x0
492 ; CHECK: [[ADDR42:%[0-9]+]]:_(p42) = COPY $x1
493 ; CHECK: [[VAL1:%[0-9]+]]:_(s64) = COPY $x2
494 ; CHECK: [[VAL2:%[0-9]+]]:_(s64) = COPY $x3
495 ; CHECK: G_STORE [[VAL1]](s64), [[ADDR]](p0) :: (store 8 into %ir.addr, align 16)
496 ; CHECK: G_STORE [[VAL2]](s64), [[ADDR42]](p42) :: (store 8 into %ir.addr42, addrspace 42)
497 ; CHECK: G_STORE [[VAL1]](s64), [[ADDR]](p0) :: (volatile store 8 into %ir.addr)
498 ; CHECK: RET_ReallyLR
499 define void @store(i64* %addr, i64 addrspace(42)* %addr42, i64 %val1, i64 %val2) {
500   store i64 %val1, i64* %addr, align 16
501   store i64 %val2, i64 addrspace(42)* %addr42
502   store volatile i64 %val1, i64* %addr
503   %sum = add i64 %val1, %val2
504   ret void
507 ; CHECK-LABEL: name: intrinsics
508 ; CHECK: [[CUR:%[0-9]+]]:_(s32) = COPY $w0
509 ; CHECK: [[BITS:%[0-9]+]]:_(s32) = COPY $w1
510 ; CHECK: [[CREG:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
511 ; CHECK: [[PTR:%[0-9]+]]:_(p0) = G_INTRINSIC intrinsic(@llvm.returnaddress), [[CREG]]
512 ; CHECK: [[PTR_VEC:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.0.ptr.vec
513 ; CHECK: [[VEC:%[0-9]+]]:_(<8 x s8>) = G_LOAD [[PTR_VEC]]
514 ; CHECK: G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aarch64.neon.st2), [[VEC]](<8 x s8>), [[VEC]](<8 x s8>), [[PTR]](p0)
515 ; CHECK: RET_ReallyLR
516 declare i8* @llvm.returnaddress(i32)
517 declare void @llvm.aarch64.neon.st2.v8i8.p0i8(<8 x i8>, <8 x i8>, i8*)
518 declare { <8 x i8>, <8 x i8> } @llvm.aarch64.neon.ld2.v8i8.p0v8i8(<8 x i8>*)
519 define void @intrinsics(i32 %cur, i32 %bits) {
520   %ptr = call i8* @llvm.returnaddress(i32 0)
521   %ptr.vec = alloca <8 x i8>
522   %vec = load <8 x i8>, <8 x i8>* %ptr.vec
523   call void @llvm.aarch64.neon.st2.v8i8.p0i8(<8 x i8> %vec, <8 x i8> %vec, i8* %ptr)
524   ret void
527 ; CHECK-LABEL: name: test_phi
528 ; CHECK:     G_BRCOND {{%.*}}, %[[TRUE:bb\.[0-9]+]]
529 ; CHECK:     G_BR %[[FALSE:bb\.[0-9]+]]
531 ; CHECK: [[TRUE]].{{[a-zA-Z0-9.]+}}:
532 ; CHECK:     [[RES1:%[0-9]+]]:_(s32) = G_LOAD
534 ; CHECK: [[FALSE]].{{[a-zA-Z0-9.]+}}:
535 ; CHECK:     [[RES2:%[0-9]+]]:_(s32) = G_LOAD
537 ; CHECK:     [[RES:%[0-9]+]]:_(s32) = G_PHI [[RES1]](s32), %[[TRUE]], [[RES2]](s32), %[[FALSE]]
538 ; CHECK:     $w0 = COPY [[RES]]
539 define i32 @test_phi(i32* %addr1, i32* %addr2, i1 %tst) {
540   br i1 %tst, label %true, label %false
542 true:
543   %res1 = load i32, i32* %addr1
544   br label %end
546 false:
547   %res2 = load i32, i32* %addr2
548   br label %end
550 end:
551   %res = phi i32 [%res1, %true], [%res2, %false]
552   ret i32 %res
555 ; CHECK-LABEL: name: unreachable
556 ; CHECK: G_ADD
557 ; CHECK-NEXT: {{^$}}
558 ; CHECK-NEXT: ...
559 define void @unreachable(i32 %a) {
560   %sum = add i32 %a, %a
561   unreachable
564   ; It's important that constants are after argument passing, but before the
565   ; rest of the entry block.
566 ; CHECK-LABEL: name: constant_int
567 ; CHECK: [[IN:%[0-9]+]]:_(s32) = COPY $w0
568 ; CHECK: [[ONE:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
570 ; CHECK: bb.{{[0-9]+}}.{{[a-zA-Z0-9.]+}}:
571 ; CHECK: [[SUM1:%[0-9]+]]:_(s32) = G_ADD [[IN]], [[ONE]]
572 ; CHECK: [[SUM2:%[0-9]+]]:_(s32) = G_ADD [[IN]], [[ONE]]
573 ; CHECK: [[RES:%[0-9]+]]:_(s32) = G_ADD [[SUM1]], [[SUM2]]
574 ; CHECK: $w0 = COPY [[RES]]
576 define i32 @constant_int(i32 %in) {
577   br label %next
579 next:
580   %sum1 = add i32 %in, 1
581   %sum2 = add i32 %in, 1
582   %res = add i32 %sum1, %sum2
583   ret i32 %res
586 ; CHECK-LABEL: name: constant_int_start
587 ; CHECK: [[TWO:%[0-9]+]]:_(s32) = G_CONSTANT i32 2
588 ; CHECK: [[ANSWER:%[0-9]+]]:_(s32) = G_CONSTANT i32 42
589 ; CHECK: [[RES:%[0-9]+]]:_(s32) = G_ADD [[TWO]], [[ANSWER]]
590 define i32 @constant_int_start() {
591   %res = add i32 2, 42
592   ret i32 %res
595 ; CHECK-LABEL: name: test_undef
596 ; CHECK: [[UNDEF:%[0-9]+]]:_(s32) = G_IMPLICIT_DEF
597 ; CHECK: $w0 = COPY [[UNDEF]]
598 define i32 @test_undef() {
599   ret i32 undef
602 ; CHECK-LABEL: name: test_constant_inttoptr
603 ; CHECK: [[ONE:%[0-9]+]]:_(s64) = G_CONSTANT i64 1
604 ; CHECK: [[PTR:%[0-9]+]]:_(p0) = G_INTTOPTR [[ONE]]
605 ; CHECK: $x0 = COPY [[PTR]]
606 define i8* @test_constant_inttoptr() {
607   ret i8* inttoptr(i64 1 to i8*)
610   ; This failed purely because the Constant -> VReg map was kept across
611   ; functions, so reuse the "i64 1" from above.
612 ; CHECK-LABEL: name: test_reused_constant
613 ; CHECK: [[ONE:%[0-9]+]]:_(s64) = G_CONSTANT i64 1
614 ; CHECK: $x0 = COPY [[ONE]]
615 define i64 @test_reused_constant() {
616   ret i64 1
619 ; CHECK-LABEL: name: test_sext
620 ; CHECK: [[IN:%[0-9]+]]:_(s32) = COPY $w0
621 ; CHECK: [[RES:%[0-9]+]]:_(s64) = G_SEXT [[IN]]
622 ; CHECK: $x0 = COPY [[RES]]
623 define i64 @test_sext(i32 %in) {
624   %res = sext i32 %in to i64
625   ret i64 %res
628 ; CHECK-LABEL: name: test_zext
629 ; CHECK: [[IN:%[0-9]+]]:_(s32) = COPY $w0
630 ; CHECK: [[RES:%[0-9]+]]:_(s64) = G_ZEXT [[IN]]
631 ; CHECK: $x0 = COPY [[RES]]
632 define i64 @test_zext(i32 %in) {
633   %res = zext i32 %in to i64
634   ret i64 %res
637 ; CHECK-LABEL: name: test_shl
638 ; CHECK: [[ARG1:%[0-9]+]]:_(s32) = COPY $w0
639 ; CHECK-NEXT: [[ARG2:%[0-9]+]]:_(s32) = COPY $w1
640 ; CHECK-NEXT: [[RES:%[0-9]+]]:_(s32) = G_SHL [[ARG1]], [[ARG2]]
641 ; CHECK-NEXT: $w0 = COPY [[RES]]
642 ; CHECK-NEXT: RET_ReallyLR implicit $w0
643 define i32 @test_shl(i32 %arg1, i32 %arg2) {
644   %res = shl i32 %arg1, %arg2
645   ret i32 %res
649 ; CHECK-LABEL: name: test_lshr
650 ; CHECK: [[ARG1:%[0-9]+]]:_(s32) = COPY $w0
651 ; CHECK-NEXT: [[ARG2:%[0-9]+]]:_(s32) = COPY $w1
652 ; CHECK-NEXT: [[RES:%[0-9]+]]:_(s32) = G_LSHR [[ARG1]], [[ARG2]]
653 ; CHECK-NEXT: $w0 = COPY [[RES]]
654 ; CHECK-NEXT: RET_ReallyLR implicit $w0
655 define i32 @test_lshr(i32 %arg1, i32 %arg2) {
656   %res = lshr i32 %arg1, %arg2
657   ret i32 %res
660 ; CHECK-LABEL: name: test_ashr
661 ; CHECK: [[ARG1:%[0-9]+]]:_(s32) = COPY $w0
662 ; CHECK-NEXT: [[ARG2:%[0-9]+]]:_(s32) = COPY $w1
663 ; CHECK-NEXT: [[RES:%[0-9]+]]:_(s32) = G_ASHR [[ARG1]], [[ARG2]]
664 ; CHECK-NEXT: $w0 = COPY [[RES]]
665 ; CHECK-NEXT: RET_ReallyLR implicit $w0
666 define i32 @test_ashr(i32 %arg1, i32 %arg2) {
667   %res = ashr i32 %arg1, %arg2
668   ret i32 %res
671 ; CHECK-LABEL: name: test_sdiv
672 ; CHECK: [[ARG1:%[0-9]+]]:_(s32) = COPY $w0
673 ; CHECK-NEXT: [[ARG2:%[0-9]+]]:_(s32) = COPY $w1
674 ; CHECK-NEXT: [[RES:%[0-9]+]]:_(s32) = G_SDIV [[ARG1]], [[ARG2]]
675 ; CHECK-NEXT: $w0 = COPY [[RES]]
676 ; CHECK-NEXT: RET_ReallyLR implicit $w0
677 define i32 @test_sdiv(i32 %arg1, i32 %arg2) {
678   %res = sdiv i32 %arg1, %arg2
679   ret i32 %res
682 ; CHECK-LABEL: name: test_udiv
683 ; CHECK: [[ARG1:%[0-9]+]]:_(s32) = COPY $w0
684 ; CHECK-NEXT: [[ARG2:%[0-9]+]]:_(s32) = COPY $w1
685 ; CHECK-NEXT: [[RES:%[0-9]+]]:_(s32) = G_UDIV [[ARG1]], [[ARG2]]
686 ; CHECK-NEXT: $w0 = COPY [[RES]]
687 ; CHECK-NEXT: RET_ReallyLR implicit $w0
688 define i32 @test_udiv(i32 %arg1, i32 %arg2) {
689   %res = udiv i32 %arg1, %arg2
690   ret i32 %res
693 ; CHECK-LABEL: name: test_srem
694 ; CHECK: [[ARG1:%[0-9]+]]:_(s32) = COPY $w0
695 ; CHECK-NEXT: [[ARG2:%[0-9]+]]:_(s32) = COPY $w1
696 ; CHECK-NEXT: [[RES:%[0-9]+]]:_(s32) = G_SREM [[ARG1]], [[ARG2]]
697 ; CHECK-NEXT: $w0 = COPY [[RES]]
698 ; CHECK-NEXT: RET_ReallyLR implicit $w0
699 define i32 @test_srem(i32 %arg1, i32 %arg2) {
700   %res = srem i32 %arg1, %arg2
701   ret i32 %res
704 ; CHECK-LABEL: name: test_urem
705 ; CHECK: [[ARG1:%[0-9]+]]:_(s32) = COPY $w0
706 ; CHECK-NEXT: [[ARG2:%[0-9]+]]:_(s32) = COPY $w1
707 ; CHECK-NEXT: [[RES:%[0-9]+]]:_(s32) = G_UREM [[ARG1]], [[ARG2]]
708 ; CHECK-NEXT: $w0 = COPY [[RES]]
709 ; CHECK-NEXT: RET_ReallyLR implicit $w0
710 define i32 @test_urem(i32 %arg1, i32 %arg2) {
711   %res = urem i32 %arg1, %arg2
712   ret i32 %res
715 ; CHECK-LABEL: name: test_constant_null
716 ; CHECK: [[ZERO:%[0-9]+]]:_(s64) = G_CONSTANT i64 0
717 ; CHECK: [[NULL:%[0-9]+]]:_(p0) = G_INTTOPTR [[ZERO]]
718 ; CHECK: $x0 = COPY [[NULL]]
719 define i8* @test_constant_null() {
720   ret i8* null
723 ; CHECK-LABEL: name: test_struct_memops
724 ; CHECK: [[ADDR:%[0-9]+]]:_(p0) = COPY $x0
725 ; CHECK: [[VAL1:%[0-9]+]]:_(s8) = G_LOAD %0(p0) :: (load 1 from %ir.addr, align 4)
726 ; CHECK: [[CST1:%[0-9]+]]:_(s64) = G_CONSTANT i64 4
727 ; CHECK: [[GEP1:%[0-9]+]]:_(p0) = G_GEP [[ADDR]], [[CST1]](s64)
728 ; CHECK: [[VAL2:%[0-9]+]]:_(s32) = G_LOAD [[GEP1]](p0) :: (load 4 from %ir.addr + 4)
729 ; CHECK: G_STORE [[VAL1]](s8), [[ADDR]](p0) :: (store 1 into %ir.addr, align 4)
730 ; CHECK: [[CST2:%[0-9]+]]:_(s64) = G_CONSTANT i64 4
731 ; CHECK: [[GEP2:%[0-9]+]]:_(p0) = G_GEP [[ADDR]], [[CST2]](s64)
732 ; CHECK: G_STORE [[VAL2]](s32), [[GEP2]](p0) :: (store 4 into %ir.addr + 4)
733 define void @test_struct_memops({ i8, i32 }* %addr) {
734   %val = load { i8, i32 }, { i8, i32 }* %addr
735   store { i8, i32 } %val, { i8, i32 }* %addr
736   ret void
739 ; CHECK-LABEL: name: test_i1_memops
740 ; CHECK: [[ADDR:%[0-9]+]]:_(p0) = COPY $x0
741 ; CHECK: [[VAL:%[0-9]+]]:_(s1) = G_LOAD [[ADDR]](p0) :: (load 1 from  %ir.addr)
742 ; CHECK: G_STORE [[VAL]](s1), [[ADDR]](p0) :: (store 1 into  %ir.addr)
743 define void @test_i1_memops(i1* %addr) {
744   %val = load i1, i1* %addr
745   store i1 %val, i1* %addr
746   ret void
749 ; CHECK-LABEL: name: int_comparison
750 ; CHECK: [[LHS:%[0-9]+]]:_(s32) = COPY $w0
751 ; CHECK: [[RHS:%[0-9]+]]:_(s32) = COPY $w1
752 ; CHECK: [[ADDR:%[0-9]+]]:_(p0) = COPY $x2
753 ; CHECK: [[TST:%[0-9]+]]:_(s1) = G_ICMP intpred(ne), [[LHS]](s32), [[RHS]]
754 ; CHECK: G_STORE [[TST]](s1), [[ADDR]](p0)
755 define void @int_comparison(i32 %a, i32 %b, i1* %addr) {
756   %res = icmp ne i32 %a, %b
757   store i1 %res, i1* %addr
758   ret void
761 ; CHECK-LABEL: name: ptr_comparison
762 ; CHECK: [[LHS:%[0-9]+]]:_(p0) = COPY $x0
763 ; CHECK: [[RHS:%[0-9]+]]:_(p0) = COPY $x1
764 ; CHECK: [[ADDR:%[0-9]+]]:_(p0) = COPY $x2
765 ; CHECK: [[TST:%[0-9]+]]:_(s1) = G_ICMP intpred(eq), [[LHS]](p0), [[RHS]]
766 ; CHECK: G_STORE [[TST]](s1), [[ADDR]](p0)
767 define void @ptr_comparison(i8* %a, i8* %b, i1* %addr) {
768   %res = icmp eq i8* %a, %b
769   store i1 %res, i1* %addr
770   ret void
773 ; CHECK-LABEL: name: test_fadd
774 ; CHECK: [[ARG1:%[0-9]+]]:_(s32) = COPY $s0
775 ; CHECK-NEXT: [[ARG2:%[0-9]+]]:_(s32) = COPY $s1
776 ; CHECK-NEXT: [[RES:%[0-9]+]]:_(s32) = G_FADD [[ARG1]], [[ARG2]]
777 ; CHECK-NEXT: $s0 = COPY [[RES]]
778 ; CHECK-NEXT: RET_ReallyLR implicit $s0
779 define float @test_fadd(float %arg1, float %arg2) {
780   %res = fadd float %arg1, %arg2
781   ret float %res
784 ; CHECK-LABEL: name: test_fsub
785 ; CHECK: [[ARG1:%[0-9]+]]:_(s32) = COPY $s0
786 ; CHECK-NEXT: [[ARG2:%[0-9]+]]:_(s32) = COPY $s1
787 ; CHECK-NEXT: [[RES:%[0-9]+]]:_(s32) = G_FSUB [[ARG1]], [[ARG2]]
788 ; CHECK-NEXT: $s0 = COPY [[RES]]
789 ; CHECK-NEXT: RET_ReallyLR implicit $s0
790 define float @test_fsub(float %arg1, float %arg2) {
791   %res = fsub float %arg1, %arg2
792   ret float %res
795 ; CHECK-LABEL: name: test_fmul
796 ; CHECK: [[ARG1:%[0-9]+]]:_(s32) = COPY $s0
797 ; CHECK-NEXT: [[ARG2:%[0-9]+]]:_(s32) = COPY $s1
798 ; CHECK-NEXT: [[RES:%[0-9]+]]:_(s32) = G_FMUL [[ARG1]], [[ARG2]]
799 ; CHECK-NEXT: $s0 = COPY [[RES]]
800 ; CHECK-NEXT: RET_ReallyLR implicit $s0
801 define float @test_fmul(float %arg1, float %arg2) {
802   %res = fmul float %arg1, %arg2
803   ret float %res
806 ; CHECK-LABEL: name: test_fdiv
807 ; CHECK: [[ARG1:%[0-9]+]]:_(s32) = COPY $s0
808 ; CHECK-NEXT: [[ARG2:%[0-9]+]]:_(s32) = COPY $s1
809 ; CHECK-NEXT: [[RES:%[0-9]+]]:_(s32) = G_FDIV [[ARG1]], [[ARG2]]
810 ; CHECK-NEXT: $s0 = COPY [[RES]]
811 ; CHECK-NEXT: RET_ReallyLR implicit $s0
812 define float @test_fdiv(float %arg1, float %arg2) {
813   %res = fdiv float %arg1, %arg2
814   ret float %res
817 ; CHECK-LABEL: name: test_frem
818 ; CHECK: [[ARG1:%[0-9]+]]:_(s32) = COPY $s0
819 ; CHECK-NEXT: [[ARG2:%[0-9]+]]:_(s32) = COPY $s1
820 ; CHECK-NEXT: [[RES:%[0-9]+]]:_(s32) = G_FREM [[ARG1]], [[ARG2]]
821 ; CHECK-NEXT: $s0 = COPY [[RES]]
822 ; CHECK-NEXT: RET_ReallyLR implicit $s0
823 define float @test_frem(float %arg1, float %arg2) {
824   %res = frem float %arg1, %arg2
825   ret float %res
828 ; CHECK-LABEL: name: test_fneg
829 ; CHECK: [[ARG1:%[0-9]+]]:_(s32) = COPY $s0
830 ; CHECK-NEXT: [[RES:%[0-9]+]]:_(s32) = G_FNEG [[ARG1]]
831 ; CHECK-NEXT: $s0 = COPY [[RES]]
832 ; CHECK-NEXT: RET_ReallyLR implicit $s0
833 define float @test_fneg(float %arg1) {
834   %res = fneg float %arg1
835   ret float %res
838 ; CHECK-LABEL: name: test_sadd_overflow
839 ; CHECK: [[LHS:%[0-9]+]]:_(s32) = COPY $w0
840 ; CHECK: [[RHS:%[0-9]+]]:_(s32) = COPY $w1
841 ; CHECK: [[ADDR:%[0-9]+]]:_(p0) = COPY $x2
842 ; CHECK: [[VAL:%[0-9]+]]:_(s32), [[OVERFLOW:%[0-9]+]]:_(s1) = G_SADDO [[LHS]], [[RHS]]
843 ; CHECK: G_STORE [[VAL]](s32), [[ADDR]](p0) :: (store 4 into %ir.addr)
844 ; CHECK: [[CST:%[0-9]+]]:_(s64) = G_CONSTANT i64 4
845 ; CHECK: [[GEP:%[0-9]+]]:_(p0) = G_GEP [[ADDR]], [[CST]](s64)
846 ; CHECK: G_STORE [[OVERFLOW]](s1), [[GEP]](p0) :: (store 1 into %ir.addr + 4, align 4)
847 declare { i32, i1 } @llvm.sadd.with.overflow.i32(i32, i32)
848 define void @test_sadd_overflow(i32 %lhs, i32 %rhs, { i32, i1 }* %addr) {
849   %res = call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 %lhs, i32 %rhs)
850   store { i32, i1 } %res, { i32, i1 }* %addr
851   ret void
854 ; CHECK-LABEL: name: test_uadd_overflow
855 ; CHECK: [[LHS:%[0-9]+]]:_(s32) = COPY $w0
856 ; CHECK: [[RHS:%[0-9]+]]:_(s32) = COPY $w1
857 ; CHECK: [[ADDR:%[0-9]+]]:_(p0) = COPY $x2
858 ; CHECK: [[VAL:%[0-9]+]]:_(s32), [[OVERFLOW:%[0-9]+]]:_(s1) = G_UADDO [[LHS]], [[RHS]]
859 ; CHECK: G_STORE [[VAL]](s32), [[ADDR]](p0) :: (store 4 into %ir.addr)
860 ; CHECK: [[CST:%[0-9]+]]:_(s64) = G_CONSTANT i64 4
861 ; CHECK: [[GEP:%[0-9]+]]:_(p0) = G_GEP [[ADDR]], [[CST]](s64)
862 ; CHECK: G_STORE [[OVERFLOW]](s1), [[GEP]](p0) :: (store 1 into %ir.addr + 4, align 4)
863 declare { i32, i1 } @llvm.uadd.with.overflow.i32(i32, i32)
864 define void @test_uadd_overflow(i32 %lhs, i32 %rhs, { i32, i1 }* %addr) {
865   %res = call { i32, i1 } @llvm.uadd.with.overflow.i32(i32 %lhs, i32 %rhs)
866   store { i32, i1 } %res, { i32, i1 }* %addr
867   ret void
870 ; CHECK-LABEL: name: test_ssub_overflow
871 ; CHECK: [[LHS:%[0-9]+]]:_(s32) = COPY $w0
872 ; CHECK: [[RHS:%[0-9]+]]:_(s32) = COPY $w1
873 ; CHECK: [[ADDR:%[0-9]+]]:_(p0) = COPY $x2
874 ; CHECK: [[VAL:%[0-9]+]]:_(s32), [[OVERFLOW:%[0-9]+]]:_(s1) = G_SSUBO [[LHS]], [[RHS]]
875 ; CHECK: G_STORE [[VAL]](s32), [[ADDR]](p0) :: (store 4 into %ir.subr)
876 ; CHECK: [[CST:%[0-9]+]]:_(s64) = G_CONSTANT i64 4
877 ; CHECK: [[GEP:%[0-9]+]]:_(p0) = G_GEP [[ADDR]], [[CST]](s64)
878 ; CHECK: G_STORE [[OVERFLOW]](s1), [[GEP]](p0) :: (store 1 into %ir.subr + 4, align 4)
879 declare { i32, i1 } @llvm.ssub.with.overflow.i32(i32, i32)
880 define void @test_ssub_overflow(i32 %lhs, i32 %rhs, { i32, i1 }* %subr) {
881   %res = call { i32, i1 } @llvm.ssub.with.overflow.i32(i32 %lhs, i32 %rhs)
882   store { i32, i1 } %res, { i32, i1 }* %subr
883   ret void
886 ; CHECK-LABEL: name: test_usub_overflow
887 ; CHECK: [[LHS:%[0-9]+]]:_(s32) = COPY $w0
888 ; CHECK: [[RHS:%[0-9]+]]:_(s32) = COPY $w1
889 ; CHECK: [[ADDR:%[0-9]+]]:_(p0) = COPY $x2
890 ; CHECK: [[VAL:%[0-9]+]]:_(s32), [[OVERFLOW:%[0-9]+]]:_(s1) = G_USUBO [[LHS]], [[RHS]]
891 ; CHECK: G_STORE [[VAL]](s32), [[ADDR]](p0) :: (store 4 into %ir.subr)
892 ; CHECK: [[CST:%[0-9]+]]:_(s64) = G_CONSTANT i64 4
893 ; CHECK: [[GEP:%[0-9]+]]:_(p0) = G_GEP [[ADDR]], [[CST]](s64)
894 ; CHECK: G_STORE [[OVERFLOW]](s1), [[GEP]](p0) :: (store 1 into %ir.subr + 4, align 4)
895 declare { i32, i1 } @llvm.usub.with.overflow.i32(i32, i32)
896 define void @test_usub_overflow(i32 %lhs, i32 %rhs, { i32, i1 }* %subr) {
897   %res = call { i32, i1 } @llvm.usub.with.overflow.i32(i32 %lhs, i32 %rhs)
898   store { i32, i1 } %res, { i32, i1 }* %subr
899   ret void
902 ; CHECK-LABEL: name: test_smul_overflow
903 ; CHECK: [[LHS:%[0-9]+]]:_(s32) = COPY $w0
904 ; CHECK: [[RHS:%[0-9]+]]:_(s32) = COPY $w1
905 ; CHECK: [[ADDR:%[0-9]+]]:_(p0) = COPY $x2
906 ; CHECK: [[VAL:%[0-9]+]]:_(s32), [[OVERFLOW:%[0-9]+]]:_(s1) = G_SMULO [[LHS]], [[RHS]]
907 ; CHECK: G_STORE [[VAL]](s32), [[ADDR]](p0) :: (store 4 into %ir.addr)
908 ; CHECK: [[CST:%[0-9]+]]:_(s64) = G_CONSTANT i64 4
909 ; CHECK: [[GEP:%[0-9]+]]:_(p0) = G_GEP [[ADDR]], [[CST]](s64)
910 ; CHECK: G_STORE [[OVERFLOW]](s1), [[GEP]](p0) :: (store 1 into %ir.addr + 4, align 4)
911 declare { i32, i1 } @llvm.smul.with.overflow.i32(i32, i32)
912 define void @test_smul_overflow(i32 %lhs, i32 %rhs, { i32, i1 }* %addr) {
913   %res = call { i32, i1 } @llvm.smul.with.overflow.i32(i32 %lhs, i32 %rhs)
914   store { i32, i1 } %res, { i32, i1 }* %addr
915   ret void
918 ; CHECK-LABEL: name: test_umul_overflow
919 ; CHECK: [[LHS:%[0-9]+]]:_(s32) = COPY $w0
920 ; CHECK: [[RHS:%[0-9]+]]:_(s32) = COPY $w1
921 ; CHECK: [[ADDR:%[0-9]+]]:_(p0) = COPY $x2
922 ; CHECK: [[VAL:%[0-9]+]]:_(s32), [[OVERFLOW:%[0-9]+]]:_(s1) = G_UMULO [[LHS]], [[RHS]]
923 ; CHECK: G_STORE [[VAL]](s32), [[ADDR]](p0) :: (store 4 into %ir.addr)
924 ; CHECK: [[CST:%[0-9]+]]:_(s64) = G_CONSTANT i64 4
925 ; CHECK: [[GEP:%[0-9]+]]:_(p0) = G_GEP [[ADDR]], [[CST]](s64)
926 ; CHECK: G_STORE [[OVERFLOW]](s1), [[GEP]](p0) :: (store 1 into %ir.addr + 4, align 4)
927 declare { i32, i1 } @llvm.umul.with.overflow.i32(i32, i32)
928 define void @test_umul_overflow(i32 %lhs, i32 %rhs, { i32, i1 }* %addr) {
929   %res = call { i32, i1 } @llvm.umul.with.overflow.i32(i32 %lhs, i32 %rhs)
930   store { i32, i1 } %res, { i32, i1 }* %addr
931   ret void
934 ; CHECK-LABEL: name: test_extractvalue
935 ; CHECK: %0:_(p0) = COPY $x0
936 ; CHECK: [[LD1:%[0-9]+]]:_(s8) = G_LOAD %0(p0) :: (load 1 from %ir.addr, align 4)
937 ; CHECK: [[CST1:%[0-9]+]]:_(s64) = G_CONSTANT i64 4
938 ; CHECK: [[GEP1:%[0-9]+]]:_(p0) = G_GEP %0, [[CST1]](s64)
939 ; CHECK: [[LD2:%[0-9]+]]:_(s8) = G_LOAD [[GEP1]](p0) :: (load 1 from %ir.addr + 4, align 4)
940 ; CHECK: [[CST2:%[0-9]+]]:_(s64) = G_CONSTANT i64 8
941 ; CHECK: [[GEP2:%[0-9]+]]:_(p0) = G_GEP %0, [[CST2]](s64)
942 ; CHECK: [[LD3:%[0-9]+]]:_(s32) = G_LOAD [[GEP2]](p0) :: (load 4 from %ir.addr + 8)
943 ; CHECK: [[CST3:%[0-9]+]]:_(s64) = G_CONSTANT i64 12
944 ; CHECK: [[GEP3:%[0-9]+]]:_(p0) = G_GEP %0, [[CST3]](s64)
945 ; CHECK: [[LD4:%[0-9]+]]:_(s32) = G_LOAD [[GEP3]](p0) :: (load 4 from %ir.addr + 12)
946 ; CHECK: $w0 = COPY [[LD3]](s32)
947 %struct.nested = type {i8, { i8, i32 }, i32}
948 define i32 @test_extractvalue(%struct.nested* %addr) {
949   %struct = load %struct.nested, %struct.nested* %addr
950   %res = extractvalue %struct.nested %struct, 1, 1
951   ret i32 %res
954 ; CHECK-LABEL: name: test_extractvalue_agg
955 ; CHECK: %0:_(p0) = COPY $x0
956 ; CHECK: %1:_(p0) = COPY $x1
957 ; CHECK: [[LD1:%[0-9]+]]:_(s8) = G_LOAD %0(p0) :: (load 1 from %ir.addr, align 4)
958 ; CHECK: [[CST1:%[0-9]+]]:_(s64) = G_CONSTANT i64 4
959 ; CHECK: [[GEP1:%[0-9]+]]:_(p0) = G_GEP %0, [[CST1]](s64)
960 ; CHECK: [[LD2:%[0-9]+]]:_(s8) = G_LOAD [[GEP1]](p0) :: (load 1 from %ir.addr + 4, align 4)
961 ; CHECK: [[CST2:%[0-9]+]]:_(s64) = G_CONSTANT i64 8
962 ; CHECK: [[GEP2:%[0-9]+]]:_(p0) = G_GEP %0, [[CST2]](s64)
963 ; CHECK: [[LD3:%[0-9]+]]:_(s32) = G_LOAD [[GEP2]](p0) :: (load 4 from %ir.addr + 8)
964 ; CHECK: [[CST3:%[0-9]+]]:_(s64) = G_CONSTANT i64 12
965 ; CHECK: [[GEP3:%[0-9]+]]:_(p0) = G_GEP %0, [[CST3]](s64)
966 ; CHECK: [[LD4:%[0-9]+]]:_(s32) = G_LOAD [[GEP3]](p0) :: (load 4 from %ir.addr + 12)
967 ; CHECK: G_STORE [[LD2]](s8), %1(p0) :: (store 1 into %ir.addr2, align 4)
968 ; CHECK: [[CST4:%[0-9]+]]:_(s64) = G_CONSTANT i64 4
969 ; CHECK: [[GEP4:%[0-9]+]]:_(p0) = G_GEP %1, [[CST4]](s64)
970 ; CHECK: G_STORE [[LD3]](s32), [[GEP4]](p0) :: (store 4 into %ir.addr2 + 4)
971 define void @test_extractvalue_agg(%struct.nested* %addr, {i8, i32}* %addr2) {
972   %struct = load %struct.nested, %struct.nested* %addr
973   %res = extractvalue %struct.nested %struct, 1
974   store {i8, i32} %res, {i8, i32}* %addr2
975   ret void
978 ; CHECK-LABEL: name: test_insertvalue
979 ; CHECK: %0:_(p0) = COPY $x0
980 ; CHECK: %1:_(s32) = COPY $w1
981 ; CHECK: [[LD1:%[0-9]+]]:_(s8) = G_LOAD %0(p0) :: (load 1 from %ir.addr, align 4)
982 ; CHECK: [[CST1:%[0-9]+]]:_(s64) = G_CONSTANT i64 4
983 ; CHECK: [[GEP1:%[0-9]+]]:_(p0) = G_GEP %0, [[CST1]](s64)
984 ; CHECK: [[LD2:%[0-9]+]]:_(s8) = G_LOAD [[GEP1]](p0) :: (load 1 from %ir.addr + 4, align 4)
985 ; CHECK: [[CST2:%[0-9]+]]:_(s64) = G_CONSTANT i64 8
986 ; CHECK: [[GEP2:%[0-9]+]]:_(p0) = G_GEP %0, [[CST2]](s64)
987 ; CHECK: [[LD3:%[0-9]+]]:_(s32) = G_LOAD [[GEP2]](p0) :: (load 4 from %ir.addr + 8)
988 ; CHECK: [[CST3:%[0-9]+]]:_(s64) = G_CONSTANT i64 12
989 ; CHECK: [[GEP3:%[0-9]+]]:_(p0) = G_GEP %0, [[CST3]](s64)
990 ; CHECK: [[LD4:%[0-9]+]]:_(s32) = G_LOAD [[GEP3]](p0) :: (load 4 from %ir.addr + 12)
991 ; CHECK: G_STORE [[LD1]](s8), %0(p0) :: (store 1 into %ir.addr, align 4)
992 ; CHECK: [[CST4:%[0-9]+]]:_(s64) = G_CONSTANT i64 4
993 ; CHECK: [[GEP4:%[0-9]+]]:_(p0) = G_GEP %0, [[CST4]](s64)
994 ; CHECK: G_STORE [[LD2]](s8), [[GEP4]](p0) :: (store 1 into %ir.addr + 4, align 4)
995 ; CHECK: [[CST5:%[0-9]+]]:_(s64) = G_CONSTANT i64 8
996 ; CHECK: [[GEP5:%[0-9]+]]:_(p0) = G_GEP %0, [[CST5]](s64)
997 ; CHECK: G_STORE %1(s32), [[GEP5]](p0) :: (store 4 into %ir.addr + 8)
998 ; CHECK: [[CST6:%[0-9]+]]:_(s64) = G_CONSTANT i64 12
999 ; CHECK: [[GEP6:%[0-9]+]]:_(p0) = G_GEP %0, [[CST6]](s64)
1000 ; CHECK: G_STORE [[LD4]](s32), [[GEP6]](p0) :: (store 4 into %ir.addr + 12)
1001 define void @test_insertvalue(%struct.nested* %addr, i32 %val) {
1002   %struct = load %struct.nested, %struct.nested* %addr
1003   %newstruct = insertvalue %struct.nested %struct, i32 %val, 1, 1
1004   store %struct.nested %newstruct, %struct.nested* %addr
1005   ret void
1008 define [1 x i64] @test_trivial_insert([1 x i64] %s, i64 %val) {
1009 ; CHECK-LABEL: name: test_trivial_insert
1010 ; CHECK: [[STRUCT:%[0-9]+]]:_(s64) = COPY $x0
1011 ; CHECK: [[VAL:%[0-9]+]]:_(s64) = COPY $x1
1012 ; CHECK: $x0 = COPY [[VAL]]
1013   %res = insertvalue [1 x i64] %s, i64 %val, 0
1014   ret [1 x i64] %res
1017 define [1 x i8*] @test_trivial_insert_ptr([1 x i8*] %s, i8* %val) {
1018 ; CHECK-LABEL: name: test_trivial_insert_ptr
1019 ; CHECK: [[STRUCT:%[0-9]+]]:_(s64) = COPY $x0
1020 ; CHECK: [[VAL:%[0-9]+]]:_(p0) = COPY $x1
1021 ; CHECK: $x0 = COPY [[VAL]]
1022   %res = insertvalue [1 x i8*] %s, i8* %val, 0
1023   ret [1 x i8*] %res
1026 ; CHECK-LABEL: name: test_insertvalue_agg
1027 ; CHECK: %0:_(p0) = COPY $x0
1028 ; CHECK: %1:_(p0) = COPY $x1
1029 ; CHECK: [[LD1:%[0-9]+]]:_(s8) = G_LOAD %1(p0) :: (load 1 from %ir.addr2, align 4)
1030 ; CHECK: [[CST1:%[0-9]+]]:_(s64) = G_CONSTANT i64 4
1031 ; CHECK: [[GEP1:%[0-9]+]]:_(p0) = G_GEP %1, [[CST1]](s64)
1032 ; CHECK: [[LD2:%[0-9]+]]:_(s32) = G_LOAD [[GEP1]](p0) :: (load 4 from %ir.addr2 + 4)
1033 ; CHECK: [[LD3:%[0-9]+]]:_(s8) = G_LOAD %0(p0) :: (load 1 from %ir.addr, align 4)
1034 ; CHECK: [[CST2:%[0-9]+]]:_(s64) = G_CONSTANT i64 4
1035 ; CHECK: [[GEP2:%[0-9]+]]:_(p0) = G_GEP %0, [[CST2]](s64)
1036 ; CHECK: [[LD4:%[0-9]+]]:_(s8) = G_LOAD [[GEP2]](p0) :: (load 1 from %ir.addr + 4, align 4)
1037 ; CHECK: [[CST3:%[0-9]+]]:_(s64) = G_CONSTANT i64 8
1038 ; CHECK: [[GEP3:%[0-9]+]]:_(p0) = G_GEP %0, [[CST3]](s64)
1039 ; CHECK: [[LD5:%[0-9]+]]:_(s32) = G_LOAD [[GEP3]](p0) :: (load 4 from %ir.addr + 8)
1040 ; CHECK: [[CST4:%[0-9]+]]:_(s64) = G_CONSTANT i64 12
1041 ; CHECK: [[GEP4:%[0-9]+]]:_(p0) = G_GEP %0, [[CST4]](s64)
1042 ; CHECK: [[LD6:%[0-9]+]]:_(s32) = G_LOAD [[GEP4]](p0) :: (load 4 from %ir.addr + 12)
1043 ; CHECK: G_STORE [[LD3]](s8), %0(p0) :: (store 1 into %ir.addr, align 4)
1044 ; CHECK: [[CST5:%[0-9]+]]:_(s64) = G_CONSTANT i64 4
1045 ; CHECK: [[GEP5:%[0-9]+]]:_(p0) = G_GEP %0, [[CST5]](s64)
1046 ; CHECK: G_STORE [[LD1]](s8), [[GEP5]](p0) :: (store 1 into %ir.addr + 4, align 4)
1047 ; CHECK: [[CST6:%[0-9]+]]:_(s64) = G_CONSTANT i64 8
1048 ; CHECK: [[GEP6:%[0-9]+]]:_(p0) = G_GEP %0, [[CST6]](s64)
1049 ; CHECK: G_STORE [[LD2]](s32), [[GEP6]](p0) :: (store 4 into %ir.addr + 8)
1050 ; CHECK: [[CST7:%[0-9]+]]:_(s64) = G_CONSTANT i64 12
1051 ; CHECK: [[GEP7:%[0-9]+]]:_(p0) = G_GEP %0, [[CST7]](s64)
1052 ; CHECK: G_STORE [[LD6]](s32), [[GEP7]](p0) :: (store 4 into %ir.addr + 12)
1053 define void @test_insertvalue_agg(%struct.nested* %addr, {i8, i32}* %addr2) {
1054   %smallstruct = load {i8, i32}, {i8, i32}* %addr2
1055   %struct = load %struct.nested, %struct.nested* %addr
1056   %res = insertvalue %struct.nested %struct, {i8, i32} %smallstruct, 1
1057   store %struct.nested %res, %struct.nested* %addr
1058   ret void
1061 ; CHECK-LABEL: name: test_select
1062 ; CHECK: [[TST_C:%[0-9]+]]:_(s32) = COPY $w0
1063 ; CHECK: [[TST:%[0-9]+]]:_(s1) = G_TRUNC [[TST_C]]
1064 ; CHECK: [[LHS:%[0-9]+]]:_(s32) = COPY $w1
1065 ; CHECK: [[RHS:%[0-9]+]]:_(s32) = COPY $w2
1066 ; CHECK: [[RES:%[0-9]+]]:_(s32) = G_SELECT [[TST]](s1), [[LHS]], [[RHS]]
1067 ; CHECK: $w0 = COPY [[RES]]
1068 define i32 @test_select(i1 %tst, i32 %lhs, i32 %rhs) {
1069   %res = select i1 %tst, i32 %lhs, i32 %rhs
1070   ret i32 %res
1073 ; CHECK-LABEL: name: test_select_ptr
1074 ; CHECK: [[TST_C:%[0-9]+]]:_(s32) = COPY $w0
1075 ; CHECK: [[TST:%[0-9]+]]:_(s1) = G_TRUNC [[TST_C]]
1076 ; CHECK: [[LHS:%[0-9]+]]:_(p0) = COPY $x1
1077 ; CHECK: [[RHS:%[0-9]+]]:_(p0) = COPY $x2
1078 ; CHECK: [[RES:%[0-9]+]]:_(p0) = G_SELECT [[TST]](s1), [[LHS]], [[RHS]]
1079 ; CHECK: $x0 = COPY [[RES]]
1080 define i8* @test_select_ptr(i1 %tst, i8* %lhs, i8* %rhs) {
1081   %res = select i1 %tst, i8* %lhs, i8* %rhs
1082   ret i8* %res
1085 ; CHECK-LABEL: name: test_select_vec
1086 ; CHECK: [[TST_C:%[0-9]+]]:_(s32) = COPY $w0
1087 ; CHECK: [[TST:%[0-9]+]]:_(s1) = G_TRUNC [[TST_C]]
1088 ; CHECK: [[LHS:%[0-9]+]]:_(<4 x s32>) = COPY $q0
1089 ; CHECK: [[RHS:%[0-9]+]]:_(<4 x s32>) = COPY $q1
1090 ; CHECK: [[RES:%[0-9]+]]:_(<4 x s32>) = G_SELECT [[TST]](s1), [[LHS]], [[RHS]]
1091 ; CHECK: $q0 = COPY [[RES]]
1092 define <4 x i32> @test_select_vec(i1 %tst, <4 x i32> %lhs, <4 x i32> %rhs) {
1093   %res = select i1 %tst, <4 x i32> %lhs, <4 x i32> %rhs
1094   ret <4 x i32> %res
1097 ; CHECK-LABEL: name: test_vselect_vec
1098 ; CHECK: [[TST32:%[0-9]+]]:_(<4 x s32>) = COPY $q0
1099 ; CHECK: [[LHS:%[0-9]+]]:_(<4 x s32>) = COPY $q1
1100 ; CHECK: [[RHS:%[0-9]+]]:_(<4 x s32>) = COPY $q2
1101 ; CHECK: [[TST:%[0-9]+]]:_(<4 x s1>) = G_TRUNC [[TST32]](<4 x s32>)
1102 ; CHECK: [[RES:%[0-9]+]]:_(<4 x s32>) = G_SELECT [[TST]](<4 x s1>), [[LHS]], [[RHS]]
1103 ; CHECK: $q0 = COPY [[RES]]
1104 define <4 x i32> @test_vselect_vec(<4 x i32> %tst32, <4 x i32> %lhs, <4 x i32> %rhs) {
1105   %tst = trunc <4 x i32> %tst32 to <4 x i1>
1106   %res = select <4 x i1> %tst, <4 x i32> %lhs, <4 x i32> %rhs
1107   ret <4 x i32> %res
1110 ; CHECK-LABEL: name: test_fptosi
1111 ; CHECK: [[FPADDR:%[0-9]+]]:_(p0) = COPY $x0
1112 ; CHECK: [[FP:%[0-9]+]]:_(s32) = G_LOAD [[FPADDR]](p0)
1113 ; CHECK: [[RES:%[0-9]+]]:_(s64) = G_FPTOSI [[FP]](s32)
1114 ; CHECK: $x0 = COPY [[RES]]
1115 define i64 @test_fptosi(float* %fp.addr) {
1116   %fp = load float, float* %fp.addr
1117   %res = fptosi float %fp to i64
1118   ret i64 %res
1121 ; CHECK-LABEL: name: test_fptoui
1122 ; CHECK: [[FPADDR:%[0-9]+]]:_(p0) = COPY $x0
1123 ; CHECK: [[FP:%[0-9]+]]:_(s32) = G_LOAD [[FPADDR]](p0)
1124 ; CHECK: [[RES:%[0-9]+]]:_(s64) = G_FPTOUI [[FP]](s32)
1125 ; CHECK: $x0 = COPY [[RES]]
1126 define i64 @test_fptoui(float* %fp.addr) {
1127   %fp = load float, float* %fp.addr
1128   %res = fptoui float %fp to i64
1129   ret i64 %res
1132 ; CHECK-LABEL: name: test_sitofp
1133 ; CHECK: [[ADDR:%[0-9]+]]:_(p0) = COPY $x0
1134 ; CHECK: [[IN:%[0-9]+]]:_(s32) = COPY $w1
1135 ; CHECK: [[FP:%[0-9]+]]:_(s64) = G_SITOFP [[IN]](s32)
1136 ; CHECK: G_STORE [[FP]](s64), [[ADDR]](p0)
1137 define void @test_sitofp(double* %addr, i32 %in) {
1138   %fp = sitofp i32 %in to double
1139   store double %fp, double* %addr
1140   ret void
1143 ; CHECK-LABEL: name: test_uitofp
1144 ; CHECK: [[ADDR:%[0-9]+]]:_(p0) = COPY $x0
1145 ; CHECK: [[IN:%[0-9]+]]:_(s32) = COPY $w1
1146 ; CHECK: [[FP:%[0-9]+]]:_(s64) = G_UITOFP [[IN]](s32)
1147 ; CHECK: G_STORE [[FP]](s64), [[ADDR]](p0)
1148 define void @test_uitofp(double* %addr, i32 %in) {
1149   %fp = uitofp i32 %in to double
1150   store double %fp, double* %addr
1151   ret void
1154 ; CHECK-LABEL: name: test_fpext
1155 ; CHECK: [[IN:%[0-9]+]]:_(s32) = COPY $s0
1156 ; CHECK: [[RES:%[0-9]+]]:_(s64) = G_FPEXT [[IN]](s32)
1157 ; CHECK: $d0 = COPY [[RES]]
1158 define double @test_fpext(float %in) {
1159   %res = fpext float %in to double
1160   ret double %res
1163 ; CHECK-LABEL: name: test_fptrunc
1164 ; CHECK: [[IN:%[0-9]+]]:_(s64) = COPY $d0
1165 ; CHECK: [[RES:%[0-9]+]]:_(s32) = G_FPTRUNC [[IN]](s64)
1166 ; CHECK: $s0 = COPY [[RES]]
1167 define float @test_fptrunc(double %in) {
1168   %res = fptrunc double %in to float
1169   ret float %res
1172 ; CHECK-LABEL: name: test_constant_float
1173 ; CHECK: [[ADDR:%[0-9]+]]:_(p0) = COPY $x0
1174 ; CHECK: [[TMP:%[0-9]+]]:_(s32) = G_FCONSTANT float 1.500000e+00
1175 ; CHECK: G_STORE [[TMP]](s32), [[ADDR]](p0)
1176 define void @test_constant_float(float* %addr) {
1177   store float 1.5, float* %addr
1178   ret void
1181 ; CHECK-LABEL: name: float_comparison
1182 ; CHECK: [[LHSADDR:%[0-9]+]]:_(p0) = COPY $x0
1183 ; CHECK: [[RHSADDR:%[0-9]+]]:_(p0) = COPY $x1
1184 ; CHECK: [[BOOLADDR:%[0-9]+]]:_(p0) = COPY $x2
1185 ; CHECK: [[LHS:%[0-9]+]]:_(s32) = G_LOAD [[LHSADDR]](p0)
1186 ; CHECK: [[RHS:%[0-9]+]]:_(s32) = G_LOAD [[RHSADDR]](p0)
1187 ; CHECK: [[TST:%[0-9]+]]:_(s1) = nnan ninf nsz arcp contract afn reassoc G_FCMP floatpred(oge), [[LHS]](s32), [[RHS]]
1188 ; CHECK: G_STORE [[TST]](s1), [[BOOLADDR]](p0)
1189 define void @float_comparison(float* %a.addr, float* %b.addr, i1* %bool.addr) {
1190   %a = load float, float* %a.addr
1191   %b = load float, float* %b.addr
1192   %res = fcmp nnan ninf nsz arcp contract afn reassoc oge float %a, %b
1193   store i1 %res, i1* %bool.addr
1194   ret void
1197 ; CHECK-LABEL: name: trivial_float_comparison
1198 ; CHECK: [[ENTRY_R1:%[0-9]+]]:_(s1) = G_CONSTANT i1 false
1199 ; CHECK: [[ENTRY_R2:%[0-9]+]]:_(s1) = G_CONSTANT i1 true
1200 ; CHECK: [[R1:%[0-9]+]]:_(s1) = COPY [[ENTRY_R1]](s1)
1201 ; CHECK: [[R2:%[0-9]+]]:_(s1) = COPY [[ENTRY_R2]](s1)
1202 ; CHECK: G_ADD [[R1]], [[R2]]
1203 define i1 @trivial_float_comparison(double %a, double %b) {
1204   %r1 = fcmp false double %a, %b
1205   %r2 = fcmp true double %a, %b
1206   %sum = add i1 %r1, %r2
1207   ret i1 %sum
1210 @var = global i32 0
1212 define i32* @test_global() {
1213 ; CHECK-LABEL: name: test_global
1214 ; CHECK: [[TMP:%[0-9]+]]:_(p0) = G_GLOBAL_VALUE @var{{$}}
1215 ; CHECK: $x0 = COPY [[TMP]](p0)
1217   ret i32* @var
1220 @var1 = addrspace(42) global i32 0
1221 define i32 addrspace(42)* @test_global_addrspace() {
1222 ; CHECK-LABEL: name: test_global
1223 ; CHECK: [[TMP:%[0-9]+]]:_(p42) = G_GLOBAL_VALUE @var1{{$}}
1224 ; CHECK: $x0 = COPY [[TMP]](p42)
1226   ret i32 addrspace(42)* @var1
1230 define void()* @test_global_func() {
1231 ; CHECK-LABEL: name: test_global_func
1232 ; CHECK: [[TMP:%[0-9]+]]:_(p0) = G_GLOBAL_VALUE @allocai64{{$}}
1233 ; CHECK: $x0 = COPY [[TMP]](p0)
1235   ret void()* @allocai64
1238 declare void @llvm.memcpy.p0i8.p0i8.i64(i8*, i8*, i64, i1)
1239 define void @test_memcpy(i8* %dst, i8* %src, i64 %size) {
1240 ; CHECK-LABEL: name: test_memcpy
1241 ; CHECK: [[DST:%[0-9]+]]:_(p0) = COPY $x0
1242 ; CHECK: [[SRC:%[0-9]+]]:_(p0) = COPY $x1
1243 ; CHECK: [[SIZE:%[0-9]+]]:_(s64) = COPY $x2
1244 ; CHECK: $x0 = COPY [[DST]]
1245 ; CHECK: $x1 = COPY [[SRC]]
1246 ; CHECK: $x2 = COPY [[SIZE]]
1247 ; CHECK: BL &memcpy, csr_aarch64_aapcs, implicit-def $lr, implicit $sp, implicit $x0, implicit $x1, implicit $x2
1248   call void @llvm.memcpy.p0i8.p0i8.i64(i8* %dst, i8* %src, i64 %size, i1 0)
1249   ret void
1252 declare void @llvm.memmove.p0i8.p0i8.i64(i8*, i8*, i64, i1)
1253 define void @test_memmove(i8* %dst, i8* %src, i64 %size) {
1254 ; CHECK-LABEL: name: test_memmove
1255 ; CHECK: [[DST:%[0-9]+]]:_(p0) = COPY $x0
1256 ; CHECK: [[SRC:%[0-9]+]]:_(p0) = COPY $x1
1257 ; CHECK: [[SIZE:%[0-9]+]]:_(s64) = COPY $x2
1258 ; CHECK: $x0 = COPY [[DST]]
1259 ; CHECK: $x1 = COPY [[SRC]]
1260 ; CHECK: $x2 = COPY [[SIZE]]
1261 ; CHECK: BL &memmove, csr_aarch64_aapcs, implicit-def $lr, implicit $sp, implicit $x0, implicit $x1, implicit $x2
1262   call void @llvm.memmove.p0i8.p0i8.i64(i8* %dst, i8* %src, i64 %size, i1 0)
1263   ret void
1266 declare void @llvm.memset.p0i8.i64(i8*, i8, i64, i1)
1267 define void @test_memset(i8* %dst, i8 %val, i64 %size) {
1268 ; CHECK-LABEL: name: test_memset
1269 ; CHECK: [[DST:%[0-9]+]]:_(p0) = COPY $x0
1270 ; CHECK: [[SRC_C:%[0-9]+]]:_(s32) = COPY $w1
1271 ; CHECK: [[SRC:%[0-9]+]]:_(s8) = G_TRUNC [[SRC_C]]
1272 ; CHECK: [[SIZE:%[0-9]+]]:_(s64) = COPY $x2
1273 ; CHECK: $x0 = COPY [[DST]]
1274 ; CHECK: [[SRC_TMP:%[0-9]+]]:_(s32) = G_ANYEXT [[SRC]]
1275 ; CHECK: $w1 = COPY [[SRC_TMP]]
1276 ; CHECK: $x2 = COPY [[SIZE]]
1277 ; CHECK: BL &memset, csr_aarch64_aapcs, implicit-def $lr, implicit $sp, implicit $x0, implicit $w1, implicit $x2
1278   call void @llvm.memset.p0i8.i64(i8* %dst, i8 %val, i64 %size, i1 0)
1279   ret void
1282 declare i64 @llvm.objectsize.i64(i8*, i1)
1283 declare i32 @llvm.objectsize.i32(i8*, i1)
1284 define void @test_objectsize(i8* %addr0, i8* %addr1) {
1285 ; CHECK-LABEL: name: test_objectsize
1286 ; CHECK: [[ADDR0:%[0-9]+]]:_(p0) = COPY $x0
1287 ; CHECK: [[ADDR1:%[0-9]+]]:_(p0) = COPY $x1
1288 ; CHECK: {{%[0-9]+}}:_(s64) = G_CONSTANT i64 -1
1289 ; CHECK: {{%[0-9]+}}:_(s64) = G_CONSTANT i64 0
1290 ; CHECK: {{%[0-9]+}}:_(s32) = G_CONSTANT i32 -1
1291 ; CHECK: {{%[0-9]+}}:_(s32) = G_CONSTANT i32 0
1292   %size64.0 = call i64 @llvm.objectsize.i64(i8* %addr0, i1 0)
1293   %size64.intmin = call i64 @llvm.objectsize.i64(i8* %addr0, i1 1)
1294   %size32.0 = call i32 @llvm.objectsize.i32(i8* %addr0, i1 0)
1295   %size32.intmin = call i32 @llvm.objectsize.i32(i8* %addr0, i1 1)
1296   ret void
1299 define void @test_large_const(i128* %addr) {
1300 ; CHECK-LABEL: name: test_large_const
1301 ; CHECK: [[ADDR:%[0-9]+]]:_(p0) = COPY $x0
1302 ; CHECK: [[VAL:%[0-9]+]]:_(s128) = G_CONSTANT i128 42
1303 ; CHECK: G_STORE [[VAL]](s128), [[ADDR]](p0)
1304   store i128 42, i128* %addr
1305   ret void
1308 ; When there was no formal argument handling (so the first BB was empty) we used
1309 ; to insert the constants at the end of the block, even if they were encountered
1310 ; after the block's terminators had been emitted. Also make sure the order is
1311 ; correct.
1312 define i8* @test_const_placement() {
1313 ; CHECK-LABEL: name: test_const_placement
1314 ; CHECK: bb.{{[0-9]+}} (%ir-block.{{[0-9]+}}):
1315 ; CHECK:   [[VAL_INT:%[0-9]+]]:_(s32) = G_CONSTANT i32 42
1316 ; CHECK:   [[VAL:%[0-9]+]]:_(p0) = G_INTTOPTR [[VAL_INT]](s32)
1317 ; CHECK: bb.{{[0-9]+}}.{{[a-zA-Z0-9.]+}}:
1318   br label %next
1320 next:
1321   ret i8* inttoptr(i32 42 to i8*)
1324 declare void @llvm.va_end(i8*)
1325 define void @test_va_end(i8* %list) {
1326 ; CHECK-LABEL: name: test_va_end
1327 ; CHECK-NOT: va_end
1328 ; CHECK-NOT: INTRINSIC
1329 ; CHECK: RET_ReallyLR
1330   call void @llvm.va_end(i8* %list)
1331   ret void
1334 define void @test_va_arg(i8* %list) {
1335 ; CHECK-LABEL: test_va_arg
1336 ; CHECK: [[LIST:%[0-9]+]]:_(p0) = COPY $x0
1337 ; CHECK: G_VAARG [[LIST]](p0), 8
1338 ; CHECK: G_VAARG [[LIST]](p0), 1
1339 ; CHECK: G_VAARG [[LIST]](p0), 16
1341   %v0 = va_arg i8* %list, i64
1342   %v1 = va_arg i8* %list, i8
1343   %v2 = va_arg i8* %list, i128
1344   ret void
1347 declare float @llvm.pow.f32(float, float)
1348 define float @test_pow_intrin(float %l, float %r) {
1349 ; CHECK-LABEL: name: test_pow_intrin
1350 ; CHECK: [[LHS:%[0-9]+]]:_(s32) = COPY $s0
1351 ; CHECK: [[RHS:%[0-9]+]]:_(s32) = COPY $s1
1352 ; CHECK: [[RES:%[0-9]+]]:_(s32) = nnan ninf nsz arcp contract afn reassoc G_FPOW [[LHS]], [[RHS]]
1353 ; CHECK: $s0 = COPY [[RES]]
1354   %res = call nnan ninf nsz arcp contract afn reassoc float @llvm.pow.f32(float %l, float %r)
1355   ret float %res
1358 declare float @llvm.fma.f32(float, float, float)
1359 define float @test_fma_intrin(float %a, float %b, float %c) {
1360 ; CHECK-LABEL: name: test_fma_intrin
1361 ; CHECK: [[A:%[0-9]+]]:_(s32) = COPY $s0
1362 ; CHECK: [[B:%[0-9]+]]:_(s32) = COPY $s1
1363 ; CHECK: [[C:%[0-9]+]]:_(s32) = COPY $s2
1364 ; CHECK: [[RES:%[0-9]+]]:_(s32) = nnan ninf nsz arcp contract afn reassoc G_FMA [[A]], [[B]], [[C]]
1365 ; CHECK: $s0 = COPY [[RES]]
1366   %res = call nnan ninf nsz arcp contract afn reassoc float @llvm.fma.f32(float %a, float %b, float %c)
1367   ret float %res
1370 declare float @llvm.exp.f32(float)
1371 define float @test_exp_intrin(float %a) {
1372 ; CHECK-LABEL: name: test_exp_intrin
1373 ; CHECK: [[A:%[0-9]+]]:_(s32) = COPY $s0
1374 ; CHECK: [[RES:%[0-9]+]]:_(s32) = nnan ninf nsz arcp contract afn reassoc G_FEXP [[A]]
1375 ; CHECK: $s0 = COPY [[RES]]
1376   %res = call nnan ninf nsz arcp contract afn reassoc float @llvm.exp.f32(float %a)
1377   ret float %res
1380 declare float @llvm.exp2.f32(float)
1381 define float @test_exp2_intrin(float %a) {
1382 ; CHECK-LABEL: name: test_exp2_intrin
1383 ; CHECK: [[A:%[0-9]+]]:_(s32) = COPY $s0
1384 ; CHECK: [[RES:%[0-9]+]]:_(s32) = nnan ninf nsz arcp contract afn reassoc G_FEXP2 [[A]]
1385 ; CHECK: $s0 = COPY [[RES]]
1386   %res = call nnan ninf nsz arcp contract afn reassoc float @llvm.exp2.f32(float %a)
1387   ret float %res
1390 declare float @llvm.log.f32(float)
1391 define float @test_log_intrin(float %a) {
1392 ; CHECK-LABEL: name: test_log_intrin
1393 ; CHECK: [[A:%[0-9]+]]:_(s32) = COPY $s0
1394 ; CHECK: [[RES:%[0-9]+]]:_(s32) = nnan ninf nsz arcp contract afn reassoc G_FLOG [[A]]
1395 ; CHECK: $s0 = COPY [[RES]]
1396   %res = call nnan ninf nsz arcp contract afn reassoc float @llvm.log.f32(float %a)
1397   ret float %res
1400 declare float @llvm.log2.f32(float)
1401 define float @test_log2_intrin(float %a) {
1402 ; CHECK-LABEL: name: test_log2_intrin
1403 ; CHECK: [[A:%[0-9]+]]:_(s32) = COPY $s0
1404 ; CHECK: [[RES:%[0-9]+]]:_(s32) = G_FLOG2 [[A]]
1405 ; CHECK: $s0 = COPY [[RES]]
1406   %res = call float @llvm.log2.f32(float %a)
1407   ret float %res
1410 declare float @llvm.log10.f32(float)
1411 define float @test_log10_intrin(float %a) {
1412 ; CHECK-LABEL: name: test_log10_intrin
1413 ; CHECK: [[A:%[0-9]+]]:_(s32) = COPY $s0
1414 ; CHECK: [[RES:%[0-9]+]]:_(s32) = nnan ninf nsz arcp contract afn reassoc G_FLOG10 [[A]]
1415 ; CHECK: $s0 = COPY [[RES]]
1416   %res = call nnan ninf nsz arcp contract afn reassoc float @llvm.log10.f32(float %a)
1417   ret float %res
1420 declare float @llvm.fabs.f32(float)
1421 define float @test_fabs_intrin(float %a) {
1422 ; CHECK-LABEL: name: test_fabs_intrin
1423 ; CHECK: [[A:%[0-9]+]]:_(s32) = COPY $s0
1424 ; CHECK: [[RES:%[0-9]+]]:_(s32) = nnan ninf nsz arcp contract afn reassoc G_FABS [[A]]
1425 ; CHECK: $s0 = COPY [[RES]]
1426   %res = call nnan ninf nsz arcp contract afn reassoc float @llvm.fabs.f32(float %a)
1427   ret float %res
1430 declare float @llvm.canonicalize.f32(float)
1431 define float @test_fcanonicalize_intrin(float %a) {
1432 ; CHECK-LABEL: name: test_fcanonicalize_intrin
1433 ; CHECK: [[A:%[0-9]+]]:_(s32) = COPY $s0
1434 ; CHECK: [[RES:%[0-9]+]]:_(s32) = nnan ninf nsz arcp contract afn reassoc G_FCANONICALIZE [[A]]
1435 ; CHECK: $s0 = COPY [[RES]]
1436   %res = call nnan ninf nsz arcp contract afn reassoc float @llvm.canonicalize.f32(float %a)
1437   ret float %res
1440 declare float @llvm.trunc.f32(float)
1441 define float @test_intrinsic_trunc(float %a) {
1442 ; CHECK-LABEL: name: test_intrinsic_trunc
1443 ; CHECK: [[A:%[0-9]+]]:_(s32) = COPY $s0
1444 ; CHECK: [[RES:%[0-9]+]]:_(s32) = G_INTRINSIC_TRUNC [[A]]
1445 ; CHECK: $s0 = COPY [[RES]]
1446   %res = call float @llvm.trunc.f32(float %a)
1447   ret float %res
1450 declare float @llvm.round.f32(float)
1451 define float @test_intrinsic_round(float %a) {
1452 ; CHECK-LABEL: name: test_intrinsic_round
1453 ; CHECK: [[A:%[0-9]+]]:_(s32) = COPY $s0
1454 ; CHECK: [[RES:%[0-9]+]]:_(s32) = G_INTRINSIC_ROUND [[A]]
1455 ; CHECK: $s0 = COPY [[RES]]
1456   %res = call float @llvm.round.f32(float %a)
1457   ret float %res
1460 declare i32 @llvm.ctlz.i32(i32, i1)
1461 define i32 @test_ctlz_intrinsic_zero_not_undef(i32 %a) {
1462 ; CHECK-LABEL: name: test_ctlz_intrinsic_zero_not_undef
1463 ; CHECK: [[A:%[0-9]+]]:_(s32) = COPY $w0
1464 ; CHECK: [[RES:%[0-9]+]]:_(s32) = G_CTLZ [[A]]
1465 ; CHECK: $w0 = COPY [[RES]]
1466   %res = call i32 @llvm.ctlz.i32(i32 %a, i1 0)
1467   ret i32 %res
1470 declare i32 @llvm.cttz.i32(i32, i1)
1471 define i32 @test_cttz_intrinsic_zero_undef(i32 %a) {
1472 ; CHECK-LABEL: name: test_cttz_intrinsic_zero_undef
1473 ; CHECK: [[A:%[0-9]+]]:_(s32) = COPY $w0
1474 ; CHECK: [[RES:%[0-9]+]]:_(s32) = G_CTTZ_ZERO_UNDEF [[A]]
1475 ; CHECK: $w0 = COPY [[RES]]
1476   %res = call i32 @llvm.cttz.i32(i32 %a, i1 1)
1477   ret i32 %res
1480 declare i32 @llvm.ctpop.i32(i32)
1481 define i32 @test_ctpop_intrinsic(i32 %a) {
1482 ; CHECK-LABEL: name: test_ctpop
1483 ; CHECK: [[A:%[0-9]+]]:_(s32) = COPY $w0
1484 ; CHECK: [[RES:%[0-9]+]]:_(s32) = G_CTPOP [[A]]
1485 ; CHECK: $w0 = COPY [[RES]]
1486   %res = call i32 @llvm.ctpop.i32(i32 %a)
1487   ret i32 %res
1490 declare void @llvm.lifetime.start.p0i8(i64, i8*)
1491 declare void @llvm.lifetime.end.p0i8(i64, i8*)
1492 define void @test_lifetime_intrin() {
1493 ; CHECK-LABEL: name: test_lifetime_intrin
1494 ; CHECK: RET_ReallyLR
1495 ; O3-LABEL: name: test_lifetime_intrin
1496 ; O3: {{%[0-9]+}}:_(p0) = G_FRAME_INDEX %stack.0.slot
1497 ; O3-NEXT: LIFETIME_START %stack.0.slot
1498 ; O3-NEXT: LIFETIME_END %stack.0.slot
1499 ; O3-NEXT: RET_ReallyLR
1500   %slot = alloca i8, i32 4
1501   call void @llvm.lifetime.start.p0i8(i64 0, i8* %slot)
1502   call void @llvm.lifetime.end.p0i8(i64 0, i8* %slot)
1503   ret void
1506 define void @test_load_store_atomics(i8* %addr) {
1507 ; CHECK-LABEL: name: test_load_store_atomics
1508 ; CHECK: [[ADDR:%[0-9]+]]:_(p0) = COPY $x0
1509 ; CHECK: [[V0:%[0-9]+]]:_(s8) = G_LOAD [[ADDR]](p0) :: (load unordered 1 from %ir.addr)
1510 ; CHECK: G_STORE [[V0]](s8), [[ADDR]](p0) :: (store monotonic 1 into %ir.addr)
1511 ; CHECK: [[V1:%[0-9]+]]:_(s8) = G_LOAD [[ADDR]](p0) :: (load acquire 1 from %ir.addr)
1512 ; CHECK: G_STORE [[V1]](s8), [[ADDR]](p0) :: (store release 1 into %ir.addr)
1513 ; CHECK: [[V2:%[0-9]+]]:_(s8) = G_LOAD [[ADDR]](p0) :: (load syncscope("singlethread") seq_cst 1 from %ir.addr)
1514 ; CHECK: G_STORE [[V2]](s8), [[ADDR]](p0) :: (store syncscope("singlethread") monotonic 1 into %ir.addr)
1515   %v0 = load atomic i8, i8* %addr unordered, align 1
1516   store atomic i8 %v0, i8* %addr monotonic, align 1
1518   %v1 = load atomic i8, i8* %addr acquire, align 1
1519   store atomic i8 %v1, i8* %addr release, align 1
1521   %v2 = load atomic i8, i8* %addr syncscope("singlethread") seq_cst, align 1
1522   store atomic i8 %v2, i8* %addr syncscope("singlethread") monotonic, align 1
1524   ret void
1527 define float @test_fneg_f32(float %x) {
1528 ; CHECK-LABEL: name: test_fneg_f32
1529 ; CHECK: [[ARG:%[0-9]+]]:_(s32) = COPY $s0
1530 ; CHECK: [[RES:%[0-9]+]]:_(s32) = G_FNEG [[ARG]]
1531 ; CHECK: $s0 = COPY [[RES]](s32)
1532   %neg = fsub float -0.000000e+00, %x
1533   ret float %neg
1536 define double @test_fneg_f64(double %x) {
1537 ; CHECK-LABEL: name: test_fneg_f64
1538 ; CHECK: [[ARG:%[0-9]+]]:_(s64) = COPY $d0
1539 ; CHECK: [[RES:%[0-9]+]]:_(s64) = G_FNEG [[ARG]]
1540 ; CHECK: $d0 = COPY [[RES]](s64)
1541   %neg = fsub double -0.000000e+00, %x
1542   ret double %neg
1545 define void @test_trivial_inlineasm() {
1546 ; CHECK-LABEL: name: test_trivial_inlineasm
1547 ; CHECK: INLINEASM &wibble, 1
1548 ; CHECK: INLINEASM &wibble, 0
1549   call void asm sideeffect "wibble", ""()
1550   call void asm "wibble", ""()
1551   ret void
1554 define <2 x i32> @test_insertelement(<2 x i32> %vec, i32 %elt, i32 %idx){
1555 ; CHECK-LABEL: name: test_insertelement
1556 ; CHECK: [[VEC:%[0-9]+]]:_(<2 x s32>) = COPY $d0
1557 ; CHECK: [[ELT:%[0-9]+]]:_(s32) = COPY $w0
1558 ; CHECK: [[IDX:%[0-9]+]]:_(s32) = COPY $w1
1559 ; CHECK: [[RES:%[0-9]+]]:_(<2 x s32>) = G_INSERT_VECTOR_ELT [[VEC]], [[ELT]](s32), [[IDX]](s32)
1560 ; CHECK: $d0 = COPY [[RES]](<2 x s32>)
1561   %res = insertelement <2 x i32> %vec, i32 %elt, i32 %idx
1562   ret <2 x i32> %res
1565 define i32 @test_extractelement(<2 x i32> %vec, i32 %idx) {
1566 ; CHECK-LABEL: name: test_extractelement
1567 ; CHECK: [[VEC:%[0-9]+]]:_(<2 x s32>) = COPY $d0
1568 ; CHECK: [[IDX:%[0-9]+]]:_(s32) = COPY $w0
1569 ; CHECK: [[IDXEXT:%[0-9]+]]:_(s64) = G_SEXT [[IDX]]
1570 ; CHECK: [[RES:%[0-9]+]]:_(s32) = G_EXTRACT_VECTOR_ELT [[VEC]](<2 x s32>), [[IDXEXT]](s64)
1571 ; CHECK: $w0 = COPY [[RES]](s32)
1572   %res = extractelement <2 x i32> %vec, i32 %idx
1573   ret i32 %res
1576 define i32 @test_extractelement_const_idx(<2 x i32> %vec) {
1577 ; CHECK-LABEL: name: test_extractelement
1578 ; CHECK: [[VEC:%[0-9]+]]:_(<2 x s32>) = COPY $d0
1579 ; CHECK: [[IDX:%[0-9]+]]:_(s64) = G_CONSTANT i64 1
1580 ; CHECK: [[RES:%[0-9]+]]:_(s32) = G_EXTRACT_VECTOR_ELT [[VEC]](<2 x s32>), [[IDX]](s64)
1581 ; CHECK: $w0 = COPY [[RES]](s32)
1582   %res = extractelement <2 x i32> %vec, i32 1
1583   ret i32 %res
1586 define i32 @test_singleelementvector(i32 %elt){
1587 ; CHECK-LABEL: name: test_singleelementvector
1588 ; CHECK: [[ELT:%[0-9]+]]:_(s32) = COPY $w0
1589 ; CHECK-NOT: G_INSERT_VECTOR_ELT
1590 ; CHECK-NOT: G_EXTRACT_VECTOR_ELT
1591 ; CHECK: $w0 = COPY [[ELT]](s32)
1592   %vec = insertelement <1 x i32> undef, i32 %elt, i32 0
1593   %res = extractelement <1 x i32> %vec, i32 0
1594   ret i32 %res
1597 define <2 x i32> @test_constantaggzerovector_v2i32() {
1598 ; CHECK-LABEL: name: test_constantaggzerovector_v2i32
1599 ; CHECK: [[ZERO:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
1600 ; CHECK: [[VEC:%[0-9]+]]:_(<2 x s32>) = G_BUILD_VECTOR [[ZERO]](s32), [[ZERO]](s32)
1601 ; CHECK: $d0 = COPY [[VEC]](<2 x s32>)
1602   ret <2 x i32> zeroinitializer
1605 define <2 x float> @test_constantaggzerovector_v2f32() {
1606 ; CHECK-LABEL: name: test_constantaggzerovector_v2f32
1607 ; CHECK: [[ZERO:%[0-9]+]]:_(s32) = G_FCONSTANT float 0.000000e+00
1608 ; CHECK: [[VEC:%[0-9]+]]:_(<2 x s32>) = G_BUILD_VECTOR [[ZERO]](s32), [[ZERO]](s32)
1609 ; CHECK: $d0 = COPY [[VEC]](<2 x s32>)
1610   ret <2 x float> zeroinitializer
1613 define i32 @test_constantaggzerovector_v3i32() {
1614 ; CHECK-LABEL: name: test_constantaggzerovector_v3i32
1615 ; CHECK: [[ZERO:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
1616 ; CHECK: [[VEC:%[0-9]+]]:_(<3 x s32>) = G_BUILD_VECTOR [[ZERO]](s32), [[ZERO]](s32), [[ZERO]](s32)
1617 ; CHECK: G_EXTRACT_VECTOR_ELT [[VEC]](<3 x s32>)
1618   %elt = extractelement <3 x i32> zeroinitializer, i32 1
1619   ret i32 %elt
1622 define <2 x i32> @test_constantdatavector_v2i32() {
1623 ; CHECK-LABEL: name: test_constantdatavector_v2i32
1624 ; CHECK: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
1625 ; CHECK: [[C2:%[0-9]+]]:_(s32) = G_CONSTANT i32 2
1626 ; CHECK: [[VEC:%[0-9]+]]:_(<2 x s32>) = G_BUILD_VECTOR [[C1]](s32), [[C2]](s32)
1627 ; CHECK: $d0 = COPY [[VEC]](<2 x s32>)
1628   ret <2 x i32> <i32 1, i32 2>
1631 define i32 @test_constantdatavector_v3i32() {
1632 ; CHECK-LABEL: name: test_constantdatavector_v3i32
1633 ; CHECK: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
1634 ; CHECK: [[C2:%[0-9]+]]:_(s32) = G_CONSTANT i32 2
1635 ; CHECK: [[C3:%[0-9]+]]:_(s32) = G_CONSTANT i32 3
1636 ; CHECK: [[VEC:%[0-9]+]]:_(<3 x s32>) = G_BUILD_VECTOR [[C1]](s32), [[C2]](s32), [[C3]](s32)
1637 ; CHECK: G_EXTRACT_VECTOR_ELT [[VEC]](<3 x s32>)
1638   %elt = extractelement <3 x i32> <i32 1, i32 2, i32 3>, i32 1
1639   ret i32 %elt
1642 define <4 x i32> @test_constantdatavector_v4i32() {
1643 ; CHECK-LABEL: name: test_constantdatavector_v4i32
1644 ; CHECK: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
1645 ; CHECK: [[C2:%[0-9]+]]:_(s32) = G_CONSTANT i32 2
1646 ; CHECK: [[C3:%[0-9]+]]:_(s32) = G_CONSTANT i32 3
1647 ; CHECK: [[C4:%[0-9]+]]:_(s32) = G_CONSTANT i32 4
1648 ; CHECK: [[VEC:%[0-9]+]]:_(<4 x s32>) = G_BUILD_VECTOR [[C1]](s32), [[C2]](s32), [[C3]](s32), [[C4]](s32)
1649 ; CHECK: $q0 = COPY [[VEC]](<4 x s32>)
1650   ret <4 x i32> <i32 1, i32 2, i32 3, i32 4>
1653 define <2 x double> @test_constantdatavector_v2f64() {
1654 ; CHECK-LABEL: name: test_constantdatavector_v2f64
1655 ; CHECK: [[FC1:%[0-9]+]]:_(s64) = G_FCONSTANT double 1.000000e+00
1656 ; CHECK: [[FC2:%[0-9]+]]:_(s64) = G_FCONSTANT double 2.000000e+00
1657 ; CHECK: [[VEC:%[0-9]+]]:_(<2 x s64>) = G_BUILD_VECTOR [[FC1]](s64), [[FC2]](s64)
1658 ; CHECK: $q0 = COPY [[VEC]](<2 x s64>)
1659   ret <2 x double> <double 1.0, double 2.0>
1662 define i32 @test_constantaggzerovector_v1s32(i32 %arg){
1663 ; CHECK-LABEL: name: test_constantaggzerovector_v1s32
1664 ; CHECK: [[ARG:%[0-9]+]]:_(s32) = COPY $w0
1665 ; CHECK: [[C0:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
1666 ; CHECK-NOT: G_MERGE_VALUES
1667 ; CHECK: G_ADD [[ARG]], [[C0]]
1668   %vec = insertelement <1 x i32> undef, i32 %arg, i32 0
1669   %add = add <1 x i32> %vec, zeroinitializer
1670   %res = extractelement <1 x i32> %add, i32 0
1671   ret i32 %res
1674 define i32 @test_constantdatavector_v1s32(i32 %arg){
1675 ; CHECK-LABEL: name: test_constantdatavector_v1s32
1676 ; CHECK: [[ARG:%[0-9]+]]:_(s32) = COPY $w0
1677 ; CHECK: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
1678 ; CHECK-NOT: G_MERGE_VALUES
1679 ; CHECK: G_ADD [[ARG]], [[C1]]
1680   %vec = insertelement <1 x i32> undef, i32 %arg, i32 0
1681   %add = add <1 x i32> %vec, <i32 1>
1682   %res = extractelement <1 x i32> %add, i32 0
1683   ret i32 %res
1686 declare ghccc float @different_call_conv_target(float %x)
1687 define float @test_different_call_conv_target(float %x) {
1688 ; CHECK-LABEL: name: test_different_call_conv
1689 ; CHECK: [[X:%[0-9]+]]:_(s32) = COPY $s0
1690 ; CHECK: $s8 = COPY [[X]]
1691 ; CHECK: BL @different_call_conv_target, csr_aarch64_aapcs, implicit-def $lr, implicit $sp, implicit $s8, implicit-def $s0
1692   %res = call ghccc float @different_call_conv_target(float %x)
1693   ret float %res
1696 define <2 x i32> @test_shufflevector_s32_v2s32(i32 %arg) {
1697 ; CHECK-LABEL: name: test_shufflevector_s32_v2s32
1698 ; CHECK: [[ARG:%[0-9]+]]:_(s32) = COPY $w0
1699 ; CHECK-DAG: [[UNDEF:%[0-9]+]]:_(s32) = G_IMPLICIT_DEF
1700 ; CHECK-DAG: [[C0:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
1701 ; CHECK-DAG: [[MASK:%[0-9]+]]:_(<2 x s32>) = G_BUILD_VECTOR [[C0]](s32), [[C0]](s32)
1702 ; CHECK: [[VEC:%[0-9]+]]:_(<2 x s32>) = G_SHUFFLE_VECTOR [[ARG]](s32), [[UNDEF]], [[MASK]](<2 x s32>)
1703 ; CHECK: $d0 = COPY [[VEC]](<2 x s32>)
1704   %vec = insertelement <1 x i32> undef, i32 %arg, i32 0
1705   %res = shufflevector <1 x i32> %vec, <1 x i32> undef, <2 x i32> zeroinitializer
1706   ret <2 x i32> %res
1709 define i32 @test_shufflevector_v2s32_s32(<2 x i32> %arg) {
1710 ; CHECK-LABEL: name: test_shufflevector_v2s32_s32
1711 ; CHECK: [[ARG:%[0-9]+]]:_(<2 x s32>) = COPY $d0
1712 ; CHECK-DAG: [[UNDEF:%[0-9]+]]:_(<2 x s32>) = G_IMPLICIT_DEF
1713 ; CHECK-DAG: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
1714 ; CHECK: [[RES:%[0-9]+]]:_(s32) = G_SHUFFLE_VECTOR [[ARG]](<2 x s32>), [[UNDEF]], [[C1]](s32)
1715 ; CHECK: $w0 = COPY [[RES]](s32)
1716   %vec = shufflevector <2 x i32> %arg, <2 x i32> undef, <1 x i32> <i32 1>
1717   %res = extractelement <1 x i32> %vec, i32 0
1718   ret i32 %res
1721 define <2 x i32> @test_shufflevector_v2s32_v2s32(<2 x i32> %arg) {
1722 ; CHECK-LABEL: name: test_shufflevector_v2s32_v2s32
1723 ; CHECK: [[ARG:%[0-9]+]]:_(<2 x s32>) = COPY $d0
1724 ; CHECK-DAG: [[UNDEF:%[0-9]+]]:_(<2 x s32>) = G_IMPLICIT_DEF
1725 ; CHECK-DAG: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
1726 ; CHECK-DAG: [[C0:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
1727 ; CHECK-DAG: [[MASK:%[0-9]+]]:_(<2 x s32>) = G_BUILD_VECTOR [[C1]](s32), [[C0]](s32)
1728 ; CHECK: [[VEC:%[0-9]+]]:_(<2 x s32>) = G_SHUFFLE_VECTOR [[ARG]](<2 x s32>), [[UNDEF]], [[MASK]](<2 x s32>)
1729 ; CHECK: $d0 = COPY [[VEC]](<2 x s32>)
1730   %res = shufflevector <2 x i32> %arg, <2 x i32> undef, <2 x i32> <i32 1, i32 0>
1731   ret <2 x i32> %res
1734 define i32 @test_shufflevector_v2s32_v3s32(<2 x i32> %arg) {
1735 ; CHECK-LABEL: name: test_shufflevector_v2s32_v3s32
1736 ; CHECK: [[ARG:%[0-9]+]]:_(<2 x s32>) = COPY $d0
1737 ; CHECK-DAG: [[UNDEF:%[0-9]+]]:_(<2 x s32>) = G_IMPLICIT_DEF
1738 ; CHECK-DAG: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
1739 ; CHECK-DAG: [[C0:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
1740 ; CHECK-DAG: [[MASK:%[0-9]+]]:_(<3 x s32>) = G_BUILD_VECTOR [[C1]](s32), [[C0]](s32), [[C1]](s32)
1741 ; CHECK: [[VEC:%[0-9]+]]:_(<3 x s32>) = G_SHUFFLE_VECTOR [[ARG]](<2 x s32>), [[UNDEF]], [[MASK]](<3 x s32>)
1742 ; CHECK: G_EXTRACT_VECTOR_ELT [[VEC]](<3 x s32>)
1743   %vec = shufflevector <2 x i32> %arg, <2 x i32> undef, <3 x i32> <i32 1, i32 0, i32 1>
1744   %res = extractelement <3 x i32> %vec, i32 0
1745   ret i32 %res
1748 define <4 x i32> @test_shufflevector_v2s32_v4s32(<2 x i32> %arg1, <2 x i32> %arg2) {
1749 ; CHECK-LABEL: name: test_shufflevector_v2s32_v4s32
1750 ; CHECK: [[ARG1:%[0-9]+]]:_(<2 x s32>) = COPY $d0
1751 ; CHECK: [[ARG2:%[0-9]+]]:_(<2 x s32>) = COPY $d1
1752 ; CHECK: [[C0:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
1753 ; CHECK: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
1754 ; CHECK: [[C2:%[0-9]+]]:_(s32) = G_CONSTANT i32 2
1755 ; CHECK: [[C3:%[0-9]+]]:_(s32) = G_CONSTANT i32 3
1756 ; CHECK: [[MASK:%[0-9]+]]:_(<4 x s32>) = G_BUILD_VECTOR [[C0]](s32), [[C1]](s32), [[C2]](s32), [[C3]](s32)
1757 ; CHECK: [[VEC:%[0-9]+]]:_(<4 x s32>) = G_SHUFFLE_VECTOR [[ARG1]](<2 x s32>), [[ARG2]], [[MASK]](<4 x s32>)
1758 ; CHECK: $q0 = COPY [[VEC]](<4 x s32>)
1759   %res = shufflevector <2 x i32> %arg1, <2 x i32> %arg2, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
1760   ret <4 x i32> %res
1763 define <2 x i32> @test_shufflevector_v4s32_v2s32(<4 x i32> %arg) {
1764 ; CHECK-LABEL: name: test_shufflevector_v4s32_v2s32
1765 ; CHECK: [[ARG:%[0-9]+]]:_(<4 x s32>) = COPY $q0
1766 ; CHECK-DAG: [[UNDEF:%[0-9]+]]:_(<4 x s32>) = G_IMPLICIT_DEF
1767 ; CHECK-DAG: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
1768 ; CHECK-DAG: [[C3:%[0-9]+]]:_(s32) = G_CONSTANT i32 3
1769 ; CHECK-DAG: [[MASK:%[0-9]+]]:_(<2 x s32>) = G_BUILD_VECTOR [[C1]](s32), [[C3]](s32)
1770 ; CHECK: [[VEC:%[0-9]+]]:_(<2 x s32>) = G_SHUFFLE_VECTOR [[ARG]](<4 x s32>), [[UNDEF]], [[MASK]](<2 x s32>)
1771 ; CHECK: $d0 = COPY [[VEC]](<2 x s32>)
1772   %res = shufflevector <4 x i32> %arg, <4 x i32> undef, <2 x i32> <i32 1, i32 3>
1773   ret <2 x i32> %res
1777 define <16 x i8> @test_shufflevector_v8s8_v16s8(<8 x i8> %arg1, <8 x i8> %arg2) {
1778 ; CHECK-LABEL: name: test_shufflevector_v8s8_v16s8
1779 ; CHECK: [[ARG1:%[0-9]+]]:_(<8 x s8>) = COPY $d0
1780 ; CHECK: [[ARG2:%[0-9]+]]:_(<8 x s8>) = COPY $d1
1781 ; CHECK: [[C0:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
1782 ; CHECK: [[C8:%[0-9]+]]:_(s32) = G_CONSTANT i32 8
1783 ; CHECK: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
1784 ; CHECK: [[C9:%[0-9]+]]:_(s32) = G_CONSTANT i32 9
1785 ; CHECK: [[C2:%[0-9]+]]:_(s32) = G_CONSTANT i32 2
1786 ; CHECK: [[C10:%[0-9]+]]:_(s32) = G_CONSTANT i32 10
1787 ; CHECK: [[C3:%[0-9]+]]:_(s32) = G_CONSTANT i32 3
1788 ; CHECK: [[C11:%[0-9]+]]:_(s32) = G_CONSTANT i32 11
1789 ; CHECK: [[C4:%[0-9]+]]:_(s32) = G_CONSTANT i32 4
1790 ; CHECK: [[C12:%[0-9]+]]:_(s32) = G_CONSTANT i32 12
1791 ; CHECK: [[C5:%[0-9]+]]:_(s32) = G_CONSTANT i32 5
1792 ; CHECK: [[C13:%[0-9]+]]:_(s32) = G_CONSTANT i32 13
1793 ; CHECK: [[C6:%[0-9]+]]:_(s32) = G_CONSTANT i32 6
1794 ; CHECK: [[C14:%[0-9]+]]:_(s32) = G_CONSTANT i32 14
1795 ; CHECK: [[C7:%[0-9]+]]:_(s32) = G_CONSTANT i32 7
1796 ; CHECK: [[C15:%[0-9]+]]:_(s32) = G_CONSTANT i32 15
1797 ; CHECK: [[MASK:%[0-9]+]]:_(<16 x s32>) = G_BUILD_VECTOR [[C0]](s32), [[C8]](s32), [[C1]](s32), [[C9]](s32), [[C2]](s32), [[C10]](s32), [[C3]](s32), [[C11]](s32), [[C4]](s32), [[C12]](s32), [[C5]](s32), [[C13]](s32), [[C6]](s32), [[C14]](s32), [[C7]](s32), [[C15]](s32)
1798 ; CHECK: [[VEC:%[0-9]+]]:_(<16 x s8>) = G_SHUFFLE_VECTOR [[ARG1]](<8 x s8>), [[ARG2]], [[MASK]](<16 x s32>)
1799 ; CHECK: $q0 = COPY [[VEC]](<16 x s8>)
1800   %res = shufflevector <8 x i8> %arg1, <8 x i8> %arg2, <16 x i32> <i32 0, i32 8, i32 1, i32 9, i32 2, i32 10, i32 3, i32 11, i32 4, i32 12, i32 5, i32 13, i32 6, i32 14, i32 7, i32 15>
1801   ret <16 x i8> %res
1804 ; CHECK-LABEL: test_constant_vector
1805 ; CHECK: [[UNDEF:%[0-9]+]]:_(s16) = G_IMPLICIT_DEF
1806 ; CHECK: [[F:%[0-9]+]]:_(s16) = G_FCONSTANT half 0xH3C00
1807 ; CHECK: [[M:%[0-9]+]]:_(<4 x s16>) = G_BUILD_VECTOR [[UNDEF]](s16), [[UNDEF]](s16), [[UNDEF]](s16), [[F]](s16)
1808 ; CHECK: $d0 = COPY [[M]](<4 x s16>)
1809 define <4 x half> @test_constant_vector() {
1810   ret <4 x half> <half undef, half undef, half undef, half 0xH3C00>
1813 define i32 @test_target_mem_intrinsic(i32* %addr) {
1814 ; CHECK-LABEL: name: test_target_mem_intrinsic
1815 ; CHECK: [[ADDR:%[0-9]+]]:_(p0) = COPY $x0
1816 ; CHECK: [[VAL:%[0-9]+]]:_(s64) = G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aarch64.ldxr), [[ADDR]](p0) :: (volatile load 4 from %ir.addr)
1817 ; CHECK: G_TRUNC [[VAL]](s64)
1818   %val = call i64 @llvm.aarch64.ldxr.p0i32(i32* %addr)
1819   %trunc = trunc i64 %val to i32
1820   ret i32 %trunc
1823 declare i64 @llvm.aarch64.ldxr.p0i32(i32*) nounwind
1825 %zerosize_type = type {}
1827 define %zerosize_type @test_empty_load_store(%zerosize_type *%ptr, %zerosize_type %in) noinline optnone {
1828 ; CHECK-LABEL: name: test_empty_load_store
1829 ; CHECK-NOT: G_STORE
1830 ; CHECK-NOT: G_LOAD
1831 ; CHECK: RET_ReallyLR
1832 entry:
1833   store %zerosize_type undef, %zerosize_type* undef, align 4
1834   %val = load %zerosize_type, %zerosize_type* %ptr, align 4
1835   ret %zerosize_type %in
1839 define i64 @test_phi_loop(i32 %n) {
1840 ; CHECK-LABEL: name: test_phi_loop
1841 ; CHECK: [[ARG1:%[0-9]+]]:_(s32) = COPY $w0
1842 ; CHECK: [[CST1:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
1843 ; CHECK: [[CST2:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
1844 ; CHECK: [[CST3:%[0-9]+]]:_(s64) = G_CONSTANT i64 0
1845 ; CHECK: [[CST4:%[0-9]+]]:_(s64) = G_CONSTANT i64 1
1847 ; CHECK: [[PN1:%[0-9]+]]:_(s32) = G_PHI [[ARG1]](s32), %bb.1, [[SUB:%[0-9]+]](s32), %bb.2
1848 ; CHECK: [[PN2:%[0-9]+]]:_(s64) = G_PHI [[CST3]](s64), %bb.1, [[PN3:%[0-9]+]](s64), %bb.2
1849 ; CHECK: [[PN3]]:_(s64) = G_PHI [[CST4]](s64), %bb.1, [[ADD:%[0-9]+]](s64), %bb.2
1850 ; CHECK: [[ADD]]:_(s64) = G_ADD [[PN2]], [[PN3]]
1851 ; CHECK: [[SUB]]:_(s32) = G_SUB [[PN1]], [[CST1]]
1852 ; CHECK: [[CMP:%[0-9]+]]:_(s1) = G_ICMP intpred(sle), [[PN1]](s32), [[CST2]]
1853 ; CHECK: G_BRCOND [[CMP]](s1), %bb.3
1854 ; CHECK: G_BR %bb.2
1856 ; CHECK: $x0 = COPY [[PN2]](s64)
1857 ; CHECK: RET_ReallyLR implicit $x0
1858 entry:
1859   br label %loop
1861 loop:
1862   %counter = phi i32 [ %n, %entry ], [ %counter.dec, %loop ]
1863   %elem = phi { i64, i64 } [ { i64 0, i64 1 }, %entry ], [ %updated, %loop ]
1864   %prev = extractvalue { i64, i64 } %elem, 0
1865   %curr = extractvalue { i64, i64 } %elem, 1
1866   %next = add i64 %prev, %curr
1867   %shifted = insertvalue { i64, i64 } %elem, i64 %curr, 0
1868   %updated = insertvalue { i64, i64 } %shifted, i64 %next, 1
1869   %counter.dec = sub i32 %counter, 1
1870   %cond = icmp sle i32 %counter, 0
1871   br i1 %cond, label %exit, label %loop
1873 exit:
1874   %res = extractvalue { i64, i64 } %elem, 0
1875   ret i64 %res
1878 define void @test_phi_diamond({ i8, i16, i32 }* %a.ptr, { i8, i16, i32 }* %b.ptr, i1 %selector, { i8, i16, i32 }* %dst) {
1879 ; CHECK-LABEL: name: test_phi_diamond
1880 ; CHECK: [[ARG1:%[0-9]+]]:_(p0) = COPY $x0
1881 ; CHECK: [[ARG2:%[0-9]+]]:_(p0) = COPY $x1
1882 ; CHECK: [[ARG3:%[0-9]+]]:_(s32) = COPY $w2
1883 ; CHECK: [[TRUNC:%[0-9]+]]:_(s1) = G_TRUNC [[ARG3]](s32)
1884 ; CHECK: [[ARG4:%[0-9]+]]:_(p0) = COPY $x3
1885 ; CHECK: G_BRCOND [[TRUNC]](s1), %bb.2
1886 ; CHECK: G_BR %bb.3
1888 ; CHECK: [[LD1:%[0-9]+]]:_(s8) = G_LOAD [[ARG1]](p0) :: (load 1 from %ir.a.ptr, align 4)
1889 ; CHECK: [[CST1:%[0-9]+]]:_(s64) = G_CONSTANT i64 2
1890 ; CHECK: [[GEP1:%[0-9]+]]:_(p0) = G_GEP [[ARG1]], [[CST1]](s64)
1891 ; CHECK: [[LD2:%[0-9]+]]:_(s16) = G_LOAD [[GEP1]](p0) :: (load 2 from %ir.a.ptr + 2)
1892 ; CHECK: [[CST2:%[0-9]+]]:_(s64) = G_CONSTANT i64 4
1893 ; CHECK: [[GEP2:%[0-9]+]]:_(p0) = G_GEP [[ARG1]], [[CST2]](s64)
1894 ; CHECK: [[LD3:%[0-9]+]]:_(s32) = G_LOAD [[GEP2]](p0) :: (load 4 from %ir.a.ptr + 4)
1895 ; CHECK: G_BR %bb.4
1897 ; CHECK: [[LD4:%[0-9]+]]:_(s8) = G_LOAD [[ARG2]](p0) :: (load 1 from %ir.b.ptr, align 4)
1898 ; CHECK: [[CST3:%[0-9]+]]:_(s64) = G_CONSTANT i64 2
1899 ; CHECK: [[GEP3:%[0-9]+]]:_(p0) = G_GEP [[ARG2]], [[CST3]](s64)
1900 ; CHECK: [[LD5:%[0-9]+]]:_(s16) = G_LOAD [[GEP3]](p0) :: (load 2 from %ir.b.ptr + 2)
1901 ; CHECK: [[CST4:%[0-9]+]]:_(s64) = G_CONSTANT i64 4
1902 ; CHECK: [[GEP4:%[0-9]+]]:_(p0) = G_GEP [[ARG2]], [[CST4]](s64)
1903 ; CHECK: [[LD6:%[0-9]+]]:_(s32) = G_LOAD [[GEP4]](p0) :: (load 4 from %ir.b.ptr + 4)
1905 ; CHECK: [[PN1:%[0-9]+]]:_(s8) = G_PHI [[LD1]](s8), %bb.2, [[LD4]](s8), %bb.3
1906 ; CHECK: [[PN2:%[0-9]+]]:_(s16) = G_PHI [[LD2]](s16), %bb.2, [[LD5]](s16), %bb.3
1907 ; CHECK: [[PN3:%[0-9]+]]:_(s32) = G_PHI [[LD3]](s32), %bb.2, [[LD6]](s32), %bb.3
1908 ; CHECK: G_STORE [[PN1]](s8), [[ARG4]](p0) :: (store 1 into %ir.dst, align 4)
1909 ; CHECK: [[CST5:%[0-9]+]]:_(s64) = G_CONSTANT i64 2
1910 ; CHECK: [[GEP5:%[0-9]+]]:_(p0) = G_GEP [[ARG4]], [[CST5]](s64)
1911 ; CHECK: G_STORE [[PN2]](s16), [[GEP5]](p0) :: (store 2 into %ir.dst + 2)
1912 ; CHECK: [[CST6:%[0-9]+]]:_(s64) = G_CONSTANT i64 4
1913 ; CHECK: [[GEP6:%[0-9]+]]:_(p0) = G_GEP [[ARG4]], [[CST6]](s64)
1914 ; CHECK: G_STORE [[PN3]](s32), [[GEP6]](p0) :: (store 4 into %ir.dst + 4)
1915 ; CHECK: RET_ReallyLR
1917 entry:
1918   br i1 %selector, label %store.a, label %store.b
1920 store.a:
1921   %a = load { i8, i16, i32 }, { i8, i16, i32 }* %a.ptr
1922   br label %join
1924 store.b:
1925   %b = load { i8, i16, i32 }, { i8, i16, i32 }* %b.ptr
1926   br label %join
1928 join:
1929   %v = phi { i8, i16, i32 } [ %a, %store.a ], [ %b, %store.b ]
1930   store { i8, i16, i32 } %v, { i8, i16, i32 }* %dst
1931   ret void
1934 %agg.inner.inner = type {i64, i64}
1935 %agg.inner = type {i16, i8, %agg.inner.inner }
1936 %agg.nested = type {i32, i32, %agg.inner, i32}
1938 define void @test_nested_aggregate_const(%agg.nested *%ptr) {
1939 ; CHECK-LABEL: name: test_nested_aggregate_const
1940 ; CHECK: [[BASE:%[0-9]+]]:_(p0) = COPY $x0
1941 ; CHECK: [[CST1:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
1942 ; CHECK: [[CST2:%[0-9]+]]:_(s16) = G_CONSTANT i16 2
1943 ; CHECK: [[CST3:%[0-9]+]]:_(s8) = G_CONSTANT i8 3
1944 ; CHECK: [[CST4:%[0-9]+]]:_(s64) = G_CONSTANT i64 5
1945 ; CHECK: [[CST5:%[0-9]+]]:_(s64) = G_CONSTANT i64 8
1946 ; CHECK: [[CST6:%[0-9]+]]:_(s32) = G_CONSTANT i32 13
1947 ; CHECK: G_STORE [[CST1]](s32), [[BASE]](p0) :: (store 4 into %ir.ptr, align 8)
1948 ; CHECK: [[CST7:%[0-9]+]]:_(s64) = G_CONSTANT i64 4
1949 ; CHECK: [[GEP1:%[0-9]+]]:_(p0) = G_GEP [[BASE]], [[CST7]](s64)
1950 ; CHECK: G_STORE [[CST1]](s32), [[GEP1]](p0) :: (store 4 into %ir.ptr + 4)
1951 ; CHECK: [[CST8:%[0-9]+]]:_(s64) = G_CONSTANT i64 8
1952 ; CHECK: [[GEP2:%[0-9]+]]:_(p0) = G_GEP [[BASE]], [[CST8]](s64)
1953 ; CHECK: G_STORE [[CST2]](s16), [[GEP2]](p0) :: (store 2 into %ir.ptr + 8, align 8)
1954 ; CHECK: [[CST9:%[0-9]+]]:_(s64) = G_CONSTANT i64 10
1955 ; CHECK: [[GEP3:%[0-9]+]]:_(p0) = G_GEP [[BASE]], [[CST9]](s64)
1956 ; CHECK: G_STORE [[CST3]](s8), [[GEP3]](p0) :: (store 1 into %ir.ptr + 10, align 2)
1957 ; CHECK: [[CST10:%[0-9]+]]:_(s64) = G_CONSTANT i64 16
1958 ; CHECK: [[GEP4:%[0-9]+]]:_(p0) = G_GEP [[BASE]], [[CST10]](s64)
1959 ; CHECK: G_STORE [[CST4]](s64), [[GEP4]](p0) :: (store 8 into %ir.ptr + 16)
1960 ; CHECK: [[CST11:%[0-9]+]]:_(s64) = G_CONSTANT i64 24
1961 ; CHECK: [[GEP5:%[0-9]+]]:_(p0) = G_GEP [[BASE]], [[CST11]](s64)
1962 ; CHECK: G_STORE [[CST5]](s64), [[GEP5]](p0) :: (store 8 into %ir.ptr + 24)
1963 ; CHECK: [[CST12:%[0-9]+]]:_(s64) = G_CONSTANT i64 32
1964 ; CHECK: [[GEP6:%[0-9]+]]:_(p0) = G_GEP [[BASE]], [[CST12]](s64)
1965 ; CHECK: G_STORE [[CST6]](s32), [[GEP6]](p0) :: (store 4 into %ir.ptr + 32, align 8)
1966   store %agg.nested { i32 1, i32 1, %agg.inner { i16 2, i8 3, %agg.inner.inner {i64 5, i64 8} }, i32 13}, %agg.nested *%ptr
1967   ret void
1970 define i1 @return_i1_zext() {
1971 ; AAPCS ABI says that booleans can only be 1 or 0, so we need to zero-extend.
1972 ; CHECK-LABEL: name: return_i1_zext
1973 ; CHECK: [[CST:%[0-9]+]]:_(s1) = G_CONSTANT i1 true
1974 ; CHECK: [[ZEXT:%[0-9]+]]:_(s8) = G_ZEXT [[CST]](s1)
1975 ; CHECK: [[ANYEXT:%[0-9]+]]:_(s32) = G_ANYEXT [[ZEXT]](s8)
1976 ; CHECK: $w0 = COPY [[ANYEXT]](s32)
1977 ; CHECK: RET_ReallyLR implicit $w0
1978   ret i1 true
1981 ; Try one cmpxchg
1982 define i32 @test_atomic_cmpxchg_1(i32* %addr) {
1983 ; CHECK-LABEL: name: test_atomic_cmpxchg_1
1984 ; CHECK:       bb.1.entry:
1985 ; CHECK-NEXT:  successors: %bb.{{[^)]+}}
1986 ; CHECK-NEXT:  liveins: $x0
1987 ; CHECK:         [[ADDR:%[0-9]+]]:_(p0) = COPY $x0
1988 ; CHECK-NEXT:    [[OLDVAL:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
1989 ; CHECK-NEXT:    [[NEWVAL:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
1990 ; CHECK:       bb.2.repeat:
1991 ; CHECK-NEXT:    successors: %bb.3({{[^)]+}}), %bb.2({{[^)]+}})
1992 ; CHECK:         [[OLDVALRES:%[0-9]+]]:_(s32), [[SUCCESS:%[0-9]+]]:_(s1) = G_ATOMIC_CMPXCHG_WITH_SUCCESS [[ADDR]](p0), [[OLDVAL]], [[NEWVAL]] :: (load store monotonic monotonic 4 on %ir.addr)
1993 ; CHECK-NEXT:    G_BRCOND [[SUCCESS]](s1), %bb.3
1994 ; CHECK-NEXT:    G_BR %bb.2
1995 ; CHECK:       bb.3.done:
1996 entry:
1997   br label %repeat
1998 repeat:
1999   %val_success = cmpxchg i32* %addr, i32 0, i32 1 monotonic monotonic
2000   %value_loaded = extractvalue { i32, i1 } %val_success, 0
2001   %success = extractvalue { i32, i1 } %val_success, 1
2002   br i1 %success, label %done, label %repeat
2003 done:
2004   ret i32 %value_loaded
2007 ; Try one cmpxchg with a small type and high atomic ordering.
2008 define i16 @test_atomic_cmpxchg_2(i16* %addr) {
2009 ; CHECK-LABEL: name: test_atomic_cmpxchg_2
2010 ; CHECK:       bb.1.entry:
2011 ; CHECK-NEXT:  successors: %bb.2({{[^)]+}})
2012 ; CHECK-NEXT:  liveins: $x0
2013 ; CHECK:         [[ADDR:%[0-9]+]]:_(p0) = COPY $x0
2014 ; CHECK-NEXT:    [[OLDVAL:%[0-9]+]]:_(s16) = G_CONSTANT i16 0
2015 ; CHECK-NEXT:    [[NEWVAL:%[0-9]+]]:_(s16) = G_CONSTANT i16 1
2016 ; CHECK:       bb.2.repeat:
2017 ; CHECK-NEXT:    successors: %bb.3({{[^)]+}}), %bb.2({{[^)]+}})
2018 ; CHECK:         [[OLDVALRES:%[0-9]+]]:_(s16), [[SUCCESS:%[0-9]+]]:_(s1) = G_ATOMIC_CMPXCHG_WITH_SUCCESS [[ADDR]](p0), [[OLDVAL]], [[NEWVAL]] :: (load store seq_cst seq_cst 2 on %ir.addr)
2019 ; CHECK-NEXT:    G_BRCOND [[SUCCESS]](s1), %bb.3
2020 ; CHECK-NEXT:    G_BR %bb.2
2021 ; CHECK:       bb.3.done:
2022 entry:
2023   br label %repeat
2024 repeat:
2025   %val_success = cmpxchg i16* %addr, i16 0, i16 1 seq_cst seq_cst
2026   %value_loaded = extractvalue { i16, i1 } %val_success, 0
2027   %success = extractvalue { i16, i1 } %val_success, 1
2028   br i1 %success, label %done, label %repeat
2029 done:
2030   ret i16 %value_loaded
2033 ; Try one cmpxchg where the success order and failure order differ.
2034 define i64 @test_atomic_cmpxchg_3(i64* %addr) {
2035 ; CHECK-LABEL: name: test_atomic_cmpxchg_3
2036 ; CHECK:       bb.1.entry:
2037 ; CHECK-NEXT:  successors: %bb.2({{[^)]+}})
2038 ; CHECK-NEXT:  liveins: $x0
2039 ; CHECK:         [[ADDR:%[0-9]+]]:_(p0) = COPY $x0
2040 ; CHECK-NEXT:    [[OLDVAL:%[0-9]+]]:_(s64) = G_CONSTANT i64 0
2041 ; CHECK-NEXT:    [[NEWVAL:%[0-9]+]]:_(s64) = G_CONSTANT i64 1
2042 ; CHECK:       bb.2.repeat:
2043 ; CHECK-NEXT:    successors: %bb.3({{[^)]+}}), %bb.2({{[^)]+}})
2044 ; CHECK:         [[OLDVALRES:%[0-9]+]]:_(s64), [[SUCCESS:%[0-9]+]]:_(s1) = G_ATOMIC_CMPXCHG_WITH_SUCCESS [[ADDR]](p0), [[OLDVAL]], [[NEWVAL]] :: (load store seq_cst acquire 8 on %ir.addr)
2045 ; CHECK-NEXT:    G_BRCOND [[SUCCESS]](s1), %bb.3
2046 ; CHECK-NEXT:    G_BR %bb.2
2047 ; CHECK:       bb.3.done:
2048 entry:
2049   br label %repeat
2050 repeat:
2051   %val_success = cmpxchg i64* %addr, i64 0, i64 1 seq_cst acquire
2052   %value_loaded = extractvalue { i64, i1 } %val_success, 0
2053   %success = extractvalue { i64, i1 } %val_success, 1
2054   br i1 %success, label %done, label %repeat
2055 done:
2056   ret i64 %value_loaded
2059 ; Try a monotonic atomicrmw xchg
2060 ; AArch64 will expand some atomicrmw's at the LLVM-IR level so we use a wide type to avoid this.
2061 define i32 @test_atomicrmw_xchg(i256* %addr) {
2062 ; CHECK-LABEL: name: test_atomicrmw_xchg
2063 ; CHECK:       bb.1 (%ir-block.{{[0-9]+}}):
2064 ; CHECK-NEXT:  liveins: $x0
2065 ; CHECK:         [[ADDR:%[0-9]+]]:_(p0) = COPY $x0
2066 ; CHECK-NEXT:    [[VAL:%[0-9]+]]:_(s256) = G_CONSTANT i256 1
2067 ; CHECK-NEXT:    [[OLDVALRES:%[0-9]+]]:_(s256) = G_ATOMICRMW_XCHG [[ADDR]](p0), [[VAL]] :: (load store monotonic 32 on %ir.addr)
2068 ; CHECK-NEXT:    [[RES:%[0-9]+]]:_(s32) = G_TRUNC [[OLDVALRES]]
2069   %oldval = atomicrmw xchg i256* %addr, i256 1 monotonic
2070   ; FIXME: We currently can't lower 'ret i256' and it's not the purpose of this
2071   ;        test so work around it by truncating to i32 for now.
2072   %oldval.trunc = trunc i256 %oldval to i32
2073   ret i32 %oldval.trunc
2076 ; Try an acquire atomicrmw add
2077 ; AArch64 will expand some atomicrmw's at the LLVM-IR level so we use a wide type to avoid this.
2078 define i32 @test_atomicrmw_add(i256* %addr) {
2079 ; CHECK-LABEL: name: test_atomicrmw_add
2080 ; CHECK:       bb.1 (%ir-block.{{[0-9]+}}):
2081 ; CHECK-NEXT:  liveins: $x0
2082 ; CHECK:         [[ADDR:%[0-9]+]]:_(p0) = COPY $x0
2083 ; CHECK-NEXT:    [[VAL:%[0-9]+]]:_(s256) = G_CONSTANT i256 1
2084 ; CHECK-NEXT:    [[OLDVALRES:%[0-9]+]]:_(s256) = G_ATOMICRMW_ADD [[ADDR]](p0), [[VAL]] :: (load store acquire 32 on %ir.addr)
2085 ; CHECK-NEXT:    [[RES:%[0-9]+]]:_(s32) = G_TRUNC [[OLDVALRES]]
2086   %oldval = atomicrmw add i256* %addr, i256 1 acquire
2087   ; FIXME: We currently can't lower 'ret i256' and it's not the purpose of this
2088   ;        test so work around it by truncating to i32 for now.
2089   %oldval.trunc = trunc i256 %oldval to i32
2090   ret i32 %oldval.trunc
2093 ; Try a release atomicrmw sub
2094 ; AArch64 will expand some atomicrmw's at the LLVM-IR level so we use a wide type to avoid this.
2095 define i32 @test_atomicrmw_sub(i256* %addr) {
2096 ; CHECK-LABEL: name: test_atomicrmw_sub
2097 ; CHECK:       bb.1 (%ir-block.{{[0-9]+}}):
2098 ; CHECK-NEXT:  liveins: $x0
2099 ; CHECK:         [[ADDR:%[0-9]+]]:_(p0) = COPY $x0
2100 ; CHECK-NEXT:    [[VAL:%[0-9]+]]:_(s256) = G_CONSTANT i256 1
2101 ; CHECK-NEXT:    [[OLDVALRES:%[0-9]+]]:_(s256) = G_ATOMICRMW_SUB [[ADDR]](p0), [[VAL]] :: (load store release 32 on %ir.addr)
2102 ; CHECK-NEXT:    [[RES:%[0-9]+]]:_(s32) = G_TRUNC [[OLDVALRES]]
2103   %oldval = atomicrmw sub i256* %addr, i256 1 release
2104   ; FIXME: We currently can't lower 'ret i256' and it's not the purpose of this
2105   ;        test so work around it by truncating to i32 for now.
2106   %oldval.trunc = trunc i256 %oldval to i32
2107   ret i32 %oldval.trunc
2110 ; Try an acq_rel atomicrmw and
2111 ; AArch64 will expand some atomicrmw's at the LLVM-IR level so we use a wide type to avoid this.
2112 define i32 @test_atomicrmw_and(i256* %addr) {
2113 ; CHECK-LABEL: name: test_atomicrmw_and
2114 ; CHECK:       bb.1 (%ir-block.{{[0-9]+}}):
2115 ; CHECK-NEXT:  liveins: $x0
2116 ; CHECK:         [[ADDR:%[0-9]+]]:_(p0) = COPY $x0
2117 ; CHECK-NEXT:    [[VAL:%[0-9]+]]:_(s256) = G_CONSTANT i256 1
2118 ; CHECK-NEXT:    [[OLDVALRES:%[0-9]+]]:_(s256) = G_ATOMICRMW_AND [[ADDR]](p0), [[VAL]] :: (load store acq_rel 32 on %ir.addr)
2119 ; CHECK-NEXT:    [[RES:%[0-9]+]]:_(s32) = G_TRUNC [[OLDVALRES]]
2120   %oldval = atomicrmw and i256* %addr, i256 1 acq_rel
2121   ; FIXME: We currently can't lower 'ret i256' and it's not the purpose of this
2122   ;        test so work around it by truncating to i32 for now.
2123   %oldval.trunc = trunc i256 %oldval to i32
2124   ret i32 %oldval.trunc
2127 ; Try an seq_cst atomicrmw nand
2128 ; AArch64 will expand some atomicrmw's at the LLVM-IR level so we use a wide type to avoid this.
2129 define i32 @test_atomicrmw_nand(i256* %addr) {
2130 ; CHECK-LABEL: name: test_atomicrmw_nand
2131 ; CHECK:       bb.1 (%ir-block.{{[0-9]+}}):
2132 ; CHECK-NEXT:  liveins: $x0
2133 ; CHECK:         [[ADDR:%[0-9]+]]:_(p0) = COPY $x0
2134 ; CHECK-NEXT:    [[VAL:%[0-9]+]]:_(s256) = G_CONSTANT i256 1
2135 ; CHECK-NEXT:    [[OLDVALRES:%[0-9]+]]:_(s256) = G_ATOMICRMW_NAND [[ADDR]](p0), [[VAL]] :: (load store seq_cst 32 on %ir.addr)
2136 ; CHECK-NEXT:    [[RES:%[0-9]+]]:_(s32) = G_TRUNC [[OLDVALRES]]
2137   %oldval = atomicrmw nand i256* %addr, i256 1 seq_cst
2138   ; FIXME: We currently can't lower 'ret i256' and it's not the purpose of this
2139   ;        test so work around it by truncating to i32 for now.
2140   %oldval.trunc = trunc i256 %oldval to i32
2141   ret i32 %oldval.trunc
2144 ; Try an seq_cst atomicrmw or
2145 ; AArch64 will expand some atomicrmw's at the LLVM-IR level so we use a wide type to avoid this.
2146 define i32 @test_atomicrmw_or(i256* %addr) {
2147 ; CHECK-LABEL: name: test_atomicrmw_or
2148 ; CHECK:       bb.1 (%ir-block.{{[0-9]+}}):
2149 ; CHECK-NEXT:  liveins: $x0
2150 ; CHECK:         [[ADDR:%[0-9]+]]:_(p0) = COPY $x0
2151 ; CHECK-NEXT:    [[VAL:%[0-9]+]]:_(s256) = G_CONSTANT i256 1
2152 ; CHECK-NEXT:    [[OLDVALRES:%[0-9]+]]:_(s256) = G_ATOMICRMW_OR [[ADDR]](p0), [[VAL]] :: (load store seq_cst 32 on %ir.addr)
2153 ; CHECK-NEXT:    [[RES:%[0-9]+]]:_(s32) = G_TRUNC [[OLDVALRES]]
2154   %oldval = atomicrmw or i256* %addr, i256 1 seq_cst
2155   ; FIXME: We currently can't lower 'ret i256' and it's not the purpose of this
2156   ;        test so work around it by truncating to i32 for now.
2157   %oldval.trunc = trunc i256 %oldval to i32
2158   ret i32 %oldval.trunc
2161 ; Try an seq_cst atomicrmw xor
2162 ; AArch64 will expand some atomicrmw's at the LLVM-IR level so we use a wide type to avoid this.
2163 define i32 @test_atomicrmw_xor(i256* %addr) {
2164 ; CHECK-LABEL: name: test_atomicrmw_xor
2165 ; CHECK:       bb.1 (%ir-block.{{[0-9]+}}):
2166 ; CHECK-NEXT:  liveins: $x0
2167 ; CHECK:         [[ADDR:%[0-9]+]]:_(p0) = COPY $x0
2168 ; CHECK-NEXT:    [[VAL:%[0-9]+]]:_(s256) = G_CONSTANT i256 1
2169 ; CHECK-NEXT:    [[OLDVALRES:%[0-9]+]]:_(s256) = G_ATOMICRMW_XOR [[ADDR]](p0), [[VAL]] :: (load store seq_cst 32 on %ir.addr)
2170 ; CHECK-NEXT:    [[RES:%[0-9]+]]:_(s32) = G_TRUNC [[OLDVALRES]]
2171   %oldval = atomicrmw xor i256* %addr, i256 1 seq_cst
2172   ; FIXME: We currently can't lower 'ret i256' and it's not the purpose of this
2173   ;        test so work around it by truncating to i32 for now.
2174   %oldval.trunc = trunc i256 %oldval to i32
2175   ret i32 %oldval.trunc
2178 ; Try an seq_cst atomicrmw min
2179 ; AArch64 will expand some atomicrmw's at the LLVM-IR level so we use a wide type to avoid this.
2180 define i32 @test_atomicrmw_min(i256* %addr) {
2181 ; CHECK-LABEL: name: test_atomicrmw_min
2182 ; CHECK:       bb.1 (%ir-block.{{[0-9]+}}):
2183 ; CHECK-NEXT:  liveins: $x0
2184 ; CHECK:         [[ADDR:%[0-9]+]]:_(p0) = COPY $x0
2185 ; CHECK-NEXT:    [[VAL:%[0-9]+]]:_(s256) = G_CONSTANT i256 1
2186 ; CHECK-NEXT:    [[OLDVALRES:%[0-9]+]]:_(s256) = G_ATOMICRMW_MIN [[ADDR]](p0), [[VAL]] :: (load store seq_cst 32 on %ir.addr)
2187 ; CHECK-NEXT:    [[RES:%[0-9]+]]:_(s32) = G_TRUNC [[OLDVALRES]]
2188   %oldval = atomicrmw min i256* %addr, i256 1 seq_cst
2189   ; FIXME: We currently can't lower 'ret i256' and it's not the purpose of this
2190   ;        test so work around it by truncating to i32 for now.
2191   %oldval.trunc = trunc i256 %oldval to i32
2192   ret i32 %oldval.trunc
2195 ; Try an seq_cst atomicrmw max
2196 ; AArch64 will expand some atomicrmw's at the LLVM-IR level so we use a wide type to avoid this.
2197 define i32 @test_atomicrmw_max(i256* %addr) {
2198 ; CHECK-LABEL: name: test_atomicrmw_max
2199 ; CHECK:       bb.1 (%ir-block.{{[0-9]+}}):
2200 ; CHECK-NEXT:  liveins: $x0
2201 ; CHECK:         [[ADDR:%[0-9]+]]:_(p0) = COPY $x0
2202 ; CHECK-NEXT:    [[VAL:%[0-9]+]]:_(s256) = G_CONSTANT i256 1
2203 ; CHECK-NEXT:    [[OLDVALRES:%[0-9]+]]:_(s256) = G_ATOMICRMW_MAX [[ADDR]](p0), [[VAL]] :: (load store seq_cst 32 on %ir.addr)
2204 ; CHECK-NEXT:    [[RES:%[0-9]+]]:_(s32) = G_TRUNC [[OLDVALRES]]
2205   %oldval = atomicrmw max i256* %addr, i256 1 seq_cst
2206   ; FIXME: We currently can't lower 'ret i256' and it's not the purpose of this
2207   ;        test so work around it by truncating to i32 for now.
2208   %oldval.trunc = trunc i256 %oldval to i32
2209   ret i32 %oldval.trunc
2212 ; Try an seq_cst atomicrmw unsigned min
2213 ; AArch64 will expand some atomicrmw's at the LLVM-IR level so we use a wide type to avoid this.
2214 define i32 @test_atomicrmw_umin(i256* %addr) {
2215 ; CHECK-LABEL: name: test_atomicrmw_umin
2216 ; CHECK:       bb.1 (%ir-block.{{[0-9]+}}):
2217 ; CHECK-NEXT:  liveins: $x0
2218 ; CHECK:         [[ADDR:%[0-9]+]]:_(p0) = COPY $x0
2219 ; CHECK-NEXT:    [[VAL:%[0-9]+]]:_(s256) = G_CONSTANT i256 1
2220 ; CHECK-NEXT:    [[OLDVALRES:%[0-9]+]]:_(s256) = G_ATOMICRMW_UMIN [[ADDR]](p0), [[VAL]] :: (load store seq_cst 32 on %ir.addr)
2221 ; CHECK-NEXT:    [[RES:%[0-9]+]]:_(s32) = G_TRUNC [[OLDVALRES]]
2222   %oldval = atomicrmw umin i256* %addr, i256 1 seq_cst
2223   ; FIXME: We currently can't lower 'ret i256' and it's not the purpose of this
2224   ;        test so work around it by truncating to i32 for now.
2225   %oldval.trunc = trunc i256 %oldval to i32
2226   ret i32 %oldval.trunc
2229 ; Try an seq_cst atomicrmw unsigned max
2230 ; AArch64 will expand some atomicrmw's at the LLVM-IR level so we use a wide type to avoid this.
2231 define i32 @test_atomicrmw_umax(i256* %addr) {
2232 ; CHECK-LABEL: name: test_atomicrmw_umax
2233 ; CHECK:       bb.1 (%ir-block.{{[0-9]+}}):
2234 ; CHECK-NEXT:  liveins: $x0
2235 ; CHECK:         [[ADDR:%[0-9]+]]:_(p0) = COPY $x0
2236 ; CHECK-NEXT:    [[VAL:%[0-9]+]]:_(s256) = G_CONSTANT i256 1
2237 ; CHECK-NEXT:    [[OLDVALRES:%[0-9]+]]:_(s256) = G_ATOMICRMW_UMAX [[ADDR]](p0), [[VAL]] :: (load store seq_cst 32 on %ir.addr)
2238 ; CHECK-NEXT:    [[RES:%[0-9]+]]:_(s32) = G_TRUNC [[OLDVALRES]]
2239   %oldval = atomicrmw umax i256* %addr, i256 1 seq_cst
2240   ; FIXME: We currently can't lower 'ret i256' and it's not the purpose of this
2241   ;        test so work around it by truncating to i32 for now.
2242   %oldval.trunc = trunc i256 %oldval to i32
2243   ret i32 %oldval.trunc
2246 @addr = global i8* null
2248 define void @test_blockaddress() {
2249 ; CHECK-LABEL: name: test_blockaddress
2250 ; CHECK: [[BADDR:%[0-9]+]]:_(p0) = G_BLOCK_ADDR blockaddress(@test_blockaddress, %ir-block.block)
2251 ; CHECK: G_STORE [[BADDR]](p0)
2252   store i8* blockaddress(@test_blockaddress, %block), i8** @addr
2253   indirectbr i8* blockaddress(@test_blockaddress, %block), [label %block]
2254 block:
2255   ret void
2258 %t = type { i32 }
2259 declare {}* @llvm.invariant.start.p0i8(i64, i8* nocapture) readonly nounwind
2260 declare void @llvm.invariant.end.p0i8({}*, i64, i8* nocapture) nounwind
2261 define void @test_invariant_intrin() {
2262 ; CHECK-LABEL: name: test_invariant_intrin
2263 ; CHECK: %{{[0-9]+}}:_(s64) = G_IMPLICIT_DEF
2264 ; CHECK-NEXT: RET_ReallyLR
2265   %x = alloca %t
2266   %y = bitcast %t* %x to i8*
2267   %inv = call {}* @llvm.invariant.start.p0i8(i64 8, i8* %y)
2268   call void @llvm.invariant.end.p0i8({}* %inv, i64 8, i8* %y)
2269   ret void
2272 declare float @llvm.ceil.f32(float)
2273 define float @test_ceil_f32(float %x) {
2274   ; CHECK-LABEL: name:            test_ceil_f32
2275   ; CHECK: %{{[0-9]+}}:_(s32) = G_FCEIL %{{[0-9]+}}
2276   %y = call float @llvm.ceil.f32(float %x)
2277   ret float %y
2280 declare double @llvm.ceil.f64(double)
2281 define double @test_ceil_f64(double %x) {
2282   ; CHECK-LABEL: name:            test_ceil_f64
2283   ; CHECK: %{{[0-9]+}}:_(s64) = G_FCEIL %{{[0-9]+}}
2284   %y = call double @llvm.ceil.f64(double %x)
2285   ret double %y
2288 declare <2 x float> @llvm.ceil.v2f32(<2 x float>)
2289 define <2 x float> @test_ceil_v2f32(<2 x float> %x) {
2290   ; CHECK-LABEL: name:            test_ceil_v2f32
2291   ; CHECK: %{{[0-9]+}}:_(<2 x s32>) = G_FCEIL %{{[0-9]+}}
2292   %y = call <2 x float> @llvm.ceil.v2f32(<2 x float> %x)
2293   ret <2 x float> %y
2296 declare <4 x float> @llvm.ceil.v4f32(<4 x float>)
2297 define <4 x float> @test_ceil_v4f32(<4 x float> %x) {
2298   ; CHECK-LABEL: name:            test_ceil_v4f32
2299   ; CHECK: %{{[0-9]+}}:_(<4 x s32>) = G_FCEIL %{{[0-9]+}}
2300   ; SELECT: %{{[0-9]+}}:fpr128 = FRINTPv4f32 %{{[0-9]+}}
2301   %y = call <4 x float> @llvm.ceil.v4f32(<4 x float> %x)
2302   ret <4 x float> %y
2305 declare <2 x double> @llvm.ceil.v2f64(<2 x double>)
2306 define <2 x double> @test_ceil_v2f64(<2 x double> %x) {
2307   ; CHECK-LABEL: name:            test_ceil_v2f64
2308   ; CHECK: %{{[0-9]+}}:_(<2 x s64>) = G_FCEIL %{{[0-9]+}}
2309   %y = call <2 x double> @llvm.ceil.v2f64(<2 x double> %x)
2310   ret <2 x double> %y
2313 declare float @llvm.cos.f32(float)
2314 define float @test_cos_f32(float %x) {
2315   ; CHECK-LABEL: name:            test_cos_f32
2316   ; CHECK: %{{[0-9]+}}:_(s32) = G_FCOS %{{[0-9]+}}
2317   %y = call float @llvm.cos.f32(float %x)
2318   ret float %y
2321 declare float @llvm.sin.f32(float)
2322 define float @test_sin_f32(float %x) {
2323   ; CHECK-LABEL: name:            test_sin_f32
2324   ; CHECK: %{{[0-9]+}}:_(s32) = G_FSIN %{{[0-9]+}}
2325   %y = call float @llvm.sin.f32(float %x)
2326   ret float %y
2329 declare float @llvm.sqrt.f32(float)
2330 define float @test_sqrt_f32(float %x) {
2331   ; CHECK-LABEL: name:            test_sqrt_f32
2332   ; CHECK: %{{[0-9]+}}:_(s32) = G_FSQRT %{{[0-9]+}}
2333   %y = call float @llvm.sqrt.f32(float %x)
2334   ret float %y
2337 declare float @llvm.floor.f32(float)
2338 define float @test_floor_f32(float %x) {
2339   ; CHECK-LABEL: name:            test_floor_f32
2340   ; CHECK: %{{[0-9]+}}:_(s32) = G_FFLOOR %{{[0-9]+}}
2341   %y = call float @llvm.floor.f32(float %x)
2342   ret float %y
2345 ; CHECK-LABEL: name: test_llvm.aarch64.neon.ld3.v4i32.p0i32
2346 ; CHECK: %1:_(s384) = G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aarch64.neon.ld3), %0(p0) :: (load 48 from %ir.ptr, align 64)
2347 define void @test_llvm.aarch64.neon.ld3.v4i32.p0i32(i32* %ptr) {
2348   %arst = call { <4 x i32>, <4 x i32>, <4 x i32> } @llvm.aarch64.neon.ld3.v4i32.p0i32(i32* %ptr)
2349   ret void
2352 declare { <4 x i32>, <4 x i32>, <4 x i32> } @llvm.aarch64.neon.ld3.v4i32.p0i32(i32*) #3