summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorQuentin Colombet <qcolombet@apple.com>2018-01-29 23:42:37 +0000
committerQuentin Colombet <qcolombet@apple.com>2018-01-29 23:42:37 +0000
commit72f6d598414f5dfc15bd8798b6e8ad85f4ce25dd (patch)
tree01a751046af158658055cafba873960276379d6f
parent3ae38d271e1b5f7e221cffe3f08de0243469699b (diff)
downloadbcm5719-llvm-72f6d598414f5dfc15bd8798b6e8ad85f4ce25dd.tar.gz
bcm5719-llvm-72f6d598414f5dfc15bd8798b6e8ad85f4ce25dd.zip
[RAFast] Don't dereference MBB::end
When RAFast sees liveins in on a basic block, it uses that information to initialize the availability of the registers. The called method uses an instruction as one of its argument and in the liveins case, RAFast was dereferencing MBB::begin which can be MBB::end for empty basic block. Change the API of definePhysReg to use MachineBasicBlock::iterator instead of MachineInstr so that we don't dereference an invalid iterator while making the call. rdar://problem/36952401 llvm-svn: 323710
-rw-r--r--llvm/lib/CodeGen/RegAllocFast.cpp11
-rw-r--r--llvm/test/CodeGen/AArch64/fast-regalloc-empty-bb-with-liveins.mir26
2 files changed, 32 insertions, 5 deletions
diff --git a/llvm/lib/CodeGen/RegAllocFast.cpp b/llvm/lib/CodeGen/RegAllocFast.cpp
index 6a5282cbbbf..17d9492d942 100644
--- a/llvm/lib/CodeGen/RegAllocFast.cpp
+++ b/llvm/lib/CodeGen/RegAllocFast.cpp
@@ -193,9 +193,10 @@ namespace {
void spillVirtReg(MachineBasicBlock::iterator MI, unsigned VirtReg);
void usePhysReg(MachineOperand &MO);
- void definePhysReg(MachineInstr &MI, MCPhysReg PhysReg, RegState NewState);
+ void definePhysReg(MachineBasicBlock::iterator MI, MCPhysReg PhysReg,
+ RegState NewState);
unsigned calcSpillCost(MCPhysReg PhysReg) const;
- void assignVirtToPhysReg(LiveReg&, MCPhysReg PhysReg);
+ void assignVirtToPhysReg(LiveReg &, MCPhysReg PhysReg);
LiveRegMap::iterator findLiveVirtReg(unsigned VirtReg) {
return LiveVirtRegs.find(TargetRegisterInfo::virtReg2Index(VirtReg));
@@ -434,8 +435,8 @@ void RegAllocFast::usePhysReg(MachineOperand &MO) {
/// Mark PhysReg as reserved or free after spilling any virtregs. This is very
/// similar to defineVirtReg except the physreg is reserved instead of
/// allocated.
-void RegAllocFast::definePhysReg(MachineInstr &MI, MCPhysReg PhysReg,
- RegState NewState) {
+void RegAllocFast::definePhysReg(MachineBasicBlock::iterator MI,
+ MCPhysReg PhysReg, RegState NewState) {
markRegUsedInInstr(PhysReg);
switch (unsigned VirtReg = PhysRegState[PhysReg]) {
case regDisabled:
@@ -857,7 +858,7 @@ void RegAllocFast::allocateBasicBlock(MachineBasicBlock &MBB) {
// Add live-in registers as live.
for (const MachineBasicBlock::RegisterMaskPair LI : MBB.liveins())
if (MRI->isAllocatable(LI.PhysReg))
- definePhysReg(*MII, LI.PhysReg, regReserved);
+ definePhysReg(MII, LI.PhysReg, regReserved);
VirtDead.clear();
Coalesced.clear();
diff --git a/llvm/test/CodeGen/AArch64/fast-regalloc-empty-bb-with-liveins.mir b/llvm/test/CodeGen/AArch64/fast-regalloc-empty-bb-with-liveins.mir
new file mode 100644
index 00000000000..fc19173a176
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/fast-regalloc-empty-bb-with-liveins.mir
@@ -0,0 +1,26 @@
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
+# RUN: llc -mtriple aarch64-apple-ios -run-pass regallocfast -o - %s | FileCheck %s
+# This test used to crash the fast register alloc.
+# Basically, when a basic block has liveins, the fast regalloc
+# was deferencing the begin iterator of this block. However,
+# when this block is empty and it will just crashed!
+---
+name: crashing
+tracksRegLiveness: true
+body: |
+ ; CHECK-LABEL: name: crashing
+ ; CHECK: bb.0:
+ ; CHECK: successors: %bb.1(0x80000000)
+ ; CHECK: liveins: %x0, %x1
+ ; CHECK: bb.1:
+ ; CHECK: renamable %w0 = MOVi32imm -1
+ ; CHECK: RET_ReallyLR implicit killed %w0
+ bb.1:
+ liveins: %x0, %x1
+
+ bb.2:
+ %0:gpr32 = MOVi32imm -1
+ %w0 = COPY %0
+ RET_ReallyLR implicit %w0
+
+...
OpenPOWER on IntegriCloud