Skip to content

Commit

Permalink
[LivePhysRegs] Remove registers clobbered by regmasks from the live set
Browse files Browse the repository at this point in the history
Dead defs were being removed from the live set (in stepForward), but
registers clobbered by regmasks weren't (more specifically, they were
actually removed by removeRegsInMask, but then they were added back in).


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@331219 91177308-0d34-0410-b5e6-96231b3b80d8
  • Loading branch information
Krzysztof Parzyszek committed Apr 30, 2018
1 parent 4d34462 commit 7d1c374
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 6 deletions.
6 changes: 5 additions & 1 deletion lib/CodeGen/LivePhysRegs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -106,9 +106,13 @@ void LivePhysRegs::stepForward(const MachineInstr &MI,

// Add defs to the set.
for (auto Reg : Clobbers) {
// Skip dead defs. They shouldn't be added to the set.
// Skip dead defs and registers clobbered by regmasks. They shouldn't
// be added to the set.
if (Reg.second->isReg() && Reg.second->isDead())
continue;
if (Reg.second->isRegMask() &&
MachineOperand::clobbersPhysReg(Reg.second->getRegMask(), Reg.first))
continue;
addReg(Reg.first);
}
}
Expand Down
5 changes: 0 additions & 5 deletions lib/Target/Hexagon/HexagonFrameLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1706,11 +1706,6 @@ bool HexagonFrameLowering::expandStoreVec2(MachineBasicBlock &B,
for (auto R = B.begin(); R != It; ++R) {
Clobbers.clear();
LPR.stepForward(*R, Clobbers);
// Dead defs are recorded in Clobbers, but are not automatically removed
// from the live set.
for (auto &C : Clobbers)
if (C.second->isReg() && C.second->isDead())
LPR.removeReg(C.first);
}

DebugLoc DL = MI->getDebugLoc();
Expand Down
39 changes: 39 additions & 0 deletions test/CodeGen/Hexagon/livephysregs-regmask-clobber.mir
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# RUN: llc -march=hexagon -verify-machineinstrs -run-pass prologepilog -o - %s | FileCheck %s

# The PS_vstorerw_ai of W0 would normally expand into stores of V0 and V1,
# but both are clobbered by the regmask. Only V0 is re-defined before the
# store, so only V0 should be stored. LivePhysRegs didn't correctly remove
# registers clobbered by regmasks, so V1 also appeared to be live and was
# stored as well. This resulted in the "using undefined physical register"
# error.

# This will fail to compile with -verify-machineinstrs, but we can also check
# directly if the output is correct.

# CHECK: J2_call &__hexagon_divsi3
# CHECK: $v0 = V6_lvsplatw
# CHECK: V6_vS32b_ai $r29, 128, {{.*}} $v0
# CHECK-NOT: V6_vS32b_ai $r29, 192, {{.*}} $v1

name: f0
tracksRegLiveness: true
stack:
- { id: 0, offset: 0, size: 128, alignment: 128 }
- { id: 1, offset: 128, size: 128, alignment: 128 }
- { id: 2, offset: 384, size: 128, alignment: 128 }
body: |
bb.0:
renamable $r0 = PS_fi %stack.0, 0
ADJCALLSTACKDOWN 0, 0, implicit-def $r29, implicit-def dead $r30, implicit $r31, implicit $r30, implicit $r29
renamable $w0 = PS_vloadrw_ai %stack.2, 0 :: (load 128 from %stack.2)
V6_vS32b_ai killed renamable $r0, 0, renamable $v1 :: (store 64 into %stack.0, align 128)
$r0 = A2_tfrsi 0
renamable $r1 = L2_loadri_io %stack.0, 4 :: (load 4 from %stack.0 + 4)
J2_call &__hexagon_divsi3, hexagoncsr, implicit-def dead $pc, implicit-def dead $r31, implicit $r29, implicit killed $r0, implicit killed $r1, implicit-def $r29, implicit-def $r0
ADJCALLSTACKUP 0, 0, implicit-def dead $r29, implicit-def dead $r30, implicit-def dead $r31, implicit $r29
renamable $v0 = V6_lvsplatw killed renamable $r0
PS_vstorerw_ai %stack.1, 0, killed renamable $w0 :: (store 128 into %stack.1)
...



0 comments on commit 7d1c374

Please sign in to comment.