[Instrumentation] Fix a warning
[llvm-project.git] / llvm / test / Transforms / SimpleLoopUnswitch / trivial-unswitch-logical-and-or.ll
blob0719b5579d0a4fb2dc3f40e64442c4795f733281
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt -passes='loop-mssa(simple-loop-unswitch)' -S %s | FileCheck %s
4 ; Test cases for trivial unswitching with selects that matches both a logical and & or.
6 declare void @some_func()
8 define void @test_select_logical_and_or_with_and_1(i1 noundef %cond1, i1 noundef %cond2) {
9 ; CHECK-LABEL: @test_select_logical_and_or_with_and_1(
10 ; CHECK-NEXT:  entry:
11 ; CHECK-NEXT:    br label [[LOOP_HEADER:%.*]]
12 ; CHECK:       loop.header:
13 ; CHECK-NEXT:    [[COND_AND1:%.*]] = and i1 [[COND2:%.*]], [[COND1:%.*]]
14 ; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[COND_AND1]], i1 true, i1 false
15 ; CHECK-NEXT:    br i1 [[SEL]], label [[EXIT:%.*]], label [[LOOP_LATCH:%.*]]
16 ; CHECK:       loop.latch:
17 ; CHECK-NEXT:    call void @some_func()
18 ; CHECK-NEXT:    br label [[LOOP_HEADER]]
19 ; CHECK:       exit:
20 ; CHECK-NEXT:    ret void
22 entry:
23   br label %loop.header
25 loop.header:
26   %cond_and1 = and i1 %cond2, %cond1
27   %sel = select i1 %cond_and1, i1 true, i1 false
28   br i1 %sel, label %exit, label %loop.latch
30 loop.latch:
31   call void @some_func()
32   br label %loop.header
34 exit:
35   ret void
38 define void @test_select_logical_and_or_with_and_2(i1 noundef %cond1, i1 noundef %cond2) {
39 ; CHECK-LABEL: @test_select_logical_and_or_with_and_2(
40 ; CHECK-NEXT:  entry:
41 ; CHECK-NEXT:    [[TMP0:%.*]] = and i1 [[COND2:%.*]], [[COND1:%.*]]
42 ; CHECK-NEXT:    br i1 [[TMP0]], label [[ENTRY_SPLIT:%.*]], label [[EXIT_SPLIT:%.*]]
43 ; CHECK:       entry.split:
44 ; CHECK-NEXT:    br label [[LOOP_HEADER:%.*]]
45 ; CHECK:       loop.header:
46 ; CHECK-NEXT:    [[COND_AND1:%.*]] = and i1 true, true
47 ; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[COND_AND1]], i1 true, i1 false
48 ; CHECK-NEXT:    br i1 [[SEL]], label [[LOOP_LATCH:%.*]], label [[EXIT:%.*]]
49 ; CHECK:       loop.latch:
50 ; CHECK-NEXT:    call void @some_func()
51 ; CHECK-NEXT:    br label [[LOOP_HEADER]]
52 ; CHECK:       exit:
53 ; CHECK-NEXT:    br label [[EXIT_SPLIT]]
54 ; CHECK:       exit.split:
55 ; CHECK-NEXT:    ret void
57 entry:
58   br label %loop.header
60 loop.header:
61   %cond_and1 = and i1 %cond2, %cond1
62   %sel = select i1 %cond_and1, i1 true, i1 false
63   br i1 %sel, label %loop.latch, label %exit
65 loop.latch:
66   call void @some_func()
67   br label %loop.header
69 exit:
70   ret void
73 define void @test_select_logical_and_or_with_or_1(i1 noundef %cond1, i1 noundef %cond2) {
74 ; CHECK-LABEL: @test_select_logical_and_or_with_or_1(
75 ; CHECK-NEXT:  entry:
76 ; CHECK-NEXT:    [[TMP0:%.*]] = or i1 [[COND2:%.*]], [[COND1:%.*]]
77 ; CHECK-NEXT:    br i1 [[TMP0]], label [[EXIT_SPLIT:%.*]], label [[ENTRY_SPLIT:%.*]]
78 ; CHECK:       entry.split:
79 ; CHECK-NEXT:    br label [[LOOP_HEADER:%.*]]
80 ; CHECK:       loop.header:
81 ; CHECK-NEXT:    [[COND_AND1:%.*]] = or i1 false, false
82 ; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[COND_AND1]], i1 true, i1 false
83 ; CHECK-NEXT:    br i1 [[SEL]], label [[EXIT:%.*]], label [[LOOP_LATCH:%.*]]
84 ; CHECK:       loop.latch:
85 ; CHECK-NEXT:    call void @some_func()
86 ; CHECK-NEXT:    br label [[LOOP_HEADER]]
87 ; CHECK:       exit:
88 ; CHECK-NEXT:    br label [[EXIT_SPLIT]]
89 ; CHECK:       exit.split:
90 ; CHECK-NEXT:    ret void
92 entry:
93   br label %loop.header
95 loop.header:
96   %cond_and1 = or i1 %cond2, %cond1
97   %sel = select i1 %cond_and1, i1 true, i1 false
98   br i1 %sel, label %exit, label %loop.latch
100 loop.latch:
101   call void @some_func()
102   br label %loop.header
104 exit:
105   ret void
109 define void @test_select_logical_and_or_with_or_2(i1 noundef %cond1, i1 noundef %cond2) {
110 ; CHECK-LABEL: @test_select_logical_and_or_with_or_2(
111 ; CHECK-NEXT:  entry:
112 ; CHECK-NEXT:    br label [[LOOP_HEADER:%.*]]
113 ; CHECK:       loop.header:
114 ; CHECK-NEXT:    [[COND_AND1:%.*]] = or i1 [[COND2:%.*]], [[COND1:%.*]]
115 ; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[COND_AND1]], i1 true, i1 false
116 ; CHECK-NEXT:    br i1 [[SEL]], label [[LOOP_LATCH:%.*]], label [[EXIT:%.*]]
117 ; CHECK:       loop.latch:
118 ; CHECK-NEXT:    call void @some_func()
119 ; CHECK-NEXT:    br label [[LOOP_HEADER]]
120 ; CHECK:       exit:
121 ; CHECK-NEXT:    ret void
123 entry:
124   br label %loop.header
126 loop.header:
127   %cond_and1 = or i1 %cond2, %cond1
128   %sel = select i1 %cond_and1, i1 true, i1 false
129   br i1 %sel, label %loop.latch, label %exit
131 loop.latch:
132   call void @some_func()
133   br label %loop.header
135 exit:
136   ret void
139 ; Check that loop unswitch looks through a combination of or and select instructions.
140 define i32 @test_partial_condition_unswitch_or_select(ptr %var, i1 %cond1, i1 %cond2, i1 %cond3, i1 %cond4, i1 %cond5, i1 %cond6) {
141 ; CHECK-LABEL: @test_partial_condition_unswitch_or_select(
142 ; CHECK-NEXT:  entry:
143 ; CHECK-NEXT:    [[COND4_FR:%.*]] = freeze i1 [[COND4:%.*]]
144 ; CHECK-NEXT:    [[COND2_FR:%.*]] = freeze i1 [[COND2:%.*]]
145 ; CHECK-NEXT:    [[COND3_FR:%.*]] = freeze i1 [[COND3:%.*]]
146 ; CHECK-NEXT:    [[COND1_FR:%.*]] = freeze i1 [[COND1:%.*]]
147 ; CHECK-NEXT:    [[TMP0:%.*]] = or i1 [[COND4_FR]], [[COND2_FR]]
148 ; CHECK-NEXT:    [[TMP1:%.*]] = or i1 [[TMP0]], [[COND3_FR]]
149 ; CHECK-NEXT:    [[TMP2:%.*]] = or i1 [[TMP1]], [[COND1_FR]]
150 ; CHECK-NEXT:    br i1 [[TMP2]], label [[LOOP_EXIT_SPLIT:%.*]], label [[ENTRY_SPLIT:%.*]]
151 ; CHECK:       entry.split:
152 ; CHECK-NEXT:    br label [[LOOP_BEGIN:%.*]]
153 ; CHECK:       loop_begin:
154 ; CHECK-NEXT:    [[VAR_VAL:%.*]] = load i32, ptr [[VAR:%.*]], align 4
155 ; CHECK-NEXT:    [[VAR_COND:%.*]] = trunc i32 [[VAR_VAL]] to i1
156 ; CHECK-NEXT:    [[COND_OR1:%.*]] = or i1 [[VAR_COND]], false
157 ; CHECK-NEXT:    [[COND_OR2:%.*]] = or i1 false, false
158 ; CHECK-NEXT:    [[COND_OR3:%.*]] = or i1 [[COND_OR1]], [[COND_OR2]]
159 ; CHECK-NEXT:    [[COND_XOR1:%.*]] = xor i1 [[COND5:%.*]], [[VAR_COND]]
160 ; CHECK-NEXT:    [[COND_AND1:%.*]] = and i1 [[COND6:%.*]], [[VAR_COND]]
161 ; CHECK-NEXT:    [[COND_OR4:%.*]] = or i1 [[COND_XOR1]], [[COND_AND1]]
162 ; CHECK-NEXT:    [[COND_OR5:%.*]] = select i1 [[COND_OR3]], i1 true, i1 [[COND_OR4]]
163 ; CHECK-NEXT:    [[COND_OR6:%.*]] = select i1 [[COND_OR5]], i1 true, i1 false
164 ; CHECK-NEXT:    br i1 [[COND_OR6]], label [[LOOP_EXIT:%.*]], label [[DO_SOMETHING:%.*]]
165 ; CHECK:       do_something:
166 ; CHECK-NEXT:    call void @some_func() #[[ATTR0:[0-9]+]]
167 ; CHECK-NEXT:    br label [[LOOP_BEGIN]]
168 ; CHECK:       loop_exit:
169 ; CHECK-NEXT:    br label [[LOOP_EXIT_SPLIT]]
170 ; CHECK:       loop_exit.split:
171 ; CHECK-NEXT:    ret i32 0
173 entry:
174   br label %loop_begin
176 loop_begin:
177   %var_val = load i32, ptr %var
178   %var_cond = trunc i32 %var_val to i1
179   %cond_or1 = or i1 %var_cond, %cond1
180   %cond_or2 = or i1 %cond2, %cond3
181   %cond_or3 = or i1 %cond_or1, %cond_or2
182   %cond_xor1 = xor i1 %cond5, %var_cond
183   %cond_and1 = and i1 %cond6, %var_cond
184   %cond_or4 = or i1 %cond_xor1, %cond_and1
185   %cond_or5 = select i1 %cond_or3, i1 true, i1 %cond_or4
186   %cond_or6 = select i1 %cond_or5, i1 true, i1 %cond4
187   br i1 %cond_or6, label %loop_exit, label %do_something
189 do_something:
190   call void @some_func() noreturn nounwind
191   br label %loop_begin
193 loop_exit:
194   ret i32 0
197 ; Same as test_partial_condition_unswitch_or_select, but with arguments marked
198 ; as noundef.
199 define i32 @test_partial_condition_unswitch_or_select_noundef(ptr noundef %var, i1 noundef %cond1, i1 noundef %cond2, i1 noundef %cond3, i1 noundef %cond4, i1 noundef %cond5, i1 noundef %cond6) {
200 ; CHECK-LABEL: @test_partial_condition_unswitch_or_select_noundef(
201 ; CHECK-NEXT:  entry:
202 ; CHECK-NEXT:    [[TMP0:%.*]] = or i1 [[COND4:%.*]], [[COND2:%.*]]
203 ; CHECK-NEXT:    [[TMP1:%.*]] = or i1 [[TMP0]], [[COND3:%.*]]
204 ; CHECK-NEXT:    [[TMP2:%.*]] = or i1 [[TMP1]], [[COND1:%.*]]
205 ; CHECK-NEXT:    br i1 [[TMP2]], label [[LOOP_EXIT_SPLIT:%.*]], label [[ENTRY_SPLIT:%.*]]
206 ; CHECK:       entry.split:
207 ; CHECK-NEXT:    br label [[LOOP_BEGIN:%.*]]
208 ; CHECK:       loop_begin:
209 ; CHECK-NEXT:    [[VAR_VAL:%.*]] = load i32, ptr [[VAR:%.*]], align 4
210 ; CHECK-NEXT:    [[VAR_COND:%.*]] = trunc i32 [[VAR_VAL]] to i1
211 ; CHECK-NEXT:    [[COND_OR1:%.*]] = or i1 [[VAR_COND]], false
212 ; CHECK-NEXT:    [[COND_OR2:%.*]] = or i1 false, false
213 ; CHECK-NEXT:    [[COND_OR3:%.*]] = or i1 [[COND_OR1]], [[COND_OR2]]
214 ; CHECK-NEXT:    [[COND_XOR1:%.*]] = xor i1 [[COND5:%.*]], [[VAR_COND]]
215 ; CHECK-NEXT:    [[COND_AND1:%.*]] = and i1 [[COND6:%.*]], [[VAR_COND]]
216 ; CHECK-NEXT:    [[COND_OR4:%.*]] = or i1 [[COND_XOR1]], [[COND_AND1]]
217 ; CHECK-NEXT:    [[COND_OR5:%.*]] = select i1 [[COND_OR3]], i1 true, i1 [[COND_OR4]]
218 ; CHECK-NEXT:    [[COND_OR6:%.*]] = select i1 [[COND_OR5]], i1 true, i1 false
219 ; CHECK-NEXT:    br i1 [[COND_OR6]], label [[LOOP_EXIT:%.*]], label [[DO_SOMETHING:%.*]]
220 ; CHECK:       do_something:
221 ; CHECK-NEXT:    call void @some_func() #[[ATTR0]]
222 ; CHECK-NEXT:    br label [[LOOP_BEGIN]]
223 ; CHECK:       loop_exit:
224 ; CHECK-NEXT:    br label [[LOOP_EXIT_SPLIT]]
225 ; CHECK:       loop_exit.split:
226 ; CHECK-NEXT:    ret i32 0
228 entry:
229   br label %loop_begin
231 loop_begin:
232   %var_val = load i32, ptr %var
233   %var_cond = trunc i32 %var_val to i1
234   %cond_or1 = or i1 %var_cond, %cond1
235   %cond_or2 = or i1 %cond2, %cond3
236   %cond_or3 = or i1 %cond_or1, %cond_or2
237   %cond_xor1 = xor i1 %cond5, %var_cond
238   %cond_and1 = and i1 %cond6, %var_cond
239   %cond_or4 = or i1 %cond_xor1, %cond_and1
240   %cond_or5 = select i1 %cond_or3, i1 true, i1 %cond_or4
241   %cond_or6 = select i1 %cond_or5, i1 true, i1 %cond4
242   br i1 %cond_or6, label %loop_exit, label %do_something
244 do_something:
245   call void @some_func() noreturn nounwind
246   br label %loop_begin
248 loop_exit:
249   ret i32 0
252 ; Test case for PR55526.
253 define void @test_pr55526(i16 %a) {
254 ; CHECK-LABEL: @test_pr55526(
255 ; CHECK-NEXT:  entry:
256 ; CHECK-NEXT:    [[TOBOOL:%.*]] = icmp ne i16 [[A:%.*]], 0
257 ; CHECK-NEXT:    br i1 [[TOBOOL]], label [[ENTRY_SPLIT:%.*]], label [[EXIT:%.*]]
258 ; CHECK:       entry.split:
259 ; CHECK-NEXT:    br label [[LOOP:%.*]]
260 ; CHECK:       loop:
261 ; CHECK-NEXT:    [[SEL:%.*]] = select i1 true, i1 true, i1 false
262 ; CHECK-NEXT:    br label [[LOOP]]
263 ; CHECK:       exit:
264 ; CHECK-NEXT:    ret void
266 entry:
267   %tobool = icmp ne i16 %a, 0
268   br label %loop
270 loop:
271   %sel = select i1 %tobool, i1 true, i1 false
272   br i1 %sel, label %loop, label %exit
274 exit:
275   ret void