| # 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 |
| |
| ... |