Commit f48bf900 authored by Hans Wennborg's avatar Hans Wennborg
Browse files

Merging r308808, r308813 and r308906:

------------------------------------------------------------------------
r308808 | arsenm | 2017-07-21 16:56:13 -0700 (Fri, 21 Jul 2017) | 6 lines

RA: Remove assert on empty live intervals

This is possible if there is an undef use when
splitting the vreg during spilling.

Fixes bug 33620.
------------------------------------------------------------------------

------------------------------------------------------------------------
r308813 | arsenm | 2017-07-21 17:24:01 -0700 (Fri, 21 Jul 2017) | 6 lines

RA: Remove another assert on empty intervals

This case is similar to the one fixed in r308808,
except when rematerializing.

Fixes bug 33884.
------------------------------------------------------------------------

------------------------------------------------------------------------
r308906 | arsenm | 2017-07-24 11:07:55 -0700 (Mon, 24 Jul 2017) | 6 lines

RA: Replace asserts related to empty live intervals

These don't exactly assert the same thing anymore, and
allow empty live intervals with non-empty uses.

Removed in r308808 and r308813.
------------------------------------------------------------------------

llvm-svn: 309171
parent c4c93b74
Loading
Loading
Loading
Loading
+5 −2
Original line number Diff line number Diff line
@@ -643,8 +643,11 @@ void InlineSpiller::reMaterializeAll() {
      Edit->eraseVirtReg(Reg);
      continue;
    }
    assert((LIS.hasInterval(Reg) && !LIS.getInterval(Reg).empty()) &&
           "Reg with empty interval has reference");

    assert(LIS.hasInterval(Reg) &&
           (!LIS.getInterval(Reg).empty() || !MRI.reg_nodbg_empty(Reg)) &&
           "Empty and not used live-range?!");

    RegsToSpill[ResultPos++] = Reg;
  }
  RegsToSpill.erase(RegsToSpill.begin() + ResultPos, RegsToSpill.end());
+5 −4
Original line number Diff line number Diff line
@@ -133,18 +133,19 @@ void RegAllocBase::allocatePhysRegs() {
    if (AvailablePhysReg)
      Matrix->assign(*VirtReg, AvailablePhysReg);

    for (VirtRegVec::iterator I = SplitVRegs.begin(), E = SplitVRegs.end();
         I != E; ++I) {
      LiveInterval *SplitVirtReg = &LIS->getInterval(*I);
    for (unsigned Reg : SplitVRegs) {
      assert(LIS->hasInterval(Reg));

      LiveInterval *SplitVirtReg = &LIS->getInterval(Reg);
      assert(!VRM->hasPhys(SplitVirtReg->reg) && "Register already assigned");
      if (MRI->reg_nodbg_empty(SplitVirtReg->reg)) {
        assert(SplitVirtReg->empty() && "Non-empty but used interval");
        DEBUG(dbgs() << "not queueing unused  " << *SplitVirtReg << '\n');
        aboutToRemoveInterval(*SplitVirtReg);
        LIS->removeInterval(SplitVirtReg->reg);
        continue;
      }
      DEBUG(dbgs() << "queuing new interval: " << *SplitVirtReg << "\n");
      assert(!SplitVirtReg->empty() && "expecting non-empty interval");
      assert(TargetRegisterInfo::isVirtualRegister(SplitVirtReg->reg) &&
             "expect split value in virtual register");
      enqueue(SplitVirtReg);
+74 −0
Original line number Diff line number Diff line
# RUN: llc -mtriple=amdgcn-amd-amdhsa-opencl -verify-machineinstrs -stress-regalloc=1 -start-before=simple-register-coalescing -stop-after=greedy -o - %s | FileCheck %s
# https://bugs.llvm.org/show_bug.cgi?id=33620

---
# This would assert due to the empty live interval created for %vreg9
# on the last S_NOP with an undef subreg use.

# CHECK-LABEL: name: expecting_non_empty_interval

# CHECK: undef %7.sub1 = V_MAC_F32_e32 0, undef %1, undef %7.sub1, implicit %exec
# CHECK-NEXT: SI_SPILL_V64_SAVE %7, %stack.0, %sgpr0_sgpr1_sgpr2_sgpr3, %sgpr5, 0, implicit %exec :: (store 8 into %stack.0, align 4)
# CHECK-NEXT: undef %5.sub1 = V_MOV_B32_e32 1786773504, implicit %exec
# CHECK-NEXT: dead %2 = V_MUL_F32_e32 0, %5.sub1, implicit %exec

# CHECK: S_NOP 0, implicit %6.sub1
# CHECK-NEXT: %8 = SI_SPILL_V64_RESTORE %stack.0, %sgpr0_sgpr1_sgpr2_sgpr3, %sgpr5, 0, implicit %exec :: (load 8 from %stack.0, align 4)
# CHECK-NEXT: S_NOP 0, implicit %8.sub1
# CHECK-NEXT: S_NOP 0, implicit undef %9.sub0

name: expecting_non_empty_interval
tracksRegLiveness: true
registers:
  - { id: 0, class: vreg_64, preferred-register: '' }
  - { id: 1, class: vgpr_32, preferred-register: '' }
  - { id: 2, class: vgpr_32, preferred-register: '' }
  - { id: 3, class: vreg_64, preferred-register: '' }
body:             |
  bb.0:
    successors: %bb.1
    undef %0.sub1 = V_MAC_F32_e32 0, undef %1, undef %0.sub1, implicit %exec
    undef %3.sub1 = V_MOV_B32_e32 1786773504, implicit %exec
    dead %2 = V_MUL_F32_e32 0, %3.sub1, implicit %exec

  bb.1:
    S_NOP 0, implicit %3.sub1
    S_NOP 0, implicit %0.sub1
    S_NOP 0, implicit undef %0.sub0
    S_ENDPGM

...

# Similar assert which happens when trying to rematerialize.
# https://bugs.llvm.org/show_bug.cgi?id=33884
---
# CHECK-LABEL: name: rematerialize_empty_interval_has_reference

# CHECK-NOT: MOV
# CHECK: undef %3.sub2 = V_MOV_B32_e32 1786773504, implicit %exec

# CHECK: bb.1:
# CHECK-NEXT: S_NOP 0, implicit %3.sub2
# CHECK-NEXT: S_NOP 0, implicit undef %6.sub0
# CHECK-NEXT: undef %4.sub2 = V_MOV_B32_e32 0, implicit %exec
# CHECK-NEXT: S_NOP 0, implicit %4.sub2
name: rematerialize_empty_interval_has_reference
tracksRegLiveness: true
registers:
  - { id: 0, class: vreg_128, preferred-register: '' }
  - { id: 1, class: vgpr_32, preferred-register: '' }
  - { id: 2, class: vgpr_32, preferred-register: '' }
  - { id: 3, class: vreg_128, preferred-register: '' }
body:             |
  bb.0:
    successors: %bb.1

    undef %0.sub2 = V_MOV_B32_e32 0, implicit %exec
    undef %3.sub2 = V_MOV_B32_e32 1786773504, implicit %exec

  bb.1:
    S_NOP 0, implicit %3.sub2
    S_NOP 0, implicit undef %0.sub0
    S_NOP 0, implicit %0.sub2

...