Index: lib/Transforms/Scalar/JumpThreading.cpp =================================================================== --- lib/Transforms/Scalar/JumpThreading.cpp +++ lib/Transforms/Scalar/JumpThreading.cpp @@ -1620,16 +1620,19 @@ } // If we have exactly one destination, remember it for efficiency below. - if (PredToDestList.empty()) { - OnlyDest = DestBB; - OnlyVal = Val; - } else { - if (OnlyDest != DestBB) - OnlyDest = MultipleDestSentinel; - // It possible we have same destination, but different value, e.g. default - // case in switchinst. - if (Val != OnlyVal) - OnlyVal = MultipleVal; + // and we can ignore null destination. + if (DestBB) { + if (PredToDestList.empty()) { + OnlyDest = DestBB; + OnlyVal = Val; + } else { + if (OnlyDest != DestBB) + OnlyDest = MultipleDestSentinel; + // It possible we have same destination, but different value, e.g. + // default case in switchinst. + if (Val != OnlyVal) + OnlyVal = MultipleVal; + } } // We know where this predecessor is going. Index: test/Transforms/JumpThreading/fold-not-thread.ll =================================================================== --- test/Transforms/JumpThreading/fold-not-thread.ll +++ test/Transforms/JumpThreading/fold-not-thread.ll @@ -244,3 +244,50 @@ call void @f3() ret void } + +; Make sure we can fold this branch ... We will not be able to thread it as +; L0 is too big to duplicate. LX is the unreachable block here, and it feeds +; UNDEF to L2. We want to make sure the UNDEF does not make jump threading think +; L2 has multiple destinations. +; CHECK-LABEL: @test_br_folding_not_threading_multiple_preds_with_undef( +; CHECK: L3: +; CHECK: call i32 @f2() +; CHECK: call void @f3() +; CHECK-NEXT: ret void +define void @test_br_folding_not_threading_multiple_preds_with_undef(i1 %condx, i1 %cond) nounwind { +L0: + br i1 %condx, label %L2, label %L1 + +L1: + br i1 %cond, label %L2, label %L5 + +LX: + br label %L2 + +L2: + %p = phi i1 [ %condx, %L0 ], [ %cond, %L1 ], [ undef, %LX] + call i32 @f2() + call i32 @f2() + call i32 @f2() + call i32 @f2() + call i32 @f2() + call i32 @f2() + call i32 @f2() + call i32 @f2() + call i32 @f2() + call i32 @f2() + call i32 @f2() + call i32 @f2() + call i32 @f2() + br i1 %p, label %L3, label %L4 + +L3: + call void @f3() + ret void +L4: + call void @f3() + ret void +L5: + call void @f3() + ret void +}