From 2eb18d3c4bd7f0014b4b372ab137249f4fff26cf Mon Sep 17 00:00:00 2001 From: Tim Northover Date: Tue, 7 Mar 2017 21:24:33 +0000 Subject: 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 --- llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp | 33 ++++++++++++++----------- 1 file changed, 19 insertions(+), 14 deletions(-) (limited to 'llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp') 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); } -- cgit v1.2.3