Make it possible that TryToSimplifyUncondBranchFromEmptyBlock merges empty basic block including lifetime intrinsics as well as phi nodes and unconditional branch into its successor or predecessor(s).
If successor of empty block has single predecessor, all contents including lifetime intrinsics are sinked into the successor. Otherwise, they are hoisted into its predecessor(s) and then merged into the predecessor(s) like below example codes.
Input IR:
define void @foo(i1 %x, i1 %y) {
entry:
%a = alloca i32, align 4 br label %while.cond
while.cond: ; preds = %if.end, %entry
br i1 %y, label %while.body, label %bb
while.body: ; preds = %while.cond
%b = bitcast i32* %a to i8* call void @llvm.lifetime.start(i64 4, i8* %b) #1 %d = load i32, i32* %a, align 4 br i1 %x, label %if.then, label %if.else
if.then: ; preds = %while.body
%e = add i32 %d, 1 store i32 %e, i32* %a, align 4 br label %if.end
if.else: ; preds = %while.body
%g = sub i32 %d, 1 store i32 %g, i32* %a, align 4 br label %if.end
if.end: ; preds = %if.else, %if.then
%c = bitcast i32* %a to i8* call void @llvm.lifetime.end(i64 4, i8* %c) #1 br label %while.cond
bb: ; preds = %while.cond
ret void
}
Optimized output IR by SimplifyCFG:
define void @foo(i1 %x, i1 %y) {
entry:
%a = alloca i32, align 4 br label %while.cond
while.cond: ; preds = %if.then, %if.else, %entry
br i1 %y, label %while.body, label %bb
while.body: ; preds = %while.cond
%b = bitcast i32* %a to i8* call void @llvm.lifetime.start(i64 4, i8* %b) %d = load i32, i32* %a, align 4 br i1 %x, label %if.then, label %if.else
if.then: ; preds = %while.body
%e = add i32 %d, 1 store i32 %e, i32* %a, align 4 %c = bitcast i32* %a to i8* call void @llvm.lifetime.end(i64 4, i8* %c) br label %while.cond
if.else: ; preds = %while.body
%g = sub i32 %d, 1 store i32 %g, i32* %a, align 4 %0 = bitcast i32* %a to i8* call void @llvm.lifetime.end(i64 4, i8* %0) br label %while.cond
bb: ; preds = %while.cond
ret void
}