forked from OSchip/llvm-project
[RDA][ARM][LowOverheadLoops] Iteration count IT blocks
Change the way that we remove the redundant iteration count code in the presence of IT blocks. collectLocalKilledOperands has been introduced to scan an instructions operands, collecting the killed instructions and then visiting them too. This is used to delete the code in the preheader which calculates the iteration count. We also track any IT blocks within the preheader and, if we remove all the instructions from the IT block, we also remove the IT instruction. isSafeToRemove is used to remove any redundant uses of the iteration count within the loop body. Differential Revision: https://reviews.llvm.org/D74975
This commit is contained in:
parent
bd5b22070b
commit
a67eb221e2
|
@ -164,6 +164,10 @@ public:
|
||||||
/// Return whether From can be moved backwards to just after To.
|
/// Return whether From can be moved backwards to just after To.
|
||||||
bool isSafeToMoveBackwards(MachineInstr *From, MachineInstr *To) const;
|
bool isSafeToMoveBackwards(MachineInstr *From, MachineInstr *To) const;
|
||||||
|
|
||||||
|
/// Assuming MI is dead, recursively search the incoming operands which are
|
||||||
|
/// killed by MI and collect those that would become dead.
|
||||||
|
void collectLocalKilledOperands(MachineInstr *MI, InstSet &Dead) const;
|
||||||
|
|
||||||
/// Return whether removing this instruction will have no effect on the
|
/// Return whether removing this instruction will have no effect on the
|
||||||
/// program, returning the redundant use-def chain.
|
/// program, returning the redundant use-def chain.
|
||||||
bool isSafeToRemove(MachineInstr *MI, InstSet &ToRemove) const;
|
bool isSafeToRemove(MachineInstr *MI, InstSet &ToRemove) const;
|
||||||
|
|
|
@ -472,6 +472,32 @@ ReachingDefAnalysis::isSafeToRemove(MachineInstr *MI, InstSet &Visited,
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ReachingDefAnalysis::collectLocalKilledOperands(MachineInstr *MI,
|
||||||
|
InstSet &Dead) const {
|
||||||
|
Dead.insert(MI);
|
||||||
|
auto IsDead = [this](MachineInstr *Def, int PhysReg) {
|
||||||
|
unsigned LiveDefs = 0;
|
||||||
|
for (auto &MO : Def->defs())
|
||||||
|
if (!MO.isDead())
|
||||||
|
++LiveDefs;
|
||||||
|
|
||||||
|
if (LiveDefs > 1)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
SmallPtrSet<MachineInstr*, 4> Uses;
|
||||||
|
getGlobalUses(Def, PhysReg, Uses);
|
||||||
|
return Uses.size() == 1;
|
||||||
|
};
|
||||||
|
|
||||||
|
for (auto &MO : MI->uses()) {
|
||||||
|
if (!MO.isReg() || MO.getReg() == 0 || !MO.isKill())
|
||||||
|
continue;
|
||||||
|
if (MachineInstr *Def = getReachingMIDef(MI, MO.getReg()))
|
||||||
|
if (IsDead(Def, MO.getReg()))
|
||||||
|
collectLocalKilledOperands(Def, Dead);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool ReachingDefAnalysis::isSafeToDefRegAt(MachineInstr *MI,
|
bool ReachingDefAnalysis::isSafeToDefRegAt(MachineInstr *MI,
|
||||||
int PhysReg) const {
|
int PhysReg) const {
|
||||||
SmallPtrSet<MachineInstr*, 1> Ignore;
|
SmallPtrSet<MachineInstr*, 1> Ignore;
|
||||||
|
|
|
@ -897,65 +897,63 @@ void ARMLowOverheadLoops::IterationCountDCE(LowOverheadLoop &LoLoop) {
|
||||||
if (!LoLoop.IsTailPredicationLegal())
|
if (!LoLoop.IsTailPredicationLegal())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (auto *Def = RDA->getReachingMIDef(LoLoop.Start,
|
auto *Def = RDA->getReachingMIDef(LoLoop.Start,
|
||||||
LoLoop.Start->getOperand(0).getReg())) {
|
LoLoop.Start->getOperand(0).getReg());
|
||||||
SmallPtrSet<MachineInstr*, 4> Remove;
|
if (!Def)
|
||||||
SmallPtrSet<MachineInstr*, 4> Ignore = { LoLoop.Start, LoLoop.Dec,
|
return;
|
||||||
LoLoop.End, LoLoop.InsertPt };
|
|
||||||
SmallVector<MachineInstr*, 4> Chain = { Def };
|
|
||||||
while (!Chain.empty()) {
|
|
||||||
MachineInstr *MI = Chain.back();
|
|
||||||
Chain.pop_back();
|
|
||||||
|
|
||||||
// If an instruction is conditionally executed, we assume here that this
|
// Collect IT blocks.
|
||||||
// an IT-block with just this single instruction in it, otherwise we
|
std::map<MachineInstr *, SmallPtrSet<MachineInstr *, 2>> ITBlocks;
|
||||||
// continue and can't perform dead-code elimination on it. This will
|
std::map<MachineInstr *, MachineInstr *> Predicates;
|
||||||
// capture most cases, because the loop iteration count expression
|
MachineInstr *IT = nullptr;
|
||||||
// that performs a round-up to next multiple of the vector length will
|
for (auto &MI : *Def->getParent()) {
|
||||||
// look like this:
|
if (MI.getOpcode() == ARM::t2IT)
|
||||||
//
|
IT = &MI;
|
||||||
// %mull = ..
|
else if (TII->getPredicate(MI) != ARMCC::AL) {
|
||||||
// %0 = add i32 %mul, 3
|
ITBlocks[IT].insert(&MI);
|
||||||
// %1 = icmp slt i32 %mul, 4
|
Predicates[&MI] = IT;
|
||||||
// %smin = select i1 %1, i32 %mul, i32 4
|
|
||||||
// %2 = sub i32 %0, %smin
|
|
||||||
// %3 = lshr i32 %2, 2
|
|
||||||
// %4 = add nuw nsw i32 %3, 1
|
|
||||||
//
|
|
||||||
// There can be a select instruction, checking if we need to execute only
|
|
||||||
// 1 vector iteration (in this examples that means 4 elements). Thus,
|
|
||||||
// we conditionally execute one instructions to materialise the iteration
|
|
||||||
// count.
|
|
||||||
MachineInstr *IT = nullptr;
|
|
||||||
if (TII->getPredicate(*MI) != ARMCC::AL) {
|
|
||||||
auto PrevMI = std::prev(MI->getIterator());
|
|
||||||
auto NextMI = std::next(MI->getIterator());
|
|
||||||
|
|
||||||
if (PrevMI->getOpcode() == ARM::t2IT &&
|
|
||||||
TII->getPredicate(*NextMI) == ARMCC::AL)
|
|
||||||
IT = &*PrevMI;
|
|
||||||
else
|
|
||||||
// We can't analyse IT-blocks with multiple statements. Be
|
|
||||||
// conservative here: clear the list, and don't remove any statements
|
|
||||||
// at all.
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (RDA->isSafeToRemove(MI, Remove, Ignore)) {
|
|
||||||
for (auto &MO : MI->operands()) {
|
|
||||||
if (!MO.isReg() || !MO.isUse() || MO.getReg() == 0)
|
|
||||||
continue;
|
|
||||||
if (auto *Op = RDA->getReachingMIDef(MI, MO.getReg()))
|
|
||||||
Chain.push_back(Op);
|
|
||||||
}
|
|
||||||
Ignore.insert(MI);
|
|
||||||
|
|
||||||
if (IT)
|
|
||||||
Remove.insert(IT);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
LoLoop.ToRemove.insert(Remove.begin(), Remove.end());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If we're removing all of the instructions within an IT block, then
|
||||||
|
// also remove the IT instruction.
|
||||||
|
SmallPtrSet<MachineInstr*, 2> ModifiedITs;
|
||||||
|
SmallPtrSet<MachineInstr*, 2> DeadITs;
|
||||||
|
SmallPtrSet<MachineInstr*, 4> Killed;
|
||||||
|
RDA->collectLocalKilledOperands(Def, Killed);
|
||||||
|
for (auto *MI : Killed) {
|
||||||
|
if (!Predicates.count(MI))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
MachineInstr *IT = Predicates[MI];
|
||||||
|
auto &CurrentBlock = ITBlocks[IT];
|
||||||
|
CurrentBlock.erase(MI);
|
||||||
|
ModifiedITs.insert(IT);
|
||||||
|
if (CurrentBlock.empty()) {
|
||||||
|
DeadITs.insert(IT);
|
||||||
|
ModifiedITs.erase(IT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delete the killed instructions only if we don't have any IT blocks that
|
||||||
|
// need to be modified because we need to fixup the mask.
|
||||||
|
// TODO: Handle cases where IT blocks are modified.
|
||||||
|
if (ModifiedITs.empty()) {
|
||||||
|
LLVM_DEBUG(dbgs() << "ARM Loops: Will remove iteration count:\n";
|
||||||
|
for (auto *MI : Killed)
|
||||||
|
dbgs() << " - " << *MI;
|
||||||
|
for (auto *MI : DeadITs)
|
||||||
|
dbgs() << " - " << *MI);
|
||||||
|
LoLoop.ToRemove.insert(Killed.begin(), Killed.end());
|
||||||
|
LoLoop.ToRemove.insert(DeadITs.begin(), DeadITs.end());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Collect and remove the users of iteration count.
|
||||||
|
SmallPtrSet<MachineInstr*, 4> Ignore = { LoLoop.Start, LoLoop.Dec,
|
||||||
|
LoLoop.End, LoLoop.InsertPt };
|
||||||
|
SmallPtrSet<MachineInstr*, 2> Remove;
|
||||||
|
if (RDA->isSafeToRemove(Def, Remove, Ignore))
|
||||||
|
LoLoop.ToRemove.insert(Remove.begin(), Remove.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
MachineInstr* ARMLowOverheadLoops::ExpandLoopStart(LowOverheadLoop &LoLoop) {
|
MachineInstr* ARMLowOverheadLoops::ExpandLoopStart(LowOverheadLoop &LoLoop) {
|
||||||
|
|
|
@ -95,12 +95,12 @@ body: |
|
||||||
; CHECK-LABEL: name: dont_ignore_vctp
|
; CHECK-LABEL: name: dont_ignore_vctp
|
||||||
; CHECK: bb.0.entry:
|
; CHECK: bb.0.entry:
|
||||||
; CHECK: successors: %bb.1(0x80000000)
|
; CHECK: successors: %bb.1(0x80000000)
|
||||||
; CHECK: liveins: $lr, $r0, $r1, $r2, $r7
|
; CHECK: liveins: $lr, $r0, $r1, $r3, $r7
|
||||||
; CHECK: frame-setup tPUSH 14, $noreg, killed $r7, killed $lr, implicit-def $sp, implicit $sp
|
; CHECK: frame-setup tPUSH 14, $noreg, killed $r7, killed $lr, implicit-def $sp, implicit $sp
|
||||||
; CHECK: frame-setup CFI_INSTRUCTION def_cfa_offset 8
|
; CHECK: frame-setup CFI_INSTRUCTION def_cfa_offset 8
|
||||||
; CHECK: frame-setup CFI_INSTRUCTION offset $lr, -4
|
; CHECK: frame-setup CFI_INSTRUCTION offset $lr, -4
|
||||||
; CHECK: frame-setup CFI_INSTRUCTION offset $r7, -8
|
; CHECK: frame-setup CFI_INSTRUCTION offset $r7, -8
|
||||||
; CHECK: renamable $r3, dead $cpsr = tLSLri killed renamable $r2, 1, 14, $noreg
|
; CHECK: tCMPi8 renamable $r3, 4, 14, $noreg, implicit-def dead $cpsr
|
||||||
; CHECK: renamable $r2 = tLEApcrel %const.0, 14, $noreg
|
; CHECK: renamable $r2 = tLEApcrel %const.0, 14, $noreg
|
||||||
; CHECK: renamable $q0 = MVE_VLDRWU32 killed renamable $r2, 0, 0, $noreg :: (load 16 from constant-pool)
|
; CHECK: renamable $q0 = MVE_VLDRWU32 killed renamable $r2, 0, 0, $noreg :: (load 16 from constant-pool)
|
||||||
; CHECK: $lr = MVE_DLSTP_32 killed renamable $r3
|
; CHECK: $lr = MVE_DLSTP_32 killed renamable $r3
|
||||||
|
|
|
@ -110,9 +110,8 @@ body: |
|
||||||
; CHECK: $r3 = t2LSLri renamable $r2, 1, 11, $cpsr, $noreg, implicit renamable $r12, implicit $itstate
|
; CHECK: $r3 = t2LSLri renamable $r2, 1, 11, $cpsr, $noreg, implicit renamable $r12, implicit $itstate
|
||||||
; CHECK: $r12 = t2LSLri renamable $r3, 1, 11, killed $cpsr, $noreg, implicit killed renamable $r12, implicit killed $itstate
|
; CHECK: $r12 = t2LSLri renamable $r3, 1, 11, killed $cpsr, $noreg, implicit killed renamable $r12, implicit killed $itstate
|
||||||
; CHECK: renamable $r2 = t2RSBrs killed renamable $r12, killed renamable $r2, 10, 14, $noreg, $noreg
|
; CHECK: renamable $r2 = t2RSBrs killed renamable $r12, killed renamable $r2, 10, 14, $noreg, $noreg
|
||||||
; CHECK: renamable $r12 = t2ADDri killed renamable $r2, 3, 14, $noreg, $noreg
|
; CHECK: dead renamable $r12 = t2ADDri killed renamable $r2, 3, 14, $noreg, $noreg
|
||||||
; CHECK: renamable $r2, dead $cpsr = tMOVi8 1, 14, $noreg
|
; CHECK: dead renamable $r2, dead $cpsr = tMOVi8 1, 14, $noreg
|
||||||
; CHECK: dead renamable $lr = nuw nsw t2ADDrs killed renamable $r2, killed renamable $r12, 19, 14, $noreg, $noreg
|
|
||||||
; CHECK: renamable $r2 = tLEApcrel %const.0, 14, $noreg
|
; CHECK: renamable $r2 = tLEApcrel %const.0, 14, $noreg
|
||||||
; CHECK: renamable $q0 = MVE_VLDRWU32 killed renamable $r2, 0, 0, $noreg :: (load 16 from constant-pool)
|
; CHECK: renamable $q0 = MVE_VLDRWU32 killed renamable $r2, 0, 0, $noreg :: (load 16 from constant-pool)
|
||||||
; CHECK: $lr = MVE_DLSTP_32 killed renamable $r3
|
; CHECK: $lr = MVE_DLSTP_32 killed renamable $r3
|
||||||
|
|
|
@ -103,16 +103,9 @@ body: |
|
||||||
; CHECK: frame-setup CFI_INSTRUCTION def_cfa_offset 8
|
; CHECK: frame-setup CFI_INSTRUCTION def_cfa_offset 8
|
||||||
; CHECK: frame-setup CFI_INSTRUCTION offset $lr, -4
|
; CHECK: frame-setup CFI_INSTRUCTION offset $lr, -4
|
||||||
; CHECK: frame-setup CFI_INSTRUCTION offset $r7, -8
|
; CHECK: frame-setup CFI_INSTRUCTION offset $r7, -8
|
||||||
; CHECK: renamable $r3, dead $cpsr = tLSLri renamable $r2, 1, 14, $noreg
|
; CHECK: renamable $r3, dead $cpsr = tLSLri killed renamable $r2, 1, 14, $noreg
|
||||||
; CHECK: renamable $r12 = t2MOVi 4, 14, $noreg, $noreg
|
; CHECK: dead renamable $r12 = t2MOVi 4, 14, $noreg, $noreg
|
||||||
; CHECK: tCMPi8 renamable $r3, 4, 14, $noreg, implicit-def $cpsr
|
; CHECK: tCMPi8 renamable $r3, 4, 14, $noreg, implicit-def dead $cpsr
|
||||||
; CHECK: t2IT 11, 8, implicit-def $itstate
|
|
||||||
; CHECK: $r12 = t2LSLri renamable $r2, 1, 11, $cpsr, $noreg, implicit killed renamable $r12, implicit $itstate
|
|
||||||
; CHECK: $r12 = t2LSLri renamable $r2, 1, 11, killed $cpsr, $noreg, implicit killed renamable $r12, implicit killed $itstate
|
|
||||||
; CHECK: renamable $r2 = t2RSBrs killed renamable $r12, killed renamable $r2, 10, 14, $noreg, $noreg
|
|
||||||
; CHECK: renamable $r12 = t2ADDri killed renamable $r2, 3, 14, $noreg, $noreg
|
|
||||||
; CHECK: renamable $r2, dead $cpsr = tMOVi8 1, 14, $noreg
|
|
||||||
; CHECK: dead renamable $lr = nuw nsw t2ADDrs killed renamable $r2, killed renamable $r12, 19, 14, $noreg, $noreg
|
|
||||||
; CHECK: renamable $r2 = tLEApcrel %const.0, 14, $noreg
|
; CHECK: renamable $r2 = tLEApcrel %const.0, 14, $noreg
|
||||||
; CHECK: renamable $q0 = MVE_VLDRWU32 killed renamable $r2, 0, 0, $noreg :: (load 16 from constant-pool)
|
; CHECK: renamable $q0 = MVE_VLDRWU32 killed renamable $r2, 0, 0, $noreg :: (load 16 from constant-pool)
|
||||||
; CHECK: $lr = MVE_DLSTP_32 killed renamable $r3
|
; CHECK: $lr = MVE_DLSTP_32 killed renamable $r3
|
||||||
|
|
|
@ -0,0 +1,218 @@
|
||||||
|
# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
|
||||||
|
# RUN: llc -mtriple=thumbv8.1m.main -run-pass=arm-low-overhead-loops %s -o - --verify-machineinstrs | FileCheck %s
|
||||||
|
|
||||||
|
--- |
|
||||||
|
; Function Attrs: nounwind
|
||||||
|
define hidden arm_aapcs_vfpcc void @cond_trip_count(float* %0, i32 %1, float* nocapture %2) local_unnamed_addr #1 {
|
||||||
|
ret void
|
||||||
|
}
|
||||||
|
|
||||||
|
...
|
||||||
|
---
|
||||||
|
name: cond_trip_count
|
||||||
|
alignment: 4
|
||||||
|
tracksRegLiveness: true
|
||||||
|
registers: []
|
||||||
|
liveins:
|
||||||
|
- { reg: '$r0', virtual-reg: '' }
|
||||||
|
- { reg: '$r1', virtual-reg: '' }
|
||||||
|
- { reg: '$r2', virtual-reg: '' }
|
||||||
|
frameInfo:
|
||||||
|
stackSize: 8
|
||||||
|
offsetAdjustment: 0
|
||||||
|
maxAlignment: 4
|
||||||
|
fixedStack: []
|
||||||
|
stack:
|
||||||
|
- { id: 0, name: '', type: spill-slot, offset: -4, size: 4, alignment: 4,
|
||||||
|
stack-id: default, callee-saved-register: '$lr', callee-saved-restored: false,
|
||||||
|
debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
|
||||||
|
- { id: 1, name: '', type: spill-slot, offset: -8, size: 4, alignment: 4,
|
||||||
|
stack-id: default, callee-saved-register: '$r4', callee-saved-restored: true,
|
||||||
|
debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
|
||||||
|
callSites: []
|
||||||
|
constants:
|
||||||
|
- id: 0
|
||||||
|
value: 'float 0.000000e+00'
|
||||||
|
alignment: 4
|
||||||
|
isTargetSpecific: false
|
||||||
|
machineFunctionInfo: {}
|
||||||
|
body: |
|
||||||
|
; CHECK-LABEL: name: cond_trip_count
|
||||||
|
; CHECK: bb.0:
|
||||||
|
; CHECK: successors: %bb.1(0x40000000), %bb.2(0x40000000)
|
||||||
|
; CHECK: liveins: $lr, $r0, $r1, $r2, $r4
|
||||||
|
; CHECK: frame-setup tPUSH 14, $noreg, killed $r4, killed $lr, implicit-def $sp, implicit $sp
|
||||||
|
; CHECK: frame-setup CFI_INSTRUCTION def_cfa_offset 8
|
||||||
|
; CHECK: frame-setup CFI_INSTRUCTION offset $lr, -4
|
||||||
|
; CHECK: frame-setup CFI_INSTRUCTION offset $r4, -8
|
||||||
|
; CHECK: tCMPi8 renamable $r1, 4, 14, $noreg, implicit-def $cpsr
|
||||||
|
; CHECK: renamable $r3 = t2MOVi 4, 14, $noreg, $noreg
|
||||||
|
; CHECK: t2IT 11, 8, implicit-def $itstate
|
||||||
|
; CHECK: dead $r3 = tMOVr renamable $r1, 11, killed $cpsr, implicit killed renamable $r3, implicit killed $itstate
|
||||||
|
; CHECK: tCMPi8 renamable $r1, 2, 14, $noreg, implicit-def $cpsr
|
||||||
|
; CHECK: renamable $r12 = t2MOVi 4, 14, $noreg, $noreg
|
||||||
|
; CHECK: tBcc %bb.2, 2, killed $cpsr
|
||||||
|
; CHECK: bb.1:
|
||||||
|
; CHECK: liveins: $r2
|
||||||
|
; CHECK: renamable $s0 = VLDRS %const.0, 0, 14, $noreg
|
||||||
|
; CHECK: VSTRS killed renamable $s0, killed renamable $r2, 0, 14, $noreg
|
||||||
|
; CHECK: tPOP_RET 14, $noreg, def $r4, def $pc
|
||||||
|
; CHECK: bb.2:
|
||||||
|
; CHECK: successors: %bb.3(0x80000000)
|
||||||
|
; CHECK: liveins: $r0, $r1, $r2, $r12
|
||||||
|
; CHECK: renamable $r4, dead $cpsr = tMOVi8 1, 14, $noreg
|
||||||
|
; CHECK: tCMPi8 renamable $r1, 4, 14, $noreg, implicit-def $cpsr
|
||||||
|
; CHECK: t2IT 11, 8, implicit-def $itstate
|
||||||
|
; CHECK: $r12 = tMOVr renamable $r1, 11, killed $cpsr, implicit killed renamable $r12, implicit killed $itstate
|
||||||
|
; CHECK: renamable $r3 = t2SUBrr renamable $r1, killed renamable $r12, 14, $noreg, $noreg
|
||||||
|
; CHECK: renamable $r3, dead $cpsr = tADDi8 killed renamable $r3, 3, 14, $noreg
|
||||||
|
; CHECK: $r12 = tMOVr $r1, 14, $noreg
|
||||||
|
; CHECK: dead renamable $r4 = nuw nsw t2ADDrs killed renamable $r4, killed renamable $r3, 19, 14, $noreg, $noreg
|
||||||
|
; CHECK: renamable $q0 = MVE_VMOVimmi32 0, 0, $noreg, undef renamable $q0
|
||||||
|
; CHECK: $r3 = tMOVr $r0, 14, $noreg
|
||||||
|
; CHECK: $lr = MVE_DLSTP_32 killed renamable $r12
|
||||||
|
; CHECK: bb.3:
|
||||||
|
; CHECK: successors: %bb.3(0x7c000000), %bb.4(0x04000000)
|
||||||
|
; CHECK: liveins: $lr, $q0, $r0, $r1, $r2, $r3
|
||||||
|
; CHECK: renamable $q1 = nnan ninf nsz MVE_VLDRWU32 renamable $r3, 0, 0, $noreg
|
||||||
|
; CHECK: renamable $q0 = nnan ninf nsz MVE_VADDf32 killed renamable $q0, killed renamable $q1, 0, killed $noreg, killed renamable $q0
|
||||||
|
; CHECK: renamable $r3, dead $cpsr = nuw tADDi8 killed renamable $r3, 16, 14, $noreg
|
||||||
|
; CHECK: $lr = MVE_LETP killed renamable $lr, %bb.3
|
||||||
|
; CHECK: bb.4:
|
||||||
|
; CHECK: successors: %bb.5(0x80000000)
|
||||||
|
; CHECK: liveins: $q0, $r0, $r1, $r2
|
||||||
|
; CHECK: renamable $s4 = nnan ninf nsz VADDS renamable $s0, renamable $s1, 14, $noreg
|
||||||
|
; CHECK: $r3 = tMOVr $r1, 14, $noreg
|
||||||
|
; CHECK: $lr = MVE_DLSTP_32 killed renamable $r3
|
||||||
|
; CHECK: renamable $s4 = nnan ninf nsz VADDS renamable $s2, killed renamable $s4, 14, $noreg
|
||||||
|
; CHECK: renamable $s0 = nnan ninf nsz VADDS killed renamable $s3, killed renamable $s4, 14, $noreg, implicit killed $q0
|
||||||
|
; CHECK: $s2 = VMOVSR $r1, 14, $noreg
|
||||||
|
; CHECK: renamable $s2 = VUITOS killed renamable $s2, 14, $noreg
|
||||||
|
; CHECK: renamable $s4 = nnan ninf nsz VDIVS killed renamable $s0, killed renamable $s2, 14, $noreg
|
||||||
|
; CHECK: renamable $q0 = MVE_VMOVimmi32 0, 0, $noreg, undef renamable $q0
|
||||||
|
; CHECK: bb.5:
|
||||||
|
; CHECK: successors: %bb.5(0x7c000000), %bb.6(0x04000000)
|
||||||
|
; CHECK: liveins: $lr, $q0, $r0, $r1, $r2, $s4
|
||||||
|
; CHECK: $r4 = VMOVRS $s4, 14, $noreg
|
||||||
|
; CHECK: renamable $q2 = nnan ninf nsz MVE_VLDRWU32 renamable $r0, 0, 0, $noreg
|
||||||
|
; CHECK: renamable $q2 = nnan ninf nsz MVE_VSUB_qr_f32 killed renamable $q2, killed renamable $r4, 0, $noreg, undef renamable $q2
|
||||||
|
; CHECK: renamable $q0 = nnan ninf nsz MVE_VFMAf32 killed renamable $q0, killed renamable $q2, killed renamable $q2, 0, killed $noreg
|
||||||
|
; CHECK: renamable $r0, dead $cpsr = nuw tADDi8 killed renamable $r0, 16, 14, $noreg
|
||||||
|
; CHECK: $lr = MVE_LETP killed renamable $lr, %bb.5
|
||||||
|
; CHECK: bb.6:
|
||||||
|
; CHECK: liveins: $q0, $r1, $r2
|
||||||
|
; CHECK: renamable $s4 = nnan ninf nsz VADDS renamable $s0, renamable $s1, 14, $noreg
|
||||||
|
; CHECK: renamable $r0, dead $cpsr = tSUBi3 killed renamable $r1, 1, 14, $noreg
|
||||||
|
; CHECK: renamable $s4 = nnan ninf nsz VADDS renamable $s2, killed renamable $s4, 14, $noreg
|
||||||
|
; CHECK: renamable $s0 = nnan ninf nsz VADDS killed renamable $s3, killed renamable $s4, 14, $noreg, implicit killed $q0
|
||||||
|
; CHECK: $s2 = VMOVSR killed $r0, 14, $noreg
|
||||||
|
; CHECK: renamable $s2 = VUITOS killed renamable $s2, 14, $noreg
|
||||||
|
; CHECK: renamable $s0 = nnan ninf nsz VDIVS killed renamable $s0, killed renamable $s2, 14, $noreg
|
||||||
|
; CHECK: VSTRS killed renamable $s0, killed renamable $r2, 0, 14, $noreg
|
||||||
|
; CHECK: tPOP_RET 14, $noreg, def $r4, def $pc
|
||||||
|
; CHECK: bb.7 (align 4):
|
||||||
|
; CHECK: CONSTPOOL_ENTRY 0, %const.0, 4
|
||||||
|
bb.0:
|
||||||
|
successors: %bb.1(0x40000000), %bb.2(0x40000000)
|
||||||
|
liveins: $r0, $r1, $r2, $r4, $lr
|
||||||
|
|
||||||
|
frame-setup tPUSH 14, $noreg, killed $r4, killed $lr, implicit-def $sp, implicit $sp
|
||||||
|
frame-setup CFI_INSTRUCTION def_cfa_offset 8
|
||||||
|
frame-setup CFI_INSTRUCTION offset $lr, -4
|
||||||
|
frame-setup CFI_INSTRUCTION offset $r4, -8
|
||||||
|
tCMPi8 renamable $r1, 4, 14, $noreg, implicit-def $cpsr
|
||||||
|
renamable $r3 = t2MOVi 4, 14, $noreg, $noreg
|
||||||
|
t2IT 11, 8, implicit-def $itstate
|
||||||
|
$r3 = tMOVr renamable $r1, 11, killed $cpsr, implicit killed renamable $r3, implicit killed $itstate
|
||||||
|
tCMPi8 renamable $r1, 2, 14, $noreg, implicit-def $cpsr
|
||||||
|
renamable $r12 = t2MOVi 4, 14, $noreg, $noreg
|
||||||
|
tBcc %bb.2, 2, killed $cpsr
|
||||||
|
|
||||||
|
bb.1:
|
||||||
|
liveins: $r2
|
||||||
|
|
||||||
|
renamable $s0 = VLDRS %const.0, 0, 14, $noreg
|
||||||
|
VSTRS killed renamable $s0, killed renamable $r2, 0, 14, $noreg
|
||||||
|
tPOP_RET 14, $noreg, def $r4, def $pc
|
||||||
|
|
||||||
|
bb.2:
|
||||||
|
successors: %bb.3(0x80000000)
|
||||||
|
liveins: $r0, $r1, $r2, $r3, $r12
|
||||||
|
|
||||||
|
renamable $r3, dead $cpsr = tSUBrr renamable $r1, killed renamable $r3, 14, $noreg
|
||||||
|
renamable $r4, dead $cpsr = tMOVi8 1, 14, $noreg
|
||||||
|
renamable $r3, dead $cpsr = tADDi8 killed renamable $r3, 3, 14, $noreg
|
||||||
|
tCMPi8 renamable $r1, 4, 14, $noreg, implicit-def $cpsr
|
||||||
|
renamable $lr = nuw nsw t2ADDrs renamable $r4, killed renamable $r3, 19, 14, $noreg, $noreg
|
||||||
|
t2IT 11, 8, implicit-def $itstate
|
||||||
|
$r12 = tMOVr renamable $r1, 11, killed $cpsr, implicit killed renamable $r12, implicit killed $itstate
|
||||||
|
renamable $r3 = t2SUBrr renamable $r1, killed renamable $r12, 14, $noreg, $noreg
|
||||||
|
renamable $r3, dead $cpsr = tADDi8 killed renamable $r3, 3, 14, $noreg
|
||||||
|
$r12 = tMOVr $r1, 14, $noreg
|
||||||
|
renamable $r4 = nuw nsw t2ADDrs killed renamable $r4, killed renamable $r3, 19, 14, $noreg, $noreg
|
||||||
|
renamable $q0 = MVE_VMOVimmi32 0, 0, $noreg, undef renamable $q0
|
||||||
|
$r3 = tMOVr $r0, 14, $noreg
|
||||||
|
t2DoLoopStart renamable $lr
|
||||||
|
|
||||||
|
bb.3:
|
||||||
|
successors: %bb.3(0x7c000000), %bb.4(0x04000000)
|
||||||
|
liveins: $lr, $q0, $r0, $r1, $r2, $r3, $r4, $r12
|
||||||
|
|
||||||
|
renamable $vpr = MVE_VCTP32 renamable $r12, 0, $noreg
|
||||||
|
renamable $lr = t2LoopDec killed renamable $lr, 1
|
||||||
|
MVE_VPST 4, implicit $vpr
|
||||||
|
renamable $q1 = nnan ninf nsz MVE_VLDRWU32 renamable $r3, 0, 1, renamable $vpr
|
||||||
|
renamable $q0 = nnan ninf nsz MVE_VADDf32 killed renamable $q0, killed renamable $q1, 1, killed renamable $vpr, renamable $q0
|
||||||
|
renamable $r12 = nsw t2SUBri killed renamable $r12, 4, 14, $noreg, $noreg
|
||||||
|
renamable $r3, dead $cpsr = nuw tADDi8 killed renamable $r3, 16, 14, $noreg
|
||||||
|
t2LoopEnd renamable $lr, %bb.3, implicit-def dead $cpsr
|
||||||
|
tB %bb.4, 14, $noreg
|
||||||
|
|
||||||
|
bb.4:
|
||||||
|
successors: %bb.5(0x80000000)
|
||||||
|
liveins: $q0, $r0, $r1, $r2, $r4
|
||||||
|
|
||||||
|
renamable $s4 = nnan ninf nsz VADDS renamable $s0, renamable $s1, 14, $noreg
|
||||||
|
$lr = tMOVr $r4, 14, $noreg
|
||||||
|
$r3 = tMOVr $r1, 14, $noreg
|
||||||
|
renamable $s4 = nnan ninf nsz VADDS renamable $s2, killed renamable $s4, 14, $noreg
|
||||||
|
renamable $s0 = nnan ninf nsz VADDS killed renamable $s3, killed renamable $s4, 14, $noreg, implicit $q0
|
||||||
|
$s2 = VMOVSR $r1, 14, $noreg
|
||||||
|
renamable $s2 = VUITOS killed renamable $s2, 14, $noreg
|
||||||
|
t2DoLoopStart killed $r4
|
||||||
|
renamable $s4 = nnan ninf nsz VDIVS killed renamable $s0, killed renamable $s2, 14, $noreg
|
||||||
|
renamable $q0 = MVE_VMOVimmi32 0, 0, $noreg, undef renamable $q0
|
||||||
|
|
||||||
|
bb.5:
|
||||||
|
successors: %bb.5(0x7c000000), %bb.6(0x04000000)
|
||||||
|
liveins: $lr, $q0, $r0, $r1, $r2, $r3, $s4
|
||||||
|
|
||||||
|
renamable $vpr = MVE_VCTP32 renamable $r3, 0, $noreg
|
||||||
|
$r4 = VMOVRS $s4, 14, $noreg
|
||||||
|
MVE_VPST 2, implicit $vpr
|
||||||
|
renamable $q2 = nnan ninf nsz MVE_VLDRWU32 renamable $r0, 0, 1, renamable $vpr
|
||||||
|
renamable $q2 = nnan ninf nsz MVE_VSUB_qr_f32 killed renamable $q2, killed renamable $r4, 1, renamable $vpr, undef renamable $q2
|
||||||
|
renamable $q0 = nnan ninf nsz MVE_VFMAf32 killed renamable $q0, killed renamable $q2, renamable $q2, 1, killed renamable $vpr
|
||||||
|
renamable $lr = t2LoopDec killed renamable $lr, 1
|
||||||
|
renamable $r3, dead $cpsr = nsw tSUBi8 killed renamable $r3, 4, 14, $noreg
|
||||||
|
renamable $r0, dead $cpsr = nuw tADDi8 killed renamable $r0, 16, 14, $noreg
|
||||||
|
t2LoopEnd renamable $lr, %bb.5, implicit-def dead $cpsr
|
||||||
|
tB %bb.6, 14, $noreg
|
||||||
|
|
||||||
|
bb.6:
|
||||||
|
liveins: $q0, $r1, $r2
|
||||||
|
|
||||||
|
renamable $s4 = nnan ninf nsz VADDS renamable $s0, renamable $s1, 14, $noreg
|
||||||
|
renamable $r0, dead $cpsr = tSUBi3 killed renamable $r1, 1, 14, $noreg
|
||||||
|
renamable $s4 = nnan ninf nsz VADDS renamable $s2, killed renamable $s4, 14, $noreg
|
||||||
|
renamable $s0 = nnan ninf nsz VADDS killed renamable $s3, killed renamable $s4, 14, $noreg, implicit $q0
|
||||||
|
$s2 = VMOVSR killed $r0, 14, $noreg
|
||||||
|
renamable $s2 = VUITOS killed renamable $s2, 14, $noreg
|
||||||
|
renamable $s0 = nnan ninf nsz VDIVS killed renamable $s0, killed renamable $s2, 14, $noreg
|
||||||
|
VSTRS killed renamable $s0, killed renamable $r2, 0, 14, $noreg
|
||||||
|
tPOP_RET 14, $noreg, def $r4, def $pc
|
||||||
|
|
||||||
|
bb.7 (align 4):
|
||||||
|
CONSTPOOL_ENTRY 0, %const.0, 4
|
||||||
|
|
||||||
|
...
|
|
@ -111,9 +111,8 @@ body: |
|
||||||
; CHECK: $r12 = t2LSLri renamable $r2, 1, 11, $cpsr, $noreg, implicit killed renamable $r12, implicit $itstate
|
; CHECK: $r12 = t2LSLri renamable $r2, 1, 11, $cpsr, $noreg, implicit killed renamable $r12, implicit $itstate
|
||||||
; CHECK: $r0 = t2ADDri killed renamable $r0, 42, 11, killed $cpsr, $noreg, implicit killed renamable $r0, implicit killed $itstate
|
; CHECK: $r0 = t2ADDri killed renamable $r0, 42, 11, killed $cpsr, $noreg, implicit killed renamable $r0, implicit killed $itstate
|
||||||
; CHECK: renamable $r2 = t2RSBrs killed renamable $r12, killed renamable $r2, 10, 14, $noreg, $noreg
|
; CHECK: renamable $r2 = t2RSBrs killed renamable $r12, killed renamable $r2, 10, 14, $noreg, $noreg
|
||||||
; CHECK: renamable $r12 = t2ADDri killed renamable $r2, 3, 14, $noreg, $noreg
|
; CHECK: dead renamable $r12 = t2ADDri killed renamable $r2, 3, 14, $noreg, $noreg
|
||||||
; CHECK: renamable $r2, dead $cpsr = tMOVi8 1, 14, $noreg
|
; CHECK: dead renamable $r2, dead $cpsr = tMOVi8 1, 14, $noreg
|
||||||
; CHECK: dead renamable $lr = nuw nsw t2ADDrs killed renamable $r2, killed renamable $r12, 19, 14, $noreg, $noreg
|
|
||||||
; CHECK: renamable $r2 = tLEApcrel %const.0, 14, $noreg
|
; CHECK: renamable $r2 = tLEApcrel %const.0, 14, $noreg
|
||||||
; CHECK: renamable $q0 = MVE_VLDRWU32 killed renamable $r2, 0, 0, $noreg :: (load 16 from constant-pool)
|
; CHECK: renamable $q0 = MVE_VLDRWU32 killed renamable $r2, 0, 0, $noreg :: (load 16 from constant-pool)
|
||||||
; CHECK: $lr = MVE_DLSTP_32 killed renamable $r3
|
; CHECK: $lr = MVE_DLSTP_32 killed renamable $r3
|
||||||
|
|
Loading…
Reference in New Issue