From 4a6dec640839a6fba799f1a553934f51dcd977e1 Mon Sep 17 00:00:00 2001 From: Justin Bogner Date: Wed, 18 Jan 2017 17:29:54 +0000 Subject: [PATCH] GlobalISel: Implement narrowing for G_STORE Legalize stores of types that are too wide by breaking them up into sequences of smaller stores. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@292412 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/GlobalISel/LegalizerHelper.cpp | 25 ++++++++++++++++++++-- .../AArch64/GlobalISel/legalize-load-store.mir | 12 +++++++++++ 2 files changed, 35 insertions(+), 2 deletions(-) diff --git a/lib/CodeGen/GlobalISel/LegalizerHelper.cpp b/lib/CodeGen/GlobalISel/LegalizerHelper.cpp index eb25b6ca268..bb4f2cf20db 100644 --- a/lib/CodeGen/GlobalISel/LegalizerHelper.cpp +++ b/lib/CodeGen/GlobalISel/LegalizerHelper.cpp @@ -125,6 +125,9 @@ LegalizerHelper::LegalizeResult LegalizerHelper::narrowScalar(MachineInstr &MI, // FIXME: Don't know how to handle secondary types yet. if (TypeIdx != 0) return UnableToLegalize; + + MIRBuilder.setInstr(MI); + switch (MI.getOpcode()) { default: return UnableToLegalize; @@ -134,8 +137,6 @@ LegalizerHelper::LegalizeResult LegalizerHelper::narrowScalar(MachineInstr &MI, int NumParts = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits() / NarrowTy.getSizeInBits(); - MIRBuilder.setInstr(MI); - SmallVector Src1Regs, Src2Regs, DstRegs; SmallVector Indexes; extractParts(MI.getOperand(1).getReg(), NarrowTy, NumParts, Src1Regs); @@ -160,6 +161,26 @@ LegalizerHelper::LegalizeResult LegalizerHelper::narrowScalar(MachineInstr &MI, MI.eraseFromParent(); return Legalized; } + case TargetOpcode::G_STORE: { + 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 SrcRegs; + extractParts(MI.getOperand(0).getReg(), NarrowTy, NumParts, SrcRegs); + + for (int i = 0; i < NumParts; ++i) { + unsigned DstReg = MRI.createGenericVirtualRegister(NarrowPtrTy); + unsigned Offset = MRI.createGenericVirtualRegister(LLT::scalar(64)); + MIRBuilder.buildConstant(Offset, i * NarrowSize / 8); + MIRBuilder.buildGEP(DstReg, MI.getOperand(1).getReg(), Offset); + MIRBuilder.buildStore(SrcRegs[i], DstReg, **MI.memoperands_begin()); + } + MI.eraseFromParent(); + return Legalized; + } } } diff --git a/test/CodeGen/AArch64/GlobalISel/legalize-load-store.mir b/test/CodeGen/AArch64/GlobalISel/legalize-load-store.mir index 6a86686fa4b..30636d33f47 100644 --- a/test/CodeGen/AArch64/GlobalISel/legalize-load-store.mir +++ b/test/CodeGen/AArch64/GlobalISel/legalize-load-store.mir @@ -62,6 +62,8 @@ registers: - { id: 3, class: _ } - { id: 4, class: _ } - { id: 5, class: _ } + - { id: 6, class: _ } + - { id: 7, class: _ } body: | bb.0.entry: liveins: %x0, %x1, %x2, %x3 @@ -92,4 +94,14 @@ body: | ; CHECK: G_STORE %0(p0), %0(p0) :: (store 8 into %ir.addr) G_STORE %0(p0), %0(p0) :: (store 8 into %ir.addr) + + ; CHECK: [[OFFSET0:%[0-9]+]](s64) = G_CONSTANT i64 0 + ; CHECK: [[GEP0:%[0-9]+]](p0) = G_GEP %0, [[OFFSET0]](s64) + ; CHECK: G_STORE %5(s64), [[GEP0]](p0) :: (store 16 into %ir.addr) + ; CHECK: [[OFFSET1:%[0-9]+]](s64) = G_CONSTANT i64 8 + ; CHECK: [[GEP1:%[0-9]+]](p0) = G_GEP %0, [[OFFSET1]](s64) + ; CHECK: G_STORE %6(s64), [[GEP1]](p0) :: (store 16 into %ir.addr) + %6(s64) = G_PTRTOINT %0(p0) + %7(s128) = G_SEQUENCE %5, 0, %6, 64 + G_STORE %7, %0 :: (store 16 into %ir.addr) ... -- 2.11.0