forked from OSchip/llvm-project
749 lines
21 KiB
YAML
749 lines
21 KiB
YAML
# RUN: llc -O0 -run-pass=regbankselect -global-isel %s -o - -verify-machineinstrs | FileCheck %s --check-prefix=CHECK --check-prefix=FAST
|
|
# RUN: llc -O0 -run-pass=regbankselect -global-isel %s -regbankselect-greedy -o - -verify-machineinstrs | FileCheck %s --check-prefix=CHECK --check-prefix=GREEDY
|
|
|
|
--- |
|
|
; ModuleID = 'generic-virtual-registers-type-error.mir'
|
|
target datalayout = "e-m:o-i64:64-i128:128-n32:64-S128"
|
|
target triple = "aarch64--"
|
|
define void @defaultMapping() {
|
|
entry:
|
|
ret void
|
|
}
|
|
define void @defaultMappingVector() {
|
|
entry:
|
|
ret void
|
|
}
|
|
define void @defaultMapping1Repair() {
|
|
entry:
|
|
ret void
|
|
}
|
|
define void @defaultMapping2Repairs() {
|
|
entry:
|
|
ret void
|
|
}
|
|
define void @defaultMappingDefRepair() {
|
|
entry:
|
|
ret void
|
|
}
|
|
define void @phiPropagation(i32* %src, i32* %dst, i1 %cond) {
|
|
entry:
|
|
%srcVal = load i32, i32* %src
|
|
br i1 %cond, label %end, label %then
|
|
then:
|
|
%res = add i32 %srcVal, 36
|
|
br label %end
|
|
end:
|
|
%toStore = phi i32 [ %srcVal, %entry ], [ %res, %then ]
|
|
store i32 %toStore, i32* %dst
|
|
ret void
|
|
}
|
|
define void @defaultMappingUseRepairPhysReg() {
|
|
entry:
|
|
ret void
|
|
}
|
|
define void @defaultMappingDefRepairPhysReg() {
|
|
entry:
|
|
ret void
|
|
}
|
|
define void @greedyMappingOr() {
|
|
entry:
|
|
ret void
|
|
}
|
|
define void @greedyMappingOrWithConstraints() {
|
|
entry:
|
|
ret void
|
|
}
|
|
|
|
define void @ignoreTargetSpecificInst() { ret void }
|
|
|
|
define void @regBankSelected_property() { ret void }
|
|
|
|
define void @bitcast_s32_gpr() { ret void }
|
|
define void @bitcast_s32_fpr() { ret void }
|
|
define void @bitcast_s32_gpr_fpr() { ret void }
|
|
define void @bitcast_s32_fpr_gpr() { ret void }
|
|
define void @bitcast_s64_gpr() { ret void }
|
|
define void @bitcast_s64_fpr() { ret void }
|
|
define void @bitcast_s64_gpr_fpr() { ret void }
|
|
define void @bitcast_s64_fpr_gpr() { ret void }
|
|
|
|
define i64 @greedyWithChainOfComputation(i64 %arg1, <2 x i32>* %addr) {
|
|
%varg1 = bitcast i64 %arg1 to <2 x i32>
|
|
%varg2 = load <2 x i32>, <2 x i32>* %addr
|
|
%vres = or <2 x i32> %varg1, %varg2
|
|
%res = bitcast <2 x i32> %vres to i64
|
|
ret i64 %res
|
|
}
|
|
|
|
define i64 @floatingPointLoad(i64 %arg1, double* %addr) {
|
|
%varg1 = bitcast i64 %arg1 to double
|
|
%varg2 = load double, double* %addr
|
|
%vres = fadd double %varg1, %varg2
|
|
%res = bitcast double %vres to i64
|
|
ret i64 %res
|
|
}
|
|
|
|
define void @floatingPointStore(i64 %arg1, double* %addr) {
|
|
%varg1 = bitcast i64 %arg1 to double
|
|
%vres = fadd double %varg1, %varg1
|
|
store double %vres, double* %addr
|
|
ret void
|
|
}
|
|
...
|
|
|
|
---
|
|
# Check that we assign a relevant register bank for %0.
|
|
# Based on the type i32, this should be gpr.
|
|
name: defaultMapping
|
|
legalized: true
|
|
# CHECK-LABEL: name: defaultMapping
|
|
# CHECK: registers:
|
|
# CHECK: - { id: 0, class: gpr, preferred-register: '' }
|
|
# CHECK: - { id: 1, class: gpr, preferred-register: '' }
|
|
registers:
|
|
- { id: 0, class: _ }
|
|
- { id: 1, class: _ }
|
|
body: |
|
|
bb.0.entry:
|
|
liveins: %x0
|
|
; CHECK: %1(s32) = G_ADD %0
|
|
%0(s32) = COPY %w0
|
|
%1(s32) = G_ADD %0, %0
|
|
...
|
|
|
|
---
|
|
# Check that we assign a relevant register bank for %0.
|
|
# Based on the type <2 x i32>, this should be fpr.
|
|
# FPR is used for both floating point and vector registers.
|
|
name: defaultMappingVector
|
|
legalized: true
|
|
# CHECK-LABEL: name: defaultMappingVector
|
|
# CHECK: registers:
|
|
# CHECK: - { id: 0, class: fpr, preferred-register: '' }
|
|
# CHECK: - { id: 1, class: fpr, preferred-register: '' }
|
|
registers:
|
|
- { id: 0, class: _ }
|
|
- { id: 1, class: _ }
|
|
body: |
|
|
bb.0.entry:
|
|
liveins: %d0
|
|
; CHECK: %0(<2 x s32>) = COPY %d0
|
|
; CHECK: %1(<2 x s32>) = G_ADD %0
|
|
%0(<2 x s32>) = COPY %d0
|
|
%1(<2 x s32>) = G_ADD %0, %0
|
|
...
|
|
|
|
---
|
|
# Check that we repair the assignment for %0.
|
|
# Indeed based on the source of the copy it should live
|
|
# in FPR, but at the use, it should be GPR.
|
|
name: defaultMapping1Repair
|
|
legalized: true
|
|
# CHECK-LABEL: name: defaultMapping1Repair
|
|
# CHECK: registers:
|
|
# CHECK-NEXT: - { id: 0, class: fpr, preferred-register: '' }
|
|
# CHECK-NEXT: - { id: 1, class: gpr, preferred-register: '' }
|
|
# CHECK-NEXT: - { id: 2, class: gpr, preferred-register: '' }
|
|
# CHECK-NEXT: - { id: 3, class: gpr, preferred-register: '' }
|
|
registers:
|
|
- { id: 0, class: _ }
|
|
- { id: 1, class: _ }
|
|
- { id: 2, class: _ }
|
|
body: |
|
|
bb.0.entry:
|
|
liveins: %s0, %x0
|
|
; CHECK: %0(s32) = COPY %s0
|
|
; CHECK-NEXT: %1(s32) = COPY %w0
|
|
; CHECK-NEXT: %3(s32) = COPY %0
|
|
; CHECK-NEXT: %2(s32) = G_ADD %3, %1
|
|
%0(s32) = COPY %s0
|
|
%1(s32) = COPY %w0
|
|
%2(s32) = G_ADD %0, %1
|
|
...
|
|
|
|
# Check that we repair the assignment for %0 differently for both uses.
|
|
name: defaultMapping2Repairs
|
|
legalized: true
|
|
# CHECK-LABEL: name: defaultMapping2Repairs
|
|
# CHECK: registers:
|
|
# CHECK-NEXT: - { id: 0, class: fpr, preferred-register: '' }
|
|
# CHECK-NEXT: - { id: 1, class: gpr, preferred-register: '' }
|
|
# CHECK-NEXT: - { id: 2, class: gpr, preferred-register: '' }
|
|
# CHECK-NEXT: - { id: 3, class: gpr, preferred-register: '' }
|
|
registers:
|
|
- { id: 0, class: _ }
|
|
- { id: 1, class: _ }
|
|
body: |
|
|
bb.0.entry:
|
|
liveins: %s0, %x0
|
|
; CHECK: %0(s32) = COPY %s0
|
|
; CHECK-NEXT: %2(s32) = COPY %0
|
|
; CHECK-NEXT: %3(s32) = COPY %0
|
|
; CHECK-NEXT: %1(s32) = G_ADD %2, %3
|
|
%0(s32) = COPY %s0
|
|
%1(s32) = G_ADD %0, %0
|
|
...
|
|
|
|
---
|
|
# Check that we repair the definition of %1.
|
|
# %1 is forced to be into FPR, but its definition actually
|
|
# requires that it lives in GPR. Make sure regbankselect
|
|
# fixes that.
|
|
name: defaultMappingDefRepair
|
|
legalized: true
|
|
# CHECK-LABEL: name: defaultMappingDefRepair
|
|
# CHECK: registers:
|
|
# CHECK-NEXT: - { id: 0, class: gpr, preferred-register: '' }
|
|
# CHECK-NEXT: - { id: 1, class: fpr, preferred-register: '' }
|
|
# CHECK-NEXT: - { id: 2, class: gpr, preferred-register: '' }
|
|
registers:
|
|
- { id: 0, class: _ }
|
|
- { id: 1, class: fpr }
|
|
body: |
|
|
bb.0.entry:
|
|
liveins: %w0
|
|
; CHECK: %0(s32) = COPY %w0
|
|
; CHECK-NEXT: %2(s32) = G_ADD %0, %0
|
|
; CHECK-NEXT: %1(s32) = COPY %2
|
|
%0(s32) = COPY %w0
|
|
%1(s32) = G_ADD %0, %0
|
|
...
|
|
|
|
---
|
|
# Check that we are able to propagate register banks from phis.
|
|
name: phiPropagation
|
|
legalized: true
|
|
tracksRegLiveness: true
|
|
# CHECK: registers:
|
|
# CHECK-NEXT: - { id: 0, class: gpr32, preferred-register: '' }
|
|
# CHECK-NEXT: - { id: 1, class: gpr64sp, preferred-register: '' }
|
|
# CHECK-NEXT: - { id: 2, class: gpr32, preferred-register: '' }
|
|
# CHECK-NEXT: - { id: 3, class: gpr, preferred-register: '' }
|
|
# CHECK-NEXT: - { id: 4, class: gpr, preferred-register: '' }
|
|
registers:
|
|
- { id: 0, class: gpr32 }
|
|
- { id: 1, class: gpr64sp }
|
|
- { id: 2, class: gpr32 }
|
|
- { id: 3, class: _ }
|
|
- { id: 4, class: _ }
|
|
- { id: 5, class: _ }
|
|
body: |
|
|
bb.0.entry:
|
|
successors: %bb.2.end, %bb.1.then
|
|
liveins: %x0, %x1, %w2
|
|
|
|
%0 = LDRWui killed %x0, 0 :: (load 4 from %ir.src)
|
|
%5(s32) = COPY %0
|
|
%1(p0) = COPY %x1
|
|
%2 = COPY %w2
|
|
TBNZW killed %2, 0, %bb.2.end
|
|
|
|
bb.1.then:
|
|
successors: %bb.2.end
|
|
%3(s32) = G_ADD %5, %5
|
|
|
|
bb.2.end:
|
|
%4(s32) = PHI %0, %bb.0.entry, %3, %bb.1.then
|
|
G_STORE killed %4, killed %1 :: (store 4 into %ir.dst)
|
|
RET_ReallyLR
|
|
...
|
|
|
|
---
|
|
# Make sure we can repair physical register uses as well.
|
|
name: defaultMappingUseRepairPhysReg
|
|
legalized: true
|
|
# CHECK-LABEL: name: defaultMappingUseRepairPhysReg
|
|
# CHECK: registers:
|
|
# CHECK-NEXT: - { id: 0, class: gpr, preferred-register: '' }
|
|
# CHECK-NEXT: - { id: 1, class: fpr, preferred-register: '' }
|
|
# CHECK-NEXT: - { id: 2, class: gpr, preferred-register: '' }
|
|
# CHECK-NEXT: - { id: 3, class: gpr, preferred-register: '' }
|
|
registers:
|
|
- { id: 0, class: _ }
|
|
- { id: 1, class: _ }
|
|
- { id: 2, class: _ }
|
|
body: |
|
|
bb.0.entry:
|
|
liveins: %w0, %s0
|
|
; CHECK: %0(s32) = COPY %w0
|
|
; CHECK-NEXT: %1(s32) = COPY %s0
|
|
; CHECK-NEXT: %3(s32) = COPY %1
|
|
; CHECK-NEXT: %2(s32) = G_ADD %0, %3
|
|
%0(s32) = COPY %w0
|
|
%1(s32) = COPY %s0
|
|
%2(s32) = G_ADD %0, %1
|
|
...
|
|
|
|
---
|
|
# Make sure we can repair physical register defs.
|
|
name: defaultMappingDefRepairPhysReg
|
|
legalized: true
|
|
# CHECK-LABEL: name: defaultMappingDefRepairPhysReg
|
|
# CHECK: registers:
|
|
# CHECK-NEXT: - { id: 0, class: gpr, preferred-register: '' }
|
|
# CHECK-NEXT: - { id: 1, class: gpr, preferred-register: '' }
|
|
registers:
|
|
- { id: 0, class: _ }
|
|
- { id: 1, class: _ }
|
|
body: |
|
|
bb.0.entry:
|
|
liveins: %w0
|
|
; CHECK: %0(s32) = COPY %w0
|
|
; CHECK-NEXT: %1(s32) = G_ADD %0, %0
|
|
; CHECK-NEXT: %s0 = COPY %1
|
|
%0(s32) = COPY %w0
|
|
%1(s32) = G_ADD %0, %0
|
|
%s0 = COPY %1
|
|
...
|
|
|
|
---
|
|
# Check that the greedy mode is able to switch the
|
|
# G_OR instruction from fpr to gpr.
|
|
name: greedyMappingOr
|
|
legalized: true
|
|
# CHECK-LABEL: name: greedyMappingOr
|
|
# CHECK: registers:
|
|
# CHECK-NEXT: - { id: 0, class: gpr, preferred-register: '' }
|
|
# CHECK-NEXT: - { id: 1, class: gpr, preferred-register: '' }
|
|
|
|
# Fast mode maps vector instruction on FPR.
|
|
# FAST-NEXT: - { id: 2, class: fpr, preferred-register: '' }
|
|
# Fast mode needs two extra copies.
|
|
# FAST-NEXT: - { id: 3, class: fpr, preferred-register: '' }
|
|
# FAST-NEXT: - { id: 4, class: fpr, preferred-register: '' }
|
|
|
|
# Greedy mode coalesce the computation on the GPR register
|
|
# because it is the cheapest.
|
|
# GREEDY-NEXT: - { id: 2, class: gpr, preferred-register: '' }
|
|
|
|
registers:
|
|
- { id: 0, class: _ }
|
|
- { id: 1, class: _ }
|
|
- { id: 2, class: _ }
|
|
body: |
|
|
bb.0.entry:
|
|
liveins: %x0, %x1
|
|
; CHECK: %0(<2 x s32>) = COPY %x0
|
|
; CHECK-NEXT: %1(<2 x s32>) = COPY %x1
|
|
|
|
|
|
; Fast mode tries to reuse the source of the copy for the destination.
|
|
; Now, the default mapping says that %0 and %1 need to be in FPR.
|
|
; The repairing code insert two copies to materialize that.
|
|
; FAST-NEXT: %3(<2 x s32>) = COPY %0
|
|
; FAST-NEXT: %4(<2 x s32>) = COPY %1
|
|
; The mapping of G_OR is on FPR.
|
|
; FAST-NEXT: %2(<2 x s32>) = G_OR %3, %4
|
|
|
|
; Greedy mode remapped the instruction on the GPR bank.
|
|
; GREEDY-NEXT: %2(<2 x s32>) = G_OR %0, %1
|
|
%0(<2 x s32>) = COPY %x0
|
|
%1(<2 x s32>) = COPY %x1
|
|
%2(<2 x s32>) = G_OR %0, %1
|
|
...
|
|
|
|
---
|
|
# Check that the greedy mode is able to switch the
|
|
# G_OR instruction from fpr to gpr, while still honoring
|
|
# %2 constraint.
|
|
name: greedyMappingOrWithConstraints
|
|
legalized: true
|
|
# CHECK-LABEL: name: greedyMappingOrWithConstraints
|
|
# CHECK: registers:
|
|
# CHECK-NEXT: - { id: 0, class: gpr, preferred-register: '' }
|
|
# CHECK-NEXT: - { id: 1, class: gpr, preferred-register: '' }
|
|
# CHECK-NEXT: - { id: 2, class: fpr, preferred-register: '' }
|
|
|
|
# Fast mode maps vector instruction on FPR.
|
|
# Fast mode needs two extra copies.
|
|
# FAST-NEXT: - { id: 3, class: fpr, preferred-register: '' }
|
|
# FAST-NEXT: - { id: 4, class: fpr, preferred-register: '' }
|
|
|
|
# Greedy mode coalesce the computation on the GPR register because it
|
|
# is the cheapest, but will need one extra copy to materialize %2 into a FPR.
|
|
# GREEDY-NEXT: - { id: 3, class: gpr, preferred-register: '' }
|
|
|
|
registers:
|
|
- { id: 0, class: _ }
|
|
- { id: 1, class: _ }
|
|
- { id: 2, class: fpr }
|
|
body: |
|
|
bb.0.entry:
|
|
liveins: %x0, %x1
|
|
; CHECK: %0(<2 x s32>) = COPY %x0
|
|
; CHECK-NEXT: %1(<2 x s32>) = COPY %x1
|
|
|
|
|
|
; Fast mode tries to reuse the source of the copy for the destination.
|
|
; Now, the default mapping says that %0 and %1 need to be in FPR.
|
|
; The repairing code insert two copies to materialize that.
|
|
; FAST-NEXT: %3(<2 x s32>) = COPY %0
|
|
; FAST-NEXT: %4(<2 x s32>) = COPY %1
|
|
; The mapping of G_OR is on FPR.
|
|
; FAST-NEXT: %2(<2 x s32>) = G_OR %3, %4
|
|
|
|
; Greedy mode remapped the instruction on the GPR bank.
|
|
; GREEDY-NEXT: %3(<2 x s32>) = G_OR %0, %1
|
|
; We need to keep %2 into FPR because we do not know anything about it.
|
|
; GREEDY-NEXT: %2(<2 x s32>) = COPY %3
|
|
%0(<2 x s32>) = COPY %x0
|
|
%1(<2 x s32>) = COPY %x1
|
|
%2(<2 x s32>) = G_OR %0, %1
|
|
...
|
|
|
|
---
|
|
# CHECK-LABEL: name: ignoreTargetSpecificInst
|
|
name: ignoreTargetSpecificInst
|
|
legalized: true
|
|
# CHECK: registers:
|
|
# CHECK-NEXT: - { id: 0, class: gpr64, preferred-register: '' }
|
|
# CHECK-NEXT: - { id: 1, class: gpr64, preferred-register: '' }
|
|
registers:
|
|
- { id: 0, class: gpr64 }
|
|
- { id: 1, class: gpr64 }
|
|
body: |
|
|
bb.0:
|
|
liveins: %x0
|
|
|
|
; CHECK: %0 = COPY %x0
|
|
; CHECK-NEXT: %1 = ADDXrr %0, %0
|
|
; CHECK-NEXT: %x0 = COPY %1
|
|
; CHECK-NEXT: RET_ReallyLR implicit %x0
|
|
|
|
%0 = COPY %x0
|
|
%1 = ADDXrr %0, %0
|
|
%x0 = COPY %1
|
|
RET_ReallyLR implicit %x0
|
|
...
|
|
|
|
---
|
|
# Check that we set the "regBankSelected" property.
|
|
# CHECK-LABEL: name: regBankSelected_property
|
|
# CHECK: legalized: true
|
|
# CHECK: regBankSelected: true
|
|
name: regBankSelected_property
|
|
legalized: true
|
|
regBankSelected: false
|
|
body: |
|
|
bb.0:
|
|
...
|
|
|
|
---
|
|
# CHECK-LABEL: name: bitcast_s32_gpr
|
|
name: bitcast_s32_gpr
|
|
legalized: true
|
|
|
|
# CHECK: registers:
|
|
# CHECK-NEXT: - { id: 0, class: gpr, preferred-register: '' }
|
|
# CHECK-NEXT: - { id: 1, class: gpr, preferred-register: '' }
|
|
registers:
|
|
- { id: 0, class: _ }
|
|
- { id: 1, class: _ }
|
|
|
|
# CHECK: body:
|
|
# CHECK: %0(s32) = COPY %w0
|
|
# CHECK: %1(s32) = G_BITCAST %0
|
|
body: |
|
|
bb.0:
|
|
liveins: %w0
|
|
|
|
%0(s32) = COPY %w0
|
|
%1(s32) = G_BITCAST %0
|
|
...
|
|
|
|
---
|
|
# CHECK-LABEL: name: bitcast_s32_fpr
|
|
name: bitcast_s32_fpr
|
|
legalized: true
|
|
|
|
# CHECK: registers:
|
|
# CHECK-NEXT: - { id: 0, class: fpr, preferred-register: '' }
|
|
# CHECK-NEXT: - { id: 1, class: fpr, preferred-register: '' }
|
|
registers:
|
|
- { id: 0, class: _ }
|
|
- { id: 1, class: _ }
|
|
|
|
# CHECK: body:
|
|
# CHECK: %0(<2 x s16>) = COPY %s0
|
|
# CHECK: %1(<2 x s16>) = G_BITCAST %0
|
|
body: |
|
|
bb.0:
|
|
liveins: %s0
|
|
|
|
%0(<2 x s16>) = COPY %s0
|
|
%1(<2 x s16>) = G_BITCAST %0
|
|
...
|
|
|
|
---
|
|
# CHECK-LABEL: name: bitcast_s32_gpr_fpr
|
|
name: bitcast_s32_gpr_fpr
|
|
legalized: true
|
|
|
|
# CHECK: registers:
|
|
# CHECK-NEXT: - { id: 0, class: gpr, preferred-register: '' }
|
|
# FAST-NEXT: - { id: 1, class: fpr, preferred-register: '' }
|
|
# GREEDY-NEXT: - { id: 1, class: gpr, preferred-register: '' }
|
|
registers:
|
|
- { id: 0, class: _ }
|
|
- { id: 1, class: _ }
|
|
|
|
# CHECK: body:
|
|
# CHECK: %0(s32) = COPY %w0
|
|
# CHECK: %1(<2 x s16>) = G_BITCAST %0
|
|
body: |
|
|
bb.0:
|
|
liveins: %w0
|
|
|
|
%0(s32) = COPY %w0
|
|
%1(<2 x s16>) = G_BITCAST %0
|
|
...
|
|
|
|
---
|
|
# CHECK-LABEL: name: bitcast_s32_fpr_gpr
|
|
name: bitcast_s32_fpr_gpr
|
|
legalized: true
|
|
|
|
# CHECK: registers:
|
|
# CHECK-NEXT: - { id: 0, class: fpr, preferred-register: '' }
|
|
# FAST-NEXT: - { id: 1, class: gpr, preferred-register: '' }
|
|
# GREEDY-NEXT: - { id: 1, class: fpr, preferred-register: '' }
|
|
registers:
|
|
- { id: 0, class: _ }
|
|
- { id: 1, class: _ }
|
|
|
|
# CHECK: body:
|
|
# CHECK: %0(<2 x s16>) = COPY %s0
|
|
# CHECK: %1(s32) = G_BITCAST %0
|
|
body: |
|
|
bb.0:
|
|
liveins: %s0
|
|
|
|
%0(<2 x s16>) = COPY %s0
|
|
%1(s32) = G_BITCAST %0
|
|
...
|
|
|
|
---
|
|
# CHECK-LABEL: name: bitcast_s64_gpr
|
|
name: bitcast_s64_gpr
|
|
legalized: true
|
|
|
|
# CHECK: registers:
|
|
# CHECK-NEXT: - { id: 0, class: gpr, preferred-register: '' }
|
|
# CHECK-NEXT: - { id: 1, class: gpr, preferred-register: '' }
|
|
registers:
|
|
- { id: 0, class: _ }
|
|
- { id: 1, class: _ }
|
|
|
|
# CHECK: body:
|
|
# CHECK: %0(s64) = COPY %x0
|
|
# CHECK: %1(s64) = G_BITCAST %0
|
|
body: |
|
|
bb.0:
|
|
liveins: %x0
|
|
|
|
%0(s64) = COPY %x0
|
|
%1(s64) = G_BITCAST %0
|
|
...
|
|
|
|
---
|
|
# CHECK-LABEL: name: bitcast_s64_fpr
|
|
name: bitcast_s64_fpr
|
|
legalized: true
|
|
|
|
# CHECK: registers:
|
|
# CHECK-NEXT: - { id: 0, class: fpr, preferred-register: '' }
|
|
# CHECK-NEXT: - { id: 1, class: fpr, preferred-register: '' }
|
|
registers:
|
|
- { id: 0, class: _ }
|
|
- { id: 1, class: _ }
|
|
|
|
# CHECK: body:
|
|
# CHECK: %0(<2 x s32>) = COPY %d0
|
|
# CHECK: %1(<2 x s32>) = G_BITCAST %0
|
|
body: |
|
|
bb.0:
|
|
liveins: %d0
|
|
|
|
%0(<2 x s32>) = COPY %d0
|
|
%1(<2 x s32>) = G_BITCAST %0
|
|
...
|
|
|
|
---
|
|
# CHECK-LABEL: name: bitcast_s64_gpr_fpr
|
|
name: bitcast_s64_gpr_fpr
|
|
legalized: true
|
|
|
|
# CHECK: registers:
|
|
# CHECK-NEXT: - { id: 0, class: gpr, preferred-register: '' }
|
|
# FAST-NEXT: - { id: 1, class: fpr, preferred-register: '' }
|
|
# GREEDY-NEXT: - { id: 1, class: gpr, preferred-register: '' }
|
|
registers:
|
|
- { id: 0, class: _ }
|
|
- { id: 1, class: _ }
|
|
# CHECK: body:
|
|
# CHECK: %0(s64) = COPY %x0
|
|
# CHECK: %1(<2 x s32>) = G_BITCAST %0
|
|
body: |
|
|
bb.0:
|
|
liveins: %x0
|
|
|
|
%0(s64) = COPY %x0
|
|
%1(<2 x s32>) = G_BITCAST %0
|
|
...
|
|
|
|
---
|
|
# CHECK-LABEL: name: bitcast_s64_fpr_gpr
|
|
name: bitcast_s64_fpr_gpr
|
|
legalized: true
|
|
|
|
# CHECK: registers:
|
|
# CHECK-NEXT: - { id: 0, class: fpr, preferred-register: '' }
|
|
# FAST-NEXT: - { id: 1, class: gpr, preferred-register: '' }
|
|
# GREEDY-NEXT: - { id: 1, class: fpr, preferred-register: '' }
|
|
registers:
|
|
- { id: 0, class: _ }
|
|
- { id: 1, class: _ }
|
|
|
|
# CHECK: body:
|
|
# CHECK: %0(<2 x s32>) = COPY %d0
|
|
# CHECK: %1(s64) = G_BITCAST %0
|
|
body: |
|
|
bb.0:
|
|
liveins: %d0
|
|
|
|
%0(<2 x s32>) = COPY %d0
|
|
%1(s64) = G_BITCAST %0
|
|
...
|
|
|
|
---
|
|
# Make sure the greedy mode is able to take advantage of the
|
|
# alternative mappings of G_LOAD to coalesce the whole chain
|
|
# of computation on GPR.
|
|
# CHECK-LABEL: name: greedyWithChainOfComputation
|
|
name: greedyWithChainOfComputation
|
|
legalized: true
|
|
|
|
# CHECK: registers:
|
|
# CHECK-NEXT: - { id: 0, class: gpr, preferred-register: '' }
|
|
# CHECK-NEXT: - { id: 1, class: gpr, preferred-register: '' }
|
|
# FAST-NEXT: - { id: 2, class: fpr, preferred-register: '' }
|
|
# FAST-NEXT: - { id: 3, class: fpr, preferred-register: '' }
|
|
# FAST-NEXT: - { id: 4, class: fpr, preferred-register: '' }
|
|
# GREEDY-NEXT: - { id: 2, class: gpr, preferred-register: '' }
|
|
# GREEDY-NEXT: - { id: 3, class: gpr, preferred-register: '' }
|
|
# GREEDY-NEXT: - { id: 4, class: gpr, preferred-register: '' }
|
|
# CHECK-NEXT: - { id: 5, class: gpr, preferred-register: '' }
|
|
registers:
|
|
- { id: 0, class: _ }
|
|
- { id: 1, class: _ }
|
|
- { id: 2, class: _ }
|
|
- { id: 3, class: _ }
|
|
- { id: 4, class: _ }
|
|
- { id: 5, class: _ }
|
|
|
|
# No repairing should be necessary for both modes.
|
|
# CHECK: %0(s64) = COPY %x0
|
|
# CHECK-NEXT: %1(p0) = COPY %x1
|
|
# CHECK-NEXT: %2(<2 x s32>) = G_BITCAST %0(s64)
|
|
# CHECK-NEXT: %3(<2 x s32>) = G_LOAD %1(p0) :: (load 8 from %ir.addr)
|
|
# CHECK-NEXT: %4(<2 x s32>) = G_OR %2, %3
|
|
# CHECK-NEXT: %5(s64) = G_BITCAST %4(<2 x s32>)
|
|
# CHECK-NEXT: %x0 = COPY %5(s64)
|
|
# CHECK-NEXT: RET_ReallyLR implicit %x0
|
|
|
|
body: |
|
|
bb.0:
|
|
liveins: %x0, %x1
|
|
|
|
%0(s64) = COPY %x0
|
|
%1(p0) = COPY %x1
|
|
%2(<2 x s32>) = G_BITCAST %0(s64)
|
|
%3(<2 x s32>) = G_LOAD %1(p0) :: (load 8 from %ir.addr)
|
|
%4(<2 x s32>) = G_OR %2, %3
|
|
%5(s64) = G_BITCAST %4(<2 x s32>)
|
|
%x0 = COPY %5(s64)
|
|
RET_ReallyLR implicit %x0
|
|
|
|
...
|
|
|
|
---
|
|
# Make sure we map what looks like floating point
|
|
# loads to floating point register bank.
|
|
# CHECK-LABEL: name: floatingPointLoad
|
|
name: floatingPointLoad
|
|
legalized: true
|
|
|
|
# CHECK: registers:
|
|
# CHECK-NEXT: - { id: 0, class: gpr, preferred-register: '' }
|
|
# CHECK-NEXT: - { id: 1, class: gpr, preferred-register: '' }
|
|
# CHECK-NEXT: - { id: 2, class: fpr, preferred-register: '' }
|
|
# CHECK-NEXT: - { id: 3, class: fpr, preferred-register: '' }
|
|
# CHECK-NEXT: - { id: 4, class: fpr, preferred-register: '' }
|
|
registers:
|
|
- { id: 0, class: _ }
|
|
- { id: 1, class: _ }
|
|
- { id: 2, class: _ }
|
|
- { id: 3, class: _ }
|
|
|
|
# No repairing should be necessary for both modes.
|
|
# CHECK: %0(s64) = COPY %x0
|
|
# CHECK-NEXT: %1(p0) = COPY %x1
|
|
# CHECK-NEXT: %2(s64) = G_LOAD %1(p0) :: (load 8 from %ir.addr)
|
|
# %0 has been mapped to GPR, we need to repair to match FPR.
|
|
# CHECK-NEXT: %4(s64) = COPY %0
|
|
# CHECK-NEXT: %3(s64) = G_FADD %4, %2
|
|
# CHECK-NEXT: %x0 = COPY %3(s64)
|
|
# CHECK-NEXT: RET_ReallyLR implicit %x0
|
|
|
|
body: |
|
|
bb.0:
|
|
liveins: %x0, %x1
|
|
|
|
%0(s64) = COPY %x0
|
|
%1(p0) = COPY %x1
|
|
%2(s64) = G_LOAD %1(p0) :: (load 8 from %ir.addr)
|
|
%3(s64) = G_FADD %0, %2
|
|
%x0 = COPY %3(s64)
|
|
RET_ReallyLR implicit %x0
|
|
|
|
...
|
|
|
|
---
|
|
# Make sure we map what looks like floating point
|
|
# stores to floating point register bank.
|
|
# CHECK-LABEL: name: floatingPointStore
|
|
name: floatingPointStore
|
|
legalized: true
|
|
|
|
# CHECK: registers:
|
|
# CHECK-NEXT: - { id: 0, class: gpr, preferred-register: '' }
|
|
# CHECK-NEXT: - { id: 1, class: gpr, preferred-register: '' }
|
|
# CHECK-NEXT: - { id: 2, class: fpr, preferred-register: '' }
|
|
# CHECK-NEXT: - { id: 3, class: fpr, preferred-register: '' }
|
|
# CHECK-NEXT: - { id: 4, class: fpr, preferred-register: '' }
|
|
registers:
|
|
- { id: 0, class: _ }
|
|
- { id: 1, class: _ }
|
|
- { id: 2, class: _ }
|
|
|
|
# CHECK: %0(s64) = COPY %x0
|
|
# CHECK-NEXT: %1(p0) = COPY %x1
|
|
# %0 has been mapped to GPR, we need to repair to match FPR.
|
|
# CHECK-NEXT: %3(s64) = COPY %0
|
|
# CHECK-NEXT: %4(s64) = COPY %0
|
|
# CHECK-NEXT: %2(s64) = G_FADD %3, %4
|
|
# CHECK-NEXT: G_STORE %2(s64), %1(p0) :: (store 8 into %ir.addr)
|
|
# CHECK-NEXT: RET_ReallyLR
|
|
|
|
body: |
|
|
bb.0:
|
|
liveins: %x0, %x1
|
|
|
|
%0(s64) = COPY %x0
|
|
%1(p0) = COPY %x1
|
|
%2(s64) = G_FADD %0, %0
|
|
G_STORE %2(s64), %1(p0) :: (store 8 into %ir.addr)
|
|
RET_ReallyLR
|
|
|
|
...
|