GlobalISel: Implement narrowing for G_STORE
Legalize stores of types that are too wide by breaking them up into
sequences of smaller stores.
llvm-svn: 292412
diff --git a/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp b/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
index eb25b6c..bb4f2cf 100644
--- a/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
@@ -125,6 +125,9 @@
// 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 @@
int NumParts = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits() /
NarrowTy.getSizeInBits();
- MIRBuilder.setInstr(MI);
-
SmallVector<unsigned, 2> Src1Regs, Src2Regs, DstRegs;
SmallVector<uint64_t, 2> Indexes;
extractParts(MI.getOperand(1).getReg(), NarrowTy, NumParts, Src1Regs);
@@ -160,6 +161,26 @@
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<unsigned, 2> 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;
+ }
}
}