; NOTE: Assertions have been autogenerated by utils/update_test_checks.py ; RUN: opt < %s -simplifycfg -simplifycfg-require-and-preserve-domtree=1 -S | FileCheck %s ; RUN: opt < %s -passes=simplifycfg -simplifycfg-require-and-preserve-domtree=1 -S | FileCheck %s declare void @foo_01() declare void @foo_02() declare void @foo_03() define i32 @test_01(i32* %p, i32 %x, i1 %cond) { ; CHECK-LABEL: @test_01( ; CHECK-NEXT: entry: ; CHECK-NEXT: br i1 [[COND:%.*]], label [[BB:%.*]], label [[COMMON_RET:%.*]] ; CHECK: common.ret: ; CHECK-NEXT: [[COMMON_RET_OP:%.*]] = phi i32 [ [[R:%.*]], [[BB]] ], [ 0, [[ENTRY:%.*]] ] ; CHECK-NEXT: ret i32 [[COMMON_RET_OP]] ; CHECK: bb: ; CHECK-NEXT: [[R]] = load i32, i32* [[P:%.*]], align 4 ; CHECK-NEXT: br label [[COMMON_RET]] ; entry: br i1 %cond, label %bb, label %pred pred: switch i32 %x, label %other_succ [i32 42, label %bb i32 123456, label %bb i32 -654321, label %bb] bb: %phi = phi i32* [null, %pred], [null, %pred], [null, %pred], [%p, %entry] %r = load i32, i32* %phi ret i32 %r other_succ: ret i32 0 } define i32 @test_02(i32* %p, i32 %x, i1 %cond) { ; CHECK-LABEL: @test_02( ; CHECK-NEXT: entry: ; CHECK-NEXT: br i1 [[COND:%.*]], label [[BB:%.*]], label [[COMMON_RET:%.*]] ; CHECK: common.ret: ; CHECK-NEXT: [[COMMON_RET_OP:%.*]] = phi i32 [ [[R:%.*]], [[BB]] ], [ 0, [[ENTRY:%.*]] ] ; CHECK-NEXT: ret i32 [[COMMON_RET_OP]] ; CHECK: bb: ; CHECK-NEXT: [[R]] = load i32, i32* [[P:%.*]], align 4 ; CHECK-NEXT: br label [[COMMON_RET]] ; entry: br i1 %cond, label %bb, label %pred pred: switch i32 %x, label %bb [i32 42, label %other_succ i32 123456, label %other_succ i32 -654321, label %other_succ] bb: %phi = phi i32* [null, %pred], [%p, %entry] %r = load i32, i32* %phi ret i32 %r other_succ: ret i32 0 } define i32 @test_03(i32* %p, i32 %x, i1 %cond) { ; CHECK-LABEL: @test_03( ; CHECK-NEXT: entry: ; CHECK-NEXT: br i1 [[COND:%.*]], label [[BB:%.*]], label [[PRED:%.*]] ; CHECK: pred: ; CHECK-NEXT: switch i32 [[X:%.*]], label [[UNREACHABLE:%.*]] [ ; CHECK-NEXT: i32 42, label [[COMMON_RET:%.*]] ; CHECK-NEXT: i32 123456, label [[COMMON_RET]] ; CHECK-NEXT: i32 -654321, label [[COMMON_RET]] ; CHECK-NEXT: i32 1, label [[DO_1:%.*]] ; CHECK-NEXT: i32 2, label [[DO_2:%.*]] ; CHECK-NEXT: i32 3, label [[DO_3:%.*]] ; CHECK-NEXT: ] ; CHECK: common.ret: ; CHECK-NEXT: [[COMMON_RET_OP:%.*]] = phi i32 [ [[R:%.*]], [[BB]] ], [ 1, [[DO_1]] ], [ 1, [[DO_2]] ], [ 1, [[DO_3]] ], [ 0, [[PRED]] ], [ 0, [[PRED]] ], [ 0, [[PRED]] ] ; CHECK-NEXT: ret i32 [[COMMON_RET_OP]] ; CHECK: unreachable: ; CHECK-NEXT: unreachable ; CHECK: bb: ; CHECK-NEXT: [[R]] = load i32, i32* [[P:%.*]], align 4 ; CHECK-NEXT: br label [[COMMON_RET]] ; CHECK: do_1: ; CHECK-NEXT: call void @foo_01() ; CHECK-NEXT: br label [[COMMON_RET]] ; CHECK: do_2: ; CHECK-NEXT: call void @foo_02() ; CHECK-NEXT: br label [[COMMON_RET]] ; CHECK: do_3: ; CHECK-NEXT: call void @foo_03() ; CHECK-NEXT: br label [[COMMON_RET]] ; entry: br i1 %cond, label %bb, label %pred pred: switch i32 %x, label %bb [i32 42, label %other_succ i32 123456, label %other_succ i32 -654321, label %other_succ i32 1, label %do_1 i32 2, label %do_2 i32 3, label %do_3] bb: %phi = phi i32* [null, %pred], [%p, %entry] %r = load i32, i32* %phi ret i32 %r do_1: call void @foo_01() ret i32 1 do_2: call void @foo_02() ret i32 1 do_3: call void @foo_03() ret i32 1 other_succ: ret i32 0 } define i32 @test_04(i32* %p, i32 %x, i1 %cond) { ; CHECK-LABEL: @test_04( ; CHECK-NEXT: entry: ; CHECK-NEXT: br i1 [[COND:%.*]], label [[BB:%.*]], label [[PRED:%.*]] ; CHECK: pred: ; CHECK-NEXT: switch i32 [[X:%.*]], label [[COMMON_RET:%.*]] [ ; CHECK-NEXT: i32 3, label [[DO_3:%.*]] ; CHECK-NEXT: i32 2, label [[DO_2:%.*]] ; CHECK-NEXT: i32 1, label [[DO_1:%.*]] ; CHECK-NEXT: ] ; CHECK: common.ret: ; CHECK-NEXT: [[COMMON_RET_OP:%.*]] = phi i32 [ [[R:%.*]], [[BB]] ], [ 1, [[DO_1]] ], [ 1, [[DO_2]] ], [ 1, [[DO_3]] ], [ 0, [[PRED]] ] ; CHECK-NEXT: ret i32 [[COMMON_RET_OP]] ; CHECK: bb: ; CHECK-NEXT: [[R]] = load i32, i32* [[P:%.*]], align 4 ; CHECK-NEXT: br label [[COMMON_RET]] ; CHECK: do_1: ; CHECK-NEXT: call void @foo_01() ; CHECK-NEXT: br label [[COMMON_RET]] ; CHECK: do_2: ; CHECK-NEXT: call void @foo_02() ; CHECK-NEXT: br label [[COMMON_RET]] ; CHECK: do_3: ; CHECK-NEXT: call void @foo_03() ; CHECK-NEXT: br label [[COMMON_RET]] ; entry: br i1 %cond, label %bb, label %pred pred: switch i32 %x, label %other_succ [i32 42, label %bb i32 123456, label %bb i32 -654321, label %bb i32 1, label %do_1 i32 2, label %do_2 i32 3, label %do_3] bb: %phi = phi i32* [null, %pred], [null, %pred], [null, %pred], [%p, %entry] %r = load i32, i32* %phi ret i32 %r do_1: call void @foo_01() ret i32 1 do_2: call void @foo_02() ret i32 1 do_3: call void @foo_03() ret i32 1 other_succ: ret i32 0 }