diff options
-rw-r--r-- | llvm/lib/Target/ARM/ARMInstructionSelector.cpp | 49 | ||||
-rw-r--r-- | llvm/test/CodeGen/ARM/GlobalISel/arm-instruction-select.mir | 95 |
2 files changed, 128 insertions, 16 deletions
diff --git a/llvm/lib/Target/ARM/ARMInstructionSelector.cpp b/llvm/lib/Target/ARM/ARMInstructionSelector.cpp index c4b9d6d25e5..f225ff82419 100644 --- a/llvm/lib/Target/ARM/ARMInstructionSelector.cpp +++ b/llvm/lib/Target/ARM/ARMInstructionSelector.cpp @@ -117,33 +117,39 @@ ARMInstructionSelector::ARMInstructionSelector(const ARMBaseTargetMachine &TM, { } -static bool selectCopy(MachineInstr &I, const TargetInstrInfo &TII, - MachineRegisterInfo &MRI, const TargetRegisterInfo &TRI, - const RegisterBankInfo &RBI) { - unsigned DstReg = I.getOperand(0).getReg(); - if (TargetRegisterInfo::isPhysicalRegister(DstReg)) - return true; - - const RegisterBank *RegBank = RBI.getRegBank(DstReg, MRI, TRI); - (void)RegBank; +static const TargetRegisterClass *guessRegClass(unsigned Reg, + MachineRegisterInfo &MRI, + const TargetRegisterInfo &TRI, + const RegisterBankInfo &RBI) { + const RegisterBank *RegBank = RBI.getRegBank(Reg, MRI, TRI); assert(RegBank && "Can't get reg bank for virtual register"); - const unsigned DstSize = MRI.getType(DstReg).getSizeInBits(); + const unsigned Size = MRI.getType(Reg).getSizeInBits(); assert((RegBank->getID() == ARM::GPRRegBankID || RegBank->getID() == ARM::FPRRegBankID) && "Unsupported reg bank"); - const TargetRegisterClass *RC = &ARM::GPRRegClass; - if (RegBank->getID() == ARM::FPRRegBankID) { - if (DstSize == 32) - RC = &ARM::SPRRegClass; - else if (DstSize == 64) - RC = &ARM::DPRRegClass; + if (Size == 32) + return &ARM::SPRRegClass; + else if (Size == 64) + return &ARM::DPRRegClass; else llvm_unreachable("Unsupported destination size"); } + return &ARM::GPRRegClass; +} + +static bool selectCopy(MachineInstr &I, const TargetInstrInfo &TII, + MachineRegisterInfo &MRI, const TargetRegisterInfo &TRI, + const RegisterBankInfo &RBI) { + unsigned DstReg = I.getOperand(0).getReg(); + if (TargetRegisterInfo::isPhysicalRegister(DstReg)) + return true; + + const TargetRegisterClass *RC = guessRegClass(DstReg, MRI, TRI, RBI); + // No need to constrain SrcReg. It will get constrained when // we hit another of its uses or its defs. // Copies do not have constraints. @@ -935,6 +941,17 @@ bool ARMInstructionSelector::select(MachineInstr &I, I.eraseFromParent(); return true; } + case G_PHI: { + I.setDesc(TII.get(PHI)); + + unsigned DstReg = I.getOperand(0).getReg(); + const TargetRegisterClass *RC = guessRegClass(DstReg, MRI, TRI, RBI); + if (!RBI.constrainGenericRegister(DstReg, *RC, MRI)) { + break; + } + + return true; + } default: return false; } diff --git a/llvm/test/CodeGen/ARM/GlobalISel/arm-instruction-select.mir b/llvm/test/CodeGen/ARM/GlobalISel/arm-instruction-select.mir index b6db0e0a75f..eaac829cab8 100644 --- a/llvm/test/CodeGen/ARM/GlobalISel/arm-instruction-select.mir +++ b/llvm/test/CodeGen/ARM/GlobalISel/arm-instruction-select.mir @@ -58,6 +58,9 @@ define void @test_br() { ret void } + define void @test_phi_s32() { ret void } + define void @test_phi_s64() #0 { ret void } + define void @test_soft_fp_double() #0 { ret void } attributes #0 = { "target-features"="+vfp2,-neonfp" } @@ -1308,6 +1311,98 @@ body: | ; CHECK: BX_RET 14, %noreg ... --- +name: test_phi_s32 +# CHECK-LABEL: name: test_phi_s32 +legalized: true +regBankSelected: true +selected: false +# CHECK: selected: true +tracksRegLiveness: true +registers: + - { id: 0, class: gprb } + - { id: 1, class: gprb } + - { id: 2, class: gprb } + - { id: 3, class: gprb } + - { id: 4, class: gprb } +body: | + bb.0: + ; CHECK: [[BB1:bb.0]]: + successors: %bb.1(0x40000000), %bb.2(0x40000000) + liveins: %r0, %r1, %r2 + + %0(s32) = COPY %r0 + %1(s1) = G_TRUNC %0(s32) + + %2(s32) = COPY %r1 + %3(s32) = COPY %r2 + ; CHECK: [[V1:%[0-9]+]]:gpr = COPY %r1 + ; CHECK: [[V2:%[0-9]+]]:gpr = COPY %r2 + + G_BRCOND %1(s1), %bb.1 + G_BR %bb.2 + + bb.1: + ; CHECK: [[BB2:bb.1]]: + successors: %bb.2(0x80000000) + + G_BR %bb.2 + ; CHECK: B %bb.2 + + bb.2: + ; CHECK: bb.2 + %4(s32) = G_PHI %2(s32), %bb.0, %3(s32), %bb.1 + ; CHECK: {{%[0-9]+}}:gpr = PHI [[V1]], %[[BB1]], [[V2]], %[[BB2]] + + %r0 = COPY %4(s32) + BX_RET 14, %noreg, implicit %r0 +... +--- +name: test_phi_s64 +# CHECK-LABEL: name: test_phi_s64 +legalized: true +regBankSelected: true +selected: false +# CHECK: selected: true +tracksRegLiveness: true +registers: + - { id: 0, class: gprb } + - { id: 1, class: gprb } + - { id: 2, class: fprb } + - { id: 3, class: fprb } + - { id: 4, class: fprb } +body: | + bb.0: + ; CHECK: [[BB1:bb.0]]: + successors: %bb.1(0x40000000), %bb.2(0x40000000) + liveins: %r0, %d0, %d1 + + %0(s32) = COPY %r0 + %1(s1) = G_TRUNC %0(s32) + + %2(s64) = COPY %d0 + %3(s64) = COPY %d1 + ; CHECK: [[V1:%[0-9]+]]:dpr = COPY %d0 + ; CHECK: [[V2:%[0-9]+]]:dpr = COPY %d1 + + G_BRCOND %1(s1), %bb.1 + G_BR %bb.2 + + bb.1: + ; CHECK: [[BB2:bb.1]]: + successors: %bb.2(0x80000000) + + G_BR %bb.2 + ; CHECK: B %bb.2 + + bb.2: + ; CHECK: bb.2 + %4(s64) = G_PHI %2(s64), %bb.0, %3(s64), %bb.1 + ; CHECK: {{%[0-9]+}}:dpr = PHI [[V1]], %[[BB1]], [[V2]], %[[BB2]] + + %d0 = COPY %4(s64) + BX_RET 14, %noreg, implicit %d0 +... +--- name: test_soft_fp_double # CHECK-LABEL: name: test_soft_fp_double legalized: true |