forked from OSchip/llvm-project
[CodeGen] Fix dependence breaking for tied operands
Differential Revision: https://reviews.llvm.org/D107582
This commit is contained in:
parent
c86f218fe4
commit
7b102fcc91
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
...
|
Loading…
Reference in New Issue