summaryrefslogtreecommitdiffstats
path: root/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
diff options
context:
space:
mode:
authorTim Northover <tnorthover@apple.com>2017-03-07 21:24:33 +0000
committerTim Northover <tnorthover@apple.com>2017-03-07 21:24:33 +0000
commit2eb18d3c4bd7f0014b4b372ab137249f4fff26cf (patch)
tree46a4b4e97289e8978bd16406fa8843018392e83e /llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
parent7f81c3d495b7b4c3c692031becb47e3019690205 (diff)
downloadbcm5719-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.cpp33
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);
}
OpenPOWER on IntegriCloud