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
4 define i1 @common_instr_with_unreachable(i64 %a, i64 %b, i64 %c) {
5 ; CHECK-LABEL: @common_instr_with_unreachable(
7 ; CHECK-NEXT: [[TMP0:%.*]] = icmp eq i64 [[B:%.*]], [[C:%.*]]
8 ; CHECK-NEXT: ret i1 [[TMP0]]
11 switch i64 %a, label %unreachable [
21 %0 = icmp eq i64 %b, %c
25 %1 = icmp eq i64 %b, %c
29 %2 = icmp eq i64 %b, %c
32 exit: ; preds = %bb2, %bb1, %bb0
33 %result = phi i1 [ %0, %bb0 ], [ %1, %bb1 ], [ %2, %bb2 ]
37 define i1 @common_instr_with_unreachable_2(i64 %a, i64 %b, i64 %c) {
38 ; CHECK-LABEL: @common_instr_with_unreachable_2(
40 ; CHECK-NEXT: [[TMP0:%.*]] = icmp eq i64 [[B:%.*]], [[C:%.*]]
41 ; CHECK-NEXT: ret i1 [[TMP0]]
44 switch i64 %a, label %bb1 [
46 i64 1, label %unreachable
54 %0 = icmp eq i64 %b, %c
58 %1 = icmp eq i64 %b, %c
62 %2 = icmp eq i64 %b, %c
65 exit: ; preds = %bb2, %bb1, %bb0
66 %result = phi i1 [ %0, %bb0 ], [ %1, %bb1 ], [ %2, %bb2 ]
70 define i1 @not_only_unreachable(i64 %a, i64 %b, i64 %c) {
71 ; CHECK-LABEL: @not_only_unreachable(
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:%.*]]
79 ; CHECK-NEXT: call void @no_return()
80 ; CHECK-NEXT: unreachable
82 ; CHECK-NEXT: [[TMP0:%.*]] = icmp eq i64 [[B:%.*]], [[C:%.*]]
83 ; CHECK-NEXT: call void @foo()
84 ; CHECK-NEXT: br label [[EXIT:%.*]]
86 ; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i64 [[B]], [[C]]
87 ; CHECK-NEXT: call void @foo()
88 ; CHECK-NEXT: br label [[EXIT]]
90 ; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i64 [[B]], [[C]]
91 ; CHECK-NEXT: call void @foo()
92 ; CHECK-NEXT: br label [[EXIT]]
94 ; CHECK-NEXT: [[RESULT:%.*]] = phi i1 [ [[TMP0]], [[BB0]] ], [ [[TMP1]], [[BB1]] ], [ [[TMP2]], [[BB2]] ]
95 ; CHECK-NEXT: ret i1 [[RESULT]]
98 switch i64 %a, label %unreachable [
105 call void @no_return()
108 bb0: ; preds = %start
109 %0 = icmp eq i64 %b, %c
113 bb1: ; preds = %start
114 %1 = icmp eq i64 %b, %c
118 bb2: ; preds = %start
119 %2 = icmp eq i64 %b, %c
123 exit: ; preds = %bb2, %bb1, %bb0
124 %result = phi i1 [ %0, %bb0 ], [ %1, %bb1 ], [ %2, %bb2 ]
128 ; If we can hoist a musttail call,
129 ; we can and have to hoist subsequent bitcast and ret instructions.
130 define ptr @switch_musttail_call(ptr %arg) {
131 ; CHECK-LABEL: @switch_musttail_call(
133 ; CHECK-NEXT: [[P0:%.*]] = musttail call ptr @musttail_call(ptr [[ARG:%.*]])
134 ; CHECK-NEXT: ret ptr [[P0]]
137 %load = load i16, ptr %arg, align 2
138 switch i16 %load, label %unreachable [
148 %p0 = musttail call ptr @musttail_call(ptr %arg)
152 %p1 = musttail call ptr @musttail_call(ptr %arg)
156 %p2 = musttail call ptr @musttail_call(ptr %arg)
160 declare void @no_return()
162 declare ptr @musttail_call(ptr)