From: Ahmed Bougacha Date: Fri, 16 Sep 2016 14:44:51 +0000 (+0000) Subject: [AArch64][GlobalISel] Add default regbank mappings for mixed-type ops. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=c3852f5056c5d9bade5ccb93627eb7b15c4697cf;p=llvm [AArch64][GlobalISel] Add default regbank mappings for mixed-type ops. We used to only support instructions with same-type operands. Instead, use the per-register type information to map each operand more accurately. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@281734 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Target/AArch64/AArch64RegisterBankInfo.cpp b/lib/Target/AArch64/AArch64RegisterBankInfo.cpp index 12fdb0d9cc6..15aef07a031 100644 --- a/lib/Target/AArch64/AArch64RegisterBankInfo.cpp +++ b/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 OpSizes(MI.getNumOperands()); + SmallVector 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/test/CodeGen/AArch64/GlobalISel/regbankselect-default.mir b/test/CodeGen/AArch64/GlobalISel/regbankselect-default.mir index d9aaac978ce..12edd40dd44 100644 --- a/test/CodeGen/AArch64/GlobalISel/regbankselect-default.mir +++ b/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 +...