diff --git a/lib/CodeGen/IfConversion.cpp b/lib/CodeGen/IfConversion.cpp index ce3eda78913..e90985bf899 100644 --- a/lib/CodeGen/IfConversion.cpp +++ b/lib/CodeGen/IfConversion.cpp @@ -520,18 +520,6 @@ bool IfConverter::ValidTriangle(BBInfo &TrueBBI, BBInfo &FalseBBI, 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 /// with their common predecessor) forms a valid diamond shape for ifcvt. bool IfConverter::ValidDiamond(BBInfo &TrueBBI, BBInfo &FalseBBI, @@ -560,64 +548,70 @@ bool IfConverter::ValidDiamond(BBInfo &TrueBBI, BBInfo &FalseBBI, (TrueBBI.ClobbersPred && FalseBBI.ClobbersPred)) return false; - MachineBasicBlock::iterator TI = TrueBBI.BB->begin(); - 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); + // Count duplicate instructions at the beginning of the true and false blocks. MachineBasicBlock::iterator TIB = TrueBBI.BB->begin(); MachineBasicBlock::iterator FIB = FalseBBI.BB->begin(); - // Skip dbg_value instructions at end of the bb's. - while (TI != TIB && TI->isDebugValue()) - --TI; - while (FI != FIB && FI->isDebugValue()) - --FI; - while (TI != TIB && FI != FIB) { + MachineBasicBlock::iterator TIE = TrueBBI.BB->end(); + MachineBasicBlock::iterator FIE = FalseBBI.BB->end(); + while (TIB != TIE && FIB != FIE) { // Skip dbg_value instructions. These do not count. - if (TI->isDebugValue()) { - while (TI != TIB && TI->isDebugValue()) - --TI; - if (TI == TIB) + if (TIB->isDebugValue()) { + while (TIB != TIE && TIB->isDebugValue()) + ++TIB; + if (TIB == TIE) break; } - if (FI->isDebugValue()) { - while (FI != FIB && FI->isDebugValue()) - --FI; - if (FI == FIB) + if (FIB->isDebugValue()) { + while (FIB != FIE && FIB->isDebugValue()) + ++FIB; + if (FIB == FIE) 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; ++Dups2; - --TI; - --FI; + --TIE; + --FIE; } return true; diff --git a/test/CodeGen/ARM/2010-10-25-ifcvt-ldm.ll b/test/CodeGen/ARM/2010-10-25-ifcvt-ldm.ll new file mode 100644 index 00000000000..2789ccd5cf5 --- /dev/null +++ b/test/CodeGen/ARM/2010-10-25-ifcvt-ldm.ll @@ -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 +} diff --git a/test/MC/ARM/simple-fp-encoding.ll b/test/MC/ARM/simple-fp-encoding.ll index 52379cbb94e..b941069244d 100644 --- a/test/MC/ARM/simple-fp-encoding.ll +++ b/test/MC/ARM/simple-fp-encoding.ll @@ -349,16 +349,16 @@ return: ; preds = %entry ret double %a } -define float @f99(float %a, i32 %i) nounwind readnone { +define float @f99(float %a, float %b, i32 %i) nounwind readnone { entry: %cmp = icmp eq i32 %i, 3 br i1 %cmp, label %if.end, label %return if.end: ; preds = %entry ; CHECK: f99 -; CHECK: vmovne r0, s0 @ encoding: [0x10,0x0a,0x10,0x1e] - %sub = fsub float -0.000000e+00, %a - ret float %sub +; CHECK: vmovne s0, r0 @ encoding: [0x10,0x0a,0x00,0x1e] +; CHECK: vmoveq s0, r1 @ encoding: [0x10,0x1a,0x00,0x0e] + ret float %b return: ; preds = %entry ret float %a