• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
3
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  }
56
57  define void @ignoreTargetSpecificInst() { ret void }
58
59  define void @regBankSelected_property() { ret void }
60
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 }
73
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  }
81
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  }
89
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  }
96
97  define void @fp16Ext32() { ret void }
98  define void @fp16Ext64() { ret void }
99  define void @fp32Ext64() { ret void }
100
101  define half @passFp16(half %p) {
102  entry:
103    ret half %p
104  }
105
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  }
113...
114
115---
116# Check that we assign a relevant register bank for %0.
117# Based on the type i32, this should be gpr.
118name:            defaultMapping
119legalized:       true
120registers:
121  - { id: 0, class: _ }
122  - { id: 1, class: _ }
123body: |
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
130...
131
132---
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.
136name:            defaultMappingVector
137legalized:       true
138registers:
139  - { id: 0, class: _ }
140  - { id: 1, class: _ }
141body: |
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
149...
150
151---
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.
155name:            defaultMapping1Repair
156legalized:       true
157registers:
158  - { id: 0, class: _ }
159  - { id: 1, class: _ }
160  - { id: 2, class: _ }
161body: |
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
172...
173
174# Check that we repair the assignment for %0 differently for both uses.
175name:            defaultMapping2Repairs
176legalized:       true
177registers:
178  - { id: 0, class: _ }
179  - { id: 1, class: _ }
180body: |
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
190...
191
192---
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.
197name:            defaultMappingDefRepair
198legalized:       true
199registers:
200  - { id: 0, class: _ }
201  - { id: 1, class: fpr }
202body: |
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
211...
212
213---
214# Check that we are able to propagate register banks from phis.
215name:            phiPropagation
216legalized:       true
217tracksRegLiveness:   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: '' }
224registers:
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: _ }
231body: |
232  bb.0.entry:
233    successors: %bb.2.end, %bb.1.then
234    liveins: $x0, $x1, $w2
235
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
241
242  bb.1.then:
243    successors: %bb.2.end
244    %3(s32) = G_ADD %5, %5
245
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
250...
251
252---
253# Make sure we can repair physical register uses as well.
254name:            defaultMappingUseRepairPhysReg
255legalized:       true
256registers:
257  - { id: 0, class: _ }
258  - { id: 1, class: _ }
259  - { id: 2, class: _ }
260body: |
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
271...
272
273---
274# Make sure we can repair physical register defs.
275name:            defaultMappingDefRepairPhysReg
276legalized:       true
277registers:
278  - { id: 0, class: _ }
279  - { id: 1, class: _ }
280body: |
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
290...
291
292---
293# Check that the greedy mode is able to switch the
294# G_OR instruction from fpr to gpr.
295name:            greedyMappingOr
296legalized:       true
297registers:
298  - { id: 0, class: _ }
299  - { id: 1, class: _ }
300  - { id: 2, class: _ }
301body: |
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
306
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
314
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
320...
321
322---
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.
326name:            greedyMappingOrWithConstraints
327legalized:       true
328registers:
329  - { id: 0, class: _ }
330  - { id: 1, class: _ }
331  - { id: 2, class: fpr }
332body: |
333  bb.0.entry:
334    liveins: $x0, $x1
335    ; CHECK-LABEL: name: greedyMappingOrWithConstraints
336
337    ; CHECK: %0:gpr(<2 x s32>) = COPY $x0
338    ; CHECK-NEXT: %1:gpr(<2 x s32>) = COPY $x1
339
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
347
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
355...
356
357---
358# CHECK-LABEL: name: ignoreTargetSpecificInst
359name:            ignoreTargetSpecificInst
360legalized:       true
361# CHECK:      registers:
362# CHECK-NEXT:  - { id: 0, class: gpr64, preferred-register: '' }
363# CHECK-NEXT:  - { id: 1, class: gpr64, preferred-register: '' }
364registers:
365  - { id: 0, class: gpr64 }
366  - { id: 1, class: gpr64 }
367body: |
368  bb.0:
369    liveins: $x0
370
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
375
376    %0 = COPY $x0
377    %1 = ADDXrr %0, %0
378    $x0 = COPY %1
379    RET_ReallyLR implicit $x0
380...
381
382---
383# Check that we set the "regBankSelected" property.
384# CHECK-LABEL: name: regBankSelected_property
385# CHECK: legalized: true
386# CHECK: regBankSelected: true
387name:            regBankSelected_property
388legalized:       true
389regBankSelected: false
390body:             |
391  bb.0:
392...
393
394---
395# CHECK-LABEL: name: bitcast_s32_gpr
396name:            bitcast_s32_gpr
397legalized:       true
398
399# CHECK:      registers:
400# CHECK-NEXT:  - { id: 0, class: gpr, preferred-register: '' }
401# CHECK-NEXT:  - { id: 1, class: gpr, preferred-register: '' }
402registers:
403  - { id: 0, class: _ }
404  - { id: 1, class: _ }
405
406# CHECK:  body:
407# CHECK:    %0:gpr(s32) = COPY $w0
408# CHECK:    %1:gpr(s32) = G_BITCAST %0
409body:             |
410  bb.0:
411    liveins: $w0
412
413    %0(s32) = COPY $w0
414    %1(s32) = G_BITCAST %0
415...
416
417---
418# CHECK-LABEL: name: bitcast_s32_fpr
419name:            bitcast_s32_fpr
420legalized:       true
421
422# CHECK:      registers:
423# CHECK-NEXT:  - { id: 0, class: fpr, preferred-register: '' }
424# CHECK-NEXT:  - { id: 1, class: fpr, preferred-register: '' }
425registers:
426  - { id: 0, class: _ }
427  - { id: 1, class: _ }
428
429# CHECK:  body:
430# CHECK:    %0:fpr(<2 x s16>) = COPY $s0
431# CHECK:    %1:fpr(<2 x s16>) = G_BITCAST %0
432body:             |
433  bb.0:
434    liveins: $s0
435
436    %0(<2 x s16>) = COPY $s0
437    %1(<2 x s16>) = G_BITCAST %0
438...
439
440---
441# CHECK-LABEL: name: bitcast_s32_gpr_fpr
442name:            bitcast_s32_gpr_fpr
443legalized:       true
444
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: '' }
449registers:
450  - { id: 0, class: _ }
451  - { id: 1, class: _ }
452
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
457body:             |
458  bb.0:
459    liveins: $w0
460
461    %0(s32) = COPY $w0
462    %1(<2 x s16>) = G_BITCAST %0
463...
464
465---
466# CHECK-LABEL: name: bitcast_s32_fpr_gpr
467name:            bitcast_s32_fpr_gpr
468legalized:       true
469registers:
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
476body:             |
477  bb.0:
478    liveins: $s0
479
480    %0(<2 x s16>) = COPY $s0
481    %1(s32) = G_BITCAST %0
482...
483
484---
485# CHECK-LABEL: name: bitcast_s64_gpr
486name:            bitcast_s64_gpr
487legalized:       true
488registers:
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
494body:             |
495  bb.0:
496    liveins: $x0
497
498    %0(s64) = COPY $x0
499    %1(s64) = G_BITCAST %0
500...
501
502---
503# CHECK-LABEL: name: bitcast_s64_fpr
504name:            bitcast_s64_fpr
505legalized:       true
506registers:
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
512body:             |
513  bb.0:
514    liveins: $d0
515
516    %0(<2 x s32>) = COPY $d0
517    %1(<2 x s32>) = G_BITCAST %0
518...
519
520---
521# CHECK-LABEL: name: bitcast_s64_gpr_fpr
522name:            bitcast_s64_gpr_fpr
523legalized:       true
524registers:
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
531body:             |
532  bb.0:
533    liveins: $x0
534
535    %0(s64) = COPY $x0
536    %1(<2 x s32>) = G_BITCAST %0
537...
538
539---
540# CHECK-LABEL: name: bitcast_s64_fpr_gpr
541name:            bitcast_s64_fpr_gpr
542legalized:       true
543registers:
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
550body:             |
551  bb.0:
552    liveins: $d0
553
554    %0(<2 x s32>) = COPY $d0
555    %1(s64) = G_BITCAST %0
556...
557
558---
559# CHECK-LABEL: name: bitcast_s128
560name:            bitcast_s128
561legalized: true
562tracksRegLiveness: true
563registers:
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)
570body:             |
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
579
580...
581
582---
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.
587name:            copy_s128
588legalized: true
589tracksRegLiveness: true
590registers:
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)
599body:             |
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
609
610...
611
612---
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.
621name:            copy_s128_from_load
622legalized: true
623tracksRegLiveness: true
624registers:
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
631body:             |
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
638
639...
640
641---
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.
648name:            copy_fp16
649legalized: true
650tracksRegLiveness: true
651registers:
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)
659body:             |
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
666
667...
668
669
670---
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
675name:            greedyWithChainOfComputation
676legalized:       true
677registers:
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
696body:             |
697  bb.0:
698    liveins: $x0, $x1
699
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
708
709...
710
711---
712# Make sure we map what looks like floating point
713# loads to floating point register bank.
714# CHECK-LABEL: name: floatingPointLoad
715name:            floatingPointLoad
716legalized:       true
717
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: '' }
724registers:
725  - { id: 0, class: _ }
726  - { id: 1, class: _ }
727  - { id: 2, class: _ }
728  - { id: 3, class: _ }
729
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
739
740body:             |
741  bb.0:
742    liveins: $x0, $x1
743
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
750
751...
752
753---
754# Make sure we map what looks like floating point
755# stores to floating point register bank.
756# CHECK-LABEL: name: floatingPointStore
757name:            floatingPointStore
758legalized:       true
759
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: '' }
766registers:
767  - { id: 0, class: _ }
768  - { id: 1, class: _ }
769  - { id: 2, class: _ }
770
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
779
780body:             |
781  bb.0:
782    liveins: $x0, $x1
783
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
789
790...
791
792---
793# Make sure we map FPEXT on FPR register bank.
794# CHECK-LABEL: name: fp16Ext32
795name:            fp16Ext32
796alignment:       2
797legalized:       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: '' }
803registers:
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
814
815body:             |
816  bb.1:
817    liveins: $w0
818
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
824
825...
826
827---
828# Make sure we map FPEXT on FPR register bank.
829# CHECK-LABEL: name: fp16Ext64
830name:            fp16Ext64
831alignment:       2
832legalized:       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: '' }
838registers:
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
849
850body:             |
851  bb.1:
852    liveins: $w0
853
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
859
860...
861
862---
863# Make sure we map FPEXT on FPR register bank.
864# CHECK-LABEL: name: fp32Ext64
865name:            fp32Ext64
866alignment:       2
867legalized:       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: '' }
872registers:
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
881body:             |
882  bb.1:
883    liveins: $w0
884
885    %0(s32) = COPY $w0
886    %1(s64) = G_FPEXT %0(s32)
887    $d0 = COPY %1(s64)
888    RET_ReallyLR implicit $d0
889
890...
891
892---
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)
899name:            passFp16
900alignment:       2
901legalized:       true
902registers:
903  - { id: 0, class: _ }
904body:             |
905  bb.1.entry:
906    liveins: $h0
907
908    %0(s16) = COPY $h0
909    $h0 = COPY %0(s16)
910    RET_ReallyLR implicit $h0
911
912...
913---
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: '' }
921#
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)
933name:            passFp16ViaAllocas
934alignment:       2
935legalized:       true
936tracksRegLiveness: true
937registers:
938  - { id: 0, class: _ }
939  - { id: 1, class: _ }
940  - { id: 2, class: _ }
941frameInfo:
942  maxAlignment:    2
943stack:
944  - { id: 0, name: p.addr, size: 2, alignment: 2, stack-id: 0 }
945body:             |
946  bb.1.entry:
947    liveins: $h0
948
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
955
956...
957