[InstCombine] Signed saturation patterns
[llvm-complete.git] / test / CodeGen / AArch64 / GlobalISel / arm64-regbankselect.mir
blobb1553237a079f0acfabd71b520f40733293a1fc3
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
4 --- |
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() {
9   entry:
10     ret void
11   }
12   define void @defaultMappingVector() {
13   entry:
14     ret void
15   }
16   define void @defaultMapping1Repair() {
17   entry:
18     ret void
19   }
20   define void @defaultMapping2Repairs() {
21   entry:
22     ret void
23   }
24   define void @defaultMappingDefRepair() {
25   entry:
26     ret void
27   }
28   define void @phiPropagation(i32* %src, i32* %dst, i1 %cond) {
29   entry:
30     %srcVal = load i32, i32* %src
31     br i1 %cond, label %end, label %then
32   then:
33     %res = add i32 %srcVal, 36
34     br label %end
35   end:
36     %toStore = phi i32 [ %srcVal, %entry ], [ %res, %then ]
37     store i32 %toStore, i32* %dst
38     ret void
39   }
40   define void @defaultMappingUseRepairPhysReg() {
41   entry:
42     ret void
43   }
44   define void @defaultMappingDefRepairPhysReg() {
45   entry:
46     ret void
47   }
48   define void @greedyMappingOr() {
49   entry:
50     ret void
51   }
52   define void @greedyMappingOrWithConstraints() {
53   entry:
54     ret void
55   }
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
79     ret i64 %res
80   }
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
87     ret i64 %res
88   }
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
94     ret void
95   }
97   define void @fp16Ext32() { ret void }
98   define void @fp16Ext64() { ret void }
99   define void @fp32Ext64() { ret void }
101   define half @passFp16(half %p) {
102   entry:
103     ret half %p
104   }
106   define half @passFp16ViaAllocas(half %p) {
107   entry:
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
111     ret half %0
112   }
116 # Check that we assign a relevant register bank for %0.
117 # Based on the type i32, this should be gpr.
118 name:            defaultMapping
119 legalized:       true
120 registers:
121   - { id: 0, class: _ }
122   - { id: 1, class: _ }
123 body: |
124   bb.0.entry:
125     liveins: $x0
126     ; CHECK-LABEL: name: defaultMapping
127     ; CHECK:      %1:gpr(s32) = G_ADD %0
128     %0(s32) = COPY $w0
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
137 legalized:       true
138 registers:
139   - { id: 0, class: _ }
140   - { id: 1, class: _ }
141 body: |
142   bb.0.entry:
143     liveins: $d0
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
156 legalized:       true
157 registers:
158   - { id: 0, class: _ }
159   - { id: 1, class: _ }
160   - { id: 2, class: _ }
161 body: |
162   bb.0.entry:
163     liveins: $s0, $x0
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
169     %0(s32) = COPY $s0
170     %1(s32) = COPY $w0
171     %2(s32) = G_ADD %0, %1
174 # Check that we repair the assignment for %0 differently for both uses.
175 name:            defaultMapping2Repairs
176 legalized:       true
177 registers:
178   - { id: 0, class: _ }
179   - { id: 1, class: _ }
180 body: |
181   bb.0.entry:
182     liveins: $s0, $x0
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
188     %0(s32) = COPY $s0
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
196 # fixes that.
197 name:            defaultMappingDefRepair
198 legalized:       true
199 registers:
200   - { id: 0, class: _ }
201   - { id: 1, class: fpr }
202 body: |
203   bb.0.entry:
204     liveins: $w0
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
209     %0(s32) = COPY $w0
210     %1(s32) = G_ADD %0, %0
214 # Check that we are able to propagate register banks from phis.
215 name:            phiPropagation
216 legalized:       true
217 tracksRegLiveness:   true
218 # CHECK:      registers:
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: '' }
224 registers:
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: _ }
231 body: |
232   bb.0.entry:
233     successors: %bb.2.end, %bb.1.then
234     liveins: $x0, $x1, $w2
236     %0 = LDRWui killed $x0, 0 :: (load 4 from %ir.src)
237     %5(s32) = COPY %0
238     %1(p0) = COPY $x1
239     %2 = COPY $w2
240     TBNZW killed %2, 0, %bb.2.end
242   bb.1.then:
243     successors: %bb.2.end
244     %3(s32) = G_ADD %5, %5
246   bb.2.end:
247     %4(s32) = PHI %0, %bb.0.entry, %3, %bb.1.then
248     G_STORE killed %4, killed %1 :: (store 4 into %ir.dst)
249     RET_ReallyLR
253 # Make sure we can repair physical register uses as well.
254 name:            defaultMappingUseRepairPhysReg
255 legalized:       true
256 registers:
257   - { id: 0, class: _ }
258   - { id: 1, class: _ }
259   - { id: 2, class: _ }
260 body: |
261   bb.0.entry:
262     liveins: $w0, $s0
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
268     %0(s32) = COPY $w0
269     %1(s32) = COPY $s0
270     %2(s32) = G_ADD %0, %1
274 # Make sure we can repair physical register defs.
275 name:            defaultMappingDefRepairPhysReg
276 legalized:       true
277 registers:
278   - { id: 0, class: _ }
279   - { id: 1, class: _ }
280 body: |
281   bb.0.entry:
282     liveins: $w0
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
287     %0(s32) = COPY $w0
288     %1(s32) = G_ADD %0, %0
289     $s0 = COPY %1
293 # Check that the greedy mode is able to switch the
294 # G_OR instruction from fpr to gpr.
295 name:            greedyMappingOr
296 legalized:       true
297 registers:
298   - { id: 0, class: _ }
299   - { id: 1, class: _ }
300   - { id: 2, class: _ }
301 body: |
302   bb.0.entry:
303     liveins: $x0, $x1
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
325 # %2 constraint.
326 name:            greedyMappingOrWithConstraints
327 legalized:       true
328 registers:
329   - { id: 0, class: _ }
330   - { id: 1, class: _ }
331   - { id: 2, class: fpr }
332 body: |
333   bb.0.entry:
334     liveins: $x0, $x1
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
360 legalized:       true
361 # CHECK:      registers:
362 # CHECK-NEXT:  - { id: 0, class: gpr64, preferred-register: '' }
363 # CHECK-NEXT:  - { id: 1, class: gpr64, preferred-register: '' }
364 registers:
365   - { id: 0, class: gpr64 }
366   - { id: 1, class: gpr64 }
367 body: |
368   bb.0:
369     liveins: $x0
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
376     %0 = COPY $x0
377     %1 = ADDXrr %0, %0
378     $x0 = COPY %1
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
388 legalized:       true
389 regBankSelected: false
390 body:             |
391   bb.0:
395 # CHECK-LABEL: name: bitcast_s32_gpr
396 name:            bitcast_s32_gpr
397 legalized:       true
399 # CHECK:      registers:
400 # CHECK-NEXT:  - { id: 0, class: gpr, preferred-register: '' }
401 # CHECK-NEXT:  - { id: 1, class: gpr, preferred-register: '' }
402 registers:
403   - { id: 0, class: _ }
404   - { id: 1, class: _ }
406 # CHECK:  body:
407 # CHECK:    %0:gpr(s32) = COPY $w0
408 # CHECK:    %1:gpr(s32) = G_BITCAST %0
409 body:             |
410   bb.0:
411     liveins: $w0
413     %0(s32) = COPY $w0
414     %1(s32) = G_BITCAST %0
418 # CHECK-LABEL: name: bitcast_s32_fpr
419 name:            bitcast_s32_fpr
420 legalized:       true
422 # CHECK:      registers:
423 # CHECK-NEXT:  - { id: 0, class: fpr, preferred-register: '' }
424 # CHECK-NEXT:  - { id: 1, class: fpr, preferred-register: '' }
425 registers:
426   - { id: 0, class: _ }
427   - { id: 1, class: _ }
429 # CHECK:  body:
430 # CHECK:    %0:fpr(<2 x s16>) = COPY $s0
431 # CHECK:    %1:fpr(<2 x s16>) = G_BITCAST %0
432 body:             |
433   bb.0:
434     liveins: $s0
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
443 legalized:       true
445 # CHECK:      registers:
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: '' }
449 registers:
450   - { id: 0, class: _ }
451   - { id: 1, class: _ }
453 # CHECK:  body:
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
457 body:             |
458   bb.0:
459     liveins: $w0
461     %0(s32) = COPY $w0
462     %1(<2 x s16>) = G_BITCAST %0
466 # CHECK-LABEL: name: bitcast_s32_fpr_gpr
467 name:            bitcast_s32_fpr_gpr
468 legalized:       true
469 registers:
470   - { id: 0, class: _ }
471   - { id: 1, class: _ }
472 # CHECK:  body:
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
476 body:             |
477   bb.0:
478     liveins: $s0
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
487 legalized:       true
488 registers:
489   - { id: 0, class: _ }
490   - { id: 1, class: _ }
491 # CHECK:  body:
492 # CHECK:    %0:gpr(s64) = COPY $x0
493 # CHECK:    %1:gpr(s64) = G_BITCAST %0
494 body:             |
495   bb.0:
496     liveins: $x0
498     %0(s64) = COPY $x0
499     %1(s64) = G_BITCAST %0
503 # CHECK-LABEL: name: bitcast_s64_fpr
504 name:            bitcast_s64_fpr
505 legalized:       true
506 registers:
507   - { id: 0, class: _ }
508   - { id: 1, class: _ }
509 # CHECK:  body:
510 # CHECK:    %0:fpr(<2 x s32>) = COPY $d0
511 # CHECK:    %1:fpr(<2 x s32>) = G_BITCAST %0
512 body:             |
513   bb.0:
514     liveins: $d0
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
523 legalized:       true
524 registers:
525   - { id: 0, class: _ }
526   - { id: 1, class: _ }
527 # CHECK:  body:
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
531 body:             |
532   bb.0:
533     liveins: $x0
535     %0(s64) = COPY $x0
536     %1(<2 x s32>) = G_BITCAST %0
540 # CHECK-LABEL: name: bitcast_s64_fpr_gpr
541 name:            bitcast_s64_fpr_gpr
542 legalized:       true
543 registers:
544   - { id: 0, class: _ }
545   - { id: 1, class: _ }
546 # CHECK:  body:
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
550 body:             |
551   bb.0:
552     liveins: $d0
554     %0(<2 x s32>) = COPY $d0
555     %1(s64) = G_BITCAST %0
559 # CHECK-LABEL: name: bitcast_s128
560 name:            bitcast_s128
561 legalized: true
562 tracksRegLiveness: true
563 registers:
564   - { id: 0, class: _}
565   - { id: 1, class: _}
566   - { id: 2, class: _}
567   - { id: 3, class: _}
568 # CHECK: %3:fpr(s128) = G_MERGE_VALUES
569 # CHECK: %2:fpr(<2 x s64>) = G_BITCAST %3(s128)
570 body:             |
571   bb.1:
572     liveins: $x0, $x1
573     %0(s64) = COPY $x0
574     %1(s64) = COPY $x1
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.
587 name:            copy_s128
588 legalized: true
589 tracksRegLiveness: true
590 registers:
591   - { id: 0, class: _}
592   - { id: 1, class: _}
593   - { id: 2, class: _}
594   - { id: 3, class: _}
595   - { id: 4, class: _}
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)
599 body:             |
600   bb.1:
601     liveins: $x0, $x1
602     %0(s64) = COPY $x0
603     %1(s64) = COPY $x1
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
622 legalized: true
623 tracksRegLiveness: true
624 registers:
625   - { id: 0, class: fpr128}
626   - { id: 1, class: _}
627 # CHECK: registers:
628 # CHECK:  - { id: 0, class: fpr128, preferred-register: '' }
629 # CHECK:  - { id: 1, class: fpr, preferred-register: '' }
630 # CHECK: %1:fpr(s128) = COPY %0
631 body:             |
632   bb.1:
633     liveins: $x0
634     %0 = LDRQui killed $x0, 0
635     %1(s128) = COPY %0
636     $q0 = COPY %1(s128)
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
647 # exist in a copy.
648 name:            copy_fp16
649 legalized: true
650 tracksRegLiveness: true
651 registers:
652   - { id: 0, class: _}
653   - { id: 1, class: _}
654 # CHECK: registers:
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)
659 body:             |
660   bb.1:
661     liveins: $w0
662     %0(s32) = COPY $w0
663     %1(s16) = G_TRUNC %0(s32)
664     $h0 = COPY %1(s16)
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
676 legalized:       true
677 registers:
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
696 body:             |
697   bb.0:
698     liveins: $x0, $x1
700     %0(s64) = COPY $x0
701     %1(p0) = COPY $x1
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>)
706     $x0 = COPY %5(s64)
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
716 legalized:       true
718 # CHECK: registers:
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: '' }
724 registers:
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
740 body:             |
741   bb.0:
742     liveins: $x0, $x1
744     %0(s64) = COPY $x0
745     %1(p0) = COPY $x1
746     %2(s64) = G_LOAD %1(p0) :: (load 8 from %ir.addr)
747     %3(s64) = G_FADD %0, %2
748     $x0 = COPY %3(s64)
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
758 legalized:       true
760 # CHECK: registers:
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: '' }
766 registers:
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
780 body:             |
781   bb.0:
782     liveins: $x0, $x1
784     %0(s64) = COPY $x0
785     %1(p0) = COPY $x1
786     %2(s64) = G_FADD %0, %0
787     G_STORE %2(s64), %1(p0) :: (store 8 into %ir.addr)
788     RET_ReallyLR
793 # Make sure we map FPEXT on FPR register bank.
794 # CHECK-LABEL: name: fp16Ext32
795 name:            fp16Ext32
796 alignment:       4
797 legalized:       true
798 # CHECK: registers:
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: '' }
803 registers:
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
815 body:             |
816   bb.1:
817     liveins: $w0
819     %1(s32) = COPY $w0
820     %0(s16) = G_TRUNC %1(s32)
821     %2(s32) = G_FPEXT %0(s16)
822     $s0 = COPY %2(s32)
823     RET_ReallyLR implicit $s0
828 # Make sure we map FPEXT on FPR register bank.
829 # CHECK-LABEL: name: fp16Ext64
830 name:            fp16Ext64
831 alignment:       4
832 legalized:       true
833 # CHECK: registers:
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: '' }
838 registers:
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
850 body:             |
851   bb.1:
852     liveins: $w0
854     %1(s32) = COPY $w0
855     %0(s16) = G_TRUNC %1(s32)
856     %2(s64) = G_FPEXT %0(s16)
857     $d0 = COPY %2(s64)
858     RET_ReallyLR implicit $d0
863 # Make sure we map FPEXT on FPR register bank.
864 # CHECK-LABEL: name: fp32Ext64
865 name:            fp32Ext64
866 alignment:       4
867 legalized:       true
868 # CHECK: registers:
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: '' }
872 registers:
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
881 body:             |
882   bb.1:
883     liveins: $w0
885     %0(s32) = COPY $w0
886     %1(s64) = G_FPEXT %0(s32)
887     $d0 = COPY %1(s64)
888     RET_ReallyLR implicit $d0
893 # Make sure we map FP16 ABI on FPR register bank.
894 # CHECK-LABEL: name: passFp16
895 # CHECK: registers:
896 # CHECK:  - { id: 0, class: fpr, preferred-register: '' }
897 # CHECK:  %0:fpr(s16) = COPY $h0
898 # CHECK-NEXT: $h0 = COPY %0(s16)
899 name:            passFp16
900 alignment:       4
901 legalized:       true
902 registers:
903   - { id: 0, class: _ }
904 body:             |
905   bb.1.entry:
906     liveins: $h0
908     %0(s16) = COPY $h0
909     $h0 = COPY %0(s16)
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
917 # CHECK: registers:
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
934 alignment:       4
935 legalized:       true
936 tracksRegLiveness: true
937 registers:
938   - { id: 0, class: _ }
939   - { id: 1, class: _ }
940   - { id: 2, class: _ }
941 frameInfo:
942   maxAlignment:    2
943 stack:
944   - { id: 0, name: p.addr, size: 2, alignment: 2, stack-id: default }
945 body:             |
946   bb.1.entry:
947     liveins: $h0
949     %0(s16) = COPY $h0
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)
953     $h0 = COPY %2(s16)
954     RET_ReallyLR implicit $h0