1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 2
2 ; RUN: opt -passes=gvn-sink -S %s | FileCheck %s
7 ; CHECK-LABEL: define void @loop1() {
9 ; CHECK-NEXT: br label [[LOOP:%.*]]
11 ; CHECK-NEXT: [[C1:%.*]] = call i32 @foo()
12 ; CHECK-NEXT: br label [[LOOP]]
23 define void @uncond_succ_no_loop() {
24 ; CHECK-LABEL: define void @uncond_succ_no_loop() {
26 ; CHECK-NEXT: [[C1:%.*]] = call i32 @foo()
27 ; CHECK-NEXT: br label [[EXIT:%.*]]
29 ; CHECK-NEXT: [[C2:%.*]] = call i32 @foo()
30 ; CHECK-NEXT: ret void
41 define void @loop_with_store(ptr %a) {
42 ; CHECK-LABEL: define void @loop_with_store
43 ; CHECK-SAME: (ptr [[A:%.*]]) {
45 ; CHECK-NEXT: [[C1:%.*]] = call i32 @foo()
46 ; CHECK-NEXT: br label [[LOOP:%.*]]
48 ; CHECK-NEXT: [[C2:%.*]] = call i32 @foo()
49 ; CHECK-NEXT: store i32 0, ptr [[A]], align 4
50 ; CHECK-NEXT: br label [[LOOP]]
62 define void @loop_linked_latches() {
63 ; CHECK-LABEL: define void @loop_linked_latches() {
65 ; CHECK-NEXT: [[C1:%.*]] = call i32 @foo()
66 ; CHECK-NEXT: br label [[LOOP:%.*]]
68 ; CHECK-NEXT: [[C2:%.*]] = call i32 @foo()
69 ; CHECK-NEXT: [[C:%.*]] = icmp eq i32 [[C2]], 100
70 ; CHECK-NEXT: br i1 [[C]], label [[LATCH_1:%.*]], label [[EXIT:%.*]]
72 ; CHECK-NEXT: br label [[LATCH_2:%.*]]
74 ; CHECK-NEXT: br label [[LOOP]]
76 ; CHECK-NEXT: ret void
84 %c = icmp eq i32 %c2, 100
85 br i1 %c, label %latch.1, label %exit
98 define void @loop_with_branch(i32 %s) {
99 ; CHECK-LABEL: define void @loop_with_branch
100 ; CHECK-SAME: (i32 [[S:%.*]]) {
102 ; CHECK-NEXT: br label [[LOOP_HEADER:%.*]]
103 ; CHECK: loop.header:
104 ; CHECK-NEXT: [[C1:%.*]] = call i32 @foo()
105 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[S]], 100
106 ; CHECK-NEXT: br i1 [[CMP]], label [[LOOP_LATCH:%.*]], label [[EXIT:%.*]]
108 ; CHECK-NEXT: br label [[LOOP_HEADER]]
110 ; CHECK-NEXT: ret void
113 %c1 = call i32 @foo()
114 br label %loop.header
117 %cmp = icmp eq i32 %s, 100
118 br i1 %cmp, label %loop.latch, label %exit
121 %c2 = call i32 @foo()
122 br label %loop.header
128 define void @loop_with_switch(i32 %s) {
129 ; CHECK-LABEL: define void @loop_with_switch
130 ; CHECK-SAME: (i32 [[S:%.*]]) {
132 ; CHECK-NEXT: br label [[LOOP_HEADER:%.*]]
133 ; CHECK: loop.header:
134 ; CHECK-NEXT: [[C1:%.*]] = call i32 @foo()
135 ; CHECK-NEXT: switch i32 [[S]], label [[LOOP_LATCH:%.*]] [
136 ; CHECK-NEXT: i32 0, label [[EXIT:%.*]]
139 ; CHECK-NEXT: br label [[LOOP_HEADER]]
141 ; CHECK-NEXT: ret void
144 %c1 = call i32 @foo()
145 br label %loop.header
148 switch i32 %s, label %loop.latch [
153 %c2 = call i32 @foo()
154 br label %loop.header
160 define void @cycle_latch_not_dominated_by_header_branch(i1 %c, i32 %s) {
161 ; CHECK-LABEL: define void @cycle_latch_not_dominated_by_header_branch
162 ; CHECK-SAME: (i1 [[C:%.*]], i32 [[S:%.*]]) {
164 ; CHECK-NEXT: br i1 [[C]], label [[THEN:%.*]], label [[CYCLE_2:%.*]]
166 ; CHECK-NEXT: br label [[CYCLE_1:%.*]]
168 ; CHECK-NEXT: [[C1:%.*]] = call i32 @foo()
169 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[S]], 100
170 ; CHECK-NEXT: br i1 [[CMP]], label [[EXIT:%.*]], label [[CYCLE_2]]
172 ; CHECK-NEXT: br label [[CYCLE_1]]
174 ; CHECK-NEXT: ret void
177 br i1 %c, label %then, label %cycle.2
180 %c1 = call i32 @foo()
184 %cmp = icmp eq i32 %s, 100
185 br i1 %cmp, label %exit, label %cycle.2
188 %c2 = call i32 @foo()
195 define void @cycle_latch_not_dominated_by_header_switch(i1 %c, i32 %s) {
196 ; CHECK-LABEL: define void @cycle_latch_not_dominated_by_header_switch
197 ; CHECK-SAME: (i1 [[C:%.*]], i32 [[S:%.*]]) {
199 ; CHECK-NEXT: br i1 [[C]], label [[THEN:%.*]], label [[CYCLE_2:%.*]]
201 ; CHECK-NEXT: br label [[CYCLE_1:%.*]]
203 ; CHECK-NEXT: [[C1:%.*]] = call i32 @foo()
204 ; CHECK-NEXT: switch i32 [[S]], label [[EXIT:%.*]] [
205 ; CHECK-NEXT: i32 0, label [[CYCLE_2]]
208 ; CHECK-NEXT: br label [[CYCLE_1]]
210 ; CHECK-NEXT: ret void
213 br i1 %c, label %then, label %cycle.2
216 %c1 = call i32 @foo()
220 switch i32 %s, label %exit [
221 i32 0, label %cycle.2
225 %c2 = call i32 @foo()