diff options
author | Tim Northover <tnorthover@apple.com> | 2017-03-07 21:24:33 +0000 |
---|---|---|
committer | Tim Northover <tnorthover@apple.com> | 2017-03-07 21:24:33 +0000 |
commit | 2eb18d3c4bd7f0014b4b372ab137249f4fff26cf (patch) | |
tree | 46a4b4e97289e8978bd16406fa8843018392e83e /llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp | |
parent | 7f81c3d495b7b4c3c692031becb47e3019690205 (diff) | |
download | bcm5719-llvm-2eb18d3c4bd7f0014b4b372ab137249f4fff26cf.tar.gz bcm5719-llvm-2eb18d3c4bd7f0014b4b372ab137249f4fff26cf.zip |
GlobalISel: fix legalization of G_INSERT
We were calculating incorrect extract/insert offsets by trying to be too
tricksy with min/max. It's clearer to just split the logic up into "register
starts before this segment" vs "after".
llvm-svn: 297226
Diffstat (limited to 'llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp')
-rw-r--r-- | llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp | 33 |
1 files changed, 19 insertions, 14 deletions
diff --git a/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp b/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp index d1f31607401..6e83270cbef 100644 --- a/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp +++ b/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp @@ -195,24 +195,29 @@ LegalizerHelper::LegalizeResult LegalizerHelper::narrowScalar(MachineInstr &MI, continue; } - int64_t OpSegStart = DstStart - OpStart; - int64_t OpSegSize = - std::min(NarrowSize - OpSegStart, OpSegStart + OpSize); - unsigned OpSegReg = OpReg; - if (OpSegSize != OpSize) { + // OpSegStart is where this destination segment would start in OpReg if it + // extended infinitely in both directions. + int64_t ExtractOffset, InsertOffset, SegSize; + if (OpStart < DstStart) { + InsertOffset = 0; + ExtractOffset = DstStart - OpStart; + SegSize = std::min(NarrowSize, OpStart + OpSize - DstStart); + } else { + InsertOffset = OpStart - DstStart; + ExtractOffset = 0; + SegSize = + std::min(NarrowSize - InsertOffset, OpStart + OpSize - DstStart); + } + + unsigned SegReg = OpReg; + if (ExtractOffset != 0 || SegSize != OpSize) { // A genuine extract is needed. - OpSegReg = MRI.createGenericVirtualRegister(LLT::scalar(OpSegSize)); - MIRBuilder.buildExtract(OpSegReg, OpReg, - std::max(OpSegStart, (int64_t)0)); + SegReg = MRI.createGenericVirtualRegister(LLT::scalar(SegSize)); + MIRBuilder.buildExtract(SegReg, OpReg, ExtractOffset); } unsigned DstReg = MRI.createGenericVirtualRegister(NarrowTy); - MIRBuilder.buildInstr(TargetOpcode::G_INSERT) - .addDef(DstReg) - .addUse(SrcRegs[i]) - .addUse(OpSegReg) - .addImm(std::max((int64_t)0, -OpSegStart)); - + MIRBuilder.buildInsert(DstReg, SrcRegs[i], SegReg, InsertOffset); DstRegs.push_back(DstReg); } |