[llvm] r281734 - [AArch64][GlobalISel] Add default regbank mappings for mixed-type ops.

Ahmed Bougacha via llvm-commits llvm-commits at lists.llvm.org
Fri Sep 16 07:44:51 PDT 2016


Author: ab
Date: Fri Sep 16 09:44:51 2016
New Revision: 281734

URL: http://llvm.org/viewvc/llvm-project?rev=281734&view=rev
Log:
[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.

Modified:
    llvm/trunk/lib/Target/AArch64/AArch64RegisterBankInfo.cpp
    llvm/trunk/test/CodeGen/AArch64/GlobalISel/regbankselect-default.mir

Modified: llvm/trunk/lib/Target/AArch64/AArch64RegisterBankInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AArch64RegisterBankInfo.cpp?rev=281734&r1=281733&r2=281734&view=diff
==============================================================================
--- llvm/trunk/lib/Target/AArch64/AArch64RegisterBankInfo.cpp (original)
+++ llvm/trunk/lib/Target/AArch64/AArch64RegisterBankInfo.cpp Fri Sep 16 09:44:51 2016
@@ -171,25 +171,43 @@ void AArch64RegisterBankInfo::applyMappi
 
 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;
+  const unsigned Opc = MI.getOpcode();
+  const MachineFunction &MF = *MI.getParent()->getParent();
+  const MachineRegisterInfo &MRI = MF.getRegInfo();
 
-  Mapping = InstructionMapping{DefaultMappingID, 1, MI.getNumOperands()};
-  int Size = Ty.isValid() ? Ty.getSizeInBits() : 0;
+  // 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;
 }

Modified: llvm/trunk/test/CodeGen/AArch64/GlobalISel/regbankselect-default.mir
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/AArch64/GlobalISel/regbankselect-default.mir?rev=281734&r1=281733&r2=281734&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/AArch64/GlobalISel/regbankselect-default.mir (original)
+++ llvm/trunk/test/CodeGen/AArch64/GlobalISel/regbankselect-default.mir Fri Sep 16 09:44:51 2016
@@ -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
+...




More information about the llvm-commits mailing list