1; RUN: opt < %s -loop-reduce -S | FileCheck %s
2
3target datalayout = "e-m:x-p:32:32-i64:64-f80:32-n8:16:32-a:0:32-S32"
4target triple = "i686-pc-windows-msvc"
5
6declare i32 @_except_handler3(...)
7declare i32 @__CxxFrameHandler3(...)
8
9declare void @external(i32*)
10declare void @reserve()
11
12define void @f() personality i32 (...)* @_except_handler3 {
13entry:
14  br label %throw
15
16throw:                                            ; preds = %throw, %entry
17  %tmp96 = getelementptr inbounds i8, i8* undef, i32 1
18  invoke void @reserve()
19          to label %throw unwind label %pad
20
21pad:                                              ; preds = %throw
22  %phi2 = phi i8* [ %tmp96, %throw ]
23  terminatepad [] unwind label %blah
24
25blah:
26  catchpad [] to label %unreachable unwind label %blah3
27
28unreachable:
29  unreachable
30
31blah3:
32  catchendpad unwind label %blah2
33
34blah2:
35  %cleanuppadi4.i.i.i = cleanuppad []
36  br label %loop_body
37
38loop_body:                                        ; preds = %iter, %pad
39  %tmp99 = phi i8* [ %tmp101, %iter ], [ %phi2, %blah2 ]
40  %tmp100 = icmp eq i8* %tmp99, undef
41  br i1 %tmp100, label %unwind_out, label %iter
42
43iter:                                             ; preds = %loop_body
44  %tmp101 = getelementptr inbounds i8, i8* %tmp99, i32 1
45  br i1 undef, label %unwind_out, label %loop_body
46
47unwind_out:                                       ; preds = %iter, %loop_body
48  cleanupret %cleanuppadi4.i.i.i unwind to caller
49}
50
51; CHECK-LABEL: define void @f(
52; CHECK: cleanuppad []
53; CHECK-NEXT: ptrtoint i8* %phi2 to i32
54
55define void @g() personality i32 (...)* @_except_handler3 {
56entry:
57  br label %throw
58
59throw:                                            ; preds = %throw, %entry
60  %tmp96 = getelementptr inbounds i8, i8* undef, i32 1
61  invoke void @reserve()
62          to label %throw unwind label %pad
63
64pad:
65  %phi2 = phi i8* [ %tmp96, %throw ]
66  catchpad [] to label %unreachable unwind label %blah
67
68unreachable:
69  unreachable
70
71blah:
72  %catchpad = catchpad [] to label %loop_body unwind label %blah3
73
74
75blah3:
76  catchendpad unwind to caller ;label %blah2
77
78unwind_out:
79  catchret %catchpad to label %leave
80
81leave:
82  ret void
83
84loop_body:                                        ; preds = %iter, %pad
85  %tmp99 = phi i8* [ %tmp101, %iter ], [ %phi2, %blah ]
86  %tmp100 = icmp eq i8* %tmp99, undef
87  br i1 %tmp100, label %unwind_out, label %iter
88
89iter:                                             ; preds = %loop_body
90  %tmp101 = getelementptr inbounds i8, i8* %tmp99, i32 1
91  br i1 undef, label %unwind_out, label %loop_body
92}
93
94; CHECK-LABEL: define void @g(
95; CHECK: blah:
96; CHECK-NEXT: catchpad []
97; CHECK-NEXT: to label %loop_body.preheader
98
99; CHECK: loop_body.preheader:
100; CHECK-NEXT: ptrtoint i8* %phi2 to i32
101
102
103define void @h() personality i32 (...)* @_except_handler3 {
104entry:
105  br label %throw
106
107throw:                                            ; preds = %throw, %entry
108  %tmp96 = getelementptr inbounds i8, i8* undef, i32 1
109  invoke void @reserve()
110          to label %throw unwind label %pad
111
112pad:
113  catchpad [] to label %unreachable unwind label %blug
114
115unreachable:
116  unreachable
117
118blug:
119  %phi2 = phi i8* [ %tmp96, %pad ]
120  %catchpad = catchpad [] to label %blah2 unwind label %blah3
121
122blah2:
123  br label %loop_body
124
125blah3:
126  catchendpad unwind to caller ;label %blah2
127
128unwind_out:
129  catchret %catchpad to label %leave
130
131leave:
132  ret void
133
134loop_body:                                        ; preds = %iter, %pad
135  %tmp99 = phi i8* [ %tmp101, %iter ], [ %phi2, %blah2 ]
136  %tmp100 = icmp eq i8* %tmp99, undef
137  br i1 %tmp100, label %unwind_out, label %iter
138
139iter:                                             ; preds = %loop_body
140  %tmp101 = getelementptr inbounds i8, i8* %tmp99, i32 1
141  br i1 undef, label %unwind_out, label %loop_body
142}
143
144; CHECK-LABEL: define void @h(
145; CHECK: blug:
146; CHECK: catchpad []
147; CHECK-NEXT: to label %blah2
148
149; CHECK: blah2:
150; CHECK-NEXT: ptrtoint i8* %phi2 to i32
151
152define void @i() personality i32 (...)* @_except_handler3 {
153entry:
154  br label %throw
155
156throw:                                            ; preds = %throw, %entry
157  %tmp96 = getelementptr inbounds i8, i8* undef, i32 1
158  invoke void @reserve()
159          to label %throw unwind label %catchpad
160
161catchpad:                                              ; preds = %throw
162  %phi2 = phi i8* [ %tmp96, %throw ]
163  catchpad [] to label %cp_body unwind label %catchendpad
164
165cp_body:
166  br label %loop_head
167
168catchendpad:
169  catchendpad unwind label %cleanuppad
170
171cleanuppad:
172  cleanuppad []
173  br label %loop_head
174
175loop_head:
176  br label %loop_body
177
178loop_body:                                        ; preds = %iter, %catchpad
179  %tmp99 = phi i8* [ %tmp101, %iter ], [ %phi2, %loop_head ]
180  %tmp100 = icmp eq i8* %tmp99, undef
181  br i1 %tmp100, label %unwind_out, label %iter
182
183iter:                                             ; preds = %loop_body
184  %tmp101 = getelementptr inbounds i8, i8* %tmp99, i32 1
185  br i1 undef, label %unwind_out, label %loop_body
186
187unwind_out:                                       ; preds = %iter, %loop_body
188  unreachable
189}
190
191; CHECK-LABEL: define void @i(
192; CHECK: ptrtoint i8* %phi2 to i32
193
194define void @test1(i32* %b, i32* %c) personality i32 (...)* @__CxxFrameHandler3 {
195entry:
196  br label %for.cond
197
198for.cond:                                         ; preds = %for.inc, %entry
199  %d.0 = phi i32* [ %b, %entry ], [ %incdec.ptr, %for.inc ]
200  invoke void @external(i32* %d.0)
201          to label %for.inc unwind label %catch.dispatch
202
203for.inc:                                          ; preds = %for.cond
204  %incdec.ptr = getelementptr inbounds i32, i32* %d.0, i32 1
205  br label %for.cond
206
207catch.dispatch:                                   ; preds = %for.cond
208  %0 = catchpad [i8* null, i32 64, i8* null]
209          to label %catch unwind label %catchendblock
210
211catchendblock:                                    ; preds = %catch.dispatch
212  catchendpad unwind label %catch.dispatch.2
213
214catch:                                            ; preds = %catch.dispatch
215  catchret %0 to label %try.cont
216
217try.cont:                                         ; preds = %catch
218  invoke void @external(i32* %c)
219          to label %try.cont.7 unwind label %catch.dispatch.2
220
221catch.dispatch.2:                                 ; preds = %try.cont, %catchendblock
222  %e.0 = phi i32* [ %c, %try.cont ], [ %b, %catchendblock ]
223  %1 = catchpad [i8* null, i32 64, i8* null]
224          to label %catch.4 unwind label %catchendblock.3
225
226catch.4:                                          ; preds = %catch.dispatch.2
227  unreachable
228
229try.cont.7:                                       ; preds = %try.cont
230  ret void
231
232catchendblock.3:                                  ; preds = %catch.dispatch.2
233  catchendpad unwind to caller
234}
235
236; CHECK-LABEL: define void @test1(
237; CHECK: for.cond:
238; CHECK:   %d.0 = phi i32* [ %b, %entry ], [ %incdec.ptr, %for.inc ]
239
240; CHECK: catchendpad unwind label %catch.dispatch.2
241
242; CHECK: catch.dispatch.2:
243; CHECK: %e.0 = phi i32* [ %c, %try.cont ], [ %b, %catchendblock ]
244