[CodeGen] Fix dependence breaking for tied operands

Differential Revision: https://reviews.llvm.org/D107582
This commit is contained in:
Danila Malyutin 2021-08-05 19:53:58 +03:00
parent c86f218fe4
commit 7b102fcc91
2 changed files with 80 additions and 9 deletions

View File

@ -212,6 +212,21 @@ void CriticalAntiDepBreaker::PrescanInstruction(MachineInstr &MI) {
if (Classes[Reg] != reinterpret_cast<TargetRegisterClass *>(-1))
RegRefs.insert(std::make_pair(Reg, &MO));
if (MO.isUse() && Special) {
if (!KeepRegs.test(Reg)) {
for (MCSubRegIterator SubRegs(Reg, TRI, /*IncludeSelf=*/true);
SubRegs.isValid(); ++SubRegs)
KeepRegs.set(*SubRegs);
}
}
}
for (unsigned I = 0, E = MI.getNumOperands(); I != E; ++I) {
const MachineOperand &MO = MI.getOperand(I);
if (!MO.isReg()) continue;
Register Reg = MO.getReg();
if (!Reg.isValid())
continue;
// If this reg is tied and live (Classes[Reg] is set to -1), we can't change
// it or any of its sub or super regs. We need to use KeepRegs to mark the
// reg because not all uses of the same reg within an instruction are
@ -222,7 +237,7 @@ void CriticalAntiDepBreaker::PrescanInstruction(MachineInstr &MI) {
// of a register? In the above 'xor' example, the uses of %eax are undef, so
// earlier instructions could still replace %eax even though the 'xor'
// itself can't be changed.
if (MI.isRegTiedToUseOperand(i) &&
if (MI.isRegTiedToUseOperand(I) &&
Classes[Reg] == reinterpret_cast<TargetRegisterClass *>(-1)) {
for (MCSubRegIterator SubRegs(Reg, TRI, /*IncludeSelf=*/true);
SubRegs.isValid(); ++SubRegs) {
@ -233,14 +248,6 @@ void CriticalAntiDepBreaker::PrescanInstruction(MachineInstr &MI) {
KeepRegs.set(*SuperRegs);
}
}
if (MO.isUse() && Special) {
if (!KeepRegs.test(Reg)) {
for (MCSubRegIterator SubRegs(Reg, TRI, /*IncludeSelf=*/true);
SubRegs.isValid(); ++SubRegs)
KeepRegs.set(*SubRegs);
}
}
}
}

View File

@ -0,0 +1,64 @@
# RUN: llc -mtriple=x86_64-unknown-linux-gnu -mcpu=slm -run-pass post-RA-sched -o - %s | FileCheck %s
#
# Verify that the critical antidependence breaker does not partially
# replace tied operands
--- |
define void @main() { ret void }
...
---
# CHECK-LABEL: main
name: main
alignment: 16
exposesReturnsTwice: false
legalized: false
regBankSelected: false
selected: false
failedISel: false
tracksRegLiveness: true
hasWinCFI: false
registers: []
liveins:
- { reg: '$edi', virtual-reg: '' }
- { reg: '$esi', virtual-reg: '' }
frameInfo:
isFrameAddressTaken: false
isReturnAddressTaken: false
hasStackMap: false
hasPatchPoint: false
stackSize: 0
offsetAdjustment: 0
maxAlignment: 1
adjustsStack: false
hasCalls: false
stackProtector: ''
maxCallFrameSize: 0
cvBytesOfCalleeSavedRegisters: 0
hasOpaqueSPAdjustment: false
hasVAStart: false
hasMustTailInVarArgFunc: false
localFrameSize: 0
savePoint: ''
restorePoint: ''
fixedStack: []
stack: []
callSites: []
debugValueSubstitutions: []
constants: []
machineFunctionInfo: {}
body: |
bb.0:
liveins: $edi, $esi
$eax = MOV32rr $esi
$eax = LEA64_32r $rdi, 1, $rsi, 0, $noreg
$edi = MOV32rr $esi
$esi = MOV32ri 4
; Verify that XOR is untouched by the dependency breaker
; CHECK: $esi = XOR32rr undef $esi, undef $esi, implicit-def dead $eflags, implicit-def $rsi
$esi = XOR32rr undef $esi, undef $esi, implicit-def dead $eflags, implicit-def $rsi
RETQ killed $eax
...