[ARM] More MVE compare vector splat combines for ANDs
[llvm-complete.git] / test / CodeGen / AArch64 / GlobalISel / arm64-irtranslator.ll
blob57b826452ef2c356a51f4d2b46a071cf46326851
1 ; RUN: llc -O0 -aarch64-enable-atomic-cfg-tidy=0 -stop-after=irtranslator -global-isel -verify-machineinstrs %s -o - 2>&1 | FileCheck %s
2 ; RUN: llc -O3 -aarch64-enable-atomic-cfg-tidy=0 -stop-after=irtranslator -global-isel -verify-machineinstrs %s -o - 2>&1 | FileCheck %s --check-prefix=O3
4 ; This file checks that the translation from llvm IR to generic MachineInstr
5 ; is correct.
6 target datalayout = "e-m:o-i64:64-i128:128-n32:64-S128"
7 target triple = "aarch64--"
9 ; Tests for add.
10 ; CHECK-LABEL: name: addi64
11 ; CHECK:      [[ARG1:%[0-9]+]]:_(s64) = COPY $x0
12 ; CHECK-NEXT: [[ARG2:%[0-9]+]]:_(s64) = COPY $x1
13 ; CHECK-NEXT: [[RES:%[0-9]+]]:_(s64) = G_ADD [[ARG1]], [[ARG2]]
14 ; CHECK-NEXT: $x0 = COPY [[RES]]
15 ; CHECK-NEXT: RET_ReallyLR implicit $x0
16 define i64 @addi64(i64 %arg1, i64 %arg2) {
17   %res = add i64 %arg1, %arg2
18   ret i64 %res
21 ; CHECK-LABEL: name: muli64
22 ; CHECK: [[ARG1:%[0-9]+]]:_(s64) = COPY $x0
23 ; CHECK-NEXT: [[ARG2:%[0-9]+]]:_(s64) = COPY $x1
24 ; CHECK-NEXT: [[RES:%[0-9]+]]:_(s64) = G_MUL [[ARG1]], [[ARG2]]
25 ; CHECK-NEXT: $x0 = COPY [[RES]]
26 ; CHECK-NEXT: RET_ReallyLR implicit $x0
27 define i64 @muli64(i64 %arg1, i64 %arg2) {
28   %res = mul i64 %arg1, %arg2
29   ret i64 %res
32 ; Tests for alloca
33 ; CHECK-LABEL: name: allocai64
34 ; CHECK: stack:
35 ; CHECK-NEXT:   - { id: 0, name: ptr1, type: default, offset: 0, size: 8, alignment: 8,
36 ; CHECK-NEXT:       stack-id: 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 ; We don't emit a branch here, as we can fallthrough to the successor.
91 ; CHECK-NOT: G_BR
92 ; CHECK: [[END]].{{[a-zA-Z0-9.]+}}:
93 ; CHECK-NEXT: RET_ReallyLR
94 define void @uncondbr_fallthrough() {
95 entry:
96   br label %end
97 end:
98   ret void
101 ; Tests for conditional br.
102 ; CHECK-LABEL: name: condbr
103 ; CHECK: body:
105 ; ABI/constant lowering and IR-level entry basic block.
106 ; CHECK: bb.{{[0-9]+}} (%ir-block.{{[0-9]+}}):
107 ; Make sure we have two successors
108 ; CHECK-NEXT: successors: %[[TRUE:bb.[0-9]+]](0x40000000),
109 ; CHECK:                  %[[FALSE:bb.[0-9]+]](0x40000000)
111 ; CHECK: [[ADDR:%.*]]:_(p0) = COPY $x0
113 ; Check that we emit the correct branch.
114 ; CHECK: [[TST:%.*]]:_(s1) = G_LOAD [[ADDR]](p0)
115 ; CHECK: G_BRCOND [[TST]](s1), %[[TRUE]]
116 ; CHECK: G_BR %[[FALSE]]
118 ; Check that each successor contains the return instruction.
119 ; CHECK: [[TRUE]].{{[a-zA-Z0-9.]+}}:
120 ; CHECK-NEXT: RET_ReallyLR
121 ; CHECK: [[FALSE]].{{[a-zA-Z0-9.]+}}:
122 ; CHECK-NEXT: RET_ReallyLR
123 define void @condbr(i1* %tstaddr) {
124   %tst = load i1, i1* %tstaddr
125   br i1 %tst, label %true, label %false
126 true:
127   ret void
128 false:
129   ret void
132 ; Tests for indirect br.
133 ; CHECK-LABEL: name: indirectbr
134 ; CHECK: body:
136 ; ABI/constant lowering and IR-level entry basic block.
137 ; CHECK: bb.{{[0-9]+.[a-zA-Z0-9.]+}}:
138 ; Make sure we have one successor
139 ; CHECK-NEXT: successors: %[[BB_L1:bb.[0-9]+]](0x80000000)
140 ; CHECK-NOT: G_BR
142 ; Check basic block L1 has 2 successors: BBL1 and BBL2
143 ; CHECK: [[BB_L1]].{{[a-zA-Z0-9.]+}} (address-taken):
144 ; CHECK-NEXT: successors: %[[BB_L1]](0x40000000),
145 ; CHECK:                  %[[BB_L2:bb.[0-9]+]](0x40000000)
146 ; CHECK: G_BRINDIRECT %{{[0-9]+}}(p0)
148 ; Check basic block L2 is the return basic block
149 ; CHECK: [[BB_L2]].{{[a-zA-Z0-9.]+}} (address-taken):
150 ; CHECK-NEXT: RET_ReallyLR
152 @indirectbr.L = internal unnamed_addr constant [3 x i8*] [i8* blockaddress(@indirectbr, %L1), i8* blockaddress(@indirectbr, %L2), i8* null], align 8
154 define void @indirectbr() {
155 entry:
156   br label %L1
157 L1:                                               ; preds = %entry, %L1
158   %i = phi i32 [ 0, %entry ], [ %inc, %L1 ]
159   %inc = add i32 %i, 1
160   %idxprom = zext i32 %i to i64
161   %arrayidx = getelementptr inbounds [3 x i8*], [3 x i8*]* @indirectbr.L, i64 0, i64 %idxprom
162   %brtarget = load i8*, i8** %arrayidx, align 8
163   indirectbr i8* %brtarget, [label %L1, label %L2]
164 L2:                                               ; preds = %L1
165   ret void
168 ; Tests for or.
169 ; CHECK-LABEL: name: ori64
170 ; CHECK: [[ARG1:%[0-9]+]]:_(s64) = COPY $x0
171 ; CHECK-NEXT: [[ARG2:%[0-9]+]]:_(s64) = COPY $x1
172 ; CHECK-NEXT: [[RES:%[0-9]+]]:_(s64) = G_OR [[ARG1]], [[ARG2]]
173 ; CHECK-NEXT: $x0 = COPY [[RES]]
174 ; CHECK-NEXT: RET_ReallyLR implicit $x0
175 define i64 @ori64(i64 %arg1, i64 %arg2) {
176   %res = or i64 %arg1, %arg2
177   ret i64 %res
180 ; CHECK-LABEL: name: ori32
181 ; CHECK: [[ARG1:%[0-9]+]]:_(s32) = COPY $w0
182 ; CHECK-NEXT: [[ARG2:%[0-9]+]]:_(s32) = COPY $w1
183 ; CHECK-NEXT: [[RES:%[0-9]+]]:_(s32) = G_OR [[ARG1]], [[ARG2]]
184 ; CHECK-NEXT: $w0 = COPY [[RES]]
185 ; CHECK-NEXT: RET_ReallyLR implicit $w0
186 define i32 @ori32(i32 %arg1, i32 %arg2) {
187   %res = or i32 %arg1, %arg2
188   ret i32 %res
191 ; Tests for xor.
192 ; CHECK-LABEL: name: xori64
193 ; CHECK: [[ARG1:%[0-9]+]]:_(s64) = COPY $x0
194 ; CHECK-NEXT: [[ARG2:%[0-9]+]]:_(s64) = COPY $x1
195 ; CHECK-NEXT: [[RES:%[0-9]+]]:_(s64) = G_XOR [[ARG1]], [[ARG2]]
196 ; CHECK-NEXT: $x0 = COPY [[RES]]
197 ; CHECK-NEXT: RET_ReallyLR implicit $x0
198 define i64 @xori64(i64 %arg1, i64 %arg2) {
199   %res = xor i64 %arg1, %arg2
200   ret i64 %res
203 ; CHECK-LABEL: name: xori32
204 ; CHECK: [[ARG1:%[0-9]+]]:_(s32) = COPY $w0
205 ; CHECK-NEXT: [[ARG2:%[0-9]+]]:_(s32) = COPY $w1
206 ; CHECK-NEXT: [[RES:%[0-9]+]]:_(s32) = G_XOR [[ARG1]], [[ARG2]]
207 ; CHECK-NEXT: $w0 = COPY [[RES]]
208 ; CHECK-NEXT: RET_ReallyLR implicit $w0
209 define i32 @xori32(i32 %arg1, i32 %arg2) {
210   %res = xor i32 %arg1, %arg2
211   ret i32 %res
214 ; Tests for and.
215 ; CHECK-LABEL: name: andi64
216 ; CHECK: [[ARG1:%[0-9]+]]:_(s64) = COPY $x0
217 ; CHECK-NEXT: [[ARG2:%[0-9]+]]:_(s64) = COPY $x1
218 ; CHECK-NEXT: [[RES:%[0-9]+]]:_(s64) = G_AND [[ARG1]], [[ARG2]]
219 ; CHECK-NEXT: $x0 = COPY [[RES]]
220 ; CHECK-NEXT: RET_ReallyLR implicit $x0
221 define i64 @andi64(i64 %arg1, i64 %arg2) {
222   %res = and i64 %arg1, %arg2
223   ret i64 %res
226 ; CHECK-LABEL: name: andi32
227 ; CHECK: [[ARG1:%[0-9]+]]:_(s32) = COPY $w0
228 ; CHECK-NEXT: [[ARG2:%[0-9]+]]:_(s32) = COPY $w1
229 ; CHECK-NEXT: [[RES:%[0-9]+]]:_(s32) = G_AND [[ARG1]], [[ARG2]]
230 ; CHECK-NEXT: $w0 = COPY [[RES]]
231 ; CHECK-NEXT: RET_ReallyLR implicit $w0
232 define i32 @andi32(i32 %arg1, i32 %arg2) {
233   %res = and i32 %arg1, %arg2
234   ret i32 %res
237 ; Tests for sub.
238 ; CHECK-LABEL: name: subi64
239 ; CHECK: [[ARG1:%[0-9]+]]:_(s64) = COPY $x0
240 ; CHECK-NEXT: [[ARG2:%[0-9]+]]:_(s64) = COPY $x1
241 ; CHECK-NEXT: [[RES:%[0-9]+]]:_(s64) = G_SUB [[ARG1]], [[ARG2]]
242 ; CHECK-NEXT: $x0 = COPY [[RES]]
243 ; CHECK-NEXT: RET_ReallyLR implicit $x0
244 define i64 @subi64(i64 %arg1, i64 %arg2) {
245   %res = sub i64 %arg1, %arg2
246   ret i64 %res
249 ; CHECK-LABEL: name: subi32
250 ; CHECK: [[ARG1:%[0-9]+]]:_(s32) = COPY $w0
251 ; CHECK-NEXT: [[ARG2:%[0-9]+]]:_(s32) = COPY $w1
252 ; CHECK-NEXT: [[RES:%[0-9]+]]:_(s32) = G_SUB [[ARG1]], [[ARG2]]
253 ; CHECK-NEXT: $w0 = COPY [[RES]]
254 ; CHECK-NEXT: RET_ReallyLR implicit $w0
255 define i32 @subi32(i32 %arg1, i32 %arg2) {
256   %res = sub i32 %arg1, %arg2
257   ret i32 %res
260 ; CHECK-LABEL: name: ptrtoint
261 ; CHECK: [[ARG1:%[0-9]+]]:_(p0) = COPY $x0
262 ; CHECK: [[RES:%[0-9]+]]:_(s64) = G_PTRTOINT [[ARG1]]
263 ; CHECK: $x0 = COPY [[RES]]
264 ; CHECK: RET_ReallyLR implicit $x0
265 define i64 @ptrtoint(i64* %a) {
266   %val = ptrtoint i64* %a to i64
267   ret i64 %val
270 ; CHECK-LABEL: name: inttoptr
271 ; CHECK: [[ARG1:%[0-9]+]]:_(s64) = COPY $x0
272 ; CHECK: [[RES:%[0-9]+]]:_(p0) = G_INTTOPTR [[ARG1]]
273 ; CHECK: $x0 = COPY [[RES]]
274 ; CHECK: RET_ReallyLR implicit $x0
275 define i64* @inttoptr(i64 %a) {
276   %val = inttoptr i64 %a to i64*
277   ret i64* %val
280 ; CHECK-LABEL: name: trivial_bitcast
281 ; CHECK: [[ARG1:%[0-9]+]]:_(p0) = COPY $x0
282 ; CHECK: $x0 = COPY [[ARG1]]
283 ; CHECK: RET_ReallyLR implicit $x0
284 define i64* @trivial_bitcast(i8* %a) {
285   %val = bitcast i8* %a to i64*
286   ret i64* %val
289 ; CHECK-LABEL: name: trivial_bitcast_with_copy
290 ; CHECK:     [[A:%[0-9]+]]:_(p0) = COPY $x0
291 ; CHECK:     G_BR %[[CAST:bb\.[0-9]+]]
293 ; CHECK: [[END:bb\.[0-9]+]].{{[a-zA-Z0-9.]+}}:
294 ; CHECK:     $x0 = COPY [[A]]
296 ; CHECK: [[CAST]].{{[a-zA-Z0-9.]+}}:
297 ; CHECK:     G_BR %[[END]]
298 define i64* @trivial_bitcast_with_copy(i8* %a) {
299   br label %cast
301 end:
302   ret i64* %val
304 cast:
305   %val = bitcast i8* %a to i64*
306   br label %end
309 ; CHECK-LABEL: name: bitcast
310 ; CHECK: [[ARG1:%[0-9]+]]:_(s64) = COPY $x0
311 ; CHECK: [[RES1:%[0-9]+]]:_(<2 x s32>) = G_BITCAST [[ARG1]]
312 ; CHECK: [[RES2:%[0-9]+]]:_(s64) = G_BITCAST [[RES1]]
313 ; CHECK: $x0 = COPY [[RES2]]
314 ; CHECK: RET_ReallyLR implicit $x0
315 define i64 @bitcast(i64 %a) {
316   %res1 = bitcast i64 %a to <2 x i32>
317   %res2 = bitcast <2 x i32> %res1 to i64
318   ret i64 %res2
321 ; CHECK-LABEL: name: addrspacecast
322 ; CHECK: [[ARG1:%[0-9]+]]:_(p1) = COPY $x0
323 ; CHECK: [[RES1:%[0-9]+]]:_(p2) = G_ADDRSPACE_CAST [[ARG1]]
324 ; CHECK: [[RES2:%[0-9]+]]:_(p0) = G_ADDRSPACE_CAST [[RES1]]
325 ; CHECK: $x0 = COPY [[RES2]]
326 ; CHECK: RET_ReallyLR implicit $x0
327 define i64* @addrspacecast(i32 addrspace(1)* %a) {
328   %res1 = addrspacecast i32 addrspace(1)* %a to i64 addrspace(2)*
329   %res2 = addrspacecast i64 addrspace(2)* %res1 to i64*
330   ret i64* %res2
333 ; CHECK-LABEL: name: trunc
334 ; CHECK: [[ARG1:%[0-9]+]]:_(s64) = COPY $x0
335 ; CHECK: [[VEC:%[0-9]+]]:_(<4 x s32>) = G_LOAD
336 ; CHECK: [[RES1:%[0-9]+]]:_(s8) = G_TRUNC [[ARG1]]
337 ; CHECK: [[RES2:%[0-9]+]]:_(<4 x s16>) = G_TRUNC [[VEC]]
338 define void @trunc(i64 %a) {
339   %vecptr = alloca <4 x i32>
340   %vec = load <4 x i32>, <4 x i32>* %vecptr
341   %res1 = trunc i64 %a to i8
342   %res2 = trunc <4 x i32> %vec to <4 x i16>
343   ret void
346 ; CHECK-LABEL: name: load
347 ; CHECK: [[ADDR:%[0-9]+]]:_(p0) = COPY $x0
348 ; CHECK: [[ADDR42:%[0-9]+]]:_(p42) = COPY $x1
349 ; CHECK: [[VAL1:%[0-9]+]]:_(s64) = G_LOAD [[ADDR]](p0) :: (load 8 from %ir.addr, align 16)
350 ; CHECK: [[VAL2:%[0-9]+]]:_(s64) = G_LOAD [[ADDR42]](p42) :: (load 8 from %ir.addr42, addrspace 42)
351 ; CHECK: [[SUM2:%.*]]:_(s64) = G_ADD [[VAL1]], [[VAL2]]
352 ; CHECK: [[VAL3:%[0-9]+]]:_(s64) = G_LOAD [[ADDR]](p0) :: (volatile load 8 from %ir.addr)
353 ; CHECK: [[SUM3:%[0-9]+]]:_(s64) = G_ADD [[SUM2]], [[VAL3]]
354 ; CHECK: [[VAL4:%[0-9]+]]:_(s64) = G_LOAD [[ADDR]](p0) :: (load 8 from %ir.addr, !range !0)
355 ; CHECK: [[SUM4:%[0-9]+]]:_(s64) = G_ADD [[SUM3]], [[VAL4]]
356 ; CHECK: $x0 = COPY [[SUM4]]
357 ; CHECK: RET_ReallyLR implicit $x0
358 define i64 @load(i64* %addr, i64 addrspace(42)* %addr42) {
359   %val1 = load i64, i64* %addr, align 16
361   %val2 = load i64, i64 addrspace(42)* %addr42
362   %sum2 = add i64 %val1, %val2
364   %val3 = load volatile i64, i64* %addr
365   %sum3 = add i64 %sum2, %val3
367   %val4 = load i64, i64* %addr, !range !0
368   %sum4 = add i64 %sum3, %val4
369   ret i64 %sum4
372 ; CHECK-LABEL: name: store
373 ; CHECK: [[ADDR:%[0-9]+]]:_(p0) = COPY $x0
374 ; CHECK: [[ADDR42:%[0-9]+]]:_(p42) = COPY $x1
375 ; CHECK: [[VAL1:%[0-9]+]]:_(s64) = COPY $x2
376 ; CHECK: [[VAL2:%[0-9]+]]:_(s64) = COPY $x3
377 ; CHECK: G_STORE [[VAL1]](s64), [[ADDR]](p0) :: (store 8 into %ir.addr, align 16)
378 ; CHECK: G_STORE [[VAL2]](s64), [[ADDR42]](p42) :: (store 8 into %ir.addr42, addrspace 42)
379 ; CHECK: G_STORE [[VAL1]](s64), [[ADDR]](p0) :: (volatile store 8 into %ir.addr)
380 ; CHECK: RET_ReallyLR
381 define void @store(i64* %addr, i64 addrspace(42)* %addr42, i64 %val1, i64 %val2) {
382   store i64 %val1, i64* %addr, align 16
383   store i64 %val2, i64 addrspace(42)* %addr42
384   store volatile i64 %val1, i64* %addr
385   %sum = add i64 %val1, %val2
386   ret void
389 ; CHECK-LABEL: name: intrinsics
390 ; CHECK: [[CUR:%[0-9]+]]:_(s32) = COPY $w0
391 ; CHECK: [[BITS:%[0-9]+]]:_(s32) = COPY $w1
392 ; CHECK: [[CREG:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
393 ; CHECK: [[PTR:%[0-9]+]]:_(p0) = G_INTRINSIC intrinsic(@llvm.returnaddress), [[CREG]]
394 ; CHECK: [[PTR_VEC:%[0-9]+]]:_(p0) = G_FRAME_INDEX %stack.0.ptr.vec
395 ; CHECK: [[VEC:%[0-9]+]]:_(<8 x s8>) = G_LOAD [[PTR_VEC]]
396 ; CHECK: G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aarch64.neon.st2), [[VEC]](<8 x s8>), [[VEC]](<8 x s8>), [[PTR]](p0)
397 ; CHECK: RET_ReallyLR
398 declare i8* @llvm.returnaddress(i32)
399 declare void @llvm.aarch64.neon.st2.v8i8.p0i8(<8 x i8>, <8 x i8>, i8*)
400 declare { <8 x i8>, <8 x i8> } @llvm.aarch64.neon.ld2.v8i8.p0v8i8(<8 x i8>*)
401 define void @intrinsics(i32 %cur, i32 %bits) {
402   %ptr = call i8* @llvm.returnaddress(i32 0)
403   %ptr.vec = alloca <8 x i8>
404   %vec = load <8 x i8>, <8 x i8>* %ptr.vec
405   call void @llvm.aarch64.neon.st2.v8i8.p0i8(<8 x i8> %vec, <8 x i8> %vec, i8* %ptr)
406   ret void
409 ; CHECK-LABEL: name: test_phi
410 ; CHECK:     G_BRCOND {{%.*}}, %[[TRUE:bb\.[0-9]+]]
411 ; CHECK:     G_BR %[[FALSE:bb\.[0-9]+]]
413 ; CHECK: [[TRUE]].{{[a-zA-Z0-9.]+}}:
414 ; CHECK:     [[RES1:%[0-9]+]]:_(s32) = G_LOAD
416 ; CHECK: [[FALSE]].{{[a-zA-Z0-9.]+}}:
417 ; CHECK:     [[RES2:%[0-9]+]]:_(s32) = G_LOAD
419 ; CHECK:     [[RES:%[0-9]+]]:_(s32) = G_PHI [[RES1]](s32), %[[TRUE]], [[RES2]](s32), %[[FALSE]]
420 ; CHECK:     $w0 = COPY [[RES]]
421 define i32 @test_phi(i32* %addr1, i32* %addr2, i1 %tst) {
422   br i1 %tst, label %true, label %false
424 true:
425   %res1 = load i32, i32* %addr1
426   br label %end
428 false:
429   %res2 = load i32, i32* %addr2
430   br label %end
432 end:
433   %res = phi i32 [%res1, %true], [%res2, %false]
434   ret i32 %res
437 ; CHECK-LABEL: name: unreachable
438 ; CHECK: G_ADD
439 ; CHECK-NEXT: {{^$}}
440 ; CHECK-NEXT: ...
441 define void @unreachable(i32 %a) {
442   %sum = add i32 %a, %a
443   unreachable
446   ; It's important that constants are after argument passing, but before the
447   ; rest of the entry block.
448 ; CHECK-LABEL: name: constant_int
449 ; CHECK: [[IN:%[0-9]+]]:_(s32) = COPY $w0
450 ; CHECK: [[ONE:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
452 ; CHECK: bb.{{[0-9]+}}.{{[a-zA-Z0-9.]+}}:
453 ; CHECK: [[SUM1:%[0-9]+]]:_(s32) = G_ADD [[IN]], [[ONE]]
454 ; CHECK: [[SUM2:%[0-9]+]]:_(s32) = G_ADD [[IN]], [[ONE]]
455 ; CHECK: [[RES:%[0-9]+]]:_(s32) = G_ADD [[SUM1]], [[SUM2]]
456 ; CHECK: $w0 = COPY [[RES]]
458 define i32 @constant_int(i32 %in) {
459   br label %next
461 next:
462   %sum1 = add i32 %in, 1
463   %sum2 = add i32 %in, 1
464   %res = add i32 %sum1, %sum2
465   ret i32 %res
468 ; CHECK-LABEL: name: constant_int_start
469 ; CHECK: [[TWO:%[0-9]+]]:_(s32) = G_CONSTANT i32 2
470 ; CHECK: [[ANSWER:%[0-9]+]]:_(s32) = G_CONSTANT i32 42
471 ; CHECK: [[RES:%[0-9]+]]:_(s32) = G_CONSTANT i32 44
472 define i32 @constant_int_start() {
473   %res = add i32 2, 42
474   ret i32 %res
477 ; CHECK-LABEL: name: test_undef
478 ; CHECK: [[UNDEF:%[0-9]+]]:_(s32) = G_IMPLICIT_DEF
479 ; CHECK: $w0 = COPY [[UNDEF]]
480 define i32 @test_undef() {
481   ret i32 undef
484 ; CHECK-LABEL: name: test_constant_inttoptr
485 ; CHECK: [[ONE:%[0-9]+]]:_(s64) = G_CONSTANT i64 1
486 ; CHECK: [[PTR:%[0-9]+]]:_(p0) = G_INTTOPTR [[ONE]]
487 ; CHECK: $x0 = COPY [[PTR]]
488 define i8* @test_constant_inttoptr() {
489   ret i8* inttoptr(i64 1 to i8*)
492   ; This failed purely because the Constant -> VReg map was kept across
493   ; functions, so reuse the "i64 1" from above.
494 ; CHECK-LABEL: name: test_reused_constant
495 ; CHECK: [[ONE:%[0-9]+]]:_(s64) = G_CONSTANT i64 1
496 ; CHECK: $x0 = COPY [[ONE]]
497 define i64 @test_reused_constant() {
498   ret i64 1
501 ; CHECK-LABEL: name: test_sext
502 ; CHECK: [[IN:%[0-9]+]]:_(s32) = COPY $w0
503 ; CHECK: [[RES:%[0-9]+]]:_(s64) = G_SEXT [[IN]]
504 ; CHECK: $x0 = COPY [[RES]]
505 define i64 @test_sext(i32 %in) {
506   %res = sext i32 %in to i64
507   ret i64 %res
510 ; CHECK-LABEL: name: test_zext
511 ; CHECK: [[IN:%[0-9]+]]:_(s32) = COPY $w0
512 ; CHECK: [[RES:%[0-9]+]]:_(s64) = G_ZEXT [[IN]]
513 ; CHECK: $x0 = COPY [[RES]]
514 define i64 @test_zext(i32 %in) {
515   %res = zext i32 %in to i64
516   ret i64 %res
519 ; CHECK-LABEL: name: test_shl
520 ; CHECK: [[ARG1:%[0-9]+]]:_(s32) = COPY $w0
521 ; CHECK-NEXT: [[ARG2:%[0-9]+]]:_(s32) = COPY $w1
522 ; CHECK-NEXT: [[RES:%[0-9]+]]:_(s32) = G_SHL [[ARG1]], [[ARG2]]
523 ; CHECK-NEXT: $w0 = COPY [[RES]]
524 ; CHECK-NEXT: RET_ReallyLR implicit $w0
525 define i32 @test_shl(i32 %arg1, i32 %arg2) {
526   %res = shl i32 %arg1, %arg2
527   ret i32 %res
531 ; CHECK-LABEL: name: test_lshr
532 ; CHECK: [[ARG1:%[0-9]+]]:_(s32) = COPY $w0
533 ; CHECK-NEXT: [[ARG2:%[0-9]+]]:_(s32) = COPY $w1
534 ; CHECK-NEXT: [[RES:%[0-9]+]]:_(s32) = G_LSHR [[ARG1]], [[ARG2]]
535 ; CHECK-NEXT: $w0 = COPY [[RES]]
536 ; CHECK-NEXT: RET_ReallyLR implicit $w0
537 define i32 @test_lshr(i32 %arg1, i32 %arg2) {
538   %res = lshr i32 %arg1, %arg2
539   ret i32 %res
542 ; CHECK-LABEL: name: test_ashr
543 ; CHECK: [[ARG1:%[0-9]+]]:_(s32) = COPY $w0
544 ; CHECK-NEXT: [[ARG2:%[0-9]+]]:_(s32) = COPY $w1
545 ; CHECK-NEXT: [[RES:%[0-9]+]]:_(s32) = G_ASHR [[ARG1]], [[ARG2]]
546 ; CHECK-NEXT: $w0 = COPY [[RES]]
547 ; CHECK-NEXT: RET_ReallyLR implicit $w0
548 define i32 @test_ashr(i32 %arg1, i32 %arg2) {
549   %res = ashr i32 %arg1, %arg2
550   ret i32 %res
553 ; CHECK-LABEL: name: test_sdiv
554 ; CHECK: [[ARG1:%[0-9]+]]:_(s32) = COPY $w0
555 ; CHECK-NEXT: [[ARG2:%[0-9]+]]:_(s32) = COPY $w1
556 ; CHECK-NEXT: [[RES:%[0-9]+]]:_(s32) = G_SDIV [[ARG1]], [[ARG2]]
557 ; CHECK-NEXT: $w0 = COPY [[RES]]
558 ; CHECK-NEXT: RET_ReallyLR implicit $w0
559 define i32 @test_sdiv(i32 %arg1, i32 %arg2) {
560   %res = sdiv i32 %arg1, %arg2
561   ret i32 %res
564 ; CHECK-LABEL: name: test_udiv
565 ; CHECK: [[ARG1:%[0-9]+]]:_(s32) = COPY $w0
566 ; CHECK-NEXT: [[ARG2:%[0-9]+]]:_(s32) = COPY $w1
567 ; CHECK-NEXT: [[RES:%[0-9]+]]:_(s32) = G_UDIV [[ARG1]], [[ARG2]]
568 ; CHECK-NEXT: $w0 = COPY [[RES]]
569 ; CHECK-NEXT: RET_ReallyLR implicit $w0
570 define i32 @test_udiv(i32 %arg1, i32 %arg2) {
571   %res = udiv i32 %arg1, %arg2
572   ret i32 %res
575 ; CHECK-LABEL: name: test_srem
576 ; CHECK: [[ARG1:%[0-9]+]]:_(s32) = COPY $w0
577 ; CHECK-NEXT: [[ARG2:%[0-9]+]]:_(s32) = COPY $w1
578 ; CHECK-NEXT: [[RES:%[0-9]+]]:_(s32) = G_SREM [[ARG1]], [[ARG2]]
579 ; CHECK-NEXT: $w0 = COPY [[RES]]
580 ; CHECK-NEXT: RET_ReallyLR implicit $w0
581 define i32 @test_srem(i32 %arg1, i32 %arg2) {
582   %res = srem i32 %arg1, %arg2
583   ret i32 %res
586 ; CHECK-LABEL: name: test_urem
587 ; CHECK: [[ARG1:%[0-9]+]]:_(s32) = COPY $w0
588 ; CHECK-NEXT: [[ARG2:%[0-9]+]]:_(s32) = COPY $w1
589 ; CHECK-NEXT: [[RES:%[0-9]+]]:_(s32) = G_UREM [[ARG1]], [[ARG2]]
590 ; CHECK-NEXT: $w0 = COPY [[RES]]
591 ; CHECK-NEXT: RET_ReallyLR implicit $w0
592 define i32 @test_urem(i32 %arg1, i32 %arg2) {
593   %res = urem i32 %arg1, %arg2
594   ret i32 %res
597 ; CHECK-LABEL: name: test_constant_null
598 ; CHECK: [[ZERO:%[0-9]+]]:_(s64) = G_CONSTANT i64 0
599 ; CHECK: [[NULL:%[0-9]+]]:_(p0) = G_INTTOPTR [[ZERO]]
600 ; CHECK: $x0 = COPY [[NULL]]
601 define i8* @test_constant_null() {
602   ret i8* null
605 ; CHECK-LABEL: name: test_struct_memops
606 ; CHECK: [[ADDR:%[0-9]+]]:_(p0) = COPY $x0
607 ; CHECK: [[VAL1:%[0-9]+]]:_(s8) = G_LOAD %0(p0) :: (load 1 from %ir.addr, align 4)
608 ; CHECK: [[CST1:%[0-9]+]]:_(s64) = G_CONSTANT i64 4
609 ; CHECK: [[GEP1:%[0-9]+]]:_(p0) = G_GEP [[ADDR]], [[CST1]](s64)
610 ; CHECK: [[VAL2:%[0-9]+]]:_(s32) = G_LOAD [[GEP1]](p0) :: (load 4 from %ir.addr + 4)
611 ; CHECK: G_STORE [[VAL1]](s8), [[ADDR]](p0) :: (store 1 into %ir.addr, align 4)
612 ; CHECK: [[GEP2:%[0-9]+]]:_(p0) = G_GEP [[ADDR]], [[CST1]](s64)
613 ; CHECK: G_STORE [[VAL2]](s32), [[GEP2]](p0) :: (store 4 into %ir.addr + 4)
614 define void @test_struct_memops({ i8, i32 }* %addr) {
615   %val = load { i8, i32 }, { i8, i32 }* %addr
616   store { i8, i32 } %val, { i8, i32 }* %addr
617   ret void
620 ; CHECK-LABEL: name: test_i1_memops
621 ; CHECK: [[ADDR:%[0-9]+]]:_(p0) = COPY $x0
622 ; CHECK: [[VAL:%[0-9]+]]:_(s1) = G_LOAD [[ADDR]](p0) :: (load 1 from  %ir.addr)
623 ; CHECK: G_STORE [[VAL]](s1), [[ADDR]](p0) :: (store 1 into  %ir.addr)
624 define void @test_i1_memops(i1* %addr) {
625   %val = load i1, i1* %addr
626   store i1 %val, i1* %addr
627   ret void
630 ; CHECK-LABEL: name: int_comparison
631 ; CHECK: [[LHS:%[0-9]+]]:_(s32) = COPY $w0
632 ; CHECK: [[RHS:%[0-9]+]]:_(s32) = COPY $w1
633 ; CHECK: [[ADDR:%[0-9]+]]:_(p0) = COPY $x2
634 ; CHECK: [[TST:%[0-9]+]]:_(s1) = G_ICMP intpred(ne), [[LHS]](s32), [[RHS]]
635 ; CHECK: G_STORE [[TST]](s1), [[ADDR]](p0)
636 define void @int_comparison(i32 %a, i32 %b, i1* %addr) {
637   %res = icmp ne i32 %a, %b
638   store i1 %res, i1* %addr
639   ret void
642 ; CHECK-LABEL: name: ptr_comparison
643 ; CHECK: [[LHS:%[0-9]+]]:_(p0) = COPY $x0
644 ; CHECK: [[RHS:%[0-9]+]]:_(p0) = COPY $x1
645 ; CHECK: [[ADDR:%[0-9]+]]:_(p0) = COPY $x2
646 ; CHECK: [[TST:%[0-9]+]]:_(s1) = G_ICMP intpred(eq), [[LHS]](p0), [[RHS]]
647 ; CHECK: G_STORE [[TST]](s1), [[ADDR]](p0)
648 define void @ptr_comparison(i8* %a, i8* %b, i1* %addr) {
649   %res = icmp eq i8* %a, %b
650   store i1 %res, i1* %addr
651   ret void
654 ; CHECK-LABEL: name: test_fadd
655 ; CHECK: [[ARG1:%[0-9]+]]:_(s32) = COPY $s0
656 ; CHECK-NEXT: [[ARG2:%[0-9]+]]:_(s32) = COPY $s1
657 ; CHECK-NEXT: [[RES:%[0-9]+]]:_(s32) = G_FADD [[ARG1]], [[ARG2]]
658 ; CHECK-NEXT: $s0 = COPY [[RES]]
659 ; CHECK-NEXT: RET_ReallyLR implicit $s0
660 define float @test_fadd(float %arg1, float %arg2) {
661   %res = fadd float %arg1, %arg2
662   ret float %res
665 ; CHECK-LABEL: name: test_fsub
666 ; CHECK: [[ARG1:%[0-9]+]]:_(s32) = COPY $s0
667 ; CHECK-NEXT: [[ARG2:%[0-9]+]]:_(s32) = COPY $s1
668 ; CHECK-NEXT: [[RES:%[0-9]+]]:_(s32) = G_FSUB [[ARG1]], [[ARG2]]
669 ; CHECK-NEXT: $s0 = COPY [[RES]]
670 ; CHECK-NEXT: RET_ReallyLR implicit $s0
671 define float @test_fsub(float %arg1, float %arg2) {
672   %res = fsub float %arg1, %arg2
673   ret float %res
676 ; CHECK-LABEL: name: test_fmul
677 ; CHECK: [[ARG1:%[0-9]+]]:_(s32) = COPY $s0
678 ; CHECK-NEXT: [[ARG2:%[0-9]+]]:_(s32) = COPY $s1
679 ; CHECK-NEXT: [[RES:%[0-9]+]]:_(s32) = G_FMUL [[ARG1]], [[ARG2]]
680 ; CHECK-NEXT: $s0 = COPY [[RES]]
681 ; CHECK-NEXT: RET_ReallyLR implicit $s0
682 define float @test_fmul(float %arg1, float %arg2) {
683   %res = fmul float %arg1, %arg2
684   ret float %res
687 ; CHECK-LABEL: name: test_fdiv
688 ; CHECK: [[ARG1:%[0-9]+]]:_(s32) = COPY $s0
689 ; CHECK-NEXT: [[ARG2:%[0-9]+]]:_(s32) = COPY $s1
690 ; CHECK-NEXT: [[RES:%[0-9]+]]:_(s32) = G_FDIV [[ARG1]], [[ARG2]]
691 ; CHECK-NEXT: $s0 = COPY [[RES]]
692 ; CHECK-NEXT: RET_ReallyLR implicit $s0
693 define float @test_fdiv(float %arg1, float %arg2) {
694   %res = fdiv float %arg1, %arg2
695   ret float %res
698 ; CHECK-LABEL: name: test_frem
699 ; CHECK: [[ARG1:%[0-9]+]]:_(s32) = COPY $s0
700 ; CHECK-NEXT: [[ARG2:%[0-9]+]]:_(s32) = COPY $s1
701 ; CHECK-NEXT: [[RES:%[0-9]+]]:_(s32) = G_FREM [[ARG1]], [[ARG2]]
702 ; CHECK-NEXT: $s0 = COPY [[RES]]
703 ; CHECK-NEXT: RET_ReallyLR implicit $s0
704 define float @test_frem(float %arg1, float %arg2) {
705   %res = frem float %arg1, %arg2
706   ret float %res
709 ; CHECK-LABEL: name: test_fneg
710 ; CHECK: [[ARG1:%[0-9]+]]:_(s32) = COPY $s0
711 ; CHECK-NEXT: [[RES:%[0-9]+]]:_(s32) = G_FNEG [[ARG1]]
712 ; CHECK-NEXT: $s0 = COPY [[RES]]
713 ; CHECK-NEXT: RET_ReallyLR implicit $s0
714 define float @test_fneg(float %arg1) {
715   %res = fneg float %arg1
716   ret float %res
719 ; CHECK-LABEL: name: test_fneg_fmf
720 ; CHECK: [[ARG1:%[0-9]+]]:_(s32) = COPY $s0
721 ; CHECK-NEXT: [[RES:%[0-9]+]]:_(s32) = nnan ninf nsz arcp contract afn reassoc G_FNEG [[ARG1]]
722 ; CHECK-NEXT: $s0 = COPY [[RES]]
723 ; CHECK-NEXT: RET_ReallyLR implicit $s0
724 define float @test_fneg_fmf(float %arg1) {
725   %res = fneg fast float %arg1
726   ret float %res
729 ; CHECK-LABEL: name: test_sadd_overflow
730 ; CHECK: [[LHS:%[0-9]+]]:_(s32) = COPY $w0
731 ; CHECK: [[RHS:%[0-9]+]]:_(s32) = COPY $w1
732 ; CHECK: [[ADDR:%[0-9]+]]:_(p0) = COPY $x2
733 ; CHECK: [[VAL:%[0-9]+]]:_(s32), [[OVERFLOW:%[0-9]+]]:_(s1) = G_SADDO [[LHS]], [[RHS]]
734 ; CHECK: G_STORE [[VAL]](s32), [[ADDR]](p0) :: (store 4 into %ir.addr)
735 ; CHECK: [[CST:%[0-9]+]]:_(s64) = G_CONSTANT i64 4
736 ; CHECK: [[GEP:%[0-9]+]]:_(p0) = G_GEP [[ADDR]], [[CST]](s64)
737 ; CHECK: G_STORE [[OVERFLOW]](s1), [[GEP]](p0) :: (store 1 into %ir.addr + 4, align 4)
738 declare { i32, i1 } @llvm.sadd.with.overflow.i32(i32, i32)
739 define void @test_sadd_overflow(i32 %lhs, i32 %rhs, { i32, i1 }* %addr) {
740   %res = call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 %lhs, i32 %rhs)
741   store { i32, i1 } %res, { i32, i1 }* %addr
742   ret void
745 ; CHECK-LABEL: name: test_uadd_overflow
746 ; CHECK: [[LHS:%[0-9]+]]:_(s32) = COPY $w0
747 ; CHECK: [[RHS:%[0-9]+]]:_(s32) = COPY $w1
748 ; CHECK: [[ADDR:%[0-9]+]]:_(p0) = COPY $x2
749 ; CHECK: [[VAL:%[0-9]+]]:_(s32), [[OVERFLOW:%[0-9]+]]:_(s1) = G_UADDO [[LHS]], [[RHS]]
750 ; CHECK: G_STORE [[VAL]](s32), [[ADDR]](p0) :: (store 4 into %ir.addr)
751 ; CHECK: [[CST:%[0-9]+]]:_(s64) = G_CONSTANT i64 4
752 ; CHECK: [[GEP:%[0-9]+]]:_(p0) = G_GEP [[ADDR]], [[CST]](s64)
753 ; CHECK: G_STORE [[OVERFLOW]](s1), [[GEP]](p0) :: (store 1 into %ir.addr + 4, align 4)
754 declare { i32, i1 } @llvm.uadd.with.overflow.i32(i32, i32)
755 define void @test_uadd_overflow(i32 %lhs, i32 %rhs, { i32, i1 }* %addr) {
756   %res = call { i32, i1 } @llvm.uadd.with.overflow.i32(i32 %lhs, i32 %rhs)
757   store { i32, i1 } %res, { i32, i1 }* %addr
758   ret void
761 ; CHECK-LABEL: name: test_ssub_overflow
762 ; CHECK: [[LHS:%[0-9]+]]:_(s32) = COPY $w0
763 ; CHECK: [[RHS:%[0-9]+]]:_(s32) = COPY $w1
764 ; CHECK: [[ADDR:%[0-9]+]]:_(p0) = COPY $x2
765 ; CHECK: [[VAL:%[0-9]+]]:_(s32), [[OVERFLOW:%[0-9]+]]:_(s1) = G_SSUBO [[LHS]], [[RHS]]
766 ; CHECK: G_STORE [[VAL]](s32), [[ADDR]](p0) :: (store 4 into %ir.subr)
767 ; CHECK: [[CST:%[0-9]+]]:_(s64) = G_CONSTANT i64 4
768 ; CHECK: [[GEP:%[0-9]+]]:_(p0) = G_GEP [[ADDR]], [[CST]](s64)
769 ; CHECK: G_STORE [[OVERFLOW]](s1), [[GEP]](p0) :: (store 1 into %ir.subr + 4, align 4)
770 declare { i32, i1 } @llvm.ssub.with.overflow.i32(i32, i32)
771 define void @test_ssub_overflow(i32 %lhs, i32 %rhs, { i32, i1 }* %subr) {
772   %res = call { i32, i1 } @llvm.ssub.with.overflow.i32(i32 %lhs, i32 %rhs)
773   store { i32, i1 } %res, { i32, i1 }* %subr
774   ret void
777 ; CHECK-LABEL: name: test_usub_overflow
778 ; CHECK: [[LHS:%[0-9]+]]:_(s32) = COPY $w0
779 ; CHECK: [[RHS:%[0-9]+]]:_(s32) = COPY $w1
780 ; CHECK: [[ADDR:%[0-9]+]]:_(p0) = COPY $x2
781 ; CHECK: [[VAL:%[0-9]+]]:_(s32), [[OVERFLOW:%[0-9]+]]:_(s1) = G_USUBO [[LHS]], [[RHS]]
782 ; CHECK: G_STORE [[VAL]](s32), [[ADDR]](p0) :: (store 4 into %ir.subr)
783 ; CHECK: [[CST:%[0-9]+]]:_(s64) = G_CONSTANT i64 4
784 ; CHECK: [[GEP:%[0-9]+]]:_(p0) = G_GEP [[ADDR]], [[CST]](s64)
785 ; CHECK: G_STORE [[OVERFLOW]](s1), [[GEP]](p0) :: (store 1 into %ir.subr + 4, align 4)
786 declare { i32, i1 } @llvm.usub.with.overflow.i32(i32, i32)
787 define void @test_usub_overflow(i32 %lhs, i32 %rhs, { i32, i1 }* %subr) {
788   %res = call { i32, i1 } @llvm.usub.with.overflow.i32(i32 %lhs, i32 %rhs)
789   store { i32, i1 } %res, { i32, i1 }* %subr
790   ret void
793 ; CHECK-LABEL: name: test_smul_overflow
794 ; CHECK: [[LHS:%[0-9]+]]:_(s32) = COPY $w0
795 ; CHECK: [[RHS:%[0-9]+]]:_(s32) = COPY $w1
796 ; CHECK: [[ADDR:%[0-9]+]]:_(p0) = COPY $x2
797 ; CHECK: [[VAL:%[0-9]+]]:_(s32), [[OVERFLOW:%[0-9]+]]:_(s1) = G_SMULO [[LHS]], [[RHS]]
798 ; CHECK: G_STORE [[VAL]](s32), [[ADDR]](p0) :: (store 4 into %ir.addr)
799 ; CHECK: [[CST:%[0-9]+]]:_(s64) = G_CONSTANT i64 4
800 ; CHECK: [[GEP:%[0-9]+]]:_(p0) = G_GEP [[ADDR]], [[CST]](s64)
801 ; CHECK: G_STORE [[OVERFLOW]](s1), [[GEP]](p0) :: (store 1 into %ir.addr + 4, align 4)
802 declare { i32, i1 } @llvm.smul.with.overflow.i32(i32, i32)
803 define void @test_smul_overflow(i32 %lhs, i32 %rhs, { i32, i1 }* %addr) {
804   %res = call { i32, i1 } @llvm.smul.with.overflow.i32(i32 %lhs, i32 %rhs)
805   store { i32, i1 } %res, { i32, i1 }* %addr
806   ret void
809 ; CHECK-LABEL: name: test_umul_overflow
810 ; CHECK: [[LHS:%[0-9]+]]:_(s32) = COPY $w0
811 ; CHECK: [[RHS:%[0-9]+]]:_(s32) = COPY $w1
812 ; CHECK: [[ADDR:%[0-9]+]]:_(p0) = COPY $x2
813 ; CHECK: [[VAL:%[0-9]+]]:_(s32), [[OVERFLOW:%[0-9]+]]:_(s1) = G_UMULO [[LHS]], [[RHS]]
814 ; CHECK: G_STORE [[VAL]](s32), [[ADDR]](p0) :: (store 4 into %ir.addr)
815 ; CHECK: [[CST:%[0-9]+]]:_(s64) = G_CONSTANT i64 4
816 ; CHECK: [[GEP:%[0-9]+]]:_(p0) = G_GEP [[ADDR]], [[CST]](s64)
817 ; CHECK: G_STORE [[OVERFLOW]](s1), [[GEP]](p0) :: (store 1 into %ir.addr + 4, align 4)
818 declare { i32, i1 } @llvm.umul.with.overflow.i32(i32, i32)
819 define void @test_umul_overflow(i32 %lhs, i32 %rhs, { i32, i1 }* %addr) {
820   %res = call { i32, i1 } @llvm.umul.with.overflow.i32(i32 %lhs, i32 %rhs)
821   store { i32, i1 } %res, { i32, i1 }* %addr
822   ret void
825 ; CHECK-LABEL: name: test_extractvalue
826 ; CHECK: %0:_(p0) = COPY $x0
827 ; CHECK: [[LD1:%[0-9]+]]:_(s8) = G_LOAD %0(p0) :: (load 1 from %ir.addr, align 4)
828 ; CHECK: [[CST1:%[0-9]+]]:_(s64) = G_CONSTANT i64 4
829 ; CHECK: [[GEP1:%[0-9]+]]:_(p0) = G_GEP %0, [[CST1]](s64)
830 ; CHECK: [[LD2:%[0-9]+]]:_(s8) = G_LOAD [[GEP1]](p0) :: (load 1 from %ir.addr + 4, align 4)
831 ; CHECK: [[CST2:%[0-9]+]]:_(s64) = G_CONSTANT i64 8
832 ; CHECK: [[GEP2:%[0-9]+]]:_(p0) = G_GEP %0, [[CST2]](s64)
833 ; CHECK: [[LD3:%[0-9]+]]:_(s32) = G_LOAD [[GEP2]](p0) :: (load 4 from %ir.addr + 8)
834 ; CHECK: [[CST3:%[0-9]+]]:_(s64) = G_CONSTANT i64 12
835 ; CHECK: [[GEP3:%[0-9]+]]:_(p0) = G_GEP %0, [[CST3]](s64)
836 ; CHECK: [[LD4:%[0-9]+]]:_(s32) = G_LOAD [[GEP3]](p0) :: (load 4 from %ir.addr + 12)
837 ; CHECK: $w0 = COPY [[LD3]](s32)
838 %struct.nested = type {i8, { i8, i32 }, i32}
839 define i32 @test_extractvalue(%struct.nested* %addr) {
840   %struct = load %struct.nested, %struct.nested* %addr
841   %res = extractvalue %struct.nested %struct, 1, 1
842   ret i32 %res
845 ; CHECK-LABEL: name: test_extractvalue_agg
846 ; CHECK: %0:_(p0) = COPY $x0
847 ; CHECK: %1:_(p0) = COPY $x1
848 ; CHECK: [[LD1:%[0-9]+]]:_(s8) = G_LOAD %0(p0) :: (load 1 from %ir.addr, align 4)
849 ; CHECK: [[CST1:%[0-9]+]]:_(s64) = G_CONSTANT i64 4
850 ; CHECK: [[GEP1:%[0-9]+]]:_(p0) = G_GEP %0, [[CST1]](s64)
851 ; CHECK: [[LD2:%[0-9]+]]:_(s8) = G_LOAD [[GEP1]](p0) :: (load 1 from %ir.addr + 4, align 4)
852 ; CHECK: [[CST2:%[0-9]+]]:_(s64) = G_CONSTANT i64 8
853 ; CHECK: [[GEP2:%[0-9]+]]:_(p0) = G_GEP %0, [[CST2]](s64)
854 ; CHECK: [[LD3:%[0-9]+]]:_(s32) = G_LOAD [[GEP2]](p0) :: (load 4 from %ir.addr + 8)
855 ; CHECK: [[CST3:%[0-9]+]]:_(s64) = G_CONSTANT i64 12
856 ; CHECK: [[GEP3:%[0-9]+]]:_(p0) = G_GEP %0, [[CST3]](s64)
857 ; CHECK: [[LD4:%[0-9]+]]:_(s32) = G_LOAD [[GEP3]](p0) :: (load 4 from %ir.addr + 12)
858 ; CHECK: G_STORE [[LD2]](s8), %1(p0) :: (store 1 into %ir.addr2, align 4)
859 ; CHECK: [[GEP4:%[0-9]+]]:_(p0) = G_GEP %1, [[CST1]](s64)
860 ; CHECK: G_STORE [[LD3]](s32), [[GEP4]](p0) :: (store 4 into %ir.addr2 + 4)
861 define void @test_extractvalue_agg(%struct.nested* %addr, {i8, i32}* %addr2) {
862   %struct = load %struct.nested, %struct.nested* %addr
863   %res = extractvalue %struct.nested %struct, 1
864   store {i8, i32} %res, {i8, i32}* %addr2
865   ret void
868 ; CHECK-LABEL: name: test_trivial_extract_ptr
869 ; CHECK: [[STRUCT:%[0-9]+]]:_(p0) = COPY $x0
870 ; CHECK: [[VAL32:%[0-9]+]]:_(s32) = COPY $w1
871 ; CHECK: [[VAL:%[0-9]+]]:_(s8) = G_TRUNC [[VAL32]]
872 ; CHECK: G_STORE [[VAL]](s8), [[STRUCT]](p0)
873 define void @test_trivial_extract_ptr([1 x i8*] %s, i8 %val) {
874   %addr = extractvalue [1 x i8*] %s, 0
875   store i8 %val, i8* %addr
876   ret void
879 ; CHECK-LABEL: name: test_insertvalue
880 ; CHECK: %0:_(p0) = COPY $x0
881 ; CHECK: %1:_(s32) = COPY $w1
882 ; CHECK: [[LD1:%[0-9]+]]:_(s8) = G_LOAD %0(p0) :: (load 1 from %ir.addr, align 4)
883 ; CHECK: [[CST1:%[0-9]+]]:_(s64) = G_CONSTANT i64 4
884 ; CHECK: [[GEP1:%[0-9]+]]:_(p0) = G_GEP %0, [[CST1]](s64)
885 ; CHECK: [[LD2:%[0-9]+]]:_(s8) = G_LOAD [[GEP1]](p0) :: (load 1 from %ir.addr + 4, align 4)
886 ; CHECK: [[CST2:%[0-9]+]]:_(s64) = G_CONSTANT i64 8
887 ; CHECK: [[GEP2:%[0-9]+]]:_(p0) = G_GEP %0, [[CST2]](s64)
888 ; CHECK: [[LD3:%[0-9]+]]:_(s32) = G_LOAD [[GEP2]](p0) :: (load 4 from %ir.addr + 8)
889 ; CHECK: [[CST3:%[0-9]+]]:_(s64) = G_CONSTANT i64 12
890 ; CHECK: [[GEP3:%[0-9]+]]:_(p0) = G_GEP %0, [[CST3]](s64)
891 ; CHECK: [[LD4:%[0-9]+]]:_(s32) = G_LOAD [[GEP3]](p0) :: (load 4 from %ir.addr + 12)
892 ; CHECK: G_STORE [[LD1]](s8), %0(p0) :: (store 1 into %ir.addr, align 4)
893 ; CHECK: [[GEP4:%[0-9]+]]:_(p0) = G_GEP %0, [[CST1]](s64)
894 ; CHECK: G_STORE [[LD2]](s8), [[GEP4]](p0) :: (store 1 into %ir.addr + 4, align 4)
895 ; CHECK: [[GEP5:%[0-9]+]]:_(p0) = G_GEP %0, [[CST2]](s64)
896 ; CHECK: G_STORE %1(s32), [[GEP5]](p0) :: (store 4 into %ir.addr + 8)
897 ; CHECK: [[GEP6:%[0-9]+]]:_(p0) = G_GEP %0, [[CST3]](s64)
898 ; CHECK: G_STORE [[LD4]](s32), [[GEP6]](p0) :: (store 4 into %ir.addr + 12)
899 define void @test_insertvalue(%struct.nested* %addr, i32 %val) {
900   %struct = load %struct.nested, %struct.nested* %addr
901   %newstruct = insertvalue %struct.nested %struct, i32 %val, 1, 1
902   store %struct.nested %newstruct, %struct.nested* %addr
903   ret void
906 define [1 x i64] @test_trivial_insert([1 x i64] %s, i64 %val) {
907 ; CHECK-LABEL: name: test_trivial_insert
908 ; CHECK: [[STRUCT:%[0-9]+]]:_(s64) = COPY $x0
909 ; CHECK: [[VAL:%[0-9]+]]:_(s64) = COPY $x1
910 ; CHECK: $x0 = COPY [[VAL]]
911   %res = insertvalue [1 x i64] %s, i64 %val, 0
912   ret [1 x i64] %res
915 define [1 x i8*] @test_trivial_insert_ptr([1 x i8*] %s, i8* %val) {
916 ; CHECK-LABEL: name: test_trivial_insert_ptr
917 ; CHECK: [[STRUCT:%[0-9]+]]:_(p0) = COPY $x0
918 ; CHECK: [[VAL:%[0-9]+]]:_(p0) = COPY $x1
919 ; CHECK: $x0 = COPY [[VAL]]
920   %res = insertvalue [1 x i8*] %s, i8* %val, 0
921   ret [1 x i8*] %res
924 ; CHECK-LABEL: name: test_insertvalue_agg
925 ; CHECK: %0:_(p0) = COPY $x0
926 ; CHECK: %1:_(p0) = COPY $x1
927 ; CHECK: [[LD1:%[0-9]+]]:_(s8) = G_LOAD %1(p0) :: (load 1 from %ir.addr2, align 4)
928 ; CHECK: [[CST1:%[0-9]+]]:_(s64) = G_CONSTANT i64 4
929 ; CHECK: [[GEP1:%[0-9]+]]:_(p0) = G_GEP %1, [[CST1]](s64)
930 ; CHECK: [[LD2:%[0-9]+]]:_(s32) = G_LOAD [[GEP1]](p0) :: (load 4 from %ir.addr2 + 4)
931 ; CHECK: [[LD3:%[0-9]+]]:_(s8) = G_LOAD %0(p0) :: (load 1 from %ir.addr, align 4)
932 ; CHECK: [[GEP2:%[0-9]+]]:_(p0) = G_GEP %0, [[CST1]](s64)
933 ; CHECK: [[LD4:%[0-9]+]]:_(s8) = G_LOAD [[GEP2]](p0) :: (load 1 from %ir.addr + 4, align 4)
934 ; CHECK: [[CST3:%[0-9]+]]:_(s64) = G_CONSTANT i64 8
935 ; CHECK: [[GEP3:%[0-9]+]]:_(p0) = G_GEP %0, [[CST3]](s64)
936 ; CHECK: [[LD5:%[0-9]+]]:_(s32) = G_LOAD [[GEP3]](p0) :: (load 4 from %ir.addr + 8)
937 ; CHECK: [[CST4:%[0-9]+]]:_(s64) = G_CONSTANT i64 12
938 ; CHECK: [[GEP4:%[0-9]+]]:_(p0) = G_GEP %0, [[CST4]](s64)
939 ; CHECK: [[LD6:%[0-9]+]]:_(s32) = G_LOAD [[GEP4]](p0) :: (load 4 from %ir.addr + 12)
940 ; CHECK: G_STORE [[LD3]](s8), %0(p0) :: (store 1 into %ir.addr, align 4)
941 ; CHECK: [[GEP5:%[0-9]+]]:_(p0) = G_GEP %0, [[CST1]](s64)
942 ; CHECK: G_STORE [[LD1]](s8), [[GEP5]](p0) :: (store 1 into %ir.addr + 4, align 4)
943 ; CHECK: [[GEP6:%[0-9]+]]:_(p0) = G_GEP %0, [[CST3]](s64)
944 ; CHECK: G_STORE [[LD2]](s32), [[GEP6]](p0) :: (store 4 into %ir.addr + 8)
945 ; CHECK: [[GEP7:%[0-9]+]]:_(p0) = G_GEP %0, [[CST4]](s64)
946 ; CHECK: G_STORE [[LD6]](s32), [[GEP7]](p0) :: (store 4 into %ir.addr + 12)
947 define void @test_insertvalue_agg(%struct.nested* %addr, {i8, i32}* %addr2) {
948   %smallstruct = load {i8, i32}, {i8, i32}* %addr2
949   %struct = load %struct.nested, %struct.nested* %addr
950   %res = insertvalue %struct.nested %struct, {i8, i32} %smallstruct, 1
951   store %struct.nested %res, %struct.nested* %addr
952   ret void
955 ; CHECK-LABEL: name: test_select
956 ; CHECK: [[TST_C:%[0-9]+]]:_(s32) = COPY $w0
957 ; CHECK: [[TST:%[0-9]+]]:_(s1) = G_TRUNC [[TST_C]]
958 ; CHECK: [[LHS:%[0-9]+]]:_(s32) = COPY $w1
959 ; CHECK: [[RHS:%[0-9]+]]:_(s32) = COPY $w2
960 ; CHECK: [[RES:%[0-9]+]]:_(s32) = G_SELECT [[TST]](s1), [[LHS]], [[RHS]]
961 ; CHECK: $w0 = COPY [[RES]]
962 define i32 @test_select(i1 %tst, i32 %lhs, i32 %rhs) {
963   %res = select i1 %tst, i32 %lhs, i32 %rhs
964   ret i32 %res
967 ; CHECK-LABEL: name: test_select_ptr
968 ; CHECK: [[TST_C:%[0-9]+]]:_(s32) = COPY $w0
969 ; CHECK: [[TST:%[0-9]+]]:_(s1) = G_TRUNC [[TST_C]]
970 ; CHECK: [[LHS:%[0-9]+]]:_(p0) = COPY $x1
971 ; CHECK: [[RHS:%[0-9]+]]:_(p0) = COPY $x2
972 ; CHECK: [[RES:%[0-9]+]]:_(p0) = G_SELECT [[TST]](s1), [[LHS]], [[RHS]]
973 ; CHECK: $x0 = COPY [[RES]]
974 define i8* @test_select_ptr(i1 %tst, i8* %lhs, i8* %rhs) {
975   %res = select i1 %tst, i8* %lhs, i8* %rhs
976   ret i8* %res
979 ; CHECK-LABEL: name: test_select_vec
980 ; CHECK: [[TST_C:%[0-9]+]]:_(s32) = COPY $w0
981 ; CHECK: [[TST:%[0-9]+]]:_(s1) = G_TRUNC [[TST_C]]
982 ; CHECK: [[LHS:%[0-9]+]]:_(<4 x s32>) = COPY $q0
983 ; CHECK: [[RHS:%[0-9]+]]:_(<4 x s32>) = COPY $q1
984 ; CHECK: [[RES:%[0-9]+]]:_(<4 x s32>) = G_SELECT [[TST]](s1), [[LHS]], [[RHS]]
985 ; CHECK: $q0 = COPY [[RES]]
986 define <4 x i32> @test_select_vec(i1 %tst, <4 x i32> %lhs, <4 x i32> %rhs) {
987   %res = select i1 %tst, <4 x i32> %lhs, <4 x i32> %rhs
988   ret <4 x i32> %res
991 ; CHECK-LABEL: name: test_vselect_vec
992 ; CHECK: [[TST32:%[0-9]+]]:_(<4 x s32>) = COPY $q0
993 ; CHECK: [[LHS:%[0-9]+]]:_(<4 x s32>) = COPY $q1
994 ; CHECK: [[RHS:%[0-9]+]]:_(<4 x s32>) = COPY $q2
995 ; CHECK: [[TST:%[0-9]+]]:_(<4 x s1>) = G_TRUNC [[TST32]](<4 x s32>)
996 ; CHECK: [[RES:%[0-9]+]]:_(<4 x s32>) = G_SELECT [[TST]](<4 x s1>), [[LHS]], [[RHS]]
997 ; CHECK: $q0 = COPY [[RES]]
998 define <4 x i32> @test_vselect_vec(<4 x i32> %tst32, <4 x i32> %lhs, <4 x i32> %rhs) {
999   %tst = trunc <4 x i32> %tst32 to <4 x i1>
1000   %res = select <4 x i1> %tst, <4 x i32> %lhs, <4 x i32> %rhs
1001   ret <4 x i32> %res
1004 ; CHECK-LABEL: name: test_fptosi
1005 ; CHECK: [[FPADDR:%[0-9]+]]:_(p0) = COPY $x0
1006 ; CHECK: [[FP:%[0-9]+]]:_(s32) = G_LOAD [[FPADDR]](p0)
1007 ; CHECK: [[RES:%[0-9]+]]:_(s64) = G_FPTOSI [[FP]](s32)
1008 ; CHECK: $x0 = COPY [[RES]]
1009 define i64 @test_fptosi(float* %fp.addr) {
1010   %fp = load float, float* %fp.addr
1011   %res = fptosi float %fp to i64
1012   ret i64 %res
1015 ; CHECK-LABEL: name: test_fptoui
1016 ; CHECK: [[FPADDR:%[0-9]+]]:_(p0) = COPY $x0
1017 ; CHECK: [[FP:%[0-9]+]]:_(s32) = G_LOAD [[FPADDR]](p0)
1018 ; CHECK: [[RES:%[0-9]+]]:_(s64) = G_FPTOUI [[FP]](s32)
1019 ; CHECK: $x0 = COPY [[RES]]
1020 define i64 @test_fptoui(float* %fp.addr) {
1021   %fp = load float, float* %fp.addr
1022   %res = fptoui float %fp to i64
1023   ret i64 %res
1026 ; CHECK-LABEL: name: test_sitofp
1027 ; CHECK: [[ADDR:%[0-9]+]]:_(p0) = COPY $x0
1028 ; CHECK: [[IN:%[0-9]+]]:_(s32) = COPY $w1
1029 ; CHECK: [[FP:%[0-9]+]]:_(s64) = G_SITOFP [[IN]](s32)
1030 ; CHECK: G_STORE [[FP]](s64), [[ADDR]](p0)
1031 define void @test_sitofp(double* %addr, i32 %in) {
1032   %fp = sitofp i32 %in to double
1033   store double %fp, double* %addr
1034   ret void
1037 ; CHECK-LABEL: name: test_uitofp
1038 ; CHECK: [[ADDR:%[0-9]+]]:_(p0) = COPY $x0
1039 ; CHECK: [[IN:%[0-9]+]]:_(s32) = COPY $w1
1040 ; CHECK: [[FP:%[0-9]+]]:_(s64) = G_UITOFP [[IN]](s32)
1041 ; CHECK: G_STORE [[FP]](s64), [[ADDR]](p0)
1042 define void @test_uitofp(double* %addr, i32 %in) {
1043   %fp = uitofp i32 %in to double
1044   store double %fp, double* %addr
1045   ret void
1048 ; CHECK-LABEL: name: test_fpext
1049 ; CHECK: [[IN:%[0-9]+]]:_(s32) = COPY $s0
1050 ; CHECK: [[RES:%[0-9]+]]:_(s64) = G_FPEXT [[IN]](s32)
1051 ; CHECK: $d0 = COPY [[RES]]
1052 define double @test_fpext(float %in) {
1053   %res = fpext float %in to double
1054   ret double %res
1057 ; CHECK-LABEL: name: test_fptrunc
1058 ; CHECK: [[IN:%[0-9]+]]:_(s64) = COPY $d0
1059 ; CHECK: [[RES:%[0-9]+]]:_(s32) = G_FPTRUNC [[IN]](s64)
1060 ; CHECK: $s0 = COPY [[RES]]
1061 define float @test_fptrunc(double %in) {
1062   %res = fptrunc double %in to float
1063   ret float %res
1066 ; CHECK-LABEL: name: test_constant_float
1067 ; CHECK: [[ADDR:%[0-9]+]]:_(p0) = COPY $x0
1068 ; CHECK: [[TMP:%[0-9]+]]:_(s32) = G_FCONSTANT float 1.500000e+00
1069 ; CHECK: G_STORE [[TMP]](s32), [[ADDR]](p0)
1070 define void @test_constant_float(float* %addr) {
1071   store float 1.5, float* %addr
1072   ret void
1075 ; CHECK-LABEL: name: float_comparison
1076 ; CHECK: [[LHSADDR:%[0-9]+]]:_(p0) = COPY $x0
1077 ; CHECK: [[RHSADDR:%[0-9]+]]:_(p0) = COPY $x1
1078 ; CHECK: [[BOOLADDR:%[0-9]+]]:_(p0) = COPY $x2
1079 ; CHECK: [[LHS:%[0-9]+]]:_(s32) = G_LOAD [[LHSADDR]](p0)
1080 ; CHECK: [[RHS:%[0-9]+]]:_(s32) = G_LOAD [[RHSADDR]](p0)
1081 ; CHECK: [[TST:%[0-9]+]]:_(s1) = nnan ninf nsz arcp contract afn reassoc G_FCMP floatpred(oge), [[LHS]](s32), [[RHS]]
1082 ; CHECK: G_STORE [[TST]](s1), [[BOOLADDR]](p0)
1083 define void @float_comparison(float* %a.addr, float* %b.addr, i1* %bool.addr) {
1084   %a = load float, float* %a.addr
1085   %b = load float, float* %b.addr
1086   %res = fcmp nnan ninf nsz arcp contract afn reassoc oge float %a, %b
1087   store i1 %res, i1* %bool.addr
1088   ret void
1091 ; CHECK-LABEL: name: trivial_float_comparison
1092 ; CHECK: [[ENTRY_R1:%[0-9]+]]:_(s1) = G_CONSTANT i1 false
1093 ; CHECK: [[ENTRY_R2:%[0-9]+]]:_(s1) = G_CONSTANT i1 true
1094 ; CHECK: [[R1:%[0-9]+]]:_(s1) = COPY [[ENTRY_R1]](s1)
1095 ; CHECK: [[R2:%[0-9]+]]:_(s1) = COPY [[ENTRY_R2]](s1)
1096 ; CHECK: G_ADD [[R1]], [[R2]]
1097 define i1 @trivial_float_comparison(double %a, double %b) {
1098   %r1 = fcmp false double %a, %b
1099   %r2 = fcmp true double %a, %b
1100   %sum = add i1 %r1, %r2
1101   ret i1 %sum
1104 @var = global i32 0
1106 define i32* @test_global() {
1107 ; CHECK-LABEL: name: test_global
1108 ; CHECK: [[TMP:%[0-9]+]]:_(p0) = G_GLOBAL_VALUE @var{{$}}
1109 ; CHECK: $x0 = COPY [[TMP]](p0)
1111   ret i32* @var
1114 @var1 = addrspace(42) global i32 0
1115 define i32 addrspace(42)* @test_global_addrspace() {
1116 ; CHECK-LABEL: name: test_global
1117 ; CHECK: [[TMP:%[0-9]+]]:_(p42) = G_GLOBAL_VALUE @var1{{$}}
1118 ; CHECK: $x0 = COPY [[TMP]](p42)
1120   ret i32 addrspace(42)* @var1
1124 define void()* @test_global_func() {
1125 ; CHECK-LABEL: name: test_global_func
1126 ; CHECK: [[TMP:%[0-9]+]]:_(p0) = G_GLOBAL_VALUE @allocai64{{$}}
1127 ; CHECK: $x0 = COPY [[TMP]](p0)
1129   ret void()* @allocai64
1132 declare void @llvm.memcpy.p0i8.p0i8.i64(i8*, i8*, i64, i1)
1133 define void @test_memcpy(i8* %dst, i8* %src, i64 %size) {
1134 ; CHECK-LABEL: name: test_memcpy
1135 ; CHECK: [[DST:%[0-9]+]]:_(p0) = COPY $x0
1136 ; CHECK: [[SRC:%[0-9]+]]:_(p0) = COPY $x1
1137 ; CHECK: [[SIZE:%[0-9]+]]:_(s64) = COPY $x2
1138 ; CHECK: G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.memcpy), [[DST]](p0), [[SRC]](p0), [[SIZE]](s64) :: (store 1 into %ir.dst), (load 1 from %ir.src)
1139   call void @llvm.memcpy.p0i8.p0i8.i64(i8* %dst, i8* %src, i64 %size, i1 0)
1140   ret void
1143 declare void @llvm.memcpy.p1i8.p1i8.i64(i8 addrspace(1)*, i8 addrspace(1)*, i64, i1)
1144 define void @test_memcpy_nonzero_as(i8 addrspace(1)* %dst, i8 addrspace(1) * %src, i64 %size) {
1145 ; CHECK-LABEL: name: test_memcpy_nonzero_as
1146 ; CHECK: [[DST:%[0-9]+]]:_(p1) = COPY $x0
1147 ; CHECK: [[SRC:%[0-9]+]]:_(p1) = COPY $x1
1148 ; CHECK: [[SIZE:%[0-9]+]]:_(s64) = COPY $x2
1149 ; CHECK: G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.memcpy), [[DST]](p1), [[SRC]](p1), [[SIZE]](s64) :: (store 1 into %ir.dst, addrspace 1), (load 1 from %ir.src, addrspace 1)
1150   call void @llvm.memcpy.p1i8.p1i8.i64(i8 addrspace(1)* %dst, i8 addrspace(1)* %src, i64 %size, i1 0)
1151   ret void
1154 declare void @llvm.memmove.p0i8.p0i8.i64(i8*, i8*, i64, i1)
1155 define void @test_memmove(i8* %dst, i8* %src, i64 %size) {
1156 ; CHECK-LABEL: name: test_memmove
1157 ; CHECK: [[DST:%[0-9]+]]:_(p0) = COPY $x0
1158 ; CHECK: [[SRC:%[0-9]+]]:_(p0) = COPY $x1
1159 ; CHECK: [[SIZE:%[0-9]+]]:_(s64) = COPY $x2
1160 ; CHECK: G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.memmove), [[DST]](p0), [[SRC]](p0), [[SIZE]](s64) :: (store 1 into %ir.dst), (load 1 from %ir.src)
1161   call void @llvm.memmove.p0i8.p0i8.i64(i8* %dst, i8* %src, i64 %size, i1 0)
1162   ret void
1165 declare void @llvm.memset.p0i8.i64(i8*, i8, i64, i1)
1166 define void @test_memset(i8* %dst, i8 %val, i64 %size) {
1167 ; CHECK-LABEL: name: test_memset
1168 ; CHECK: [[DST:%[0-9]+]]:_(p0) = COPY $x0
1169 ; CHECK: [[SRC_C:%[0-9]+]]:_(s32) = COPY $w1
1170 ; CHECK: [[SRC:%[0-9]+]]:_(s8) = G_TRUNC [[SRC_C]]
1171 ; CHECK: [[SIZE:%[0-9]+]]:_(s64) = COPY $x2
1172 ; CHECK: G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.memset), [[DST]](p0), [[SRC]](s8), [[SIZE]](s64) :: (store 1 into %ir.dst)
1173   call void @llvm.memset.p0i8.i64(i8* %dst, i8 %val, i64 %size, i1 0)
1174   ret void
1177 declare i64 @llvm.objectsize.i64(i8*, i1)
1178 declare i32 @llvm.objectsize.i32(i8*, i1)
1179 define void @test_objectsize(i8* %addr0, i8* %addr1) {
1180 ; CHECK-LABEL: name: test_objectsize
1181 ; CHECK: [[ADDR0:%[0-9]+]]:_(p0) = COPY $x0
1182 ; CHECK: [[ADDR1:%[0-9]+]]:_(p0) = COPY $x1
1183 ; CHECK: {{%[0-9]+}}:_(s64) = G_CONSTANT i64 -1
1184 ; CHECK: {{%[0-9]+}}:_(s64) = G_CONSTANT i64 0
1185 ; CHECK: {{%[0-9]+}}:_(s32) = G_CONSTANT i32 -1
1186 ; CHECK: {{%[0-9]+}}:_(s32) = G_CONSTANT i32 0
1187   %size64.0 = call i64 @llvm.objectsize.i64(i8* %addr0, i1 0)
1188   %size64.intmin = call i64 @llvm.objectsize.i64(i8* %addr0, i1 1)
1189   %size32.0 = call i32 @llvm.objectsize.i32(i8* %addr0, i1 0)
1190   %size32.intmin = call i32 @llvm.objectsize.i32(i8* %addr0, i1 1)
1191   ret void
1194 define void @test_large_const(i128* %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, i128* %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 i8* @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 i8* inttoptr(i32 42 to i8*)
1219 declare void @llvm.va_end(i8*)
1220 define void @test_va_end(i8* %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(i8* %list)
1226   ret void
1229 define void @test_va_arg(i8* %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 i8* %list, i64
1237   %v1 = va_arg i8* %list, i8
1238   %v2 = va_arg i8* %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.fma.f32(float, float, float)
1254 define float @test_fma_intrin(float %a, float %b, float %c) {
1255 ; CHECK-LABEL: name: test_fma_intrin
1256 ; CHECK: [[A:%[0-9]+]]:_(s32) = COPY $s0
1257 ; CHECK: [[B:%[0-9]+]]:_(s32) = COPY $s1
1258 ; CHECK: [[C:%[0-9]+]]:_(s32) = COPY $s2
1259 ; CHECK: [[RES:%[0-9]+]]:_(s32) = nnan ninf nsz arcp contract afn reassoc G_FMA [[A]], [[B]], [[C]]
1260 ; CHECK: $s0 = COPY [[RES]]
1261   %res = call nnan ninf nsz arcp contract afn reassoc float @llvm.fma.f32(float %a, float %b, float %c)
1262   ret float %res
1265 declare float @llvm.exp.f32(float)
1266 define float @test_exp_intrin(float %a) {
1267 ; CHECK-LABEL: name: test_exp_intrin
1268 ; CHECK: [[A:%[0-9]+]]:_(s32) = COPY $s0
1269 ; CHECK: [[RES:%[0-9]+]]:_(s32) = nnan ninf nsz arcp contract afn reassoc G_FEXP [[A]]
1270 ; CHECK: $s0 = COPY [[RES]]
1271   %res = call nnan ninf nsz arcp contract afn reassoc float @llvm.exp.f32(float %a)
1272   ret float %res
1275 declare float @llvm.exp2.f32(float)
1276 define float @test_exp2_intrin(float %a) {
1277 ; CHECK-LABEL: name: test_exp2_intrin
1278 ; CHECK: [[A:%[0-9]+]]:_(s32) = COPY $s0
1279 ; CHECK: [[RES:%[0-9]+]]:_(s32) = nnan ninf nsz arcp contract afn reassoc G_FEXP2 [[A]]
1280 ; CHECK: $s0 = COPY [[RES]]
1281   %res = call nnan ninf nsz arcp contract afn reassoc float @llvm.exp2.f32(float %a)
1282   ret float %res
1285 declare float @llvm.log.f32(float)
1286 define float @test_log_intrin(float %a) {
1287 ; CHECK-LABEL: name: test_log_intrin
1288 ; CHECK: [[A:%[0-9]+]]:_(s32) = COPY $s0
1289 ; CHECK: [[RES:%[0-9]+]]:_(s32) = nnan ninf nsz arcp contract afn reassoc G_FLOG [[A]]
1290 ; CHECK: $s0 = COPY [[RES]]
1291   %res = call nnan ninf nsz arcp contract afn reassoc float @llvm.log.f32(float %a)
1292   ret float %res
1295 declare float @llvm.log2.f32(float)
1296 define float @test_log2_intrin(float %a) {
1297 ; CHECK-LABEL: name: test_log2_intrin
1298 ; CHECK: [[A:%[0-9]+]]:_(s32) = COPY $s0
1299 ; CHECK: [[RES:%[0-9]+]]:_(s32) = G_FLOG2 [[A]]
1300 ; CHECK: $s0 = COPY [[RES]]
1301   %res = call float @llvm.log2.f32(float %a)
1302   ret float %res
1305 declare float @llvm.log10.f32(float)
1306 define float @test_log10_intrin(float %a) {
1307 ; CHECK-LABEL: name: test_log10_intrin
1308 ; CHECK: [[A:%[0-9]+]]:_(s32) = COPY $s0
1309 ; CHECK: [[RES:%[0-9]+]]:_(s32) = nnan ninf nsz arcp contract afn reassoc G_FLOG10 [[A]]
1310 ; CHECK: $s0 = COPY [[RES]]
1311   %res = call nnan ninf nsz arcp contract afn reassoc float @llvm.log10.f32(float %a)
1312   ret float %res
1315 declare float @llvm.fabs.f32(float)
1316 define float @test_fabs_intrin(float %a) {
1317 ; CHECK-LABEL: name: test_fabs_intrin
1318 ; CHECK: [[A:%[0-9]+]]:_(s32) = COPY $s0
1319 ; CHECK: [[RES:%[0-9]+]]:_(s32) = nnan ninf nsz arcp contract afn reassoc G_FABS [[A]]
1320 ; CHECK: $s0 = COPY [[RES]]
1321   %res = call nnan ninf nsz arcp contract afn reassoc float @llvm.fabs.f32(float %a)
1322   ret float %res
1325 declare float @llvm.copysign.f32(float, float)
1326 define float @test_fcopysign_intrin(float %a, float %b) {
1327 ; CHECK-LABEL: name: test_fcopysign_intrin
1328 ; CHECK: [[A:%[0-9]+]]:_(s32) = COPY $s0
1329 ; CHECK: [[B:%[0-9]+]]:_(s32) = COPY $s1
1330 ; CHECK: [[RES:%[0-9]+]]:_(s32) = nnan ninf nsz arcp contract afn reassoc G_FCOPYSIGN [[A]], [[B]]
1331 ; CHECK: $s0 = COPY [[RES]]
1333   %res = call nnan ninf nsz arcp contract afn reassoc float @llvm.copysign.f32(float %a, float %b)
1334   ret float %res
1337 declare float @llvm.canonicalize.f32(float)
1338 define float @test_fcanonicalize_intrin(float %a) {
1339 ; CHECK-LABEL: name: test_fcanonicalize_intrin
1340 ; CHECK: [[A:%[0-9]+]]:_(s32) = COPY $s0
1341 ; CHECK: [[RES:%[0-9]+]]:_(s32) = nnan ninf nsz arcp contract afn reassoc G_FCANONICALIZE [[A]]
1342 ; CHECK: $s0 = COPY [[RES]]
1343   %res = call nnan ninf nsz arcp contract afn reassoc float @llvm.canonicalize.f32(float %a)
1344   ret float %res
1347 declare float @llvm.trunc.f32(float)
1348 define float @test_intrinsic_trunc(float %a) {
1349 ; CHECK-LABEL: name: test_intrinsic_trunc
1350 ; CHECK: [[A:%[0-9]+]]:_(s32) = COPY $s0
1351 ; CHECK: [[RES:%[0-9]+]]:_(s32) = G_INTRINSIC_TRUNC [[A]]
1352 ; CHECK: $s0 = COPY [[RES]]
1353   %res = call float @llvm.trunc.f32(float %a)
1354   ret float %res
1357 declare float @llvm.round.f32(float)
1358 define float @test_intrinsic_round(float %a) {
1359 ; CHECK-LABEL: name: test_intrinsic_round
1360 ; CHECK: [[A:%[0-9]+]]:_(s32) = COPY $s0
1361 ; CHECK: [[RES:%[0-9]+]]:_(s32) = G_INTRINSIC_ROUND [[A]]
1362 ; CHECK: $s0 = COPY [[RES]]
1363   %res = call float @llvm.round.f32(float %a)
1364   ret float %res
1367 declare i32 @llvm.ctlz.i32(i32, i1)
1368 define i32 @test_ctlz_intrinsic_zero_not_undef(i32 %a) {
1369 ; CHECK-LABEL: name: test_ctlz_intrinsic_zero_not_undef
1370 ; CHECK: [[A:%[0-9]+]]:_(s32) = COPY $w0
1371 ; CHECK: [[RES:%[0-9]+]]:_(s32) = G_CTLZ [[A]]
1372 ; CHECK: $w0 = COPY [[RES]]
1373   %res = call i32 @llvm.ctlz.i32(i32 %a, i1 0)
1374   ret i32 %res
1377 declare i32 @llvm.cttz.i32(i32, i1)
1378 define i32 @test_cttz_intrinsic_zero_undef(i32 %a) {
1379 ; CHECK-LABEL: name: test_cttz_intrinsic_zero_undef
1380 ; CHECK: [[A:%[0-9]+]]:_(s32) = COPY $w0
1381 ; CHECK: [[RES:%[0-9]+]]:_(s32) = G_CTTZ_ZERO_UNDEF [[A]]
1382 ; CHECK: $w0 = COPY [[RES]]
1383   %res = call i32 @llvm.cttz.i32(i32 %a, i1 1)
1384   ret i32 %res
1387 declare i32 @llvm.ctpop.i32(i32)
1388 define i32 @test_ctpop_intrinsic(i32 %a) {
1389 ; CHECK-LABEL: name: test_ctpop
1390 ; CHECK: [[A:%[0-9]+]]:_(s32) = COPY $w0
1391 ; CHECK: [[RES:%[0-9]+]]:_(s32) = G_CTPOP [[A]]
1392 ; CHECK: $w0 = COPY [[RES]]
1393   %res = call i32 @llvm.ctpop.i32(i32 %a)
1394   ret i32 %res
1397 declare void @llvm.lifetime.start.p0i8(i64, i8*)
1398 declare void @llvm.lifetime.end.p0i8(i64, i8*)
1399 define void @test_lifetime_intrin() {
1400 ; CHECK-LABEL: name: test_lifetime_intrin
1401 ; CHECK: RET_ReallyLR
1402 ; O3-LABEL: name: test_lifetime_intrin
1403 ; O3: {{%[0-9]+}}:_(p0) = G_FRAME_INDEX %stack.0.slot
1404 ; O3-NEXT: LIFETIME_START %stack.0.slot
1405 ; O3-NEXT: LIFETIME_END %stack.0.slot
1406 ; O3-NEXT: RET_ReallyLR
1407   %slot = alloca i8, i32 4
1408   call void @llvm.lifetime.start.p0i8(i64 0, i8* %slot)
1409   call void @llvm.lifetime.end.p0i8(i64 0, i8* %slot)
1410   ret void
1413 define void @test_load_store_atomics(i8* %addr) {
1414 ; CHECK-LABEL: name: test_load_store_atomics
1415 ; CHECK: [[ADDR:%[0-9]+]]:_(p0) = COPY $x0
1416 ; CHECK: [[V0:%[0-9]+]]:_(s8) = G_LOAD [[ADDR]](p0) :: (load unordered 1 from %ir.addr)
1417 ; CHECK: G_STORE [[V0]](s8), [[ADDR]](p0) :: (store monotonic 1 into %ir.addr)
1418 ; CHECK: [[V1:%[0-9]+]]:_(s8) = G_LOAD [[ADDR]](p0) :: (load acquire 1 from %ir.addr)
1419 ; CHECK: G_STORE [[V1]](s8), [[ADDR]](p0) :: (store release 1 into %ir.addr)
1420 ; CHECK: [[V2:%[0-9]+]]:_(s8) = G_LOAD [[ADDR]](p0) :: (load syncscope("singlethread") seq_cst 1 from %ir.addr)
1421 ; CHECK: G_STORE [[V2]](s8), [[ADDR]](p0) :: (store syncscope("singlethread") monotonic 1 into %ir.addr)
1422   %v0 = load atomic i8, i8* %addr unordered, align 1
1423   store atomic i8 %v0, i8* %addr monotonic, align 1
1425   %v1 = load atomic i8, i8* %addr acquire, align 1
1426   store atomic i8 %v1, i8* %addr release, align 1
1428   %v2 = load atomic i8, i8* %addr syncscope("singlethread") seq_cst, align 1
1429   store atomic i8 %v2, i8* %addr syncscope("singlethread") monotonic, align 1
1431   ret void
1434 define float @test_fneg_f32(float %x) {
1435 ; CHECK-LABEL: name: test_fneg_f32
1436 ; CHECK: [[ARG:%[0-9]+]]:_(s32) = COPY $s0
1437 ; CHECK: [[RES:%[0-9]+]]:_(s32) = G_FNEG [[ARG]]
1438 ; CHECK: $s0 = COPY [[RES]](s32)
1439   %neg = fsub float -0.000000e+00, %x
1440   ret float %neg
1443 define float @test_fneg_f32_fmf(float %x) {
1444 ; CHECK-LABEL: name: test_fneg_f32
1445 ; CHECK: [[ARG:%[0-9]+]]:_(s32) = COPY $s0
1446 ; CHECK: [[RES:%[0-9]+]]:_(s32) = nnan ninf nsz arcp contract afn reassoc G_FNEG [[ARG]]
1447 ; CHECK: $s0 = COPY [[RES]](s32)
1448   %neg = fsub fast float -0.000000e+00, %x
1449   ret float %neg
1452 define double @test_fneg_f64(double %x) {
1453 ; CHECK-LABEL: name: test_fneg_f64
1454 ; CHECK: [[ARG:%[0-9]+]]:_(s64) = COPY $d0
1455 ; CHECK: [[RES:%[0-9]+]]:_(s64) = G_FNEG [[ARG]]
1456 ; CHECK: $d0 = COPY [[RES]](s64)
1457   %neg = fsub double -0.000000e+00, %x
1458   ret double %neg
1461 define double @test_fneg_f64_fmf(double %x) {
1462 ; CHECK-LABEL: name: test_fneg_f64
1463 ; CHECK: [[ARG:%[0-9]+]]:_(s64) = COPY $d0
1464 ; CHECK: [[RES:%[0-9]+]]:_(s64) = nnan ninf nsz arcp contract afn reassoc G_FNEG [[ARG]]
1465 ; CHECK: $d0 = COPY [[RES]](s64)
1466   %neg = fsub fast double -0.000000e+00, %x
1467   ret double %neg
1470 define void @test_trivial_inlineasm() {
1471 ; CHECK-LABEL: name: test_trivial_inlineasm
1472 ; CHECK: INLINEASM &wibble, 1
1473 ; CHECK: INLINEASM &wibble, 0
1474   call void asm sideeffect "wibble", ""()
1475   call void asm "wibble", ""()
1476   ret void
1479 define <2 x i32> @test_insertelement(<2 x i32> %vec, i32 %elt, i32 %idx){
1480 ; CHECK-LABEL: name: test_insertelement
1481 ; CHECK: [[VEC:%[0-9]+]]:_(<2 x s32>) = COPY $d0
1482 ; CHECK: [[ELT:%[0-9]+]]:_(s32) = COPY $w0
1483 ; CHECK: [[IDX:%[0-9]+]]:_(s32) = COPY $w1
1484 ; CHECK: [[RES:%[0-9]+]]:_(<2 x s32>) = G_INSERT_VECTOR_ELT [[VEC]], [[ELT]](s32), [[IDX]](s32)
1485 ; CHECK: $d0 = COPY [[RES]](<2 x s32>)
1486   %res = insertelement <2 x i32> %vec, i32 %elt, i32 %idx
1487   ret <2 x i32> %res
1490 define i32 @test_extractelement(<2 x i32> %vec, i32 %idx) {
1491 ; CHECK-LABEL: name: test_extractelement
1492 ; CHECK: [[VEC:%[0-9]+]]:_(<2 x s32>) = COPY $d0
1493 ; CHECK: [[IDX:%[0-9]+]]:_(s32) = COPY $w0
1494 ; CHECK: [[IDXEXT:%[0-9]+]]:_(s64) = G_SEXT [[IDX]]
1495 ; CHECK: [[RES:%[0-9]+]]:_(s32) = G_EXTRACT_VECTOR_ELT [[VEC]](<2 x s32>), [[IDXEXT]](s64)
1496 ; CHECK: $w0 = COPY [[RES]](s32)
1497   %res = extractelement <2 x i32> %vec, i32 %idx
1498   ret i32 %res
1501 define i32 @test_extractelement_const_idx(<2 x i32> %vec) {
1502 ; CHECK-LABEL: name: test_extractelement
1503 ; CHECK: [[VEC:%[0-9]+]]:_(<2 x s32>) = COPY $d0
1504 ; CHECK: [[IDX:%[0-9]+]]:_(s64) = G_CONSTANT i64 1
1505 ; CHECK: [[RES:%[0-9]+]]:_(s32) = G_EXTRACT_VECTOR_ELT [[VEC]](<2 x s32>), [[IDX]](s64)
1506 ; CHECK: $w0 = COPY [[RES]](s32)
1507   %res = extractelement <2 x i32> %vec, i32 1
1508   ret i32 %res
1511 define i32 @test_singleelementvector(i32 %elt){
1512 ; CHECK-LABEL: name: test_singleelementvector
1513 ; CHECK: [[ELT:%[0-9]+]]:_(s32) = COPY $w0
1514 ; CHECK-NOT: G_INSERT_VECTOR_ELT
1515 ; CHECK-NOT: G_EXTRACT_VECTOR_ELT
1516 ; CHECK: $w0 = COPY [[ELT]](s32)
1517   %vec = insertelement <1 x i32> undef, i32 %elt, i32 0
1518   %res = extractelement <1 x i32> %vec, i32 0
1519   ret i32 %res
1522 define <2 x i32> @test_constantaggzerovector_v2i32() {
1523 ; CHECK-LABEL: name: test_constantaggzerovector_v2i32
1524 ; CHECK: [[ZERO:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
1525 ; CHECK: [[VEC:%[0-9]+]]:_(<2 x s32>) = G_BUILD_VECTOR [[ZERO]](s32), [[ZERO]](s32)
1526 ; CHECK: $d0 = COPY [[VEC]](<2 x s32>)
1527   ret <2 x i32> zeroinitializer
1530 define <2 x float> @test_constantaggzerovector_v2f32() {
1531 ; CHECK-LABEL: name: test_constantaggzerovector_v2f32
1532 ; CHECK: [[ZERO:%[0-9]+]]:_(s32) = G_FCONSTANT float 0.000000e+00
1533 ; CHECK: [[VEC:%[0-9]+]]:_(<2 x s32>) = G_BUILD_VECTOR [[ZERO]](s32), [[ZERO]](s32)
1534 ; CHECK: $d0 = COPY [[VEC]](<2 x s32>)
1535   ret <2 x float> zeroinitializer
1538 define i32 @test_constantaggzerovector_v3i32() {
1539 ; CHECK-LABEL: name: test_constantaggzerovector_v3i32
1540 ; CHECK: [[ZERO:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
1541 ; CHECK: [[VEC:%[0-9]+]]:_(<3 x s32>) = G_BUILD_VECTOR [[ZERO]](s32), [[ZERO]](s32), [[ZERO]](s32)
1542 ; CHECK: G_EXTRACT_VECTOR_ELT [[VEC]](<3 x s32>)
1543   %elt = extractelement <3 x i32> zeroinitializer, i32 1
1544   ret i32 %elt
1547 define <2 x i32> @test_constantdatavector_v2i32() {
1548 ; CHECK-LABEL: name: test_constantdatavector_v2i32
1549 ; CHECK: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
1550 ; CHECK: [[C2:%[0-9]+]]:_(s32) = G_CONSTANT i32 2
1551 ; CHECK: [[VEC:%[0-9]+]]:_(<2 x s32>) = G_BUILD_VECTOR [[C1]](s32), [[C2]](s32)
1552 ; CHECK: $d0 = COPY [[VEC]](<2 x s32>)
1553   ret <2 x i32> <i32 1, i32 2>
1556 define i32 @test_constantdatavector_v3i32() {
1557 ; CHECK-LABEL: name: test_constantdatavector_v3i32
1558 ; CHECK: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
1559 ; CHECK: [[C2:%[0-9]+]]:_(s32) = G_CONSTANT i32 2
1560 ; CHECK: [[C3:%[0-9]+]]:_(s32) = G_CONSTANT i32 3
1561 ; CHECK: [[VEC:%[0-9]+]]:_(<3 x s32>) = G_BUILD_VECTOR [[C1]](s32), [[C2]](s32), [[C3]](s32)
1562 ; CHECK: G_EXTRACT_VECTOR_ELT [[VEC]](<3 x s32>)
1563   %elt = extractelement <3 x i32> <i32 1, i32 2, i32 3>, i32 1
1564   ret i32 %elt
1567 define <4 x i32> @test_constantdatavector_v4i32() {
1568 ; CHECK-LABEL: name: test_constantdatavector_v4i32
1569 ; CHECK: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
1570 ; CHECK: [[C2:%[0-9]+]]:_(s32) = G_CONSTANT i32 2
1571 ; CHECK: [[C3:%[0-9]+]]:_(s32) = G_CONSTANT i32 3
1572 ; CHECK: [[C4:%[0-9]+]]:_(s32) = G_CONSTANT i32 4
1573 ; CHECK: [[VEC:%[0-9]+]]:_(<4 x s32>) = G_BUILD_VECTOR [[C1]](s32), [[C2]](s32), [[C3]](s32), [[C4]](s32)
1574 ; CHECK: $q0 = COPY [[VEC]](<4 x s32>)
1575   ret <4 x i32> <i32 1, i32 2, i32 3, i32 4>
1578 define <2 x double> @test_constantdatavector_v2f64() {
1579 ; CHECK-LABEL: name: test_constantdatavector_v2f64
1580 ; CHECK: [[FC1:%[0-9]+]]:_(s64) = G_FCONSTANT double 1.000000e+00
1581 ; CHECK: [[FC2:%[0-9]+]]:_(s64) = G_FCONSTANT double 2.000000e+00
1582 ; CHECK: [[VEC:%[0-9]+]]:_(<2 x s64>) = G_BUILD_VECTOR [[FC1]](s64), [[FC2]](s64)
1583 ; CHECK: $q0 = COPY [[VEC]](<2 x s64>)
1584   ret <2 x double> <double 1.0, double 2.0>
1587 define i32 @test_constantaggzerovector_v1s32(i32 %arg){
1588 ; CHECK-LABEL: name: test_constantaggzerovector_v1s32
1589 ; CHECK: [[ARG:%[0-9]+]]:_(s32) = COPY $w0
1590 ; CHECK: [[C0:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
1591 ; CHECK-NOT: G_MERGE_VALUES
1592 ; CHECK: G_ADD [[ARG]], [[C0]]
1593   %vec = insertelement <1 x i32> undef, i32 %arg, i32 0
1594   %add = add <1 x i32> %vec, zeroinitializer
1595   %res = extractelement <1 x i32> %add, i32 0
1596   ret i32 %res
1599 define i32 @test_constantdatavector_v1s32(i32 %arg){
1600 ; CHECK-LABEL: name: test_constantdatavector_v1s32
1601 ; CHECK: [[ARG:%[0-9]+]]:_(s32) = COPY $w0
1602 ; CHECK: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
1603 ; CHECK-NOT: G_MERGE_VALUES
1604 ; CHECK: G_ADD [[ARG]], [[C1]]
1605   %vec = insertelement <1 x i32> undef, i32 %arg, i32 0
1606   %add = add <1 x i32> %vec, <i32 1>
1607   %res = extractelement <1 x i32> %add, i32 0
1608   ret i32 %res
1611 declare ghccc float @different_call_conv_target(float %x)
1612 define float @test_different_call_conv_target(float %x) {
1613 ; CHECK-LABEL: name: test_different_call_conv
1614 ; CHECK: [[X:%[0-9]+]]:_(s32) = COPY $s0
1615 ; CHECK: $s8 = COPY [[X]]
1616 ; CHECK: BL @different_call_conv_target, csr_aarch64_aapcs, implicit-def $lr, implicit $sp, implicit $s8, implicit-def $s0
1617   %res = call ghccc float @different_call_conv_target(float %x)
1618   ret float %res
1621 define <2 x i32> @test_shufflevector_s32_v2s32(i32 %arg) {
1622 ; CHECK-LABEL: name: test_shufflevector_s32_v2s32
1623 ; CHECK: [[ARG:%[0-9]+]]:_(s32) = COPY $w0
1624 ; CHECK-DAG: [[UNDEF:%[0-9]+]]:_(s32) = G_IMPLICIT_DEF
1625 ; CHECK-DAG: [[C0:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
1626 ; CHECK-DAG: [[MASK:%[0-9]+]]:_(<2 x s32>) = G_BUILD_VECTOR [[C0]](s32), [[C0]](s32)
1627 ; CHECK: [[VEC:%[0-9]+]]:_(<2 x s32>) = G_SHUFFLE_VECTOR [[ARG]](s32), [[UNDEF]], [[MASK]](<2 x s32>)
1628 ; CHECK: $d0 = COPY [[VEC]](<2 x s32>)
1629   %vec = insertelement <1 x i32> undef, i32 %arg, i32 0
1630   %res = shufflevector <1 x i32> %vec, <1 x i32> undef, <2 x i32> zeroinitializer
1631   ret <2 x i32> %res
1634 define i32 @test_shufflevector_v2s32_s32(<2 x i32> %arg) {
1635 ; CHECK-LABEL: name: test_shufflevector_v2s32_s32
1636 ; CHECK: [[ARG:%[0-9]+]]:_(<2 x s32>) = COPY $d0
1637 ; CHECK-DAG: [[UNDEF:%[0-9]+]]:_(<2 x s32>) = G_IMPLICIT_DEF
1638 ; CHECK-DAG: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
1639 ; CHECK: [[RES:%[0-9]+]]:_(s32) = G_SHUFFLE_VECTOR [[ARG]](<2 x s32>), [[UNDEF]], [[C1]](s32)
1640 ; CHECK: $w0 = COPY [[RES]](s32)
1641   %vec = shufflevector <2 x i32> %arg, <2 x i32> undef, <1 x i32> <i32 1>
1642   %res = extractelement <1 x i32> %vec, i32 0
1643   ret i32 %res
1646 define <2 x i32> @test_shufflevector_v2s32_v2s32(<2 x i32> %arg) {
1647 ; CHECK-LABEL: name: test_shufflevector_v2s32_v2s32
1648 ; CHECK: [[ARG:%[0-9]+]]:_(<2 x s32>) = COPY $d0
1649 ; CHECK-DAG: [[UNDEF:%[0-9]+]]:_(<2 x s32>) = G_IMPLICIT_DEF
1650 ; CHECK-DAG: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
1651 ; CHECK-DAG: [[C0:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
1652 ; CHECK-DAG: [[MASK:%[0-9]+]]:_(<2 x s32>) = G_BUILD_VECTOR [[C1]](s32), [[C0]](s32)
1653 ; CHECK: [[VEC:%[0-9]+]]:_(<2 x s32>) = G_SHUFFLE_VECTOR [[ARG]](<2 x s32>), [[UNDEF]], [[MASK]](<2 x s32>)
1654 ; CHECK: $d0 = COPY [[VEC]](<2 x s32>)
1655   %res = shufflevector <2 x i32> %arg, <2 x i32> undef, <2 x i32> <i32 1, i32 0>
1656   ret <2 x i32> %res
1659 define i32 @test_shufflevector_v2s32_v3s32(<2 x i32> %arg) {
1660 ; CHECK-LABEL: name: test_shufflevector_v2s32_v3s32
1661 ; CHECK: [[ARG:%[0-9]+]]:_(<2 x s32>) = COPY $d0
1662 ; CHECK-DAG: [[UNDEF:%[0-9]+]]:_(<2 x s32>) = G_IMPLICIT_DEF
1663 ; CHECK-DAG: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
1664 ; CHECK-DAG: [[C0:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
1665 ; CHECK-DAG: [[MASK:%[0-9]+]]:_(<3 x s32>) = G_BUILD_VECTOR [[C1]](s32), [[C0]](s32), [[C1]](s32)
1666 ; CHECK: [[VEC:%[0-9]+]]:_(<3 x s32>) = G_SHUFFLE_VECTOR [[ARG]](<2 x s32>), [[UNDEF]], [[MASK]](<3 x s32>)
1667 ; CHECK: G_EXTRACT_VECTOR_ELT [[VEC]](<3 x s32>)
1668   %vec = shufflevector <2 x i32> %arg, <2 x i32> undef, <3 x i32> <i32 1, i32 0, i32 1>
1669   %res = extractelement <3 x i32> %vec, i32 0
1670   ret i32 %res
1673 define <4 x i32> @test_shufflevector_v2s32_v4s32(<2 x i32> %arg1, <2 x i32> %arg2) {
1674 ; CHECK-LABEL: name: test_shufflevector_v2s32_v4s32
1675 ; CHECK: [[ARG1:%[0-9]+]]:_(<2 x s32>) = COPY $d0
1676 ; CHECK: [[ARG2:%[0-9]+]]:_(<2 x s32>) = COPY $d1
1677 ; CHECK: [[C0:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
1678 ; CHECK: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
1679 ; CHECK: [[C2:%[0-9]+]]:_(s32) = G_CONSTANT i32 2
1680 ; CHECK: [[C3:%[0-9]+]]:_(s32) = G_CONSTANT i32 3
1681 ; CHECK: [[MASK:%[0-9]+]]:_(<4 x s32>) = G_BUILD_VECTOR [[C0]](s32), [[C1]](s32), [[C2]](s32), [[C3]](s32)
1682 ; CHECK: [[VEC:%[0-9]+]]:_(<4 x s32>) = G_SHUFFLE_VECTOR [[ARG1]](<2 x s32>), [[ARG2]], [[MASK]](<4 x s32>)
1683 ; CHECK: $q0 = COPY [[VEC]](<4 x s32>)
1684   %res = shufflevector <2 x i32> %arg1, <2 x i32> %arg2, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
1685   ret <4 x i32> %res
1688 define <2 x i32> @test_shufflevector_v4s32_v2s32(<4 x i32> %arg) {
1689 ; CHECK-LABEL: name: test_shufflevector_v4s32_v2s32
1690 ; CHECK: [[ARG:%[0-9]+]]:_(<4 x s32>) = COPY $q0
1691 ; CHECK-DAG: [[UNDEF:%[0-9]+]]:_(<4 x s32>) = G_IMPLICIT_DEF
1692 ; CHECK-DAG: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
1693 ; CHECK-DAG: [[C3:%[0-9]+]]:_(s32) = G_CONSTANT i32 3
1694 ; CHECK-DAG: [[MASK:%[0-9]+]]:_(<2 x s32>) = G_BUILD_VECTOR [[C1]](s32), [[C3]](s32)
1695 ; CHECK: [[VEC:%[0-9]+]]:_(<2 x s32>) = G_SHUFFLE_VECTOR [[ARG]](<4 x s32>), [[UNDEF]], [[MASK]](<2 x s32>)
1696 ; CHECK: $d0 = COPY [[VEC]](<2 x s32>)
1697   %res = shufflevector <4 x i32> %arg, <4 x i32> undef, <2 x i32> <i32 1, i32 3>
1698   ret <2 x i32> %res
1702 define <16 x i8> @test_shufflevector_v8s8_v16s8(<8 x i8> %arg1, <8 x i8> %arg2) {
1703 ; CHECK-LABEL: name: test_shufflevector_v8s8_v16s8
1704 ; CHECK: [[ARG1:%[0-9]+]]:_(<8 x s8>) = COPY $d0
1705 ; CHECK: [[ARG2:%[0-9]+]]:_(<8 x s8>) = COPY $d1
1706 ; CHECK: [[C0:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
1707 ; CHECK: [[C8:%[0-9]+]]:_(s32) = G_CONSTANT i32 8
1708 ; CHECK: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
1709 ; CHECK: [[C9:%[0-9]+]]:_(s32) = G_CONSTANT i32 9
1710 ; CHECK: [[C2:%[0-9]+]]:_(s32) = G_CONSTANT i32 2
1711 ; CHECK: [[C10:%[0-9]+]]:_(s32) = G_CONSTANT i32 10
1712 ; CHECK: [[C3:%[0-9]+]]:_(s32) = G_CONSTANT i32 3
1713 ; CHECK: [[C11:%[0-9]+]]:_(s32) = G_CONSTANT i32 11
1714 ; CHECK: [[C4:%[0-9]+]]:_(s32) = G_CONSTANT i32 4
1715 ; CHECK: [[C12:%[0-9]+]]:_(s32) = G_CONSTANT i32 12
1716 ; CHECK: [[C5:%[0-9]+]]:_(s32) = G_CONSTANT i32 5
1717 ; CHECK: [[C13:%[0-9]+]]:_(s32) = G_CONSTANT i32 13
1718 ; CHECK: [[C6:%[0-9]+]]:_(s32) = G_CONSTANT i32 6
1719 ; CHECK: [[C14:%[0-9]+]]:_(s32) = G_CONSTANT i32 14
1720 ; CHECK: [[C7:%[0-9]+]]:_(s32) = G_CONSTANT i32 7
1721 ; CHECK: [[C15:%[0-9]+]]:_(s32) = G_CONSTANT i32 15
1722 ; CHECK: [[MASK:%[0-9]+]]:_(<16 x s32>) = G_BUILD_VECTOR [[C0]](s32), [[C8]](s32), [[C1]](s32), [[C9]](s32), [[C2]](s32), [[C10]](s32), [[C3]](s32), [[C11]](s32), [[C4]](s32), [[C12]](s32), [[C5]](s32), [[C13]](s32), [[C6]](s32), [[C14]](s32), [[C7]](s32), [[C15]](s32)
1723 ; CHECK: [[VEC:%[0-9]+]]:_(<16 x s8>) = G_SHUFFLE_VECTOR [[ARG1]](<8 x s8>), [[ARG2]], [[MASK]](<16 x s32>)
1724 ; CHECK: $q0 = COPY [[VEC]](<16 x s8>)
1725   %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>
1726   ret <16 x i8> %res
1729 ; CHECK-LABEL: test_constant_vector
1730 ; CHECK: [[UNDEF:%[0-9]+]]:_(s16) = G_IMPLICIT_DEF
1731 ; CHECK: [[F:%[0-9]+]]:_(s16) = G_FCONSTANT half 0xH3C00
1732 ; CHECK: [[M:%[0-9]+]]:_(<4 x s16>) = G_BUILD_VECTOR [[UNDEF]](s16), [[UNDEF]](s16), [[UNDEF]](s16), [[F]](s16)
1733 ; CHECK: $d0 = COPY [[M]](<4 x s16>)
1734 define <4 x half> @test_constant_vector() {
1735   ret <4 x half> <half undef, half undef, half undef, half 0xH3C00>
1738 define i32 @test_target_mem_intrinsic(i32* %addr) {
1739 ; CHECK-LABEL: name: test_target_mem_intrinsic
1740 ; CHECK: [[ADDR:%[0-9]+]]:_(p0) = COPY $x0
1741 ; CHECK: [[VAL:%[0-9]+]]:_(s64) = G_INTRINSIC_W_SIDE_EFFECTS intrinsic(@llvm.aarch64.ldxr), [[ADDR]](p0) :: (volatile load 4 from %ir.addr)
1742 ; CHECK: G_TRUNC [[VAL]](s64)
1743   %val = call i64 @llvm.aarch64.ldxr.p0i32(i32* %addr)
1744   %trunc = trunc i64 %val to i32
1745   ret i32 %trunc
1748 declare i64 @llvm.aarch64.ldxr.p0i32(i32*) nounwind
1750 %zerosize_type = type {}
1752 define %zerosize_type @test_empty_load_store(%zerosize_type *%ptr, %zerosize_type %in) noinline optnone {
1753 ; CHECK-LABEL: name: test_empty_load_store
1754 ; CHECK-NOT: G_STORE
1755 ; CHECK-NOT: G_LOAD
1756 ; CHECK: RET_ReallyLR
1757 entry:
1758   store %zerosize_type undef, %zerosize_type* undef, align 4
1759   %val = load %zerosize_type, %zerosize_type* %ptr, align 4
1760   ret %zerosize_type %in
1764 define i64 @test_phi_loop(i32 %n) {
1765 ; CHECK-LABEL: name: test_phi_loop
1766 ; CHECK: [[ARG1:%[0-9]+]]:_(s32) = COPY $w0
1767 ; CHECK: [[CST1:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
1768 ; CHECK: [[CST2:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
1769 ; CHECK: [[CST3:%[0-9]+]]:_(s64) = G_CONSTANT i64 0
1770 ; CHECK: [[CST4:%[0-9]+]]:_(s64) = G_CONSTANT i64 1
1772 ; CHECK: [[PN1:%[0-9]+]]:_(s32) = G_PHI [[ARG1]](s32), %bb.1, [[SUB:%[0-9]+]](s32), %bb.2
1773 ; CHECK: [[PN2:%[0-9]+]]:_(s64) = G_PHI [[CST3]](s64), %bb.1, [[PN3:%[0-9]+]](s64), %bb.2
1774 ; CHECK: [[PN3]]:_(s64) = G_PHI [[CST4]](s64), %bb.1, [[ADD:%[0-9]+]](s64), %bb.2
1775 ; CHECK: [[ADD]]:_(s64) = G_ADD [[PN2]], [[PN3]]
1776 ; CHECK: [[SUB]]:_(s32) = G_SUB [[PN1]], [[CST1]]
1777 ; CHECK: [[CMP:%[0-9]+]]:_(s1) = G_ICMP intpred(sle), [[PN1]](s32), [[CST2]]
1778 ; CHECK: G_BRCOND [[CMP]](s1), %bb.3
1779 ; CHECK: G_BR %bb.2
1781 ; CHECK: $x0 = COPY [[PN2]](s64)
1782 ; CHECK: RET_ReallyLR implicit $x0
1783 entry:
1784   br label %loop
1786 loop:
1787   %counter = phi i32 [ %n, %entry ], [ %counter.dec, %loop ]
1788   %elem = phi { i64, i64 } [ { i64 0, i64 1 }, %entry ], [ %updated, %loop ]
1789   %prev = extractvalue { i64, i64 } %elem, 0
1790   %curr = extractvalue { i64, i64 } %elem, 1
1791   %next = add i64 %prev, %curr
1792   %shifted = insertvalue { i64, i64 } %elem, i64 %curr, 0
1793   %updated = insertvalue { i64, i64 } %shifted, i64 %next, 1
1794   %counter.dec = sub i32 %counter, 1
1795   %cond = icmp sle i32 %counter, 0
1796   br i1 %cond, label %exit, label %loop
1798 exit:
1799   %res = extractvalue { i64, i64 } %elem, 0
1800   ret i64 %res
1803 define void @test_phi_diamond({ i8, i16, i32 }* %a.ptr, { i8, i16, i32 }* %b.ptr, i1 %selector, { i8, i16, i32 }* %dst) {
1804 ; CHECK-LABEL: name: test_phi_diamond
1805 ; CHECK: [[ARG1:%[0-9]+]]:_(p0) = COPY $x0
1806 ; CHECK: [[ARG2:%[0-9]+]]:_(p0) = COPY $x1
1807 ; CHECK: [[ARG3:%[0-9]+]]:_(s32) = COPY $w2
1808 ; CHECK: [[TRUNC:%[0-9]+]]:_(s1) = G_TRUNC [[ARG3]](s32)
1809 ; CHECK: [[ARG4:%[0-9]+]]:_(p0) = COPY $x3
1810 ; CHECK: G_BRCOND [[TRUNC]](s1), %bb.2
1811 ; CHECK: G_BR %bb.3
1813 ; CHECK: [[LD1:%[0-9]+]]:_(s8) = G_LOAD [[ARG1]](p0) :: (load 1 from %ir.a.ptr, align 4)
1814 ; CHECK: [[CST1:%[0-9]+]]:_(s64) = G_CONSTANT i64 2
1815 ; CHECK: [[GEP1:%[0-9]+]]:_(p0) = G_GEP [[ARG1]], [[CST1]](s64)
1816 ; CHECK: [[LD2:%[0-9]+]]:_(s16) = G_LOAD [[GEP1]](p0) :: (load 2 from %ir.a.ptr + 2)
1817 ; CHECK: [[CST2:%[0-9]+]]:_(s64) = G_CONSTANT i64 4
1818 ; CHECK: [[GEP2:%[0-9]+]]:_(p0) = G_GEP [[ARG1]], [[CST2]](s64)
1819 ; CHECK: [[LD3:%[0-9]+]]:_(s32) = G_LOAD [[GEP2]](p0) :: (load 4 from %ir.a.ptr + 4)
1820 ; CHECK: G_BR %bb.4
1822 ; CHECK: [[LD4:%[0-9]+]]:_(s8) = G_LOAD [[ARG2]](p0) :: (load 1 from %ir.b.ptr, align 4)
1823 ; CHECK: [[CST3:%[0-9]+]]:_(s64) = G_CONSTANT i64 2
1824 ; CHECK: [[GEP3:%[0-9]+]]:_(p0) = G_GEP [[ARG2]], [[CST3]](s64)
1825 ; CHECK: [[LD5:%[0-9]+]]:_(s16) = G_LOAD [[GEP3]](p0) :: (load 2 from %ir.b.ptr + 2)
1826 ; CHECK: [[CST4:%[0-9]+]]:_(s64) = G_CONSTANT i64 4
1827 ; CHECK: [[GEP4:%[0-9]+]]:_(p0) = G_GEP [[ARG2]], [[CST4]](s64)
1828 ; CHECK: [[LD6:%[0-9]+]]:_(s32) = G_LOAD [[GEP4]](p0) :: (load 4 from %ir.b.ptr + 4)
1830 ; CHECK: [[PN1:%[0-9]+]]:_(s8) = G_PHI [[LD1]](s8), %bb.2, [[LD4]](s8), %bb.3
1831 ; CHECK: [[PN2:%[0-9]+]]:_(s16) = G_PHI [[LD2]](s16), %bb.2, [[LD5]](s16), %bb.3
1832 ; CHECK: [[PN3:%[0-9]+]]:_(s32) = G_PHI [[LD3]](s32), %bb.2, [[LD6]](s32), %bb.3
1833 ; CHECK: G_STORE [[PN1]](s8), [[ARG4]](p0) :: (store 1 into %ir.dst, align 4)
1834 ; CHECK: [[CST5:%[0-9]+]]:_(s64) = G_CONSTANT i64 2
1835 ; CHECK: [[GEP5:%[0-9]+]]:_(p0) = G_GEP [[ARG4]], [[CST5]](s64)
1836 ; CHECK: G_STORE [[PN2]](s16), [[GEP5]](p0) :: (store 2 into %ir.dst + 2)
1837 ; CHECK: [[CST6:%[0-9]+]]:_(s64) = G_CONSTANT i64 4
1838 ; CHECK: [[GEP6:%[0-9]+]]:_(p0) = G_GEP [[ARG4]], [[CST6]](s64)
1839 ; CHECK: G_STORE [[PN3]](s32), [[GEP6]](p0) :: (store 4 into %ir.dst + 4)
1840 ; CHECK: RET_ReallyLR
1842 entry:
1843   br i1 %selector, label %store.a, label %store.b
1845 store.a:
1846   %a = load { i8, i16, i32 }, { i8, i16, i32 }* %a.ptr
1847   br label %join
1849 store.b:
1850   %b = load { i8, i16, i32 }, { i8, i16, i32 }* %b.ptr
1851   br label %join
1853 join:
1854   %v = phi { i8, i16, i32 } [ %a, %store.a ], [ %b, %store.b ]
1855   store { i8, i16, i32 } %v, { i8, i16, i32 }* %dst
1856   ret void
1859 %agg.inner.inner = type {i64, i64}
1860 %agg.inner = type {i16, i8, %agg.inner.inner }
1861 %agg.nested = type {i32, i32, %agg.inner, i32}
1863 define void @test_nested_aggregate_const(%agg.nested *%ptr) {
1864 ; CHECK-LABEL: name: test_nested_aggregate_const
1865 ; CHECK: [[BASE:%[0-9]+]]:_(p0) = COPY $x0
1866 ; CHECK: [[CST1:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
1867 ; CHECK: [[CST2:%[0-9]+]]:_(s16) = G_CONSTANT i16 2
1868 ; CHECK: [[CST3:%[0-9]+]]:_(s8) = G_CONSTANT i8 3
1869 ; CHECK: [[CST4:%[0-9]+]]:_(s64) = G_CONSTANT i64 5
1870 ; CHECK: [[CST5:%[0-9]+]]:_(s64) = G_CONSTANT i64 8
1871 ; CHECK: [[CST6:%[0-9]+]]:_(s32) = G_CONSTANT i32 13
1872 ; CHECK: G_STORE [[CST1]](s32), [[BASE]](p0) :: (store 4 into %ir.ptr, align 8)
1873 ; CHECK: [[CST7:%[0-9]+]]:_(s64) = G_CONSTANT i64 4
1874 ; CHECK: [[GEP1:%[0-9]+]]:_(p0) = G_GEP [[BASE]], [[CST7]](s64)
1875 ; CHECK: G_STORE [[CST1]](s32), [[GEP1]](p0) :: (store 4 into %ir.ptr + 4)
1876 ; CHECK: [[CST8:%[0-9]+]]:_(s64) = G_CONSTANT i64 8
1877 ; CHECK: [[GEP2:%[0-9]+]]:_(p0) = G_GEP [[BASE]], [[CST8]](s64)
1878 ; CHECK: G_STORE [[CST2]](s16), [[GEP2]](p0) :: (store 2 into %ir.ptr + 8, align 8)
1879 ; CHECK: [[CST9:%[0-9]+]]:_(s64) = G_CONSTANT i64 10
1880 ; CHECK: [[GEP3:%[0-9]+]]:_(p0) = G_GEP [[BASE]], [[CST9]](s64)
1881 ; CHECK: G_STORE [[CST3]](s8), [[GEP3]](p0) :: (store 1 into %ir.ptr + 10, align 2)
1882 ; CHECK: [[CST10:%[0-9]+]]:_(s64) = G_CONSTANT i64 16
1883 ; CHECK: [[GEP4:%[0-9]+]]:_(p0) = G_GEP [[BASE]], [[CST10]](s64)
1884 ; CHECK: G_STORE [[CST4]](s64), [[GEP4]](p0) :: (store 8 into %ir.ptr + 16)
1885 ; CHECK: [[CST11:%[0-9]+]]:_(s64) = G_CONSTANT i64 24
1886 ; CHECK: [[GEP5:%[0-9]+]]:_(p0) = G_GEP [[BASE]], [[CST11]](s64)
1887 ; CHECK: G_STORE [[CST5]](s64), [[GEP5]](p0) :: (store 8 into %ir.ptr + 24)
1888 ; CHECK: [[CST12:%[0-9]+]]:_(s64) = G_CONSTANT i64 32
1889 ; CHECK: [[GEP6:%[0-9]+]]:_(p0) = G_GEP [[BASE]], [[CST12]](s64)
1890 ; CHECK: G_STORE [[CST6]](s32), [[GEP6]](p0) :: (store 4 into %ir.ptr + 32, align 8)
1891   store %agg.nested { i32 1, i32 1, %agg.inner { i16 2, i8 3, %agg.inner.inner {i64 5, i64 8} }, i32 13}, %agg.nested *%ptr
1892   ret void
1895 define i1 @return_i1_zext() {
1896 ; AAPCS ABI says that booleans can only be 1 or 0, so we need to zero-extend.
1897 ; CHECK-LABEL: name: return_i1_zext
1898 ; CHECK: [[CST:%[0-9]+]]:_(s1) = G_CONSTANT i1 true
1899 ; CHECK: [[ZEXT:%[0-9]+]]:_(s8) = G_ZEXT [[CST]](s1)
1900 ; CHECK: [[ANYEXT:%[0-9]+]]:_(s32) = G_ANYEXT [[ZEXT]](s8)
1901 ; CHECK: $w0 = COPY [[ANYEXT]](s32)
1902 ; CHECK: RET_ReallyLR implicit $w0
1903   ret i1 true
1906 ; Try one cmpxchg
1907 define i32 @test_atomic_cmpxchg_1(i32* %addr) {
1908 ; CHECK-LABEL: name: test_atomic_cmpxchg_1
1909 ; CHECK:       bb.1.entry:
1910 ; CHECK-NEXT:  successors: %bb.{{[^)]+}}
1911 ; CHECK-NEXT:  liveins: $x0
1912 ; CHECK:         [[ADDR:%[0-9]+]]:_(p0) = COPY $x0
1913 ; CHECK-NEXT:    [[OLDVAL:%[0-9]+]]:_(s32) = G_CONSTANT i32 0
1914 ; CHECK-NEXT:    [[NEWVAL:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
1915 ; CHECK:       bb.2.repeat:
1916 ; CHECK-NEXT:    successors: %bb.3({{[^)]+}}), %bb.2({{[^)]+}})
1917 ; CHECK:         [[OLDVALRES:%[0-9]+]]:_(s32), [[SUCCESS:%[0-9]+]]:_(s1) = G_ATOMIC_CMPXCHG_WITH_SUCCESS [[ADDR]](p0), [[OLDVAL]], [[NEWVAL]] :: (load store monotonic monotonic 4 on %ir.addr)
1918 ; CHECK-NEXT:    G_BRCOND [[SUCCESS]](s1), %bb.3
1919 ; CHECK-NEXT:    G_BR %bb.2
1920 ; CHECK:       bb.3.done:
1921 entry:
1922   br label %repeat
1923 repeat:
1924   %val_success = cmpxchg i32* %addr, i32 0, i32 1 monotonic monotonic
1925   %value_loaded = extractvalue { i32, i1 } %val_success, 0
1926   %success = extractvalue { i32, i1 } %val_success, 1
1927   br i1 %success, label %done, label %repeat
1928 done:
1929   ret i32 %value_loaded
1932 ; Try one cmpxchg with a small type and high atomic ordering.
1933 define i16 @test_atomic_cmpxchg_2(i16* %addr) {
1934 ; CHECK-LABEL: name: test_atomic_cmpxchg_2
1935 ; CHECK:       bb.1.entry:
1936 ; CHECK-NEXT:  successors: %bb.2({{[^)]+}})
1937 ; CHECK-NEXT:  liveins: $x0
1938 ; CHECK:         [[ADDR:%[0-9]+]]:_(p0) = COPY $x0
1939 ; CHECK-NEXT:    [[OLDVAL:%[0-9]+]]:_(s16) = G_CONSTANT i16 0
1940 ; CHECK-NEXT:    [[NEWVAL:%[0-9]+]]:_(s16) = G_CONSTANT i16 1
1941 ; CHECK:       bb.2.repeat:
1942 ; CHECK-NEXT:    successors: %bb.3({{[^)]+}}), %bb.2({{[^)]+}})
1943 ; CHECK:         [[OLDVALRES:%[0-9]+]]:_(s16), [[SUCCESS:%[0-9]+]]:_(s1) = G_ATOMIC_CMPXCHG_WITH_SUCCESS [[ADDR]](p0), [[OLDVAL]], [[NEWVAL]] :: (load store seq_cst seq_cst 2 on %ir.addr)
1944 ; CHECK-NEXT:    G_BRCOND [[SUCCESS]](s1), %bb.3
1945 ; CHECK-NEXT:    G_BR %bb.2
1946 ; CHECK:       bb.3.done:
1947 entry:
1948   br label %repeat
1949 repeat:
1950   %val_success = cmpxchg i16* %addr, i16 0, i16 1 seq_cst seq_cst
1951   %value_loaded = extractvalue { i16, i1 } %val_success, 0
1952   %success = extractvalue { i16, i1 } %val_success, 1
1953   br i1 %success, label %done, label %repeat
1954 done:
1955   ret i16 %value_loaded
1958 ; Try one cmpxchg where the success order and failure order differ.
1959 define i64 @test_atomic_cmpxchg_3(i64* %addr) {
1960 ; CHECK-LABEL: name: test_atomic_cmpxchg_3
1961 ; CHECK:       bb.1.entry:
1962 ; CHECK-NEXT:  successors: %bb.2({{[^)]+}})
1963 ; CHECK-NEXT:  liveins: $x0
1964 ; CHECK:         [[ADDR:%[0-9]+]]:_(p0) = COPY $x0
1965 ; CHECK-NEXT:    [[OLDVAL:%[0-9]+]]:_(s64) = G_CONSTANT i64 0
1966 ; CHECK-NEXT:    [[NEWVAL:%[0-9]+]]:_(s64) = G_CONSTANT i64 1
1967 ; CHECK:       bb.2.repeat:
1968 ; CHECK-NEXT:    successors: %bb.3({{[^)]+}}), %bb.2({{[^)]+}})
1969 ; CHECK:         [[OLDVALRES:%[0-9]+]]:_(s64), [[SUCCESS:%[0-9]+]]:_(s1) = G_ATOMIC_CMPXCHG_WITH_SUCCESS [[ADDR]](p0), [[OLDVAL]], [[NEWVAL]] :: (load store seq_cst acquire 8 on %ir.addr)
1970 ; CHECK-NEXT:    G_BRCOND [[SUCCESS]](s1), %bb.3
1971 ; CHECK-NEXT:    G_BR %bb.2
1972 ; CHECK:       bb.3.done:
1973 entry:
1974   br label %repeat
1975 repeat:
1976   %val_success = cmpxchg i64* %addr, i64 0, i64 1 seq_cst acquire
1977   %value_loaded = extractvalue { i64, i1 } %val_success, 0
1978   %success = extractvalue { i64, i1 } %val_success, 1
1979   br i1 %success, label %done, label %repeat
1980 done:
1981   ret i64 %value_loaded
1984 ; Try a monotonic atomicrmw xchg
1985 ; AArch64 will expand some atomicrmw's at the LLVM-IR level so we use a wide type to avoid this.
1986 define i32 @test_atomicrmw_xchg(i256* %addr) {
1987 ; CHECK-LABEL: name: test_atomicrmw_xchg
1988 ; CHECK:       bb.1 (%ir-block.{{[0-9]+}}):
1989 ; CHECK-NEXT:  liveins: $x0
1990 ; CHECK:         [[ADDR:%[0-9]+]]:_(p0) = COPY $x0
1991 ; CHECK-NEXT:    [[VAL:%[0-9]+]]:_(s256) = G_CONSTANT i256 1
1992 ; CHECK-NEXT:    [[OLDVALRES:%[0-9]+]]:_(s256) = G_ATOMICRMW_XCHG [[ADDR]](p0), [[VAL]] :: (load store monotonic 32 on %ir.addr)
1993 ; CHECK-NEXT:    [[RES:%[0-9]+]]:_(s32) = G_TRUNC [[OLDVALRES]]
1994   %oldval = atomicrmw xchg i256* %addr, i256 1 monotonic
1995   ; FIXME: We currently can't lower 'ret i256' and it's not the purpose of this
1996   ;        test so work around it by truncating to i32 for now.
1997   %oldval.trunc = trunc i256 %oldval to i32
1998   ret i32 %oldval.trunc
2001 ; Try an acquire atomicrmw add
2002 ; AArch64 will expand some atomicrmw's at the LLVM-IR level so we use a wide type to avoid this.
2003 define i32 @test_atomicrmw_add(i256* %addr) {
2004 ; CHECK-LABEL: name: test_atomicrmw_add
2005 ; CHECK:       bb.1 (%ir-block.{{[0-9]+}}):
2006 ; CHECK-NEXT:  liveins: $x0
2007 ; CHECK:         [[ADDR:%[0-9]+]]:_(p0) = COPY $x0
2008 ; CHECK-NEXT:    [[VAL:%[0-9]+]]:_(s256) = G_CONSTANT i256 1
2009 ; CHECK-NEXT:    [[OLDVALRES:%[0-9]+]]:_(s256) = G_ATOMICRMW_ADD [[ADDR]](p0), [[VAL]] :: (load store acquire 32 on %ir.addr)
2010 ; CHECK-NEXT:    [[RES:%[0-9]+]]:_(s32) = G_TRUNC [[OLDVALRES]]
2011   %oldval = atomicrmw add i256* %addr, i256 1 acquire
2012   ; FIXME: We currently can't lower 'ret i256' and it's not the purpose of this
2013   ;        test so work around it by truncating to i32 for now.
2014   %oldval.trunc = trunc i256 %oldval to i32
2015   ret i32 %oldval.trunc
2018 ; Try a release atomicrmw sub
2019 ; AArch64 will expand some atomicrmw's at the LLVM-IR level so we use a wide type to avoid this.
2020 define i32 @test_atomicrmw_sub(i256* %addr) {
2021 ; CHECK-LABEL: name: test_atomicrmw_sub
2022 ; CHECK:       bb.1 (%ir-block.{{[0-9]+}}):
2023 ; CHECK-NEXT:  liveins: $x0
2024 ; CHECK:         [[ADDR:%[0-9]+]]:_(p0) = COPY $x0
2025 ; CHECK-NEXT:    [[VAL:%[0-9]+]]:_(s256) = G_CONSTANT i256 1
2026 ; CHECK-NEXT:    [[OLDVALRES:%[0-9]+]]:_(s256) = G_ATOMICRMW_SUB [[ADDR]](p0), [[VAL]] :: (load store release 32 on %ir.addr)
2027 ; CHECK-NEXT:    [[RES:%[0-9]+]]:_(s32) = G_TRUNC [[OLDVALRES]]
2028   %oldval = atomicrmw sub i256* %addr, i256 1 release
2029   ; FIXME: We currently can't lower 'ret i256' and it's not the purpose of this
2030   ;        test so work around it by truncating to i32 for now.
2031   %oldval.trunc = trunc i256 %oldval to i32
2032   ret i32 %oldval.trunc
2035 ; Try an acq_rel atomicrmw and
2036 ; AArch64 will expand some atomicrmw's at the LLVM-IR level so we use a wide type to avoid this.
2037 define i32 @test_atomicrmw_and(i256* %addr) {
2038 ; CHECK-LABEL: name: test_atomicrmw_and
2039 ; CHECK:       bb.1 (%ir-block.{{[0-9]+}}):
2040 ; CHECK-NEXT:  liveins: $x0
2041 ; CHECK:         [[ADDR:%[0-9]+]]:_(p0) = COPY $x0
2042 ; CHECK-NEXT:    [[VAL:%[0-9]+]]:_(s256) = G_CONSTANT i256 1
2043 ; CHECK-NEXT:    [[OLDVALRES:%[0-9]+]]:_(s256) = G_ATOMICRMW_AND [[ADDR]](p0), [[VAL]] :: (load store acq_rel 32 on %ir.addr)
2044 ; CHECK-NEXT:    [[RES:%[0-9]+]]:_(s32) = G_TRUNC [[OLDVALRES]]
2045   %oldval = atomicrmw and i256* %addr, i256 1 acq_rel
2046   ; FIXME: We currently can't lower 'ret i256' and it's not the purpose of this
2047   ;        test so work around it by truncating to i32 for now.
2048   %oldval.trunc = trunc i256 %oldval to i32
2049   ret i32 %oldval.trunc
2052 ; Try an seq_cst atomicrmw nand
2053 ; AArch64 will expand some atomicrmw's at the LLVM-IR level so we use a wide type to avoid this.
2054 define i32 @test_atomicrmw_nand(i256* %addr) {
2055 ; CHECK-LABEL: name: test_atomicrmw_nand
2056 ; CHECK:       bb.1 (%ir-block.{{[0-9]+}}):
2057 ; CHECK-NEXT:  liveins: $x0
2058 ; CHECK:         [[ADDR:%[0-9]+]]:_(p0) = COPY $x0
2059 ; CHECK-NEXT:    [[VAL:%[0-9]+]]:_(s256) = G_CONSTANT i256 1
2060 ; CHECK-NEXT:    [[OLDVALRES:%[0-9]+]]:_(s256) = G_ATOMICRMW_NAND [[ADDR]](p0), [[VAL]] :: (load store seq_cst 32 on %ir.addr)
2061 ; CHECK-NEXT:    [[RES:%[0-9]+]]:_(s32) = G_TRUNC [[OLDVALRES]]
2062   %oldval = atomicrmw nand i256* %addr, i256 1 seq_cst
2063   ; FIXME: We currently can't lower 'ret i256' and it's not the purpose of this
2064   ;        test so work around it by truncating to i32 for now.
2065   %oldval.trunc = trunc i256 %oldval to i32
2066   ret i32 %oldval.trunc
2069 ; Try an seq_cst atomicrmw or
2070 ; AArch64 will expand some atomicrmw's at the LLVM-IR level so we use a wide type to avoid this.
2071 define i32 @test_atomicrmw_or(i256* %addr) {
2072 ; CHECK-LABEL: name: test_atomicrmw_or
2073 ; CHECK:       bb.1 (%ir-block.{{[0-9]+}}):
2074 ; CHECK-NEXT:  liveins: $x0
2075 ; CHECK:         [[ADDR:%[0-9]+]]:_(p0) = COPY $x0
2076 ; CHECK-NEXT:    [[VAL:%[0-9]+]]:_(s256) = G_CONSTANT i256 1
2077 ; CHECK-NEXT:    [[OLDVALRES:%[0-9]+]]:_(s256) = G_ATOMICRMW_OR [[ADDR]](p0), [[VAL]] :: (load store seq_cst 32 on %ir.addr)
2078 ; CHECK-NEXT:    [[RES:%[0-9]+]]:_(s32) = G_TRUNC [[OLDVALRES]]
2079   %oldval = atomicrmw or i256* %addr, i256 1 seq_cst
2080   ; FIXME: We currently can't lower 'ret i256' and it's not the purpose of this
2081   ;        test so work around it by truncating to i32 for now.
2082   %oldval.trunc = trunc i256 %oldval to i32
2083   ret i32 %oldval.trunc
2086 ; Try an seq_cst atomicrmw xor
2087 ; AArch64 will expand some atomicrmw's at the LLVM-IR level so we use a wide type to avoid this.
2088 define i32 @test_atomicrmw_xor(i256* %addr) {
2089 ; CHECK-LABEL: name: test_atomicrmw_xor
2090 ; CHECK:       bb.1 (%ir-block.{{[0-9]+}}):
2091 ; CHECK-NEXT:  liveins: $x0
2092 ; CHECK:         [[ADDR:%[0-9]+]]:_(p0) = COPY $x0
2093 ; CHECK-NEXT:    [[VAL:%[0-9]+]]:_(s256) = G_CONSTANT i256 1
2094 ; CHECK-NEXT:    [[OLDVALRES:%[0-9]+]]:_(s256) = G_ATOMICRMW_XOR [[ADDR]](p0), [[VAL]] :: (load store seq_cst 32 on %ir.addr)
2095 ; CHECK-NEXT:    [[RES:%[0-9]+]]:_(s32) = G_TRUNC [[OLDVALRES]]
2096   %oldval = atomicrmw xor i256* %addr, i256 1 seq_cst
2097   ; FIXME: We currently can't lower 'ret i256' and it's not the purpose of this
2098   ;        test so work around it by truncating to i32 for now.
2099   %oldval.trunc = trunc i256 %oldval to i32
2100   ret i32 %oldval.trunc
2103 ; Try an seq_cst atomicrmw min
2104 ; AArch64 will expand some atomicrmw's at the LLVM-IR level so we use a wide type to avoid this.
2105 define i32 @test_atomicrmw_min(i256* %addr) {
2106 ; CHECK-LABEL: name: test_atomicrmw_min
2107 ; CHECK:       bb.1 (%ir-block.{{[0-9]+}}):
2108 ; CHECK-NEXT:  liveins: $x0
2109 ; CHECK:         [[ADDR:%[0-9]+]]:_(p0) = COPY $x0
2110 ; CHECK-NEXT:    [[VAL:%[0-9]+]]:_(s256) = G_CONSTANT i256 1
2111 ; CHECK-NEXT:    [[OLDVALRES:%[0-9]+]]:_(s256) = G_ATOMICRMW_MIN [[ADDR]](p0), [[VAL]] :: (load store seq_cst 32 on %ir.addr)
2112 ; CHECK-NEXT:    [[RES:%[0-9]+]]:_(s32) = G_TRUNC [[OLDVALRES]]
2113   %oldval = atomicrmw min i256* %addr, i256 1 seq_cst
2114   ; FIXME: We currently can't lower 'ret i256' and it's not the purpose of this
2115   ;        test so work around it by truncating to i32 for now.
2116   %oldval.trunc = trunc i256 %oldval to i32
2117   ret i32 %oldval.trunc
2120 ; Try an seq_cst atomicrmw max
2121 ; AArch64 will expand some atomicrmw's at the LLVM-IR level so we use a wide type to avoid this.
2122 define i32 @test_atomicrmw_max(i256* %addr) {
2123 ; CHECK-LABEL: name: test_atomicrmw_max
2124 ; CHECK:       bb.1 (%ir-block.{{[0-9]+}}):
2125 ; CHECK-NEXT:  liveins: $x0
2126 ; CHECK:         [[ADDR:%[0-9]+]]:_(p0) = COPY $x0
2127 ; CHECK-NEXT:    [[VAL:%[0-9]+]]:_(s256) = G_CONSTANT i256 1
2128 ; CHECK-NEXT:    [[OLDVALRES:%[0-9]+]]:_(s256) = G_ATOMICRMW_MAX [[ADDR]](p0), [[VAL]] :: (load store seq_cst 32 on %ir.addr)
2129 ; CHECK-NEXT:    [[RES:%[0-9]+]]:_(s32) = G_TRUNC [[OLDVALRES]]
2130   %oldval = atomicrmw max i256* %addr, i256 1 seq_cst
2131   ; FIXME: We currently can't lower 'ret i256' and it's not the purpose of this
2132   ;        test so work around it by truncating to i32 for now.
2133   %oldval.trunc = trunc i256 %oldval to i32
2134   ret i32 %oldval.trunc
2137 ; Try an seq_cst atomicrmw unsigned min
2138 ; AArch64 will expand some atomicrmw's at the LLVM-IR level so we use a wide type to avoid this.
2139 define i32 @test_atomicrmw_umin(i256* %addr) {
2140 ; CHECK-LABEL: name: test_atomicrmw_umin
2141 ; CHECK:       bb.1 (%ir-block.{{[0-9]+}}):
2142 ; CHECK-NEXT:  liveins: $x0
2143 ; CHECK:         [[ADDR:%[0-9]+]]:_(p0) = COPY $x0
2144 ; CHECK-NEXT:    [[VAL:%[0-9]+]]:_(s256) = G_CONSTANT i256 1
2145 ; CHECK-NEXT:    [[OLDVALRES:%[0-9]+]]:_(s256) = G_ATOMICRMW_UMIN [[ADDR]](p0), [[VAL]] :: (load store seq_cst 32 on %ir.addr)
2146 ; CHECK-NEXT:    [[RES:%[0-9]+]]:_(s32) = G_TRUNC [[OLDVALRES]]
2147   %oldval = atomicrmw umin i256* %addr, i256 1 seq_cst
2148   ; FIXME: We currently can't lower 'ret i256' and it's not the purpose of this
2149   ;        test so work around it by truncating to i32 for now.
2150   %oldval.trunc = trunc i256 %oldval to i32
2151   ret i32 %oldval.trunc
2154 ; Try an seq_cst atomicrmw unsigned max
2155 ; AArch64 will expand some atomicrmw's at the LLVM-IR level so we use a wide type to avoid this.
2156 define i32 @test_atomicrmw_umax(i256* %addr) {
2157 ; CHECK-LABEL: name: test_atomicrmw_umax
2158 ; CHECK:       bb.1 (%ir-block.{{[0-9]+}}):
2159 ; CHECK-NEXT:  liveins: $x0
2160 ; CHECK:         [[ADDR:%[0-9]+]]:_(p0) = COPY $x0
2161 ; CHECK-NEXT:    [[VAL:%[0-9]+]]:_(s256) = G_CONSTANT i256 1
2162 ; CHECK-NEXT:    [[OLDVALRES:%[0-9]+]]:_(s256) = G_ATOMICRMW_UMAX [[ADDR]](p0), [[VAL]] :: (load store seq_cst 32 on %ir.addr)
2163 ; CHECK-NEXT:    [[RES:%[0-9]+]]:_(s32) = G_TRUNC [[OLDVALRES]]
2164   %oldval = atomicrmw umax i256* %addr, i256 1 seq_cst
2165   ; FIXME: We currently can't lower 'ret i256' and it's not the purpose of this
2166   ;        test so work around it by truncating to i32 for now.
2167   %oldval.trunc = trunc i256 %oldval to i32
2168   ret i32 %oldval.trunc
2171 @addr = global i8* null
2173 define void @test_blockaddress() {
2174 ; CHECK-LABEL: name: test_blockaddress
2175 ; CHECK: [[BADDR:%[0-9]+]]:_(p0) = G_BLOCK_ADDR blockaddress(@test_blockaddress, %ir-block.block)
2176 ; CHECK: G_STORE [[BADDR]](p0)
2177   store i8* blockaddress(@test_blockaddress, %block), i8** @addr
2178   indirectbr i8* blockaddress(@test_blockaddress, %block), [label %block]
2179 block:
2180   ret void
2183 %t = type { i32 }
2184 declare {}* @llvm.invariant.start.p0i8(i64, i8* nocapture) readonly nounwind
2185 declare void @llvm.invariant.end.p0i8({}*, i64, i8* nocapture) nounwind
2186 define void @test_invariant_intrin() {
2187 ; CHECK-LABEL: name: test_invariant_intrin
2188 ; CHECK: %{{[0-9]+}}:_(s64) = G_IMPLICIT_DEF
2189 ; CHECK-NEXT: RET_ReallyLR
2190   %x = alloca %t
2191   %y = bitcast %t* %x to i8*
2192   %inv = call {}* @llvm.invariant.start.p0i8(i64 8, i8* %y)
2193   call void @llvm.invariant.end.p0i8({}* %inv, i64 8, i8* %y)
2194   ret void
2197 declare float @llvm.ceil.f32(float)
2198 define float @test_ceil_f32(float %x) {
2199   ; CHECK-LABEL: name:            test_ceil_f32
2200   ; CHECK: %{{[0-9]+}}:_(s32) = G_FCEIL %{{[0-9]+}}
2201   %y = call float @llvm.ceil.f32(float %x)
2202   ret float %y
2205 declare double @llvm.ceil.f64(double)
2206 define double @test_ceil_f64(double %x) {
2207   ; CHECK-LABEL: name:            test_ceil_f64
2208   ; CHECK: %{{[0-9]+}}:_(s64) = G_FCEIL %{{[0-9]+}}
2209   %y = call double @llvm.ceil.f64(double %x)
2210   ret double %y
2213 declare <2 x float> @llvm.ceil.v2f32(<2 x float>)
2214 define <2 x float> @test_ceil_v2f32(<2 x float> %x) {
2215   ; CHECK-LABEL: name:            test_ceil_v2f32
2216   ; CHECK: %{{[0-9]+}}:_(<2 x s32>) = G_FCEIL %{{[0-9]+}}
2217   %y = call <2 x float> @llvm.ceil.v2f32(<2 x float> %x)
2218   ret <2 x float> %y
2221 declare <4 x float> @llvm.ceil.v4f32(<4 x float>)
2222 define <4 x float> @test_ceil_v4f32(<4 x float> %x) {
2223   ; CHECK-LABEL: name:            test_ceil_v4f32
2224   ; CHECK: %{{[0-9]+}}:_(<4 x s32>) = G_FCEIL %{{[0-9]+}}
2225   ; SELECT: %{{[0-9]+}}:fpr128 = FRINTPv4f32 %{{[0-9]+}}
2226   %y = call <4 x float> @llvm.ceil.v4f32(<4 x float> %x)
2227   ret <4 x float> %y
2230 declare <2 x double> @llvm.ceil.v2f64(<2 x double>)
2231 define <2 x double> @test_ceil_v2f64(<2 x double> %x) {
2232   ; CHECK-LABEL: name:            test_ceil_v2f64
2233   ; CHECK: %{{[0-9]+}}:_(<2 x s64>) = G_FCEIL %{{[0-9]+}}
2234   %y = call <2 x double> @llvm.ceil.v2f64(<2 x double> %x)
2235   ret <2 x double> %y
2238 declare float @llvm.cos.f32(float)
2239 define float @test_cos_f32(float %x) {
2240   ; CHECK-LABEL: name:            test_cos_f32
2241   ; CHECK: %{{[0-9]+}}:_(s32) = G_FCOS %{{[0-9]+}}
2242   %y = call float @llvm.cos.f32(float %x)
2243   ret float %y
2246 declare float @llvm.sin.f32(float)
2247 define float @test_sin_f32(float %x) {
2248   ; CHECK-LABEL: name:            test_sin_f32
2249   ; CHECK: %{{[0-9]+}}:_(s32) = G_FSIN %{{[0-9]+}}
2250   %y = call float @llvm.sin.f32(float %x)
2251   ret float %y
2254 declare float @llvm.sqrt.f32(float)
2255 define float @test_sqrt_f32(float %x) {
2256   ; CHECK-LABEL: name:            test_sqrt_f32
2257   ; CHECK: %{{[0-9]+}}:_(s32) = G_FSQRT %{{[0-9]+}}
2258   %y = call float @llvm.sqrt.f32(float %x)
2259   ret float %y
2262 declare float @llvm.floor.f32(float)
2263 define float @test_floor_f32(float %x) {
2264   ; CHECK-LABEL: name:            test_floor_f32
2265   ; CHECK: %{{[0-9]+}}:_(s32) = G_FFLOOR %{{[0-9]+}}
2266   %y = call float @llvm.floor.f32(float %x)
2267   ret float %y
2270 declare float @llvm.nearbyint.f32(float)
2271 define float @test_nearbyint_f32(float %x) {
2272   ; CHECK-LABEL: name:            test_nearbyint_f32
2273   ; CHECK: %{{[0-9]+}}:_(s32) = G_FNEARBYINT %{{[0-9]+}}
2274   %y = call float @llvm.nearbyint.f32(float %x)
2275   ret float %y
2278 ; CHECK-LABEL: name: test_llvm.aarch64.neon.ld3.v4i32.p0i32
2279 ; 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 48 from %ir.ptr, align 64)
2280 define void @test_llvm.aarch64.neon.ld3.v4i32.p0i32(i32* %ptr) {
2281   %arst = call { <4 x i32>, <4 x i32>, <4 x i32> } @llvm.aarch64.neon.ld3.v4i32.p0i32(i32* %ptr)
2282   ret void
2285 declare { <4 x i32>, <4 x i32>, <4 x i32> } @llvm.aarch64.neon.ld3.v4i32.p0i32(i32*) #3
2287 define void @test_i1_arg_zext(void (i1)* %f) {
2288 ; CHECK-LABEL: name: test_i1_arg_zext
2289 ; CHECK: [[I1:%[0-9]+]]:_(s1) = G_CONSTANT i1 true
2290 ; CHECK: [[ZEXT:%[0-9]+]]:_(s32) = G_ZEXT [[I1]](s1)
2291 ; CHECK: $w0 = COPY [[ZEXT]](s32)
2292   call void %f(i1 true)
2293   ret void
2296 declare i8* @llvm.stacksave()
2297 declare void @llvm.stackrestore(i8*)
2298 define void @test_stacksaverestore() {
2299   ; CHECK-LABEL: name: test_stacksaverestore
2300   ; CHECK: [[SAVE:%[0-9]+]]:_(p0) = COPY $sp
2301   ; CHECK-NEXT: $sp = COPY [[SAVE]](p0)
2302   ; CHECK-NEXT: RET_ReallyLR
2303   %sp = call i8* @llvm.stacksave()
2304   call void @llvm.stackrestore(i8* %sp)
2305   ret void
2308 declare float @llvm.rint.f32(float)
2309 define float @test_rint_f32(float %x) {
2310   ; CHECK-LABEL: name:            test_rint_f32
2311   ; CHECK: %{{[0-9]+}}:_(s32) = G_FRINT %{{[0-9]+}}
2312   %y = call float @llvm.rint.f32(float %x)
2313   ret float %y
2316 declare void @llvm.assume(i1)
2317 define void @test_assume(i1 %x) {
2318   ; CHECK-LABEL: name:            test_assume
2319   ; CHECK-NOT: llvm.assume
2320   ; CHECK: RET_ReallyLR
2321   call void @llvm.assume(i1 %x)
2322   ret void
2325 declare void @llvm.sideeffect()
2326 define void @test_sideeffect() {
2327   ; CHECK-LABEL: name:            test_sideeffect
2328   ; CHECK-NOT: llvm.sideeffect
2329   ; CHECK: RET_ReallyLR
2330   call void @llvm.sideeffect()
2331   ret void
2334 declare void @llvm.var.annotation(i8*, i8*, i8*, i32)
2335 define void @test_var_annotation(i8*, i8*, i8*, i32) {
2336   ; CHECK-LABEL: name:            test_var_annotation
2337   ; CHECK-NOT: llvm.var.annotation
2338   ; CHECK: RET_ReallyLR
2339   call void @llvm.var.annotation(i8* %0, i8* %1, i8* %2, i32 %3)
2340   ret void
2343 !0 = !{ i64 0, i64 2 }