xref: /llvm-project/llvm/test/Transforms/SimpleLoopUnswitch/trivial-unswitch-profmd.ll (revision 2f79f5438cd6f4fa0fdc32458911c2d163f917c0)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2;       then metadata checks MDn were added manually.
3; RUN: opt -passes='loop(simple-loop-unswitch),verify<loops>' -S < %s | FileCheck %s
4; RUN: opt -verify-memoryssa -passes='loop-mssa(simple-loop-unswitch),verify<loops>' -S < %s | FileCheck %s
5
6declare void @some_func()
7
8; Test for a trivially unswitchable switch with non-default case exiting.
9define i32 @test2(ptr %var, i32 %cond1, i32 %cond2) {
10; CHECK-LABEL: @test2(
11; CHECK-NEXT:  entry:
12; CHECK-NEXT:    switch i32 [[COND2:%.*]], label [[ENTRY_SPLIT:%.*]] [
13; CHECK-NEXT:    i32 2, label [[LOOP_EXIT2:%.*]]
14; CHECK-NEXT:    ], !prof ![[MD0:[0-9]+]]
15; CHECK:       entry.split:
16; CHECK-NEXT:    br label [[LOOP_BEGIN:%.*]]
17; CHECK:       loop_begin:
18; CHECK-NEXT:    [[VAR_VAL:%.*]] = load i32, ptr [[VAR:%.*]]
19; CHECK-NEXT:    switch i32 [[COND2]], label [[LOOP2:%.*]] [
20; CHECK-NEXT:    i32 0, label [[LOOP0:%.*]]
21; CHECK-NEXT:    i32 1, label [[LOOP1:%.*]]
22; CHECK-NEXT:    ], !prof ![[MD1:[0-9]+]]
23; CHECK:       loop0:
24; CHECK-NEXT:    call void @some_func()
25; CHECK-NEXT:    br label [[LOOP_LATCH:%.*]]
26; CHECK:       loop1:
27; CHECK-NEXT:    call void @some_func()
28; CHECK-NEXT:    br label [[LOOP_LATCH]]
29; CHECK:       loop2:
30; CHECK-NEXT:    call void @some_func()
31; CHECK-NEXT:    br label [[LOOP_LATCH]]
32; CHECK:       loop_latch:
33; CHECK-NEXT:    br label [[LOOP_BEGIN]]
34; CHECK:       loop_exit1:
35; CHECK-NEXT:    ret i32 0
36; CHECK:       loop_exit2:
37; CHECK-NEXT:    ret i32 0
38; CHECK:       loop_exit3:
39; CHECK-NEXT:    ret i32 0
40;
41entry:
42  br label %loop_begin
43
44loop_begin:
45  %var_val = load i32, ptr %var
46  switch i32 %cond2, label %loop2 [
47  i32 0, label %loop0
48  i32 1, label %loop1
49  i32 2, label %loop_exit2
50  ], !prof !{!"branch_weights", i32 99, i32 100, i32 101, i32 102}
51
52loop0:
53  call void @some_func()
54  br label %loop_latch
55
56loop1:
57  call void @some_func()
58  br label %loop_latch
59
60loop2:
61  call void @some_func()
62  br label %loop_latch
63
64loop_latch:
65  br label %loop_begin
66
67loop_exit1:
68  ret i32 0
69
70loop_exit2:
71  ret i32 0
72
73loop_exit3:
74  ret i32 0
75}
76
77; Test for a trivially unswitchable switch with only the default case exiting.
78define i32 @test3(ptr %var, i32 %cond1, i32 %cond2) {
79; CHECK-LABEL: @test3(
80; CHECK-NEXT:  entry:
81; CHECK-NEXT:    switch i32 [[COND2:%.*]], label [[LOOP_EXIT2:%.*]] [
82; CHECK-NEXT:    i32 0, label [[ENTRY_SPLIT:%.*]]
83; CHECK-NEXT:    i32 1, label [[ENTRY_SPLIT]]
84; CHECK-NEXT:    i32 2, label [[ENTRY_SPLIT]]
85; CHECK-NEXT:    ], !prof ![[MD2:[0-9]+]]
86; CHECK:       entry.split:
87; CHECK-NEXT:    br label [[LOOP_BEGIN:%.*]]
88; CHECK:       loop_begin:
89; CHECK-NEXT:    [[VAR_VAL:%.*]] = load i32, ptr [[VAR:%.*]]
90; CHECK-NEXT:    switch i32 [[COND2]], label [[LOOP2:%.*]] [
91; CHECK-NEXT:    i32 0, label [[LOOP0:%.*]]
92; CHECK-NEXT:    i32 1, label [[LOOP1:%.*]]
93; CHECK-NEXT:    ], !prof ![[MD3:[0-9]+]]
94; CHECK:       loop0:
95; CHECK-NEXT:    call void @some_func()
96; CHECK-NEXT:    br label [[LOOP_LATCH:%.*]]
97; CHECK:       loop1:
98; CHECK-NEXT:    call void @some_func()
99; CHECK-NEXT:    br label [[LOOP_LATCH]]
100; CHECK:       loop2:
101; CHECK-NEXT:    call void @some_func()
102; CHECK-NEXT:    br label [[LOOP_LATCH]]
103; CHECK:       loop_latch:
104; CHECK-NEXT:    br label [[LOOP_BEGIN]]
105; CHECK:       loop_exit1:
106; CHECK-NEXT:    ret i32 0
107; CHECK:       loop_exit2:
108; CHECK-NEXT:    ret i32 0
109; CHECK:       loop_exit3:
110; CHECK-NEXT:    ret i32 0
111;
112entry:
113  br label %loop_begin
114
115loop_begin:
116  %var_val = load i32, ptr %var
117  switch i32 %cond2, label %loop_exit2 [
118  i32 0, label %loop0
119  i32 1, label %loop1
120  i32 2, label %loop2
121  ], !prof !{!"branch_weights", i32 99, i32 100, i32 101, i32 102}
122
123loop0:
124  call void @some_func()
125  br label %loop_latch
126
127loop1:
128  call void @some_func()
129  br label %loop_latch
130
131loop2:
132  call void @some_func()
133  br label %loop_latch
134
135loop_latch:
136  br label %loop_begin
137
138loop_exit1:
139  ret i32 0
140
141loop_exit2:
142  ret i32 0
143
144loop_exit3:
145  ret i32 0
146}
147
148; Test for a trivially unswitchable switch with multiple exiting cases and
149; multiple looping cases.
150define i32 @test4(ptr %var, i32 %cond1, i32 %cond2) {
151; CHECK-LABEL: @test4(
152; CHECK-NEXT:  entry:
153; CHECK-NEXT:    switch i32 [[COND2:%.*]], label [[LOOP_EXIT2:%.*]] [
154; CHECK-NEXT:    i32 13, label [[LOOP_EXIT1:%.*]]
155; CHECK-NEXT:    i32 42, label [[LOOP_EXIT3:%.*]]
156; CHECK-NEXT:    i32 0, label [[ENTRY_SPLIT:%.*]]
157; CHECK-NEXT:    i32 1, label [[ENTRY_SPLIT]]
158; CHECK-NEXT:    i32 2, label [[ENTRY_SPLIT]]
159; CHECK-NEXT:    ], !prof ![[MD4:[0-9]+]]
160; CHECK:       entry.split:
161; CHECK-NEXT:    br label [[LOOP_BEGIN:%.*]]
162; CHECK:       loop_begin:
163; CHECK-NEXT:    [[VAR_VAL:%.*]] = load i32, ptr [[VAR:%.*]]
164; CHECK-NEXT:    switch i32 [[COND2]], label [[LOOP2:%.*]] [
165; CHECK-NEXT:    i32 0, label [[LOOP0:%.*]]
166; CHECK-NEXT:    i32 1, label [[LOOP1:%.*]]
167; CHECK-NEXT:    ], !prof ![[MD3:[0-9]+]]
168; CHECK:       loop0:
169; CHECK-NEXT:    call void @some_func()
170; CHECK-NEXT:    br label [[LOOP_LATCH:%.*]]
171; CHECK:       loop1:
172; CHECK-NEXT:    call void @some_func()
173; CHECK-NEXT:    br label [[LOOP_LATCH]]
174; CHECK:       loop2:
175; CHECK-NEXT:    call void @some_func()
176; CHECK-NEXT:    br label [[LOOP_LATCH]]
177; CHECK:       loop_latch:
178; CHECK-NEXT:    br label [[LOOP_BEGIN]]
179; CHECK:       loop_exit1:
180; CHECK-NEXT:    ret i32 0
181; CHECK:       loop_exit2:
182; CHECK-NEXT:    ret i32 0
183; CHECK:       loop_exit3:
184; CHECK-NEXT:    ret i32 0
185;
186entry:
187  br label %loop_begin
188
189loop_begin:
190  %var_val = load i32, ptr %var
191  switch i32 %cond2, label %loop_exit2 [
192  i32 0, label %loop0
193  i32 1, label %loop1
194  i32 13, label %loop_exit1
195  i32 2, label %loop2
196  i32 42, label %loop_exit3
197  ], !prof !{!"branch_weights", i32 99, i32 100, i32 101, i32 113, i32 102, i32 142}
198
199loop0:
200  call void @some_func()
201  br label %loop_latch
202
203loop1:
204  call void @some_func()
205  br label %loop_latch
206
207loop2:
208  call void @some_func()
209  br label %loop_latch
210
211loop_latch:
212  br label %loop_begin
213
214loop_exit1:
215  ret i32 0
216
217loop_exit2:
218  ret i32 0
219
220loop_exit3:
221  ret i32 0
222}
223
224; CHECK: ![[MD0]] = !{!"branch_weights", i32 300, i32 102}
225; CHECK: ![[MD1]] = !{!"branch_weights", i32 99, i32 100, i32 101}
226; CHECK: ![[MD2]] = !{!"branch_weights", i32 99, i32 100, i32 101, i32 102}
227; CHECK: ![[MD3]] = !{!"branch_weights", i32 102, i32 100, i32 101}
228; CHECK: ![[MD4]] = !{!"branch_weights", i32 99, i32 113, i32 142, i32 100, i32 101, i32 102}
229