OSDN Git Service

GlobalISel: Implement narrowing for G_LOAD
authorJustin Bogner <mail@justinbogner.com>
Thu, 19 Jan 2017 01:05:48 +0000 (01:05 +0000)
committerJustin Bogner <mail@justinbogner.com>
Thu, 19 Jan 2017 01:05:48 +0000 (01:05 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@292461 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/GlobalISel/LegalizerHelper.cpp
test/CodeGen/AArch64/GlobalISel/legalize-load-store.mir

index bb4f2cf..443c6e1 100644 (file)
@@ -161,6 +161,32 @@ LegalizerHelper::LegalizeResult LegalizerHelper::narrowScalar(MachineInstr &MI,
     MI.eraseFromParent();
     return Legalized;
   }
+  case TargetOpcode::G_LOAD: {
+    unsigned NarrowSize = NarrowTy.getSizeInBits();
+    int NumParts =
+        MRI.getType(MI.getOperand(0).getReg()).getSizeInBits() / NarrowSize;
+    LLT NarrowPtrTy = LLT::pointer(
+        MRI.getType(MI.getOperand(1).getReg()).getAddressSpace(), NarrowSize);
+
+    SmallVector<unsigned, 2> DstRegs;
+    SmallVector<uint64_t, 2> Indexes;
+    for (int i = 0; i < NumParts; ++i) {
+      unsigned DstReg = MRI.createGenericVirtualRegister(NarrowTy);
+      unsigned SrcReg = MRI.createGenericVirtualRegister(NarrowPtrTy);
+      unsigned Offset = MRI.createGenericVirtualRegister(LLT::scalar(64));
+
+      MIRBuilder.buildConstant(Offset, i * NarrowSize / 8);
+      MIRBuilder.buildGEP(SrcReg, MI.getOperand(1).getReg(), Offset);
+      MIRBuilder.buildLoad(DstReg, SrcReg, **MI.memoperands_begin());
+
+      DstRegs.push_back(DstReg);
+      Indexes.push_back(i * NarrowSize);
+    }
+    unsigned DstReg = MI.getOperand(0).getReg();
+    MIRBuilder.buildSequence(DstReg, DstRegs, Indexes);
+    MI.eraseFromParent();
+    return Legalized;
+  }
   case TargetOpcode::G_STORE: {
     unsigned NarrowSize = NarrowTy.getSizeInBits();
     int NumParts =
index 30636d3..00145ad 100644 (file)
@@ -24,6 +24,7 @@ registers:
   - { id: 5, class: _ }
   - { id: 6, class: _ }
   - { id: 7, class: _ }
+  - { id: 8, class: _ }
 body: |
   bb.0.entry:
     liveins: %x0, %x1, %x2, %x3
@@ -51,6 +52,15 @@ body: |
 
     ; CHECK: %7(<2 x s32>) = G_LOAD %0(p0) :: (load 8 from %ir.addr)
     %7(<2 x s32>) = G_LOAD %0(p0) :: (load 8 from %ir.addr)
+
+    ; CHECK: [[OFFSET0:%[0-9]+]](s64) = G_CONSTANT i64 0
+    ; CHECK: [[GEP0:%[0-9]+]](p0) = G_GEP %0, [[OFFSET0]](s64)
+    ; CHECK: [[LOAD0:%[0-9]+]](s64) = G_LOAD [[GEP0]](p0) :: (load 16 from %ir.addr)
+    ; CHECK: [[OFFSET1:%[0-9]+]](s64) = G_CONSTANT i64 8
+    ; CHECK: [[GEP1:%[0-9]+]](p0) = G_GEP %0, [[OFFSET1]](s64)
+    ; CHECK: [[LOAD1:%[0-9]+]](s64) = G_LOAD [[GEP1]](p0) :: (load 16 from %ir.addr)
+    ; CHECK: %8(s128) = G_SEQUENCE [[LOAD0]](s64), 0, [[LOAD1]](s64), 64
+    %8(s128) = G_LOAD %0(p0) :: (load 16 from %ir.addr)
 ...
 
 ---