Bump version to 19.1.0-rc3
[llvm-project.git] / llvm / test / Transforms / GVNSink / cycles.ll
blob1f093b4d2898903cb69c211eefc4b3c974f8efb7
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
4 declare i32 @foo()
6 define void @loop1() {
7 ; CHECK-LABEL: define void @loop1() {
8 ; CHECK-NEXT:  entry:
9 ; CHECK-NEXT:    br label [[LOOP:%.*]]
10 ; CHECK:       loop:
11 ; CHECK-NEXT:    [[C1:%.*]] = call i32 @foo()
12 ; CHECK-NEXT:    br label [[LOOP]]
14 entry:
15   %c1 = call i32 @foo()
16   br label %loop
18 loop:
19   %c2 = call i32 @foo()
20   br label %loop
23 define void @uncond_succ_no_loop() {
24 ; CHECK-LABEL: define void @uncond_succ_no_loop() {
25 ; CHECK-NEXT:  entry:
26 ; CHECK-NEXT:    [[C1:%.*]] = call i32 @foo()
27 ; CHECK-NEXT:    br label [[EXIT:%.*]]
28 ; CHECK:       exit:
29 ; CHECK-NEXT:    [[C2:%.*]] = call i32 @foo()
30 ; CHECK-NEXT:    ret void
32 entry:
33   %c1 = call i32 @foo()
34   br label %exit
36 exit:
37   %c2 = call i32 @foo()
38   ret void
41 define void @loop_with_store(ptr %a) {
42 ; CHECK-LABEL: define void @loop_with_store
43 ; CHECK-SAME: (ptr [[A:%.*]]) {
44 ; CHECK-NEXT:  entry:
45 ; CHECK-NEXT:    [[C1:%.*]] = call i32 @foo()
46 ; CHECK-NEXT:    br label [[LOOP:%.*]]
47 ; CHECK:       loop:
48 ; CHECK-NEXT:    [[C2:%.*]] = call i32 @foo()
49 ; CHECK-NEXT:    store i32 0, ptr [[A]], align 4
50 ; CHECK-NEXT:    br label [[LOOP]]
52 entry:
53   %c1 = call i32 @foo()
54   br label %loop
56 loop:
57   %c2 = call i32 @foo()
58   store i32 0, ptr %a
59   br label %loop
62 define void @loop_linked_latches() {
63 ; CHECK-LABEL: define void @loop_linked_latches() {
64 ; CHECK-NEXT:  entry:
65 ; CHECK-NEXT:    [[C1:%.*]] = call i32 @foo()
66 ; CHECK-NEXT:    br label [[LOOP:%.*]]
67 ; CHECK:       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:%.*]]
71 ; CHECK:       latch.1:
72 ; CHECK-NEXT:    br label [[LATCH_2:%.*]]
73 ; CHECK:       latch.2:
74 ; CHECK-NEXT:    br label [[LOOP]]
75 ; CHECK:       exit:
76 ; CHECK-NEXT:    ret void
78 entry:
79   %c1 = call i32 @foo()
80   br label %loop
82 loop:
83   %c2  = call i32 @foo()
84   %c = icmp eq i32 %c2, 100
85   br i1 %c, label %latch.1, label %exit
87 latch.1:
88   br label %latch.2
90 latch.2:
91   br label %loop
94 exit:
95   ret void
98 define void @loop_with_branch(i32 %s) {
99 ; CHECK-LABEL: define void @loop_with_branch
100 ; CHECK-SAME: (i32 [[S:%.*]]) {
101 ; CHECK-NEXT:  entry:
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:%.*]]
107 ; CHECK:       loop.latch:
108 ; CHECK-NEXT:    br label [[LOOP_HEADER]]
109 ; CHECK:       exit:
110 ; CHECK-NEXT:    ret void
112 entry:
113   %c1 = call i32 @foo()
114   br label %loop.header
116 loop.header:
117   %cmp = icmp eq i32 %s, 100
118   br i1 %cmp, label %loop.latch, label %exit
120 loop.latch:
121   %c2 = call i32 @foo()
122   br label %loop.header
124 exit:
125   ret void
128 define void @loop_with_switch(i32 %s) {
129 ; CHECK-LABEL: define void @loop_with_switch
130 ; CHECK-SAME: (i32 [[S:%.*]]) {
131 ; CHECK-NEXT:  entry:
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:%.*]]
137 ; CHECK-NEXT:    ]
138 ; CHECK:       loop.latch:
139 ; CHECK-NEXT:    br label [[LOOP_HEADER]]
140 ; CHECK:       exit:
141 ; CHECK-NEXT:    ret void
143 entry:
144   %c1 = call i32 @foo()
145   br label %loop.header
147 loop.header:
148   switch i32 %s, label %loop.latch [
149   i32 0, label %exit
150   ]
152 loop.latch:
153   %c2 = call i32 @foo()
154   br label %loop.header
156 exit:
157   ret void
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:%.*]]) {
163 ; CHECK-NEXT:  entry:
164 ; CHECK-NEXT:    br i1 [[C]], label [[THEN:%.*]], label [[CYCLE_2:%.*]]
165 ; CHECK:       then:
166 ; CHECK-NEXT:    br label [[CYCLE_1:%.*]]
167 ; CHECK:       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]]
171 ; CHECK:       cycle.2:
172 ; CHECK-NEXT:    br label [[CYCLE_1]]
173 ; CHECK:       exit:
174 ; CHECK-NEXT:    ret void
176 entry:
177   br i1 %c, label %then, label %cycle.2
179 then:
180   %c1 = call i32 @foo()
181   br label %cycle.1
183 cycle.1:
184   %cmp = icmp eq i32 %s, 100
185   br i1 %cmp, label %exit, label %cycle.2
187 cycle.2:
188   %c2 = call i32 @foo()
189   br label %cycle.1
191 exit:
192   ret void
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:%.*]]) {
198 ; CHECK-NEXT:  entry:
199 ; CHECK-NEXT:    br i1 [[C]], label [[THEN:%.*]], label [[CYCLE_2:%.*]]
200 ; CHECK:       then:
201 ; CHECK-NEXT:    br label [[CYCLE_1:%.*]]
202 ; CHECK:       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]]
206 ; CHECK-NEXT:    ]
207 ; CHECK:       cycle.2:
208 ; CHECK-NEXT:    br label [[CYCLE_1]]
209 ; CHECK:       exit:
210 ; CHECK-NEXT:    ret void
212 entry:
213   br i1 %c, label %then, label %cycle.2
215 then:
216   %c1 = call i32 @foo()
217   br label %cycle.1
219 cycle.1:
220   switch i32 %s, label %exit [
221   i32 0, label %cycle.2
222   ]
224 cycle.2:
225   %c2 = call i32 @foo()
226   br label %cycle.1
228 exit:
229   ret void