When the "true" and "false" blocks of a diamond if-conversion are the same,

do not double-count the duplicate instructions by counting once from the
beginning and again from the end.  Keep track of where the duplicates from
the beginning ended and don't go past that point when counting duplicates
at the end.  Radar 8589805.

This change causes one of the MC/ARM/simple-fp-encoding tests to produce
different (better!) code without the vmovne instruction being tested.
I changed the test to produce vmovne and vmoveq instructions but moving
between register files in the opposite direction.  That's not quite the same
but predicated versions of those instructions weren't being tested before,
so at least the test coverage is not any worse, just different.

llvm-svn: 117333
This commit is contained in:
Bob Wilson 2010-10-26 00:02:24 +00:00
parent efd360c535
commit e1961fe289
3 changed files with 90 additions and 65 deletions

View File

@ -520,18 +520,6 @@ bool IfConverter::ValidTriangle(BBInfo &TrueBBI, BBInfo &FalseBBI,
return TExit && TExit == FalseBBI.BB; return TExit && TExit == FalseBBI.BB;
} }
static
MachineBasicBlock::iterator firstNonBranchInst(MachineBasicBlock *BB,
const TargetInstrInfo *TII) {
MachineBasicBlock::iterator I = BB->end();
while (I != BB->begin()) {
--I;
if (!I->getDesc().isBranch())
break;
}
return I;
}
/// ValidDiamond - Returns true if the 'true' and 'false' blocks (along /// ValidDiamond - Returns true if the 'true' and 'false' blocks (along
/// with their common predecessor) forms a valid diamond shape for ifcvt. /// with their common predecessor) forms a valid diamond shape for ifcvt.
bool IfConverter::ValidDiamond(BBInfo &TrueBBI, BBInfo &FalseBBI, bool IfConverter::ValidDiamond(BBInfo &TrueBBI, BBInfo &FalseBBI,
@ -560,64 +548,70 @@ bool IfConverter::ValidDiamond(BBInfo &TrueBBI, BBInfo &FalseBBI,
(TrueBBI.ClobbersPred && FalseBBI.ClobbersPred)) (TrueBBI.ClobbersPred && FalseBBI.ClobbersPred))
return false; return false;
MachineBasicBlock::iterator TI = TrueBBI.BB->begin(); // Count duplicate instructions at the beginning of the true and false blocks.
MachineBasicBlock::iterator FI = FalseBBI.BB->begin();
MachineBasicBlock::iterator TIE = TrueBBI.BB->end();
MachineBasicBlock::iterator FIE = FalseBBI.BB->end();
// Skip dbg_value instructions
while (TI != TIE && TI->isDebugValue())
++TI;
while (FI != FIE && FI->isDebugValue())
++FI;
while (TI != TIE && FI != FIE) {
// Skip dbg_value instructions. These do not count.
if (TI->isDebugValue()) {
while (TI != TIE && TI->isDebugValue())
++TI;
if (TI == TIE)
break;
}
if (FI->isDebugValue()) {
while (FI != FIE && FI->isDebugValue())
++FI;
if (FI == FIE)
break;
}
if (!TI->isIdenticalTo(FI))
break;
++Dups1;
++TI;
++FI;
}
TI = firstNonBranchInst(TrueBBI.BB, TII);
FI = firstNonBranchInst(FalseBBI.BB, TII);
MachineBasicBlock::iterator TIB = TrueBBI.BB->begin(); MachineBasicBlock::iterator TIB = TrueBBI.BB->begin();
MachineBasicBlock::iterator FIB = FalseBBI.BB->begin(); MachineBasicBlock::iterator FIB = FalseBBI.BB->begin();
// Skip dbg_value instructions at end of the bb's. MachineBasicBlock::iterator TIE = TrueBBI.BB->end();
while (TI != TIB && TI->isDebugValue()) MachineBasicBlock::iterator FIE = FalseBBI.BB->end();
--TI; while (TIB != TIE && FIB != FIE) {
while (FI != FIB && FI->isDebugValue())
--FI;
while (TI != TIB && FI != FIB) {
// Skip dbg_value instructions. These do not count. // Skip dbg_value instructions. These do not count.
if (TI->isDebugValue()) { if (TIB->isDebugValue()) {
while (TI != TIB && TI->isDebugValue()) while (TIB != TIE && TIB->isDebugValue())
--TI; ++TIB;
if (TI == TIB) if (TIB == TIE)
break; break;
} }
if (FI->isDebugValue()) { if (FIB->isDebugValue()) {
while (FI != FIB && FI->isDebugValue()) while (FIB != FIE && FIB->isDebugValue())
--FI; ++FIB;
if (FI == FIB) if (FIB == FIE)
break; break;
} }
if (!TI->isIdenticalTo(FI)) if (!TIB->isIdenticalTo(FIB))
break;
++Dups1;
++TIB;
++FIB;
}
// Now, in preparation for counting duplicate instructions at the ends of the
// blocks, move the end iterators up past any branch instructions.
while (TIE != TIB) {
--TIE;
if (!TIE->getDesc().isBranch())
break;
}
while (FIE != FIB) {
--FIE;
if (!FIE->getDesc().isBranch())
break;
}
// If Dups1 includes all of a block, then don't count duplicate
// instructions at the end of the blocks.
if (TIB == TIE || FIB == FIE)
return true;
// Count duplicate instructions at the ends of the blocks.
while (TIE != TIB && FIE != FIB) {
// Skip dbg_value instructions. These do not count.
if (TIE->isDebugValue()) {
while (TIE != TIB && TIE->isDebugValue())
--TIE;
if (TIE == TIB)
break;
}
if (FIE->isDebugValue()) {
while (FIE != FIB && FIE->isDebugValue())
--FIE;
if (FIE == FIB)
break;
}
if (!TIE->isIdenticalTo(FIE))
break; break;
++Dups2; ++Dups2;
--TI; --TIE;
--FI; --FIE;
} }
return true; return true;

View File

@ -0,0 +1,31 @@
; RUN: llc < %s -mtriple=armv6-apple-darwin -mcpu=arm1136jf-s | FileCheck %s
; Radar 8589805: Counting the number of microcoded operations, such as for an
; LDM instruction, was causing an assertion failure because the microop count
; was being treated as an instruction count.
; CHECK: ldmia
; CHECK: ldmia
; CHECK: ldmia
; CHECK: ldmia
define i32 @test(i32 %x) {
entry:
%0 = tail call signext i16 undef(i32* undef)
switch i32 undef, label %bb3 [
i32 0, label %bb4
i32 1, label %bb1
i32 2, label %bb2
]
bb1:
ret i32 1
bb2:
ret i32 2
bb3:
ret i32 1
bb4:
ret i32 3
}

View File

@ -349,16 +349,16 @@ return: ; preds = %entry
ret double %a ret double %a
} }
define float @f99(float %a, i32 %i) nounwind readnone { define float @f99(float %a, float %b, i32 %i) nounwind readnone {
entry: entry:
%cmp = icmp eq i32 %i, 3 %cmp = icmp eq i32 %i, 3
br i1 %cmp, label %if.end, label %return br i1 %cmp, label %if.end, label %return
if.end: ; preds = %entry if.end: ; preds = %entry
; CHECK: f99 ; CHECK: f99
; CHECK: vmovne r0, s0 @ encoding: [0x10,0x0a,0x10,0x1e] ; CHECK: vmovne s0, r0 @ encoding: [0x10,0x0a,0x00,0x1e]
%sub = fsub float -0.000000e+00, %a ; CHECK: vmoveq s0, r1 @ encoding: [0x10,0x1a,0x00,0x0e]
ret float %sub ret float %b
return: ; preds = %entry return: ; preds = %entry
ret float %a ret float %a