summaryrefslogtreecommitdiffstats
path: root/llvm
diff options
context:
space:
mode:
authorQuentin Colombet <qcolombet@apple.com>2015-05-21 21:41:55 +0000
committerQuentin Colombet <qcolombet@apple.com>2015-05-21 21:41:55 +0000
commit7b73bfa67a2aba68801d0d56e5b8edb380b3a532 (patch)
treea430d43c3903df8ceb2248b1acfc7902acf747bc /llvm
parentce8e5abbaf5cafccf44059c012c08424fe207ee3 (diff)
downloadbcm5719-llvm-7b73bfa67a2aba68801d0d56e5b8edb380b3a532.tar.gz
bcm5719-llvm-7b73bfa67a2aba68801d0d56e5b8edb380b3a532.zip
[InlineSpiller] Fix rematerialization for bundles.
Prior to this patch, we could update the operand of another MI in the same bundle. Longer version: Before InlineSpiller rematerializes a vreg, it iterates over operands of each MI in a bundle, collecting all (MI, OpNo) pairs that reference that vreg. Then if it does rematerialize, it goes through the pair list and replaces the operands with the new (rematerialized) vreg. The problem is, it tries to replace all of these operands in the main MI ! This works fine for single MIs. However, if we are processing a bundle of MIs and the list contains multiple pairs - the rematerialization will either crash trying to access a non-existing operand of the main MI, or silently corrupt one of the existing ones. It will also ignore other MIs in the bundle. The obvious fix is to use the MI pointers saved in collected (MI, OpNo) pairs. This must have been the original intent of the pair list but somehow these pointers got lost. Patch by Dmitri Shtilman <dshtilman@icloud.com>! Differential revision: http://reviews.llvm.org/D9904 <rdar://problem/21002163> llvm-svn: 237964
Diffstat (limited to 'llvm')
-rw-r--r--llvm/lib/CodeGen/InlineSpiller.cpp3
1 files changed, 2 insertions, 1 deletions
diff --git a/llvm/lib/CodeGen/InlineSpiller.cpp b/llvm/lib/CodeGen/InlineSpiller.cpp
index 59a92890f5a..9989f233d09 100644
--- a/llvm/lib/CodeGen/InlineSpiller.cpp
+++ b/llvm/lib/CodeGen/InlineSpiller.cpp
@@ -921,7 +921,7 @@ bool InlineSpiller::reMaterializeFor(LiveInterval &VirtReg,
// Replace operands
for (unsigned i = 0, e = Ops.size(); i != e; ++i) {
- MachineOperand &MO = MI->getOperand(Ops[i].second);
+ MachineOperand &MO = Ops[i].first->getOperand(Ops[i].second);
if (MO.isReg() && MO.isUse() && MO.getReg() == VirtReg.reg) {
MO.setReg(NewVReg);
MO.setIsKill();
@@ -1100,6 +1100,7 @@ foldMemoryOperand(ArrayRef<std::pair<MachineInstr*, unsigned> > Ops,
SmallVector<unsigned, 8> FoldOps;
for (unsigned i = 0, e = Ops.size(); i != e; ++i) {
unsigned Idx = Ops[i].second;
+ assert(MI == Ops[i].first && "Instruction conflict during operand folding");
MachineOperand &MO = MI->getOperand(Idx);
if (MO.isImplicit()) {
ImpReg = MO.getReg();
OpenPOWER on IntegriCloud