mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-01-31 12:41:49 +01:00
[PowerPC] fix killed/dead flag after convert x-form to d-form tranformation.
Differential Revision: https://reviews.llvm.org/D58428 llvm-svn: 355378
This commit is contained in:
parent
22917f076e
commit
7f925b398f
@ -2424,6 +2424,83 @@ const unsigned *PPCInstrInfo::getLoadOpcodesForSpillArray() const {
|
||||
return OpcodesForSpill[(Subtarget.hasP9Vector()) ? 1 : 0];
|
||||
}
|
||||
|
||||
void PPCInstrInfo::fixupIsDeadOrKill(MachineInstr &StartMI, MachineInstr &EndMI,
|
||||
unsigned RegNo) const {
|
||||
const MachineRegisterInfo &MRI =
|
||||
StartMI.getParent()->getParent()->getRegInfo();
|
||||
if (MRI.isSSA())
|
||||
return;
|
||||
|
||||
// Instructions between [StartMI, EndMI] should be in same basic block.
|
||||
assert((StartMI.getParent() == EndMI.getParent()) &&
|
||||
"Instructions are not in same basic block");
|
||||
|
||||
bool IsKillSet = false;
|
||||
|
||||
auto clearOperandKillInfo = [=] (MachineInstr &MI, unsigned Index) {
|
||||
MachineOperand &MO = MI.getOperand(Index);
|
||||
if (MO.isReg() && MO.isUse() && MO.isKill() &&
|
||||
getRegisterInfo().regsOverlap(MO.getReg(), RegNo))
|
||||
MO.setIsKill(false);
|
||||
};
|
||||
|
||||
// Set killed flag for EndMI.
|
||||
// No need to do anything if EndMI defines RegNo.
|
||||
int UseIndex =
|
||||
EndMI.findRegisterUseOperandIdx(RegNo, false, &getRegisterInfo());
|
||||
if (UseIndex != -1) {
|
||||
EndMI.getOperand(UseIndex).setIsKill(true);
|
||||
IsKillSet = true;
|
||||
// Clear killed flag for other EndMI operands related to RegNo. In some
|
||||
// upexpected cases, killed may be set multiple times for same register
|
||||
// operand in same MI.
|
||||
for (int i = 0, e = EndMI.getNumOperands(); i != e; ++i)
|
||||
if (i != UseIndex)
|
||||
clearOperandKillInfo(EndMI, i);
|
||||
}
|
||||
|
||||
// Walking the inst in reverse order (EndMI -> StartMI].
|
||||
MachineBasicBlock::reverse_iterator It = EndMI;
|
||||
MachineBasicBlock::reverse_iterator E = EndMI.getParent()->rend();
|
||||
// EndMI has been handled above, skip it here.
|
||||
It++;
|
||||
MachineOperand *MO = nullptr;
|
||||
for (; It != E; ++It) {
|
||||
// Skip insturctions which could not be a def/use of RegNo.
|
||||
if (It->isDebugInstr() || It->isPosition())
|
||||
continue;
|
||||
|
||||
// Clear killed flag for all It operands related to RegNo. In some
|
||||
// upexpected cases, killed may be set multiple times for same register
|
||||
// operand in same MI.
|
||||
for (int i = 0, e = It->getNumOperands(); i != e; ++i)
|
||||
clearOperandKillInfo(*It, i);
|
||||
|
||||
// If killed is not set, set killed for its last use or set dead for its def
|
||||
// if no use found.
|
||||
if (!IsKillSet) {
|
||||
if ((MO = It->findRegisterUseOperand(RegNo, false, &getRegisterInfo()))) {
|
||||
// Use found, set it killed.
|
||||
IsKillSet = true;
|
||||
MO->setIsKill(true);
|
||||
continue;
|
||||
} else if ((MO = It->findRegisterDefOperand(RegNo, false, true,
|
||||
&getRegisterInfo()))) {
|
||||
// No use found, set dead for its def.
|
||||
assert(&*It == &StartMI && "No new def between StartMI and EndMI.");
|
||||
MO->setIsDead(true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ((&*It) == &StartMI)
|
||||
break;
|
||||
}
|
||||
// Ensure RegMo liveness is killed after EndMI.
|
||||
assert((IsKillSet || (MO && MO->isDead())) &&
|
||||
"RegNo should be killed or dead");
|
||||
}
|
||||
|
||||
// If this instruction has an immediate form and one of its operands is a
|
||||
// result of a load-immediate or an add-immediate, convert it to
|
||||
// the immediate form if the constant is in range.
|
||||
@ -2440,8 +2517,9 @@ bool PPCInstrInfo::convertToImmediateForm(MachineInstr &MI,
|
||||
return false;
|
||||
assert(ForwardingOperand < MI.getNumOperands() &&
|
||||
"The forwarding operand needs to be valid at this point");
|
||||
bool KillFwdDefMI = !SeenIntermediateUse &&
|
||||
MI.getOperand(ForwardingOperand).isKill();
|
||||
bool IsForwardingOperandKilled = MI.getOperand(ForwardingOperand).isKill();
|
||||
bool KillFwdDefMI = !SeenIntermediateUse && IsForwardingOperandKilled;
|
||||
unsigned ForwardingOperandReg = MI.getOperand(ForwardingOperand).getReg();
|
||||
if (KilledDef && KillFwdDefMI)
|
||||
*KilledDef = DefMI;
|
||||
|
||||
@ -2450,8 +2528,9 @@ bool PPCInstrInfo::convertToImmediateForm(MachineInstr &MI,
|
||||
// If this is a reg+reg instruction that has a reg+imm form,
|
||||
// and one of the operands is produced by an add-immediate,
|
||||
// try to convert it.
|
||||
if (HasImmForm && transformToImmFormFedByAdd(MI, III, ForwardingOperand,
|
||||
*DefMI, KillFwdDefMI))
|
||||
if (HasImmForm &&
|
||||
transformToImmFormFedByAdd(MI, III, ForwardingOperand, *DefMI,
|
||||
KillFwdDefMI))
|
||||
return true;
|
||||
|
||||
if ((DefMI->getOpcode() != PPC::LI && DefMI->getOpcode() != PPC::LI8) ||
|
||||
@ -2466,7 +2545,7 @@ bool PPCInstrInfo::convertToImmediateForm(MachineInstr &MI,
|
||||
// If this is a reg+reg instruction that has a reg+imm form,
|
||||
// and one of the operands is produced by LI, convert it now.
|
||||
if (HasImmForm)
|
||||
return transformToImmFormFedByLI(MI, III, ForwardingOperand, SExtImm);
|
||||
return transformToImmFormFedByLI(MI, III, ForwardingOperand, *DefMI, SExtImm);
|
||||
|
||||
bool ReplaceWithLI = false;
|
||||
bool Is64BitLI = false;
|
||||
@ -2486,6 +2565,8 @@ bool PPCInstrInfo::convertToImmediateForm(MachineInstr &MI,
|
||||
case PPC::CMPLDI: {
|
||||
// Doing this post-RA would require dataflow analysis to reliably find uses
|
||||
// of the CR register set by the compare.
|
||||
// No need to fixup killed/dead flag since this transformation is only valid
|
||||
// before RA.
|
||||
if (PostRA)
|
||||
return false;
|
||||
// If a compare-immediate is fed by an immediate and is itself an input of
|
||||
@ -2662,6 +2743,14 @@ bool PPCInstrInfo::convertToImmediateForm(MachineInstr &MI,
|
||||
if (KilledDef && SetCR)
|
||||
*KilledDef = nullptr;
|
||||
replaceInstrWithLI(MI, LII);
|
||||
|
||||
// Fixup killed/dead flag after transformation.
|
||||
// Pattern:
|
||||
// ForwardingOperandReg = LI imm1
|
||||
// y = op2 imm2, ForwardingOperandReg(killed)
|
||||
if (IsForwardingOperandKilled)
|
||||
fixupIsDeadOrKill(*DefMI, MI, ForwardingOperandReg);
|
||||
|
||||
LLVM_DEBUG(dbgs() << "With:\n");
|
||||
LLVM_DEBUG(MI.dump());
|
||||
return true;
|
||||
@ -3169,11 +3258,10 @@ bool PPCInstrInfo::isDefMIElgibleForForwarding(MachineInstr &DefMI,
|
||||
return isAnImmediateOperand(*ImmMO);
|
||||
}
|
||||
|
||||
bool PPCInstrInfo::isRegElgibleForForwarding(const MachineOperand &RegMO,
|
||||
const MachineInstr &DefMI,
|
||||
const MachineInstr &MI,
|
||||
bool KillDefMI
|
||||
) const {
|
||||
bool PPCInstrInfo::isRegElgibleForForwarding(
|
||||
const MachineOperand &RegMO, const MachineInstr &DefMI,
|
||||
const MachineInstr &MI, bool KillDefMI,
|
||||
bool &IsFwdFeederRegKilled) const {
|
||||
// x = addi y, imm
|
||||
// ...
|
||||
// z = lfdx 0, x -> z = lfd imm(y)
|
||||
@ -3193,6 +3281,8 @@ bool PPCInstrInfo::isRegElgibleForForwarding(const MachineOperand &RegMO,
|
||||
for (; It != E; ++It) {
|
||||
if (It->modifiesRegister(Reg, &getRegisterInfo()) && (&*It) != &DefMI)
|
||||
return false;
|
||||
else if (It->killsRegister(Reg, &getRegisterInfo()) && (&*It) != &DefMI)
|
||||
IsFwdFeederRegKilled = true;
|
||||
// Made it to DefMI without encountering a clobber.
|
||||
if ((&*It) == &DefMI)
|
||||
break;
|
||||
@ -3264,11 +3354,9 @@ bool PPCInstrInfo::isImmElgibleForForwarding(const MachineOperand &ImmMO,
|
||||
// is the literal zero, attempt to forward the source of the add-immediate to
|
||||
// the corresponding D-Form instruction with the displacement coming from
|
||||
// the immediate being added.
|
||||
bool PPCInstrInfo::transformToImmFormFedByAdd(MachineInstr &MI,
|
||||
const ImmInstrInfo &III,
|
||||
unsigned OpNoForForwarding,
|
||||
MachineInstr &DefMI,
|
||||
bool KillDefMI) const {
|
||||
bool PPCInstrInfo::transformToImmFormFedByAdd(
|
||||
MachineInstr &MI, const ImmInstrInfo &III, unsigned OpNoForForwarding,
|
||||
MachineInstr &DefMI, bool KillDefMI) const {
|
||||
// RegMO ImmMO
|
||||
// | |
|
||||
// x = addi reg, imm <----- DefMI
|
||||
@ -3293,10 +3381,19 @@ bool PPCInstrInfo::transformToImmFormFedByAdd(MachineInstr &MI,
|
||||
if (!isImmElgibleForForwarding(*ImmMO, DefMI, III, Imm))
|
||||
return false;
|
||||
|
||||
bool IsFwdFeederRegKilled = false;
|
||||
// Check if the RegMO can be forwarded to MI.
|
||||
if (!isRegElgibleForForwarding(*RegMO, DefMI, MI, KillDefMI))
|
||||
if (!isRegElgibleForForwarding(*RegMO, DefMI, MI, KillDefMI,
|
||||
IsFwdFeederRegKilled))
|
||||
return false;
|
||||
|
||||
// Get killed info in case fixup needed after transformation.
|
||||
unsigned ForwardKilledOperandReg = ~0U;
|
||||
MachineRegisterInfo &MRI = MI.getParent()->getParent()->getRegInfo();
|
||||
bool PostRA = !MRI.isSSA();
|
||||
if (PostRA && MI.getOperand(OpNoForForwarding).isKill())
|
||||
ForwardKilledOperandReg = MI.getOperand(OpNoForForwarding).getReg();
|
||||
|
||||
// We know that, the MI and DefMI both meet the pattern, and
|
||||
// the Imm also meet the requirement with the new Imm-form.
|
||||
// It is safe to do the transformation now.
|
||||
@ -3347,6 +3444,22 @@ bool PPCInstrInfo::transformToImmFormFedByAdd(MachineInstr &MI,
|
||||
// Update the opcode.
|
||||
MI.setDesc(get(III.ImmOpcode));
|
||||
|
||||
// Fix up killed/dead flag after transformation.
|
||||
// Pattern 1:
|
||||
// x = ADD KilledFwdFeederReg, imm
|
||||
// n = opn KilledFwdFeederReg(killed), regn
|
||||
// y = XOP 0, x
|
||||
// Pattern 2:
|
||||
// x = ADD reg(killed), imm
|
||||
// y = XOP 0, x
|
||||
if (IsFwdFeederRegKilled || RegMO->isKill())
|
||||
fixupIsDeadOrKill(DefMI, MI, RegMO->getReg());
|
||||
// Pattern 3:
|
||||
// ForwardKilledOperandReg = ADD reg, imm
|
||||
// y = XOP 0, ForwardKilledOperandReg(killed)
|
||||
if (ForwardKilledOperandReg != ~0U)
|
||||
fixupIsDeadOrKill(DefMI, MI, ForwardKilledOperandReg);
|
||||
|
||||
LLVM_DEBUG(dbgs() << "With:\n");
|
||||
LLVM_DEBUG(MI.dump());
|
||||
|
||||
@ -3356,6 +3469,7 @@ bool PPCInstrInfo::transformToImmFormFedByAdd(MachineInstr &MI,
|
||||
bool PPCInstrInfo::transformToImmFormFedByLI(MachineInstr &MI,
|
||||
const ImmInstrInfo &III,
|
||||
unsigned ConstantOpNo,
|
||||
MachineInstr &DefMI,
|
||||
int64_t Imm) const {
|
||||
MachineRegisterInfo &MRI = MI.getParent()->getParent()->getRegInfo();
|
||||
bool PostRA = !MRI.isSSA();
|
||||
@ -3394,6 +3508,11 @@ bool PPCInstrInfo::transformToImmFormFedByLI(MachineInstr &MI,
|
||||
return false;
|
||||
}
|
||||
|
||||
// Get killed info in case fixup needed after transformation.
|
||||
unsigned ForwardKilledOperandReg = ~0U;
|
||||
if (PostRA && MI.getOperand(ConstantOpNo).isKill())
|
||||
ForwardKilledOperandReg = MI.getOperand(ConstantOpNo).getReg();
|
||||
|
||||
unsigned Opc = MI.getOpcode();
|
||||
bool SpecialShift32 =
|
||||
Opc == PPC::SLW || Opc == PPC::SLWo || Opc == PPC::SRW || Opc == PPC::SRWo;
|
||||
@ -3476,6 +3595,13 @@ bool PPCInstrInfo::transformToImmFormFedByLI(MachineInstr &MI,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Fix up killed/dead flag after transformation.
|
||||
// Pattern:
|
||||
// ForwardKilledOperandReg = LI imm
|
||||
// y = XOP reg, ForwardKilledOperandReg(killed)
|
||||
if (ForwardKilledOperandReg != ~0U)
|
||||
fixupIsDeadOrKill(DefMI, MI, ForwardKilledOperandReg);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -128,12 +128,12 @@ class PPCInstrInfo : public PPCGenInstrInfo {
|
||||
// If the inst has imm-form and one of its operand is produced by a LI,
|
||||
// put the imm into the inst directly and remove the LI if possible.
|
||||
bool transformToImmFormFedByLI(MachineInstr &MI, const ImmInstrInfo &III,
|
||||
unsigned ConstantOpNo, int64_t Imm) const;
|
||||
unsigned ConstantOpNo, MachineInstr &DefMI,
|
||||
int64_t Imm) const;
|
||||
// If the inst has imm-form and one of its operand is produced by an
|
||||
// add-immediate, try to transform it when possible.
|
||||
bool transformToImmFormFedByAdd(MachineInstr &MI, const ImmInstrInfo &III,
|
||||
unsigned ConstantOpNo,
|
||||
MachineInstr &DefMI,
|
||||
unsigned ConstantOpNo, MachineInstr &DefMI,
|
||||
bool KillDefMI) const;
|
||||
// Try to find that, if the instruction 'MI' contains any operand that
|
||||
// could be forwarded from some inst that feeds it. If yes, return the
|
||||
@ -158,8 +158,8 @@ class PPCInstrInfo : public PPCGenInstrInfo {
|
||||
int64_t &Imm) const;
|
||||
bool isRegElgibleForForwarding(const MachineOperand &RegMO,
|
||||
const MachineInstr &DefMI,
|
||||
const MachineInstr &MI,
|
||||
bool KillDefMI) const;
|
||||
const MachineInstr &MI, bool KillDefMI,
|
||||
bool &IsFwdFeederRegKilled) const;
|
||||
const unsigned *getStoreOpcodesForSpillArray() const;
|
||||
const unsigned *getLoadOpcodesForSpillArray() const;
|
||||
virtual void anchor();
|
||||
@ -411,6 +411,18 @@ public:
|
||||
|
||||
bool convertToImmediateForm(MachineInstr &MI,
|
||||
MachineInstr **KilledDef = nullptr) const;
|
||||
|
||||
/// Fixup killed/dead flag for register \p RegNo between instructions [\p
|
||||
/// StartMI, \p EndMI]. Some PostRA transformations may violate register
|
||||
/// killed/dead flags semantics, this function can be called to fix up. Before
|
||||
/// calling this function,
|
||||
/// 1. Ensure that \p RegNo liveness is killed after instruction \p EndMI.
|
||||
/// 2. Ensure that there is no new definition between (\p StartMI, \p EndMI)
|
||||
/// and possible definition for \p RegNo is \p StartMI or \p EndMI.
|
||||
/// 3. Ensure that all instructions between [\p StartMI, \p EndMI] are in same
|
||||
/// basic block.
|
||||
void fixupIsDeadOrKill(MachineInstr &StartMI, MachineInstr &EndMI,
|
||||
unsigned RegNo) const;
|
||||
void replaceInstrWithLI(MachineInstr &MI, const LoadImmediateInfo &LII) const;
|
||||
void replaceInstrOperandWithImm(MachineInstr &MI, unsigned OpNo,
|
||||
int64_t Imm) const;
|
||||
|
@ -27,7 +27,7 @@ body: |
|
||||
; Following instruction $r3 also reads $x3, ADDI8 can not be erased
|
||||
; CHECK: $x3 = ADDI8 $x5, 100, implicit-def $r3
|
||||
STW $r3, $x5, 100
|
||||
; CHECK: STW $r3, $x5, 100
|
||||
; CHECK: STW killed $r3, $x5, 100
|
||||
STFSX killed $f1, $zero8, $x3
|
||||
; CHECK: STFS killed $f1, 100, $x5
|
||||
STD $x5, $x5, 100
|
||||
|
183
test/CodeGen/PowerPC/convert-rr-to-ri-instrs-kill-flag.mir
Normal file
183
test/CodeGen/PowerPC/convert-rr-to-ri-instrs-kill-flag.mir
Normal file
@ -0,0 +1,183 @@
|
||||
# RUN: llc -mtriple=powerpc64le--linux-gnu -stop-after ppc-pre-emit-peephole %s -o - -verify-machineinstrs | FileCheck %s
|
||||
|
||||
---
|
||||
# LI + XFORM -> DFORM, no killed/dead flag fixup.
|
||||
name: testKillPassUpLI1
|
||||
#CHECK : name : testKillPassUpLI1
|
||||
tracksRegLiveness: true
|
||||
body: |
|
||||
bb.0.entry:
|
||||
liveins: $x3, $f1, $x5
|
||||
$x3 = LI8 100
|
||||
STFSX killed $f1, $x3, $x5
|
||||
; CHECK: STFS killed $f1, 100, $x5
|
||||
STD killed $x3, killed $x5, 100
|
||||
; CHECK: STD killed $x3, killed $x5, 100
|
||||
BLR8 implicit $lr8, implicit $rm
|
||||
|
||||
...
|
||||
---
|
||||
# LI + XFORM -> DFORM, fixup killed/dead flag for $x3, find no use, set def as
|
||||
# dead(LI8 is deleted).
|
||||
name : testKillPassUpLI2
|
||||
# CHECK: name: testKillPassUpLI2
|
||||
tracksRegLiveness: true
|
||||
body: |
|
||||
bb.0.entry:
|
||||
liveins: $x3, $f1, $x5
|
||||
$x3 = LI8 100
|
||||
; CHECK-NOT: LI8
|
||||
STFSX killed $f1, killed $x3, killed $x5
|
||||
; CHECK: STFS killed $f1, 100, killed $x5
|
||||
BLR8 implicit $lr8, implicit $rm
|
||||
|
||||
...
|
||||
---
|
||||
# LI + XFORM -> DFORM, fixup killed/dead flag for $x3, find last use, set last
|
||||
# use as killed.
|
||||
name: testKillPassUpLI3
|
||||
# CHECK: name: testKillPassUpLI3
|
||||
tracksRegLiveness: true
|
||||
body: |
|
||||
bb.0.entry:
|
||||
liveins: $x3, $f1, $x5
|
||||
$x3 = LI8 100
|
||||
STD $x3, $x5, 100
|
||||
; CHECK: STD killed $x3, $x5, 100
|
||||
STFSX killed $f1, killed $x3, $x5
|
||||
; CHECK: STFS killed $f1, 100, $x5
|
||||
STD killed $x5, $x5, 100
|
||||
; CHECK: STD killed $x5, $x5, 100
|
||||
BLR8 implicit $lr8, implicit $rm
|
||||
|
||||
...
|
||||
---
|
||||
# LI + OP -> LI, fixup killed/dead flag for $x3, find last use, set last use as
|
||||
# killed.
|
||||
name: testKillPassUpLI4
|
||||
# CHECK: name: testKillPassUpLI4
|
||||
tracksRegLiveness: true
|
||||
body: |
|
||||
bb.0.entry:
|
||||
liveins: $x3, $x5
|
||||
$x3 = LI8 100
|
||||
STD $x3, $x5, 100
|
||||
; CHECK: STD killed $x3, killed $x5, 100
|
||||
$x5 = ADDI8 killed $x3, 200
|
||||
; CHECK: $x5 = LI8 300
|
||||
STD $x5, $x5, 100
|
||||
BLR8 implicit $lr8, implicit $rm
|
||||
|
||||
...
|
||||
---
|
||||
# ADD + XFORM -> DFORM, fixup killed/dead flag for $x3, find no use, set def as dead
|
||||
# (ADDI8 is deleted).
|
||||
name: testKillPassUpADD1
|
||||
# CHECK: name: testKillPassUpADD1
|
||||
tracksRegLiveness: true
|
||||
body: |
|
||||
bb.0.entry:
|
||||
liveins: $x3, $f1, $x5
|
||||
$x3 = ADDI8 killed $x5, 100
|
||||
; CHECK-NOT: ADDI8
|
||||
STFSX killed $f1, $zero8, killed $x3
|
||||
; CHECK: STFS killed $f1, 100, killed $x5
|
||||
BLR8 implicit $lr8, implicit $rm
|
||||
|
||||
...
|
||||
---
|
||||
# ADD + XFORM -> DFORM, fixup killed/dead flag for $x3, find last use, set last
|
||||
# use as killed.
|
||||
name: testKillPassUpADD2
|
||||
# CHECK: name: testKillPassUpADD2
|
||||
tracksRegLiveness: true
|
||||
body: |
|
||||
bb.0.entry:
|
||||
liveins: $x3, $f1, $x5
|
||||
$x3 = ADDI8 $x5, 100
|
||||
STD $x3, $x5, 100
|
||||
; CHECK: STD killed $x3, $x5, 100
|
||||
STFSX killed $f1, $zero8, killed $x3
|
||||
; CHECK: STFS killed $f1, 100, $x5
|
||||
STD killed $x5, $x5, 100
|
||||
; CHECK: STD killed $x5, $x5, 100
|
||||
BLR8 implicit $lr8, implicit $rm
|
||||
|
||||
...
|
||||
---
|
||||
# ADD + XFORM -> DFORM, fixup killed/dead flag for register $x5, DFORM
|
||||
# instruction uses $x5 and no other kill uses, set it as killed in
|
||||
# DFORM instruction.
|
||||
name: testKillPassDownADD1
|
||||
# CHECK: name: testKillPassDownADD1
|
||||
tracksRegLiveness: true
|
||||
body: |
|
||||
bb.0.entry:
|
||||
liveins: $x3, $f1, $x5
|
||||
$x3 = ADDI8 killed $x5, 100
|
||||
; CHECK: $x3 = ADDI8 $x5, 100
|
||||
STFSX killed $f1, $zero8, $x3
|
||||
; CHECK: STFS killed $f1, 100, killed $x5
|
||||
STD killed $x3, $x3, 100
|
||||
; CHECK: STD killed $x3, $x3, 100
|
||||
BLR8 implicit $lr8, implicit $rm
|
||||
|
||||
...
|
||||
---
|
||||
# ADD + XFORM -> DFORM, fixup killed/dead flag for register $x5, DFORM
|
||||
# instruction uses $x5 and there is one kill use, set $x5 as killed in
|
||||
# DFORM instruction and clear the other kill use killed flag.
|
||||
name: testKillPassDownADD2
|
||||
# CHECK: name: testKillPassDownADD2
|
||||
tracksRegLiveness: true
|
||||
body: |
|
||||
bb.0.entry:
|
||||
liveins: $x3, $f1, $x5
|
||||
$x3 = ADDI8 $x5, 100
|
||||
STD killed $x5, $x5, 100
|
||||
; CHECK: STD $x5, $x5, 100
|
||||
STFSX killed $f1, $zero8, killed $x3
|
||||
; CHECK: STFS killed $f1, 100, killed $x5
|
||||
BLR8 implicit $lr8, implicit $rm
|
||||
|
||||
...
|
||||
---
|
||||
# ADD + XFORM -> DFORM, fixup killed/dead flag for register $x3, DFORM
|
||||
# instruction defines $x3, do nothing for killed/dead flag.
|
||||
name: testKillPassDownADD3
|
||||
# CHECK: name: testKillPassDownADD3
|
||||
tracksRegLiveness: true
|
||||
body: |
|
||||
bb.0.entry:
|
||||
liveins: $x3, $x5
|
||||
$x3 = ADDI8 $x5, 100
|
||||
$x3 = LDX $zero8, killed $x3
|
||||
; CHECK: $x3 = LD 100, $x5
|
||||
STD killed $x5, $x5, 100
|
||||
; CHECK: STD killed $x5, $x5, 100
|
||||
STD killed $x3, $x3, 200
|
||||
; CHECK: STD killed $x3, $x3, 200
|
||||
BLR8 implicit $lr8, implicit $rm
|
||||
|
||||
...
|
||||
---
|
||||
# ADD + XFORM -> DFORM, fixup killed/dead flag for both register $x5 and $x3,
|
||||
# DFORM instruction uses $x5 and there is one kill use, set $x5 as killed in
|
||||
# DFORM instruction and clear the other kill use killed flag. Find last use for
|
||||
# $x3, set last use as killed.
|
||||
name: testKillPassDownADD4
|
||||
# CHECK: name: testKillPassDownADD4
|
||||
tracksRegLiveness: true
|
||||
body: |
|
||||
bb.0.entry:
|
||||
liveins: $x3, $f1, $x5
|
||||
$x3 = ADDI8 $x5, 100
|
||||
STD killed $x5, $x5, 100
|
||||
; CHECK: STD $x5, $x5, 100
|
||||
STD $x3, $x3, 200
|
||||
; CHECK: STD killed $x3, $x3, 200
|
||||
STFSX killed $f1, $zero8, killed $x3
|
||||
; CHECK: STFS killed $f1, 100, killed $x5
|
||||
BLR8 implicit $lr8, implicit $rm
|
||||
|
||||
...
|
Loading…
x
Reference in New Issue
Block a user