[sanitizer] Improve FreeBSD ASLR detection
[llvm-project.git] / llvm / test / Transforms / LoopSimplify / basictest.ll
blobfc3864bdfc2ea43bc57a4c46dec99440669971ad
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -S -loop-simplify | FileCheck %s
3 ; RUN: opt < %s -S -passes=loop-simplify | FileCheck %s
5 ; This function should get a preheader inserted before bb3, that is jumped
6 ; to by bb1 & bb2
7 define void @test() {
8 ; CHECK-LABEL: @test(
9 ; CHECK-NEXT:  entry:
10 ; CHECK-NEXT:    br i1 true, label [[BB1:%.*]], label [[BB2:%.*]]
11 ; CHECK:       bb1:
12 ; CHECK-NEXT:    br label [[BB3_PREHEADER:%.*]]
13 ; CHECK:       bb2:
14 ; CHECK-NEXT:    br label [[BB3_PREHEADER]]
15 ; CHECK:       bb3.preheader:
16 ; CHECK-NEXT:    br label [[BB3:%.*]]
17 ; CHECK:       bb3:
18 ; CHECK-NEXT:    br label [[BB3]]
20 entry:
21   br i1 true, label %bb1, label %bb2
23 bb1:
24   br label %bb3
26 bb2:
27   br label %bb3
29 bb3:
30   br label %bb3
33 ; Test a case where we have multiple exit blocks as successors of a single loop
34 ; block that need to be made dedicated exit blocks. We also have multiple
35 ; exiting edges to one of the exit blocks that all should be rewritten.
36 define void @test_multiple_exits_from_single_block(i8 %a, i8* %b.ptr) {
37 ; CHECK-LABEL: @test_multiple_exits_from_single_block(
38 ; CHECK-NEXT:  entry:
39 ; CHECK-NEXT:    switch i8 [[A:%.*]], label [[LOOP_PREHEADER:%.*]] [
40 ; CHECK-NEXT:    i8 0, label [[EXIT_A:%.*]]
41 ; CHECK-NEXT:    i8 1, label [[EXIT_B:%.*]]
42 ; CHECK-NEXT:    ]
43 ; CHECK:       loop.preheader:
44 ; CHECK-NEXT:    br label [[LOOP:%.*]]
45 ; CHECK:       loop:
46 ; CHECK-NEXT:    [[B:%.*]] = load volatile i8, i8* [[B_PTR:%.*]]
47 ; CHECK-NEXT:    switch i8 [[B]], label [[LOOP_BACKEDGE:%.*]] [
48 ; CHECK-NEXT:    i8 0, label [[EXIT_A_LOOPEXIT:%.*]]
49 ; CHECK-NEXT:    i8 1, label [[EXIT_B_LOOPEXIT:%.*]]
50 ; CHECK-NEXT:    i8 2, label [[LOOP_BACKEDGE]]
51 ; CHECK-NEXT:    i8 3, label [[EXIT_A_LOOPEXIT]]
52 ; CHECK-NEXT:    i8 4, label [[LOOP_BACKEDGE]]
53 ; CHECK-NEXT:    i8 5, label [[EXIT_A_LOOPEXIT]]
54 ; CHECK-NEXT:    i8 6, label [[LOOP_BACKEDGE]]
55 ; CHECK-NEXT:    ]
56 ; CHECK:       loop.backedge:
57 ; CHECK-NEXT:    br label [[LOOP]]
58 ; CHECK:       exit.a.loopexit:
59 ; CHECK-NEXT:    br label [[EXIT_A]]
60 ; CHECK:       exit.a:
61 ; CHECK-NEXT:    ret void
62 ; CHECK:       exit.b.loopexit:
63 ; CHECK-NEXT:    br label [[EXIT_B]]
64 ; CHECK:       exit.b:
65 ; CHECK-NEXT:    ret void
67 entry:
68   switch i8 %a, label %loop [
69   i8 0, label %exit.a
70   i8 1, label %exit.b
71   ]
73 loop:
74   %b = load volatile i8, i8* %b.ptr
75   switch i8 %b, label %loop [
76   i8 0, label %exit.a
77   i8 1, label %exit.b
78   i8 2, label %loop
79   i8 3, label %exit.a
80   i8 4, label %loop
81   i8 5, label %exit.a
82   i8 6, label %loop
83   ]
85 exit.a:
86   ret void
88 exit.b:
89   ret void
92 ; Check that we leave already dedicated exits alone when forming dedicated exit
93 ; blocks.
94 define void @test_pre_existing_dedicated_exits(i1 %a, i1* %ptr) {
95 ; CHECK-LABEL: @test_pre_existing_dedicated_exits(
96 ; CHECK-NEXT:  entry:
97 ; CHECK-NEXT:    br i1 [[A:%.*]], label [[LOOP_PH:%.*]], label [[NON_DEDICATED_EXIT:%.*]]
98 ; CHECK:       loop.ph:
99 ; CHECK-NEXT:    br label [[LOOP_HEADER:%.*]]
100 ; CHECK:       loop.header:
101 ; CHECK-NEXT:    [[C1:%.*]] = load volatile i1, i1* [[PTR:%.*]]
102 ; CHECK-NEXT:    br i1 [[C1]], label [[LOOP_BODY1:%.*]], label [[DEDICATED_EXIT1:%.*]]
103 ; CHECK:       loop.body1:
104 ; CHECK-NEXT:    [[C2:%.*]] = load volatile i1, i1* [[PTR]]
105 ; CHECK-NEXT:    br i1 [[C2]], label [[LOOP_BODY2:%.*]], label [[NON_DEDICATED_EXIT_LOOPEXIT:%.*]]
106 ; CHECK:       loop.body2:
107 ; CHECK-NEXT:    [[C3:%.*]] = load volatile i1, i1* [[PTR]]
108 ; CHECK-NEXT:    br i1 [[C3]], label [[LOOP_BACKEDGE:%.*]], label [[DEDICATED_EXIT2:%.*]]
109 ; CHECK:       loop.backedge:
110 ; CHECK-NEXT:    br label [[LOOP_HEADER]]
111 ; CHECK:       dedicated_exit1:
112 ; CHECK-NEXT:    ret void
113 ; CHECK:       dedicated_exit2:
114 ; CHECK-NEXT:    ret void
115 ; CHECK:       non_dedicated_exit.loopexit:
116 ; CHECK-NEXT:    br label [[NON_DEDICATED_EXIT]]
117 ; CHECK:       non_dedicated_exit:
118 ; CHECK-NEXT:    ret void
120 entry:
121   br i1 %a, label %loop.ph, label %non_dedicated_exit
123 loop.ph:
124   br label %loop.header
126 loop.header:
127   %c1 = load volatile i1, i1* %ptr
128   br i1 %c1, label %loop.body1, label %dedicated_exit1
130 loop.body1:
131   %c2 = load volatile i1, i1* %ptr
132   br i1 %c2, label %loop.body2, label %non_dedicated_exit
134 loop.body2:
135   %c3 = load volatile i1, i1* %ptr
136   br i1 %c3, label %loop.backedge, label %dedicated_exit2
138 loop.backedge:
139   br label %loop.header
141 dedicated_exit1:
142   ret void
143 ; Check that there isn't a split loop exit.
145 dedicated_exit2:
146   ret void
147 ; Check that there isn't a split loop exit.
149 non_dedicated_exit:
150   ret void
153 ; Check that we form what dedicated exits we can even when some exits are
154 ; reached via indirectbr which precludes forming dedicated exits.
155 define void @test_form_some_dedicated_exits_despite_indirectbr(i8 %a, i8* %ptr, i8** %addr.ptr) {
156 ; CHECK-LABEL: @test_form_some_dedicated_exits_despite_indirectbr(
157 ; CHECK-NEXT:  entry:
158 ; CHECK-NEXT:    switch i8 [[A:%.*]], label [[LOOP_PH:%.*]] [
159 ; CHECK-NEXT:    i8 0, label [[EXIT_A:%.*]]
160 ; CHECK-NEXT:    i8 1, label [[EXIT_B:%.*]]
161 ; CHECK-NEXT:    i8 2, label [[EXIT_C:%.*]]
162 ; CHECK-NEXT:    ]
163 ; CHECK:       loop.ph:
164 ; CHECK-NEXT:    br label [[LOOP_HEADER:%.*]]
165 ; CHECK:       loop.header:
166 ; CHECK-NEXT:    [[ADDR1:%.*]] = load volatile i8*, i8** [[ADDR_PTR:%.*]]
167 ; CHECK-NEXT:    indirectbr i8* [[ADDR1]], [label [[LOOP_BODY1:%.*]], label %exit.a]
168 ; CHECK:       loop.body1:
169 ; CHECK-NEXT:    [[B:%.*]] = load volatile i8, i8* [[PTR:%.*]]
170 ; CHECK-NEXT:    switch i8 [[B]], label [[LOOP_BODY2:%.*]] [
171 ; CHECK-NEXT:    i8 0, label [[EXIT_A]]
172 ; CHECK-NEXT:    i8 1, label [[EXIT_B_LOOPEXIT:%.*]]
173 ; CHECK-NEXT:    i8 2, label [[EXIT_C]]
174 ; CHECK-NEXT:    ]
175 ; CHECK:       loop.body2:
176 ; CHECK-NEXT:    [[ADDR2:%.*]] = load volatile i8*, i8** [[ADDR_PTR]]
177 ; CHECK-NEXT:    indirectbr i8* [[ADDR2]], [label [[LOOP_BACKEDGE:%.*]], label %exit.c]
178 ; CHECK:       loop.backedge:
179 ; CHECK-NEXT:    br label [[LOOP_HEADER]]
180 ; CHECK:       exit.a:
181 ; CHECK-NEXT:    ret void
182 ; CHECK:       exit.b.loopexit:
183 ; CHECK-NEXT:    br label [[EXIT_B]]
184 ; CHECK:       exit.b:
185 ; CHECK-NEXT:    ret void
186 ; CHECK:       exit.c:
187 ; CHECK-NEXT:    ret void
189 entry:
190   switch i8 %a, label %loop.ph [
191   i8 0, label %exit.a
192   i8 1, label %exit.b
193   i8 2, label %exit.c
194   ]
196 loop.ph:
197   br label %loop.header
199 loop.header:
200   %addr1 = load volatile i8*, i8** %addr.ptr
201   indirectbr i8* %addr1, [label %loop.body1, label %exit.a]
203 loop.body1:
204   %b = load volatile i8, i8* %ptr
205   switch i8 %b, label %loop.body2 [
206   i8 0, label %exit.a
207   i8 1, label %exit.b
208   i8 2, label %exit.c
209   ]
211 loop.body2:
212   %addr2 = load volatile i8*, i8** %addr.ptr
213   indirectbr i8* %addr2, [label %loop.backedge, label %exit.c]
215 loop.backedge:
216   br label %loop.header
218 exit.a:
219   ret void
220 ; Check that there isn't a split loop exit.
222 exit.b:
223   ret void
225 exit.c:
226   ret void
227 ; Check that there isn't a split loop exit.