diff --git a/llvm/lib/Transforms/Scalar/JumpThreading.cpp b/llvm/lib/Transforms/Scalar/JumpThreading.cpp --- a/llvm/lib/Transforms/Scalar/JumpThreading.cpp +++ b/llvm/lib/Transforms/Scalar/JumpThreading.cpp @@ -700,12 +700,10 @@ return true; } - // Handle Freeze instructions, in a manner similar to Cast. if (FreezeInst *FI = dyn_cast(I)) { Value *Source = FI->getOperand(0); - if (!isa(Source) && !isa(Source) && - !isa(Source)) - return false; + // Unlike cast, don't limit the type of Source because it generates a + // sub-optimal code compared to the case when branch conditions are unfrozen ComputeValueKnownInPredecessorsImpl(Source, BB, Result, Preference, RecursionSet, CxtI); diff --git a/llvm/test/Transforms/JumpThreading/freeze.ll b/llvm/test/Transforms/JumpThreading/freeze.ll --- a/llvm/test/Transforms/JumpThreading/freeze.ll +++ b/llvm/test/Transforms/JumpThreading/freeze.ll @@ -85,20 +85,14 @@ define i32 @test1_cast2(i1 %cond) { ; CHECK-LABEL: @test1_cast2( -; CHECK-NEXT: br i1 [[COND:%.*]], label [[MERGE_THREAD:%.*]], label [[MERGE:%.*]] -; CHECK: Merge.thread: -; CHECK-NEXT: [[V1:%.*]] = call i32 @f1() -; CHECK-NEXT: br label [[T2:%.*]] -; CHECK: Merge: -; CHECK-NEXT: [[V2:%.*]] = call i32 @f2() -; CHECK-NEXT: [[A0_FR:%.*]] = freeze i32 0 -; CHECK-NEXT: [[A_FR:%.*]] = trunc i32 [[A0_FR]] to i1 -; CHECK-NEXT: br i1 [[A_FR]], label [[T2]], label [[F2:%.*]] +; CHECK-NEXT: br i1 [[COND:%.*]], label [[T2:%.*]], label [[F2:%.*]] ; CHECK: T2: -; CHECK-NEXT: [[B5:%.*]] = phi i32 [ [[V1]], [[MERGE_THREAD]] ], [ [[V2]], [[MERGE]] ] +; CHECK-NEXT: [[V1:%.*]] = call i32 @f1() ; CHECK-NEXT: call void @f3() -; CHECK-NEXT: ret i32 [[B5]] +; CHECK-NEXT: ret i32 [[V1]] ; CHECK: F2: +; CHECK-NEXT: [[V2:%.*]] = call i32 @f2() +; CHECK-NEXT: [[A0_FR:%.*]] = freeze i32 0 ; CHECK-NEXT: ret i32 [[V2]] ; br i1 %cond, label %T1, label %F1