Index: llvm/trunk/lib/Transforms/InstCombine/InstCombineCompares.cpp =================================================================== --- llvm/trunk/lib/Transforms/InstCombine/InstCombineCompares.cpp +++ llvm/trunk/lib/Transforms/InstCombine/InstCombineCompares.cpp @@ -3950,7 +3950,7 @@ assert((SIOpd == 1 || SIOpd == 2) && "Invalid select operand!"); if (isChainSelectCmpBranch(SI) && Icmp->getPredicate() == ICmpInst::ICMP_EQ) { BasicBlock *Succ = SI->getParent()->getTerminator()->getSuccessor(1); - // The check for the unique predecessor is not the best that can be + // The check for the single predecessor is not the best that can be // done. But it protects efficiently against cases like when SI's // home block has two successors, Succ and Succ1, and Succ1 predecessor // of Succ. Then SI can't be replaced by SIOpd because the use that gets @@ -3958,8 +3958,10 @@ // guarantees that the path all uses of SI (outside SI's parent) are on // is disjoint from all other paths out of SI. But that information // is more expensive to compute, and the trade-off here is in favor - // of compile-time. - if (Succ->getUniquePredecessor() && dominatesAllUses(SI, Icmp, Succ)) { + // of compile-time. It should also be noticed that we check for a single + // predecessor and not only uniqueness. This to handle the situation when + // Succ and Succ1 points to the same basic block. + if (Succ->getSinglePredecessor() && dominatesAllUses(SI, Icmp, Succ)) { NumSel++; SI->replaceUsesOutsideBlock(SI->getOperand(SIOpd), SI->getParent()); return true; Index: llvm/trunk/test/Transforms/InstCombine/select-cmp-br.ll =================================================================== --- llvm/trunk/test/Transforms/InstCombine/select-cmp-br.ll +++ llvm/trunk/test/Transforms/InstCombine/select-cmp-br.ll @@ -242,3 +242,22 @@ br label %bb } +; Negative test. Must not trigger the select-cmp-br combine because the result +; of the select is used in both flows following the br (the special case where +; the conditional branch has the same target for both flows). +define i32 @test6(i32 %arg, i1 %arg1) { +; CHECK-LABEL: @test6( +; CHECK-NEXT: entry: +; CHECK-NEXT: br i1 undef, label [[BB:%.*]], label [[BB]] +; CHECK: bb: +; CHECK-NEXT: [[TMP:%.*]] = select i1 [[ARG1:%.*]], i32 [[ARG:%.*]], i32 0 +; CHECK-NEXT: ret i32 [[TMP]] +; +entry: + %tmp = select i1 %arg1, i32 %arg, i32 0 + %tmp2 = icmp eq i32 %tmp, 0 + br i1 %tmp2, label %bb, label %bb + +bb: ; preds = %entry, %entry + ret i32 %tmp +}