forked from OSchip/llvm-project
[fastregalloc] Fix bug when undef value is tied to def.
If the tied use is undef value, fastregalloc should free the def register. There is no reload needed for the undef value. Reviewed By: MatzeB Differential Revision: https://reviews.llvm.org/D124834
This commit is contained in:
parent
1d6430b9e2
commit
764676b737
|
@ -1112,6 +1112,12 @@ void RegAllocFast::allocateInstruction(MachineInstr &MI) {
|
|||
RegMasks.clear();
|
||||
BundleVirtRegsMap.clear();
|
||||
|
||||
auto TiedOpIsUndef = [&](const MachineOperand &MO, unsigned Idx) {
|
||||
assert(MO.isTied());
|
||||
unsigned TiedIdx = MI.findTiedOperandIdx(Idx);
|
||||
const MachineOperand &TiedMO = MI.getOperand(TiedIdx);
|
||||
return TiedMO.isUndef();
|
||||
};
|
||||
// Scan for special cases; Apply pre-assigned register defs to state.
|
||||
bool HasPhysRegUse = false;
|
||||
bool HasRegMask = false;
|
||||
|
@ -1119,7 +1125,8 @@ void RegAllocFast::allocateInstruction(MachineInstr &MI) {
|
|||
bool HasDef = false;
|
||||
bool HasEarlyClobber = false;
|
||||
bool NeedToAssignLiveThroughs = false;
|
||||
for (MachineOperand &MO : MI.operands()) {
|
||||
for (unsigned I = 0; I < MI.getNumOperands(); ++I) {
|
||||
MachineOperand &MO = MI.getOperand(I);
|
||||
if (MO.isReg()) {
|
||||
Register Reg = MO.getReg();
|
||||
if (Reg.isVirtual()) {
|
||||
|
@ -1130,7 +1137,8 @@ void RegAllocFast::allocateInstruction(MachineInstr &MI) {
|
|||
HasEarlyClobber = true;
|
||||
NeedToAssignLiveThroughs = true;
|
||||
}
|
||||
if (MO.isTied() || (MO.getSubReg() != 0 && !MO.isUndef()))
|
||||
if ((MO.isTied() && !TiedOpIsUndef(MO, I)) ||
|
||||
(MO.getSubReg() != 0 && !MO.isUndef()))
|
||||
NeedToAssignLiveThroughs = true;
|
||||
}
|
||||
} else if (Reg.isPhysical()) {
|
||||
|
@ -1230,7 +1238,8 @@ void RegAllocFast::allocateInstruction(MachineInstr &MI) {
|
|||
MachineOperand &MO = MI.getOperand(OpIdx);
|
||||
LLVM_DEBUG(dbgs() << "Allocating " << MO << '\n');
|
||||
unsigned Reg = MO.getReg();
|
||||
if (MO.isEarlyClobber() || MO.isTied() ||
|
||||
if (MO.isEarlyClobber() ||
|
||||
(MO.isTied() && !TiedOpIsUndef(MO, OpIdx)) ||
|
||||
(MO.getSubReg() && !MO.isUndef())) {
|
||||
defineLiveThroughVirtReg(MI, OpIdx, Reg);
|
||||
} else {
|
||||
|
@ -1253,7 +1262,8 @@ void RegAllocFast::allocateInstruction(MachineInstr &MI) {
|
|||
// Free registers occupied by defs.
|
||||
// Iterate operands in reverse order, so we see the implicit super register
|
||||
// defs first (we added them earlier in case of <def,read-undef>).
|
||||
for (MachineOperand &MO : llvm::reverse(MI.operands())) {
|
||||
for (signed I = MI.getNumOperands() - 1; I >= 0; --I) {
|
||||
MachineOperand &MO = MI.getOperand(I);
|
||||
if (!MO.isReg() || !MO.isDef())
|
||||
continue;
|
||||
|
||||
|
@ -1268,7 +1278,7 @@ void RegAllocFast::allocateInstruction(MachineInstr &MI) {
|
|||
"tied def assigned to clobbered register");
|
||||
|
||||
// Do not free tied operands and early clobbers.
|
||||
if (MO.isTied() || MO.isEarlyClobber())
|
||||
if ((MO.isTied() && !TiedOpIsUndef(MO, I)) || MO.isEarlyClobber())
|
||||
continue;
|
||||
Register Reg = MO.getReg();
|
||||
if (!Reg)
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
# RUN: llc -mtriple=x86_64-- -run-pass=regallocfast -o - %s | FileCheck %s
|
||||
|
||||
# If the tied use is undef value, fastregalloc should free the def register.
|
||||
# There is no reload needed for the undef value.
|
||||
...
|
||||
---
|
||||
name: foo
|
||||
alignment: 16
|
||||
tracksRegLiveness: true
|
||||
registers:
|
||||
- { id: 0, class: vr128 }
|
||||
frameInfo:
|
||||
maxAlignment: 16
|
||||
stack:
|
||||
- { id: 0, size: 64, alignment: 16 }
|
||||
- { id: 1, size: 16, alignment: 16 }
|
||||
machineFunctionInfo: {}
|
||||
body: |
|
||||
bb.0.entry:
|
||||
; CHECK-LABEL: bb.0.entry
|
||||
; CHECK-NEXT: renamable $xmm0 = PXORrr undef renamable $xmm0, undef renamable $xmm0
|
||||
; CHECK-NEXT: MOVAPSmr %stack.1, 1, $noreg, 0, $noreg, renamable $xmm0
|
||||
; CHECK-NEXT: MOVAPSmr %stack.0, 1, $noreg, 0, $noreg, renamable $xmm0
|
||||
; CHECK-NEXT: MOVAPSmr %stack.0, 1, $noreg, 16, $noreg, renamable $xmm0
|
||||
; CHECK-NEXT: MOVAPSmr %stack.0, 1, $noreg, 32, $noreg, renamable $xmm0
|
||||
; CHECK-NEXT: MOVAPSmr %stack.0, 1, $noreg, 48, $noreg, killed renamable $xmm0
|
||||
|
||||
%0:vr128 = PXORrr undef %0, undef %0
|
||||
MOVAPSmr %stack.1, 1, $noreg, 0, $noreg, %0
|
||||
MOVAPSmr %stack.0, 1, $noreg, 0, $noreg, %0
|
||||
MOVAPSmr %stack.0, 1, $noreg, 16, $noreg, %0
|
||||
MOVAPSmr %stack.0, 1, $noreg, 32, $noreg, %0
|
||||
MOVAPSmr %stack.0, 1, $noreg, 48, $noreg, killed %0
|
||||
RET 0
|
||||
|
||||
...
|
Loading…
Reference in New Issue