Index: lib/Transforms/Scalar/JumpThreading.cpp =================================================================== --- lib/Transforms/Scalar/JumpThreading.cpp +++ lib/Transforms/Scalar/JumpThreading.cpp @@ -410,6 +410,10 @@ // stack pops back out again. RecursionSetRemover remover(RecursionSet, std::make_pair(V, BB)); + if (Instruction *I = dyn_cast(V)) + if (Value *NewV = SimplifyInstruction(I, BB->getModule()->getDataLayout())) + V = NewV; + // If V is a constant, then it is known in all predecessors. if (Constant *KC = getKnownConstant(V, Preference)) { for (BasicBlock *Pred : predecessors(BB)) Index: test/Transforms/JumpThreading/basic.ll =================================================================== --- test/Transforms/JumpThreading/basic.ll +++ test/Transforms/JumpThreading/basic.ll @@ -476,6 +476,43 @@ ; CHECK: } } + +;;; Verify that we can handle constraint propagation through cast. +define i32 @test16(i1 %cond) { +Entry: +; CHECK-LABEL: @test16( + br i1 %cond, label %Merge, label %F1 + +; CHECK: Entry: +; CHECK-NEXT: br i1 %cond, label %F2, label %Merge + +F1: + %v1 = call i32 @f1() + br label %Merge + +Merge: + %B = phi i32 [1, %Entry], [%v1, %F1] + %M = icmp eq i32 %B, 0 + %M1 = zext i1 %M to i32 + %N = icmp eq i32 %M1, 1 + br i1 %N, label %T2, label %F2 + +; CHECK: Merge: +; CHECK-NOT: phi +; CHECK-NEXT: %v1 = call i32 @f1() + +T2: + %Q = zext i1 %M to i32 + ret i32 %Q + +F2: + ret i32 %B +; CHECK: F2: +; CHECK-NEXT: phi i32 +} + + + ; In this test we check that block duplication is inhibited by the presence ; of a function with the 'noduplicate' attribute.