1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2025-01-31 12:41:49 +01:00

[MachineCopyPropagation] BackwardPropagatableCopy: add check for hasOverlappingMultipleDef

In MachineCopyPropagation::BackwardPropagatableCopy(),
a check is added for multiple destination registers.

The copy propagation is avoided if the copied destination register
is the same register as another destination on the same instruction.

A new test is added.  This used to fail on ARM like this:
error: unpredictable instruction, RdHi and RdLo must be different
        umull   r9, r9, lr, r0

Reviewed By: lkail

Differential Revision: https://reviews.llvm.org/D82638
This commit is contained in:
Simon Wallis 2020-07-29 16:17:47 +01:00
parent 1f86714980
commit 8010bdcf94
2 changed files with 33 additions and 0 deletions

View File

@ -288,6 +288,8 @@ private:
const MachineInstr &UseI,
unsigned UseIdx);
bool hasImplicitOverlap(const MachineInstr &MI, const MachineOperand &Use);
bool hasOverlappingMultipleDef(const MachineInstr &MI,
const MachineOperand &MODef, Register Def);
/// Candidates for deletion.
SmallSetVector<MachineInstr *, 8> MaybeDeadCopies;
@ -461,6 +463,21 @@ bool MachineCopyPropagation::hasImplicitOverlap(const MachineInstr &MI,
return false;
}
/// For an MI that has multiple definitions, check whether \p MI has
/// a definition that overlaps with another of its definitions.
/// For example, on ARM: umull r9, r9, lr, r0
/// The umull instruction is unpredictable unless RdHi and RdLo are different.
bool MachineCopyPropagation::hasOverlappingMultipleDef(
const MachineInstr &MI, const MachineOperand &MODef, Register Def) {
for (const MachineOperand &MIDef : MI.defs()) {
if ((&MIDef != &MODef) && MIDef.isReg() &&
TRI->regsOverlap(Def, MIDef.getReg()))
return true;
}
return false;
}
/// Look for available copies whose destination register is used by \p MI and
/// replace the use in \p MI with the copy's source register.
void MachineCopyPropagation::forwardUses(MachineInstr &MI) {
@ -786,6 +803,9 @@ void MachineCopyPropagation::propagateDefs(MachineInstr &MI) {
if (hasImplicitOverlap(MI, MODef))
continue;
if (hasOverlappingMultipleDef(MI, MODef, Def))
continue;
LLVM_DEBUG(dbgs() << "MCP: Replacing " << printReg(MODef.getReg(), TRI)
<< "\n with " << printReg(Def, TRI) << "\n in "
<< MI << " from " << *Copy);

View File

@ -0,0 +1,13 @@
# RUN: llc -mtriple=arm-eabi -O1 -run-pass=machine-cp %s -o - \
# RUN: -verify-machineinstrs -simplify-mir | FileCheck %s
name: h
body: |
bb.0:
dead renamable $r9, renamable $r0 = UMULL renamable $lr, killed renamable $r0, 14 /* CC::al */, $noreg, $noreg
; CHECK: dead renamable $r9, renamable $r0 = UMULL renamable $lr, killed renamable $r0, 14 /* CC::al */, $noreg, $noreg
renamable $r9 = COPY killed renamable $r0
...