Revert " [LoongArch][ISel] Check the number of sign bits in `PatGprGpr_32` (#107432)"
[llvm-project.git] / llvm / test / CodeGen / AArch64 / GlobalISel / arm64-irtranslator.ll
blob314c5458e30909a53191a4176061441af5433dc1
1 ; RUN: llc -O0 -aarch64-enable-atomic-cfg-tidy=0 -mattr=+lse -stop-after=irtranslator -global-isel -verify-machineinstrs %s -o - 2>&1 | FileCheck %s
2 ; RUN: llc -O3 -aarch64-enable-atomic-cfg-tidy=0 -mattr=+lse -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: default, 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: default, 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: default, 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 ; CHECK: [[END]].{{[a-zA-Z0-9.]+}}:
91 ; CHECK-NEXT: RET_ReallyLR
92 define void @uncondbr_fallthrough() {
93 entry:
94   br label %end
95 end:
96   ret void
99 ; Tests for conditional br.
100 ; CHECK-LABEL: name: condbr
101 ; CHECK: body:
103 ; ABI/constant lowering and IR-level entry basic block.
104 ; CHECK: bb.{{[0-9]+}} (%ir-block.{{[0-9]+}}):
105 ; Make sure we have two successors
106 ; CHECK-NEXT: successors: %[[TRUE:bb.[0-9]+]](0x40000000),
107 ; CHECK:                  %[[FALSE:bb.[0-9]+]](0x40000000)
109 ; CHECK: [[ADDR:%.*]]:_(p0) = COPY $x0
111 ; Check that we emit the correct branch.
112 ; CHECK: [[TST:%.*]]:_(s1) = G_LOAD [[ADDR]](p0)
113 ; CHECK: G_BRCOND [[TST]](s1), %[[TRUE]]
114 ; CHECK: G_BR %[[FALSE]]
116 ; Check that each successor contains the return instruction.
117 ; CHECK: [[TRUE]].{{[a-zA-Z0-9.]+}}:
118 ; CHECK-NEXT: RET_ReallyLR
119 ; CHECK: [[FALSE]].{{[a-zA-Z0-9.]+}}:
120 ; CHECK-NEXT: RET_ReallyLR
121 define void @condbr(ptr %tstaddr) {
122   %tst = load i1, ptr %tstaddr
123   br i1 %tst, label %true, label %false
124 true:
125   ret void
126 false:
127   ret void
130 ; Tests for indirect br.
131 ; CHECK-LABEL: name: indirectbr
132 ; CHECK: body:
134 ; ABI/constant lowering and IR-level entry basic block.
135 ; CHECK: bb.{{[0-9]+.[a-zA-Z0-9.]+}}:
136 ; Make sure we have one successor
137 ; CHECK-NEXT: successors: %[[BB_L1:bb.[0-9]+]](0x80000000)
139 ; Check basic block L1 has 2 successors: BBL1 and BBL2
140 ; CHECK: [[BB_L1]].{{[a-zA-Z0-9.]+}} (ir-block-address-taken %ir-block.{{[a-zA-Z0-9.]+}}):
141 ; CHECK-NEXT: successors: %[[BB_L1]](0x40000000),
142 ; CHECK:                  %[[BB_L2:bb.[0-9]+]](0x40000000)
143 ; CHECK: G_BRINDIRECT %{{[0-9]+}}(p0)
145 ; Check basic block L2 is the return basic block
146 ; CHECK: [[BB_L2]].{{[a-zA-Z0-9.]+}} (ir-block-address-taken %ir-block.{{[a-zA-Z0-9.]+}}):
147 ; CHECK-NEXT: RET_ReallyLR
149 @indirectbr.L = internal unnamed_addr constant [3 x ptr] [ptr blockaddress(@indirectbr, %L1), ptr blockaddress(@indirectbr, %L2), ptr null], align 8
151 define void @indirectbr() {
152 entry:
153   br label %L1
154 L1:                                               ; preds = %entry, %L1
155   %i = phi i32 [ 0, %entry ], [ %inc, %L1 ]
156   %inc = add i32 %i, 1
157   %idxprom = zext i32 %i to i64
158   %arrayidx = getelementptr inbounds [3 x ptr], ptr @indirectbr.L, i64 0, i64 %idxprom
159   %brtarget = load ptr, ptr %arrayidx, align 8
160   indirectbr ptr %brtarget, [label %L1, label %L2]
161 L2:                                               ; preds = %L1
162   ret void
165 ; Tests for or.
166 ; CHECK-LABEL: name: ori64
167 ; CHECK: [[ARG1:%[0-9]+]]:_(s64) = COPY $x0
168 ; CHECK-NEXT: [[ARG2:%[0-9]+]]:_(s64) = COPY $x1
169 ; CHECK-NEXT: [[RES:%[0-9]+]]:_(s64) = G_OR [[ARG1]], [[ARG2]]
170 ; CHECK-NEXT: $x0 = COPY [[RES]]
171 ; CHECK-NEXT: RET_ReallyLR implicit $x0
172 define i64 @ori64(i64 %arg1, i64 %arg2) {
173   %res = or i64 %arg1, %arg2
174   ret i64 %res
177 ; CHECK-LABEL: name: ori32
178 ; CHECK: [[ARG1:%[0-9]+]]:_(s32) = COPY $w0
179 ; CHECK-NEXT: [[ARG2:%[0-9]+]]:_(s32) = COPY $w1
180 ; CHECK-NEXT: [[RES:%[0-9]+]]:_(s32) = G_OR [[ARG1]], [[ARG2]]
181 ; CHECK-NEXT: $w0 = COPY [[RES]]
182 ; CHECK-NEXT: RET_ReallyLR implicit $w0
183 define i32 @ori32(i32 %arg1, i32 %arg2) {
184   %res = or i32 %arg1, %arg2
185   ret i32 %res
188 ; Tests for xor.
189 ; CHECK-LABEL: name: xori64
190 ; CHECK: [[ARG1:%[0-9]+]]:_(s64) = COPY $x0
191 ; CHECK-NEXT: [[ARG2:%[0-9]+]]:_(s64) = COPY $x1
192 ; CHECK-NEXT: [[RES:%[0-9]+]]:_(s64) = G_XOR [[ARG1]], [[ARG2]]
193 ; CHECK-NEXT: $x0 = COPY [[RES]]
194 ; CHECK-NEXT: RET_ReallyLR implicit $x0
195 define i64 @xori64(i64 %arg1, i64 %arg2) {
196   %res = xor i64 %arg1, %arg2
197   ret i64 %res
200 ; CHECK-LABEL: name: xori32
201 ; CHECK: [[ARG1:%[0-9]+]]:_(s32) = COPY $w0
202 ; CHECK-NEXT: [[ARG2:%[0-9]+]]:_(s32) = COPY $w1
203 ; CHECK-NEXT: [[RES:%[0-9]+]]:_(s32) = G_XOR [[ARG1]], [[ARG2]]
204 ; CHECK-NEXT: $w0 = COPY [[RES]]
205 ; CHECK-NEXT: RET_ReallyLR implicit $w0
206 define i32 @xori32(i32 %arg1, i32 %arg2) {
207   %res = xor i32 %arg1, %arg2
208   ret i32 %res
211 ; Tests for and.
212 ; CHECK-LABEL: name: andi64
213 ; CHECK: [[ARG1:%[0-9]+]]:_(s64) = COPY $x0
214 ; CHECK-NEXT: [[ARG2:%[0-9]+]]:_(s64) = COPY $x1
215 ; CHECK-NEXT: [[RES:%[0-9]+]]:_(s64) = G_AND [[ARG1]], [[ARG2]]
216 ; CHECK-NEXT: $x0 = COPY [[RES]]
217 ; CHECK-NEXT: RET_ReallyLR implicit $x0
218 define i64 @andi64(i64 %arg1, i64 %arg2) {
219   %res = and i64 %arg1, %arg2
220   ret i64 %res
223 ; CHECK-LABEL: name: andi32
224 ; CHECK: [[ARG1:%[0-9]+]]:_(s32) = COPY $w0
225 ; CHECK-NEXT: [[ARG2:%[0-9]+]]:_(s32) = COPY $w1
226 ; CHECK-NEXT: [[RES:%[0-9]+]]:_(s32) = G_AND [[ARG1]], [[ARG2]]
227 ; CHECK-NEXT: $w0 = COPY [[RES]]
228 ; CHECK-NEXT: RET_ReallyLR implicit $w0
229 define i32 @andi32(i32 %arg1, i32 %arg2) {
230   %res = and i32 %arg1, %arg2
231   ret i32 %res
234 ; Tests for sub.
235 ; CHECK-LABEL: name: subi64
236 ; CHECK: [[ARG1:%[0-9]+]]:_(s64) = COPY $x0
237 ; CHECK-NEXT: [[ARG2:%[0-9]+]]:_(s64) = COPY $x1
238 ; CHECK-NEXT: [[RES:%[0-9]+]]:_(s64) = G_SUB [[ARG1]], [[ARG2]]
239 ; CHECK-NEXT: $x0 = COPY [[RES]]
240 ; CHECK-NEXT: RET_ReallyLR implicit $x0
241 define i64 @subi64(i64 %arg1, i64 %arg2) {
242   %res = sub i64 %arg1, %arg2
243   ret i64 %res
246 ; CHECK-LABEL: name: subi32
247 ; CHECK: [[ARG1:%[0-9]+]]:_(s32) = COPY $w0
248 ; CHECK-NEXT: [[ARG2:%[0-9]+]]:_(s32) = COPY $w1
249 ; CHECK-NEXT: [[RES:%[0-9]+]]:_(s32) = G_SUB [[ARG1]], [[ARG2]]
250 ; CHECK-NEXT: $w0 = COPY [[RES]]
251 ; CHECK-NEXT: RET_ReallyLR implicit $w0
252 define i32 @subi32(i32 %arg1, i32 %arg2) {
253   %res = sub i32 %arg1, %arg2
254   ret i32 %res
257 ; CHECK-LABEL: name: ptrtoint
258 ; CHECK: [[ARG1:%[0-9]+]]:_(p0) = COPY $x0
259 ; CHECK: [[RES:%[0-9]+]]:_(s64) = G_PTRTOINT [[ARG1]]
260 ; CHECK: $x0 = COPY [[RES]]
261 ; CHECK: RET_ReallyLR implicit $x0
262 define i64 @ptrtoint(ptr %a) {
263   %val = ptrtoint ptr %a to i64
264   ret i64 %val
267 ; CHECK-LABEL: name: inttoptr
268 ; CHECK: [[ARG1:%[0-9]+]]:_(s64) = COPY $x0
269 ; CHECK: [[RES:%[0-9]+]]:_(p0) = G_INTTOPTR [[ARG1]]
270 ; CHECK: $x0 = COPY [[RES]]
271 ; CHECK: RET_ReallyLR implicit $x0
272 define ptr @inttoptr(i64 %a) {
273   %val = inttoptr i64 %a to ptr
274   ret ptr %val
277 ; CHECK-LABEL: name: trivial_bitcast
278 ; CHECK: [[ARG1:%[0-9]+]]:_(p0) = COPY $x0
279 ; CHECK: $x0 = COPY [[ARG1]]
280 ; CHECK: RET_ReallyLR implicit $x0
281 define ptr @trivial_bitcast(ptr %a) {
282   ret ptr %a
285 ; CHECK-LABEL: name: trivial_bitcast_with_copy
286 ; CHECK:     [[A:%[0-9]+]]:_(s64) = COPY $d0
287 ; CHECK:     G_BR %[[CAST:bb\.[0-9]+]]
289 ; CHECK: [[END:bb\.[0-9]+]].{{[a-zA-Z0-9.]+}}:
290 ; CHECK:     $x0 = COPY [[A]]
292 ; CHECK: [[CAST]].{{[a-zA-Z0-9.]+}}:
293 ; CHECK:     G_BR %[[END]]
294 define i64 @trivial_bitcast_with_copy(double %a) {
295   br label %cast
297 end:
298   ret i64 %val
300 cast:
301   %val = bitcast double %a to i64
302   br label %end
305 ; CHECK-LABEL: name: bitcast
306 ; CHECK: [[ARG1:%[0-9]+]]:_(s64) = COPY $x0
307 ; CHECK: [[RES1:%[0-9]+]]:_(<2 x s32>) = G_BITCAST [[ARG1]]
308 ; CHECK: [[RES2:%[0-9]+]]:_(s64) = G_BITCAST [[RES1]]
309 ; CHECK: $x0 = COPY [[RES2]]
310 ; CHECK: RET_ReallyLR implicit $x0
311 define i64 @bitcast(i64 %a) {
312   %res1 = bitcast i64 %a to <2 x i32>
313   %res2 = bitcast <2 x i32> %res1 to i64
314   ret i64 %res2
317 ; CHECK-LABEL: name: addrspacecast
318 ; CHECK: [[ARG1:%[0-9]+]]:_(p1) = COPY $x0
319 ; CHECK: [[RES1:%[0-9]+]]:_(p2) = G_ADDRSPACE_CAST [[ARG1]]
320 ; CHECK: [[RES2:%[0-9]+]]:_(p0) = G_ADDRSPACE_CAST [[RES1]]
321 ; CHECK: $x0 = COPY [[RES2]]
322 ; CHECK: RET_ReallyLR implicit $x0
323 define ptr @addrspacecast(ptr addrspace(1) %a) {
324   %res1 = addrspacecast ptr addrspace(1) %a to ptr addrspace(2)
325   %res2 = addrspacecast ptr addrspace(2) %res1 to ptr
326   ret ptr %res2
329 ; CHECK-LABEL: name: trunc
330 ; CHECK: [[ARG1:%[0-9]+]]:_(s64) = COPY $x0
331 ; CHECK: [[VEC:%[0-9]+]]:_(<4 x s32>) = G_LOAD
332 ; CHECK: [[RES1:%[0-9]+]]:_(s8) = G_TRUNC [[ARG1]]
333 ; CHECK: [[RES2:%[0-9]+]]:_(<4 x s16>) = G_TRUNC [[VEC]]
334 define void @trunc(i64 %a) {
335   %vecptr = alloca <4 x i32>
336   %vec = load <4 x i32>, ptr %vecptr
337   %res1 = trunc i64 %a to i8
338   %res2 = trunc <4 x i32> %vec to <4 x i16>
339   ret void
342 ; CHECK-LABEL: name: load
343 ; CHECK: [[ADDR:%[0-9]+]]:_(p0) = COPY $x0
344 ; CHECK: [[ADDR42:%[0-9]+]]:_(p42) = COPY $x1
345 ; CHECK: [[VAL1:%[0-9]+]]:_(s64) = G_LOAD [[ADDR]](p0) :: (load (s64) from %ir.addr, align 16)
346 ; CHECK: [[VAL2:%[0-9]+]]:_(s64) = G_LOAD [[ADDR42]](p42) :: (load (s64) from %ir.addr42, addrspace 42)
347 ; CHECK: [[SUM2:%.*]]:_(s64) = G_ADD [[VAL1]], [[VAL2]]
348 ; CHECK: [[VAL3:%[0-9]+]]:_(s64) = G_LOAD [[ADDR]](p0) :: (volatile load (s64) from %ir.addr)
349 ; CHECK: [[SUM3:%[0-9]+]]:_(s64) = G_ADD [[SUM2]], [[VAL3]]
350 ; CHECK: [[VAL4:%[0-9]+]]:_(s64) = G_LOAD [[ADDR]](p0) :: (load (s64) from %ir.addr, !range !0)
351 ; CHECK: [[SUM4:%[0-9]+]]:_(s64) = G_ADD [[SUM3]], [[VAL4]]
352 ; CHECK: $x0 = COPY [[SUM4]]
353 ; CHECK: RET_ReallyLR implicit $x0
354 define i64 @load(ptr %addr, ptr addrspace(42) %addr42) {
355   %val1 = load i64, ptr %addr, align 16
357   %val2 = load i64, ptr addrspace(42) %addr42
358   %sum2 = add i64 %val1, %val2
360   %val3 = load volatile i64, ptr %addr
361   %sum3 = add i64 %sum2, %val3
363   %val4 = load i64, ptr %addr, !range !0
364   %sum4 = add i64 %sum3, %val4
365   ret i64 %sum4
368 ; CHECK-LABEL: name: store
369 ; CHECK: [[ADDR:%[0-9]+]]:_(p0) = COPY $x0
370 ; CHECK: [[ADDR42:%[0-9]+]]:_(p42) = COPY $x1
371 ; CHECK: [[VAL1:%[0-9]+]]:_(s64) = COPY $x2
372 ; CHECK: [[VAL2:%[0-9]+]]:_(s64) = COPY $x3
373 ; CHECK: G_STORE [[VAL1]](s64), [[ADDR]](p0) :: (store (s64) into %ir.addr, align 16)
374 ; CHECK: G_STORE [[VAL2]](s64), [[ADDR42]](p42) :: (store (s64) into %ir.addr42, addrspace 42)
375 ; CHECK: G_STORE [[VAL1]](s64), [[ADDR]](p0) :: (volatile store (s64) into %ir.addr)
376 ; CHECK: RET_ReallyLR
377 define void @store(ptr %addr, ptr addrspace(42) %addr42, i64 %val1, i64 %val2) {
378   store i64 %val1, ptr %addr, align 16
379   store i64 %val2, ptr addrspace(42) %addr42
380   store volatile i64 %val1, ptr %addr
381   %sum = add i64 %val1, %val2
382   ret void
385 ; CHECK-LABEL: name: intrinsics
386 ; CHECK: [[CUR:%[0-9]+]]:_(s32) = COPY $w0
387 ; CHECK: [[BITS:%[0-9]+]]:_(s32) = COPY $w1
388 ; CHECK: [[PTR:%[0-9]+]]:_(p0) = G_INTRINSIC intrinsic(@llvm.returnaddress), 0
389 ; CHECK: [[PTR_VEC:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.0.ptr.vec
390 ; CHECK: [[VEC:%[0-9]+]]:_(<8 x s8>) = G_LOAD [[PTR_VEC]]
391 ; CHECK: G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aarch64.neon.st2), [[VEC]](<8 x s8>), [[VEC]](<8 x s8>), [[PTR]](p0)
392 ; CHECK: RET_ReallyLR
393 declare ptr @llvm.returnaddress(i32)
394 declare void @llvm.aarch64.neon.st2.v8i8.p0(<8 x i8>, <8 x i8>, ptr)
395 declare { <8 x i8>, <8 x i8> } @llvm.aarch64.neon.ld2.v8i8.p0(ptr)
396 define void @intrinsics(i32 %cur, i32 %bits) {
397   %ptr = call ptr @llvm.returnaddress(i32 0)
398   %ptr.vec = alloca <8 x i8>
399   %vec = load <8 x i8>, ptr %ptr.vec
400   call void @llvm.aarch64.neon.st2.v8i8.p0(<8 x i8> %vec, <8 x i8> %vec, ptr %ptr)
401   ret void
404 ; CHECK-LABEL: name: test_phi
405 ; CHECK:     G_BRCOND {{%.*}}, %[[TRUE:bb\.[0-9]+]]
406 ; CHECK:     G_BR %[[FALSE:bb\.[0-9]+]]
408 ; CHECK: [[TRUE]].{{[a-zA-Z0-9.]+}}:
409 ; CHECK:     [[RES1:%[0-9]+]]:_(s32) = G_LOAD
411 ; CHECK: [[FALSE]].{{[a-zA-Z0-9.]+}}:
412 ; CHECK:     [[RES2:%[0-9]+]]:_(s32) = G_LOAD
414 ; CHECK:     [[RES:%[0-9]+]]:_(s32) = G_PHI [[RES1]](s32), %[[TRUE]], [[RES2]](s32), %[[FALSE]]
415 ; CHECK:     $w0 = COPY [[RES]]
416 define i32 @test_phi(ptr %addr1, ptr %addr2, i1 %tst) {
417   br i1 %tst, label %true, label %false
419 true:
420   %res1 = load i32, ptr %addr1
421   br label %end
423 false:
424   %res2 = load i32, ptr %addr2
425   br label %end
427 end:
428   %res = phi i32 [%res1, %true], [%res2, %false]
429   ret i32 %res
432 ; CHECK-LABEL: name: unreachable
433 ; CHECK: G_ADD
434 ; CHECK-NEXT: {{^$}}
435 ; CHECK-NEXT: ...
436 define void @unreachable(i32 %a) {
437   %sum = add i32 %a, %a
438   unreachable
441   ; It's important that constants are after argument passing, but before the
442   ; rest of the entry block.
443 ; CHECK-LABEL: name: constant_int
444 ; CHECK: [[IN:%[0-9]+]]:_(s32) = COPY $w0
445 ; CHECK: [[ONE:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
447 ; CHECK: bb.{{[0-9]+}}.{{[a-zA-Z0-9.]+}}:
448 ; CHECK: [[SUM1:%[0-9]+]]:_(s32) = G_ADD [[IN]], [[ONE]]
449 ; CHECK: [[SUM2:%[0-9]+]]:_(s32) = G_ADD [[IN]], [[ONE]]
450 ; CHECK: [[RES:%[0-9]+]]:_(s32) = G_ADD [[SUM1]], [[SUM2]]
451 ; CHECK: $w0 = COPY [[RES]]
453 define i32 @constant_int(i32 %in) {
454   br label %next
456 next:
457   %sum1 = add i32 %in, 1
458   %sum2 = add i32 %in, 1
459   %res = add i32 %sum1, %sum2
460   ret i32 %res
463 ; CHECK-LABEL: name: constant_int_start
464 ; CHECK: [[TWO:%[0-9]+]]:_(s32) = G_CONSTANT i32 2
465 ; CHECK: [[ANSWER:%[0-9]+]]:_(s32) = G_CONSTANT i32 42
466 ; CHECK: [[RES:%[0-9]+]]:_(s32) = G_CONSTANT i32 44
467 define i32 @constant_int_start() {
468   %res = add i32 2, 42
469   ret i32 %res
472 ; CHECK-LABEL: name: test_undef
473 ; CHECK: [[UNDEF:%[0-9]+]]:_(s32) = G_IMPLICIT_DEF
474 ; CHECK: $w0 = COPY [[UNDEF]]
475 define i32 @test_undef() {
476   ret i32 undef
479 ; CHECK-LABEL: name: test_constant_inttoptr
480 ; CHECK: [[ONE:%[0-9]+]]:_(s64) = G_CONSTANT i64 1
481 ; CHECK: [[PTR:%[0-9]+]]:_(p0) = G_INTTOPTR [[ONE]]
482 ; CHECK: $x0 = COPY [[PTR]]
483 define ptr @test_constant_inttoptr() {
484   ret ptr inttoptr(i64 1 to ptr)
487   ; This failed purely because the Constant -> VReg map was kept across
488   ; functions, so reuse the "i64 1" from above.
489 ; CHECK-LABEL: name: test_reused_constant
490 ; CHECK: [[ONE:%[0-9]+]]:_(s64) = G_CONSTANT i64 1
491 ; CHECK: $x0 = COPY [[ONE]]
492 define i64 @test_reused_constant() {
493   ret i64 1
496 ; CHECK-LABEL: name: test_sext
497 ; CHECK: [[IN:%[0-9]+]]:_(s32) = COPY $w0
498 ; CHECK: [[RES:%[0-9]+]]:_(s64) = G_SEXT [[IN]]
499 ; CHECK: $x0 = COPY [[RES]]
500 define i64 @test_sext(i32 %in) {
501   %res = sext i32 %in to i64
502   ret i64 %res
505 ; CHECK-LABEL: name: test_zext
506 ; CHECK: [[IN:%[0-9]+]]:_(s32) = COPY $w0
507 ; CHECK: [[RES:%[0-9]+]]:_(s64) = G_ZEXT [[IN]]
508 ; CHECK: $x0 = COPY [[RES]]
509 define i64 @test_zext(i32 %in) {
510   %res = zext i32 %in to i64
511   ret i64 %res
514 ; CHECK-LABEL: name: test_shl
515 ; CHECK: [[ARG1:%[0-9]+]]:_(s32) = COPY $w0
516 ; CHECK-NEXT: [[ARG2:%[0-9]+]]:_(s32) = COPY $w1
517 ; CHECK-NEXT: [[RES:%[0-9]+]]:_(s32) = G_SHL [[ARG1]], [[ARG2]]
518 ; CHECK-NEXT: $w0 = COPY [[RES]]
519 ; CHECK-NEXT: RET_ReallyLR implicit $w0
520 define i32 @test_shl(i32 %arg1, i32 %arg2) {
521   %res = shl i32 %arg1, %arg2
522   ret i32 %res
526 ; CHECK-LABEL: name: test_lshr
527 ; CHECK: [[ARG1:%[0-9]+]]:_(s32) = COPY $w0
528 ; CHECK-NEXT: [[ARG2:%[0-9]+]]:_(s32) = COPY $w1
529 ; CHECK-NEXT: [[RES:%[0-9]+]]:_(s32) = G_LSHR [[ARG1]], [[ARG2]]
530 ; CHECK-NEXT: $w0 = COPY [[RES]]
531 ; CHECK-NEXT: RET_ReallyLR implicit $w0
532 define i32 @test_lshr(i32 %arg1, i32 %arg2) {
533   %res = lshr i32 %arg1, %arg2
534   ret i32 %res
537 ; CHECK-LABEL: name: test_ashr
538 ; CHECK: [[ARG1:%[0-9]+]]:_(s32) = COPY $w0
539 ; CHECK-NEXT: [[ARG2:%[0-9]+]]:_(s32) = COPY $w1
540 ; CHECK-NEXT: [[RES:%[0-9]+]]:_(s32) = G_ASHR [[ARG1]], [[ARG2]]
541 ; CHECK-NEXT: $w0 = COPY [[RES]]
542 ; CHECK-NEXT: RET_ReallyLR implicit $w0
543 define i32 @test_ashr(i32 %arg1, i32 %arg2) {
544   %res = ashr i32 %arg1, %arg2
545   ret i32 %res
548 ; CHECK-LABEL: name: test_sdiv
549 ; CHECK: [[ARG1:%[0-9]+]]:_(s32) = COPY $w0
550 ; CHECK-NEXT: [[ARG2:%[0-9]+]]:_(s32) = COPY $w1
551 ; CHECK-NEXT: [[RES:%[0-9]+]]:_(s32) = G_SDIV [[ARG1]], [[ARG2]]
552 ; CHECK-NEXT: $w0 = COPY [[RES]]
553 ; CHECK-NEXT: RET_ReallyLR implicit $w0
554 define i32 @test_sdiv(i32 %arg1, i32 %arg2) {
555   %res = sdiv i32 %arg1, %arg2
556   ret i32 %res
559 ; CHECK-LABEL: name: test_udiv
560 ; CHECK: [[ARG1:%[0-9]+]]:_(s32) = COPY $w0
561 ; CHECK-NEXT: [[ARG2:%[0-9]+]]:_(s32) = COPY $w1
562 ; CHECK-NEXT: [[RES:%[0-9]+]]:_(s32) = G_UDIV [[ARG1]], [[ARG2]]
563 ; CHECK-NEXT: $w0 = COPY [[RES]]
564 ; CHECK-NEXT: RET_ReallyLR implicit $w0
565 define i32 @test_udiv(i32 %arg1, i32 %arg2) {
566   %res = udiv i32 %arg1, %arg2
567   ret i32 %res
570 ; CHECK-LABEL: name: test_srem
571 ; CHECK: [[ARG1:%[0-9]+]]:_(s32) = COPY $w0
572 ; CHECK-NEXT: [[ARG2:%[0-9]+]]:_(s32) = COPY $w1
573 ; CHECK-NEXT: [[RES:%[0-9]+]]:_(s32) = G_SREM [[ARG1]], [[ARG2]]
574 ; CHECK-NEXT: $w0 = COPY [[RES]]
575 ; CHECK-NEXT: RET_ReallyLR implicit $w0
576 define i32 @test_srem(i32 %arg1, i32 %arg2) {
577   %res = srem i32 %arg1, %arg2
578   ret i32 %res
581 ; CHECK-LABEL: name: test_urem
582 ; CHECK: [[ARG1:%[0-9]+]]:_(s32) = COPY $w0
583 ; CHECK-NEXT: [[ARG2:%[0-9]+]]:_(s32) = COPY $w1
584 ; CHECK-NEXT: [[RES:%[0-9]+]]:_(s32) = G_UREM [[ARG1]], [[ARG2]]
585 ; CHECK-NEXT: $w0 = COPY [[RES]]
586 ; CHECK-NEXT: RET_ReallyLR implicit $w0
587 define i32 @test_urem(i32 %arg1, i32 %arg2) {
588   %res = urem i32 %arg1, %arg2
589   ret i32 %res
592 ; CHECK-LABEL: name: test_constant_null
593 ; CHECK: [[NULL:%[0-9]+]]:_(p0) = G_CONSTANT i64 0
594 ; CHECK: $x0 = COPY [[NULL]]
595 define ptr @test_constant_null() {
596   ret ptr null
599 ; CHECK-LABEL: name: test_struct_memops
600 ; CHECK: [[ADDR:%[0-9]+]]:_(p0) = COPY $x0
601 ; CHECK: [[VAL1:%[0-9]+]]:_(s8) = G_LOAD %0(p0) :: (load (s8) from %ir.addr, align 4)
602 ; CHECK: [[CST1:%[0-9]+]]:_(s64) = G_CONSTANT i64 4
603 ; CHECK: [[GEP1:%[0-9]+]]:_(p0) = G_PTR_ADD [[ADDR]], [[CST1]](s64)
604 ; CHECK: [[VAL2:%[0-9]+]]:_(s32) = G_LOAD [[GEP1]](p0) :: (load (s32) from %ir.addr + 4)
605 ; CHECK: G_STORE [[VAL1]](s8), [[ADDR]](p0) :: (store (s8) into %ir.addr, align 4)
606 ; CHECK: [[GEP2:%[0-9]+]]:_(p0) = G_PTR_ADD [[ADDR]], [[CST1]](s64)
607 ; CHECK: G_STORE [[VAL2]](s32), [[GEP2]](p0) :: (store (s32) into %ir.addr + 4)
608 define void @test_struct_memops(ptr %addr) {
609   %val = load { i8, i32 }, ptr %addr
610   store { i8, i32 } %val, ptr %addr
611   ret void
614 ; CHECK-LABEL: name: test_i1_memops
615 ; CHECK: [[ADDR:%[0-9]+]]:_(p0) = COPY $x0
616 ; CHECK: [[VAL:%[0-9]+]]:_(s1) = G_LOAD [[ADDR]](p0) :: (load (s1) from  %ir.addr)
617 ; CHECK: G_STORE [[VAL]](s1), [[ADDR]](p0) :: (store (s1) into  %ir.addr)
618 define void @test_i1_memops(ptr %addr) {
619   %val = load i1, ptr %addr
620   store i1 %val, ptr %addr
621   ret void
624 ; CHECK-LABEL: name: int_comparison
625 ; CHECK: [[LHS:%[0-9]+]]:_(s32) = COPY $w0
626 ; CHECK: [[RHS:%[0-9]+]]:_(s32) = COPY $w1
627 ; CHECK: [[ADDR:%[0-9]+]]:_(p0) = COPY $x2
628 ; CHECK: [[TST:%[0-9]+]]:_(s1) = G_ICMP intpred(ne), [[LHS]](s32), [[RHS]]
629 ; CHECK: G_STORE [[TST]](s1), [[ADDR]](p0)
630 define void @int_comparison(i32 %a, i32 %b, ptr %addr) {
631   %res = icmp ne i32 %a, %b
632   store i1 %res, ptr %addr
633   ret void
636 ; CHECK-LABEL: name: ptr_comparison
637 ; CHECK: [[LHS:%[0-9]+]]:_(p0) = COPY $x0
638 ; CHECK: [[RHS:%[0-9]+]]:_(p0) = COPY $x1
639 ; CHECK: [[ADDR:%[0-9]+]]:_(p0) = COPY $x2
640 ; CHECK: [[TST:%[0-9]+]]:_(s1) = G_ICMP intpred(eq), [[LHS]](p0), [[RHS]]
641 ; CHECK: G_STORE [[TST]](s1), [[ADDR]](p0)
642 define void @ptr_comparison(ptr %a, ptr %b, ptr %addr) {
643   %res = icmp eq ptr %a, %b
644   store i1 %res, ptr %addr
645   ret void
648 ; CHECK-LABEL: name: test_fadd
649 ; CHECK: [[ARG1:%[0-9]+]]:_(s32) = COPY $s0
650 ; CHECK-NEXT: [[ARG2:%[0-9]+]]:_(s32) = COPY $s1
651 ; CHECK-NEXT: [[RES:%[0-9]+]]:_(s32) = G_FADD [[ARG1]], [[ARG2]]
652 ; CHECK-NEXT: $s0 = COPY [[RES]]
653 ; CHECK-NEXT: RET_ReallyLR implicit $s0
654 define float @test_fadd(float %arg1, float %arg2) {
655   %res = fadd float %arg1, %arg2
656   ret float %res
659 ; CHECK-LABEL: name: test_fsub
660 ; CHECK: [[ARG1:%[0-9]+]]:_(s32) = COPY $s0
661 ; CHECK-NEXT: [[ARG2:%[0-9]+]]:_(s32) = COPY $s1
662 ; CHECK-NEXT: [[RES:%[0-9]+]]:_(s32) = G_FSUB [[ARG1]], [[ARG2]]
663 ; CHECK-NEXT: $s0 = COPY [[RES]]
664 ; CHECK-NEXT: RET_ReallyLR implicit $s0
665 define float @test_fsub(float %arg1, float %arg2) {
666   %res = fsub float %arg1, %arg2
667   ret float %res
670 ; CHECK-LABEL: name: test_fmul
671 ; CHECK: [[ARG1:%[0-9]+]]:_(s32) = COPY $s0
672 ; CHECK-NEXT: [[ARG2:%[0-9]+]]:_(s32) = COPY $s1
673 ; CHECK-NEXT: [[RES:%[0-9]+]]:_(s32) = G_FMUL [[ARG1]], [[ARG2]]
674 ; CHECK-NEXT: $s0 = COPY [[RES]]
675 ; CHECK-NEXT: RET_ReallyLR implicit $s0
676 define float @test_fmul(float %arg1, float %arg2) {
677   %res = fmul float %arg1, %arg2
678   ret float %res
681 ; CHECK-LABEL: name: test_fdiv
682 ; CHECK: [[ARG1:%[0-9]+]]:_(s32) = COPY $s0
683 ; CHECK-NEXT: [[ARG2:%[0-9]+]]:_(s32) = COPY $s1
684 ; CHECK-NEXT: [[RES:%[0-9]+]]:_(s32) = G_FDIV [[ARG1]], [[ARG2]]
685 ; CHECK-NEXT: $s0 = COPY [[RES]]
686 ; CHECK-NEXT: RET_ReallyLR implicit $s0
687 define float @test_fdiv(float %arg1, float %arg2) {
688   %res = fdiv float %arg1, %arg2
689   ret float %res
692 ; CHECK-LABEL: name: test_frem
693 ; CHECK: [[ARG1:%[0-9]+]]:_(s32) = COPY $s0
694 ; CHECK-NEXT: [[ARG2:%[0-9]+]]:_(s32) = COPY $s1
695 ; CHECK-NEXT: [[RES:%[0-9]+]]:_(s32) = G_FREM [[ARG1]], [[ARG2]]
696 ; CHECK-NEXT: $s0 = COPY [[RES]]
697 ; CHECK-NEXT: RET_ReallyLR implicit $s0
698 define float @test_frem(float %arg1, float %arg2) {
699   %res = frem float %arg1, %arg2
700   ret float %res
703 ; CHECK-LABEL: name: test_sadd_overflow
704 ; CHECK: [[LHS:%[0-9]+]]:_(s32) = COPY $w0
705 ; CHECK: [[RHS:%[0-9]+]]:_(s32) = COPY $w1
706 ; CHECK: [[ADDR:%[0-9]+]]:_(p0) = COPY $x2
707 ; CHECK: [[VAL:%[0-9]+]]:_(s32), [[OVERFLOW:%[0-9]+]]:_(s1) = G_SADDO [[LHS]], [[RHS]]
708 ; CHECK: G_STORE [[VAL]](s32), [[ADDR]](p0) :: (store (s32) into %ir.addr)
709 ; CHECK: [[CST:%[0-9]+]]:_(s64) = G_CONSTANT i64 4
710 ; CHECK: [[GEP:%[0-9]+]]:_(p0) = G_PTR_ADD [[ADDR]], [[CST]](s64)
711 ; CHECK: G_STORE [[OVERFLOW]](s1), [[GEP]](p0) :: (store (s1) into %ir.addr + 4, align 4)
712 declare { i32, i1 } @llvm.sadd.with.overflow.i32(i32, i32)
713 define void @test_sadd_overflow(i32 %lhs, i32 %rhs, ptr %addr) {
714   %res = call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 %lhs, i32 %rhs)
715   store { i32, i1 } %res, ptr %addr
716   ret void
719 ; CHECK-LABEL: name: test_uadd_overflow
720 ; CHECK: [[LHS:%[0-9]+]]:_(s32) = COPY $w0
721 ; CHECK: [[RHS:%[0-9]+]]:_(s32) = COPY $w1
722 ; CHECK: [[ADDR:%[0-9]+]]:_(p0) = COPY $x2
723 ; CHECK: [[VAL:%[0-9]+]]:_(s32), [[OVERFLOW:%[0-9]+]]:_(s1) = G_UADDO [[LHS]], [[RHS]]
724 ; CHECK: G_STORE [[VAL]](s32), [[ADDR]](p0) :: (store (s32) into %ir.addr)
725 ; CHECK: [[CST:%[0-9]+]]:_(s64) = G_CONSTANT i64 4
726 ; CHECK: [[GEP:%[0-9]+]]:_(p0) = G_PTR_ADD [[ADDR]], [[CST]](s64)
727 ; CHECK: G_STORE [[OVERFLOW]](s1), [[GEP]](p0) :: (store (s1) into %ir.addr + 4, align 4)
728 declare { i32, i1 } @llvm.uadd.with.overflow.i32(i32, i32)
729 define void @test_uadd_overflow(i32 %lhs, i32 %rhs, ptr %addr) {
730   %res = call { i32, i1 } @llvm.uadd.with.overflow.i32(i32 %lhs, i32 %rhs)
731   store { i32, i1 } %res, ptr %addr
732   ret void
735 ; CHECK-LABEL: name: test_ssub_overflow
736 ; CHECK: [[LHS:%[0-9]+]]:_(s32) = COPY $w0
737 ; CHECK: [[RHS:%[0-9]+]]:_(s32) = COPY $w1
738 ; CHECK: [[ADDR:%[0-9]+]]:_(p0) = COPY $x2
739 ; CHECK: [[VAL:%[0-9]+]]:_(s32), [[OVERFLOW:%[0-9]+]]:_(s1) = G_SSUBO [[LHS]], [[RHS]]
740 ; CHECK: G_STORE [[VAL]](s32), [[ADDR]](p0) :: (store (s32) into %ir.subr)
741 ; CHECK: [[CST:%[0-9]+]]:_(s64) = G_CONSTANT i64 4
742 ; CHECK: [[GEP:%[0-9]+]]:_(p0) = G_PTR_ADD [[ADDR]], [[CST]](s64)
743 ; CHECK: G_STORE [[OVERFLOW]](s1), [[GEP]](p0) :: (store (s1) into %ir.subr + 4, align 4)
744 declare { i32, i1 } @llvm.ssub.with.overflow.i32(i32, i32)
745 define void @test_ssub_overflow(i32 %lhs, i32 %rhs, ptr %subr) {
746   %res = call { i32, i1 } @llvm.ssub.with.overflow.i32(i32 %lhs, i32 %rhs)
747   store { i32, i1 } %res, ptr %subr
748   ret void
751 ; CHECK-LABEL: name: test_usub_overflow
752 ; CHECK: [[LHS:%[0-9]+]]:_(s32) = COPY $w0
753 ; CHECK: [[RHS:%[0-9]+]]:_(s32) = COPY $w1
754 ; CHECK: [[ADDR:%[0-9]+]]:_(p0) = COPY $x2
755 ; CHECK: [[VAL:%[0-9]+]]:_(s32), [[OVERFLOW:%[0-9]+]]:_(s1) = G_USUBO [[LHS]], [[RHS]]
756 ; CHECK: G_STORE [[VAL]](s32), [[ADDR]](p0) :: (store (s32) into %ir.subr)
757 ; CHECK: [[CST:%[0-9]+]]:_(s64) = G_CONSTANT i64 4
758 ; CHECK: [[GEP:%[0-9]+]]:_(p0) = G_PTR_ADD [[ADDR]], [[CST]](s64)
759 ; CHECK: G_STORE [[OVERFLOW]](s1), [[GEP]](p0) :: (store (s1) into %ir.subr + 4, align 4)
760 declare { i32, i1 } @llvm.usub.with.overflow.i32(i32, i32)
761 define void @test_usub_overflow(i32 %lhs, i32 %rhs, ptr %subr) {
762   %res = call { i32, i1 } @llvm.usub.with.overflow.i32(i32 %lhs, i32 %rhs)
763   store { i32, i1 } %res, ptr %subr
764   ret void
767 ; CHECK-LABEL: name: test_smul_overflow
768 ; CHECK: [[LHS:%[0-9]+]]:_(s32) = COPY $w0
769 ; CHECK: [[RHS:%[0-9]+]]:_(s32) = COPY $w1
770 ; CHECK: [[ADDR:%[0-9]+]]:_(p0) = COPY $x2
771 ; CHECK: [[VAL:%[0-9]+]]:_(s32), [[OVERFLOW:%[0-9]+]]:_(s1) = G_SMULO [[LHS]], [[RHS]]
772 ; CHECK: G_STORE [[VAL]](s32), [[ADDR]](p0) :: (store (s32) into %ir.addr)
773 ; CHECK: [[CST:%[0-9]+]]:_(s64) = G_CONSTANT i64 4
774 ; CHECK: [[GEP:%[0-9]+]]:_(p0) = G_PTR_ADD [[ADDR]], [[CST]](s64)
775 ; CHECK: G_STORE [[OVERFLOW]](s1), [[GEP]](p0) :: (store (s1) into %ir.addr + 4, align 4)
776 declare { i32, i1 } @llvm.smul.with.overflow.i32(i32, i32)
777 define void @test_smul_overflow(i32 %lhs, i32 %rhs, ptr %addr) {
778   %res = call { i32, i1 } @llvm.smul.with.overflow.i32(i32 %lhs, i32 %rhs)
779   store { i32, i1 } %res, ptr %addr
780   ret void
783 ; CHECK-LABEL: name: test_umul_overflow
784 ; CHECK: [[LHS:%[0-9]+]]:_(s32) = COPY $w0
785 ; CHECK: [[RHS:%[0-9]+]]:_(s32) = COPY $w1
786 ; CHECK: [[ADDR:%[0-9]+]]:_(p0) = COPY $x2
787 ; CHECK: [[VAL:%[0-9]+]]:_(s32), [[OVERFLOW:%[0-9]+]]:_(s1) = G_UMULO [[LHS]], [[RHS]]
788 ; CHECK: G_STORE [[VAL]](s32), [[ADDR]](p0) :: (store (s32) into %ir.addr)
789 ; CHECK: [[CST:%[0-9]+]]:_(s64) = G_CONSTANT i64 4
790 ; CHECK: [[GEP:%[0-9]+]]:_(p0) = G_PTR_ADD [[ADDR]], [[CST]](s64)
791 ; CHECK: G_STORE [[OVERFLOW]](s1), [[GEP]](p0) :: (store (s1) into %ir.addr + 4, align 4)
792 declare { i32, i1 } @llvm.umul.with.overflow.i32(i32, i32)
793 define void @test_umul_overflow(i32 %lhs, i32 %rhs, ptr %addr) {
794   %res = call { i32, i1 } @llvm.umul.with.overflow.i32(i32 %lhs, i32 %rhs)
795   store { i32, i1 } %res, ptr %addr
796   ret void
799 ; CHECK-LABEL: name: test_extractvalue
800 ; CHECK: %0:_(p0) = COPY $x0
801 ; CHECK: [[LD1:%[0-9]+]]:_(s8) = G_LOAD %0(p0) :: (load (s8) from %ir.addr, align 4)
802 ; CHECK: [[CST1:%[0-9]+]]:_(s64) = G_CONSTANT i64 4
803 ; CHECK: [[GEP1:%[0-9]+]]:_(p0) = G_PTR_ADD %0, [[CST1]](s64)
804 ; CHECK: [[LD2:%[0-9]+]]:_(s8) = G_LOAD [[GEP1]](p0) :: (load (s8) from %ir.addr + 4, align 4)
805 ; CHECK: [[CST2:%[0-9]+]]:_(s64) = G_CONSTANT i64 8
806 ; CHECK: [[GEP2:%[0-9]+]]:_(p0) = G_PTR_ADD %0, [[CST2]](s64)
807 ; CHECK: [[LD3:%[0-9]+]]:_(s32) = G_LOAD [[GEP2]](p0) :: (load (s32) from %ir.addr + 8)
808 ; CHECK: [[CST3:%[0-9]+]]:_(s64) = G_CONSTANT i64 12
809 ; CHECK: [[GEP3:%[0-9]+]]:_(p0) = G_PTR_ADD %0, [[CST3]](s64)
810 ; CHECK: [[LD4:%[0-9]+]]:_(s32) = G_LOAD [[GEP3]](p0) :: (load (s32) from %ir.addr + 12)
811 ; CHECK: $w0 = COPY [[LD3]](s32)
812 %struct.nested = type {i8, { i8, i32 }, i32}
813 define i32 @test_extractvalue(ptr %addr) {
814   %struct = load %struct.nested, ptr %addr
815   %res = extractvalue %struct.nested %struct, 1, 1
816   ret i32 %res
819 ; CHECK-LABEL: name: test_extractvalue_agg
820 ; CHECK: %0:_(p0) = COPY $x0
821 ; CHECK: %1:_(p0) = COPY $x1
822 ; CHECK: [[LD1:%[0-9]+]]:_(s8) = G_LOAD %0(p0) :: (load (s8) from %ir.addr, align 4)
823 ; CHECK: [[CST1:%[0-9]+]]:_(s64) = G_CONSTANT i64 4
824 ; CHECK: [[GEP1:%[0-9]+]]:_(p0) = G_PTR_ADD %0, [[CST1]](s64)
825 ; CHECK: [[LD2:%[0-9]+]]:_(s8) = G_LOAD [[GEP1]](p0) :: (load (s8) from %ir.addr + 4, align 4)
826 ; CHECK: [[CST2:%[0-9]+]]:_(s64) = G_CONSTANT i64 8
827 ; CHECK: [[GEP2:%[0-9]+]]:_(p0) = G_PTR_ADD %0, [[CST2]](s64)
828 ; CHECK: [[LD3:%[0-9]+]]:_(s32) = G_LOAD [[GEP2]](p0) :: (load (s32) from %ir.addr + 8)
829 ; CHECK: [[CST3:%[0-9]+]]:_(s64) = G_CONSTANT i64 12
830 ; CHECK: [[GEP3:%[0-9]+]]:_(p0) = G_PTR_ADD %0, [[CST3]](s64)
831 ; CHECK: [[LD4:%[0-9]+]]:_(s32) = G_LOAD [[GEP3]](p0) :: (load (s32) from %ir.addr + 12)
832 ; CHECK: G_STORE [[LD2]](s8), %1(p0) :: (store (s8) into %ir.addr2, align 4)
833 ; CHECK: [[GEP4:%[0-9]+]]:_(p0) = G_PTR_ADD %1, [[CST1]](s64)
834 ; CHECK: G_STORE [[LD3]](s32), [[GEP4]](p0) :: (store (s32) into %ir.addr2 + 4)
835 define void @test_extractvalue_agg(ptr %addr, ptr %addr2) {
836   %struct = load %struct.nested, ptr %addr
837   %res = extractvalue %struct.nested %struct, 1
838   store {i8, i32} %res, ptr %addr2
839   ret void
842 ; CHECK-LABEL: name: test_trivial_extract_ptr
843 ; CHECK: [[STRUCT:%[0-9]+]]:_(p0) = COPY $x0
844 ; CHECK: [[VAL32:%[0-9]+]]:_(s32) = COPY $w1
845 ; CHECK: [[VAL:%[0-9]+]]:_(s8) = G_TRUNC [[VAL32]]
846 ; CHECK: G_STORE [[VAL]](s8), [[STRUCT]](p0)
847 define void @test_trivial_extract_ptr([1 x ptr] %s, i8 %val) {
848   %addr = extractvalue [1 x ptr] %s, 0
849   store i8 %val, ptr %addr
850   ret void
853 ; CHECK-LABEL: name: test_insertvalue
854 ; CHECK: %0:_(p0) = COPY $x0
855 ; CHECK: %1:_(s32) = COPY $w1
856 ; CHECK: [[LD1:%[0-9]+]]:_(s8) = G_LOAD %0(p0) :: (load (s8) from %ir.addr, align 4)
857 ; CHECK: [[CST1:%[0-9]+]]:_(s64) = G_CONSTANT i64 4
858 ; CHECK: [[GEP1:%[0-9]+]]:_(p0) = G_PTR_ADD %0, [[CST1]](s64)
859 ; CHECK: [[LD2:%[0-9]+]]:_(s8) = G_LOAD [[GEP1]](p0) :: (load (s8) from %ir.addr + 4, align 4)
860 ; CHECK: [[CST2:%[0-9]+]]:_(s64) = G_CONSTANT i64 8
861 ; CHECK: [[GEP2:%[0-9]+]]:_(p0) = G_PTR_ADD %0, [[CST2]](s64)
862 ; CHECK: [[LD3:%[0-9]+]]:_(s32) = G_LOAD [[GEP2]](p0) :: (load (s32) from %ir.addr + 8)
863 ; CHECK: [[CST3:%[0-9]+]]:_(s64) = G_CONSTANT i64 12
864 ; CHECK: [[GEP3:%[0-9]+]]:_(p0) = G_PTR_ADD %0, [[CST3]](s64)
865 ; CHECK: [[LD4:%[0-9]+]]:_(s32) = G_LOAD [[GEP3]](p0) :: (load (s32) from %ir.addr + 12)
866 ; CHECK: G_STORE [[LD1]](s8), %0(p0) :: (store (s8) into %ir.addr, align 4)
867 ; CHECK: [[GEP4:%[0-9]+]]:_(p0) = G_PTR_ADD %0, [[CST1]](s64)
868 ; CHECK: G_STORE [[LD2]](s8), [[GEP4]](p0) :: (store (s8) into %ir.addr + 4, align 4)
869 ; CHECK: [[GEP5:%[0-9]+]]:_(p0) = G_PTR_ADD %0, [[CST2]](s64)
870 ; CHECK: G_STORE %1(s32), [[GEP5]](p0) :: (store (s32) into %ir.addr + 8)
871 ; CHECK: [[GEP6:%[0-9]+]]:_(p0) = G_PTR_ADD %0, [[CST3]](s64)
872 ; CHECK: G_STORE [[LD4]](s32), [[GEP6]](p0) :: (store (s32) into %ir.addr + 12)
873 define void @test_insertvalue(ptr %addr, i32 %val) {
874   %struct = load %struct.nested, ptr %addr
875   %newstruct = insertvalue %struct.nested %struct, i32 %val, 1, 1
876   store %struct.nested %newstruct, ptr %addr
877   ret void
880 define [1 x i64] @test_trivial_insert([1 x i64] %s, i64 %val) {
881 ; CHECK-LABEL: name: test_trivial_insert
882 ; CHECK: [[STRUCT:%[0-9]+]]:_(s64) = COPY $x0
883 ; CHECK: [[VAL:%[0-9]+]]:_(s64) = COPY $x1
884 ; CHECK: $x0 = COPY [[VAL]]
885   %res = insertvalue [1 x i64] %s, i64 %val, 0
886   ret [1 x i64] %res
889 define [1 x ptr] @test_trivial_insert_ptr([1 x ptr] %s, ptr %val) {
890 ; CHECK-LABEL: name: test_trivial_insert_ptr
891 ; CHECK: [[STRUCT:%[0-9]+]]:_(p0) = COPY $x0
892 ; CHECK: [[VAL:%[0-9]+]]:_(p0) = COPY $x1
893 ; CHECK: $x0 = COPY [[VAL]]
894   %res = insertvalue [1 x ptr] %s, ptr %val, 0
895   ret [1 x ptr] %res
898 ; CHECK-LABEL: name: test_insertvalue_agg
899 ; CHECK: %0:_(p0) = COPY $x0
900 ; CHECK: %1:_(p0) = COPY $x1
901 ; CHECK: [[LD1:%[0-9]+]]:_(s8) = G_LOAD %1(p0) :: (load (s8) from %ir.addr2, align 4)
902 ; CHECK: [[CST1:%[0-9]+]]:_(s64) = G_CONSTANT i64 4
903 ; CHECK: [[GEP1:%[0-9]+]]:_(p0) = G_PTR_ADD %1, [[CST1]](s64)
904 ; CHECK: [[LD2:%[0-9]+]]:_(s32) = G_LOAD [[GEP1]](p0) :: (load (s32) from %ir.addr2 + 4)
905 ; CHECK: [[LD3:%[0-9]+]]:_(s8) = G_LOAD %0(p0) :: (load (s8) from %ir.addr, align 4)
906 ; CHECK: [[GEP2:%[0-9]+]]:_(p0) = G_PTR_ADD %0, [[CST1]](s64)
907 ; CHECK: [[LD4:%[0-9]+]]:_(s8) = G_LOAD [[GEP2]](p0) :: (load (s8) from %ir.addr + 4, align 4)
908 ; CHECK: [[CST3:%[0-9]+]]:_(s64) = G_CONSTANT i64 8
909 ; CHECK: [[GEP3:%[0-9]+]]:_(p0) = G_PTR_ADD %0, [[CST3]](s64)
910 ; CHECK: [[LD5:%[0-9]+]]:_(s32) = G_LOAD [[GEP3]](p0) :: (load (s32) from %ir.addr + 8)
911 ; CHECK: [[CST4:%[0-9]+]]:_(s64) = G_CONSTANT i64 12
912 ; CHECK: [[GEP4:%[0-9]+]]:_(p0) = G_PTR_ADD %0, [[CST4]](s64)
913 ; CHECK: [[LD6:%[0-9]+]]:_(s32) = G_LOAD [[GEP4]](p0) :: (load (s32) from %ir.addr + 12)
914 ; CHECK: G_STORE [[LD3]](s8), %0(p0) :: (store (s8) into %ir.addr, align 4)
915 ; CHECK: [[GEP5:%[0-9]+]]:_(p0) = G_PTR_ADD %0, [[CST1]](s64)
916 ; CHECK: G_STORE [[LD1]](s8), [[GEP5]](p0) :: (store (s8) into %ir.addr + 4, align 4)
917 ; CHECK: [[GEP6:%[0-9]+]]:_(p0) = G_PTR_ADD %0, [[CST3]](s64)
918 ; CHECK: G_STORE [[LD2]](s32), [[GEP6]](p0) :: (store (s32) into %ir.addr + 8)
919 ; CHECK: [[GEP7:%[0-9]+]]:_(p0) = G_PTR_ADD %0, [[CST4]](s64)
920 ; CHECK: G_STORE [[LD6]](s32), [[GEP7]](p0) :: (store (s32) into %ir.addr + 12)
921 define void @test_insertvalue_agg(ptr %addr, ptr %addr2) {
922   %smallstruct = load {i8, i32}, ptr %addr2
923   %struct = load %struct.nested, ptr %addr
924   %res = insertvalue %struct.nested %struct, {i8, i32} %smallstruct, 1
925   store %struct.nested %res, ptr %addr
926   ret void
929 ; CHECK-LABEL: name: test_select
930 ; CHECK: [[TST_C:%[0-9]+]]:_(s32) = COPY $w0
931 ; CHECK: [[TSTEXT:%[0-9]+]]:_(s8) = G_TRUNC [[TST_C]]
932 ; CHECK: [[LHS:%[0-9]+]]:_(s32) = COPY $w1
933 ; CHECK: [[RHS:%[0-9]+]]:_(s32) = COPY $w2
934 ; CHECK: [[TSTASSERT:%[0-9]+]]:_(s8) = G_ASSERT_ZEXT [[TSTEXT]], 1
935 ; CHECK: [[TST:%[0-9]+]]:_(s1) = G_TRUNC [[TSTASSERT]]
936 ; CHECK: [[RES:%[0-9]+]]:_(s32) = G_SELECT [[TST]](s1), [[LHS]], [[RHS]]
937 ; CHECK: $w0 = COPY [[RES]]
938 define i32 @test_select(i1 %tst, i32 %lhs, i32 %rhs) {
939   %res = select i1 %tst, i32 %lhs, i32 %rhs
940   ret i32 %res
943 ; CHECK-LABEL: name: test_select_flags
944 ; CHECK:   [[COPY:%[0-9]+]]:_(s32) = COPY $w0
945 ; CHECK:   [[TRUNC8:%[0-9]+]]:_(s8) = G_TRUNC [[COPY]]
946 ; CHECK:   [[COPY1:%[0-9]+]]:_(s32) = COPY $s0
947 ; CHECK:   [[COPY2:%[0-9]+]]:_(s32) = COPY $s1
948 ; CHECK:   [[TRUNCASSERT:%[0-9]+]]:_(s8) = G_ASSERT_ZEXT [[TRUNC8]], 1
949 ; CHECK:   [[TRUNC:%[0-9]+]]:_(s1) = G_TRUNC [[TRUNCASSERT]]
950 ; CHECK:   [[SELECT:%[0-9]+]]:_(s32) = nnan G_SELECT [[TRUNC]](s1), [[COPY1]], [[COPY2]]
951 define float @test_select_flags(i1 %tst, float %lhs, float %rhs) {
952   %res = select nnan i1 %tst, float %lhs, float %rhs
953   ret float %res
956 ; Don't take the flags from the compare condition
957 ; CHECK-LABEL: name: test_select_cmp_flags
958 ; CHECK:   [[COPY0:%[0-9]+]]:_(s32) = COPY $s0
959 ; CHECK:   [[COPY1:%[0-9]+]]:_(s32) = COPY $s1
960 ; CHECK:   [[COPY2:%[0-9]+]]:_(s32) = COPY $s2
961 ; CHECK:   [[COPY3:%[0-9]+]]:_(s32) = COPY $s3
962 ; CHECK:   [[CMP:%[0-9]+]]:_(s1) = nsz G_FCMP floatpred(oeq), [[COPY0]](s32), [[COPY1]]
963 ; CHECK:   [[SELECT:%[0-9]+]]:_(s32) = G_SELECT [[CMP]](s1), [[COPY2]], [[COPY3]]
964 define float @test_select_cmp_flags(float %cmp0, float %cmp1, float %lhs, float %rhs) {
965   %tst = fcmp nsz oeq float %cmp0, %cmp1
966   %res = select i1 %tst, float %lhs, float %rhs
967   ret float %res
970 ; CHECK-LABEL: name: test_select_ptr
971 ; CHECK: [[TST_C:%[0-9]+]]:_(s32) = COPY $w0
972 ; CHECK: [[TSTEXT:%[0-9]+]]:_(s8) = G_TRUNC [[TST_C]]
973 ; CHECK: [[LHS:%[0-9]+]]:_(p0) = COPY $x1
974 ; CHECK: [[RHS:%[0-9]+]]:_(p0) = COPY $x2
975 ; CHECK: [[TSTASSERT:%[0-9]+]]:_(s8) = G_ASSERT_ZEXT [[TSTEXT]], 1
976 ; CHECK: [[TST:%[0-9]+]]:_(s1) = G_TRUNC [[TSTASSERT]]
977 ; CHECK: [[RES:%[0-9]+]]:_(p0) = G_SELECT [[TST]](s1), [[LHS]], [[RHS]]
978 ; CHECK: $x0 = COPY [[RES]]
979 define ptr @test_select_ptr(i1 %tst, ptr %lhs, ptr %rhs) {
980   %res = select i1 %tst, ptr %lhs, ptr %rhs
981   ret ptr %res
984 ; CHECK-LABEL: name: test_select_vec
985 ; CHECK: [[TST_C:%[0-9]+]]:_(s32) = COPY $w0
986 ; CHECK: [[TSTEXT:%[0-9]+]]:_(s8) = G_TRUNC [[TST_C]]
987 ; CHECK: [[LHS:%[0-9]+]]:_(<4 x s32>) = COPY $q0
988 ; CHECK: [[RHS:%[0-9]+]]:_(<4 x s32>) = COPY $q1
989 ; CHECK: [[TSTASSERT:%[0-9]+]]:_(s8) = G_ASSERT_ZEXT [[TSTEXT]], 1
990 ; CHECK: [[TST:%[0-9]+]]:_(s1) = G_TRUNC [[TSTASSERT]]
991 ; CHECK: [[RES:%[0-9]+]]:_(<4 x s32>) = G_SELECT [[TST]](s1), [[LHS]], [[RHS]]
992 ; CHECK: $q0 = COPY [[RES]]
993 define <4 x i32> @test_select_vec(i1 %tst, <4 x i32> %lhs, <4 x i32> %rhs) {
994   %res = select i1 %tst, <4 x i32> %lhs, <4 x i32> %rhs
995   ret <4 x i32> %res
998 ; CHECK-LABEL: name: test_vselect_vec
999 ; CHECK: [[TST32:%[0-9]+]]:_(<4 x s32>) = COPY $q0
1000 ; CHECK: [[LHS:%[0-9]+]]:_(<4 x s32>) = COPY $q1
1001 ; CHECK: [[RHS:%[0-9]+]]:_(<4 x s32>) = COPY $q2
1002 ; CHECK: [[TST:%[0-9]+]]:_(<4 x s1>) = G_TRUNC [[TST32]](<4 x s32>)
1003 ; CHECK: [[RES:%[0-9]+]]:_(<4 x s32>) = G_SELECT [[TST]](<4 x s1>), [[LHS]], [[RHS]]
1004 ; CHECK: $q0 = COPY [[RES]]
1005 define <4 x i32> @test_vselect_vec(<4 x i32> %tst32, <4 x i32> %lhs, <4 x i32> %rhs) {
1006   %tst = trunc <4 x i32> %tst32 to <4 x i1>
1007   %res = select <4 x i1> %tst, <4 x i32> %lhs, <4 x i32> %rhs
1008   ret <4 x i32> %res
1011 ; CHECK-LABEL: name: test_fptosi
1012 ; CHECK: [[FPADDR:%[0-9]+]]:_(p0) = COPY $x0
1013 ; CHECK: [[FP:%[0-9]+]]:_(s32) = G_LOAD [[FPADDR]](p0)
1014 ; CHECK: [[RES:%[0-9]+]]:_(s64) = G_FPTOSI [[FP]](s32)
1015 ; CHECK: $x0 = COPY [[RES]]
1016 define i64 @test_fptosi(ptr %fp.addr) {
1017   %fp = load float, ptr %fp.addr
1018   %res = fptosi float %fp to i64
1019   ret i64 %res
1022 ; CHECK-LABEL: name: test_fptoui
1023 ; CHECK: [[FPADDR:%[0-9]+]]:_(p0) = COPY $x0
1024 ; CHECK: [[FP:%[0-9]+]]:_(s32) = G_LOAD [[FPADDR]](p0)
1025 ; CHECK: [[RES:%[0-9]+]]:_(s64) = G_FPTOUI [[FP]](s32)
1026 ; CHECK: $x0 = COPY [[RES]]
1027 define i64 @test_fptoui(ptr %fp.addr) {
1028   %fp = load float, ptr %fp.addr
1029   %res = fptoui float %fp to i64
1030   ret i64 %res
1033 ; CHECK-LABEL: name: test_sitofp
1034 ; CHECK: [[ADDR:%[0-9]+]]:_(p0) = COPY $x0
1035 ; CHECK: [[IN:%[0-9]+]]:_(s32) = COPY $w1
1036 ; CHECK: [[FP:%[0-9]+]]:_(s64) = G_SITOFP [[IN]](s32)
1037 ; CHECK: G_STORE [[FP]](s64), [[ADDR]](p0)
1038 define void @test_sitofp(ptr %addr, i32 %in) {
1039   %fp = sitofp i32 %in to double
1040   store double %fp, ptr %addr
1041   ret void
1044 ; CHECK-LABEL: name: test_uitofp
1045 ; CHECK: [[ADDR:%[0-9]+]]:_(p0) = COPY $x0
1046 ; CHECK: [[IN:%[0-9]+]]:_(s32) = COPY $w1
1047 ; CHECK: [[FP:%[0-9]+]]:_(s64) = G_UITOFP [[IN]](s32)
1048 ; CHECK: G_STORE [[FP]](s64), [[ADDR]](p0)
1049 define void @test_uitofp(ptr %addr, i32 %in) {
1050   %fp = uitofp i32 %in to double
1051   store double %fp, ptr %addr
1052   ret void
1055 ; CHECK-LABEL: name: test_fpext
1056 ; CHECK: [[IN:%[0-9]+]]:_(s32) = COPY $s0
1057 ; CHECK: [[RES:%[0-9]+]]:_(s64) = G_FPEXT [[IN]](s32)
1058 ; CHECK: $d0 = COPY [[RES]]
1059 define double @test_fpext(float %in) {
1060   %res = fpext float %in to double
1061   ret double %res
1064 ; CHECK-LABEL: name: test_fptrunc
1065 ; CHECK: [[IN:%[0-9]+]]:_(s64) = COPY $d0
1066 ; CHECK: [[RES:%[0-9]+]]:_(s32) = G_FPTRUNC [[IN]](s64)
1067 ; CHECK: $s0 = COPY [[RES]]
1068 define float @test_fptrunc(double %in) {
1069   %res = fptrunc double %in to float
1070   ret float %res
1073 ; CHECK-LABEL: name: test_constant_float
1074 ; CHECK: [[ADDR:%[0-9]+]]:_(p0) = COPY $x0
1075 ; CHECK: [[TMP:%[0-9]+]]:_(s32) = G_FCONSTANT float 1.500000e+00
1076 ; CHECK: G_STORE [[TMP]](s32), [[ADDR]](p0)
1077 define void @test_constant_float(ptr %addr) {
1078   store float 1.5, ptr %addr
1079   ret void
1082 ; CHECK-LABEL: name: float_comparison
1083 ; CHECK: [[LHSADDR:%[0-9]+]]:_(p0) = COPY $x0
1084 ; CHECK: [[RHSADDR:%[0-9]+]]:_(p0) = COPY $x1
1085 ; CHECK: [[BOOLADDR:%[0-9]+]]:_(p0) = COPY $x2
1086 ; CHECK: [[LHS:%[0-9]+]]:_(s32) = G_LOAD [[LHSADDR]](p0)
1087 ; CHECK: [[RHS:%[0-9]+]]:_(s32) = G_LOAD [[RHSADDR]](p0)
1088 ; CHECK: [[TST:%[0-9]+]]:_(s1) = nnan ninf nsz arcp contract afn reassoc G_FCMP floatpred(oge), [[LHS]](s32), [[RHS]]
1089 ; CHECK: G_STORE [[TST]](s1), [[BOOLADDR]](p0)
1090 define void @float_comparison(ptr %a.addr, ptr %b.addr, ptr %bool.addr) {
1091   %a = load float, ptr %a.addr
1092   %b = load float, ptr %b.addr
1093   %res = fcmp nnan ninf nsz arcp contract afn reassoc oge float %a, %b
1094   store i1 %res, ptr %bool.addr
1095   ret void
1098 ; CHECK-LABEL: name: trivial_float_comparison
1099 ; CHECK: [[ENTRY_R1:%[0-9]+]]:_(s1) = G_CONSTANT i1 false
1100 ; CHECK: [[ENTRY_R2:%[0-9]+]]:_(s1) = G_CONSTANT i1 true
1101 ; CHECK: [[R1:%[0-9]+]]:_(s1) = COPY [[ENTRY_R1]](s1)
1102 ; CHECK: [[R2:%[0-9]+]]:_(s1) = COPY [[ENTRY_R2]](s1)
1103 ; CHECK: G_ADD [[R1]], [[R2]]
1104 define i1 @trivial_float_comparison(double %a, double %b) {
1105   %r1 = fcmp false double %a, %b
1106   %r2 = fcmp true double %a, %b
1107   %sum = add i1 %r1, %r2
1108   ret i1 %sum
1111 @var = global i32 0
1113 define ptr @test_global() {
1114 ; CHECK-LABEL: name: test_global
1115 ; CHECK: [[TMP:%[0-9]+]]:_(p0) = G_GLOBAL_VALUE @var{{$}}
1116 ; CHECK: $x0 = COPY [[TMP]](p0)
1118   ret ptr @var
1121 @var1 = addrspace(42) global i32 0
1122 define ptr addrspace(42) @test_global_addrspace() {
1123 ; CHECK-LABEL: name: test_global
1124 ; CHECK: [[TMP:%[0-9]+]]:_(p42) = G_GLOBAL_VALUE @var1{{$}}
1125 ; CHECK: $x0 = COPY [[TMP]](p42)
1127   ret ptr addrspace(42) @var1
1131 define ptr @test_global_func() {
1132 ; CHECK-LABEL: name: test_global_func
1133 ; CHECK: [[TMP:%[0-9]+]]:_(p0) = G_GLOBAL_VALUE @allocai64{{$}}
1134 ; CHECK: $x0 = COPY [[TMP]](p0)
1136   ret ptr @allocai64
1139 declare void @llvm.memcpy.p0.p0.i64(ptr, ptr, i64, i1)
1140 define void @test_memcpy(ptr %dst, ptr %src, i64 %size) {
1141 ; CHECK-LABEL: name: test_memcpy
1142 ; CHECK: [[DST:%[0-9]+]]:_(p0) = COPY $x0
1143 ; CHECK: [[SRC:%[0-9]+]]:_(p0) = COPY $x1
1144 ; CHECK: [[SIZE:%[0-9]+]]:_(s64) = COPY $x2
1145 ; CHECK: G_MEMCPY [[DST]](p0), [[SRC]](p0), [[SIZE]](s64), 0 :: (store (s8) into %ir.dst), (load (s8) from %ir.src)
1146   call void @llvm.memcpy.p0.p0.i64(ptr %dst, ptr %src, i64 %size, i1 0)
1147   ret void
1150 define void @test_memcpy_tail(ptr %dst, ptr %src, i64 %size) {
1151 ; CHECK-LABEL: name: test_memcpy_tail
1152 ; CHECK: [[DST:%[0-9]+]]:_(p0) = COPY $x0
1153 ; CHECK: [[SRC:%[0-9]+]]:_(p0) = COPY $x1
1154 ; CHECK: [[SIZE:%[0-9]+]]:_(s64) = COPY $x2
1155 ; CHECK: G_MEMCPY [[DST]](p0), [[SRC]](p0), [[SIZE]](s64), 1 :: (store (s8) into %ir.dst), (load (s8) from %ir.src)
1156   tail call void @llvm.memcpy.p0.p0.i64(ptr %dst, ptr %src, i64 %size, i1 0)
1157   ret void
1160 declare void @llvm.memcpy.p1.p1.i64(ptr addrspace(1), ptr addrspace(1), i64, i1)
1161 define void @test_memcpy_nonzero_as(ptr addrspace(1) %dst, ptr addrspace(1) %src, i64 %size) {
1162 ; CHECK-LABEL: name: test_memcpy_nonzero_as
1163 ; CHECK: [[DST:%[0-9]+]]:_(p1) = COPY $x0
1164 ; CHECK: [[SRC:%[0-9]+]]:_(p1) = COPY $x1
1165 ; CHECK: [[SIZE:%[0-9]+]]:_(s64) = COPY $x2
1166 ; CHECK: G_MEMCPY [[DST]](p1), [[SRC]](p1), [[SIZE]](s64), 0 :: (store (s8) into %ir.dst, addrspace 1), (load (s8) from %ir.src, addrspace 1)
1167   call void @llvm.memcpy.p1.p1.i64(ptr addrspace(1) %dst, ptr addrspace(1) %src, i64 %size, i1 0)
1168   ret void
1171 declare void @llvm.memmove.p0.p0.i64(ptr, ptr, i64, i1)
1172 define void @test_memmove(ptr %dst, ptr %src, i64 %size) {
1173 ; CHECK-LABEL: name: test_memmove
1174 ; CHECK: [[DST:%[0-9]+]]:_(p0) = COPY $x0
1175 ; CHECK: [[SRC:%[0-9]+]]:_(p0) = COPY $x1
1176 ; CHECK: [[SIZE:%[0-9]+]]:_(s64) = COPY $x2
1177 ; CHECK: G_MEMMOVE [[DST]](p0), [[SRC]](p0), [[SIZE]](s64), 0 :: (store (s8) into %ir.dst), (load (s8) from %ir.src)
1178   call void @llvm.memmove.p0.p0.i64(ptr %dst, ptr %src, i64 %size, i1 0)
1179   ret void
1182 declare void @llvm.memset.p0.i64(ptr, i8, i64, i1)
1183 define void @test_memset(ptr %dst, i8 %val, i64 %size) {
1184 ; CHECK-LABEL: name: test_memset
1185 ; CHECK: [[DST:%[0-9]+]]:_(p0) = COPY $x0
1186 ; CHECK: [[SRC_C:%[0-9]+]]:_(s32) = COPY $w1
1187 ; CHECK: [[SRC:%[0-9]+]]:_(s8) = G_TRUNC [[SRC_C]]
1188 ; CHECK: [[SIZE:%[0-9]+]]:_(s64) = COPY $x2
1189 ; CHECK: G_MEMSET [[DST]](p0), [[SRC]](s8), [[SIZE]](s64), 0 :: (store (s8) into %ir.dst)
1190   call void @llvm.memset.p0.i64(ptr %dst, i8 %val, i64 %size, i1 0)
1191   ret void
1194 define void @test_large_const(ptr %addr) {
1195 ; CHECK-LABEL: name: test_large_const
1196 ; CHECK: [[ADDR:%[0-9]+]]:_(p0) = COPY $x0
1197 ; CHECK: [[VAL:%[0-9]+]]:_(s128) = G_CONSTANT i128 42
1198 ; CHECK: G_STORE [[VAL]](s128), [[ADDR]](p0)
1199   store i128 42, ptr %addr
1200   ret void
1203 ; When there was no formal argument handling (so the first BB was empty) we used
1204 ; to insert the constants at the end of the block, even if they were encountered
1205 ; after the block's terminators had been emitted. Also make sure the order is
1206 ; correct.
1207 define ptr @test_const_placement() {
1208 ; CHECK-LABEL: name: test_const_placement
1209 ; CHECK: bb.{{[0-9]+}} (%ir-block.{{[0-9]+}}):
1210 ; CHECK:   [[VAL_INT:%[0-9]+]]:_(s32) = G_CONSTANT i32 42
1211 ; CHECK:   [[VAL:%[0-9]+]]:_(p0) = G_INTTOPTR [[VAL_INT]](s32)
1212 ; CHECK: bb.{{[0-9]+}}.{{[a-zA-Z0-9.]+}}:
1213   br label %next
1215 next:
1216   ret ptr inttoptr(i32 42 to ptr)
1219 declare void @llvm.va_end(ptr)
1220 define void @test_va_end(ptr %list) {
1221 ; CHECK-LABEL: name: test_va_end
1222 ; CHECK-NOT: va_end
1223 ; CHECK-NOT: INTRINSIC
1224 ; CHECK: RET_ReallyLR
1225   call void @llvm.va_end(ptr %list)
1226   ret void
1229 define void @test_va_arg(ptr %list) {
1230 ; CHECK-LABEL: test_va_arg
1231 ; CHECK: [[LIST:%[0-9]+]]:_(p0) = COPY $x0
1232 ; CHECK: G_VAARG [[LIST]](p0), 8
1233 ; CHECK: G_VAARG [[LIST]](p0), 1
1234 ; CHECK: G_VAARG [[LIST]](p0), 16
1236   %v0 = va_arg ptr %list, i64
1237   %v1 = va_arg ptr %list, i8
1238   %v2 = va_arg ptr %list, i128
1239   ret void
1242 declare float @llvm.pow.f32(float, float)
1243 define float @test_pow_intrin(float %l, float %r) {
1244 ; CHECK-LABEL: name: test_pow_intrin
1245 ; CHECK: [[LHS:%[0-9]+]]:_(s32) = COPY $s0
1246 ; CHECK: [[RHS:%[0-9]+]]:_(s32) = COPY $s1
1247 ; CHECK: [[RES:%[0-9]+]]:_(s32) = nnan ninf nsz arcp contract afn reassoc G_FPOW [[LHS]], [[RHS]]
1248 ; CHECK: $s0 = COPY [[RES]]
1249   %res = call nnan ninf nsz arcp contract afn reassoc float @llvm.pow.f32(float %l, float %r)
1250   ret float %res
1253 declare float @llvm.powi.f32.i32(float, i32)
1254 define float @test_powi_intrin(float %l, i32 %r) {
1255 ; CHECK-LABEL: name: test_powi_intrin
1256 ; CHECK: [[LHS:%[0-9]+]]:_(s32) = COPY $s0
1257 ; CHECK: [[RHS:%[0-9]+]]:_(s32) = COPY $w0
1258 ; CHECK: [[RES:%[0-9]+]]:_(s32) = nnan ninf nsz arcp contract afn reassoc G_FPOWI [[LHS]], [[RHS]]
1259 ; CHECK: $s0 = COPY [[RES]]
1260   %res = call nnan ninf nsz arcp contract afn reassoc float @llvm.powi.f32.i32(float %l, i32 %r)
1261   ret float %res
1264 declare float @llvm.fma.f32(float, float, float)
1265 define float @test_fma_intrin(float %a, float %b, float %c) {
1266 ; CHECK-LABEL: name: test_fma_intrin
1267 ; CHECK: [[A:%[0-9]+]]:_(s32) = COPY $s0
1268 ; CHECK: [[B:%[0-9]+]]:_(s32) = COPY $s1
1269 ; CHECK: [[C:%[0-9]+]]:_(s32) = COPY $s2
1270 ; CHECK: [[RES:%[0-9]+]]:_(s32) = nnan ninf nsz arcp contract afn reassoc G_FMA [[A]], [[B]], [[C]]
1271 ; CHECK: $s0 = COPY [[RES]]
1272   %res = call nnan ninf nsz arcp contract afn reassoc float @llvm.fma.f32(float %a, float %b, float %c)
1273   ret float %res
1276 declare float @llvm.exp.f32(float)
1277 define float @test_exp_intrin(float %a) {
1278 ; CHECK-LABEL: name: test_exp_intrin
1279 ; CHECK: [[A:%[0-9]+]]:_(s32) = COPY $s0
1280 ; CHECK: [[RES:%[0-9]+]]:_(s32) = nnan ninf nsz arcp contract afn reassoc G_FEXP [[A]]
1281 ; CHECK: $s0 = COPY [[RES]]
1282   %res = call nnan ninf nsz arcp contract afn reassoc float @llvm.exp.f32(float %a)
1283   ret float %res
1286 declare float @llvm.exp2.f32(float)
1287 define float @test_exp2_intrin(float %a) {
1288 ; CHECK-LABEL: name: test_exp2_intrin
1289 ; CHECK: [[A:%[0-9]+]]:_(s32) = COPY $s0
1290 ; CHECK: [[RES:%[0-9]+]]:_(s32) = nnan ninf nsz arcp contract afn reassoc G_FEXP2 [[A]]
1291 ; CHECK: $s0 = COPY [[RES]]
1292   %res = call nnan ninf nsz arcp contract afn reassoc float @llvm.exp2.f32(float %a)
1293   ret float %res
1296 declare float @llvm.log.f32(float)
1297 define float @test_log_intrin(float %a) {
1298 ; CHECK-LABEL: name: test_log_intrin
1299 ; CHECK: [[A:%[0-9]+]]:_(s32) = COPY $s0
1300 ; CHECK: [[RES:%[0-9]+]]:_(s32) = nnan ninf nsz arcp contract afn reassoc G_FLOG [[A]]
1301 ; CHECK: $s0 = COPY [[RES]]
1302   %res = call nnan ninf nsz arcp contract afn reassoc float @llvm.log.f32(float %a)
1303   ret float %res
1306 declare float @llvm.log2.f32(float)
1307 define float @test_log2_intrin(float %a) {
1308 ; CHECK-LABEL: name: test_log2_intrin
1309 ; CHECK: [[A:%[0-9]+]]:_(s32) = COPY $s0
1310 ; CHECK: [[RES:%[0-9]+]]:_(s32) = G_FLOG2 [[A]]
1311 ; CHECK: $s0 = COPY [[RES]]
1312   %res = call float @llvm.log2.f32(float %a)
1313   ret float %res
1316 declare float @llvm.log10.f32(float)
1317 define float @test_log10_intrin(float %a) {
1318 ; CHECK-LABEL: name: test_log10_intrin
1319 ; CHECK: [[A:%[0-9]+]]:_(s32) = COPY $s0
1320 ; CHECK: [[RES:%[0-9]+]]:_(s32) = nnan ninf nsz arcp contract afn reassoc G_FLOG10 [[A]]
1321 ; CHECK: $s0 = COPY [[RES]]
1322   %res = call nnan ninf nsz arcp contract afn reassoc float @llvm.log10.f32(float %a)
1323   ret float %res
1326 declare float @llvm.fabs.f32(float)
1327 define float @test_fabs_intrin(float %a) {
1328 ; CHECK-LABEL: name: test_fabs_intrin
1329 ; CHECK: [[A:%[0-9]+]]:_(s32) = COPY $s0
1330 ; CHECK: [[RES:%[0-9]+]]:_(s32) = nnan ninf nsz arcp contract afn reassoc G_FABS [[A]]
1331 ; CHECK: $s0 = COPY [[RES]]
1332   %res = call nnan ninf nsz arcp contract afn reassoc float @llvm.fabs.f32(float %a)
1333   ret float %res
1336 declare float @llvm.copysign.f32(float, float)
1337 define float @test_fcopysign_intrin(float %a, float %b) {
1338 ; CHECK-LABEL: name: test_fcopysign_intrin
1339 ; CHECK: [[A:%[0-9]+]]:_(s32) = COPY $s0
1340 ; CHECK: [[B:%[0-9]+]]:_(s32) = COPY $s1
1341 ; CHECK: [[RES:%[0-9]+]]:_(s32) = nnan ninf nsz arcp contract afn reassoc G_FCOPYSIGN [[A]], [[B]]
1342 ; CHECK: $s0 = COPY [[RES]]
1344   %res = call nnan ninf nsz arcp contract afn reassoc float @llvm.copysign.f32(float %a, float %b)
1345   ret float %res
1348 declare float @llvm.canonicalize.f32(float)
1349 define float @test_fcanonicalize_intrin(float %a) {
1350 ; CHECK-LABEL: name: test_fcanonicalize_intrin
1351 ; CHECK: [[A:%[0-9]+]]:_(s32) = COPY $s0
1352 ; CHECK: [[RES:%[0-9]+]]:_(s32) = nnan ninf nsz arcp contract afn reassoc G_FCANONICALIZE [[A]]
1353 ; CHECK: $s0 = COPY [[RES]]
1354   %res = call nnan ninf nsz arcp contract afn reassoc float @llvm.canonicalize.f32(float %a)
1355   ret float %res
1358 declare float @llvm.trunc.f32(float)
1359 define float @test_intrinsic_trunc(float %a) {
1360 ; CHECK-LABEL: name: test_intrinsic_trunc
1361 ; CHECK: [[A:%[0-9]+]]:_(s32) = COPY $s0
1362 ; CHECK: [[RES:%[0-9]+]]:_(s32) = G_INTRINSIC_TRUNC [[A]]
1363 ; CHECK: $s0 = COPY [[RES]]
1364   %res = call float @llvm.trunc.f32(float %a)
1365   ret float %res
1368 declare float @llvm.round.f32(float)
1369 define float @test_intrinsic_round(float %a) {
1370 ; CHECK-LABEL: name: test_intrinsic_round
1371 ; CHECK: [[A:%[0-9]+]]:_(s32) = COPY $s0
1372 ; CHECK: [[RES:%[0-9]+]]:_(s32) = G_INTRINSIC_ROUND [[A]]
1373 ; CHECK: $s0 = COPY [[RES]]
1374   %res = call float @llvm.round.f32(float %a)
1375   ret float %res
1378 declare i32 @llvm.lrint.i32.f32(float)
1379 define i32 @test_intrinsic_lrint(float %a) {
1380 ; CHECK-LABEL: name: test_intrinsic_lrint
1381 ; CHECK: [[A:%[0-9]+]]:_(s32) = COPY $s0
1382 ; CHECK: [[RES:%[0-9]+]]:_(s32) = G_INTRINSIC_LRINT [[A]]
1383 ; CHECK: $w0 = COPY [[RES]]
1384   %res = call i32 @llvm.lrint.i32.f32(float %a)
1385   ret i32 %res
1388 declare i32 @llvm.llrint.i32.f32(float)
1389 define i32 @test_intrinsic_llrint(float %a) {
1390 ; CHECK-LABEL: name: test_intrinsic_llrint
1391 ; CHECK: [[A:%[0-9]+]]:_(s32) = COPY $s0
1392 ; CHECK: [[RES:%[0-9]+]]:_(s32) = G_INTRINSIC_LLRINT [[A]]
1393 ; CHECK: $w0 = COPY [[RES]]
1394   %res = call i32 @llvm.llrint.i32.f32(float %a)
1395   ret i32 %res
1398 declare i32 @llvm.ctlz.i32(i32, i1)
1399 define i32 @test_ctlz_intrinsic_zero_not_undef(i32 %a) {
1400 ; CHECK-LABEL: name: test_ctlz_intrinsic_zero_not_undef
1401 ; CHECK: [[A:%[0-9]+]]:_(s32) = COPY $w0
1402 ; CHECK: [[RES:%[0-9]+]]:_(s32) = G_CTLZ [[A]]
1403 ; CHECK: $w0 = COPY [[RES]]
1404   %res = call i32 @llvm.ctlz.i32(i32 %a, i1 0)
1405   ret i32 %res
1408 declare i32 @llvm.cttz.i32(i32, i1)
1409 define i32 @test_cttz_intrinsic_zero_undef(i32 %a) {
1410 ; CHECK-LABEL: name: test_cttz_intrinsic_zero_undef
1411 ; CHECK: [[A:%[0-9]+]]:_(s32) = COPY $w0
1412 ; CHECK: [[RES:%[0-9]+]]:_(s32) = G_CTTZ_ZERO_UNDEF [[A]]
1413 ; CHECK: $w0 = COPY [[RES]]
1414   %res = call i32 @llvm.cttz.i32(i32 %a, i1 1)
1415   ret i32 %res
1418 declare i32 @llvm.ctpop.i32(i32)
1419 define i32 @test_ctpop_intrinsic(i32 %a) {
1420 ; CHECK-LABEL: name: test_ctpop
1421 ; CHECK: [[A:%[0-9]+]]:_(s32) = COPY $w0
1422 ; CHECK: [[RES:%[0-9]+]]:_(s32) = G_CTPOP [[A]]
1423 ; CHECK: $w0 = COPY [[RES]]
1424   %res = call i32 @llvm.ctpop.i32(i32 %a)
1425   ret i32 %res
1428 declare i32 @llvm.bitreverse.i32(i32)
1429 define i32 @test_bitreverse_intrinsic(i32 %a) {
1430 ; CHECK-LABEL: name: test_bitreverse
1431 ; CHECK: [[A:%[0-9]+]]:_(s32) = COPY $w0
1432 ; CHECK: [[RES:%[0-9]+]]:_(s32) = G_BITREVERSE [[A]]
1433 ; CHECK: $w0 = COPY [[RES]]
1434   %res = call i32 @llvm.bitreverse.i32(i32 %a)
1435   ret i32 %res
1438 declare i32 @llvm.fshl.i32(i32, i32, i32)
1439 define i32 @test_fshl_intrinsic(i32 %a, i32 %b, i32 %c) {
1440 ; CHECK-LABEL: name: test_fshl_intrinsic
1441 ; CHECK: [[A:%[0-9]+]]:_(s32) = COPY $w0
1442 ; CHECK: [[B:%[0-9]+]]:_(s32) = COPY $w1
1443 ; CHECK: [[C:%[0-9]+]]:_(s32) = COPY $w2
1444 ; CHECK: [[RES:%[0-9]+]]:_(s32) = G_FSHL [[A]], [[B]], [[C]]
1445 ; CHECK: $w0 = COPY [[RES]]
1446   %res = call i32 @llvm.fshl.i32(i32 %a, i32 %b, i32 %c)
1447   ret i32 %res
1450 declare i32 @llvm.fshr.i32(i32, i32, i32)
1451 define i32 @test_fshr_intrinsic(i32 %a, i32 %b, i32 %c) {
1452 ; CHECK-LABEL: name: test_fshr_intrinsic
1453 ; CHECK: [[A:%[0-9]+]]:_(s32) = COPY $w0
1454 ; CHECK: [[B:%[0-9]+]]:_(s32) = COPY $w1
1455 ; CHECK: [[C:%[0-9]+]]:_(s32) = COPY $w2
1456 ; CHECK: [[RES:%[0-9]+]]:_(s32) = G_FSHR [[A]], [[B]], [[C]]
1457 ; CHECK: $w0 = COPY [[RES]]
1458   %res = call i32 @llvm.fshr.i32(i32 %a, i32 %b, i32 %c)
1459   ret i32 %res
1462 declare void @llvm.lifetime.start.p0(i64, ptr)
1463 declare void @llvm.lifetime.end.p0(i64, ptr)
1464 define void @test_lifetime_intrin() {
1465 ; CHECK-LABEL: name: test_lifetime_intrin
1466 ; CHECK: RET_ReallyLR
1467 ; O3-LABEL: name: test_lifetime_intrin
1468 ; O3: {{%[0-9]+}}:_(p0) = G_FRAME_INDEX %stack.0.slot
1469 ; O3-NEXT: LIFETIME_START %stack.0.slot
1470 ; O3-NEXT: G_STORE
1471 ; O3-NEXT: LIFETIME_END %stack.0.slot
1472 ; O3-NEXT: RET_ReallyLR
1473   %slot = alloca i8, i32 4
1474   call void @llvm.lifetime.start.p0(i64 0, ptr %slot)
1475   store volatile i8 10, ptr %slot
1476   call void @llvm.lifetime.end.p0(i64 0, ptr %slot)
1477   ret void
1480 define void @test_load_store_atomics(ptr %addr) {
1481 ; CHECK-LABEL: name: test_load_store_atomics
1482 ; CHECK: [[ADDR:%[0-9]+]]:_(p0) = COPY $x0
1483 ; CHECK: [[V0:%[0-9]+]]:_(s8) = G_LOAD [[ADDR]](p0) :: (load unordered (s8) from %ir.addr)
1484 ; CHECK: G_STORE [[V0]](s8), [[ADDR]](p0) :: (store monotonic (s8) into %ir.addr)
1485 ; CHECK: [[V1:%[0-9]+]]:_(s8) = G_LOAD [[ADDR]](p0) :: (load acquire (s8) from %ir.addr)
1486 ; CHECK: G_STORE [[V1]](s8), [[ADDR]](p0) :: (store release (s8) into %ir.addr)
1487 ; CHECK: [[V2:%[0-9]+]]:_(s8) = G_LOAD [[ADDR]](p0) :: (load syncscope("singlethread") seq_cst (s8) from %ir.addr)
1488 ; CHECK: G_STORE [[V2]](s8), [[ADDR]](p0) :: (store syncscope("singlethread") monotonic (s8) into %ir.addr)
1489   %v0 = load atomic i8, ptr %addr unordered, align 1
1490   store atomic i8 %v0, ptr %addr monotonic, align 1
1492   %v1 = load atomic i8, ptr %addr acquire, align 1
1493   store atomic i8 %v1, ptr %addr release, align 1
1495   %v2 = load atomic i8, ptr %addr syncscope("singlethread") seq_cst, align 1
1496   store atomic i8 %v2, ptr %addr syncscope("singlethread") monotonic, align 1
1498   ret void
1501 define float @test_fneg_f32(float %x) {
1502 ; CHECK-LABEL: name: test_fneg_f32
1503 ; CHECK: [[ARG:%[0-9]+]]:_(s32) = COPY $s0
1504 ; CHECK: [[RES:%[0-9]+]]:_(s32) = G_FNEG [[ARG]]
1505 ; CHECK: $s0 = COPY [[RES]](s32)
1506   %neg = fneg float %x
1507   ret float %neg
1510 define float @test_fneg_f32_fmf(float %x) {
1511 ; CHECK-LABEL: name: test_fneg_f32
1512 ; CHECK: [[ARG:%[0-9]+]]:_(s32) = COPY $s0
1513 ; CHECK: [[RES:%[0-9]+]]:_(s32) = nnan ninf nsz arcp contract afn reassoc G_FNEG [[ARG]]
1514 ; CHECK: $s0 = COPY [[RES]](s32)
1515   %neg = fneg fast float %x
1516   ret float %neg
1519 define double @test_fneg_f64(double %x) {
1520 ; CHECK-LABEL: name: test_fneg_f64
1521 ; CHECK: [[ARG:%[0-9]+]]:_(s64) = COPY $d0
1522 ; CHECK: [[RES:%[0-9]+]]:_(s64) = G_FNEG [[ARG]]
1523 ; CHECK: $d0 = COPY [[RES]](s64)
1524   %neg = fneg double %x
1525   ret double %neg
1528 define double @test_fneg_f64_fmf(double %x) {
1529 ; CHECK-LABEL: name: test_fneg_f64
1530 ; CHECK: [[ARG:%[0-9]+]]:_(s64) = COPY $d0
1531 ; CHECK: [[RES:%[0-9]+]]:_(s64) = nnan ninf nsz arcp contract afn reassoc G_FNEG [[ARG]]
1532 ; CHECK: $d0 = COPY [[RES]](s64)
1533   %neg = fneg fast double %x
1534   ret double %neg
1537 define void @test_trivial_inlineasm() {
1538 ; CHECK-LABEL: name: test_trivial_inlineasm
1539 ; CHECK: INLINEASM &wibble, 1
1540 ; CHECK: INLINEASM &wibble, 0
1541   call void asm sideeffect "wibble", ""()
1542   call void asm "wibble", ""()
1543   ret void
1546 define <2 x i32> @test_insertelement(<2 x i32> %vec, i32 %elt, i32 %idx){
1547 ; CHECK-LABEL: name: test_insertelement
1548 ; CHECK: [[VEC:%[0-9]+]]:_(<2 x s32>) = COPY $d0
1549 ; CHECK: [[ELT:%[0-9]+]]:_(s32) = COPY $w0
1550 ; CHECK: [[IDX:%[0-9]+]]:_(s32) = COPY $w1
1551 ; CHECK: [[IDX2:%[0-9]+]]:_(s64) = G_ZEXT [[IDX]]
1552 ; CHECK: [[RES:%[0-9]+]]:_(<2 x s32>) = G_INSERT_VECTOR_ELT [[VEC]], [[ELT]](s32), [[IDX2]](s64)
1553 ; CHECK: $d0 = COPY [[RES]](<2 x s32>)
1554   %res = insertelement <2 x i32> %vec, i32 %elt, i32 %idx
1555   ret <2 x i32> %res
1558 define i32 @test_extractelement(<2 x i32> %vec, i32 %idx) {
1559 ; CHECK-LABEL: name: test_extractelement
1560 ; CHECK: [[VEC:%[0-9]+]]:_(<2 x s32>) = COPY $d0
1561 ; CHECK: [[IDX:%[0-9]+]]:_(s32) = COPY $w0
1562 ; CHECK: [[IDXEXT:%[0-9]+]]:_(s64) = G_ZEXT [[IDX]]
1563 ; CHECK: [[RES:%[0-9]+]]:_(s32) = G_EXTRACT_VECTOR_ELT [[VEC]](<2 x s32>), [[IDXEXT]](s64)
1564 ; CHECK: $w0 = COPY [[RES]](s32)
1565   %res = extractelement <2 x i32> %vec, i32 %idx
1566   ret i32 %res
1569 define i32 @test_extractelement_const_idx(<2 x i32> %vec) {
1570 ; CHECK-LABEL: name: test_extractelement
1571 ; CHECK: [[VEC:%[0-9]+]]:_(<2 x s32>) = COPY $d0
1572 ; CHECK: [[IDX:%[0-9]+]]:_(s64) = G_CONSTANT i64 1
1573 ; CHECK: [[RES:%[0-9]+]]:_(s32) = G_EXTRACT_VECTOR_ELT [[VEC]](<2 x s32>), [[IDX]](s64)
1574 ; CHECK: $w0 = COPY [[RES]](s32)
1575   %res = extractelement <2 x i32> %vec, i32 1
1576   ret i32 %res
1579 define i32 @test_extractelement_const_idx_zext_i1(<2 x i32> %vec) {
1580 ; CHECK-LABEL: name: test_extractelement
1581 ; CHECK: [[VEC:%[0-9]+]]:_(<2 x s32>) = COPY $d0
1582 ; CHECK: [[IDX:%[0-9]+]]:_(s64) = G_CONSTANT i64 1
1583 ; CHECK: [[RES:%[0-9]+]]:_(s32) = G_EXTRACT_VECTOR_ELT [[VEC]](<2 x s32>), [[IDX]](s64)
1584 ; CHECK: $w0 = COPY [[RES]](s32)
1585   %res = extractelement <2 x i32> %vec, i1 true
1586   ret i32 %res
1589 define i32 @test_extractelement_const_idx_zext_i8(<2 x i32> %vec) {
1590 ; CHECK-LABEL: name: test_extractelement
1591 ; CHECK: [[VEC:%[0-9]+]]:_(<2 x s32>) = COPY $d0
1592 ; CHECK: [[IDX:%[0-9]+]]:_(s64) = G_CONSTANT i64 255
1593 ; CHECK: [[RES:%[0-9]+]]:_(s32) = G_EXTRACT_VECTOR_ELT [[VEC]](<2 x s32>), [[IDX]](s64)
1594 ; CHECK: $w0 = COPY [[RES]](s32)
1595   %res = extractelement <2 x i32> %vec, i8 255
1596   ret i32 %res
1600 define i32 @test_singleelementvector(i32 %elt){
1601 ; CHECK-LABEL: name: test_singleelementvector
1602 ; CHECK: [[ELT:%[0-9]+]]:_(s32) = COPY $w0
1603 ; CHECK-NOT: G_INSERT_VECTOR_ELT
1604 ; CHECK-NOT: G_EXTRACT_VECTOR_ELT
1605 ; CHECK: $w0 = COPY [[ELT]](s32)
1606   %vec = insertelement <1 x i32> undef, i32 %elt, i32 0
1607   %res = extractelement <1 x i32> %vec, i32 0
1608   ret i32 %res
1611 define <2 x i32> @test_constantaggzerovector_v2i32() {
1612 ; CHECK-LABEL: name: test_constantaggzerovector_v2i32
1613 ; CHECK: [[ZERO:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
1614 ; CHECK: [[VEC:%[0-9]+]]:_(<2 x s32>) = G_BUILD_VECTOR [[ZERO]](s32), [[ZERO]](s32)
1615 ; CHECK: $d0 = COPY [[VEC]](<2 x s32>)
1616   ret <2 x i32> zeroinitializer
1619 define <2 x float> @test_constantaggzerovector_v2f32() {
1620 ; CHECK-LABEL: name: test_constantaggzerovector_v2f32
1621 ; CHECK: [[ZERO:%[0-9]+]]:_(s32) = G_FCONSTANT float 0.000000e+00
1622 ; CHECK: [[VEC:%[0-9]+]]:_(<2 x s32>) = G_BUILD_VECTOR [[ZERO]](s32), [[ZERO]](s32)
1623 ; CHECK: $d0 = COPY [[VEC]](<2 x s32>)
1624   ret <2 x float> zeroinitializer
1627 define i32 @test_constantaggzerovector_v3i32() {
1628 ; CHECK-LABEL: name: test_constantaggzerovector_v3i32
1629 ; CHECK: [[ZERO:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
1630 ; CHECK: [[VEC:%[0-9]+]]:_(<3 x s32>) = G_BUILD_VECTOR [[ZERO]](s32), [[ZERO]](s32), [[ZERO]](s32)
1631 ; CHECK: G_EXTRACT_VECTOR_ELT [[VEC]](<3 x s32>)
1632   %elt = extractelement <3 x i32> zeroinitializer, i32 1
1633   ret i32 %elt
1636 define <2 x i32> @test_constantdatavector_v2i32() {
1637 ; CHECK-LABEL: name: test_constantdatavector_v2i32
1638 ; CHECK: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
1639 ; CHECK: [[C2:%[0-9]+]]:_(s32) = G_CONSTANT i32 2
1640 ; CHECK: [[VEC:%[0-9]+]]:_(<2 x s32>) = G_BUILD_VECTOR [[C1]](s32), [[C2]](s32)
1641 ; CHECK: $d0 = COPY [[VEC]](<2 x s32>)
1642   ret <2 x i32> <i32 1, i32 2>
1645 define i32 @test_constantdatavector_v3i32() {
1646 ; CHECK-LABEL: name: test_constantdatavector_v3i32
1647 ; CHECK: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
1648 ; CHECK: [[C2:%[0-9]+]]:_(s32) = G_CONSTANT i32 2
1649 ; CHECK: [[C3:%[0-9]+]]:_(s32) = G_CONSTANT i32 3
1650 ; CHECK: [[VEC:%[0-9]+]]:_(<3 x s32>) = G_BUILD_VECTOR [[C1]](s32), [[C2]](s32), [[C3]](s32)
1651 ; CHECK: G_EXTRACT_VECTOR_ELT [[VEC]](<3 x s32>)
1652   %elt = extractelement <3 x i32> <i32 1, i32 2, i32 3>, i32 1
1653   ret i32 %elt
1656 define <4 x i32> @test_constantdatavector_v4i32() {
1657 ; CHECK-LABEL: name: test_constantdatavector_v4i32
1658 ; CHECK: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
1659 ; CHECK: [[C2:%[0-9]+]]:_(s32) = G_CONSTANT i32 2
1660 ; CHECK: [[C3:%[0-9]+]]:_(s32) = G_CONSTANT i32 3
1661 ; CHECK: [[C4:%[0-9]+]]:_(s32) = G_CONSTANT i32 4
1662 ; CHECK: [[VEC:%[0-9]+]]:_(<4 x s32>) = G_BUILD_VECTOR [[C1]](s32), [[C2]](s32), [[C3]](s32), [[C4]](s32)
1663 ; CHECK: $q0 = COPY [[VEC]](<4 x s32>)
1664   ret <4 x i32> <i32 1, i32 2, i32 3, i32 4>
1667 define <2 x double> @test_constantdatavector_v2f64() {
1668 ; CHECK-LABEL: name: test_constantdatavector_v2f64
1669 ; CHECK: [[FC1:%[0-9]+]]:_(s64) = G_FCONSTANT double 1.000000e+00
1670 ; CHECK: [[FC2:%[0-9]+]]:_(s64) = G_FCONSTANT double 2.000000e+00
1671 ; CHECK: [[VEC:%[0-9]+]]:_(<2 x s64>) = G_BUILD_VECTOR [[FC1]](s64), [[FC2]](s64)
1672 ; CHECK: $q0 = COPY [[VEC]](<2 x s64>)
1673   ret <2 x double> <double 1.0, double 2.0>
1676 define i32 @test_constantaggzerovector_v1s32(i32 %arg){
1677 ; CHECK-LABEL: name: test_constantaggzerovector_v1s32
1678 ; CHECK: [[ARG:%[0-9]+]]:_(s32) = COPY $w0
1679 ; CHECK: [[C0:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
1680 ; CHECK-NOT: G_MERGE_VALUES
1681 ; CHECK: [[COPY:%[0-9]+]]:_(s32) = COPY [[C0]]
1682 ; CHECK-NOT: G_MERGE_VALUES
1683 ; CHECK: G_ADD [[ARG]], [[COPY]]
1684   %vec = insertelement <1 x i32> undef, i32 %arg, i32 0
1685   %add = add <1 x i32> %vec, zeroinitializer
1686   %res = extractelement <1 x i32> %add, i32 0
1687   ret i32 %res
1690 define i32 @test_constantdatavector_v1s32(i32 %arg){
1691 ; CHECK-LABEL: name: test_constantdatavector_v1s32
1692 ; CHECK: [[ARG:%[0-9]+]]:_(s32) = COPY $w0
1693 ; CHECK: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
1694 ; CHECK-NOT: G_MERGE_VALUES
1695 ; CHECK: [[COPY:%[0-9]+]]:_(s32) = COPY [[C0]]
1696 ; CHECK-NOT: G_MERGE_VALUES
1697 ; CHECK: G_ADD [[ARG]], [[COPY]]
1698   %vec = insertelement <1 x i32> undef, i32 %arg, i32 0
1699   %add = add <1 x i32> %vec, <i32 1>
1700   %res = extractelement <1 x i32> %add, i32 0
1701   ret i32 %res
1704 declare ghccc float @different_call_conv_target(float %x)
1705 define float @test_different_call_conv_target(float %x) {
1706 ; CHECK-LABEL: name: test_different_call_conv
1707 ; CHECK: [[X:%[0-9]+]]:_(s32) = COPY $s0
1708 ; CHECK: $s8 = COPY [[X]]
1709 ; CHECK: BL @different_call_conv_target, csr_aarch64_noregs, implicit-def $lr, implicit $sp, implicit $s8, implicit-def $s0
1710   %res = call ghccc float @different_call_conv_target(float %x)
1711   ret float %res
1714 define <2 x i32> @test_shufflevector_s32_v2s32(i32 %arg) {
1715 ; CHECK-LABEL: name: test_shufflevector_s32_v2s32
1716 ; CHECK: [[ARG:%[0-9]+]]:_(s32) = COPY $w0
1717 ; CHECK-DAG: [[UNDEF:%[0-9]+]]:_(s32) = G_IMPLICIT_DEF
1718 ; CHECK: [[VEC:%[0-9]+]]:_(<2 x s32>) = G_SHUFFLE_VECTOR [[ARG]](s32), [[UNDEF]], shufflemask(0, 0)
1719 ; CHECK: $d0 = COPY [[VEC]](<2 x s32>)
1720   %vec = insertelement <1 x i32> undef, i32 %arg, i32 0
1721   %res = shufflevector <1 x i32> %vec, <1 x i32> undef, <2 x i32> zeroinitializer
1722   ret <2 x i32> %res
1725 define i32 @test_shufflevector_v2s32_s32(<2 x i32> %arg) {
1726 ; CHECK-LABEL: name: test_shufflevector_v2s32_s32
1727 ; CHECK: [[ARG:%[0-9]+]]:_(<2 x s32>) = COPY $d0
1728 ; CHECK: [[RES:%[0-9]+]]:_(s32) = G_SHUFFLE_VECTOR [[ARG]](<2 x s32>), [[UNDEF]], shufflemask(1)
1729 ; CHECK: $w0 = COPY [[RES]](s32)
1730   %vec = shufflevector <2 x i32> %arg, <2 x i32> undef, <1 x i32> <i32 1>
1731   %res = extractelement <1 x i32> %vec, i32 0
1732   ret i32 %res
1735 define <2 x i32> @test_shufflevector_v2s32_v2s32_undef(<2 x i32> %arg) {
1736 ; CHECK-LABEL: name: test_shufflevector_v2s32_v2s32_undef
1737 ; CHECK: [[ARG:%[0-9]+]]:_(<2 x s32>) = COPY $d0
1738 ; CHECK-DAG: [[UNDEF:%[0-9]+]]:_(<2 x s32>) = G_IMPLICIT_DEF
1739 ; CHECK: [[VEC:%[0-9]+]]:_(<2 x s32>) = G_SHUFFLE_VECTOR [[ARG]](<2 x s32>), [[UNDEF]], shufflemask(undef, undef)
1740 ; CHECK: $d0 = COPY [[VEC]](<2 x s32>)
1741   %res = shufflevector <2 x i32> %arg, <2 x i32> undef, <2 x i32> undef
1742   ret <2 x i32> %res
1745 define <2 x i32> @test_shufflevector_v2s32_v2s32_undef_0(<2 x i32> %arg) {
1746 ; CHECK-LABEL: name: test_shufflevector_v2s32_v2s32_undef_0
1747 ; CHECK: [[ARG:%[0-9]+]]:_(<2 x s32>) = COPY $d0
1748 ; CHECK-DAG: [[UNDEF:%[0-9]+]]:_(<2 x s32>) = G_IMPLICIT_DEF
1749 ; CHECK: [[VEC:%[0-9]+]]:_(<2 x s32>) = G_SHUFFLE_VECTOR [[ARG]](<2 x s32>), [[UNDEF]], shufflemask(undef, 0)
1750 ; CHECK: $d0 = COPY [[VEC]](<2 x s32>)
1751   %res = shufflevector <2 x i32> %arg, <2 x i32> undef, <2 x i32> <i32 undef, i32 0>
1752   ret <2 x i32> %res
1755 define <2 x i32> @test_shufflevector_v2s32_v2s32_0_undef(<2 x i32> %arg) {
1756 ; CHECK-LABEL: name: test_shufflevector_v2s32_v2s32_0_undef
1757 ; CHECK: [[ARG:%[0-9]+]]:_(<2 x s32>) = COPY $d0
1758 ; CHECK-DAG: [[UNDEF:%[0-9]+]]:_(<2 x s32>) = G_IMPLICIT_DEF
1759 ; CHECK: [[VEC:%[0-9]+]]:_(<2 x s32>) = G_SHUFFLE_VECTOR [[ARG]](<2 x s32>), [[UNDEF]], shufflemask(0, undef)
1760 ; CHECK: $d0 = COPY [[VEC]](<2 x s32>)
1761   %res = shufflevector <2 x i32> %arg, <2 x i32> undef, <2 x i32> <i32 0, i32 undef>
1762   ret <2 x i32> %res
1765 define i32 @test_shufflevector_v2s32_v3s32(<2 x i32> %arg) {
1766 ; CHECK-LABEL: name: test_shufflevector_v2s32_v3s32
1767 ; CHECK: [[ARG:%[0-9]+]]:_(<2 x s32>) = COPY $d0
1768 ; CHECK-DAG: [[UNDEF:%[0-9]+]]:_(<2 x s32>) = G_IMPLICIT_DEF
1769 ; CHECK: [[VEC:%[0-9]+]]:_(<3 x s32>) = G_SHUFFLE_VECTOR [[ARG]](<2 x s32>), [[UNDEF]], shufflemask(1, 0, 1)
1770 ; CHECK: G_EXTRACT_VECTOR_ELT [[VEC]](<3 x s32>)
1771   %vec = shufflevector <2 x i32> %arg, <2 x i32> undef, <3 x i32> <i32 1, i32 0, i32 1>
1772   %res = extractelement <3 x i32> %vec, i32 0
1773   ret i32 %res
1776 define <4 x i32> @test_shufflevector_v2s32_v4s32(<2 x i32> %arg1, <2 x i32> %arg2) {
1777 ; CHECK-LABEL: name: test_shufflevector_v2s32_v4s32
1778 ; CHECK: [[ARG1:%[0-9]+]]:_(<2 x s32>) = COPY $d0
1779 ; CHECK: [[ARG2:%[0-9]+]]:_(<2 x s32>) = COPY $d1
1780 ; CHECK: [[VEC:%[0-9]+]]:_(<4 x s32>) = G_SHUFFLE_VECTOR [[ARG1]](<2 x s32>), [[ARG2]], shufflemask(0, 1, 2, 3)
1781 ; CHECK: $q0 = COPY [[VEC]](<4 x s32>)
1782   %res = shufflevector <2 x i32> %arg1, <2 x i32> %arg2, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
1783   ret <4 x i32> %res
1786 define <2 x i32> @test_shufflevector_v4s32_v2s32(<4 x i32> %arg) {
1787 ; CHECK-LABEL: name: test_shufflevector_v4s32_v2s32
1788 ; CHECK: [[ARG:%[0-9]+]]:_(<4 x s32>) = COPY $q0
1789 ; CHECK-DAG: [[UNDEF:%[0-9]+]]:_(<4 x s32>) = G_IMPLICIT_DEF
1790 ; CHECK: [[VEC:%[0-9]+]]:_(<2 x s32>) = G_SHUFFLE_VECTOR [[ARG]](<4 x s32>), [[UNDEF]], shufflemask(1, 3)
1791 ; CHECK: $d0 = COPY [[VEC]](<2 x s32>)
1792   %res = shufflevector <4 x i32> %arg, <4 x i32> undef, <2 x i32> <i32 1, i32 3>
1793   ret <2 x i32> %res
1797 define <16 x i8> @test_shufflevector_v8s8_v16s8(<8 x i8> %arg1, <8 x i8> %arg2) {
1798 ; CHECK-LABEL: name: test_shufflevector_v8s8_v16s8
1799 ; CHECK: [[ARG1:%[0-9]+]]:_(<8 x s8>) = COPY $d0
1800 ; CHECK: [[ARG2:%[0-9]+]]:_(<8 x s8>) = COPY $d1
1801 ; CHECK: [[VEC:%[0-9]+]]:_(<16 x s8>) = G_SHUFFLE_VECTOR [[ARG1]](<8 x s8>), [[ARG2]], shufflemask(0, 8, 1, 9, 2, 10, 3, 11, 4, 12, 5, 13, 6, 14, 7, 15)
1802 ; CHECK: $q0 = COPY [[VEC]](<16 x s8>)
1803   %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>
1804   ret <16 x i8> %res
1807 ; CHECK-LABEL: test_constant_vector
1808 ; CHECK: [[UNDEF:%[0-9]+]]:_(s16) = G_IMPLICIT_DEF
1809 ; CHECK: [[F:%[0-9]+]]:_(s16) = G_FCONSTANT half 0xH3C00
1810 ; CHECK: [[M:%[0-9]+]]:_(<4 x s16>) = G_BUILD_VECTOR [[UNDEF]](s16), [[UNDEF]](s16), [[UNDEF]](s16), [[F]](s16)
1811 ; CHECK: $d0 = COPY [[M]](<4 x s16>)
1812 define <4 x half> @test_constant_vector() {
1813   ret <4 x half> <half undef, half undef, half undef, half 0xH3C00>
1816 define i32 @test_target_mem_intrinsic(ptr %addr) {
1817 ; CHECK-LABEL: name: test_target_mem_intrinsic
1818 ; CHECK: [[ADDR:%[0-9]+]]:_(p0) = COPY $x0
1819 ; CHECK: [[VAL:%[0-9]+]]:_(s64) = G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aarch64.ldxr), [[ADDR]](p0) :: (volatile load (s32) from %ir.addr)
1820 ; CHECK: G_TRUNC [[VAL]](s64)
1821   %val = call i64 @llvm.aarch64.ldxr.p0(ptr elementtype(i32) %addr)
1822   %trunc = trunc i64 %val to i32
1823   ret i32 %trunc
1826 declare i64 @llvm.aarch64.ldxr.p0(ptr) nounwind
1828 %zerosize_type = type {}
1830 define %zerosize_type @test_empty_load_store(ptr %ptr, %zerosize_type %in) noinline optnone {
1831 ; CHECK-LABEL: name: test_empty_load_store
1832 ; CHECK-NOT: G_STORE
1833 ; CHECK-NOT: G_LOAD
1834 ; CHECK: RET_ReallyLR
1835 entry:
1836   store %zerosize_type undef, ptr undef, align 4
1837   %val = load %zerosize_type, ptr %ptr, align 4
1838   ret %zerosize_type %in
1842 define i64 @test_phi_loop(i32 %n) {
1843 ; CHECK-LABEL: name: test_phi_loop
1844 ; CHECK: [[ARG1:%[0-9]+]]:_(s32) = COPY $w0
1845 ; CHECK: [[CST1:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
1846 ; CHECK: [[CST2:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
1847 ; CHECK: [[CST3:%[0-9]+]]:_(s64) = G_CONSTANT i64 0
1848 ; CHECK: [[CST4:%[0-9]+]]:_(s64) = G_CONSTANT i64 1
1850 ; CHECK: [[PN1:%[0-9]+]]:_(s32) = G_PHI [[ARG1]](s32), %bb.1, [[SUB:%[0-9]+]](s32), %bb.2
1851 ; CHECK: [[PN2:%[0-9]+]]:_(s64) = G_PHI [[CST3]](s64), %bb.1, [[PN3:%[0-9]+]](s64), %bb.2
1852 ; CHECK: [[PN3]]:_(s64) = G_PHI [[CST4]](s64), %bb.1, [[ADD:%[0-9]+]](s64), %bb.2
1853 ; CHECK: [[ADD]]:_(s64) = G_ADD [[PN2]], [[PN3]]
1854 ; CHECK: [[SUB]]:_(s32) = G_SUB [[PN1]], [[CST1]]
1855 ; CHECK: [[CMP:%[0-9]+]]:_(s1) = G_ICMP intpred(sle), [[PN1]](s32), [[CST2]]
1856 ; CHECK: G_BRCOND [[CMP]](s1), %bb.3
1857 ; CHECK: G_BR %bb.2
1859 ; CHECK: $x0 = COPY [[PN2]](s64)
1860 ; CHECK: RET_ReallyLR implicit $x0
1861 entry:
1862   br label %loop
1864 loop:
1865   %counter = phi i32 [ %n, %entry ], [ %counter.dec, %loop ]
1866   %elem = phi { i64, i64 } [ { i64 0, i64 1 }, %entry ], [ %updated, %loop ]
1867   %prev = extractvalue { i64, i64 } %elem, 0
1868   %curr = extractvalue { i64, i64 } %elem, 1
1869   %next = add i64 %prev, %curr
1870   %shifted = insertvalue { i64, i64 } %elem, i64 %curr, 0
1871   %updated = insertvalue { i64, i64 } %shifted, i64 %next, 1
1872   %counter.dec = sub i32 %counter, 1
1873   %cond = icmp sle i32 %counter, 0
1874   br i1 %cond, label %exit, label %loop
1876 exit:
1877   %res = extractvalue { i64, i64 } %elem, 0
1878   ret i64 %res
1881 define void @test_phi_diamond(ptr %a.ptr, ptr %b.ptr, i1 %selector, ptr %dst) {
1882 ; CHECK-LABEL: name: test_phi_diamond
1883 ; CHECK: [[ARG1:%[0-9]+]]:_(p0) = COPY $x0
1884 ; CHECK: [[ARG2:%[0-9]+]]:_(p0) = COPY $x1
1885 ; CHECK: [[ARG3:%[0-9]+]]:_(s32) = COPY $w2
1886 ; CHECK: [[TRUNC8:%[0-9]+]]:_(s8) = G_TRUNC [[ARG3]]
1887 ; CHECK: [[ARG4:%[0-9]+]]:_(p0) = COPY $x3
1888 ; CHECK: [[TRUNCASSERT:%[0-9]+]]:_(s8) = G_ASSERT_ZEXT [[TRUNC8]], 1
1889 ; CHECK: [[TRUNC:%[0-9]+]]:_(s1) = G_TRUNC [[TRUNCASSERT]]
1890 ; CHECK: G_BRCOND [[TRUNC]](s1), %bb.2
1891 ; CHECK: G_BR %bb.3
1893 ; CHECK: [[LD1:%[0-9]+]]:_(s8) = G_LOAD [[ARG1]](p0) :: (load (s8) from %ir.a.ptr, align 4)
1894 ; CHECK: [[CST1:%[0-9]+]]:_(s64) = G_CONSTANT i64 2
1895 ; CHECK: [[GEP1:%[0-9]+]]:_(p0) = G_PTR_ADD [[ARG1]], [[CST1]](s64)
1896 ; CHECK: [[LD2:%[0-9]+]]:_(s16) = G_LOAD [[GEP1]](p0) :: (load (s16) from %ir.a.ptr + 2)
1897 ; CHECK: [[CST2:%[0-9]+]]:_(s64) = G_CONSTANT i64 4
1898 ; CHECK: [[GEP2:%[0-9]+]]:_(p0) = G_PTR_ADD [[ARG1]], [[CST2]](s64)
1899 ; CHECK: [[LD3:%[0-9]+]]:_(s32) = G_LOAD [[GEP2]](p0) :: (load (s32) from %ir.a.ptr + 4)
1900 ; CHECK: G_BR %bb.4
1902 ; CHECK: [[LD4:%[0-9]+]]:_(s8) = G_LOAD [[ARG2]](p0) :: (load (s8) from %ir.b.ptr, align 4)
1903 ; CHECK: [[CST3:%[0-9]+]]:_(s64) = G_CONSTANT i64 2
1904 ; CHECK: [[GEP3:%[0-9]+]]:_(p0) = G_PTR_ADD [[ARG2]], [[CST3]](s64)
1905 ; CHECK: [[LD5:%[0-9]+]]:_(s16) = G_LOAD [[GEP3]](p0) :: (load (s16) from %ir.b.ptr + 2)
1906 ; CHECK: [[CST4:%[0-9]+]]:_(s64) = G_CONSTANT i64 4
1907 ; CHECK: [[GEP4:%[0-9]+]]:_(p0) = G_PTR_ADD [[ARG2]], [[CST4]](s64)
1908 ; CHECK: [[LD6:%[0-9]+]]:_(s32) = G_LOAD [[GEP4]](p0) :: (load (s32) from %ir.b.ptr + 4)
1910 ; CHECK: [[PN1:%[0-9]+]]:_(s8) = G_PHI [[LD1]](s8), %bb.2, [[LD4]](s8), %bb.3
1911 ; CHECK: [[PN2:%[0-9]+]]:_(s16) = G_PHI [[LD2]](s16), %bb.2, [[LD5]](s16), %bb.3
1912 ; CHECK: [[PN3:%[0-9]+]]:_(s32) = G_PHI [[LD3]](s32), %bb.2, [[LD6]](s32), %bb.3
1913 ; CHECK: G_STORE [[PN1]](s8), [[ARG4]](p0) :: (store (s8) into %ir.dst, align 4)
1914 ; CHECK: [[CST5:%[0-9]+]]:_(s64) = G_CONSTANT i64 2
1915 ; CHECK: [[GEP5:%[0-9]+]]:_(p0) = G_PTR_ADD [[ARG4]], [[CST5]](s64)
1916 ; CHECK: G_STORE [[PN2]](s16), [[GEP5]](p0) :: (store (s16) into %ir.dst + 2)
1917 ; CHECK: [[CST6:%[0-9]+]]:_(s64) = G_CONSTANT i64 4
1918 ; CHECK: [[GEP6:%[0-9]+]]:_(p0) = G_PTR_ADD [[ARG4]], [[CST6]](s64)
1919 ; CHECK: G_STORE [[PN3]](s32), [[GEP6]](p0) :: (store (s32) into %ir.dst + 4)
1920 ; CHECK: RET_ReallyLR
1922 entry:
1923   br i1 %selector, label %store.a, label %store.b
1925 store.a:
1926   %a = load { i8, i16, i32 }, ptr %a.ptr
1927   br label %join
1929 store.b:
1930   %b = load { i8, i16, i32 }, ptr %b.ptr
1931   br label %join
1933 join:
1934   %v = phi { i8, i16, i32 } [ %a, %store.a ], [ %b, %store.b ]
1935   store { i8, i16, i32 } %v, ptr %dst
1936   ret void
1939 %agg.inner.inner = type {i64, i64}
1940 %agg.inner = type {i16, i8, %agg.inner.inner }
1941 %agg.nested = type {i32, i32, %agg.inner, i32}
1943 define void @test_nested_aggregate_const(ptr %ptr) {
1944 ; CHECK-LABEL: name: test_nested_aggregate_const
1945 ; CHECK: [[BASE:%[0-9]+]]:_(p0) = COPY $x0
1946 ; CHECK: [[CST1:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
1947 ; CHECK: [[CST2:%[0-9]+]]:_(s16) = G_CONSTANT i16 2
1948 ; CHECK: [[CST3:%[0-9]+]]:_(s8) = G_CONSTANT i8 3
1949 ; CHECK: [[CST4:%[0-9]+]]:_(s64) = G_CONSTANT i64 5
1950 ; CHECK: [[CST5:%[0-9]+]]:_(s64) = G_CONSTANT i64 8
1951 ; CHECK: [[CST6:%[0-9]+]]:_(s32) = G_CONSTANT i32 13
1952 ; CHECK: G_STORE [[CST1]](s32), [[BASE]](p0) :: (store (s32) into %ir.ptr, align 8)
1953 ; CHECK: [[CST7:%[0-9]+]]:_(s64) = G_CONSTANT i64 4
1954 ; CHECK: [[GEP1:%[0-9]+]]:_(p0) = G_PTR_ADD [[BASE]], [[CST7]](s64)
1955 ; CHECK: G_STORE [[CST1]](s32), [[GEP1]](p0) :: (store (s32) into %ir.ptr + 4)
1956 ; CHECK: [[CST8:%[0-9]+]]:_(s64) = G_CONSTANT i64 8
1957 ; CHECK: [[GEP2:%[0-9]+]]:_(p0) = G_PTR_ADD [[BASE]], [[CST8]](s64)
1958 ; CHECK: G_STORE [[CST2]](s16), [[GEP2]](p0) :: (store (s16) into %ir.ptr + 8, align 8)
1959 ; CHECK: [[CST9:%[0-9]+]]:_(s64) = G_CONSTANT i64 10
1960 ; CHECK: [[GEP3:%[0-9]+]]:_(p0) = G_PTR_ADD [[BASE]], [[CST9]](s64)
1961 ; CHECK: G_STORE [[CST3]](s8), [[GEP3]](p0) :: (store (s8) into %ir.ptr + 10, align 2)
1962 ; CHECK: [[CST10:%[0-9]+]]:_(s64) = G_CONSTANT i64 16
1963 ; CHECK: [[GEP4:%[0-9]+]]:_(p0) = G_PTR_ADD [[BASE]], [[CST10]](s64)
1964 ; CHECK: G_STORE [[CST4]](s64), [[GEP4]](p0) :: (store (s64) into %ir.ptr + 16)
1965 ; CHECK: [[CST11:%[0-9]+]]:_(s64) = G_CONSTANT i64 24
1966 ; CHECK: [[GEP5:%[0-9]+]]:_(p0) = G_PTR_ADD [[BASE]], [[CST11]](s64)
1967 ; CHECK: G_STORE [[CST5]](s64), [[GEP5]](p0) :: (store (s64) into %ir.ptr + 24)
1968 ; CHECK: [[CST12:%[0-9]+]]:_(s64) = G_CONSTANT i64 32
1969 ; CHECK: [[GEP6:%[0-9]+]]:_(p0) = G_PTR_ADD [[BASE]], [[CST12]](s64)
1970 ; CHECK: G_STORE [[CST6]](s32), [[GEP6]](p0) :: (store (s32) into %ir.ptr + 32, align 8)
1971   store %agg.nested { i32 1, i32 1, %agg.inner { i16 2, i8 3, %agg.inner.inner {i64 5, i64 8} }, i32 13}, ptr %ptr
1972   ret void
1975 define i1 @return_i1_zext() {
1976 ; AAPCS ABI says that booleans can only be 1 or 0, so we need to zero-extend.
1977 ; CHECK-LABEL: name: return_i1_zext
1978 ; CHECK: [[CST:%[0-9]+]]:_(s1) = G_CONSTANT i1 true
1979 ; CHECK: [[ZEXT:%[0-9]+]]:_(s8) = G_ZEXT [[CST]](s1)
1980 ; CHECK: [[ANYEXT:%[0-9]+]]:_(s32) = G_ANYEXT [[ZEXT]](s8)
1981 ; CHECK: $w0 = COPY [[ANYEXT]](s32)
1982 ; CHECK: RET_ReallyLR implicit $w0
1983   ret i1 true
1986 ; Try one cmpxchg
1987 define i32 @test_atomic_cmpxchg_1(ptr %addr) {
1988 ; CHECK-LABEL: name: test_atomic_cmpxchg_1
1989 ; CHECK:       bb.1.entry:
1990 ; CHECK-NEXT:  successors: %bb.{{[^)]+}}
1991 ; CHECK-NEXT:  liveins: $x0
1992 ; CHECK:         [[ADDR:%[0-9]+]]:_(p0) = COPY $x0
1993 ; CHECK-NEXT:    [[OLDVAL:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
1994 ; CHECK-NEXT:    [[NEWVAL:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
1995 ; CHECK:       bb.2.repeat:
1996 ; CHECK-NEXT:    successors: %bb.3({{[^)]+}}), %bb.2({{[^)]+}})
1997 ; CHECK:         [[OLDVALRES:%[0-9]+]]:_(s32), [[SUCCESS:%[0-9]+]]:_(s1) = G_ATOMIC_CMPXCHG_WITH_SUCCESS [[ADDR]](p0), [[OLDVAL]], [[NEWVAL]] :: (load store monotonic monotonic (s32) on %ir.addr)
1998 ; CHECK-NEXT:    G_BRCOND [[SUCCESS]](s1), %bb.3
1999 ; CHECK-NEXT:    G_BR %bb.2
2000 ; CHECK:       bb.3.done:
2001 entry:
2002   br label %repeat
2003 repeat:
2004   %val_success = cmpxchg ptr %addr, i32 0, i32 1 monotonic monotonic
2005   %value_loaded = extractvalue { i32, i1 } %val_success, 0
2006   %success = extractvalue { i32, i1 } %val_success, 1
2007   br i1 %success, label %done, label %repeat
2008 done:
2009   ret i32 %value_loaded
2012 ; Try one cmpxchg
2013 define i32 @test_weak_atomic_cmpxchg_1(ptr %addr) {
2014 ; CHECK-LABEL: name: test_weak_atomic_cmpxchg_1
2015 ; CHECK:       bb.1.entry:
2016 ; CHECK-NEXT:  successors: %bb.{{[^)]+}}
2017 ; CHECK-NEXT:  liveins: $x0
2018 ; CHECK:         [[ADDR:%[0-9]+]]:_(p0) = COPY $x0
2019 ; CHECK-NEXT:    [[OLDVAL:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
2020 ; CHECK-NEXT:    [[NEWVAL:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
2021 ; CHECK:       bb.2.repeat:
2022 ; CHECK-NEXT:    successors: %bb.3({{[^)]+}}), %bb.2({{[^)]+}})
2023 ; CHECK:         [[OLDVALRES:%[0-9]+]]:_(s32), [[SUCCESS:%[0-9]+]]:_(s1) = G_ATOMIC_CMPXCHG_WITH_SUCCESS [[ADDR]](p0), [[OLDVAL]], [[NEWVAL]] :: (load store monotonic monotonic (s32) on %ir.addr)
2024 ; CHECK-NEXT:    G_BRCOND [[SUCCESS]](s1), %bb.3
2025 ; CHECK-NEXT:    G_BR %bb.2
2026 ; CHECK:       bb.3.done:
2027 entry:
2028   br label %repeat
2029 repeat:
2030   %val_success = cmpxchg weak ptr %addr, i32 0, i32 1 monotonic monotonic
2031   %value_loaded = extractvalue { i32, i1 } %val_success, 0
2032   %success = extractvalue { i32, i1 } %val_success, 1
2033   br i1 %success, label %done, label %repeat
2034 done:
2035   ret i32 %value_loaded
2038 ; Try one cmpxchg with a small type and high atomic ordering.
2039 define i16 @test_atomic_cmpxchg_2(ptr %addr) {
2040 ; CHECK-LABEL: name: test_atomic_cmpxchg_2
2041 ; CHECK:       bb.1.entry:
2042 ; CHECK-NEXT:  successors: %bb.2({{[^)]+}})
2043 ; CHECK-NEXT:  liveins: $x0
2044 ; CHECK:         [[ADDR:%[0-9]+]]:_(p0) = COPY $x0
2045 ; CHECK-NEXT:    [[OLDVAL:%[0-9]+]]:_(s16) = G_CONSTANT i16 0
2046 ; CHECK-NEXT:    [[NEWVAL:%[0-9]+]]:_(s16) = G_CONSTANT i16 1
2047 ; CHECK:       bb.2.repeat:
2048 ; CHECK-NEXT:    successors: %bb.3({{[^)]+}}), %bb.2({{[^)]+}})
2049 ; CHECK:         [[OLDVALRES:%[0-9]+]]:_(s16), [[SUCCESS:%[0-9]+]]:_(s1) = G_ATOMIC_CMPXCHG_WITH_SUCCESS [[ADDR]](p0), [[OLDVAL]], [[NEWVAL]] :: (load store seq_cst seq_cst (s16) on %ir.addr)
2050 ; CHECK-NEXT:    G_BRCOND [[SUCCESS]](s1), %bb.3
2051 ; CHECK-NEXT:    G_BR %bb.2
2052 ; CHECK:       bb.3.done:
2053 entry:
2054   br label %repeat
2055 repeat:
2056   %val_success = cmpxchg ptr %addr, i16 0, i16 1 seq_cst seq_cst
2057   %value_loaded = extractvalue { i16, i1 } %val_success, 0
2058   %success = extractvalue { i16, i1 } %val_success, 1
2059   br i1 %success, label %done, label %repeat
2060 done:
2061   ret i16 %value_loaded
2064 ; Try one cmpxchg where the success order and failure order differ.
2065 define i64 @test_atomic_cmpxchg_3(ptr %addr) {
2066 ; CHECK-LABEL: name: test_atomic_cmpxchg_3
2067 ; CHECK:       bb.1.entry:
2068 ; CHECK-NEXT:  successors: %bb.2({{[^)]+}})
2069 ; CHECK-NEXT:  liveins: $x0
2070 ; CHECK:         [[ADDR:%[0-9]+]]:_(p0) = COPY $x0
2071 ; CHECK-NEXT:    [[OLDVAL:%[0-9]+]]:_(s64) = G_CONSTANT i64 0
2072 ; CHECK-NEXT:    [[NEWVAL:%[0-9]+]]:_(s64) = G_CONSTANT i64 1
2073 ; CHECK:       bb.2.repeat:
2074 ; CHECK-NEXT:    successors: %bb.3({{[^)]+}}), %bb.2({{[^)]+}})
2075 ; CHECK:         [[OLDVALRES:%[0-9]+]]:_(s64), [[SUCCESS:%[0-9]+]]:_(s1) = G_ATOMIC_CMPXCHG_WITH_SUCCESS [[ADDR]](p0), [[OLDVAL]], [[NEWVAL]] :: (load store seq_cst acquire (s64) on %ir.addr)
2076 ; CHECK-NEXT:    G_BRCOND [[SUCCESS]](s1), %bb.3
2077 ; CHECK-NEXT:    G_BR %bb.2
2078 ; CHECK:       bb.3.done:
2079 entry:
2080   br label %repeat
2081 repeat:
2082   %val_success = cmpxchg ptr %addr, i64 0, i64 1 seq_cst acquire
2083   %value_loaded = extractvalue { i64, i1 } %val_success, 0
2084   %success = extractvalue { i64, i1 } %val_success, 1
2085   br i1 %success, label %done, label %repeat
2086 done:
2087   ret i64 %value_loaded
2090 ; Try a monotonic atomicrmw xchg
2091 define i32 @test_atomicrmw_xchg(ptr %addr) {
2092 ; CHECK-LABEL: name: test_atomicrmw_xchg
2093 ; CHECK:       bb.1 (%ir-block.{{[0-9]+}}):
2094 ; CHECK-NEXT:  liveins: $x0
2095 ; CHECK:         [[ADDR:%[0-9]+]]:_(p0) = COPY $x0
2096 ; CHECK-NEXT:    [[VAL:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
2097 ; CHECK-NEXT:    [[OLDVALRES:%[0-9]+]]:_(s32) = G_ATOMICRMW_XCHG [[ADDR]](p0), [[VAL]] :: (load store monotonic (s32) on %ir.addr)
2098   %oldval = atomicrmw xchg ptr %addr, i32 1 monotonic
2099   ret i32 %oldval
2102 ; Try an acquire atomicrmw add
2103 define i32 @test_atomicrmw_add(ptr %addr) {
2104 ; CHECK-LABEL: name: test_atomicrmw_add
2105 ; CHECK:       bb.1 (%ir-block.{{[0-9]+}}):
2106 ; CHECK-NEXT:  liveins: $x0
2107 ; CHECK:         [[ADDR:%[0-9]+]]:_(p0) = COPY $x0
2108 ; CHECK-NEXT:    [[VAL:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
2109 ; CHECK-NEXT:    [[OLDVALRES:%[0-9]+]]:_(s32) = G_ATOMICRMW_ADD [[ADDR]](p0), [[VAL]] :: (load store acquire (s32) on %ir.addr)
2110   %oldval = atomicrmw add ptr %addr, i32 1 acquire
2111   ret i32 %oldval
2114 ; Try a release atomicrmw sub
2115 define i32 @test_atomicrmw_sub(ptr %addr) {
2116 ; CHECK-LABEL: name: test_atomicrmw_sub
2117 ; CHECK:       bb.1 (%ir-block.{{[0-9]+}}):
2118 ; CHECK-NEXT:  liveins: $x0
2119 ; CHECK:         [[ADDR:%[0-9]+]]:_(p0) = COPY $x0
2120 ; CHECK-NEXT:    [[VAL:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
2121 ; CHECK-NEXT:    [[OLDVALRES:%[0-9]+]]:_(s32) = G_ATOMICRMW_SUB [[ADDR]](p0), [[VAL]] :: (load store release (s32) on %ir.addr)
2122   %oldval = atomicrmw sub ptr %addr, i32 1 release
2123   ret i32 %oldval
2126 ; Try an acq_rel atomicrmw and
2127 define i32 @test_atomicrmw_and(ptr %addr) {
2128 ; CHECK-LABEL: name: test_atomicrmw_and
2129 ; CHECK:       bb.1 (%ir-block.{{[0-9]+}}):
2130 ; CHECK-NEXT:  liveins: $x0
2131 ; CHECK:         [[ADDR:%[0-9]+]]:_(p0) = COPY $x0
2132 ; CHECK-NEXT:    [[VAL:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
2133 ; CHECK-NEXT:    [[OLDVALRES:%[0-9]+]]:_(s32) = G_ATOMICRMW_AND [[ADDR]](p0), [[VAL]] :: (load store acq_rel (s32) on %ir.addr)
2134   %oldval = atomicrmw and ptr %addr, i32 1 acq_rel
2135   ret i32 %oldval
2138 ; Try an seq_cst atomicrmw nand. NAND isn't supported by LSE, so it
2139 ; expands to G_ATOMIC_CMPXCHG_WITH_SUCCESS.
2140 define i32 @test_atomicrmw_nand(ptr %addr) {
2141 ; CHECK-LABEL: name: test_atomicrmw_nand
2142 ; CHECK:       bb.1 (%ir-block.{{[0-9]+}}):
2143 ; CHECK-NEXT:  successors: %bb.2(0x80000000)
2144 ; CHECK-NEXT:  liveins: $x0
2145 ; CHECK:         [[ADDR:%[0-9]+]]:_(p0) = COPY $x0
2146 ; CHECK-NEXT:    [[VAL:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
2147 ; CHECK-NEXT:    [[NEG1:%[0-9]+]]:_(s32) = G_CONSTANT i32 -1
2148 ; CHECK-NEXT:    [[OLDVALSTART:%[0-9]+]]:_(s32) = G_LOAD [[ADDR]](p0) :: (load (s32) from %ir.addr)
2149 ; CHECK:       bb.2.atomicrmw.start:
2150 ; CHECK-NEXT:    successors: %bb.3({{[^)]+}}), %bb.2({{[^)]+}})
2151 ; CHECK:         [[OLDVAL:%[0-9]+]]:_(s32) = G_PHI [[OLDVALSTART]](s32), %bb.1, [[OLDVALRES:%[0-9]+]](s32), %bb.2
2152 ; CHECK-NEXT:    [[AND:%[0-9]+]]:_(s32) = G_AND [[OLDVAL]], [[VAL]]
2153 ; CHECK-NEXT:    [[NEWVAL:%[0-9]+]]:_(s32) = G_XOR [[AND]], [[NEG1]]
2154 ; CHECK:         [[OLDVALRES]]:_(s32), [[SUCCESS:%[0-9]+]]:_(s1) = G_ATOMIC_CMPXCHG_WITH_SUCCESS [[ADDR]](p0), [[OLDVAL]], [[NEWVAL]] :: (load store seq_cst seq_cst (s32) on %ir.addr)
2155 ; CHECK-NEXT:    G_BRCOND [[SUCCESS]](s1), %bb.3
2156 ; CHECK-NEXT:    G_BR %bb.2
2157 ; CHECK:       bb.3.atomicrmw.end:
2158   %oldval = atomicrmw nand ptr %addr, i32 1 seq_cst
2159   ret i32 %oldval
2162 ; Try an seq_cst atomicrmw or
2163 define i32 @test_atomicrmw_or(ptr %addr) {
2164 ; CHECK-LABEL: name: test_atomicrmw_or
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]+]]:_(s32) = G_CONSTANT i32 1
2169 ; CHECK-NEXT:    [[OLDVALRES:%[0-9]+]]:_(s32) = G_ATOMICRMW_OR [[ADDR]](p0), [[VAL]] :: (load store seq_cst (s32) on %ir.addr)
2170   %oldval = atomicrmw or ptr %addr, i32 1 seq_cst
2171   ret i32 %oldval
2174 ; Try an seq_cst atomicrmw xor
2175 define i32 @test_atomicrmw_xor(ptr %addr) {
2176 ; CHECK-LABEL: name: test_atomicrmw_xor
2177 ; CHECK:       bb.1 (%ir-block.{{[0-9]+}}):
2178 ; CHECK-NEXT:  liveins: $x0
2179 ; CHECK:         [[ADDR:%[0-9]+]]:_(p0) = COPY $x0
2180 ; CHECK-NEXT:    [[VAL:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
2181 ; CHECK-NEXT:    [[OLDVALRES:%[0-9]+]]:_(s32) = G_ATOMICRMW_XOR [[ADDR]](p0), [[VAL]] :: (load store seq_cst (s32) on %ir.addr)
2182   %oldval = atomicrmw xor ptr %addr, i32 1 seq_cst
2183   ret i32 %oldval
2186 ; Try an seq_cst atomicrmw min
2187 define i32 @test_atomicrmw_min(ptr %addr) {
2188 ; CHECK-LABEL: name: test_atomicrmw_min
2189 ; CHECK:       bb.1 (%ir-block.{{[0-9]+}}):
2190 ; CHECK-NEXT:  liveins: $x0
2191 ; CHECK:         [[ADDR:%[0-9]+]]:_(p0) = COPY $x0
2192 ; CHECK-NEXT:    [[VAL:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
2193 ; CHECK-NEXT:    [[OLDVALRES:%[0-9]+]]:_(s32) = G_ATOMICRMW_MIN [[ADDR]](p0), [[VAL]] :: (load store seq_cst (s32) on %ir.addr)
2194   %oldval = atomicrmw min ptr %addr, i32 1 seq_cst
2195   ret i32 %oldval
2198 ; Try an seq_cst atomicrmw max
2199 define i32 @test_atomicrmw_max(ptr %addr) {
2200 ; CHECK-LABEL: name: test_atomicrmw_max
2201 ; CHECK:       bb.1 (%ir-block.{{[0-9]+}}):
2202 ; CHECK-NEXT:  liveins: $x0
2203 ; CHECK:         [[ADDR:%[0-9]+]]:_(p0) = COPY $x0
2204 ; CHECK-NEXT:    [[VAL:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
2205 ; CHECK-NEXT:    [[OLDVALRES:%[0-9]+]]:_(s32) = G_ATOMICRMW_MAX [[ADDR]](p0), [[VAL]] :: (load store seq_cst (s32) on %ir.addr)
2206   %oldval = atomicrmw max ptr %addr, i32 1 seq_cst
2207   ret i32 %oldval
2210 ; Try an seq_cst atomicrmw unsigned min
2211 define i32 @test_atomicrmw_umin(ptr %addr) {
2212 ; CHECK-LABEL: name: test_atomicrmw_umin
2213 ; CHECK:       bb.1 (%ir-block.{{[0-9]+}}):
2214 ; CHECK-NEXT:  liveins: $x0
2215 ; CHECK:         [[ADDR:%[0-9]+]]:_(p0) = COPY $x0
2216 ; CHECK-NEXT:    [[VAL:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
2217 ; CHECK-NEXT:    [[OLDVALRES:%[0-9]+]]:_(s32) = G_ATOMICRMW_UMIN [[ADDR]](p0), [[VAL]] :: (load store seq_cst (s32) on %ir.addr)
2218   %oldval = atomicrmw umin ptr %addr, i32 1 seq_cst
2219   ret i32 %oldval
2222 ; Try an seq_cst atomicrmw unsigned max
2223 define i32 @test_atomicrmw_umax(ptr %addr) {
2224 ; CHECK-LABEL: name: test_atomicrmw_umax
2225 ; CHECK:       bb.1 (%ir-block.{{[0-9]+}}):
2226 ; CHECK-NEXT:  liveins: $x0
2227 ; CHECK:         [[ADDR:%[0-9]+]]:_(p0) = COPY $x0
2228 ; CHECK-NEXT:    [[VAL:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
2229 ; CHECK-NEXT:    [[OLDVALRES:%[0-9]+]]:_(s32) = G_ATOMICRMW_UMAX [[ADDR]](p0), [[VAL]] :: (load store seq_cst (s32) on %ir.addr)
2230   %oldval = atomicrmw umax ptr %addr, i32 1 seq_cst
2231   ret i32 %oldval
2234 @addr = global ptr null
2236 define void @test_blockaddress() {
2237 ; CHECK-LABEL: name: test_blockaddress
2238 ; CHECK: [[BADDR:%[0-9]+]]:_(p0) = G_BLOCK_ADDR blockaddress(@test_blockaddress, %ir-block.block)
2239 ; CHECK: G_STORE [[BADDR]](p0)
2240   store ptr blockaddress(@test_blockaddress, %block), ptr @addr
2241   indirectbr ptr blockaddress(@test_blockaddress, %block), [label %block]
2242 block:
2243   ret void
2246 %t = type { i32 }
2247 declare ptr @llvm.invariant.start.p0(i64, ptr nocapture) readonly nounwind
2248 declare void @llvm.invariant.end.p0(ptr, i64, ptr nocapture) nounwind
2249 define void @test_invariant_intrin() {
2250 ; CHECK-LABEL: name: test_invariant_intrin
2251 ; CHECK: %{{[0-9]+}}:_(s64) = G_IMPLICIT_DEF
2252 ; CHECK-NEXT: RET_ReallyLR
2253   %x = alloca %t
2254   %inv = call ptr @llvm.invariant.start.p0(i64 8, ptr %x)
2255   call void @llvm.invariant.end.p0(ptr %inv, i64 8, ptr %x)
2256   ret void
2259 declare float @llvm.ceil.f32(float)
2260 define float @test_ceil_f32(float %x) {
2261   ; CHECK-LABEL: name:            test_ceil_f32
2262   ; CHECK: %{{[0-9]+}}:_(s32) = G_FCEIL %{{[0-9]+}}
2263   %y = call float @llvm.ceil.f32(float %x)
2264   ret float %y
2267 declare double @llvm.ceil.f64(double)
2268 define double @test_ceil_f64(double %x) {
2269   ; CHECK-LABEL: name:            test_ceil_f64
2270   ; CHECK: %{{[0-9]+}}:_(s64) = G_FCEIL %{{[0-9]+}}
2271   %y = call double @llvm.ceil.f64(double %x)
2272   ret double %y
2275 declare <2 x float> @llvm.ceil.v2f32(<2 x float>)
2276 define <2 x float> @test_ceil_v2f32(<2 x float> %x) {
2277   ; CHECK-LABEL: name:            test_ceil_v2f32
2278   ; CHECK: %{{[0-9]+}}:_(<2 x s32>) = G_FCEIL %{{[0-9]+}}
2279   %y = call <2 x float> @llvm.ceil.v2f32(<2 x float> %x)
2280   ret <2 x float> %y
2283 declare <4 x float> @llvm.ceil.v4f32(<4 x float>)
2284 define <4 x float> @test_ceil_v4f32(<4 x float> %x) {
2285   ; CHECK-LABEL: name:            test_ceil_v4f32
2286   ; CHECK: %{{[0-9]+}}:_(<4 x s32>) = G_FCEIL %{{[0-9]+}}
2287   ; SELECT: %{{[0-9]+}}:fpr128 = FRINTPv4f32 %{{[0-9]+}}
2288   %y = call <4 x float> @llvm.ceil.v4f32(<4 x float> %x)
2289   ret <4 x float> %y
2292 declare <2 x double> @llvm.ceil.v2f64(<2 x double>)
2293 define <2 x double> @test_ceil_v2f64(<2 x double> %x) {
2294   ; CHECK-LABEL: name:            test_ceil_v2f64
2295   ; CHECK: %{{[0-9]+}}:_(<2 x s64>) = G_FCEIL %{{[0-9]+}}
2296   %y = call <2 x double> @llvm.ceil.v2f64(<2 x double> %x)
2297   ret <2 x double> %y
2300 declare float @llvm.cos.f32(float)
2301 define float @test_cos_f32(float %x) {
2302   ; CHECK-LABEL: name:            test_cos_f32
2303   ; CHECK: %{{[0-9]+}}:_(s32) = G_FCOS %{{[0-9]+}}
2304   %y = call float @llvm.cos.f32(float %x)
2305   ret float %y
2308 declare float @llvm.sin.f32(float)
2309 define float @test_sin_f32(float %x) {
2310   ; CHECK-LABEL: name:            test_sin_f32
2311   ; CHECK: %{{[0-9]+}}:_(s32) = G_FSIN %{{[0-9]+}}
2312   %y = call float @llvm.sin.f32(float %x)
2313   ret float %y
2316 declare float @llvm.tan.f32(float)
2317 define float @test_tan_f32(float %x) {
2318   ; CHECK-LABEL: name:            test_tan_f32
2319   ; CHECK: %{{[0-9]+}}:_(s32) = G_FTAN %{{[0-9]+}}
2320   %y = call float @llvm.tan.f32(float %x)
2321   ret float %y
2324 declare float @llvm.acos.f32(float)
2325 define float @test_acos_f32(float %x) {
2326   ; CHECK-LABEL: name:            test_acos_f32
2327   ; CHECK: %{{[0-9]+}}:_(s32) = G_FACOS %{{[0-9]+}}
2328   %y = call float @llvm.acos.f32(float %x)
2329   ret float %y
2332 declare float @llvm.asin.f32(float)
2333 define float @test_asin_f32(float %x) {
2334   ; CHECK-LABEL: name:            test_asin_f32
2335   ; CHECK: %{{[0-9]+}}:_(s32) = G_FASIN %{{[0-9]+}}
2336   %y = call float @llvm.asin.f32(float %x)
2337   ret float %y
2340 declare float @llvm.atan.f32(float)
2341 define float @test_atan_f32(float %x) {
2342   ; CHECK-LABEL: name:            test_atan_f32
2343   ; CHECK: %{{[0-9]+}}:_(s32) = G_FATAN %{{[0-9]+}}
2344   %y = call float @llvm.atan.f32(float %x)
2345   ret float %y
2348 declare float @llvm.cosh.f32(float)
2349 define float @test_cosh_f32(float %x) {
2350   ; CHECK-LABEL: name:            test_cosh_f32
2351   ; CHECK: %{{[0-9]+}}:_(s32) = G_FCOSH %{{[0-9]+}}
2352   %y = call float @llvm.cosh.f32(float %x)
2353   ret float %y
2356 declare float @llvm.sinh.f32(float)
2357 define float @test_sinh_f32(float %x) {
2358   ; CHECK-LABEL: name:            test_sinh_f32
2359   ; CHECK: %{{[0-9]+}}:_(s32) = G_FSINH %{{[0-9]+}}
2360   %y = call float @llvm.sinh.f32(float %x)
2361   ret float %y
2364 declare float @llvm.tanh.f32(float)
2365 define float @test_tanh_f32(float %x) {
2366   ; CHECK-LABEL: name:            test_tanh_f32
2367   ; CHECK: %{{[0-9]+}}:_(s32) = G_FTANH %{{[0-9]+}}
2368   %y = call float @llvm.tanh.f32(float %x)
2369   ret float %y
2372 declare float @llvm.sqrt.f32(float)
2373 define float @test_sqrt_f32(float %x) {
2374   ; CHECK-LABEL: name:            test_sqrt_f32
2375   ; CHECK: %{{[0-9]+}}:_(s32) = G_FSQRT %{{[0-9]+}}
2376   %y = call float @llvm.sqrt.f32(float %x)
2377   ret float %y
2380 declare float @llvm.floor.f32(float)
2381 define float @test_floor_f32(float %x) {
2382   ; CHECK-LABEL: name:            test_floor_f32
2383   ; CHECK: %{{[0-9]+}}:_(s32) = G_FFLOOR %{{[0-9]+}}
2384   %y = call float @llvm.floor.f32(float %x)
2385   ret float %y
2388 declare float @llvm.nearbyint.f32(float)
2389 define float @test_nearbyint_f32(float %x) {
2390   ; CHECK-LABEL: name:            test_nearbyint_f32
2391   ; CHECK: %{{[0-9]+}}:_(s32) = G_FNEARBYINT %{{[0-9]+}}
2392   %y = call float @llvm.nearbyint.f32(float %x)
2393   ret float %y
2396 ; CHECK-LABEL: name: test_llvm.aarch64.neon.ld3.v4i32.p0i32
2397 ; CHECK: %1:_(<4 x s32>), %2:_(<4 x s32>), %3:_(<4 x s32>) = G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aarch64.neon.ld3), %0(p0) :: (load (s384) from %ir.ptr, align 64)
2398 define void @test_llvm.aarch64.neon.ld3.v4i32.p0i32(ptr %ptr) {
2399   %arst = call { <4 x i32>, <4 x i32>, <4 x i32> } @llvm.aarch64.neon.ld3.v4i32.p0(ptr %ptr)
2400   ret void
2403 declare { <4 x i32>, <4 x i32>, <4 x i32> } @llvm.aarch64.neon.ld3.v4i32.p0(ptr) #3
2405 define void @test_i1_arg_zext(ptr %f) {
2406 ; CHECK-LABEL: name: test_i1_arg_zext
2407 ; CHECK: [[I1:%[0-9]+]]:_(s1) = G_CONSTANT i1 true
2408 ; CHECK: [[ZEXT0:%[0-9]+]]:_(s8) = G_ZEXT [[I1]](s1)
2409 ; CHECK: [[ZEXT1:%[0-9]+]]:_(s32) = G_ANYEXT [[ZEXT0]](s8)
2410 ; CHECK: $w0 = COPY [[ZEXT1]](s32)
2411   call void %f(i1 true)
2412   ret void
2415 declare ptr @llvm.stacksave()
2416 declare void @llvm.stackrestore(ptr)
2417 define void @test_stacksaverestore() {
2418   ; CHECK-LABEL: name: test_stacksaverestore
2419   ; CHECK: [[SAVE:%[0-9]+]]:_(p0) = G_STACKSAVE
2420   ; CHECK-NEXT: G_STACKRESTORE [[SAVE]]
2421   ; CHECK-NEXT: RET_ReallyLR
2422   %sp = call ptr @llvm.stacksave()
2423   call void @llvm.stackrestore(ptr %sp)
2424   ret void
2427 declare float @llvm.rint.f32(float)
2428 define float @test_rint_f32(float %x) {
2429   ; CHECK-LABEL: name:            test_rint_f32
2430   ; CHECK: %{{[0-9]+}}:_(s32) = G_FRINT %{{[0-9]+}}
2431   %y = call float @llvm.rint.f32(float %x)
2432   ret float %y
2435 declare void @llvm.assume(i1)
2436 define void @test_assume(i1 %x) {
2437   ; CHECK-LABEL: name:            test_assume
2438   ; CHECK-NOT: llvm.assume
2439   ; CHECK: RET_ReallyLR
2440   call void @llvm.assume(i1 %x)
2441   ret void
2444 declare void @llvm.experimental.noalias.scope.decl(metadata)
2445 define void @test.llvm.noalias.scope.decl(ptr %P, ptr %Q) nounwind ssp {
2446   tail call void @llvm.experimental.noalias.scope.decl(metadata !3)
2447   ; CHECK-LABEL: name: test.llvm.noalias.scope.decl
2448   ; CHECK-NOT: llvm.experimental.noalias.scope.decl
2449   ; CHECK: RET_ReallyLR
2450   ret void
2453 !3 = !{ !4 }
2454 !4 = distinct !{ !4, !5, !"test1: var" }
2455 !5 = distinct !{ !5, !"test1" }
2458 declare void @llvm.sideeffect()
2459 define void @test_sideeffect() {
2460   ; CHECK-LABEL: name:            test_sideeffect
2461   ; CHECK-NOT: llvm.sideeffect
2462   ; CHECK: RET_ReallyLR
2463   call void @llvm.sideeffect()
2464   ret void
2467 declare void @llvm.var.annotation(ptr, ptr, ptr, i32, ptr)
2468 define void @test_var_annotation(ptr, ptr, ptr, i32) {
2469   ; CHECK-LABEL: name:            test_var_annotation
2470   ; CHECK-NOT: llvm.var.annotation
2471   ; CHECK: RET_ReallyLR
2472   call void @llvm.var.annotation(ptr %0, ptr %1, ptr %2, i32 %3, ptr null)
2473   ret void
2476 declare i64 @llvm.readcyclecounter()
2477 define i64 @test_readcyclecounter() {
2478   ; CHECK-LABEL: name:            test_readcyclecounter
2479   ; CHECK: [[RES:%[0-9]+]]:_(s64) = G_READCYCLECOUNTER{{$}}
2480   ; CHECK-NEXT: $x0 = COPY [[RES]]
2481   ; CHECK-NEXT: RET_ReallyLR implicit $x0
2482   %res = call i64 @llvm.readcyclecounter()
2483   ret i64 %res
2486 define i64 @test_freeze(i64 %a) {
2487   ; CHECK-LABEL: name:            test_freeze
2488   ; CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY $x0
2489   ; CHECK-NEXT: [[RES:%[0-9]+]]:_(s64) = G_FREEZE [[COPY]]
2490   ; CHECK-NEXT: $x0 = COPY [[RES]]
2491   ; CHECK-NEXT: RET_ReallyLR implicit $x0
2492   %res = freeze i64 %a
2493   ret i64 %res
2496 define {i8, i32} @test_freeze_struct(ptr %addr) {
2497   ; CHECK-LABEL: name:            test_freeze_struct
2498   ; CHECK: [[COPY:%[0-9]+]]:_(p0) = COPY $x0
2499   ; CHECK-NEXT: [[LOAD:%[0-9]+]]:_(s8) = G_LOAD [[COPY]](p0)
2500   ; CHECK-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 4
2501   ; CHECK-NEXT: [[PTR_ADD:%[0-9]+]]:_(p0) = G_PTR_ADD [[COPY]], [[C]]
2502   ; CHECK-NEXT: [[LOAD1:%[0-9]+]]:_(s32) = G_LOAD [[PTR_ADD]](p0)
2503   ; CHECK-NEXT: [[FREEZE:%[0-9]+]]:_(s8) = G_FREEZE [[LOAD]]
2504   ; CHECK-NEXT: [[FREEZE1:%[0-9]+]]:_(s32) = G_FREEZE [[LOAD1]]
2505   ; CHECK-NEXT: [[ANYEXT:%[0-9]+]]:_(s32) = G_ANYEXT [[FREEZE]]
2506   ; CHECK-NEXT: $w0 = COPY [[ANYEXT]]
2507   ; CHECK-NEXT: $w1 = COPY [[FREEZE1]]
2508   ; CHECK-NEXT: RET_ReallyLR implicit $w0, implicit $w1
2509   %load = load { i8, i32 }, ptr %addr
2510   %res = freeze {i8, i32} %load
2511   ret {i8, i32} %res
2514 !0 = !{ i64 0, i64 2 }
2516 declare i64 @llvm.lround.i64.f32(float) nounwind readnone
2517 define i64 @lround(float %x) {
2518   ; CHECK-LABEL: name: lround
2519   ; CHECK: bb.1 (%ir-block.0):
2520   ; CHECK:   liveins: $s0
2521   ; CHECK:   [[COPY:%[0-9]+]]:_(s32) = COPY $s0
2522   ; CHECK:   [[LROUND:%[0-9]+]]:_(s64) = G_LROUND [[COPY]](s32)
2523   ; CHECK:   $x0 = COPY [[LROUND]](s64)
2524   ; CHECK:   RET_ReallyLR implicit $x0
2525   %lround = tail call i64 @llvm.lround.i64.f32(float %x)
2526   ret i64 %lround
2529 declare i64 @llvm.llround.i64.f32(float) nounwind readnone
2530 define i64 @llround(float %x) {
2531   ; CHECK-LABEL: name: llround
2532   ; CHECK: bb.1 (%ir-block.0):
2533   ; CHECK:   liveins: $s0
2534   ; CHECK:   [[COPY:%[0-9]+]]:_(s32) = COPY $s0
2535   ; CHECK:   [[LLROUND:%[0-9]+]]:_(s64) = G_LLROUND [[COPY]](s32)
2536   ; CHECK:   $x0 = COPY [[LLROUND]](s64)
2537   ; CHECK:   RET_ReallyLR implicit $x0
2538   %lround = tail call i64 @llvm.llround.i64.f32(float %x)
2539   ret i64 %lround