1ad5a84c8SPhilip Reames; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2ad5a84c8SPhilip Reames; RUN: opt < %s -loop-predication -S | FileCheck %s
3ad5a84c8SPhilip Reames
4ad5a84c8SPhilip Reamesdeclare void @prevent_merging()
5ad5a84c8SPhilip Reames
6ad5a84c8SPhilip Reames; Base case - with side effects in loop
7ad5a84c8SPhilip Reamesdefine i32 @test1(i32* %array, i32 %length, i32 %n, i1 %cond_0) {
8ad5a84c8SPhilip Reames; CHECK-LABEL: @test1(
9ad5a84c8SPhilip Reames; CHECK-NEXT:  entry:
10ad5a84c8SPhilip Reames; CHECK-NEXT:    [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
11*b46c085dSRoman Lebedev; CHECK-NEXT:    [[UMAX:%.*]] = call i32 @llvm.umax.i32(i32 [[N:%.*]], i32 1)
12*b46c085dSRoman Lebedev; CHECK-NEXT:    [[TMP0:%.*]] = add i32 [[UMAX]], -1
13*b46c085dSRoman Lebedev; CHECK-NEXT:    [[UMIN:%.*]] = call i32 @llvm.umin.i32(i32 [[LENGTH:%.*]], i32 [[TMP0]])
14*b46c085dSRoman Lebedev; CHECK-NEXT:    [[TMP1:%.*]] = icmp ugt i32 [[LENGTH]], [[UMIN]]
15*b46c085dSRoman Lebedev; CHECK-NEXT:    [[TMP2:%.*]] = freeze i1 [[TMP1]]
16*b46c085dSRoman Lebedev; CHECK-NEXT:    [[TMP3:%.*]] = and i1 [[TMP2]], [[COND_0:%.*]]
17*b46c085dSRoman Lebedev; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[TMP3]], [[WIDENABLE_COND]]
18ad5a84c8SPhilip Reames; CHECK-NEXT:    br i1 [[EXIPLICIT_GUARD_COND]], label [[LOOP_PREHEADER:%.*]], label [[DEOPT:%.*]], !prof !0
19ad5a84c8SPhilip Reames; CHECK:       deopt:
20ad5a84c8SPhilip Reames; CHECK-NEXT:    [[DEOPTRET:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
21ad5a84c8SPhilip Reames; CHECK-NEXT:    ret i32 [[DEOPTRET]]
22ad5a84c8SPhilip Reames; CHECK:       loop.preheader:
23ad5a84c8SPhilip Reames; CHECK-NEXT:    br label [[LOOP:%.*]]
24ad5a84c8SPhilip Reames; CHECK:       loop:
25ad5a84c8SPhilip Reames; CHECK-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
26ad5a84c8SPhilip Reames; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ]
27ad5a84c8SPhilip Reames; CHECK-NEXT:    call void @unknown()
28ad5a84c8SPhilip Reames; CHECK-NEXT:    [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH]]
29ad5a84c8SPhilip Reames; CHECK-NEXT:    br i1 true, label [[GUARDED]], label [[DEOPT2:%.*]], !prof !0
30ad5a84c8SPhilip Reames; CHECK:       deopt2:
31ad5a84c8SPhilip Reames; CHECK-NEXT:    call void @unknown()
32ad5a84c8SPhilip Reames; CHECK-NEXT:    [[DEOPTRET2:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
33ad5a84c8SPhilip Reames; CHECK-NEXT:    ret i32 [[DEOPTRET2]]
34ad5a84c8SPhilip Reames; CHECK:       guarded:
35ad5a84c8SPhilip Reames; CHECK-NEXT:    [[I_I64:%.*]] = zext i32 [[I]] to i64
36ad5a84c8SPhilip Reames; CHECK-NEXT:    [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
37ad5a84c8SPhilip Reames; CHECK-NEXT:    [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
38*b46c085dSRoman Lebedev; CHECK-NEXT:    store i32 0, i32* [[ARRAY_I_PTR]], align 4
39ad5a84c8SPhilip Reames; CHECK-NEXT:    [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
40ad5a84c8SPhilip Reames; CHECK-NEXT:    [[I_NEXT]] = add nuw i32 [[I]], 1
41ad5a84c8SPhilip Reames; CHECK-NEXT:    [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[N]]
42ad5a84c8SPhilip Reames; CHECK-NEXT:    br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT:%.*]]
43ad5a84c8SPhilip Reames; CHECK:       exit:
44ad5a84c8SPhilip Reames; CHECK-NEXT:    [[RESULT:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ]
45ad5a84c8SPhilip Reames; CHECK-NEXT:    ret i32 [[RESULT]]
46ad5a84c8SPhilip Reames;
47ad5a84c8SPhilip Reamesentry:
48ad5a84c8SPhilip Reames  %widenable_cond = call i1 @llvm.experimental.widenable.condition()
49ad5a84c8SPhilip Reames  %exiplicit_guard_cond = and i1 %cond_0, %widenable_cond
50ad5a84c8SPhilip Reames  br i1 %exiplicit_guard_cond, label %loop.preheader, label %deopt, !prof !0
51ad5a84c8SPhilip Reames
52ad5a84c8SPhilip Reamesdeopt:
53ad5a84c8SPhilip Reames  %deoptret = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
54ad5a84c8SPhilip Reames  ret i32 %deoptret
55ad5a84c8SPhilip Reames
56ad5a84c8SPhilip Reamesloop.preheader:
57ad5a84c8SPhilip Reames  br label %loop
58ad5a84c8SPhilip Reames
59ad5a84c8SPhilip Reamesloop:
60ad5a84c8SPhilip Reames  %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ]
61ad5a84c8SPhilip Reames  %i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ]
62ad5a84c8SPhilip Reames  call void @unknown()
63ad5a84c8SPhilip Reames  %within.bounds = icmp ult i32 %i, %length
64ad5a84c8SPhilip Reames  br i1 %within.bounds, label %guarded, label %deopt2, !prof !0
65ad5a84c8SPhilip Reames
66ad5a84c8SPhilip Reamesdeopt2:
67ad5a84c8SPhilip Reames  call void @unknown()
68ad5a84c8SPhilip Reames  %deoptret2 = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
69ad5a84c8SPhilip Reames  ret i32 %deoptret2
70ad5a84c8SPhilip Reames
71ad5a84c8SPhilip Reamesguarded:
72ad5a84c8SPhilip Reames  %i.i64 = zext i32 %i to i64
73ad5a84c8SPhilip Reames  %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
74ad5a84c8SPhilip Reames  %array.i = load i32, i32* %array.i.ptr, align 4
75ad5a84c8SPhilip Reames  store i32 0, i32* %array.i.ptr
76ad5a84c8SPhilip Reames  %loop.acc.next = add i32 %loop.acc, %array.i
77ad5a84c8SPhilip Reames  %i.next = add nuw i32 %i, 1
78ad5a84c8SPhilip Reames  %continue = icmp ult i32 %i.next, %n
79ad5a84c8SPhilip Reames  br i1 %continue, label %loop, label %exit
80ad5a84c8SPhilip Reames
81ad5a84c8SPhilip Reamesexit:
82ad5a84c8SPhilip Reames  %result = phi i32 [ %loop.acc.next, %guarded ]
83ad5a84c8SPhilip Reames  ret i32 %result
84ad5a84c8SPhilip Reames}
85ad5a84c8SPhilip Reames
86ad5a84c8SPhilip Reames
87ad5a84c8SPhilip Reames
88ad5a84c8SPhilip Reamesdefine i32 @test_non_canonical(i32* %array, i32 %length, i1 %cond_0) {
89ad5a84c8SPhilip Reames; CHECK-LABEL: @test_non_canonical(
90ad5a84c8SPhilip Reames; CHECK-NEXT:  entry:
91ad5a84c8SPhilip Reames; CHECK-NEXT:    [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
92*b46c085dSRoman Lebedev; CHECK-NEXT:    [[UMAX:%.*]] = call i32 @llvm.umax.i32(i32 [[LENGTH:%.*]], i32 1)
93*b46c085dSRoman Lebedev; CHECK-NEXT:    [[TMP0:%.*]] = add i32 [[UMAX]], -1
94*b46c085dSRoman Lebedev; CHECK-NEXT:    [[UMIN:%.*]] = call i32 @llvm.umin.i32(i32 [[LENGTH]], i32 [[TMP0]])
95*b46c085dSRoman Lebedev; CHECK-NEXT:    [[TMP1:%.*]] = icmp ugt i32 [[LENGTH]], [[UMIN]]
96*b46c085dSRoman Lebedev; CHECK-NEXT:    [[TMP2:%.*]] = freeze i1 [[TMP1]]
97*b46c085dSRoman Lebedev; CHECK-NEXT:    [[TMP3:%.*]] = and i1 [[TMP2]], [[COND_0:%.*]]
98*b46c085dSRoman Lebedev; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[TMP3]], [[WIDENABLE_COND]]
99ad5a84c8SPhilip Reames; CHECK-NEXT:    br i1 [[EXIPLICIT_GUARD_COND]], label [[LOOP_PREHEADER:%.*]], label [[DEOPT:%.*]], !prof !0
100ad5a84c8SPhilip Reames; CHECK:       deopt:
101ad5a84c8SPhilip Reames; CHECK-NEXT:    [[DEOPTRET:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
102ad5a84c8SPhilip Reames; CHECK-NEXT:    ret i32 [[DEOPTRET]]
103ad5a84c8SPhilip Reames; CHECK:       loop.preheader:
104ad5a84c8SPhilip Reames; CHECK-NEXT:    br label [[LOOP:%.*]]
105ad5a84c8SPhilip Reames; CHECK:       loop:
106ad5a84c8SPhilip Reames; CHECK-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
107ad5a84c8SPhilip Reames; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ]
108ad5a84c8SPhilip Reames; CHECK-NEXT:    call void @unknown()
109ad5a84c8SPhilip Reames; CHECK-NEXT:    [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH]]
110ad5a84c8SPhilip Reames; CHECK-NEXT:    br i1 true, label [[GUARDED]], label [[DEOPT2:%.*]], !prof !0
111ad5a84c8SPhilip Reames; CHECK:       deopt2:
112ad5a84c8SPhilip Reames; CHECK-NEXT:    call void @unknown()
113ad5a84c8SPhilip Reames; CHECK-NEXT:    [[DEOPTRET2:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
114ad5a84c8SPhilip Reames; CHECK-NEXT:    ret i32 [[DEOPTRET2]]
115ad5a84c8SPhilip Reames; CHECK:       guarded:
116ad5a84c8SPhilip Reames; CHECK-NEXT:    [[I_I64:%.*]] = zext i32 [[I]] to i64
117ad5a84c8SPhilip Reames; CHECK-NEXT:    [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
118ad5a84c8SPhilip Reames; CHECK-NEXT:    [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
119*b46c085dSRoman Lebedev; CHECK-NEXT:    store i32 0, i32* [[ARRAY_I_PTR]], align 4
120ad5a84c8SPhilip Reames; CHECK-NEXT:    [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
121ad5a84c8SPhilip Reames; CHECK-NEXT:    [[I_NEXT]] = add nuw i32 [[I]], 1
122ad5a84c8SPhilip Reames; CHECK-NEXT:    [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[LENGTH]]
123ad5a84c8SPhilip Reames; CHECK-NEXT:    br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT:%.*]]
124ad5a84c8SPhilip Reames; CHECK:       exit:
125ad5a84c8SPhilip Reames; CHECK-NEXT:    [[RESULT:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ]
126ad5a84c8SPhilip Reames; CHECK-NEXT:    ret i32 [[RESULT]]
127ad5a84c8SPhilip Reames;
128ad5a84c8SPhilip Reamesentry:
129ad5a84c8SPhilip Reames  %widenable_cond = call i1 @llvm.experimental.widenable.condition()
130ad5a84c8SPhilip Reames  %exiplicit_guard_cond = and i1 %cond_0, %widenable_cond
131ad5a84c8SPhilip Reames  br i1 %exiplicit_guard_cond, label %loop.preheader, label %deopt, !prof !0
132ad5a84c8SPhilip Reames
133ad5a84c8SPhilip Reamesdeopt:
134ad5a84c8SPhilip Reames  %deoptret = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
135ad5a84c8SPhilip Reames  ret i32 %deoptret
136ad5a84c8SPhilip Reames
137ad5a84c8SPhilip Reamesloop.preheader:
138ad5a84c8SPhilip Reames  br label %loop
139ad5a84c8SPhilip Reames
140ad5a84c8SPhilip Reamesloop:
141ad5a84c8SPhilip Reames  %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ]
142ad5a84c8SPhilip Reames  %i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ]
143ad5a84c8SPhilip Reames  call void @unknown()
144ad5a84c8SPhilip Reames  %within.bounds = icmp ult i32 %i, %length
145ad5a84c8SPhilip Reames  br i1 %within.bounds, label %guarded, label %deopt2, !prof !0
146ad5a84c8SPhilip Reames
147ad5a84c8SPhilip Reamesdeopt2:
148ad5a84c8SPhilip Reames  call void @unknown()
149ad5a84c8SPhilip Reames  %deoptret2 = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
150ad5a84c8SPhilip Reames  ret i32 %deoptret2
151ad5a84c8SPhilip Reames
152ad5a84c8SPhilip Reamesguarded:
153ad5a84c8SPhilip Reames  %i.i64 = zext i32 %i to i64
154ad5a84c8SPhilip Reames  %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
155ad5a84c8SPhilip Reames  %array.i = load i32, i32* %array.i.ptr, align 4
156ad5a84c8SPhilip Reames  store i32 0, i32* %array.i.ptr
157ad5a84c8SPhilip Reames  %loop.acc.next = add i32 %loop.acc, %array.i
158ad5a84c8SPhilip Reames  %i.next = add nuw i32 %i, 1
159ad5a84c8SPhilip Reames  %continue = icmp ult i32 %i.next, %length
160ad5a84c8SPhilip Reames  br i1 %continue, label %loop, label %exit
161ad5a84c8SPhilip Reames
162ad5a84c8SPhilip Reamesexit:
163ad5a84c8SPhilip Reames  %result = phi i32 [ %loop.acc.next, %guarded ]
164ad5a84c8SPhilip Reames  ret i32 %result
165ad5a84c8SPhilip Reames}
166ad5a84c8SPhilip Reames
167ad5a84c8SPhilip Reames
168ad5a84c8SPhilip Reamesdefine i32 @test_two_range_checks(i32* %array, i32 %length.1, i32 %length.2, i32 %n, i1 %cond_0) {
169ad5a84c8SPhilip Reames; CHECK-LABEL: @test_two_range_checks(
170ad5a84c8SPhilip Reames; CHECK-NEXT:  entry:
171ad5a84c8SPhilip Reames; CHECK-NEXT:    [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
172*b46c085dSRoman Lebedev; CHECK-NEXT:    [[UMIN:%.*]] = call i32 @llvm.umin.i32(i32 [[LENGTH_2:%.*]], i32 [[LENGTH_1:%.*]])
173*b46c085dSRoman Lebedev; CHECK-NEXT:    [[UMAX:%.*]] = call i32 @llvm.umax.i32(i32 [[N:%.*]], i32 1)
174*b46c085dSRoman Lebedev; CHECK-NEXT:    [[TMP0:%.*]] = add i32 [[UMAX]], -1
175*b46c085dSRoman Lebedev; CHECK-NEXT:    [[UMIN1:%.*]] = call i32 @llvm.umin.i32(i32 [[UMIN]], i32 [[TMP0]])
176*b46c085dSRoman Lebedev; CHECK-NEXT:    [[TMP1:%.*]] = icmp ugt i32 [[LENGTH_1]], [[UMIN1]]
177*b46c085dSRoman Lebedev; CHECK-NEXT:    [[TMP2:%.*]] = freeze i1 [[TMP1]]
178*b46c085dSRoman Lebedev; CHECK-NEXT:    [[TMP3:%.*]] = and i1 [[TMP2]], [[COND_0:%.*]]
179*b46c085dSRoman Lebedev; CHECK-NEXT:    [[TMP4:%.*]] = icmp ugt i32 [[LENGTH_2]], [[UMIN1]]
180ad5a84c8SPhilip Reames; CHECK-NEXT:    [[TMP5:%.*]] = freeze i1 [[TMP4]]
181*b46c085dSRoman Lebedev; CHECK-NEXT:    [[TMP6:%.*]] = and i1 [[TMP5]], [[TMP3]]
182*b46c085dSRoman Lebedev; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[TMP6]], [[WIDENABLE_COND]]
183ad5a84c8SPhilip Reames; CHECK-NEXT:    br i1 [[EXIPLICIT_GUARD_COND]], label [[LOOP_PREHEADER:%.*]], label [[DEOPT:%.*]], !prof !0
184ad5a84c8SPhilip Reames; CHECK:       deopt:
185ad5a84c8SPhilip Reames; CHECK-NEXT:    [[DEOPTRET:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
186ad5a84c8SPhilip Reames; CHECK-NEXT:    ret i32 [[DEOPTRET]]
187ad5a84c8SPhilip Reames; CHECK:       loop.preheader:
188ad5a84c8SPhilip Reames; CHECK-NEXT:    br label [[LOOP:%.*]]
189ad5a84c8SPhilip Reames; CHECK:       loop:
190ad5a84c8SPhilip Reames; CHECK-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED2:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
191ad5a84c8SPhilip Reames; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED2]] ], [ 0, [[LOOP_PREHEADER]] ]
192ad5a84c8SPhilip Reames; CHECK-NEXT:    call void @unknown()
193ad5a84c8SPhilip Reames; CHECK-NEXT:    [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH_1]]
194ad5a84c8SPhilip Reames; CHECK-NEXT:    br i1 true, label [[GUARDED:%.*]], label [[DEOPT2:%.*]], !prof !0
195ad5a84c8SPhilip Reames; CHECK:       deopt2:
196ad5a84c8SPhilip Reames; CHECK-NEXT:    call void @unknown()
197ad5a84c8SPhilip Reames; CHECK-NEXT:    [[DEOPTRET2:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
198ad5a84c8SPhilip Reames; CHECK-NEXT:    ret i32 [[DEOPTRET2]]
199ad5a84c8SPhilip Reames; CHECK:       guarded:
200ad5a84c8SPhilip Reames; CHECK-NEXT:    [[WITHIN_BOUNDS2:%.*]] = icmp ult i32 [[I]], [[LENGTH_2]]
201ad5a84c8SPhilip Reames; CHECK-NEXT:    br i1 true, label [[GUARDED2]], label [[DEOPT3:%.*]], !prof !0
202ad5a84c8SPhilip Reames; CHECK:       deopt3:
203ad5a84c8SPhilip Reames; CHECK-NEXT:    call void @unknown()
204ad5a84c8SPhilip Reames; CHECK-NEXT:    [[DEOPTRET3:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
205ad5a84c8SPhilip Reames; CHECK-NEXT:    ret i32 [[DEOPTRET3]]
206ad5a84c8SPhilip Reames; CHECK:       guarded2:
207ad5a84c8SPhilip Reames; CHECK-NEXT:    [[I_I64:%.*]] = zext i32 [[I]] to i64
208ad5a84c8SPhilip Reames; CHECK-NEXT:    [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
209ad5a84c8SPhilip Reames; CHECK-NEXT:    [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
210*b46c085dSRoman Lebedev; CHECK-NEXT:    store i32 0, i32* [[ARRAY_I_PTR]], align 4
211ad5a84c8SPhilip Reames; CHECK-NEXT:    [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
212ad5a84c8SPhilip Reames; CHECK-NEXT:    [[I_NEXT]] = add nuw i32 [[I]], 1
213ad5a84c8SPhilip Reames; CHECK-NEXT:    [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[N]]
214ad5a84c8SPhilip Reames; CHECK-NEXT:    br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT:%.*]]
215ad5a84c8SPhilip Reames; CHECK:       exit:
216ad5a84c8SPhilip Reames; CHECK-NEXT:    [[RESULT:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED2]] ]
217ad5a84c8SPhilip Reames; CHECK-NEXT:    ret i32 [[RESULT]]
218ad5a84c8SPhilip Reames;
219ad5a84c8SPhilip Reamesentry:
220ad5a84c8SPhilip Reames  %widenable_cond = call i1 @llvm.experimental.widenable.condition()
221ad5a84c8SPhilip Reames  %exiplicit_guard_cond = and i1 %cond_0, %widenable_cond
222ad5a84c8SPhilip Reames  br i1 %exiplicit_guard_cond, label %loop.preheader, label %deopt, !prof !0
223ad5a84c8SPhilip Reames
224ad5a84c8SPhilip Reamesdeopt:
225ad5a84c8SPhilip Reames  %deoptret = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
226ad5a84c8SPhilip Reames  ret i32 %deoptret
227ad5a84c8SPhilip Reames
228ad5a84c8SPhilip Reamesloop.preheader:
229ad5a84c8SPhilip Reames  br label %loop
230ad5a84c8SPhilip Reames
231ad5a84c8SPhilip Reamesloop:
232ad5a84c8SPhilip Reames  %loop.acc = phi i32 [ %loop.acc.next, %guarded2 ], [ 0, %loop.preheader ]
233ad5a84c8SPhilip Reames  %i = phi i32 [ %i.next, %guarded2 ], [ 0, %loop.preheader ]
234ad5a84c8SPhilip Reames  call void @unknown()
235ad5a84c8SPhilip Reames  %within.bounds = icmp ult i32 %i, %length.1
236ad5a84c8SPhilip Reames  br i1 %within.bounds, label %guarded, label %deopt2, !prof !0
237ad5a84c8SPhilip Reames
238ad5a84c8SPhilip Reamesdeopt2:
239ad5a84c8SPhilip Reames  call void @unknown()
240ad5a84c8SPhilip Reames  %deoptret2 = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
241ad5a84c8SPhilip Reames  ret i32 %deoptret2
242ad5a84c8SPhilip Reames
243ad5a84c8SPhilip Reamesguarded:
244ad5a84c8SPhilip Reames  %within.bounds2 = icmp ult i32 %i, %length.2
245ad5a84c8SPhilip Reames  br i1 %within.bounds2, label %guarded2, label %deopt3, !prof !0
246ad5a84c8SPhilip Reames
247ad5a84c8SPhilip Reamesdeopt3:
248ad5a84c8SPhilip Reames  call void @unknown()
249ad5a84c8SPhilip Reames  %deoptret3 = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
250ad5a84c8SPhilip Reames  ret i32 %deoptret3
251ad5a84c8SPhilip Reames
252ad5a84c8SPhilip Reamesguarded2:
253ad5a84c8SPhilip Reames  %i.i64 = zext i32 %i to i64
254ad5a84c8SPhilip Reames  %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
255ad5a84c8SPhilip Reames  %array.i = load i32, i32* %array.i.ptr, align 4
256ad5a84c8SPhilip Reames  store i32 0, i32* %array.i.ptr
257ad5a84c8SPhilip Reames  %loop.acc.next = add i32 %loop.acc, %array.i
258ad5a84c8SPhilip Reames  %i.next = add nuw i32 %i, 1
259ad5a84c8SPhilip Reames  %continue = icmp ult i32 %i.next, %n
260ad5a84c8SPhilip Reames  br i1 %continue, label %loop, label %exit
261ad5a84c8SPhilip Reames
262ad5a84c8SPhilip Reamesexit:
263ad5a84c8SPhilip Reames  %result = phi i32 [ %loop.acc.next, %guarded2 ]
264ad5a84c8SPhilip Reames  ret i32 %result
265ad5a84c8SPhilip Reames}
266ad5a84c8SPhilip Reames
267ad5a84c8SPhilip Reames@G = external global i32
268ad5a84c8SPhilip Reames
269ad5a84c8SPhilip Reamesdefine i32 @test_unanalyzeable_exit(i32* %array, i32 %length, i32 %n, i1 %cond_0) {
270ad5a84c8SPhilip Reames; CHECK-LABEL: @test_unanalyzeable_exit(
271ad5a84c8SPhilip Reames; CHECK-NEXT:  entry:
272ad5a84c8SPhilip Reames; CHECK-NEXT:    [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
273ad5a84c8SPhilip Reames; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[COND_0:%.*]], [[WIDENABLE_COND]]
274ad5a84c8SPhilip Reames; CHECK-NEXT:    br i1 [[EXIPLICIT_GUARD_COND]], label [[LOOP_PREHEADER:%.*]], label [[DEOPT:%.*]], !prof !0
275ad5a84c8SPhilip Reames; CHECK:       deopt:
276ad5a84c8SPhilip Reames; CHECK-NEXT:    [[DEOPTRET:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
277ad5a84c8SPhilip Reames; CHECK-NEXT:    ret i32 [[DEOPTRET]]
278ad5a84c8SPhilip Reames; CHECK:       loop.preheader:
279ad5a84c8SPhilip Reames; CHECK-NEXT:    br label [[LOOP:%.*]]
280ad5a84c8SPhilip Reames; CHECK:       loop:
281ad5a84c8SPhilip Reames; CHECK-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED2:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
282ad5a84c8SPhilip Reames; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED2]] ], [ 0, [[LOOP_PREHEADER]] ]
283ad5a84c8SPhilip Reames; CHECK-NEXT:    call void @unknown()
284*b46c085dSRoman Lebedev; CHECK-NEXT:    [[VOL:%.*]] = load volatile i32, i32* @G, align 4
285ad5a84c8SPhilip Reames; CHECK-NEXT:    [[UNKNOWN:%.*]] = icmp eq i32 [[VOL]], 0
286ad5a84c8SPhilip Reames; CHECK-NEXT:    br i1 [[UNKNOWN]], label [[GUARDED2]], label [[DEOPT3:%.*]], !prof !0
287ad5a84c8SPhilip Reames; CHECK:       deopt3:
288ad5a84c8SPhilip Reames; CHECK-NEXT:    call void @unknown()
289ad5a84c8SPhilip Reames; CHECK-NEXT:    [[DEOPTRET3:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
290ad5a84c8SPhilip Reames; CHECK-NEXT:    ret i32 [[DEOPTRET3]]
291ad5a84c8SPhilip Reames; CHECK:       guarded2:
292ad5a84c8SPhilip Reames; CHECK-NEXT:    [[I_I64:%.*]] = zext i32 [[I]] to i64
293ad5a84c8SPhilip Reames; CHECK-NEXT:    [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
294ad5a84c8SPhilip Reames; CHECK-NEXT:    [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
295*b46c085dSRoman Lebedev; CHECK-NEXT:    store i32 0, i32* [[ARRAY_I_PTR]], align 4
296ad5a84c8SPhilip Reames; CHECK-NEXT:    [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
297ad5a84c8SPhilip Reames; CHECK-NEXT:    [[I_NEXT]] = add nuw i32 [[I]], 1
298ad5a84c8SPhilip Reames; CHECK-NEXT:    [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[N:%.*]]
299ad5a84c8SPhilip Reames; CHECK-NEXT:    br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT:%.*]]
300ad5a84c8SPhilip Reames; CHECK:       exit:
301ad5a84c8SPhilip Reames; CHECK-NEXT:    [[RESULT:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED2]] ]
302ad5a84c8SPhilip Reames; CHECK-NEXT:    ret i32 [[RESULT]]
303ad5a84c8SPhilip Reames;
304ad5a84c8SPhilip Reamesentry:
305ad5a84c8SPhilip Reames  %widenable_cond = call i1 @llvm.experimental.widenable.condition()
306ad5a84c8SPhilip Reames  %exiplicit_guard_cond = and i1 %cond_0, %widenable_cond
307ad5a84c8SPhilip Reames  br i1 %exiplicit_guard_cond, label %loop.preheader, label %deopt, !prof !0
308ad5a84c8SPhilip Reames
309ad5a84c8SPhilip Reamesdeopt:
310ad5a84c8SPhilip Reames  %deoptret = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
311ad5a84c8SPhilip Reames  ret i32 %deoptret
312ad5a84c8SPhilip Reames
313ad5a84c8SPhilip Reamesloop.preheader:
314ad5a84c8SPhilip Reames  br label %loop
315ad5a84c8SPhilip Reames
316ad5a84c8SPhilip Reamesloop:
317ad5a84c8SPhilip Reames  %loop.acc = phi i32 [ %loop.acc.next, %guarded2 ], [ 0, %loop.preheader ]
318ad5a84c8SPhilip Reames  %i = phi i32 [ %i.next, %guarded2 ], [ 0, %loop.preheader ]
319ad5a84c8SPhilip Reames  call void @unknown()
320ad5a84c8SPhilip Reames  %vol = load volatile i32, i32* @G
321ad5a84c8SPhilip Reames  %unknown = icmp eq i32 %vol, 0
322ad5a84c8SPhilip Reames  br i1 %unknown, label %guarded2, label %deopt3, !prof !0
323ad5a84c8SPhilip Reames
324ad5a84c8SPhilip Reamesdeopt3:
325ad5a84c8SPhilip Reames  call void @unknown()
326ad5a84c8SPhilip Reames  %deoptret3 = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
327ad5a84c8SPhilip Reames  ret i32 %deoptret3
328ad5a84c8SPhilip Reames
329ad5a84c8SPhilip Reamesguarded2:
330ad5a84c8SPhilip Reames  %i.i64 = zext i32 %i to i64
331ad5a84c8SPhilip Reames  %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
332ad5a84c8SPhilip Reames  %array.i = load i32, i32* %array.i.ptr, align 4
333ad5a84c8SPhilip Reames  store i32 0, i32* %array.i.ptr
334ad5a84c8SPhilip Reames  %loop.acc.next = add i32 %loop.acc, %array.i
335ad5a84c8SPhilip Reames  %i.next = add nuw i32 %i, 1
336ad5a84c8SPhilip Reames  %continue = icmp ult i32 %i.next, %n
337ad5a84c8SPhilip Reames  br i1 %continue, label %loop, label %exit
338ad5a84c8SPhilip Reames
339ad5a84c8SPhilip Reamesexit:
340ad5a84c8SPhilip Reames  %result = phi i32 [ %loop.acc.next, %guarded2 ]
341ad5a84c8SPhilip Reames  ret i32 %result
342ad5a84c8SPhilip Reames}
343ad5a84c8SPhilip Reames
344ad5a84c8SPhilip Reamesdefine i32 @test_unanalyzeable_exit2(i32* %array, i32 %length, i32 %n, i1 %cond_0) {
345ad5a84c8SPhilip Reames; CHECK-LABEL: @test_unanalyzeable_exit2(
346ad5a84c8SPhilip Reames; CHECK-NEXT:  entry:
347ad5a84c8SPhilip Reames; CHECK-NEXT:    [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
348*b46c085dSRoman Lebedev; CHECK-NEXT:    [[UMAX:%.*]] = call i32 @llvm.umax.i32(i32 [[N:%.*]], i32 1)
349*b46c085dSRoman Lebedev; CHECK-NEXT:    [[TMP0:%.*]] = add i32 [[UMAX]], -1
350*b46c085dSRoman Lebedev; CHECK-NEXT:    [[UMIN:%.*]] = call i32 @llvm.umin.i32(i32 [[LENGTH:%.*]], i32 [[TMP0]])
351*b46c085dSRoman Lebedev; CHECK-NEXT:    [[TMP1:%.*]] = icmp ugt i32 [[LENGTH]], [[UMIN]]
352*b46c085dSRoman Lebedev; CHECK-NEXT:    [[TMP2:%.*]] = freeze i1 [[TMP1]]
353*b46c085dSRoman Lebedev; CHECK-NEXT:    [[TMP3:%.*]] = and i1 [[TMP2]], [[COND_0:%.*]]
354*b46c085dSRoman Lebedev; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[TMP3]], [[WIDENABLE_COND]]
355ad5a84c8SPhilip Reames; CHECK-NEXT:    br i1 [[EXIPLICIT_GUARD_COND]], label [[LOOP_PREHEADER:%.*]], label [[DEOPT:%.*]], !prof !0
356ad5a84c8SPhilip Reames; CHECK:       deopt:
357ad5a84c8SPhilip Reames; CHECK-NEXT:    [[DEOPTRET:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
358ad5a84c8SPhilip Reames; CHECK-NEXT:    ret i32 [[DEOPTRET]]
359ad5a84c8SPhilip Reames; CHECK:       loop.preheader:
360ad5a84c8SPhilip Reames; CHECK-NEXT:    br label [[LOOP:%.*]]
361ad5a84c8SPhilip Reames; CHECK:       loop:
362ad5a84c8SPhilip Reames; CHECK-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED2:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
363ad5a84c8SPhilip Reames; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED2]] ], [ 0, [[LOOP_PREHEADER]] ]
364ad5a84c8SPhilip Reames; CHECK-NEXT:    call void @unknown()
365ad5a84c8SPhilip Reames; CHECK-NEXT:    [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH]]
366ad5a84c8SPhilip Reames; CHECK-NEXT:    br i1 true, label [[GUARDED:%.*]], label [[DEOPT2:%.*]], !prof !0
367ad5a84c8SPhilip Reames; CHECK:       deopt2:
368ad5a84c8SPhilip Reames; CHECK-NEXT:    call void @unknown()
369ad5a84c8SPhilip Reames; CHECK-NEXT:    [[DEOPTRET2:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
370ad5a84c8SPhilip Reames; CHECK-NEXT:    ret i32 [[DEOPTRET2]]
371ad5a84c8SPhilip Reames; CHECK:       guarded:
372*b46c085dSRoman Lebedev; CHECK-NEXT:    [[VOL:%.*]] = load volatile i32, i32* @G, align 4
373ad5a84c8SPhilip Reames; CHECK-NEXT:    [[UNKNOWN:%.*]] = icmp eq i32 [[VOL]], 0
374ad5a84c8SPhilip Reames; CHECK-NEXT:    br i1 [[UNKNOWN]], label [[GUARDED2]], label [[DEOPT3:%.*]], !prof !0
375ad5a84c8SPhilip Reames; CHECK:       deopt3:
376ad5a84c8SPhilip Reames; CHECK-NEXT:    call void @unknown()
377ad5a84c8SPhilip Reames; CHECK-NEXT:    [[DEOPTRET3:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
378ad5a84c8SPhilip Reames; CHECK-NEXT:    ret i32 [[DEOPTRET3]]
379ad5a84c8SPhilip Reames; CHECK:       guarded2:
380ad5a84c8SPhilip Reames; CHECK-NEXT:    [[I_I64:%.*]] = zext i32 [[I]] to i64
381ad5a84c8SPhilip Reames; CHECK-NEXT:    [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
382ad5a84c8SPhilip Reames; CHECK-NEXT:    [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
383*b46c085dSRoman Lebedev; CHECK-NEXT:    store i32 0, i32* [[ARRAY_I_PTR]], align 4
384ad5a84c8SPhilip Reames; CHECK-NEXT:    [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
385ad5a84c8SPhilip Reames; CHECK-NEXT:    [[I_NEXT]] = add nuw i32 [[I]], 1
386ad5a84c8SPhilip Reames; CHECK-NEXT:    [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[N]]
387ad5a84c8SPhilip Reames; CHECK-NEXT:    br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT:%.*]]
388ad5a84c8SPhilip Reames; CHECK:       exit:
389ad5a84c8SPhilip Reames; CHECK-NEXT:    [[RESULT:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED2]] ]
390ad5a84c8SPhilip Reames; CHECK-NEXT:    ret i32 [[RESULT]]
391ad5a84c8SPhilip Reames;
392ad5a84c8SPhilip Reamesentry:
393ad5a84c8SPhilip Reames  %widenable_cond = call i1 @llvm.experimental.widenable.condition()
394ad5a84c8SPhilip Reames  %exiplicit_guard_cond = and i1 %cond_0, %widenable_cond
395ad5a84c8SPhilip Reames  br i1 %exiplicit_guard_cond, label %loop.preheader, label %deopt, !prof !0
396ad5a84c8SPhilip Reames
397ad5a84c8SPhilip Reamesdeopt:
398ad5a84c8SPhilip Reames  %deoptret = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
399ad5a84c8SPhilip Reames  ret i32 %deoptret
400ad5a84c8SPhilip Reames
401ad5a84c8SPhilip Reamesloop.preheader:
402ad5a84c8SPhilip Reames  br label %loop
403ad5a84c8SPhilip Reames
404ad5a84c8SPhilip Reamesloop:
405ad5a84c8SPhilip Reames  %loop.acc = phi i32 [ %loop.acc.next, %guarded2 ], [ 0, %loop.preheader ]
406ad5a84c8SPhilip Reames  %i = phi i32 [ %i.next, %guarded2 ], [ 0, %loop.preheader ]
407ad5a84c8SPhilip Reames  call void @unknown()
408ad5a84c8SPhilip Reames  %within.bounds = icmp ult i32 %i, %length
409ad5a84c8SPhilip Reames  br i1 %within.bounds, label %guarded, label %deopt2, !prof !0
410ad5a84c8SPhilip Reames
411ad5a84c8SPhilip Reamesdeopt2:
412ad5a84c8SPhilip Reames  call void @unknown()
413ad5a84c8SPhilip Reames  %deoptret2 = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
414ad5a84c8SPhilip Reames  ret i32 %deoptret2
415ad5a84c8SPhilip Reames
416ad5a84c8SPhilip Reamesguarded:
417ad5a84c8SPhilip Reames  %vol = load volatile i32, i32* @G
418ad5a84c8SPhilip Reames  %unknown = icmp eq i32 %vol, 0
419ad5a84c8SPhilip Reames  br i1 %unknown, label %guarded2, label %deopt3, !prof !0
420ad5a84c8SPhilip Reames
421ad5a84c8SPhilip Reamesdeopt3:
422ad5a84c8SPhilip Reames  call void @unknown()
423ad5a84c8SPhilip Reames  %deoptret3 = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
424ad5a84c8SPhilip Reames  ret i32 %deoptret3
425ad5a84c8SPhilip Reames
426ad5a84c8SPhilip Reamesguarded2:
427ad5a84c8SPhilip Reames  %i.i64 = zext i32 %i to i64
428ad5a84c8SPhilip Reames  %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
429ad5a84c8SPhilip Reames  %array.i = load i32, i32* %array.i.ptr, align 4
430ad5a84c8SPhilip Reames  store i32 0, i32* %array.i.ptr
431ad5a84c8SPhilip Reames  %loop.acc.next = add i32 %loop.acc, %array.i
432ad5a84c8SPhilip Reames  %i.next = add nuw i32 %i, 1
433ad5a84c8SPhilip Reames  %continue = icmp ult i32 %i.next, %n
434ad5a84c8SPhilip Reames  br i1 %continue, label %loop, label %exit
435ad5a84c8SPhilip Reames
436ad5a84c8SPhilip Reamesexit:
437ad5a84c8SPhilip Reames  %result = phi i32 [ %loop.acc.next, %guarded2 ]
438ad5a84c8SPhilip Reames  ret i32 %result
439ad5a84c8SPhilip Reames}
440ad5a84c8SPhilip Reames
441ad5a84c8SPhilip Reames
442ad5a84c8SPhilip Reamesdefine i32 @test_unanalyzeable_latch(i32* %array, i32 %length, i32 %n, i1 %cond_0) {
443ad5a84c8SPhilip Reames; CHECK-LABEL: @test_unanalyzeable_latch(
444ad5a84c8SPhilip Reames; CHECK-NEXT:  entry:
445ad5a84c8SPhilip Reames; CHECK-NEXT:    [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
446ad5a84c8SPhilip Reames; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[COND_0:%.*]], [[WIDENABLE_COND]]
447ad5a84c8SPhilip Reames; CHECK-NEXT:    br i1 [[EXIPLICIT_GUARD_COND]], label [[LOOP_PREHEADER:%.*]], label [[DEOPT:%.*]], !prof !0
448ad5a84c8SPhilip Reames; CHECK:       deopt:
449ad5a84c8SPhilip Reames; CHECK-NEXT:    [[DEOPTRET:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
450ad5a84c8SPhilip Reames; CHECK-NEXT:    ret i32 [[DEOPTRET]]
451ad5a84c8SPhilip Reames; CHECK:       loop.preheader:
452ad5a84c8SPhilip Reames; CHECK-NEXT:    br label [[LOOP:%.*]]
453ad5a84c8SPhilip Reames; CHECK:       loop:
454ad5a84c8SPhilip Reames; CHECK-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
455ad5a84c8SPhilip Reames; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ]
456ad5a84c8SPhilip Reames; CHECK-NEXT:    call void @unknown()
457ad5a84c8SPhilip Reames; CHECK-NEXT:    [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH:%.*]]
458ad5a84c8SPhilip Reames; CHECK-NEXT:    br i1 [[WITHIN_BOUNDS]], label [[GUARDED]], label [[DEOPT2:%.*]], !prof !0
459ad5a84c8SPhilip Reames; CHECK:       deopt2:
460ad5a84c8SPhilip Reames; CHECK-NEXT:    call void @unknown()
461ad5a84c8SPhilip Reames; CHECK-NEXT:    [[DEOPTRET2:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
462ad5a84c8SPhilip Reames; CHECK-NEXT:    ret i32 [[DEOPTRET2]]
463ad5a84c8SPhilip Reames; CHECK:       guarded:
464ad5a84c8SPhilip Reames; CHECK-NEXT:    [[I_I64:%.*]] = zext i32 [[I]] to i64
465ad5a84c8SPhilip Reames; CHECK-NEXT:    [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
466ad5a84c8SPhilip Reames; CHECK-NEXT:    [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
467*b46c085dSRoman Lebedev; CHECK-NEXT:    store i32 0, i32* [[ARRAY_I_PTR]], align 4
468ad5a84c8SPhilip Reames; CHECK-NEXT:    [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
469ad5a84c8SPhilip Reames; CHECK-NEXT:    [[I_NEXT]] = add nuw i32 [[I]], 1
470*b46c085dSRoman Lebedev; CHECK-NEXT:    [[VOL:%.*]] = load volatile i32, i32* @G, align 4
471ad5a84c8SPhilip Reames; CHECK-NEXT:    [[UNKNOWN:%.*]] = icmp eq i32 [[VOL]], 0
472ad5a84c8SPhilip Reames; CHECK-NEXT:    br i1 [[UNKNOWN]], label [[LOOP]], label [[EXIT:%.*]]
473ad5a84c8SPhilip Reames; CHECK:       exit:
474ad5a84c8SPhilip Reames; CHECK-NEXT:    [[RESULT:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ]
475ad5a84c8SPhilip Reames; CHECK-NEXT:    ret i32 [[RESULT]]
476ad5a84c8SPhilip Reames;
477ad5a84c8SPhilip Reamesentry:
478ad5a84c8SPhilip Reames  %widenable_cond = call i1 @llvm.experimental.widenable.condition()
479ad5a84c8SPhilip Reames  %exiplicit_guard_cond = and i1 %cond_0, %widenable_cond
480ad5a84c8SPhilip Reames  br i1 %exiplicit_guard_cond, label %loop.preheader, label %deopt, !prof !0
481ad5a84c8SPhilip Reames
482ad5a84c8SPhilip Reamesdeopt:
483ad5a84c8SPhilip Reames  %deoptret = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
484ad5a84c8SPhilip Reames  ret i32 %deoptret
485ad5a84c8SPhilip Reames
486ad5a84c8SPhilip Reamesloop.preheader:
487ad5a84c8SPhilip Reames  br label %loop
488ad5a84c8SPhilip Reames
489ad5a84c8SPhilip Reamesloop:
490ad5a84c8SPhilip Reames  %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ]
491ad5a84c8SPhilip Reames  %i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ]
492ad5a84c8SPhilip Reames  call void @unknown()
493ad5a84c8SPhilip Reames  %within.bounds = icmp ult i32 %i, %length
494ad5a84c8SPhilip Reames  br i1 %within.bounds, label %guarded, label %deopt2, !prof !0
495ad5a84c8SPhilip Reames
496ad5a84c8SPhilip Reamesdeopt2:
497ad5a84c8SPhilip Reames  call void @unknown()
498ad5a84c8SPhilip Reames  %deoptret2 = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
499ad5a84c8SPhilip Reames  ret i32 %deoptret2
500ad5a84c8SPhilip Reames
501ad5a84c8SPhilip Reamesguarded:
502ad5a84c8SPhilip Reames  %i.i64 = zext i32 %i to i64
503ad5a84c8SPhilip Reames  %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
504ad5a84c8SPhilip Reames  %array.i = load i32, i32* %array.i.ptr, align 4
505ad5a84c8SPhilip Reames  store i32 0, i32* %array.i.ptr
506ad5a84c8SPhilip Reames  %loop.acc.next = add i32 %loop.acc, %array.i
507ad5a84c8SPhilip Reames  %i.next = add nuw i32 %i, 1
508ad5a84c8SPhilip Reames  %vol = load volatile i32, i32* @G
509ad5a84c8SPhilip Reames  %unknown = icmp eq i32 %vol, 0
510ad5a84c8SPhilip Reames  br i1 %unknown, label %loop, label %exit
511ad5a84c8SPhilip Reames
512ad5a84c8SPhilip Reamesexit:
513ad5a84c8SPhilip Reames  %result = phi i32 [ %loop.acc.next, %guarded ]
514ad5a84c8SPhilip Reames  ret i32 %result
515ad5a84c8SPhilip Reames}
516ad5a84c8SPhilip Reames
517ad5a84c8SPhilip Reames
518ad5a84c8SPhilip Reamesdefine i32 @provably_taken(i32* %array, i1 %cond_0) {
519ad5a84c8SPhilip Reames; CHECK-LABEL: @provably_taken(
520ad5a84c8SPhilip Reames; CHECK-NEXT:  entry:
521ad5a84c8SPhilip Reames; CHECK-NEXT:    [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
522ad5a84c8SPhilip Reames; CHECK-NEXT:    [[TMP0:%.*]] = freeze i1 false
523ad5a84c8SPhilip Reames; CHECK-NEXT:    [[TMP1:%.*]] = and i1 [[TMP0]], [[COND_0:%.*]]
524ad5a84c8SPhilip Reames; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[TMP1]], [[WIDENABLE_COND]]
525ad5a84c8SPhilip Reames; CHECK-NEXT:    br i1 [[EXIPLICIT_GUARD_COND]], label [[LOOP_PREHEADER:%.*]], label [[DEOPT:%.*]], !prof !0
526ad5a84c8SPhilip Reames; CHECK:       deopt:
527ad5a84c8SPhilip Reames; CHECK-NEXT:    [[DEOPTRET:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
528ad5a84c8SPhilip Reames; CHECK-NEXT:    ret i32 [[DEOPTRET]]
529ad5a84c8SPhilip Reames; CHECK:       loop.preheader:
530ad5a84c8SPhilip Reames; CHECK-NEXT:    br label [[LOOP:%.*]]
531ad5a84c8SPhilip Reames; CHECK:       loop:
532ad5a84c8SPhilip Reames; CHECK-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
533ad5a84c8SPhilip Reames; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ]
534ad5a84c8SPhilip Reames; CHECK-NEXT:    call void @unknown()
535ad5a84c8SPhilip Reames; CHECK-NEXT:    [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], 198
536ad5a84c8SPhilip Reames; CHECK-NEXT:    br i1 true, label [[GUARDED]], label [[DEOPT2:%.*]], !prof !0
537ad5a84c8SPhilip Reames; CHECK:       deopt2:
538ad5a84c8SPhilip Reames; CHECK-NEXT:    call void @unknown()
539ad5a84c8SPhilip Reames; CHECK-NEXT:    [[DEOPTRET2:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
540ad5a84c8SPhilip Reames; CHECK-NEXT:    ret i32 [[DEOPTRET2]]
541ad5a84c8SPhilip Reames; CHECK:       guarded:
542ad5a84c8SPhilip Reames; CHECK-NEXT:    [[I_I64:%.*]] = zext i32 [[I]] to i64
543ad5a84c8SPhilip Reames; CHECK-NEXT:    [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
544ad5a84c8SPhilip Reames; CHECK-NEXT:    [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
545*b46c085dSRoman Lebedev; CHECK-NEXT:    store i32 0, i32* [[ARRAY_I_PTR]], align 4
546ad5a84c8SPhilip Reames; CHECK-NEXT:    [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
547ad5a84c8SPhilip Reames; CHECK-NEXT:    [[I_NEXT]] = add nuw i32 [[I]], 1
548ad5a84c8SPhilip Reames; CHECK-NEXT:    [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], 200
549ad5a84c8SPhilip Reames; CHECK-NEXT:    br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT:%.*]]
550ad5a84c8SPhilip Reames; CHECK:       exit:
551ad5a84c8SPhilip Reames; CHECK-NEXT:    [[RESULT:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ]
552ad5a84c8SPhilip Reames; CHECK-NEXT:    ret i32 [[RESULT]]
553ad5a84c8SPhilip Reames;
554ad5a84c8SPhilip Reamesentry:
555ad5a84c8SPhilip Reames  %widenable_cond = call i1 @llvm.experimental.widenable.condition()
556ad5a84c8SPhilip Reames  %exiplicit_guard_cond = and i1 %cond_0, %widenable_cond
557ad5a84c8SPhilip Reames  br i1 %exiplicit_guard_cond, label %loop.preheader, label %deopt, !prof !0
558ad5a84c8SPhilip Reames
559ad5a84c8SPhilip Reamesdeopt:
560ad5a84c8SPhilip Reames  %deoptret = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
561ad5a84c8SPhilip Reames  ret i32 %deoptret
562ad5a84c8SPhilip Reames
563ad5a84c8SPhilip Reamesloop.preheader:
564ad5a84c8SPhilip Reames  br label %loop
565ad5a84c8SPhilip Reames
566ad5a84c8SPhilip Reamesloop:
567ad5a84c8SPhilip Reames  %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ]
568ad5a84c8SPhilip Reames  %i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ]
569ad5a84c8SPhilip Reames  call void @unknown()
570ad5a84c8SPhilip Reames  %within.bounds = icmp ult i32 %i, 198
571ad5a84c8SPhilip Reames  br i1 %within.bounds, label %guarded, label %deopt2, !prof !0
572ad5a84c8SPhilip Reames
573ad5a84c8SPhilip Reamesdeopt2:
574ad5a84c8SPhilip Reames  call void @unknown()
575ad5a84c8SPhilip Reames  %deoptret2 = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
576ad5a84c8SPhilip Reames  ret i32 %deoptret2
577ad5a84c8SPhilip Reames
578ad5a84c8SPhilip Reamesguarded:
579ad5a84c8SPhilip Reames  %i.i64 = zext i32 %i to i64
580ad5a84c8SPhilip Reames  %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
581ad5a84c8SPhilip Reames  %array.i = load i32, i32* %array.i.ptr, align 4
582ad5a84c8SPhilip Reames  store i32 0, i32* %array.i.ptr
583ad5a84c8SPhilip Reames  %loop.acc.next = add i32 %loop.acc, %array.i
584ad5a84c8SPhilip Reames  %i.next = add nuw i32 %i, 1
585ad5a84c8SPhilip Reames  %continue = icmp ult i32 %i.next, 200
586ad5a84c8SPhilip Reames  br i1 %continue, label %loop, label %exit
587ad5a84c8SPhilip Reames
588ad5a84c8SPhilip Reamesexit:
589ad5a84c8SPhilip Reames  %result = phi i32 [ %loop.acc.next, %guarded ]
590ad5a84c8SPhilip Reames  ret i32 %result
591ad5a84c8SPhilip Reames}
592ad5a84c8SPhilip Reames
593ad5a84c8SPhilip Reamesdefine i32 @provably_not_taken(i32* %array, i1 %cond_0) {
594ad5a84c8SPhilip Reames; CHECK-LABEL: @provably_not_taken(
595ad5a84c8SPhilip Reames; CHECK-NEXT:  entry:
596ad5a84c8SPhilip Reames; CHECK-NEXT:    [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
597ad5a84c8SPhilip Reames; CHECK-NEXT:    [[TMP0:%.*]] = freeze i1 true
598ad5a84c8SPhilip Reames; CHECK-NEXT:    [[TMP1:%.*]] = and i1 [[TMP0]], [[COND_0:%.*]]
599ad5a84c8SPhilip Reames; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[TMP1]], [[WIDENABLE_COND]]
600ad5a84c8SPhilip Reames; CHECK-NEXT:    br i1 [[EXIPLICIT_GUARD_COND]], label [[LOOP_PREHEADER:%.*]], label [[DEOPT:%.*]], !prof !0
601ad5a84c8SPhilip Reames; CHECK:       deopt:
602ad5a84c8SPhilip Reames; CHECK-NEXT:    [[DEOPTRET:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
603ad5a84c8SPhilip Reames; CHECK-NEXT:    ret i32 [[DEOPTRET]]
604ad5a84c8SPhilip Reames; CHECK:       loop.preheader:
605ad5a84c8SPhilip Reames; CHECK-NEXT:    br label [[LOOP:%.*]]
606ad5a84c8SPhilip Reames; CHECK:       loop:
607ad5a84c8SPhilip Reames; CHECK-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
608ad5a84c8SPhilip Reames; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ]
609ad5a84c8SPhilip Reames; CHECK-NEXT:    call void @unknown()
610ad5a84c8SPhilip Reames; CHECK-NEXT:    [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], 205
611ad5a84c8SPhilip Reames; CHECK-NEXT:    br i1 true, label [[GUARDED]], label [[DEOPT2:%.*]], !prof !0
612ad5a84c8SPhilip Reames; CHECK:       deopt2:
613ad5a84c8SPhilip Reames; CHECK-NEXT:    call void @unknown()
614ad5a84c8SPhilip Reames; CHECK-NEXT:    [[DEOPTRET2:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
615ad5a84c8SPhilip Reames; CHECK-NEXT:    ret i32 [[DEOPTRET2]]
616ad5a84c8SPhilip Reames; CHECK:       guarded:
617ad5a84c8SPhilip Reames; CHECK-NEXT:    [[I_I64:%.*]] = zext i32 [[I]] to i64
618ad5a84c8SPhilip Reames; CHECK-NEXT:    [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
619ad5a84c8SPhilip Reames; CHECK-NEXT:    [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
620*b46c085dSRoman Lebedev; CHECK-NEXT:    store i32 0, i32* [[ARRAY_I_PTR]], align 4
621ad5a84c8SPhilip Reames; CHECK-NEXT:    [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
622ad5a84c8SPhilip Reames; CHECK-NEXT:    [[I_NEXT]] = add nuw i32 [[I]], 1
623ad5a84c8SPhilip Reames; CHECK-NEXT:    [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], 200
624ad5a84c8SPhilip Reames; CHECK-NEXT:    br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT:%.*]]
625ad5a84c8SPhilip Reames; CHECK:       exit:
626ad5a84c8SPhilip Reames; CHECK-NEXT:    [[RESULT:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ]
627ad5a84c8SPhilip Reames; CHECK-NEXT:    ret i32 [[RESULT]]
628ad5a84c8SPhilip Reames;
629ad5a84c8SPhilip Reamesentry:
630ad5a84c8SPhilip Reames  %widenable_cond = call i1 @llvm.experimental.widenable.condition()
631ad5a84c8SPhilip Reames  %exiplicit_guard_cond = and i1 %cond_0, %widenable_cond
632ad5a84c8SPhilip Reames  br i1 %exiplicit_guard_cond, label %loop.preheader, label %deopt, !prof !0
633ad5a84c8SPhilip Reames
634ad5a84c8SPhilip Reamesdeopt:
635ad5a84c8SPhilip Reames  %deoptret = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
636ad5a84c8SPhilip Reames  ret i32 %deoptret
637ad5a84c8SPhilip Reames
638ad5a84c8SPhilip Reamesloop.preheader:
639ad5a84c8SPhilip Reames  br label %loop
640ad5a84c8SPhilip Reames
641ad5a84c8SPhilip Reamesloop:
642ad5a84c8SPhilip Reames  %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ]
643ad5a84c8SPhilip Reames  %i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ]
644ad5a84c8SPhilip Reames  call void @unknown()
645ad5a84c8SPhilip Reames  %within.bounds = icmp ult i32 %i, 205
646ad5a84c8SPhilip Reames  br i1 %within.bounds, label %guarded, label %deopt2, !prof !0
647ad5a84c8SPhilip Reames
648ad5a84c8SPhilip Reamesdeopt2:
649ad5a84c8SPhilip Reames  call void @unknown()
650ad5a84c8SPhilip Reames  %deoptret2 = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
651ad5a84c8SPhilip Reames  ret i32 %deoptret2
652ad5a84c8SPhilip Reames
653ad5a84c8SPhilip Reamesguarded:
654ad5a84c8SPhilip Reames  %i.i64 = zext i32 %i to i64
655ad5a84c8SPhilip Reames  %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
656ad5a84c8SPhilip Reames  %array.i = load i32, i32* %array.i.ptr, align 4
657ad5a84c8SPhilip Reames  store i32 0, i32* %array.i.ptr
658ad5a84c8SPhilip Reames  %loop.acc.next = add i32 %loop.acc, %array.i
659ad5a84c8SPhilip Reames  %i.next = add nuw i32 %i, 1
660ad5a84c8SPhilip Reames  %continue = icmp ult i32 %i.next, 200
661ad5a84c8SPhilip Reames  br i1 %continue, label %loop, label %exit
662ad5a84c8SPhilip Reames
663ad5a84c8SPhilip Reamesexit:
664ad5a84c8SPhilip Reames  %result = phi i32 [ %loop.acc.next, %guarded ]
665ad5a84c8SPhilip Reames  ret i32 %result
666ad5a84c8SPhilip Reames}
667ad5a84c8SPhilip Reames
668ad5a84c8SPhilip Reames
669f3eb5deeSPhilip Reames;; Unswitch likes to produce some ugly exit blocks without simplifications
670f3eb5deeSPhilip Reames;; being applied.  Make sure we can handle that form.
671f3eb5deeSPhilip Reamesdefine i32 @unswitch_exit_form(i32* %array, i32 %length, i32 %n, i1 %cond_0) {
672f3eb5deeSPhilip Reames; CHECK-LABEL: @unswitch_exit_form(
673f3eb5deeSPhilip Reames; CHECK-NEXT:  entry:
674f3eb5deeSPhilip Reames; CHECK-NEXT:    [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
675*b46c085dSRoman Lebedev; CHECK-NEXT:    [[UMAX:%.*]] = call i32 @llvm.umax.i32(i32 [[N:%.*]], i32 1)
676*b46c085dSRoman Lebedev; CHECK-NEXT:    [[TMP0:%.*]] = add i32 [[UMAX]], -1
677*b46c085dSRoman Lebedev; CHECK-NEXT:    [[UMIN:%.*]] = call i32 @llvm.umin.i32(i32 [[LENGTH:%.*]], i32 [[TMP0]])
678*b46c085dSRoman Lebedev; CHECK-NEXT:    [[TMP1:%.*]] = icmp ugt i32 [[LENGTH]], [[UMIN]]
679*b46c085dSRoman Lebedev; CHECK-NEXT:    [[TMP2:%.*]] = freeze i1 [[TMP1]]
680*b46c085dSRoman Lebedev; CHECK-NEXT:    [[TMP3:%.*]] = and i1 [[TMP2]], [[COND_0:%.*]]
681*b46c085dSRoman Lebedev; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[TMP3]], [[WIDENABLE_COND]]
682f3eb5deeSPhilip Reames; CHECK-NEXT:    br i1 [[EXIPLICIT_GUARD_COND]], label [[LOOP_PREHEADER:%.*]], label [[DEOPT:%.*]], !prof !0
683f3eb5deeSPhilip Reames; CHECK:       deopt.loopexit:
684f3eb5deeSPhilip Reames; CHECK-NEXT:    br label [[DEOPT]]
685f3eb5deeSPhilip Reames; CHECK:       deopt:
686f3eb5deeSPhilip Reames; CHECK-NEXT:    [[PHI:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ 1, [[DEOPT_LOOPEXIT:%.*]] ]
687f3eb5deeSPhilip Reames; CHECK-NEXT:    call void @unknown()
688f3eb5deeSPhilip Reames; CHECK-NEXT:    br label [[ACTUAL_DEOPT:%.*]]
689f3eb5deeSPhilip Reames; CHECK:       actual_deopt:
690f3eb5deeSPhilip Reames; CHECK-NEXT:    [[DEOPTRET:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"(i32 [[PHI]]) ]
691f3eb5deeSPhilip Reames; CHECK-NEXT:    ret i32 [[DEOPTRET]]
692f3eb5deeSPhilip Reames; CHECK:       loop.preheader:
693f3eb5deeSPhilip Reames; CHECK-NEXT:    br label [[LOOP:%.*]]
694f3eb5deeSPhilip Reames; CHECK:       loop:
695f3eb5deeSPhilip Reames; CHECK-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
696f3eb5deeSPhilip Reames; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ]
697f3eb5deeSPhilip Reames; CHECK-NEXT:    call void @unknown()
698f3eb5deeSPhilip Reames; CHECK-NEXT:    [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH]]
699f3eb5deeSPhilip Reames; CHECK-NEXT:    br i1 true, label [[GUARDED]], label [[DEOPT_LOOPEXIT]], !prof !0
700f3eb5deeSPhilip Reames; CHECK:       guarded:
701f3eb5deeSPhilip Reames; CHECK-NEXT:    [[I_I64:%.*]] = zext i32 [[I]] to i64
702f3eb5deeSPhilip Reames; CHECK-NEXT:    [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
703f3eb5deeSPhilip Reames; CHECK-NEXT:    [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
704*b46c085dSRoman Lebedev; CHECK-NEXT:    store i32 0, i32* [[ARRAY_I_PTR]], align 4
705f3eb5deeSPhilip Reames; CHECK-NEXT:    [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
706f3eb5deeSPhilip Reames; CHECK-NEXT:    [[I_NEXT]] = add nuw i32 [[I]], 1
707f3eb5deeSPhilip Reames; CHECK-NEXT:    [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[N]]
708f3eb5deeSPhilip Reames; CHECK-NEXT:    br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT:%.*]]
709f3eb5deeSPhilip Reames; CHECK:       exit:
710f3eb5deeSPhilip Reames; CHECK-NEXT:    [[RESULT:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ]
711f3eb5deeSPhilip Reames; CHECK-NEXT:    ret i32 [[RESULT]]
712f3eb5deeSPhilip Reames;
713f3eb5deeSPhilip Reamesentry:
714f3eb5deeSPhilip Reames  %widenable_cond = call i1 @llvm.experimental.widenable.condition()
715f3eb5deeSPhilip Reames  %exiplicit_guard_cond = and i1 %cond_0, %widenable_cond
716f3eb5deeSPhilip Reames  br i1 %exiplicit_guard_cond, label %loop.preheader, label %deopt, !prof !0
717ad5a84c8SPhilip Reames
718f3eb5deeSPhilip Reamesdeopt:
719f3eb5deeSPhilip Reames  ;; This is written to look like an unsimplified loop exit after unswitch
720f3eb5deeSPhilip Reames  ;; (i.e. phis, merge, and branch to actual block)
721f3eb5deeSPhilip Reames  %phi = phi i32 [0, %entry], [1, %loop]
722f3eb5deeSPhilip Reames  call void @unknown() ;; it's okay to skip possible throws
723f3eb5deeSPhilip Reames  br label %actual_deopt
724ad5a84c8SPhilip Reames
725f3eb5deeSPhilip Reamesactual_deopt:
726f3eb5deeSPhilip Reames  %deoptret = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"(i32 %phi) ]
727f3eb5deeSPhilip Reames  ret i32 %deoptret
728ad5a84c8SPhilip Reames
729f3eb5deeSPhilip Reamesloop.preheader:
730f3eb5deeSPhilip Reames  br label %loop
731ad5a84c8SPhilip Reames
732f3eb5deeSPhilip Reamesloop:
733f3eb5deeSPhilip Reames  %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ]
734f3eb5deeSPhilip Reames  %i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ]
735f3eb5deeSPhilip Reames  call void @unknown()
736f3eb5deeSPhilip Reames  %within.bounds = icmp ult i32 %i, %length
737f3eb5deeSPhilip Reames  br i1 %within.bounds, label %guarded, label %deopt, !prof !0
738ad5a84c8SPhilip Reames
739f3eb5deeSPhilip Reamesguarded:
740f3eb5deeSPhilip Reames  %i.i64 = zext i32 %i to i64
741f3eb5deeSPhilip Reames  %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
742f3eb5deeSPhilip Reames  %array.i = load i32, i32* %array.i.ptr, align 4
743f3eb5deeSPhilip Reames  store i32 0, i32* %array.i.ptr
744f3eb5deeSPhilip Reames  %loop.acc.next = add i32 %loop.acc, %array.i
745f3eb5deeSPhilip Reames  %i.next = add nuw i32 %i, 1
746f3eb5deeSPhilip Reames  %continue = icmp ult i32 %i.next, %n
747f3eb5deeSPhilip Reames  br i1 %continue, label %loop, label %exit
748f3eb5deeSPhilip Reames
749f3eb5deeSPhilip Reamesexit:
750f3eb5deeSPhilip Reames  %result = phi i32 [ %loop.acc.next, %guarded ]
751f3eb5deeSPhilip Reames  ret i32 %result
752f3eb5deeSPhilip Reames}
753ad5a84c8SPhilip Reames
754aaea2480SPhilip Reamesdefine i32 @swapped_wb(i32* %array, i32 %length, i32 %n, i1 %cond_0) {
755aaea2480SPhilip Reames; CHECK-LABEL: @swapped_wb(
756aaea2480SPhilip Reames; CHECK-NEXT:  entry:
757aaea2480SPhilip Reames; CHECK-NEXT:    [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
758*b46c085dSRoman Lebedev; CHECK-NEXT:    [[UMAX:%.*]] = call i32 @llvm.umax.i32(i32 [[N:%.*]], i32 1)
759*b46c085dSRoman Lebedev; CHECK-NEXT:    [[TMP0:%.*]] = add i32 [[UMAX]], -1
760*b46c085dSRoman Lebedev; CHECK-NEXT:    [[UMIN:%.*]] = call i32 @llvm.umin.i32(i32 [[LENGTH:%.*]], i32 [[TMP0]])
761*b46c085dSRoman Lebedev; CHECK-NEXT:    [[TMP1:%.*]] = icmp ugt i32 [[LENGTH]], [[UMIN]]
762*b46c085dSRoman Lebedev; CHECK-NEXT:    [[TMP2:%.*]] = freeze i1 [[TMP1]]
763*b46c085dSRoman Lebedev; CHECK-NEXT:    [[TMP3:%.*]] = and i1 [[TMP2]], [[COND_0:%.*]]
764*b46c085dSRoman Lebedev; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[WIDENABLE_COND]], [[TMP3]]
765aaea2480SPhilip Reames; CHECK-NEXT:    br i1 [[EXIPLICIT_GUARD_COND]], label [[LOOP_PREHEADER:%.*]], label [[DEOPT:%.*]], !prof !0
766aaea2480SPhilip Reames; CHECK:       deopt:
767aaea2480SPhilip Reames; CHECK-NEXT:    [[DEOPTRET:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
768aaea2480SPhilip Reames; CHECK-NEXT:    ret i32 [[DEOPTRET]]
769aaea2480SPhilip Reames; CHECK:       loop.preheader:
770aaea2480SPhilip Reames; CHECK-NEXT:    br label [[LOOP:%.*]]
771aaea2480SPhilip Reames; CHECK:       loop:
772aaea2480SPhilip Reames; CHECK-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
773aaea2480SPhilip Reames; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ]
774aaea2480SPhilip Reames; CHECK-NEXT:    call void @unknown()
775aaea2480SPhilip Reames; CHECK-NEXT:    [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH]]
776aaea2480SPhilip Reames; CHECK-NEXT:    br i1 true, label [[GUARDED]], label [[DEOPT2:%.*]], !prof !0
777aaea2480SPhilip Reames; CHECK:       deopt2:
778aaea2480SPhilip Reames; CHECK-NEXT:    call void @unknown()
779aaea2480SPhilip Reames; CHECK-NEXT:    [[DEOPTRET2:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
780aaea2480SPhilip Reames; CHECK-NEXT:    ret i32 [[DEOPTRET2]]
781aaea2480SPhilip Reames; CHECK:       guarded:
782aaea2480SPhilip Reames; CHECK-NEXT:    [[I_I64:%.*]] = zext i32 [[I]] to i64
783aaea2480SPhilip Reames; CHECK-NEXT:    [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
784aaea2480SPhilip Reames; CHECK-NEXT:    [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
785*b46c085dSRoman Lebedev; CHECK-NEXT:    store i32 0, i32* [[ARRAY_I_PTR]], align 4
786aaea2480SPhilip Reames; CHECK-NEXT:    [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
787aaea2480SPhilip Reames; CHECK-NEXT:    [[I_NEXT]] = add nuw i32 [[I]], 1
788aaea2480SPhilip Reames; CHECK-NEXT:    [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[N]]
789aaea2480SPhilip Reames; CHECK-NEXT:    br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT:%.*]]
790aaea2480SPhilip Reames; CHECK:       exit:
791aaea2480SPhilip Reames; CHECK-NEXT:    [[RESULT:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ]
792aaea2480SPhilip Reames; CHECK-NEXT:    ret i32 [[RESULT]]
793aaea2480SPhilip Reames;
794aaea2480SPhilip Reamesentry:
795aaea2480SPhilip Reames  %widenable_cond = call i1 @llvm.experimental.widenable.condition()
796aaea2480SPhilip Reames  %exiplicit_guard_cond = and i1 %widenable_cond, %cond_0
797aaea2480SPhilip Reames  br i1 %exiplicit_guard_cond, label %loop.preheader, label %deopt, !prof !0
798aaea2480SPhilip Reames
799aaea2480SPhilip Reamesdeopt:
800aaea2480SPhilip Reames  %deoptret = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
801aaea2480SPhilip Reames  ret i32 %deoptret
802aaea2480SPhilip Reames
803aaea2480SPhilip Reamesloop.preheader:
804aaea2480SPhilip Reames  br label %loop
805aaea2480SPhilip Reames
806aaea2480SPhilip Reamesloop:
807aaea2480SPhilip Reames  %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ]
808aaea2480SPhilip Reames  %i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ]
809aaea2480SPhilip Reames  call void @unknown()
810aaea2480SPhilip Reames  %within.bounds = icmp ult i32 %i, %length
811aaea2480SPhilip Reames  br i1 %within.bounds, label %guarded, label %deopt2, !prof !0
812aaea2480SPhilip Reames
813aaea2480SPhilip Reamesdeopt2:
814aaea2480SPhilip Reames  call void @unknown()
815aaea2480SPhilip Reames  %deoptret2 = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
816aaea2480SPhilip Reames  ret i32 %deoptret2
817aaea2480SPhilip Reames
818aaea2480SPhilip Reamesguarded:
819aaea2480SPhilip Reames  %i.i64 = zext i32 %i to i64
820aaea2480SPhilip Reames  %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
821aaea2480SPhilip Reames  %array.i = load i32, i32* %array.i.ptr, align 4
822aaea2480SPhilip Reames  store i32 0, i32* %array.i.ptr
823aaea2480SPhilip Reames  %loop.acc.next = add i32 %loop.acc, %array.i
824aaea2480SPhilip Reames  %i.next = add nuw i32 %i, 1
825aaea2480SPhilip Reames  %continue = icmp ult i32 %i.next, %n
826aaea2480SPhilip Reames  br i1 %continue, label %loop, label %exit
827aaea2480SPhilip Reames
828aaea2480SPhilip Reamesexit:
829aaea2480SPhilip Reames  %result = phi i32 [ %loop.acc.next, %guarded ]
830aaea2480SPhilip Reames  ret i32 %result
831aaea2480SPhilip Reames}
832aaea2480SPhilip Reames
833aaea2480SPhilip Reamesdefine i32 @trivial_wb(i32* %array, i32 %length, i32 %n) {
834aaea2480SPhilip Reames; CHECK-LABEL: @trivial_wb(
835aaea2480SPhilip Reames; CHECK-NEXT:  entry:
836*b46c085dSRoman Lebedev; CHECK-NEXT:    [[UMAX:%.*]] = call i32 @llvm.umax.i32(i32 [[N:%.*]], i32 1)
837*b46c085dSRoman Lebedev; CHECK-NEXT:    [[TMP0:%.*]] = add i32 [[UMAX]], -1
838*b46c085dSRoman Lebedev; CHECK-NEXT:    [[UMIN:%.*]] = call i32 @llvm.umin.i32(i32 [[LENGTH:%.*]], i32 [[TMP0]])
839*b46c085dSRoman Lebedev; CHECK-NEXT:    [[TMP1:%.*]] = icmp ugt i32 [[LENGTH]], [[UMIN]]
840*b46c085dSRoman Lebedev; CHECK-NEXT:    [[TMP2:%.*]] = freeze i1 [[TMP1]]
841aaea2480SPhilip Reames; CHECK-NEXT:    [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
842*b46c085dSRoman Lebedev; CHECK-NEXT:    [[TMP3:%.*]] = and i1 [[TMP2]], [[WIDENABLE_COND]]
843*b46c085dSRoman Lebedev; CHECK-NEXT:    br i1 [[TMP3]], label [[LOOP_PREHEADER:%.*]], label [[DEOPT:%.*]], !prof !0
844aaea2480SPhilip Reames; CHECK:       deopt:
845aaea2480SPhilip Reames; CHECK-NEXT:    [[DEOPTRET:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
846aaea2480SPhilip Reames; CHECK-NEXT:    ret i32 [[DEOPTRET]]
847aaea2480SPhilip Reames; CHECK:       loop.preheader:
848aaea2480SPhilip Reames; CHECK-NEXT:    br label [[LOOP:%.*]]
849aaea2480SPhilip Reames; CHECK:       loop:
850aaea2480SPhilip Reames; CHECK-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
851aaea2480SPhilip Reames; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ]
852aaea2480SPhilip Reames; CHECK-NEXT:    call void @unknown()
853aaea2480SPhilip Reames; CHECK-NEXT:    [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH]]
854aaea2480SPhilip Reames; CHECK-NEXT:    br i1 true, label [[GUARDED]], label [[DEOPT2:%.*]], !prof !0
855aaea2480SPhilip Reames; CHECK:       deopt2:
856aaea2480SPhilip Reames; CHECK-NEXT:    call void @unknown()
857aaea2480SPhilip Reames; CHECK-NEXT:    [[DEOPTRET2:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
858aaea2480SPhilip Reames; CHECK-NEXT:    ret i32 [[DEOPTRET2]]
859aaea2480SPhilip Reames; CHECK:       guarded:
860aaea2480SPhilip Reames; CHECK-NEXT:    [[I_I64:%.*]] = zext i32 [[I]] to i64
861aaea2480SPhilip Reames; CHECK-NEXT:    [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
862aaea2480SPhilip Reames; CHECK-NEXT:    [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
863*b46c085dSRoman Lebedev; CHECK-NEXT:    store i32 0, i32* [[ARRAY_I_PTR]], align 4
864aaea2480SPhilip Reames; CHECK-NEXT:    [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
865aaea2480SPhilip Reames; CHECK-NEXT:    [[I_NEXT]] = add nuw i32 [[I]], 1
866aaea2480SPhilip Reames; CHECK-NEXT:    [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[N]]
867aaea2480SPhilip Reames; CHECK-NEXT:    br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT:%.*]]
868aaea2480SPhilip Reames; CHECK:       exit:
869aaea2480SPhilip Reames; CHECK-NEXT:    [[RESULT:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ]
870aaea2480SPhilip Reames; CHECK-NEXT:    ret i32 [[RESULT]]
871aaea2480SPhilip Reames;
872aaea2480SPhilip Reamesentry:
873aaea2480SPhilip Reames  %widenable_cond = call i1 @llvm.experimental.widenable.condition()
874aaea2480SPhilip Reames  br i1 %widenable_cond, label %loop.preheader, label %deopt, !prof !0
875aaea2480SPhilip Reames
876aaea2480SPhilip Reamesdeopt:
877aaea2480SPhilip Reames  %deoptret = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
878aaea2480SPhilip Reames  ret i32 %deoptret
879aaea2480SPhilip Reames
880aaea2480SPhilip Reamesloop.preheader:
881aaea2480SPhilip Reames  br label %loop
882aaea2480SPhilip Reames
883aaea2480SPhilip Reamesloop:
884aaea2480SPhilip Reames  %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ]
885aaea2480SPhilip Reames  %i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ]
886aaea2480SPhilip Reames  call void @unknown()
887aaea2480SPhilip Reames  %within.bounds = icmp ult i32 %i, %length
888aaea2480SPhilip Reames  br i1 %within.bounds, label %guarded, label %deopt2, !prof !0
889aaea2480SPhilip Reames
890aaea2480SPhilip Reamesdeopt2:
891aaea2480SPhilip Reames  call void @unknown()
892aaea2480SPhilip Reames  %deoptret2 = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
893aaea2480SPhilip Reames  ret i32 %deoptret2
894aaea2480SPhilip Reames
895aaea2480SPhilip Reamesguarded:
896aaea2480SPhilip Reames  %i.i64 = zext i32 %i to i64
897aaea2480SPhilip Reames  %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
898aaea2480SPhilip Reames  %array.i = load i32, i32* %array.i.ptr, align 4
899aaea2480SPhilip Reames  store i32 0, i32* %array.i.ptr
900aaea2480SPhilip Reames  %loop.acc.next = add i32 %loop.acc, %array.i
901aaea2480SPhilip Reames  %i.next = add nuw i32 %i, 1
902aaea2480SPhilip Reames  %continue = icmp ult i32 %i.next, %n
903aaea2480SPhilip Reames  br i1 %continue, label %loop, label %exit
904aaea2480SPhilip Reames
905aaea2480SPhilip Reamesexit:
906aaea2480SPhilip Reames  %result = phi i32 [ %loop.acc.next, %guarded ]
907aaea2480SPhilip Reames  ret i32 %result
908aaea2480SPhilip Reames}
909aaea2480SPhilip Reames
910ad5a84c8SPhilip Reames; TODO: Non-latch exits can still be predicated
911ad5a84c8SPhilip Reames; This is currently prevented by an overly restrictive profitability check.
912ad5a84c8SPhilip Reamesdefine i32 @todo_unconditional_latch(i32* %array, i32 %length, i1 %cond_0) {
913ad5a84c8SPhilip Reames; CHECK-LABEL: @todo_unconditional_latch(
914ad5a84c8SPhilip Reames; CHECK-NEXT:  entry:
915ad5a84c8SPhilip Reames; CHECK-NEXT:    [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
916ad5a84c8SPhilip Reames; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[COND_0:%.*]], [[WIDENABLE_COND]]
917ad5a84c8SPhilip Reames; CHECK-NEXT:    br i1 [[EXIPLICIT_GUARD_COND]], label [[LOOP_PREHEADER:%.*]], label [[DEOPT:%.*]], !prof !0
918ad5a84c8SPhilip Reames; CHECK:       deopt:
919ad5a84c8SPhilip Reames; CHECK-NEXT:    [[DEOPTRET:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
920ad5a84c8SPhilip Reames; CHECK-NEXT:    ret i32 [[DEOPTRET]]
921ad5a84c8SPhilip Reames; CHECK:       loop.preheader:
922ad5a84c8SPhilip Reames; CHECK-NEXT:    br label [[LOOP:%.*]]
923ad5a84c8SPhilip Reames; CHECK:       loop:
924ad5a84c8SPhilip Reames; CHECK-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
925ad5a84c8SPhilip Reames; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ]
926ad5a84c8SPhilip Reames; CHECK-NEXT:    call void @unknown()
927ad5a84c8SPhilip Reames; CHECK-NEXT:    [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH:%.*]]
928ad5a84c8SPhilip Reames; CHECK-NEXT:    br i1 [[WITHIN_BOUNDS]], label [[GUARDED]], label [[DEOPT2:%.*]], !prof !0
929ad5a84c8SPhilip Reames; CHECK:       deopt2:
930ad5a84c8SPhilip Reames; CHECK-NEXT:    call void @unknown()
931ad5a84c8SPhilip Reames; CHECK-NEXT:    [[DEOPTRET2:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
932ad5a84c8SPhilip Reames; CHECK-NEXT:    ret i32 [[DEOPTRET2]]
933ad5a84c8SPhilip Reames; CHECK:       guarded:
934ad5a84c8SPhilip Reames; CHECK-NEXT:    [[I_I64:%.*]] = zext i32 [[I]] to i64
935ad5a84c8SPhilip Reames; CHECK-NEXT:    [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
936ad5a84c8SPhilip Reames; CHECK-NEXT:    [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
937*b46c085dSRoman Lebedev; CHECK-NEXT:    store i32 0, i32* [[ARRAY_I_PTR]], align 4
938ad5a84c8SPhilip Reames; CHECK-NEXT:    [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
939ad5a84c8SPhilip Reames; CHECK-NEXT:    [[I_NEXT]] = add nuw i32 [[I]], 1
940ad5a84c8SPhilip Reames; CHECK-NEXT:    br label [[LOOP]]
941ad5a84c8SPhilip Reames;
942ad5a84c8SPhilip Reamesentry:
943ad5a84c8SPhilip Reames  %widenable_cond = call i1 @llvm.experimental.widenable.condition()
944ad5a84c8SPhilip Reames  %exiplicit_guard_cond = and i1 %cond_0, %widenable_cond
945ad5a84c8SPhilip Reames  br i1 %exiplicit_guard_cond, label %loop.preheader, label %deopt, !prof !0
946ad5a84c8SPhilip Reames
947ad5a84c8SPhilip Reamesdeopt:
948ad5a84c8SPhilip Reames  %deoptret = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
949ad5a84c8SPhilip Reames  ret i32 %deoptret
950ad5a84c8SPhilip Reames
951ad5a84c8SPhilip Reamesloop.preheader:
952ad5a84c8SPhilip Reames  br label %loop
953ad5a84c8SPhilip Reames
954ad5a84c8SPhilip Reamesloop:
955ad5a84c8SPhilip Reames  %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ]
956ad5a84c8SPhilip Reames  %i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ]
957ad5a84c8SPhilip Reames  call void @unknown()
958ad5a84c8SPhilip Reames  %within.bounds = icmp ult i32 %i, %length
959ad5a84c8SPhilip Reames  br i1 %within.bounds, label %guarded, label %deopt2, !prof !0
960ad5a84c8SPhilip Reames
961ad5a84c8SPhilip Reamesdeopt2:
962ad5a84c8SPhilip Reames  call void @unknown()
963ad5a84c8SPhilip Reames  %deoptret2 = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
964ad5a84c8SPhilip Reames  ret i32 %deoptret2
965ad5a84c8SPhilip Reames
966ad5a84c8SPhilip Reamesguarded:
967ad5a84c8SPhilip Reames  %i.i64 = zext i32 %i to i64
968ad5a84c8SPhilip Reames  %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
969ad5a84c8SPhilip Reames  %array.i = load i32, i32* %array.i.ptr, align 4
970ad5a84c8SPhilip Reames  store i32 0, i32* %array.i.ptr
971ad5a84c8SPhilip Reames  %loop.acc.next = add i32 %loop.acc, %array.i
972ad5a84c8SPhilip Reames  %i.next = add nuw i32 %i, 1
973ad5a84c8SPhilip Reames  br label %loop
974ad5a84c8SPhilip Reames}
975ad5a84c8SPhilip Reames
976ad5a84c8SPhilip Reames
977dfb7a909SPhilip Reames; If we have a stray widenable branch in the loop, we should still be able to
978dfb7a909SPhilip Reames; run.  This can happen when unswitching's cost model avoids unswitching some
979dfb7a909SPhilip Reames; branches.
980dfb7a909SPhilip Reamesdefine i32 @wb_in_loop(i32* %array, i32 %length, i32 %n, i1 %cond_0) {
981dfb7a909SPhilip Reames; CHECK-LABEL: @wb_in_loop(
982dfb7a909SPhilip Reames; CHECK-NEXT:  entry:
983dfb7a909SPhilip Reames; CHECK-NEXT:    [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
984dfb7a909SPhilip Reames; CHECK-NEXT:    [[WC2:%.*]] = call i1 @llvm.experimental.widenable.condition()
985*b46c085dSRoman Lebedev; CHECK-NEXT:    [[UMAX:%.*]] = call i32 @llvm.umax.i32(i32 [[N:%.*]], i32 1)
986*b46c085dSRoman Lebedev; CHECK-NEXT:    [[TMP0:%.*]] = add i32 [[UMAX]], -1
987*b46c085dSRoman Lebedev; CHECK-NEXT:    [[UMIN:%.*]] = call i32 @llvm.umin.i32(i32 [[LENGTH:%.*]], i32 [[TMP0]])
988*b46c085dSRoman Lebedev; CHECK-NEXT:    [[TMP1:%.*]] = icmp ugt i32 [[LENGTH]], [[UMIN]]
989*b46c085dSRoman Lebedev; CHECK-NEXT:    [[TMP2:%.*]] = freeze i1 [[TMP1]]
990*b46c085dSRoman Lebedev; CHECK-NEXT:    [[TMP3:%.*]] = and i1 [[TMP2]], [[COND_0:%.*]]
991*b46c085dSRoman Lebedev; CHECK-NEXT:    [[TMP4:%.*]] = icmp ugt i32 [[LENGTH]], [[UMIN]]
992*b46c085dSRoman Lebedev; CHECK-NEXT:    [[TMP5:%.*]] = freeze i1 [[TMP4]]
993*b46c085dSRoman Lebedev; CHECK-NEXT:    [[TMP6:%.*]] = and i1 [[TMP5]], [[TMP3]]
994*b46c085dSRoman Lebedev; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[TMP6]], [[WIDENABLE_COND]]
995dfb7a909SPhilip Reames; CHECK-NEXT:    br i1 [[EXIPLICIT_GUARD_COND]], label [[LOOP_PREHEADER:%.*]], label [[DEOPT:%.*]], !prof !0
996dfb7a909SPhilip Reames; CHECK:       deopt:
997dfb7a909SPhilip Reames; CHECK-NEXT:    [[DEOPTRET:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
998dfb7a909SPhilip Reames; CHECK-NEXT:    ret i32 [[DEOPTRET]]
999dfb7a909SPhilip Reames; CHECK:       loop.preheader:
1000dfb7a909SPhilip Reames; CHECK-NEXT:    br label [[LOOP:%.*]]
1001dfb7a909SPhilip Reames; CHECK:       loop:
1002dfb7a909SPhilip Reames; CHECK-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED2:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
1003dfb7a909SPhilip Reames; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED2]] ], [ 0, [[LOOP_PREHEADER]] ]
1004dfb7a909SPhilip Reames; CHECK-NEXT:    call void @unknown()
1005dfb7a909SPhilip Reames; CHECK-NEXT:    [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH]]
1006dfb7a909SPhilip Reames; CHECK-NEXT:    br i1 true, label [[GUARDED:%.*]], label [[DEOPT2:%.*]], !prof !0
1007dfb7a909SPhilip Reames; CHECK:       deopt2:
1008dfb7a909SPhilip Reames; CHECK-NEXT:    call void @unknown()
1009dfb7a909SPhilip Reames; CHECK-NEXT:    [[DEOPTRET2:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
1010dfb7a909SPhilip Reames; CHECK-NEXT:    ret i32 [[DEOPTRET2]]
1011dfb7a909SPhilip Reames; CHECK:       guarded:
1012dfb7a909SPhilip Reames; CHECK-NEXT:    call void @unknown()
1013dfb7a909SPhilip Reames; CHECK-NEXT:    [[WITHIN_BOUNDS2:%.*]] = icmp ult i32 [[I]], [[LENGTH]]
1014dfb7a909SPhilip Reames; CHECK-NEXT:    [[WB_COND:%.*]] = and i1 [[WITHIN_BOUNDS2]], true
1015dfb7a909SPhilip Reames; CHECK-NEXT:    br i1 true, label [[GUARDED2]], label [[DEOPT3:%.*]], !prof !0
1016dfb7a909SPhilip Reames; CHECK:       deopt3:
1017dfb7a909SPhilip Reames; CHECK-NEXT:    call void @unknown()
1018dfb7a909SPhilip Reames; CHECK-NEXT:    [[DEOPTRET3:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
1019dfb7a909SPhilip Reames; CHECK-NEXT:    ret i32 [[DEOPTRET3]]
1020dfb7a909SPhilip Reames; CHECK:       guarded2:
1021dfb7a909SPhilip Reames; CHECK-NEXT:    [[I_I64:%.*]] = zext i32 [[I]] to i64
1022dfb7a909SPhilip Reames; CHECK-NEXT:    [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
1023dfb7a909SPhilip Reames; CHECK-NEXT:    [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
1024*b46c085dSRoman Lebedev; CHECK-NEXT:    store i32 0, i32* [[ARRAY_I_PTR]], align 4
1025dfb7a909SPhilip Reames; CHECK-NEXT:    [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
1026dfb7a909SPhilip Reames; CHECK-NEXT:    [[I_NEXT]] = add nuw i32 [[I]], 1
1027dfb7a909SPhilip Reames; CHECK-NEXT:    [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[N]]
1028dfb7a909SPhilip Reames; CHECK-NEXT:    br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT:%.*]]
1029dfb7a909SPhilip Reames; CHECK:       exit:
1030dfb7a909SPhilip Reames; CHECK-NEXT:    [[RESULT:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED2]] ]
1031dfb7a909SPhilip Reames; CHECK-NEXT:    ret i32 [[RESULT]]
1032dfb7a909SPhilip Reames;
1033dfb7a909SPhilip Reamesentry:
1034dfb7a909SPhilip Reames  %widenable_cond = call i1 @llvm.experimental.widenable.condition()
1035dfb7a909SPhilip Reames  %wc2 = call i1 @llvm.experimental.widenable.condition()
1036dfb7a909SPhilip Reames  %exiplicit_guard_cond = and i1 %cond_0, %widenable_cond
1037dfb7a909SPhilip Reames  br i1 %exiplicit_guard_cond, label %loop.preheader, label %deopt, !prof !0
1038dfb7a909SPhilip Reames
1039dfb7a909SPhilip Reamesdeopt:
1040dfb7a909SPhilip Reames  %deoptret = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
1041dfb7a909SPhilip Reames  ret i32 %deoptret
1042dfb7a909SPhilip Reames
1043dfb7a909SPhilip Reamesloop.preheader:
1044dfb7a909SPhilip Reames  br label %loop
1045dfb7a909SPhilip Reames
1046dfb7a909SPhilip Reamesloop:
1047dfb7a909SPhilip Reames  %loop.acc = phi i32 [ %loop.acc.next, %guarded2 ], [ 0, %loop.preheader ]
1048dfb7a909SPhilip Reames  %i = phi i32 [ %i.next, %guarded2 ], [ 0, %loop.preheader ]
1049dfb7a909SPhilip Reames  call void @unknown()
1050dfb7a909SPhilip Reames  %within.bounds = icmp ult i32 %i, %length
1051dfb7a909SPhilip Reames  br i1 %within.bounds, label %guarded, label %deopt2, !prof !0
1052dfb7a909SPhilip Reames
1053dfb7a909SPhilip Reamesdeopt2:
1054dfb7a909SPhilip Reames  call void @unknown()
1055dfb7a909SPhilip Reames  %deoptret2 = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
1056dfb7a909SPhilip Reames  ret i32 %deoptret2
1057dfb7a909SPhilip Reames
1058dfb7a909SPhilip Reamesguarded:
1059dfb7a909SPhilip Reames  call void @unknown()
1060dfb7a909SPhilip Reames  %within.bounds2 = icmp ult i32 %i, %length
1061dfb7a909SPhilip Reames  %wb_cond = and i1 %within.bounds2, %wc2
1062dfb7a909SPhilip Reames  br i1 %wb_cond, label %guarded2, label %deopt3, !prof !0
1063dfb7a909SPhilip Reames
1064dfb7a909SPhilip Reamesdeopt3:
1065dfb7a909SPhilip Reames  call void @unknown()
1066dfb7a909SPhilip Reames  %deoptret3 = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
1067dfb7a909SPhilip Reames  ret i32 %deoptret3
1068dfb7a909SPhilip Reames
1069dfb7a909SPhilip Reamesguarded2:
1070dfb7a909SPhilip Reames  %i.i64 = zext i32 %i to i64
1071dfb7a909SPhilip Reames  %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
1072dfb7a909SPhilip Reames  %array.i = load i32, i32* %array.i.ptr, align 4
1073dfb7a909SPhilip Reames  store i32 0, i32* %array.i.ptr
1074dfb7a909SPhilip Reames  %loop.acc.next = add i32 %loop.acc, %array.i
1075dfb7a909SPhilip Reames  %i.next = add nuw i32 %i, 1
1076dfb7a909SPhilip Reames  %continue = icmp ult i32 %i.next, %n
1077dfb7a909SPhilip Reames  br i1 %continue, label %loop, label %exit
1078dfb7a909SPhilip Reames
1079dfb7a909SPhilip Reamesexit:
1080dfb7a909SPhilip Reames  %result = phi i32 [ %loop.acc.next, %guarded2 ]
1081dfb7a909SPhilip Reames  ret i32 %result
1082dfb7a909SPhilip Reames}
1083dfb7a909SPhilip Reames
1084dfb7a909SPhilip Reames
1085dfb7a909SPhilip Reames
1086ad5a84c8SPhilip Reamesdeclare void @unknown()
1087ad5a84c8SPhilip Reames
1088ad5a84c8SPhilip Reamesdeclare i1 @llvm.experimental.widenable.condition()
1089ad5a84c8SPhilip Reamesdeclare i32 @llvm.experimental.deoptimize.i32(...)
1090ad5a84c8SPhilip Reames
1091ad5a84c8SPhilip Reames!0 = !{!"branch_weights", i32 1048576, i32 1}
1092ad5a84c8SPhilip Reames!1 = !{i32 1, i32 -2147483648}
1093ad5a84c8SPhilip Reames!2 = !{i32 0, i32 50}
1094