tryWidenCondBranchToCondBranch is supposed to perform guard widening,
redirecting a deopting exit of successor block into a deopting exit of the
widenable predecessor block. But the check that the latter is actually deoptimizing
was never done. As result, the transform was turning
define i32 @test(float %arg) gc "statepoint-example" personality i32* ()* @blam {
bb:
%tmp = call i1 @llvm.experimental.widenable.condition()
br i1 %tmp, label %bb2, label %bb1
bb1: ; preds = %bb
br i1 undef, label %bb7, label %bb5
bb2: ; preds = %bb
%tmp3 = getelementptr inbounds i8, i8 addrspace(1)* undef, i64 16
br i1 undef, label %bb7, label %bb4
bb4: ; preds = %bb2
call void @snork() [ "deopt"() ]
unreachable
bb5: ; preds = %bb1
ret i32 0
bb7: ; preds = %bb2, %bb1
%tmp8 = call i32 (...) @llvm.experimental.deoptimize.i32(i32 10) [ "deopt"() ]
ret i32 %tmp8
}into
define i32 @test(float %arg) gc "statepoint-example" personality i32* ()* @blam {
bb:
%tmp = call i1 @llvm.experimental.widenable.condition()
br i1 %tmp, label %bb2, label %bb1
bb1: ; preds = %bb2, %bb
br i1 undef, label %bb7, label %bb5
bb2: ; preds = %bb
%tmp3 = getelementptr inbounds i8, i8 addrspace(1)* undef, i64 16
br i1 undef, label %bb1, label %bb4
bb4: ; preds = %bb2
call void @snork() [ "deopt"() ]
unreachable
bb5: ; preds = %bb1
ret i32 0
bb7: ; preds = %bb1
%tmp8 = call i32 (...) @llvm.experimental.deoptimize.i32(i32 10) [ "deopt"() ]
ret i32 %tmp8
}Note that this is just wrong: previously taking branch bb2->bb7 was always a deopt,
but then it was replaced with bb2->bb1 and then it could go to bb5 which was not
even reachable from bb2 before the transform. (In this test conditions are undef, but
in fact they are never analyzed so it doesn't matter; condition in bb2 could as well be
a regular value).
So in fact, this transform may replace a deopting edge with some random edge which
never deopts. It's a miscompile by itself, and in case of SimplifyCFG, it has weird interactions
with other transforms of SimplifyCondBranchToCondBranch, which create a .pr Phi, then
thread through it, and then the described buggy transform repeats and brings the code into
its initial state. So we end up stuck in an infinite loop.
This patch fixes this situation by ensuring that widenable condition branch actually goes to
deopt if the condition is false.