1 # RUN: llc -O0 -run-pass=regbankselect %s -o - -verify-machineinstrs | FileCheck %s --check-prefix=CHECK --check-prefix=FAST
2 # RUN: llc -O0 -run-pass=regbankselect %s -regbankselect-greedy -o - -verify-machineinstrs | FileCheck %s --check-prefix=CHECK --check-prefix=GREEDY
5 ; ModuleID = 'generic-virtual-registers-type-error.mir'
6 target datalayout = "e-m:o-i64:64-i128:128-n32:64-S128"
7 target triple = "aarch64--"
8 define void @defaultMapping() {
12 define void @defaultMappingVector() {
16 define void @defaultMapping1Repair() {
20 define void @defaultMapping2Repairs() {
24 define void @defaultMappingDefRepair() {
28 define void @phiPropagation(i32* %src, i32* %dst, i1 %cond) {
30 %srcVal = load i32, i32* %src
31 br i1 %cond, label %end, label %then
33 %res = add i32 %srcVal, 36
36 %toStore = phi i32 [ %srcVal, %entry ], [ %res, %then ]
37 store i32 %toStore, i32* %dst
40 define void @defaultMappingUseRepairPhysReg() {
44 define void @defaultMappingDefRepairPhysReg() {
48 define void @greedyMappingOr() {
52 define void @greedyMappingOrWithConstraints() {
57 define void @ignoreTargetSpecificInst() { ret void }
59 define void @regBankSelected_property() { ret void }
61 define void @bitcast_s32_gpr() { ret void }
62 define void @bitcast_s32_fpr() { ret void }
63 define void @bitcast_s32_gpr_fpr() { ret void }
64 define void @bitcast_s32_fpr_gpr() { ret void }
65 define void @bitcast_s64_gpr() { ret void }
66 define void @bitcast_s64_fpr() { ret void }
67 define void @bitcast_s64_gpr_fpr() { ret void }
68 define void @bitcast_s64_fpr_gpr() { ret void }
69 define void @bitcast_s128() { ret void }
70 define void @copy_s128() { ret void }
71 define void @copy_s128_from_load() { ret void }
72 define void @copy_fp16() { ret void }
74 define i64 @greedyWithChainOfComputation(i64 %arg1, <2 x i32>* %addr) {
75 %varg1 = bitcast i64 %arg1 to <2 x i32>
76 %varg2 = load <2 x i32>, <2 x i32>* %addr
77 %vres = or <2 x i32> %varg1, %varg2
78 %res = bitcast <2 x i32> %vres to i64
82 define i64 @floatingPointLoad(i64 %arg1, double* %addr) {
83 %varg1 = bitcast i64 %arg1 to double
84 %varg2 = load double, double* %addr
85 %vres = fadd double %varg1, %varg2
86 %res = bitcast double %vres to i64
90 define void @floatingPointStore(i64 %arg1, double* %addr) {
91 %varg1 = bitcast i64 %arg1 to double
92 %vres = fadd double %varg1, %varg1
93 store double %vres, double* %addr
97 define void @fp16Ext32() { ret void }
98 define void @fp16Ext64() { ret void }
99 define void @fp32Ext64() { ret void }
101 define half @passFp16(half %p) {
106 define half @passFp16ViaAllocas(half %p) {
108 %p.addr = alloca half, align 2
109 store half %p, half* %p.addr, align 2
110 %0 = load half, half* %p.addr, align 2
116 # Check that we assign a relevant register bank for %0.
117 # Based on the type i32, this should be gpr.
121 - { id: 0, class: _ }
122 - { id: 1, class: _ }
126 ; CHECK-LABEL: name: defaultMapping
127 ; CHECK: %1:gpr(s32) = G_ADD %0
129 %1(s32) = G_ADD %0, %0
133 # Check that we assign a relevant register bank for %0.
134 # Based on the type <2 x i32>, this should be fpr.
135 # FPR is used for both floating point and vector registers.
136 name: defaultMappingVector
139 - { id: 0, class: _ }
140 - { id: 1, class: _ }
144 ; CHECK-LABEL: name: defaultMappingVector
145 ; CHECK: %0:fpr(<2 x s32>) = COPY $d0
146 ; CHECK: %1:fpr(<2 x s32>) = G_ADD %0
147 %0(<2 x s32>) = COPY $d0
148 %1(<2 x s32>) = G_ADD %0, %0
152 # Check that we repair the assignment for %0.
153 # Indeed based on the source of the copy it should live
154 # in FPR, but at the use, it should be GPR.
155 name: defaultMapping1Repair
158 - { id: 0, class: _ }
159 - { id: 1, class: _ }
160 - { id: 2, class: _ }
164 ; CHECK-LABEL: name: defaultMapping1Repair
165 ; CHECK: %0:fpr(s32) = COPY $s0
166 ; CHECK-NEXT: %1:gpr(s32) = COPY $w0
167 ; CHECK-NEXT: %3:gpr(s32) = COPY %0
168 ; CHECK-NEXT: %2:gpr(s32) = G_ADD %3, %1
171 %2(s32) = G_ADD %0, %1
174 # Check that we repair the assignment for %0 differently for both uses.
175 name: defaultMapping2Repairs
178 - { id: 0, class: _ }
179 - { id: 1, class: _ }
183 ; CHECK-LABEL: name: defaultMapping2Repairs
184 ; CHECK: %0:fpr(s32) = COPY $s0
185 ; CHECK-NEXT: %2:gpr(s32) = COPY %0
186 ; CHECK-NEXT: %3:gpr(s32) = COPY %0
187 ; CHECK-NEXT: %1:gpr(s32) = G_ADD %2, %3
189 %1(s32) = G_ADD %0, %0
193 # Check that we repair the definition of %1.
194 # %1 is forced to be into FPR, but its definition actually
195 # requires that it lives in GPR. Make sure regbankselect
197 name: defaultMappingDefRepair
200 - { id: 0, class: _ }
201 - { id: 1, class: fpr }
205 ; CHECK-LABEL: name: defaultMappingDefRepair
206 ; CHECK: %0:gpr(s32) = COPY $w0
207 ; CHECK-NEXT: %2:gpr(s32) = G_ADD %0, %0
208 ; CHECK-NEXT: %1:fpr(s32) = COPY %2
210 %1(s32) = G_ADD %0, %0
214 # Check that we are able to propagate register banks from phis.
217 tracksRegLiveness: true
219 # CHECK-NEXT: - { id: 0, class: gpr32, preferred-register: '' }
220 # CHECK-NEXT: - { id: 1, class: gpr64sp, preferred-register: '' }
221 # CHECK-NEXT: - { id: 2, class: gpr32, preferred-register: '' }
222 # CHECK-NEXT: - { id: 3, class: gpr, preferred-register: '' }
223 # CHECK-NEXT: - { id: 4, class: gpr, preferred-register: '' }
225 - { id: 0, class: gpr32 }
226 - { id: 1, class: gpr64sp }
227 - { id: 2, class: gpr32 }
228 - { id: 3, class: _ }
229 - { id: 4, class: _ }
230 - { id: 5, class: _ }
233 successors: %bb.2.end, %bb.1.then
234 liveins: $x0, $x1, $w2
236 %0 = LDRWui killed $x0, 0 :: (load 4 from %ir.src)
240 TBNZW killed %2, 0, %bb.2.end
243 successors: %bb.2.end
244 %3(s32) = G_ADD %5, %5
247 %4(s32) = PHI %0, %bb.0.entry, %3, %bb.1.then
248 G_STORE killed %4, killed %1 :: (store 4 into %ir.dst)
253 # Make sure we can repair physical register uses as well.
254 name: defaultMappingUseRepairPhysReg
257 - { id: 0, class: _ }
258 - { id: 1, class: _ }
259 - { id: 2, class: _ }
263 ; CHECK-LABEL: name: defaultMappingUseRepairPhysReg
264 ; CHECK: %0:gpr(s32) = COPY $w0
265 ; CHECK-NEXT: %1:fpr(s32) = COPY $s0
266 ; CHECK-NEXT: %3:gpr(s32) = COPY %1
267 ; CHECK-NEXT: %2:gpr(s32) = G_ADD %0, %3
270 %2(s32) = G_ADD %0, %1
274 # Make sure we can repair physical register defs.
275 name: defaultMappingDefRepairPhysReg
278 - { id: 0, class: _ }
279 - { id: 1, class: _ }
283 ; CHECK-LABEL: name: defaultMappingDefRepairPhysReg
284 ; CHECK: %0:gpr(s32) = COPY $w0
285 ; CHECK-NEXT: %1:gpr(s32) = G_ADD %0, %0
286 ; CHECK-NEXT: $s0 = COPY %1
288 %1(s32) = G_ADD %0, %0
293 # Check that the greedy mode is able to switch the
294 # G_OR instruction from fpr to gpr.
295 name: greedyMappingOr
298 - { id: 0, class: _ }
299 - { id: 1, class: _ }
300 - { id: 2, class: _ }
304 ; CHECK: %0:gpr(<2 x s32>) = COPY $x0
305 ; CHECK-NEXT: %1:gpr(<2 x s32>) = COPY $x1
307 ; Fast mode tries to reuse the source of the copy for the destination.
308 ; Now, the default mapping says that %0 and %1 need to be in FPR.
309 ; The repairing code insert two copies to materialize that.
310 ; FAST-NEXT: %3:fpr(<2 x s32>) = COPY %0
311 ; FAST-NEXT: %4:fpr(<2 x s32>) = COPY %1
312 ; The mapping of G_OR is on FPR.
313 ; FAST-NEXT: %2:fpr(<2 x s32>) = G_OR %3, %4
315 ; Greedy mode remapped the instruction on the GPR bank.
316 ; GREEDY-NEXT: %2:gpr(<2 x s32>) = G_OR %0, %1
317 %0(<2 x s32>) = COPY $x0
318 %1(<2 x s32>) = COPY $x1
319 %2(<2 x s32>) = G_OR %0, %1
323 # Check that the greedy mode is able to switch the
324 # G_OR instruction from fpr to gpr, while still honoring
326 name: greedyMappingOrWithConstraints
329 - { id: 0, class: _ }
330 - { id: 1, class: _ }
331 - { id: 2, class: fpr }
335 ; CHECK-LABEL: name: greedyMappingOrWithConstraints
337 ; CHECK: %0:gpr(<2 x s32>) = COPY $x0
338 ; CHECK-NEXT: %1:gpr(<2 x s32>) = COPY $x1
340 ; Fast mode tries to reuse the source of the copy for the destination.
341 ; Now, the default mapping says that %0 and %1 need to be in FPR.
342 ; The repairing code insert two copies to materialize that.
343 ; FAST-NEXT: %3:fpr(<2 x s32>) = COPY %0
344 ; FAST-NEXT: %4:fpr(<2 x s32>) = COPY %1
345 ; The mapping of G_OR is on FPR.
346 ; FAST-NEXT: %2:fpr(<2 x s32>) = G_OR %3, %4
348 ; Greedy mode remapped the instruction on the GPR bank.
349 ; GREEDY-NEXT: %3:gpr(<2 x s32>) = G_OR %0, %1
350 ; We need to keep %2 into FPR because we do not know anything about it.
351 ; GREEDY-NEXT: %2:fpr(<2 x s32>) = COPY %3
352 %0(<2 x s32>) = COPY $x0
353 %1(<2 x s32>) = COPY $x1
354 %2(<2 x s32>) = G_OR %0, %1
358 # CHECK-LABEL: name: ignoreTargetSpecificInst
359 name: ignoreTargetSpecificInst
362 # CHECK-NEXT: - { id: 0, class: gpr64, preferred-register: '' }
363 # CHECK-NEXT: - { id: 1, class: gpr64, preferred-register: '' }
365 - { id: 0, class: gpr64 }
366 - { id: 1, class: gpr64 }
371 ; CHECK: %0:gpr64 = COPY $x0
372 ; CHECK-NEXT: %1:gpr64 = ADDXrr %0, %0
373 ; CHECK-NEXT: $x0 = COPY %1
374 ; CHECK-NEXT: RET_ReallyLR implicit $x0
379 RET_ReallyLR implicit $x0
383 # Check that we set the "regBankSelected" property.
384 # CHECK-LABEL: name: regBankSelected_property
385 # CHECK: legalized: true
386 # CHECK: regBankSelected: true
387 name: regBankSelected_property
389 regBankSelected: false
395 # CHECK-LABEL: name: bitcast_s32_gpr
396 name: bitcast_s32_gpr
400 # CHECK-NEXT: - { id: 0, class: gpr, preferred-register: '' }
401 # CHECK-NEXT: - { id: 1, class: gpr, preferred-register: '' }
403 - { id: 0, class: _ }
404 - { id: 1, class: _ }
407 # CHECK: %0:gpr(s32) = COPY $w0
408 # CHECK: %1:gpr(s32) = G_BITCAST %0
414 %1(s32) = G_BITCAST %0
418 # CHECK-LABEL: name: bitcast_s32_fpr
419 name: bitcast_s32_fpr
423 # CHECK-NEXT: - { id: 0, class: fpr, preferred-register: '' }
424 # CHECK-NEXT: - { id: 1, class: fpr, preferred-register: '' }
426 - { id: 0, class: _ }
427 - { id: 1, class: _ }
430 # CHECK: %0:fpr(<2 x s16>) = COPY $s0
431 # CHECK: %1:fpr(<2 x s16>) = G_BITCAST %0
436 %0(<2 x s16>) = COPY $s0
437 %1(<2 x s16>) = G_BITCAST %0
441 # CHECK-LABEL: name: bitcast_s32_gpr_fpr
442 name: bitcast_s32_gpr_fpr
446 # CHECK-NEXT: - { id: 0, class: gpr, preferred-register: '' }
447 # FAST-NEXT: - { id: 1, class: fpr, preferred-register: '' }
448 # GREEDY-NEXT: - { id: 1, class: gpr, preferred-register: '' }
450 - { id: 0, class: _ }
451 - { id: 1, class: _ }
454 # CHECK: %0:gpr(s32) = COPY $w0
455 # FAST: %1:fpr(<2 x s16>) = G_BITCAST %0
456 # GREEDY: %1:gpr(<2 x s16>) = G_BITCAST %0
462 %1(<2 x s16>) = G_BITCAST %0
466 # CHECK-LABEL: name: bitcast_s32_fpr_gpr
467 name: bitcast_s32_fpr_gpr
470 - { id: 0, class: _ }
471 - { id: 1, class: _ }
473 # CHECK: %0:fpr(<2 x s16>) = COPY $s0
474 # FAST: %1:gpr(s32) = G_BITCAST %0
475 # GREEDY: %1:fpr(s32) = G_BITCAST %0
480 %0(<2 x s16>) = COPY $s0
481 %1(s32) = G_BITCAST %0
485 # CHECK-LABEL: name: bitcast_s64_gpr
486 name: bitcast_s64_gpr
489 - { id: 0, class: _ }
490 - { id: 1, class: _ }
492 # CHECK: %0:gpr(s64) = COPY $x0
493 # CHECK: %1:gpr(s64) = G_BITCAST %0
499 %1(s64) = G_BITCAST %0
503 # CHECK-LABEL: name: bitcast_s64_fpr
504 name: bitcast_s64_fpr
507 - { id: 0, class: _ }
508 - { id: 1, class: _ }
510 # CHECK: %0:fpr(<2 x s32>) = COPY $d0
511 # CHECK: %1:fpr(<2 x s32>) = G_BITCAST %0
516 %0(<2 x s32>) = COPY $d0
517 %1(<2 x s32>) = G_BITCAST %0
521 # CHECK-LABEL: name: bitcast_s64_gpr_fpr
522 name: bitcast_s64_gpr_fpr
525 - { id: 0, class: _ }
526 - { id: 1, class: _ }
528 # CHECK: %0:gpr(s64) = COPY $x0
529 # FAST: %1:fpr(<2 x s32>) = G_BITCAST %0
530 # GREEDY: %1:gpr(<2 x s32>) = G_BITCAST %0
536 %1(<2 x s32>) = G_BITCAST %0
540 # CHECK-LABEL: name: bitcast_s64_fpr_gpr
541 name: bitcast_s64_fpr_gpr
544 - { id: 0, class: _ }
545 - { id: 1, class: _ }
547 # CHECK: %0:fpr(<2 x s32>) = COPY $d0
548 # FAST: %1:gpr(s64) = G_BITCAST %0
549 # GREEDY: %1:fpr(s64) = G_BITCAST %0
554 %0(<2 x s32>) = COPY $d0
555 %1(s64) = G_BITCAST %0
559 # CHECK-LABEL: name: bitcast_s128
562 tracksRegLiveness: true
568 # CHECK: %3:fpr(s128) = G_MERGE_VALUES
569 # CHECK: %2:fpr(<2 x s64>) = G_BITCAST %3(s128)
575 %3(s128) = G_MERGE_VALUES %0(s64), %1(s64)
576 %2(<2 x s64>) = G_BITCAST %3(s128)
577 $q0 = COPY %2(<2 x s64>)
578 RET_ReallyLR implicit $q0
583 # CHECK-LABEL: name: copy_s128
584 # This test checks that we issue the proper mapping
585 # for copy of size > 64.
586 # The mapping should be the same as G_BITCAST.
589 tracksRegLiveness: true
596 # CHECK: %3:fpr(s128) = G_MERGE_VALUES
597 # CHECK: %4:fpr(s128) = COPY %3(s128)
598 # CHECK-NEXT: %2:fpr(<2 x s64>) = G_BITCAST %4(s128)
604 %3(s128) = G_MERGE_VALUES %0(s64), %1(s64)
605 %4(s128) = COPY %3(s128)
606 %2(<2 x s64>) = G_BITCAST %4(s128)
607 $q0 = COPY %2(<2 x s64>)
608 RET_ReallyLR implicit $q0
613 # CHECK-LABEL: name: copy_s128_from_load
614 # This test checks that we issue the proper mapping
615 # for copy of size > 64 when the input is neither
616 # a physcal register nor a generic register.
617 # This used to crash when we moved to the statically
618 # computed mapping, because we were assuming non-physregs
619 # were generic registers and thus have a type, whereas
620 # it is not necessarily the case.
621 name: copy_s128_from_load
623 tracksRegLiveness: true
625 - { id: 0, class: fpr128}
628 # CHECK: - { id: 0, class: fpr128, preferred-register: '' }
629 # CHECK: - { id: 1, class: fpr, preferred-register: '' }
630 # CHECK: %1:fpr(s128) = COPY %0
634 %0 = LDRQui killed $x0, 0
637 RET_ReallyLR implicit $q0
642 # CHECK-LABEL: name: copy_fp16
643 # This test checks that we issue the proper mapping
644 # for copy of size == 16 when the destination is a fpr
645 # physical register and the source a gpr.
646 # We used to crash because we thought that mapping couldn't
650 tracksRegLiveness: true
655 # CHECK: - { id: 0, class: gpr, preferred-register: '' }
656 # CHECK: - { id: 1, class: gpr, preferred-register: '' }
657 # CHECK: %0:gpr(s32) = COPY $w0
658 # CHECK-NEXT: %1:gpr(s16) = G_TRUNC %0(s32)
663 %1(s16) = G_TRUNC %0(s32)
665 RET_ReallyLR implicit $h0
671 # Make sure the greedy mode is able to take advantage of the
672 # alternative mappings of G_LOAD to coalesce the whole chain
673 # of computation on GPR.
674 # CHECK-LABEL: name: greedyWithChainOfComputation
675 name: greedyWithChainOfComputation
678 - { id: 0, class: _ }
679 - { id: 1, class: _ }
680 - { id: 2, class: _ }
681 - { id: 3, class: _ }
682 - { id: 4, class: _ }
683 - { id: 5, class: _ }
684 # No repairing should be necessary for both modes.
685 # CHECK: %0:gpr(s64) = COPY $x0
686 # CHECK-NEXT: %1:gpr(p0) = COPY $x1
687 # FAST-NEXT: %2:fpr(<2 x s32>) = G_BITCAST %0(s64)
688 # FAST-NEXT: %3:fpr(<2 x s32>) = G_LOAD %1(p0) :: (load 8 from %ir.addr)
689 # FAST-NEXT: %4:fpr(<2 x s32>) = G_OR %2, %3
690 # GREEDY-NEXT: %2:gpr(<2 x s32>) = G_BITCAST %0(s64)
691 # GREEDY-NEXT: %3:gpr(<2 x s32>) = G_LOAD %1(p0) :: (load 8 from %ir.addr)
692 # GREEDY-NEXT: %4:gpr(<2 x s32>) = G_OR %2, %3
693 # CHECK-NEXT: %5:gpr(s64) = G_BITCAST %4(<2 x s32>)
694 # CHECK-NEXT: $x0 = COPY %5(s64)
695 # CHECK-NEXT: RET_ReallyLR implicit $x0
702 %2(<2 x s32>) = G_BITCAST %0(s64)
703 %3(<2 x s32>) = G_LOAD %1(p0) :: (load 8 from %ir.addr)
704 %4(<2 x s32>) = G_OR %2, %3
705 %5(s64) = G_BITCAST %4(<2 x s32>)
707 RET_ReallyLR implicit $x0
712 # Make sure we map what looks like floating point
713 # loads to floating point register bank.
714 # CHECK-LABEL: name: floatingPointLoad
715 name: floatingPointLoad
719 # CHECK-NEXT: - { id: 0, class: gpr, preferred-register: '' }
720 # CHECK-NEXT: - { id: 1, class: gpr, preferred-register: '' }
721 # CHECK-NEXT: - { id: 2, class: fpr, preferred-register: '' }
722 # CHECK-NEXT: - { id: 3, class: fpr, preferred-register: '' }
723 # CHECK-NEXT: - { id: 4, class: fpr, preferred-register: '' }
725 - { id: 0, class: _ }
726 - { id: 1, class: _ }
727 - { id: 2, class: _ }
728 - { id: 3, class: _ }
730 # No repairing should be necessary for both modes.
731 # CHECK: %0:gpr(s64) = COPY $x0
732 # CHECK-NEXT: %1:gpr(p0) = COPY $x1
733 # CHECK-NEXT: %2:fpr(s64) = G_LOAD %1(p0) :: (load 8 from %ir.addr)
734 # %0 has been mapped to GPR, we need to repair to match FPR.
735 # CHECK-NEXT: %4:fpr(s64) = COPY %0
736 # CHECK-NEXT: %3:fpr(s64) = G_FADD %4, %2
737 # CHECK-NEXT: $x0 = COPY %3(s64)
738 # CHECK-NEXT: RET_ReallyLR implicit $x0
746 %2(s64) = G_LOAD %1(p0) :: (load 8 from %ir.addr)
747 %3(s64) = G_FADD %0, %2
749 RET_ReallyLR implicit $x0
754 # Make sure we map what looks like floating point
755 # stores to floating point register bank.
756 # CHECK-LABEL: name: floatingPointStore
757 name: floatingPointStore
761 # CHECK-NEXT: - { id: 0, class: gpr, preferred-register: '' }
762 # CHECK-NEXT: - { id: 1, class: gpr, preferred-register: '' }
763 # CHECK-NEXT: - { id: 2, class: fpr, preferred-register: '' }
764 # CHECK-NEXT: - { id: 3, class: fpr, preferred-register: '' }
765 # CHECK-NEXT: - { id: 4, class: fpr, preferred-register: '' }
767 - { id: 0, class: _ }
768 - { id: 1, class: _ }
769 - { id: 2, class: _ }
771 # CHECK: %0:gpr(s64) = COPY $x0
772 # CHECK-NEXT: %1:gpr(p0) = COPY $x1
773 # %0 has been mapped to GPR, we need to repair to match FPR.
774 # CHECK-NEXT: %3:fpr(s64) = COPY %0
775 # CHECK-NEXT: %4:fpr(s64) = COPY %0
776 # CHECK-NEXT: %2:fpr(s64) = G_FADD %3, %4
777 # CHECK-NEXT: G_STORE %2(s64), %1(p0) :: (store 8 into %ir.addr)
778 # CHECK-NEXT: RET_ReallyLR
786 %2(s64) = G_FADD %0, %0
787 G_STORE %2(s64), %1(p0) :: (store 8 into %ir.addr)
793 # Make sure we map FPEXT on FPR register bank.
794 # CHECK-LABEL: name: fp16Ext32
799 # CHECK-NEXT: - { id: 0, class: gpr, preferred-register: '' }
800 # CHECK-NEXT: - { id: 1, class: gpr, preferred-register: '' }
801 # CHECK-NEXT: - { id: 2, class: fpr, preferred-register: '' }
802 # CHECK-NEXT: - { id: 3, class: fpr, preferred-register: '' }
804 - { id: 0, class: _ }
805 - { id: 1, class: _ }
806 - { id: 2, class: _ }
807 # CHECK: %1:gpr(s32) = COPY $w0
808 # CHECK-NEXT: %0:gpr(s16) = G_TRUNC %1
809 # %0 has been mapped to GPR, we need to repair to match FPR.
810 # CHECK-NEXT: %3:fpr(s16) = COPY %0
811 # CHECK-NEXT: %2:fpr(s32) = G_FPEXT %3
812 # CHECK-NEXT: $s0 = COPY %2
813 # CHECK-NEXT: RET_ReallyLR
820 %0(s16) = G_TRUNC %1(s32)
821 %2(s32) = G_FPEXT %0(s16)
823 RET_ReallyLR implicit $s0
828 # Make sure we map FPEXT on FPR register bank.
829 # CHECK-LABEL: name: fp16Ext64
834 # CHECK-NEXT: - { id: 0, class: gpr, preferred-register: '' }
835 # CHECK-NEXT: - { id: 1, class: gpr, preferred-register: '' }
836 # CHECK-NEXT: - { id: 2, class: fpr, preferred-register: '' }
837 # CHECK-NEXT: - { id: 3, class: fpr, preferred-register: '' }
839 - { id: 0, class: _ }
840 - { id: 1, class: _ }
841 - { id: 2, class: _ }
842 # CHECK: %1:gpr(s32) = COPY $w0
843 # CHECK-NEXT: %0:gpr(s16) = G_TRUNC %1
844 # %0 has been mapped to GPR, we need to repair to match FPR.
845 # CHECK-NEXT: %3:fpr(s16) = COPY %0
846 # CHECK-NEXT: %2:fpr(s64) = G_FPEXT %3
847 # CHECK-NEXT: $d0 = COPY %2
848 # CHECK-NEXT: RET_ReallyLR
855 %0(s16) = G_TRUNC %1(s32)
856 %2(s64) = G_FPEXT %0(s16)
858 RET_ReallyLR implicit $d0
863 # Make sure we map FPEXT on FPR register bank.
864 # CHECK-LABEL: name: fp32Ext64
869 # CHECK-NEXT: - { id: 0, class: gpr, preferred-register: '' }
870 # CHECK-NEXT: - { id: 1, class: fpr, preferred-register: '' }
871 # CHECK-NEXT: - { id: 2, class: fpr, preferred-register: '' }
873 - { id: 0, class: _ }
874 - { id: 1, class: _ }
875 # CHECK: %0:gpr(s32) = COPY $w0
876 # %0 has been mapped to GPR, we need to repair to match FPR.
877 # CHECK-NEXT: %2:fpr(s32) = COPY %0
878 # CHECK-NEXT: %1:fpr(s64) = G_FPEXT %2
879 # CHECK-NEXT: $d0 = COPY %1
880 # CHECK-NEXT: RET_ReallyLR
886 %1(s64) = G_FPEXT %0(s32)
888 RET_ReallyLR implicit $d0
893 # Make sure we map FP16 ABI on FPR register bank.
894 # CHECK-LABEL: name: passFp16
896 # CHECK: - { id: 0, class: fpr, preferred-register: '' }
897 # CHECK: %0:fpr(s16) = COPY $h0
898 # CHECK-NEXT: $h0 = COPY %0(s16)
903 - { id: 0, class: _ }
910 RET_ReallyLR implicit $h0
914 # Make sure we properly detect fp types through copies.
915 # In that example, the copy comes from an ABI lowering of a fp type.
916 # CHECK-LABEL: name: passFp16ViaAllocas
918 # CHECK: - { id: 0, class: fpr, preferred-register: '' }
919 # CHECK: - { id: 1, class: gpr, preferred-register: '' }
920 # CHECK: - { id: 2, class: fpr, preferred-register: '' }
922 # CHECK: %0:fpr(s16) = COPY $h0
923 # CHECK-NEXT: %1:gpr(p0) = G_FRAME_INDEX %stack.0.p.addr
924 # If we didn't look through the copy for %0, the default mapping
925 # would have been on GPR and we would have to insert a copy to move
926 # the value away from FPR (h0).
927 # CHECK-NEXT: G_STORE %0(s16), %1(p0) :: (store 2 into %ir.p.addr)
928 # If we didn't look through the copy for %2, the default mapping
929 # would have been on GPR and we would have to insert a copy to move
930 # the value to FPR (h0).
931 # CHECK-NEXT: %2:fpr(s16) = G_LOAD %1(p0) :: (load 2 from %ir.p.addr)
932 # CHECK-NEXT: $h0 = COPY %2(s16)
933 name: passFp16ViaAllocas
936 tracksRegLiveness: true
938 - { id: 0, class: _ }
939 - { id: 1, class: _ }
940 - { id: 2, class: _ }
944 - { id: 0, name: p.addr, size: 2, alignment: 2, stack-id: default }
950 %1(p0) = G_FRAME_INDEX %stack.0.p.addr
951 G_STORE %0(s16), %1(p0) :: (store 2 into %ir.p.addr)
952 %2(s16) = G_LOAD %1(p0) :: (load 2 from %ir.p.addr)
954 RET_ReallyLR implicit $h0