1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt -passes='loop(simple-loop-unswitch)' -S %s | FileCheck %s
3
4declare void @some_func()
5
6define i32 @need_freeze_of_individual_or_conditions1(i1 %cond1, i1 %cond2, i1 %cond3, i1 %cond4) {
7; CHECK-LABEL: @need_freeze_of_individual_or_conditions1(
8; CHECK-NEXT:  entry:
9; CHECK-NEXT:    [[COND4_FR:%.*]] = freeze i1 [[COND4:%.*]]
10; CHECK-NEXT:    [[COND1_FR:%.*]] = freeze i1 [[COND1:%.*]]
11; CHECK-NEXT:    [[TMP0:%.*]] = and i1 [[COND4_FR]], [[COND1_FR]]
12; CHECK-NEXT:    br i1 [[TMP0]], label [[ENTRY_SPLIT:%.*]], label [[EXIT_SPLIT:%.*]]
13; CHECK:       entry.split:
14; CHECK-NEXT:    br label [[LOOP_HEADER:%.*]]
15; CHECK:       loop.header:
16; CHECK-NEXT:    [[OR:%.*]] = or i1 [[COND2:%.*]], [[COND3:%.*]]
17; CHECK-NEXT:    [[AND1:%.*]] = and i1 [[OR]], true
18; CHECK-NEXT:    [[AND2:%.*]] = select i1 [[AND1]], i1 true, i1 false
19; CHECK-NEXT:    br i1 [[AND2]], label [[LOOP_LATCH:%.*]], label [[EXIT:%.*]]
20; CHECK:       loop.latch:
21; CHECK-NEXT:    call void @some_func()
22; CHECK-NEXT:    br label [[LOOP_HEADER]]
23; CHECK:       exit:
24; CHECK-NEXT:    br label [[EXIT_SPLIT]]
25; CHECK:       exit.split:
26; CHECK-NEXT:    ret i32 0
27;
28entry:
29  br label %loop.header
30
31loop.header:
32  %or = or i1 %cond2, %cond3
33  %and1 = and i1 %or, %cond1
34  %and2 = select i1 %and1, i1 %cond4, i1 false
35  br i1 %and2, label %loop.latch, label %exit
36
37loop.latch:
38  call void @some_func()
39  br label %loop.header
40
41exit:
42  ret i32 0
43}
44
45define i32 @need_freeze_of_individual_or_conditions2(i1 noundef %cond1, i1 %cond2, i1 %cond3, i1 %cond4) {
46; CHECK-LABEL: @need_freeze_of_individual_or_conditions2(
47; CHECK-NEXT:  entry:
48; CHECK-NEXT:    [[COND4_FR:%.*]] = freeze i1 [[COND4:%.*]]
49; CHECK-NEXT:    [[TMP0:%.*]] = and i1 [[COND4_FR]], [[COND1:%.*]]
50; CHECK-NEXT:    br i1 [[TMP0]], label [[ENTRY_SPLIT:%.*]], label [[EXIT_SPLIT:%.*]]
51; CHECK:       entry.split:
52; CHECK-NEXT:    br label [[LOOP_HEADER:%.*]]
53; CHECK:       loop.header:
54; CHECK-NEXT:    [[OR:%.*]] = or i1 [[COND2:%.*]], [[COND3:%.*]]
55; CHECK-NEXT:    [[AND1:%.*]] = and i1 [[OR]], true
56; CHECK-NEXT:    [[AND2:%.*]] = select i1 [[AND1]], i1 true, i1 false
57; CHECK-NEXT:    br i1 [[AND2]], label [[LOOP_LATCH:%.*]], label [[EXIT:%.*]]
58; CHECK:       loop.latch:
59; CHECK-NEXT:    call void @some_func()
60; CHECK-NEXT:    br label [[LOOP_HEADER]]
61; CHECK:       exit:
62; CHECK-NEXT:    br label [[EXIT_SPLIT]]
63; CHECK:       exit.split:
64; CHECK-NEXT:    ret i32 0
65;
66entry:
67  br label %loop.header
68
69loop.header:
70  %or = or i1 %cond2, %cond3
71  %and1 = and i1 %or, %cond1
72  %and2 = select i1 %and1, i1 %cond4, i1 false
73  br i1 %and2, label %loop.latch, label %exit
74
75loop.latch:
76  call void @some_func()
77  br label %loop.header
78
79exit:
80  ret i32 0
81}
82
83define i32 @need_freeze_of_individual_or_conditions3(i1 %cond1, i1 %cond2, i1 %cond3, i1 noundef %cond4) {
84; CHECK-LABEL: @need_freeze_of_individual_or_conditions3(
85; CHECK-NEXT:  entry:
86; CHECK-NEXT:    [[COND1_FR:%.*]] = freeze i1 [[COND1:%.*]]
87; CHECK-NEXT:    [[TMP0:%.*]] = and i1 [[COND4:%.*]], [[COND1_FR]]
88; CHECK-NEXT:    br i1 [[TMP0]], label [[ENTRY_SPLIT:%.*]], label [[EXIT_SPLIT:%.*]]
89; CHECK:       entry.split:
90; CHECK-NEXT:    br label [[LOOP_HEADER:%.*]]
91; CHECK:       loop.header:
92; CHECK-NEXT:    [[OR:%.*]] = or i1 [[COND2:%.*]], [[COND3:%.*]]
93; CHECK-NEXT:    [[AND1:%.*]] = and i1 [[OR]], true
94; CHECK-NEXT:    [[AND2:%.*]] = select i1 [[AND1]], i1 true, i1 false
95; CHECK-NEXT:    br i1 [[AND2]], label [[LOOP_LATCH:%.*]], label [[EXIT:%.*]]
96; CHECK:       loop.latch:
97; CHECK-NEXT:    call void @some_func()
98; CHECK-NEXT:    br label [[LOOP_HEADER]]
99; CHECK:       exit:
100; CHECK-NEXT:    br label [[EXIT_SPLIT]]
101; CHECK:       exit.split:
102; CHECK-NEXT:    ret i32 0
103;
104entry:
105  br label %loop.header
106
107loop.header:
108  %or = or i1 %cond2, %cond3
109  %and1 = and i1 %or, %cond1
110  %and2 = select i1 %and1, i1 %cond4, i1 false
111  br i1 %and2, label %loop.latch, label %exit
112
113loop.latch:
114  call void @some_func()
115  br label %loop.header
116
117exit:
118  ret i32 0
119}
120
121define i32 @need_freeze_of_individual_and_conditions1(i1 %cond1, i1 %cond4) {
122; CHECK-LABEL: @need_freeze_of_individual_and_conditions1(
123; CHECK-NEXT:  entry:
124; CHECK-NEXT:    [[COND4_FR:%.*]] = freeze i1 [[COND4:%.*]]
125; CHECK-NEXT:    [[COND1_FR:%.*]] = freeze i1 [[COND1:%.*]]
126; CHECK-NEXT:    [[TMP0:%.*]] = or i1 [[COND4_FR]], [[COND1_FR]]
127; CHECK-NEXT:    br i1 [[TMP0]], label [[EXIT_SPLIT:%.*]], label [[ENTRY_SPLIT:%.*]]
128; CHECK:       entry.split:
129; CHECK-NEXT:    br label [[LOOP_HEADER:%.*]]
130; CHECK:       loop.header:
131; CHECK-NEXT:    [[COND_OR1:%.*]] = or i1 undef, false
132; CHECK-NEXT:    [[COND_OR6:%.*]] = select i1 [[COND_OR1]], i1 true, i1 false
133; CHECK-NEXT:    br i1 [[COND_OR6]], label [[EXIT:%.*]], label [[LOOP_LATCH:%.*]]
134; CHECK:       loop.latch:
135; CHECK-NEXT:    br label [[LOOP_HEADER]]
136; CHECK:       exit:
137; CHECK-NEXT:    br label [[EXIT_SPLIT]]
138; CHECK:       exit.split:
139; CHECK-NEXT:    ret i32 0
140;
141entry:
142  br label %loop.header
143
144loop.header:
145  %cond_or1 = or i1 undef, %cond1
146  %cond_or6 = select i1 %cond_or1, i1 true, i1 %cond4
147  br i1 %cond_or6, label %exit, label %loop.latch
148
149loop.latch:
150  br label %loop.header
151
152exit:
153  ret i32 0
154}
155
156define i32 @need_freeze_of_individual_and_conditions2(i1 noundef %cond1, i1 %cond4) {
157; CHECK-LABEL: @need_freeze_of_individual_and_conditions2(
158; CHECK-NEXT:  entry:
159; CHECK-NEXT:    [[COND4_FR:%.*]] = freeze i1 [[COND4:%.*]]
160; CHECK-NEXT:    [[TMP0:%.*]] = or i1 [[COND4_FR]], [[COND1:%.*]]
161; CHECK-NEXT:    br i1 [[TMP0]], label [[EXIT_SPLIT:%.*]], label [[ENTRY_SPLIT:%.*]]
162; CHECK:       entry.split:
163; CHECK-NEXT:    br label [[LOOP_HEADER:%.*]]
164; CHECK:       loop.header:
165; CHECK-NEXT:    [[COND_OR1:%.*]] = or i1 undef, false
166; CHECK-NEXT:    [[COND_OR6:%.*]] = select i1 [[COND_OR1]], i1 true, i1 false
167; CHECK-NEXT:    br i1 [[COND_OR6]], label [[EXIT:%.*]], label [[LOOP_LATCH:%.*]]
168; CHECK:       loop.latch:
169; CHECK-NEXT:    br label [[LOOP_HEADER]]
170; CHECK:       exit:
171; CHECK-NEXT:    br label [[EXIT_SPLIT]]
172; CHECK:       exit.split:
173; CHECK-NEXT:    ret i32 0
174;
175entry:
176  br label %loop.header
177
178loop.header:
179  %cond_or1 = or i1 undef, %cond1
180  %cond_or6 = select i1 %cond_or1, i1 true, i1 %cond4
181  br i1 %cond_or6, label %exit, label %loop.latch
182
183loop.latch:
184  br label %loop.header
185
186exit:
187  ret i32 0
188}
189
190define i32 @need_freeze_of_individual_and_conditions3(i1 %cond1, i1 noundef %cond4) {
191; CHECK-LABEL: @need_freeze_of_individual_and_conditions3(
192; CHECK-NEXT:  entry:
193; CHECK-NEXT:    [[COND1_FR:%.*]] = freeze i1 [[COND1:%.*]]
194; CHECK-NEXT:    [[TMP0:%.*]] = or i1 [[COND4:%.*]], [[COND1_FR]]
195; CHECK-NEXT:    br i1 [[TMP0]], label [[EXIT_SPLIT:%.*]], label [[ENTRY_SPLIT:%.*]]
196; CHECK:       entry.split:
197; CHECK-NEXT:    br label [[LOOP_HEADER:%.*]]
198; CHECK:       loop.header:
199; CHECK-NEXT:    [[COND_OR1:%.*]] = or i1 undef, false
200; CHECK-NEXT:    [[COND_OR6:%.*]] = select i1 [[COND_OR1]], i1 true, i1 false
201; CHECK-NEXT:    br i1 [[COND_OR6]], label [[EXIT:%.*]], label [[LOOP_LATCH:%.*]]
202; CHECK:       loop.latch:
203; CHECK-NEXT:    br label [[LOOP_HEADER]]
204; CHECK:       exit:
205; CHECK-NEXT:    br label [[EXIT_SPLIT]]
206; CHECK:       exit.split:
207; CHECK-NEXT:    ret i32 0
208;
209entry:
210  br label %loop.header
211
212loop.header:
213  %cond_or1 = or i1 undef, %cond1
214  %cond_or6 = select i1 %cond_or1, i1 true, i1 %cond4
215  br i1 %cond_or6, label %exit, label %loop.latch
216
217loop.latch:
218  br label %loop.header
219
220exit:
221  ret i32 0
222}
223
224define i32 @need_freeze_of_individual_and_conditions4(i1 noundef %cond1, i1 noundef %cond4) {
225; CHECK-LABEL: @need_freeze_of_individual_and_conditions4(
226; CHECK-NEXT:  entry:
227; CHECK-NEXT:    [[TMP0:%.*]] = or i1 [[COND4:%.*]], [[COND1:%.*]]
228; CHECK-NEXT:    br i1 [[TMP0]], label [[EXIT_SPLIT:%.*]], label [[ENTRY_SPLIT:%.*]]
229; CHECK:       entry.split:
230; CHECK-NEXT:    br label [[LOOP_HEADER:%.*]]
231; CHECK:       loop.header:
232; CHECK-NEXT:    [[COND_OR1:%.*]] = or i1 undef, false
233; CHECK-NEXT:    [[COND_OR6:%.*]] = select i1 [[COND_OR1]], i1 true, i1 false
234; CHECK-NEXT:    br i1 [[COND_OR6]], label [[EXIT:%.*]], label [[LOOP_LATCH:%.*]]
235; CHECK:       loop.latch:
236; CHECK-NEXT:    br label [[LOOP_HEADER]]
237; CHECK:       exit:
238; CHECK-NEXT:    br label [[EXIT_SPLIT]]
239; CHECK:       exit.split:
240; CHECK-NEXT:    ret i32 0
241;
242entry:
243  br label %loop.header
244
245loop.header:
246  %cond_or1 = or i1 undef, %cond1
247  %cond_or6 = select i1 %cond_or1, i1 true, i1 %cond4
248  br i1 %cond_or6, label %exit, label %loop.latch
249
250loop.latch:
251  br label %loop.header
252
253exit:
254  ret i32 0
255}
256