[TwoAddressInstructionPass] Relax assert in statepoint processing.

D124631 added special processing for STATEPOINT instructions.
It appears that assertion added there is too strong. We can get two
tied operands with the same register tied to different defs. If we
hit such case, do not process it in statepoint-specific code and
delegate it to common case.
This commit is contained in:
Denis Antrushin 2022-06-01 18:58:32 +07:00
parent 0a96885940
commit 7047d79fde
2 changed files with 40 additions and 5 deletions

View File

@ -161,7 +161,7 @@ class TwoAddressInstructionPass : public MachineFunctionPass {
bool collectTiedOperands(MachineInstr *MI, TiedOperandMap&);
void processTiedPairs(MachineInstr *MI, TiedPairList&, unsigned &Dist);
void eliminateRegSequence(MachineBasicBlock::iterator&);
void processStatepoint(MachineInstr *MI, TiedOperandMap &TiedOperands);
bool processStatepoint(MachineInstr *MI, TiedOperandMap &TiedOperands);
public:
static char ID; // Pass identification, replacement for typeid
@ -1635,12 +1635,16 @@ TwoAddressInstructionPass::processTiedPairs(MachineInstr *MI,
// and replaces all uses of RegA with RegB.
// No extra COPY instruction is necessary because tied use is killed at
// STATEPOINT.
void TwoAddressInstructionPass::processStatepoint(
bool TwoAddressInstructionPass::processStatepoint(
MachineInstr *MI, TiedOperandMap &TiedOperands) {
bool NeedCopy = false;
for (auto &TO : TiedOperands) {
Register RegB = TO.first;
assert(TO.second.size() == 1 && "statepoints has single tied use");
if (TO.second.size() != 1) {
NeedCopy = true;
continue;
}
unsigned SrcIdx = TO.second[0].first;
unsigned DstIdx = TO.second[0].second;
@ -1676,6 +1680,7 @@ void TwoAddressInstructionPass::processStatepoint(
LV->addVirtualRegisterKilled(RegB, *KillMI, false);
}
}
return !NeedCopy;
}
/// Reduce two-address instructions to two operands.
@ -1771,8 +1776,8 @@ bool TwoAddressInstructionPass::runOnMachineFunction(MachineFunction &Func) {
}
}
if (mi->getOpcode() == TargetOpcode::STATEPOINT) {
processStatepoint(&*mi, TiedOperands);
if (mi->getOpcode() == TargetOpcode::STATEPOINT &&
processStatepoint(&*mi, TiedOperands)) {
TiedOperands.clear();
LLVM_DEBUG(dbgs() << "\t\trewrite to:\t" << *mi);
mi = nmi;

View File

@ -12,6 +12,7 @@
declare i1 @return_i1()
declare void @consume(i32 addrspace(1)*)
declare void @consume1(i8 addrspace(1)*, i64 addrspace(1)*)
define i1 @test_relocate(i32 addrspace(1)* %a) gc "statepoint-example" {
entry:
@ -22,6 +23,10 @@
ret i1 %res1
}
define void @test_duplicate_gcregs(i8 addrspace(1)* %a) gc "statepoint-example" {
ret void
}
; Function Attrs: nounwind readnone
declare i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(token, i32 immarg, i32 immarg) #0
@ -62,3 +67,28 @@ body: |
RET 0, killed $al
...
---
name: test_duplicate_gcregs
alignment: 16
tracksRegLiveness: true
liveins:
- { reg: '$rdi', virtual-reg: '%0' }
body: |
bb.0 (%ir-block.0):
liveins: $rdi
; CHECK-LABEL: name: test_duplicate_gcregs
; CHECK: %1:gr64 = COPY %0
; CHECK: %2:gr64 = COPY %0
; CHECK: %1:gr64, %2:gr64 = STATEPOINT 0, 0, 0, target-flags(x86-plt) @return_i1, 2, 0, 2, 0, 2, 0, 2, 2, %1(tied-def 0), %2(tied-def 1), 2, 0, 2, 2, 0, 0, 1, 1, csr_64
; CHECK: $rdi = COPY killed %1
; CHECK: $rsi = COPY killed %2
; CHECK: CALL64pcrel32 target-flags(x86-plt) @consume1, csr_64, implicit $rsp, implicit $ssp, implicit killed $rdi, implicit killed $rsi, implicit-def $rsp, implicit-def $ssp
; CHECK: RET 0
%0:gr64 = COPY killed $rdi
%1:gr64, %2:gr64 = STATEPOINT 0, 0, 0, target-flags(x86-plt) @return_i1, 2, 0, 2, 0, 2, 0, 2, 2, killed %0(tied-def 0), killed %0(tied-def 1), 2, 0, 2, 2, 0, 0, 1, 1, csr_64, implicit-def $rsp, implicit-def $ssp, implicit-def dead $al
$rdi = COPY killed %1
$rsi = COPY killed %2
CALL64pcrel32 target-flags(x86-plt) @consume1, csr_64, implicit $rsp, implicit $ssp, implicit killed $rdi, implicit killed $rsi, implicit-def $rsp, implicit-def $ssp
RET 0
...