diff options
Diffstat (limited to 'llvm')
| -rw-r--r-- | llvm/lib/Target/AArch64/AArch64RegisterBankInfo.cpp | 54 | ||||
| -rw-r--r-- | llvm/test/CodeGen/AArch64/GlobalISel/regbankselect-default.mir | 217 |
2 files changed, 253 insertions, 18 deletions
diff --git a/llvm/lib/Target/AArch64/AArch64RegisterBankInfo.cpp b/llvm/lib/Target/AArch64/AArch64RegisterBankInfo.cpp index 12fdb0d9cc6..15aef07a031 100644 --- a/llvm/lib/Target/AArch64/AArch64RegisterBankInfo.cpp +++ b/llvm/lib/Target/AArch64/AArch64RegisterBankInfo.cpp @@ -171,25 +171,43 @@ void AArch64RegisterBankInfo::applyMappingImpl( RegisterBankInfo::InstructionMapping AArch64RegisterBankInfo::getInstrMapping(const MachineInstr &MI) const { - RegisterBankInfo::InstructionMapping Mapping = getInstrMappingImpl(MI); - if (Mapping.isValid()) - return Mapping; - - // As a top-level guess, vectors go in FPRs, scalars in GPRs. Obviously this - // won't work for normal floating-point types (or NZCV). When such - // instructions exist we'll need to look at the MI's opcode. - auto &MRI = MI.getParent()->getParent()->getRegInfo(); - LLT Ty = MRI.getType(MI.getOperand(0).getReg()); - unsigned BankID; - if (Ty.isVector()) - BankID = AArch64::FPRRegBankID; - else - BankID = AArch64::GPRRegBankID; - - Mapping = InstructionMapping{DefaultMappingID, 1, MI.getNumOperands()}; - int Size = Ty.isValid() ? Ty.getSizeInBits() : 0; + const unsigned Opc = MI.getOpcode(); + const MachineFunction &MF = *MI.getParent()->getParent(); + const MachineRegisterInfo &MRI = MF.getRegInfo(); + + // Try the default logic for non-generic instructions that are either copies + // or already have some operands assigned to banks. + if (!isPreISelGenericOpcode(Opc)) { + RegisterBankInfo::InstructionMapping Mapping = getInstrMappingImpl(MI); + if (Mapping.isValid()) + return Mapping; + } + + RegisterBankInfo::InstructionMapping Mapping = + InstructionMapping{DefaultMappingID, 1, MI.getNumOperands()}; + + // Track the size and bank of each register. We don't do partial mappings. + SmallVector<unsigned, 4> OpSizes(MI.getNumOperands()); + SmallVector<unsigned, 4> OpBanks(MI.getNumOperands()); + for (unsigned Idx = 0; Idx < MI.getNumOperands(); ++Idx) { + auto &MO = MI.getOperand(Idx); + if (!MO.isReg()) + continue; + + LLT Ty = MRI.getType(MO.getReg()); + OpSizes[Idx] = Ty.getSizeInBits(); + + // As a top-level guess, vectors go in FPRs, scalars and pointers in GPRs. + if (Ty.isVector()) + OpBanks[Idx] = AArch64::FPRRegBankID; + else + OpBanks[Idx] = AArch64::GPRRegBankID; + } + + // Finally construct the computed mapping. for (unsigned Idx = 0; Idx < MI.getNumOperands(); ++Idx) - Mapping.setOperandMapping(Idx, Size, getRegBank(BankID)); + if (MI.getOperand(Idx).isReg()) + Mapping.setOperandMapping(Idx, OpSizes[Idx], getRegBank(OpBanks[Idx])); return Mapping; } diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/regbankselect-default.mir b/llvm/test/CodeGen/AArch64/GlobalISel/regbankselect-default.mir index d9aaac978ce..12edd40dd44 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/regbankselect-default.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/regbankselect-default.mir @@ -26,6 +26,25 @@ define void @test_sdiv_s32() { ret void } define void @test_udiv_s32() { ret void } + + define void @test_anyext_s64_s32() { ret void } + define void @test_sext_s64_s32() { ret void } + define void @test_zext_s64_s32() { ret void } + define void @test_trunc_s32_s64() { ret void } + + define void @test_constant_s32() { ret void } + define void @test_constant_p0() { ret void } + + define void @test_frame_index_p0() { + %ptr0 = alloca i64 + ret void + } + + define void @test_ptrtoint_s64_p0() { ret void } + define void @test_inttoptr_p0_s64() { ret void } + + define void @test_load_s32_p0() { ret void } + define void @test_store_s32_p0() { ret void } ... --- @@ -369,3 +388,201 @@ body: | %0(s32) = COPY %w0 %1(s32) = G_UDIV %0, %0 ... + +--- +# CHECK-LABEL: name: test_anyext_s64_s32 +name: test_anyext_s64_s32 +legalized: true +# CHECK: registers: +# CHECK: - { id: 0, class: gpr } +# CHECK: - { id: 1, class: gpr } +registers: + - { id: 0, class: _ } + - { id: 1, class: _ } +body: | + bb.0: + liveins: %w0 + ; CHECK: %0(s32) = COPY %w0 + ; CHECK: %1(s64) = G_ANYEXT %0 + %0(s32) = COPY %w0 + %1(s64) = G_ANYEXT %0 +... + +--- +# CHECK-LABEL: name: test_sext_s64_s32 +name: test_sext_s64_s32 +legalized: true +# CHECK: registers: +# CHECK: - { id: 0, class: gpr } +# CHECK: - { id: 1, class: gpr } +registers: + - { id: 0, class: _ } + - { id: 1, class: _ } +body: | + bb.0: + liveins: %w0 + ; CHECK: %0(s32) = COPY %w0 + ; CHECK: %1(s64) = G_SEXT %0 + %0(s32) = COPY %w0 + %1(s64) = G_SEXT %0 +... + +--- +# CHECK-LABEL: name: test_zext_s64_s32 +name: test_zext_s64_s32 +legalized: true +# CHECK: registers: +# CHECK: - { id: 0, class: gpr } +# CHECK: - { id: 1, class: gpr } +registers: + - { id: 0, class: _ } + - { id: 1, class: _ } +body: | + bb.0: + liveins: %w0 + ; CHECK: %0(s32) = COPY %w0 + ; CHECK: %1(s64) = G_ZEXT %0 + %0(s32) = COPY %w0 + %1(s64) = G_ZEXT %0 +... + +--- +# CHECK-LABEL: name: test_trunc_s32_s64 +name: test_trunc_s32_s64 +legalized: true +# CHECK: registers: +# CHECK: - { id: 0, class: gpr } +# CHECK: - { id: 1, class: gpr } +registers: + - { id: 0, class: _ } + - { id: 1, class: _ } +body: | + bb.0: + liveins: %x0 + ; CHECK: %0(s64) = COPY %x0 + ; CHECK: %1(s32) = G_TRUNC %0 + %0(s64) = COPY %x0 + %1(s32) = G_TRUNC %0 +... + +--- +# CHECK-LABEL: name: test_constant_s32 +name: test_constant_s32 +legalized: true +# CHECK: registers: +# CHECK: - { id: 0, class: gpr } +registers: + - { id: 0, class: _ } +body: | + bb.0: + ; CHECK: %0(s32) = G_CONSTANT 123 + %0(s32) = G_CONSTANT 123 +... + +--- +# CHECK-LABEL: name: test_constant_p0 +name: test_constant_p0 +legalized: true +# CHECK: registers: +# CHECK: - { id: 0, class: gpr } +registers: + - { id: 0, class: _ } +body: | + bb.0: + ; CHECK: %0(p0) = G_CONSTANT 0 + %0(p0) = G_CONSTANT 0 +... + +--- +# CHECK-LABEL: name: test_frame_index_p0 +name: test_frame_index_p0 +legalized: true +# CHECK: registers: +# CHECK: - { id: 0, class: gpr } +registers: + - { id: 0, class: _ } +stack: + - { id: 0, name: ptr0, offset: 0, size: 8, alignment: 8 } +body: | + bb.0: + ; CHECK: %0(p0) = G_FRAME_INDEX %stack.0.ptr0 + %0(p0) = G_FRAME_INDEX %stack.0.ptr0 +... + +--- +# CHECK-LABEL: name: test_ptrtoint_s64_p0 +name: test_ptrtoint_s64_p0 +legalized: true +# CHECK: registers: +# CHECK: - { id: 0, class: gpr } +# CHECK: - { id: 1, class: gpr } +registers: + - { id: 0, class: _ } + - { id: 1, class: _ } +body: | + bb.0: + liveins: %x0 + ; CHECK: %0(p0) = COPY %x0 + ; CHECK: %1(s64) = G_PTRTOINT %0 + %0(p0) = COPY %x0 + %1(s64) = G_PTRTOINT %0 +... + +--- +# CHECK-LABEL: name: test_inttoptr_p0_s64 +name: test_inttoptr_p0_s64 +legalized: true +# CHECK: registers: +# CHECK: - { id: 0, class: gpr } +# CHECK: - { id: 1, class: gpr } +registers: + - { id: 0, class: _ } + - { id: 1, class: _ } +body: | + bb.0: + liveins: %x0 + ; CHECK: %0(s64) = COPY %x0 + ; CHECK: %1(p0) = G_INTTOPTR %0 + %0(s64) = COPY %x0 + %1(p0) = G_INTTOPTR %0 +... + +--- +# CHECK-LABEL: name: test_load_s32_p0 +name: test_load_s32_p0 +legalized: true +# CHECK: registers: +# CHECK: - { id: 0, class: gpr } +# CHECK: - { id: 1, class: gpr } +registers: + - { id: 0, class: _ } + - { id: 1, class: _ } +body: | + bb.0: + liveins: %x0 + ; CHECK: %0(p0) = COPY %x0 + ; CHECK: %1(s32) = G_LOAD %0 + %0(p0) = COPY %x0 + %1(s32) = G_LOAD %0 +... + +--- +# CHECK-LABEL: name: test_store_s32_p0 +name: test_store_s32_p0 +legalized: true +# CHECK: registers: +# CHECK: - { id: 0, class: gpr } +# CHECK: - { id: 1, class: gpr } +registers: + - { id: 0, class: _ } + - { id: 1, class: _ } +body: | + bb.0: + liveins: %x0, %w1 + ; CHECK: %0(p0) = COPY %x0 + ; CHECK: %1(s32) = COPY %w1 + ; CHECK: G_STORE %1(s32), %0(p0) + %0(p0) = COPY %x0 + %1(s32) = COPY %w1 + G_STORE %1, %0 +... |

