1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -passes=simplifycfg -simplifycfg-require-and-preserve-domtree=1 -S -hoist-common-insts=true | FileCheck %s
6 define void @test(i1 %P, ptr %Q) {
8 ; CHECK-NEXT: common.ret:
9 ; CHECK-NEXT: store i32 1, ptr [[Q:%.*]], align 4
10 ; CHECK-NEXT: [[A:%.*]] = load i32, ptr [[Q]], align 4
11 ; CHECK-NEXT: call void @bar(i32 [[A]])
12 ; CHECK-NEXT: ret void
14 br i1 %P, label %T, label %F
17 %A = load i32, ptr %Q ; <i32> [#uses=1]
18 call void @bar( i32 %A )
22 %B = load i32, ptr %Q ; <i32> [#uses=1]
23 call void @bar( i32 %B )
27 define void @test_switch(i64 %i, ptr %Q) {
28 ; CHECK-LABEL: @test_switch(
29 ; CHECK-NEXT: common.ret:
30 ; CHECK-NEXT: store i32 1, ptr [[Q:%.*]], align 4
31 ; CHECK-NEXT: [[A:%.*]] = load i32, ptr [[Q]], align 4
32 ; CHECK-NEXT: call void @bar(i32 [[A]])
33 ; CHECK-NEXT: ret void
35 switch i64 %i, label %bb0 [
41 %A = load i32, ptr %Q ; <i32> [#uses=1]
42 call void @bar( i32 %A )
46 %B = load i32, ptr %Q ; <i32> [#uses=1]
47 call void @bar( i32 %B )
51 %C = load i32, ptr %Q ; <i32> [#uses=1]
52 call void @bar( i32 %C )
56 ; We ensure that we examine all instructions during each iteration to confirm the presence of a terminating one.
57 define void @test_switch_reach_terminator(i64 %i, ptr %p) {
58 ; CHECK-LABEL: @test_switch_reach_terminator(
59 ; CHECK-NEXT: switch i64 [[I:%.*]], label [[BB0:%.*]] [
60 ; CHECK-NEXT: i64 1, label [[BB1:%.*]]
61 ; CHECK-NEXT: i64 2, label [[COMMON_RET:%.*]]
64 ; CHECK-NEXT: ret void
66 ; CHECK-NEXT: store i32 1, ptr [[P:%.*]], align 4
67 ; CHECK-NEXT: br label [[COMMON_RET]]
69 ; CHECK-NEXT: store i32 2, ptr [[P]], align 4
70 ; CHECK-NEXT: br label [[COMMON_RET]]
72 switch i64 %i, label %bb0 [
86 define i1 @common_instr_on_switch(i64 %a, i64 %b, i64 %c) unnamed_addr {
87 ; CHECK-LABEL: @common_instr_on_switch(
89 ; CHECK-NEXT: [[TMP0:%.*]] = icmp eq i64 [[B:%.*]], [[C:%.*]]
90 ; CHECK-NEXT: ret i1 [[TMP0]]
93 switch i64 %a, label %bb0 [
99 %0 = icmp eq i64 %b, %c
102 bb1: ; preds = %start
103 %1 = icmp eq i64 %b, %c
106 bb2: ; preds = %start
107 %2 = icmp eq i64 %b, %c
110 exit: ; preds = %bb2, %bb1, %bb0
111 %result = phi i1 [ %0, %bb0 ], [ %1, %bb1 ], [ %2, %bb2 ]
115 define i1 @partial_common_instr_on_switch(i64 %a, i64 %b, i64 %c) unnamed_addr {
116 ; CHECK-LABEL: @partial_common_instr_on_switch(
118 ; CHECK-NEXT: switch i64 [[A:%.*]], label [[BB0:%.*]] [
119 ; CHECK-NEXT: i64 1, label [[BB1:%.*]]
120 ; CHECK-NEXT: i64 2, label [[BB2:%.*]]
123 ; CHECK-NEXT: [[TMP0:%.*]] = icmp eq i64 [[B:%.*]], [[C:%.*]]
124 ; CHECK-NEXT: br label [[EXIT:%.*]]
126 ; CHECK-NEXT: [[TMP1:%.*]] = icmp ne i64 [[B]], [[C]]
127 ; CHECK-NEXT: br label [[EXIT]]
129 ; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i64 [[B]], [[C]]
130 ; CHECK-NEXT: br label [[EXIT]]
132 ; CHECK-NEXT: [[RESULT:%.*]] = phi i1 [ [[TMP0]], [[BB0]] ], [ [[TMP1]], [[BB1]] ], [ [[TMP2]], [[BB2]] ]
133 ; CHECK-NEXT: ret i1 [[RESULT]]
136 switch i64 %a, label %bb0 [
141 bb0: ; preds = %start
142 %0 = icmp eq i64 %b, %c
145 bb1: ; preds = %start
146 %1 = icmp ne i64 %b, %c
149 bb2: ; preds = %start
150 %2 = icmp eq i64 %b, %c
153 exit: ; preds = %bb2, %bb1, %bb0
154 %result = phi i1 [ %0, %bb0 ], [ %1, %bb1 ], [ %2, %bb2 ]