summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJustin Bogner <mail@justinbogner.com>2016-03-25 20:03:28 +0000
committerJustin Bogner <mail@justinbogner.com>2016-03-25 20:03:28 +0000
commitec0e7d2582abe0169ebde8fb2105d998bdc79d4d (patch)
treed9990be2bf10faa272120b8d12f65b236f501e96
parent750a90df6ab4d119fe0fab51715464dad5ebaf2b (diff)
downloadbcm5719-llvm-ec0e7d2582abe0169ebde8fb2105d998bdc79d4d.tar.gz
bcm5719-llvm-ec0e7d2582abe0169ebde8fb2105d998bdc79d4d.zip
CodeGen: Don't iterate over operands after we've erased an MI
This fixes a use-after-free introduced 3 years ago, in r182872 ;) The code more or less worked because the memory that CopyMI was pointing to happened to still be valid, but lots of tests would crash if you ran under ASAN with the recycling allocator changes from llvm.org/PR26808 llvm-svn: 264455
-rw-r--r--llvm/lib/CodeGen/RegisterCoalescer.cpp33
1 files changed, 20 insertions, 13 deletions
diff --git a/llvm/lib/CodeGen/RegisterCoalescer.cpp b/llvm/lib/CodeGen/RegisterCoalescer.cpp
index 18cbad59ad4..42e56521932 100644
--- a/llvm/lib/CodeGen/RegisterCoalescer.cpp
+++ b/llvm/lib/CodeGen/RegisterCoalescer.cpp
@@ -979,6 +979,23 @@ bool RegisterCoalescer::reMaterializeTrivialDef(const CoalescerPair &CP,
}
}
+ // CopyMI may have implicit operands, save them so that we can transfer them
+ // over to the newly materialized instruction after CopyMI is removed.
+ SmallVector<MachineOperand, 4> ImplicitOps;
+ ImplicitOps.reserve(CopyMI->getNumOperands() -
+ CopyMI->getDesc().getNumOperands());
+ for (unsigned I = CopyMI->getDesc().getNumOperands(),
+ E = CopyMI->getNumOperands();
+ I != E; ++I) {
+ MachineOperand &MO = CopyMI->getOperand(I);
+ if (MO.isReg()) {
+ assert(MO.isImplicit() && "No explicit operands after implict operands.");
+ // Discard VReg implicit defs.
+ if (TargetRegisterInfo::isPhysicalRegister(MO.getReg()))
+ ImplicitOps.push_back(MO);
+ }
+ }
+
LIS->ReplaceMachineInstrInMaps(*CopyMI, *NewMI);
CopyMI->eraseFromParent();
ErasedInstrs.insert(CopyMI);
@@ -1082,19 +1099,9 @@ bool RegisterCoalescer::reMaterializeTrivialDef(const CoalescerPair &CP,
if (NewMI->getOperand(0).getSubReg())
NewMI->getOperand(0).setIsUndef();
- // CopyMI may have implicit operands, transfer them over to the newly
- // rematerialized instruction. And update implicit def interval valnos.
- for (unsigned i = CopyMI->getDesc().getNumOperands(),
- e = CopyMI->getNumOperands(); i != e; ++i) {
- MachineOperand &MO = CopyMI->getOperand(i);
- if (MO.isReg()) {
- assert(MO.isImplicit() && "No explicit operands after implict operands.");
- // Discard VReg implicit defs.
- if (TargetRegisterInfo::isPhysicalRegister(MO.getReg())) {
- NewMI->addOperand(MO);
- }
- }
- }
+ // Transfer over implicit operands to the rematerialized instruction.
+ for (MachineOperand &MO : ImplicitOps)
+ NewMI->addOperand(MO);
SlotIndex NewMIIdx = LIS->getInstructionIndex(*NewMI);
for (unsigned i = 0, e = NewMIImplDefs.size(); i != e; ++i) {
OpenPOWER on IntegriCloud