1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt < %s -passes='simplifycfg<hoist-common-insts;no-sink-common-insts>' -simplifycfg-require-and-preserve-domtree=1 -S | FileCheck %s 3 4define i1 @common_instr_with_unreachable(i64 %a, i64 %b, i64 %c) { 5; CHECK-LABEL: @common_instr_with_unreachable( 6; CHECK-NEXT: start: 7; CHECK-NEXT: [[TMP0:%.*]] = icmp eq i64 [[B:%.*]], [[C:%.*]] 8; CHECK-NEXT: ret i1 [[TMP0]] 9; 10start: 11 switch i64 %a, label %unreachable [ 12 i64 0, label %bb0 13 i64 1, label %bb1 14 i64 2, label %bb2 15 ] 16 17unreachable: 18 unreachable 19 20bb0: ; preds = %start 21 %0 = icmp eq i64 %b, %c 22 br label %exit 23 24bb1: ; preds = %start 25 %1 = icmp eq i64 %b, %c 26 br label %exit 27 28bb2: ; preds = %start 29 %2 = icmp eq i64 %b, %c 30 br label %exit 31 32exit: ; preds = %bb2, %bb1, %bb0 33 %result = phi i1 [ %0, %bb0 ], [ %1, %bb1 ], [ %2, %bb2 ] 34 ret i1 %result 35} 36 37define i1 @common_instr_with_unreachable_2(i64 %a, i64 %b, i64 %c) { 38; CHECK-LABEL: @common_instr_with_unreachable_2( 39; CHECK-NEXT: start: 40; CHECK-NEXT: [[TMP0:%.*]] = icmp eq i64 [[B:%.*]], [[C:%.*]] 41; CHECK-NEXT: ret i1 [[TMP0]] 42; 43start: 44 switch i64 %a, label %bb1 [ 45 i64 0, label %bb0 46 i64 1, label %unreachable 47 i64 2, label %bb2 48 ] 49 50unreachable: 51 unreachable 52 53bb0: ; preds = %start 54 %0 = icmp eq i64 %b, %c 55 br label %exit 56 57bb1: ; preds = %start 58 %1 = icmp eq i64 %b, %c 59 br label %exit 60 61bb2: ; preds = %start 62 %2 = icmp eq i64 %b, %c 63 br label %exit 64 65exit: ; preds = %bb2, %bb1, %bb0 66 %result = phi i1 [ %0, %bb0 ], [ %1, %bb1 ], [ %2, %bb2 ] 67 ret i1 %result 68} 69 70define i1 @not_only_unreachable(i64 %a, i64 %b, i64 %c) { 71; CHECK-LABEL: @not_only_unreachable( 72; CHECK-NEXT: start: 73; CHECK-NEXT: switch i64 [[A:%.*]], label [[UNREACHABLE:%.*]] [ 74; CHECK-NEXT: i64 0, label [[BB0:%.*]] 75; CHECK-NEXT: i64 1, label [[BB1:%.*]] 76; CHECK-NEXT: i64 2, label [[BB2:%.*]] 77; CHECK-NEXT: ] 78; CHECK: unreachable: 79; CHECK-NEXT: call void @no_return() 80; CHECK-NEXT: unreachable 81; CHECK: bb0: 82; CHECK-NEXT: [[TMP0:%.*]] = icmp eq i64 [[B:%.*]], [[C:%.*]] 83; CHECK-NEXT: call void @foo() 84; CHECK-NEXT: br label [[EXIT:%.*]] 85; CHECK: bb1: 86; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i64 [[B]], [[C]] 87; CHECK-NEXT: call void @foo() 88; CHECK-NEXT: br label [[EXIT]] 89; CHECK: bb2: 90; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i64 [[B]], [[C]] 91; CHECK-NEXT: call void @foo() 92; CHECK-NEXT: br label [[EXIT]] 93; CHECK: exit: 94; CHECK-NEXT: [[RESULT:%.*]] = phi i1 [ [[TMP0]], [[BB0]] ], [ [[TMP1]], [[BB1]] ], [ [[TMP2]], [[BB2]] ] 95; CHECK-NEXT: ret i1 [[RESULT]] 96; 97start: 98 switch i64 %a, label %unreachable [ 99 i64 0, label %bb0 100 i64 1, label %bb1 101 i64 2, label %bb2 102 ] 103 104unreachable: 105 call void @no_return() 106 unreachable 107 108bb0: ; preds = %start 109 %0 = icmp eq i64 %b, %c 110 call void @foo() 111 br label %exit 112 113bb1: ; preds = %start 114 %1 = icmp eq i64 %b, %c 115 call void @foo() 116 br label %exit 117 118bb2: ; preds = %start 119 %2 = icmp eq i64 %b, %c 120 call void @foo() 121 br label %exit 122 123exit: ; preds = %bb2, %bb1, %bb0 124 %result = phi i1 [ %0, %bb0 ], [ %1, %bb1 ], [ %2, %bb2 ] 125 ret i1 %result 126} 127 128; If we can hoist a musttail call, 129; we can and have to hoist subsequent bitcast and ret instructions. 130define ptr @switch_musttail_call(ptr %arg) { 131; CHECK-LABEL: @switch_musttail_call( 132; CHECK-NEXT: bb: 133; CHECK-NEXT: [[P0:%.*]] = musttail call ptr @musttail_call(ptr [[ARG:%.*]]) 134; CHECK-NEXT: ret ptr [[P0]] 135; 136bb: 137 %load = load i16, ptr %arg, align 2 138 switch i16 %load, label %unreachable [ 139 i16 0, label %bb0 140 i16 1, label %bb1 141 i16 2, label %bb2 142 ] 143 144unreachable: 145 unreachable 146 147bb0: 148 %p0 = musttail call ptr @musttail_call(ptr %arg) 149 ret ptr %p0 150 151bb1: 152 %p1 = musttail call ptr @musttail_call(ptr %arg) 153 ret ptr %p1 154 155bb2: 156 %p2 = musttail call ptr @musttail_call(ptr %arg) 157 ret ptr %p2 158} 159 160declare void @no_return() 161declare void @foo() 162declare ptr @musttail_call(ptr) 163