Bump version to 19.1.0-rc3
[llvm-project.git] / llvm / test / Transforms / SimplifyCFG / hoist-common-code.ll
blob991b89a486e0f5ac7657e72f458945259f5f5b7a
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
4 declare void @bar(i32)
6 define void @test(i1 %P, ptr %Q) {
7 ; CHECK-LABEL: @test(
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
15 T:              ; preds = %0
16   store i32 1, ptr %Q
17   %A = load i32, ptr %Q               ; <i32> [#uses=1]
18   call void @bar( i32 %A )
19   ret void
20 F:              ; preds = %0
21   store i32 1, ptr %Q
22   %B = load i32, ptr %Q               ; <i32> [#uses=1]
23   call void @bar( i32 %B )
24   ret void
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 [
36   i64 1, label %bb1
37   i64 2, label %bb2
38   ]
39 bb0:              ; preds = %0
40   store i32 1, ptr %Q
41   %A = load i32, ptr %Q               ; <i32> [#uses=1]
42   call void @bar( i32 %A )
43   ret void
44 bb1:              ; preds = %0
45   store i32 1, ptr %Q
46   %B = load i32, ptr %Q               ; <i32> [#uses=1]
47   call void @bar( i32 %B )
48   ret void
49 bb2:              ; preds = %0
50   store i32 1, ptr %Q
51   %C = load i32, ptr %Q               ; <i32> [#uses=1]
52   call void @bar( i32 %C )
53   ret void
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:%.*]]
62 ; CHECK-NEXT:    ]
63 ; CHECK:       common.ret:
64 ; CHECK-NEXT:    ret void
65 ; CHECK:       bb0:
66 ; CHECK-NEXT:    store i32 1, ptr [[P:%.*]], align 4
67 ; CHECK-NEXT:    br label [[COMMON_RET]]
68 ; CHECK:       bb1:
69 ; CHECK-NEXT:    store i32 2, ptr [[P]], align 4
70 ; CHECK-NEXT:    br label [[COMMON_RET]]
72   switch i64 %i, label %bb0 [
73   i64 1, label %bb1
74   i64 2, label %bb2
75   ]
76 bb0:              ; preds = %0
77   store i32 1, ptr %p
78   ret void
79 bb1:              ; preds = %0
80   store i32 2, ptr %p
81   ret void
82 bb2:              ; preds = %0
83   ret void
86 define i1 @common_instr_on_switch(i64 %a, i64 %b, i64 %c) unnamed_addr {
87 ; CHECK-LABEL: @common_instr_on_switch(
88 ; CHECK-NEXT:  start:
89 ; CHECK-NEXT:    [[TMP0:%.*]] = icmp eq i64 [[B:%.*]], [[C:%.*]]
90 ; CHECK-NEXT:    ret i1 [[TMP0]]
92 start:
93   switch i64 %a, label %bb0 [
94   i64 1, label %bb1
95   i64 2, label %bb2
96   ]
98 bb0:                                              ; preds = %start
99   %0 = icmp eq i64 %b, %c
100   br label %exit
102 bb1:                                              ; preds = %start
103   %1 = icmp eq i64 %b, %c
104   br label %exit
106 bb2:                                              ; preds = %start
107   %2 = icmp eq i64 %b, %c
108   br label %exit
110 exit:                                             ; preds = %bb2, %bb1, %bb0
111   %result = phi i1 [ %0, %bb0 ], [ %1, %bb1 ], [ %2, %bb2 ]
112   ret i1 %result
115 define i1 @partial_common_instr_on_switch(i64 %a, i64 %b, i64 %c) unnamed_addr {
116 ; CHECK-LABEL: @partial_common_instr_on_switch(
117 ; CHECK-NEXT:  start:
118 ; CHECK-NEXT:    switch i64 [[A:%.*]], label [[BB0:%.*]] [
119 ; CHECK-NEXT:      i64 1, label [[BB1:%.*]]
120 ; CHECK-NEXT:      i64 2, label [[BB2:%.*]]
121 ; CHECK-NEXT:    ]
122 ; CHECK:       bb0:
123 ; CHECK-NEXT:    [[TMP0:%.*]] = icmp eq i64 [[B:%.*]], [[C:%.*]]
124 ; CHECK-NEXT:    br label [[EXIT:%.*]]
125 ; CHECK:       bb1:
126 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp ne i64 [[B]], [[C]]
127 ; CHECK-NEXT:    br label [[EXIT]]
128 ; CHECK:       bb2:
129 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp eq i64 [[B]], [[C]]
130 ; CHECK-NEXT:    br label [[EXIT]]
131 ; CHECK:       exit:
132 ; CHECK-NEXT:    [[RESULT:%.*]] = phi i1 [ [[TMP0]], [[BB0]] ], [ [[TMP1]], [[BB1]] ], [ [[TMP2]], [[BB2]] ]
133 ; CHECK-NEXT:    ret i1 [[RESULT]]
135 start:
136   switch i64 %a, label %bb0 [
137   i64 1, label %bb1
138   i64 2, label %bb2
139   ]
141 bb0:                                              ; preds = %start
142   %0 = icmp eq i64 %b, %c
143   br label %exit
145 bb1:                                              ; preds = %start
146   %1 = icmp ne i64 %b, %c
147   br label %exit
149 bb2:                                              ; preds = %start
150   %2 = icmp eq i64 %b, %c
151   br label %exit
153 exit:                                             ; preds = %bb2, %bb1, %bb0
154   %result = phi i1 [ %0, %bb0 ], [ %1, %bb1 ], [ %2, %bb2 ]
155   ret i1 %result