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()
11ad5a84c8SPhilip Reames; CHECK-NEXT:    [[TMP0:%.*]] = icmp ugt i32 [[N:%.*]], 1
12ad5a84c8SPhilip Reames; CHECK-NEXT:    [[UMAX:%.*]] = select i1 [[TMP0]], i32 [[N]], i32 1
13ad5a84c8SPhilip Reames; CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[UMAX]], -1
14ad5a84c8SPhilip Reames; CHECK-NEXT:    [[TMP2:%.*]] = icmp ult i32 [[LENGTH:%.*]], [[TMP1]]
15ad5a84c8SPhilip Reames; CHECK-NEXT:    [[UMIN:%.*]] = select i1 [[TMP2]], i32 [[LENGTH]], i32 [[TMP1]]
16ad5a84c8SPhilip Reames; CHECK-NEXT:    [[TMP3:%.*]] = icmp ugt i32 [[LENGTH]], [[UMIN]]
17ad5a84c8SPhilip Reames; CHECK-NEXT:    [[TMP4:%.*]] = freeze i1 [[TMP3]]
18ad5a84c8SPhilip Reames; CHECK-NEXT:    [[TMP5:%.*]] = and i1 [[TMP4]], [[COND_0:%.*]]
19ad5a84c8SPhilip Reames; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[TMP5]], [[WIDENABLE_COND]]
20ad5a84c8SPhilip Reames; CHECK-NEXT:    br i1 [[EXIPLICIT_GUARD_COND]], label [[LOOP_PREHEADER:%.*]], label [[DEOPT:%.*]], !prof !0
21ad5a84c8SPhilip Reames; CHECK:       deopt:
22ad5a84c8SPhilip Reames; CHECK-NEXT:    [[DEOPTRET:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
23ad5a84c8SPhilip Reames; CHECK-NEXT:    ret i32 [[DEOPTRET]]
24ad5a84c8SPhilip Reames; CHECK:       loop.preheader:
25ad5a84c8SPhilip Reames; CHECK-NEXT:    br label [[LOOP:%.*]]
26ad5a84c8SPhilip Reames; CHECK:       loop:
27ad5a84c8SPhilip Reames; CHECK-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
28ad5a84c8SPhilip Reames; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ]
29ad5a84c8SPhilip Reames; CHECK-NEXT:    call void @unknown()
30ad5a84c8SPhilip Reames; CHECK-NEXT:    [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH]]
31ad5a84c8SPhilip Reames; CHECK-NEXT:    br i1 true, label [[GUARDED]], label [[DEOPT2:%.*]], !prof !0
32ad5a84c8SPhilip Reames; CHECK:       deopt2:
33ad5a84c8SPhilip Reames; CHECK-NEXT:    call void @unknown()
34ad5a84c8SPhilip Reames; CHECK-NEXT:    [[DEOPTRET2:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
35ad5a84c8SPhilip Reames; CHECK-NEXT:    ret i32 [[DEOPTRET2]]
36ad5a84c8SPhilip Reames; CHECK:       guarded:
37ad5a84c8SPhilip Reames; CHECK-NEXT:    [[I_I64:%.*]] = zext i32 [[I]] to i64
38ad5a84c8SPhilip Reames; CHECK-NEXT:    [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
39ad5a84c8SPhilip Reames; CHECK-NEXT:    [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
40ad5a84c8SPhilip Reames; CHECK-NEXT:    store i32 0, i32* [[ARRAY_I_PTR]]
41ad5a84c8SPhilip Reames; CHECK-NEXT:    [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
42ad5a84c8SPhilip Reames; CHECK-NEXT:    [[I_NEXT]] = add nuw i32 [[I]], 1
43ad5a84c8SPhilip Reames; CHECK-NEXT:    [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[N]]
44ad5a84c8SPhilip Reames; CHECK-NEXT:    br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT:%.*]]
45ad5a84c8SPhilip Reames; CHECK:       exit:
46ad5a84c8SPhilip Reames; CHECK-NEXT:    [[RESULT:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ]
47ad5a84c8SPhilip Reames; CHECK-NEXT:    ret i32 [[RESULT]]
48ad5a84c8SPhilip Reames;
49ad5a84c8SPhilip Reamesentry:
50ad5a84c8SPhilip Reames  %widenable_cond = call i1 @llvm.experimental.widenable.condition()
51ad5a84c8SPhilip Reames  %exiplicit_guard_cond = and i1 %cond_0, %widenable_cond
52ad5a84c8SPhilip Reames  br i1 %exiplicit_guard_cond, label %loop.preheader, label %deopt, !prof !0
53ad5a84c8SPhilip Reames
54ad5a84c8SPhilip Reamesdeopt:
55ad5a84c8SPhilip Reames  %deoptret = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
56ad5a84c8SPhilip Reames  ret i32 %deoptret
57ad5a84c8SPhilip Reames
58ad5a84c8SPhilip Reamesloop.preheader:
59ad5a84c8SPhilip Reames  br label %loop
60ad5a84c8SPhilip Reames
61ad5a84c8SPhilip Reamesloop:
62ad5a84c8SPhilip Reames  %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ]
63ad5a84c8SPhilip Reames  %i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ]
64ad5a84c8SPhilip Reames  call void @unknown()
65ad5a84c8SPhilip Reames  %within.bounds = icmp ult i32 %i, %length
66ad5a84c8SPhilip Reames  br i1 %within.bounds, label %guarded, label %deopt2, !prof !0
67ad5a84c8SPhilip Reames
68ad5a84c8SPhilip Reamesdeopt2:
69ad5a84c8SPhilip Reames  call void @unknown()
70ad5a84c8SPhilip Reames  %deoptret2 = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
71ad5a84c8SPhilip Reames  ret i32 %deoptret2
72ad5a84c8SPhilip Reames
73ad5a84c8SPhilip Reamesguarded:
74ad5a84c8SPhilip Reames  %i.i64 = zext i32 %i to i64
75ad5a84c8SPhilip Reames  %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
76ad5a84c8SPhilip Reames  %array.i = load i32, i32* %array.i.ptr, align 4
77ad5a84c8SPhilip Reames  store i32 0, i32* %array.i.ptr
78ad5a84c8SPhilip Reames  %loop.acc.next = add i32 %loop.acc, %array.i
79ad5a84c8SPhilip Reames  %i.next = add nuw i32 %i, 1
80ad5a84c8SPhilip Reames  %continue = icmp ult i32 %i.next, %n
81ad5a84c8SPhilip Reames  br i1 %continue, label %loop, label %exit
82ad5a84c8SPhilip Reames
83ad5a84c8SPhilip Reamesexit:
84ad5a84c8SPhilip Reames  %result = phi i32 [ %loop.acc.next, %guarded ]
85ad5a84c8SPhilip Reames  ret i32 %result
86ad5a84c8SPhilip Reames}
87ad5a84c8SPhilip Reames
88ad5a84c8SPhilip Reames
89ad5a84c8SPhilip Reames
90ad5a84c8SPhilip Reamesdefine i32 @test_non_canonical(i32* %array, i32 %length, i1 %cond_0) {
91ad5a84c8SPhilip Reames; CHECK-LABEL: @test_non_canonical(
92ad5a84c8SPhilip Reames; CHECK-NEXT:  entry:
93ad5a84c8SPhilip Reames; CHECK-NEXT:    [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
94ad5a84c8SPhilip Reames; CHECK-NEXT:    [[TMP0:%.*]] = icmp ugt i32 [[LENGTH:%.*]], 1
95ad5a84c8SPhilip Reames; CHECK-NEXT:    [[UMAX:%.*]] = select i1 [[TMP0]], i32 [[LENGTH]], i32 1
96ad5a84c8SPhilip Reames; CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[UMAX]], -1
97ad5a84c8SPhilip Reames; CHECK-NEXT:    [[TMP2:%.*]] = icmp ult i32 [[LENGTH]], [[TMP1]]
98ad5a84c8SPhilip Reames; CHECK-NEXT:    [[UMIN:%.*]] = select i1 [[TMP2]], i32 [[LENGTH]], i32 [[TMP1]]
99ad5a84c8SPhilip Reames; CHECK-NEXT:    [[TMP3:%.*]] = icmp ugt i32 [[LENGTH]], [[UMIN]]
100ad5a84c8SPhilip Reames; CHECK-NEXT:    [[TMP4:%.*]] = freeze i1 [[TMP3]]
101ad5a84c8SPhilip Reames; CHECK-NEXT:    [[TMP5:%.*]] = and i1 [[TMP4]], [[COND_0:%.*]]
102ad5a84c8SPhilip Reames; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[TMP5]], [[WIDENABLE_COND]]
103ad5a84c8SPhilip Reames; CHECK-NEXT:    br i1 [[EXIPLICIT_GUARD_COND]], label [[LOOP_PREHEADER:%.*]], label [[DEOPT:%.*]], !prof !0
104ad5a84c8SPhilip Reames; CHECK:       deopt:
105ad5a84c8SPhilip Reames; CHECK-NEXT:    [[DEOPTRET:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
106ad5a84c8SPhilip Reames; CHECK-NEXT:    ret i32 [[DEOPTRET]]
107ad5a84c8SPhilip Reames; CHECK:       loop.preheader:
108ad5a84c8SPhilip Reames; CHECK-NEXT:    br label [[LOOP:%.*]]
109ad5a84c8SPhilip Reames; CHECK:       loop:
110ad5a84c8SPhilip Reames; CHECK-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
111ad5a84c8SPhilip Reames; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ]
112ad5a84c8SPhilip Reames; CHECK-NEXT:    call void @unknown()
113ad5a84c8SPhilip Reames; CHECK-NEXT:    [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH]]
114ad5a84c8SPhilip Reames; CHECK-NEXT:    br i1 true, label [[GUARDED]], label [[DEOPT2:%.*]], !prof !0
115ad5a84c8SPhilip Reames; CHECK:       deopt2:
116ad5a84c8SPhilip Reames; CHECK-NEXT:    call void @unknown()
117ad5a84c8SPhilip Reames; CHECK-NEXT:    [[DEOPTRET2:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
118ad5a84c8SPhilip Reames; CHECK-NEXT:    ret i32 [[DEOPTRET2]]
119ad5a84c8SPhilip Reames; CHECK:       guarded:
120ad5a84c8SPhilip Reames; CHECK-NEXT:    [[I_I64:%.*]] = zext i32 [[I]] to i64
121ad5a84c8SPhilip Reames; CHECK-NEXT:    [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
122ad5a84c8SPhilip Reames; CHECK-NEXT:    [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
123ad5a84c8SPhilip Reames; CHECK-NEXT:    store i32 0, i32* [[ARRAY_I_PTR]]
124ad5a84c8SPhilip Reames; CHECK-NEXT:    [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
125ad5a84c8SPhilip Reames; CHECK-NEXT:    [[I_NEXT]] = add nuw i32 [[I]], 1
126ad5a84c8SPhilip Reames; CHECK-NEXT:    [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[LENGTH]]
127ad5a84c8SPhilip Reames; CHECK-NEXT:    br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT:%.*]]
128ad5a84c8SPhilip Reames; CHECK:       exit:
129ad5a84c8SPhilip Reames; CHECK-NEXT:    [[RESULT:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ]
130ad5a84c8SPhilip Reames; CHECK-NEXT:    ret i32 [[RESULT]]
131ad5a84c8SPhilip Reames;
132ad5a84c8SPhilip Reamesentry:
133ad5a84c8SPhilip Reames  %widenable_cond = call i1 @llvm.experimental.widenable.condition()
134ad5a84c8SPhilip Reames  %exiplicit_guard_cond = and i1 %cond_0, %widenable_cond
135ad5a84c8SPhilip Reames  br i1 %exiplicit_guard_cond, label %loop.preheader, label %deopt, !prof !0
136ad5a84c8SPhilip Reames
137ad5a84c8SPhilip Reamesdeopt:
138ad5a84c8SPhilip Reames  %deoptret = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
139ad5a84c8SPhilip Reames  ret i32 %deoptret
140ad5a84c8SPhilip Reames
141ad5a84c8SPhilip Reamesloop.preheader:
142ad5a84c8SPhilip Reames  br label %loop
143ad5a84c8SPhilip Reames
144ad5a84c8SPhilip Reamesloop:
145ad5a84c8SPhilip Reames  %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ]
146ad5a84c8SPhilip Reames  %i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ]
147ad5a84c8SPhilip Reames  call void @unknown()
148ad5a84c8SPhilip Reames  %within.bounds = icmp ult i32 %i, %length
149ad5a84c8SPhilip Reames  br i1 %within.bounds, label %guarded, label %deopt2, !prof !0
150ad5a84c8SPhilip Reames
151ad5a84c8SPhilip Reamesdeopt2:
152ad5a84c8SPhilip Reames  call void @unknown()
153ad5a84c8SPhilip Reames  %deoptret2 = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
154ad5a84c8SPhilip Reames  ret i32 %deoptret2
155ad5a84c8SPhilip Reames
156ad5a84c8SPhilip Reamesguarded:
157ad5a84c8SPhilip Reames  %i.i64 = zext i32 %i to i64
158ad5a84c8SPhilip Reames  %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
159ad5a84c8SPhilip Reames  %array.i = load i32, i32* %array.i.ptr, align 4
160ad5a84c8SPhilip Reames  store i32 0, i32* %array.i.ptr
161ad5a84c8SPhilip Reames  %loop.acc.next = add i32 %loop.acc, %array.i
162ad5a84c8SPhilip Reames  %i.next = add nuw i32 %i, 1
163ad5a84c8SPhilip Reames  %continue = icmp ult i32 %i.next, %length
164ad5a84c8SPhilip Reames  br i1 %continue, label %loop, label %exit
165ad5a84c8SPhilip Reames
166ad5a84c8SPhilip Reamesexit:
167ad5a84c8SPhilip Reames  %result = phi i32 [ %loop.acc.next, %guarded ]
168ad5a84c8SPhilip Reames  ret i32 %result
169ad5a84c8SPhilip Reames}
170ad5a84c8SPhilip Reames
171ad5a84c8SPhilip Reames
172ad5a84c8SPhilip Reamesdefine i32 @test_two_range_checks(i32* %array, i32 %length.1, i32 %length.2, i32 %n, i1 %cond_0) {
173ad5a84c8SPhilip Reames; CHECK-LABEL: @test_two_range_checks(
174ad5a84c8SPhilip Reames; CHECK-NEXT:  entry:
175ad5a84c8SPhilip Reames; CHECK-NEXT:    [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
176ad5a84c8SPhilip Reames; CHECK-NEXT:    [[TMP0:%.*]] = icmp ult i32 [[LENGTH_2:%.*]], [[LENGTH_1:%.*]]
177ad5a84c8SPhilip Reames; CHECK-NEXT:    [[UMIN:%.*]] = select i1 [[TMP0]], i32 [[LENGTH_2]], i32 [[LENGTH_1]]
178ad5a84c8SPhilip Reames; CHECK-NEXT:    [[TMP1:%.*]] = icmp ugt i32 [[N:%.*]], 1
179ad5a84c8SPhilip Reames; CHECK-NEXT:    [[UMAX:%.*]] = select i1 [[TMP1]], i32 [[N]], i32 1
180ad5a84c8SPhilip Reames; CHECK-NEXT:    [[TMP2:%.*]] = add i32 [[UMAX]], -1
181ad5a84c8SPhilip Reames; CHECK-NEXT:    [[TMP3:%.*]] = icmp ult i32 [[UMIN]], [[TMP2]]
182ad5a84c8SPhilip Reames; CHECK-NEXT:    [[UMIN1:%.*]] = select i1 [[TMP3]], i32 [[UMIN]], i32 [[TMP2]]
183ad5a84c8SPhilip Reames; CHECK-NEXT:    [[TMP4:%.*]] = icmp ugt i32 [[LENGTH_1]], [[UMIN1]]
184ad5a84c8SPhilip Reames; CHECK-NEXT:    [[TMP5:%.*]] = freeze i1 [[TMP4]]
185ad5a84c8SPhilip Reames; CHECK-NEXT:    [[TMP6:%.*]] = and i1 [[TMP5]], [[COND_0:%.*]]
186ad5a84c8SPhilip Reames; CHECK-NEXT:    [[TMP7:%.*]] = icmp ugt i32 [[LENGTH_2]], [[UMIN1]]
187ad5a84c8SPhilip Reames; CHECK-NEXT:    [[TMP8:%.*]] = freeze i1 [[TMP7]]
188ad5a84c8SPhilip Reames; CHECK-NEXT:    [[TMP9:%.*]] = and i1 [[TMP8]], [[TMP6]]
189ad5a84c8SPhilip Reames; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[TMP9]], [[WIDENABLE_COND]]
190ad5a84c8SPhilip Reames; CHECK-NEXT:    br i1 [[EXIPLICIT_GUARD_COND]], label [[LOOP_PREHEADER:%.*]], label [[DEOPT:%.*]], !prof !0
191ad5a84c8SPhilip Reames; CHECK:       deopt:
192ad5a84c8SPhilip Reames; CHECK-NEXT:    [[DEOPTRET:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
193ad5a84c8SPhilip Reames; CHECK-NEXT:    ret i32 [[DEOPTRET]]
194ad5a84c8SPhilip Reames; CHECK:       loop.preheader:
195ad5a84c8SPhilip Reames; CHECK-NEXT:    br label [[LOOP:%.*]]
196ad5a84c8SPhilip Reames; CHECK:       loop:
197ad5a84c8SPhilip Reames; CHECK-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED2:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
198ad5a84c8SPhilip Reames; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED2]] ], [ 0, [[LOOP_PREHEADER]] ]
199ad5a84c8SPhilip Reames; CHECK-NEXT:    call void @unknown()
200ad5a84c8SPhilip Reames; CHECK-NEXT:    [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH_1]]
201ad5a84c8SPhilip Reames; CHECK-NEXT:    br i1 true, label [[GUARDED:%.*]], label [[DEOPT2:%.*]], !prof !0
202ad5a84c8SPhilip Reames; CHECK:       deopt2:
203ad5a84c8SPhilip Reames; CHECK-NEXT:    call void @unknown()
204ad5a84c8SPhilip Reames; CHECK-NEXT:    [[DEOPTRET2:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
205ad5a84c8SPhilip Reames; CHECK-NEXT:    ret i32 [[DEOPTRET2]]
206ad5a84c8SPhilip Reames; CHECK:       guarded:
207ad5a84c8SPhilip Reames; CHECK-NEXT:    [[WITHIN_BOUNDS2:%.*]] = icmp ult i32 [[I]], [[LENGTH_2]]
208ad5a84c8SPhilip Reames; CHECK-NEXT:    br i1 true, label [[GUARDED2]], label [[DEOPT3:%.*]], !prof !0
209ad5a84c8SPhilip Reames; CHECK:       deopt3:
210ad5a84c8SPhilip Reames; CHECK-NEXT:    call void @unknown()
211ad5a84c8SPhilip Reames; CHECK-NEXT:    [[DEOPTRET3:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
212ad5a84c8SPhilip Reames; CHECK-NEXT:    ret i32 [[DEOPTRET3]]
213ad5a84c8SPhilip Reames; CHECK:       guarded2:
214ad5a84c8SPhilip Reames; CHECK-NEXT:    [[I_I64:%.*]] = zext i32 [[I]] to i64
215ad5a84c8SPhilip Reames; CHECK-NEXT:    [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
216ad5a84c8SPhilip Reames; CHECK-NEXT:    [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
217ad5a84c8SPhilip Reames; CHECK-NEXT:    store i32 0, i32* [[ARRAY_I_PTR]]
218ad5a84c8SPhilip Reames; CHECK-NEXT:    [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
219ad5a84c8SPhilip Reames; CHECK-NEXT:    [[I_NEXT]] = add nuw i32 [[I]], 1
220ad5a84c8SPhilip Reames; CHECK-NEXT:    [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[N]]
221ad5a84c8SPhilip Reames; CHECK-NEXT:    br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT:%.*]]
222ad5a84c8SPhilip Reames; CHECK:       exit:
223ad5a84c8SPhilip Reames; CHECK-NEXT:    [[RESULT:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED2]] ]
224ad5a84c8SPhilip Reames; CHECK-NEXT:    ret i32 [[RESULT]]
225ad5a84c8SPhilip Reames;
226ad5a84c8SPhilip Reamesentry:
227ad5a84c8SPhilip Reames  %widenable_cond = call i1 @llvm.experimental.widenable.condition()
228ad5a84c8SPhilip Reames  %exiplicit_guard_cond = and i1 %cond_0, %widenable_cond
229ad5a84c8SPhilip Reames  br i1 %exiplicit_guard_cond, label %loop.preheader, label %deopt, !prof !0
230ad5a84c8SPhilip Reames
231ad5a84c8SPhilip Reamesdeopt:
232ad5a84c8SPhilip Reames  %deoptret = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
233ad5a84c8SPhilip Reames  ret i32 %deoptret
234ad5a84c8SPhilip Reames
235ad5a84c8SPhilip Reamesloop.preheader:
236ad5a84c8SPhilip Reames  br label %loop
237ad5a84c8SPhilip Reames
238ad5a84c8SPhilip Reamesloop:
239ad5a84c8SPhilip Reames  %loop.acc = phi i32 [ %loop.acc.next, %guarded2 ], [ 0, %loop.preheader ]
240ad5a84c8SPhilip Reames  %i = phi i32 [ %i.next, %guarded2 ], [ 0, %loop.preheader ]
241ad5a84c8SPhilip Reames  call void @unknown()
242ad5a84c8SPhilip Reames  %within.bounds = icmp ult i32 %i, %length.1
243ad5a84c8SPhilip Reames  br i1 %within.bounds, label %guarded, label %deopt2, !prof !0
244ad5a84c8SPhilip Reames
245ad5a84c8SPhilip Reamesdeopt2:
246ad5a84c8SPhilip Reames  call void @unknown()
247ad5a84c8SPhilip Reames  %deoptret2 = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
248ad5a84c8SPhilip Reames  ret i32 %deoptret2
249ad5a84c8SPhilip Reames
250ad5a84c8SPhilip Reamesguarded:
251ad5a84c8SPhilip Reames  %within.bounds2 = icmp ult i32 %i, %length.2
252ad5a84c8SPhilip Reames  br i1 %within.bounds2, label %guarded2, label %deopt3, !prof !0
253ad5a84c8SPhilip Reames
254ad5a84c8SPhilip Reamesdeopt3:
255ad5a84c8SPhilip Reames  call void @unknown()
256ad5a84c8SPhilip Reames  %deoptret3 = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
257ad5a84c8SPhilip Reames  ret i32 %deoptret3
258ad5a84c8SPhilip Reames
259ad5a84c8SPhilip Reamesguarded2:
260ad5a84c8SPhilip Reames  %i.i64 = zext i32 %i to i64
261ad5a84c8SPhilip Reames  %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
262ad5a84c8SPhilip Reames  %array.i = load i32, i32* %array.i.ptr, align 4
263ad5a84c8SPhilip Reames  store i32 0, i32* %array.i.ptr
264ad5a84c8SPhilip Reames  %loop.acc.next = add i32 %loop.acc, %array.i
265ad5a84c8SPhilip Reames  %i.next = add nuw i32 %i, 1
266ad5a84c8SPhilip Reames  %continue = icmp ult i32 %i.next, %n
267ad5a84c8SPhilip Reames  br i1 %continue, label %loop, label %exit
268ad5a84c8SPhilip Reames
269ad5a84c8SPhilip Reamesexit:
270ad5a84c8SPhilip Reames  %result = phi i32 [ %loop.acc.next, %guarded2 ]
271ad5a84c8SPhilip Reames  ret i32 %result
272ad5a84c8SPhilip Reames}
273ad5a84c8SPhilip Reames
274ad5a84c8SPhilip Reames@G = external global i32
275ad5a84c8SPhilip Reames
276ad5a84c8SPhilip Reamesdefine i32 @test_unanalyzeable_exit(i32* %array, i32 %length, i32 %n, i1 %cond_0) {
277ad5a84c8SPhilip Reames; CHECK-LABEL: @test_unanalyzeable_exit(
278ad5a84c8SPhilip Reames; CHECK-NEXT:  entry:
279ad5a84c8SPhilip Reames; CHECK-NEXT:    [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
280ad5a84c8SPhilip Reames; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[COND_0:%.*]], [[WIDENABLE_COND]]
281ad5a84c8SPhilip Reames; CHECK-NEXT:    br i1 [[EXIPLICIT_GUARD_COND]], label [[LOOP_PREHEADER:%.*]], label [[DEOPT:%.*]], !prof !0
282ad5a84c8SPhilip Reames; CHECK:       deopt:
283ad5a84c8SPhilip Reames; CHECK-NEXT:    [[DEOPTRET:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
284ad5a84c8SPhilip Reames; CHECK-NEXT:    ret i32 [[DEOPTRET]]
285ad5a84c8SPhilip Reames; CHECK:       loop.preheader:
286ad5a84c8SPhilip Reames; CHECK-NEXT:    br label [[LOOP:%.*]]
287ad5a84c8SPhilip Reames; CHECK:       loop:
288ad5a84c8SPhilip Reames; CHECK-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED2:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
289ad5a84c8SPhilip Reames; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED2]] ], [ 0, [[LOOP_PREHEADER]] ]
290ad5a84c8SPhilip Reames; CHECK-NEXT:    call void @unknown()
291ad5a84c8SPhilip Reames; CHECK-NEXT:    [[VOL:%.*]] = load volatile i32, i32* @G
292ad5a84c8SPhilip Reames; CHECK-NEXT:    [[UNKNOWN:%.*]] = icmp eq i32 [[VOL]], 0
293ad5a84c8SPhilip Reames; CHECK-NEXT:    br i1 [[UNKNOWN]], label [[GUARDED2]], label [[DEOPT3:%.*]], !prof !0
294ad5a84c8SPhilip Reames; CHECK:       deopt3:
295ad5a84c8SPhilip Reames; CHECK-NEXT:    call void @unknown()
296ad5a84c8SPhilip Reames; CHECK-NEXT:    [[DEOPTRET3:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
297ad5a84c8SPhilip Reames; CHECK-NEXT:    ret i32 [[DEOPTRET3]]
298ad5a84c8SPhilip Reames; CHECK:       guarded2:
299ad5a84c8SPhilip Reames; CHECK-NEXT:    [[I_I64:%.*]] = zext i32 [[I]] to i64
300ad5a84c8SPhilip Reames; CHECK-NEXT:    [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
301ad5a84c8SPhilip Reames; CHECK-NEXT:    [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
302ad5a84c8SPhilip Reames; CHECK-NEXT:    store i32 0, i32* [[ARRAY_I_PTR]]
303ad5a84c8SPhilip Reames; CHECK-NEXT:    [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
304ad5a84c8SPhilip Reames; CHECK-NEXT:    [[I_NEXT]] = add nuw i32 [[I]], 1
305ad5a84c8SPhilip Reames; CHECK-NEXT:    [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[N:%.*]]
306ad5a84c8SPhilip Reames; CHECK-NEXT:    br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT:%.*]]
307ad5a84c8SPhilip Reames; CHECK:       exit:
308ad5a84c8SPhilip Reames; CHECK-NEXT:    [[RESULT:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED2]] ]
309ad5a84c8SPhilip Reames; CHECK-NEXT:    ret i32 [[RESULT]]
310ad5a84c8SPhilip Reames;
311ad5a84c8SPhilip Reamesentry:
312ad5a84c8SPhilip Reames  %widenable_cond = call i1 @llvm.experimental.widenable.condition()
313ad5a84c8SPhilip Reames  %exiplicit_guard_cond = and i1 %cond_0, %widenable_cond
314ad5a84c8SPhilip Reames  br i1 %exiplicit_guard_cond, label %loop.preheader, label %deopt, !prof !0
315ad5a84c8SPhilip Reames
316ad5a84c8SPhilip Reamesdeopt:
317ad5a84c8SPhilip Reames  %deoptret = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
318ad5a84c8SPhilip Reames  ret i32 %deoptret
319ad5a84c8SPhilip Reames
320ad5a84c8SPhilip Reamesloop.preheader:
321ad5a84c8SPhilip Reames  br label %loop
322ad5a84c8SPhilip Reames
323ad5a84c8SPhilip Reamesloop:
324ad5a84c8SPhilip Reames  %loop.acc = phi i32 [ %loop.acc.next, %guarded2 ], [ 0, %loop.preheader ]
325ad5a84c8SPhilip Reames  %i = phi i32 [ %i.next, %guarded2 ], [ 0, %loop.preheader ]
326ad5a84c8SPhilip Reames  call void @unknown()
327ad5a84c8SPhilip Reames  %vol = load volatile i32, i32* @G
328ad5a84c8SPhilip Reames  %unknown = icmp eq i32 %vol, 0
329ad5a84c8SPhilip Reames  br i1 %unknown, label %guarded2, label %deopt3, !prof !0
330ad5a84c8SPhilip Reames
331ad5a84c8SPhilip Reamesdeopt3:
332ad5a84c8SPhilip Reames  call void @unknown()
333ad5a84c8SPhilip Reames  %deoptret3 = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
334ad5a84c8SPhilip Reames  ret i32 %deoptret3
335ad5a84c8SPhilip Reames
336ad5a84c8SPhilip Reamesguarded2:
337ad5a84c8SPhilip Reames  %i.i64 = zext i32 %i to i64
338ad5a84c8SPhilip Reames  %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
339ad5a84c8SPhilip Reames  %array.i = load i32, i32* %array.i.ptr, align 4
340ad5a84c8SPhilip Reames  store i32 0, i32* %array.i.ptr
341ad5a84c8SPhilip Reames  %loop.acc.next = add i32 %loop.acc, %array.i
342ad5a84c8SPhilip Reames  %i.next = add nuw i32 %i, 1
343ad5a84c8SPhilip Reames  %continue = icmp ult i32 %i.next, %n
344ad5a84c8SPhilip Reames  br i1 %continue, label %loop, label %exit
345ad5a84c8SPhilip Reames
346ad5a84c8SPhilip Reamesexit:
347ad5a84c8SPhilip Reames  %result = phi i32 [ %loop.acc.next, %guarded2 ]
348ad5a84c8SPhilip Reames  ret i32 %result
349ad5a84c8SPhilip Reames}
350ad5a84c8SPhilip Reames
351ad5a84c8SPhilip Reamesdefine i32 @test_unanalyzeable_exit2(i32* %array, i32 %length, i32 %n, i1 %cond_0) {
352ad5a84c8SPhilip Reames; CHECK-LABEL: @test_unanalyzeable_exit2(
353ad5a84c8SPhilip Reames; CHECK-NEXT:  entry:
354ad5a84c8SPhilip Reames; CHECK-NEXT:    [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
355ad5a84c8SPhilip Reames; CHECK-NEXT:    [[TMP0:%.*]] = icmp ugt i32 [[N:%.*]], 1
356ad5a84c8SPhilip Reames; CHECK-NEXT:    [[UMAX:%.*]] = select i1 [[TMP0]], i32 [[N]], i32 1
357ad5a84c8SPhilip Reames; CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[UMAX]], -1
358ad5a84c8SPhilip Reames; CHECK-NEXT:    [[TMP2:%.*]] = icmp ult i32 [[LENGTH:%.*]], [[TMP1]]
359ad5a84c8SPhilip Reames; CHECK-NEXT:    [[UMIN:%.*]] = select i1 [[TMP2]], i32 [[LENGTH]], i32 [[TMP1]]
360ad5a84c8SPhilip Reames; CHECK-NEXT:    [[TMP3:%.*]] = icmp ugt i32 [[LENGTH]], [[UMIN]]
361ad5a84c8SPhilip Reames; CHECK-NEXT:    [[TMP4:%.*]] = freeze i1 [[TMP3]]
362ad5a84c8SPhilip Reames; CHECK-NEXT:    [[TMP5:%.*]] = and i1 [[TMP4]], [[COND_0:%.*]]
363ad5a84c8SPhilip Reames; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[TMP5]], [[WIDENABLE_COND]]
364ad5a84c8SPhilip Reames; CHECK-NEXT:    br i1 [[EXIPLICIT_GUARD_COND]], label [[LOOP_PREHEADER:%.*]], label [[DEOPT:%.*]], !prof !0
365ad5a84c8SPhilip Reames; CHECK:       deopt:
366ad5a84c8SPhilip Reames; CHECK-NEXT:    [[DEOPTRET:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
367ad5a84c8SPhilip Reames; CHECK-NEXT:    ret i32 [[DEOPTRET]]
368ad5a84c8SPhilip Reames; CHECK:       loop.preheader:
369ad5a84c8SPhilip Reames; CHECK-NEXT:    br label [[LOOP:%.*]]
370ad5a84c8SPhilip Reames; CHECK:       loop:
371ad5a84c8SPhilip Reames; CHECK-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED2:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
372ad5a84c8SPhilip Reames; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED2]] ], [ 0, [[LOOP_PREHEADER]] ]
373ad5a84c8SPhilip Reames; CHECK-NEXT:    call void @unknown()
374ad5a84c8SPhilip Reames; CHECK-NEXT:    [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH]]
375ad5a84c8SPhilip Reames; CHECK-NEXT:    br i1 true, label [[GUARDED:%.*]], label [[DEOPT2:%.*]], !prof !0
376ad5a84c8SPhilip Reames; CHECK:       deopt2:
377ad5a84c8SPhilip Reames; CHECK-NEXT:    call void @unknown()
378ad5a84c8SPhilip Reames; CHECK-NEXT:    [[DEOPTRET2:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
379ad5a84c8SPhilip Reames; CHECK-NEXT:    ret i32 [[DEOPTRET2]]
380ad5a84c8SPhilip Reames; CHECK:       guarded:
381ad5a84c8SPhilip Reames; CHECK-NEXT:    [[VOL:%.*]] = load volatile i32, i32* @G
382ad5a84c8SPhilip Reames; CHECK-NEXT:    [[UNKNOWN:%.*]] = icmp eq i32 [[VOL]], 0
383ad5a84c8SPhilip Reames; CHECK-NEXT:    br i1 [[UNKNOWN]], label [[GUARDED2]], label [[DEOPT3:%.*]], !prof !0
384ad5a84c8SPhilip Reames; CHECK:       deopt3:
385ad5a84c8SPhilip Reames; CHECK-NEXT:    call void @unknown()
386ad5a84c8SPhilip Reames; CHECK-NEXT:    [[DEOPTRET3:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
387ad5a84c8SPhilip Reames; CHECK-NEXT:    ret i32 [[DEOPTRET3]]
388ad5a84c8SPhilip Reames; CHECK:       guarded2:
389ad5a84c8SPhilip Reames; CHECK-NEXT:    [[I_I64:%.*]] = zext i32 [[I]] to i64
390ad5a84c8SPhilip Reames; CHECK-NEXT:    [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
391ad5a84c8SPhilip Reames; CHECK-NEXT:    [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
392ad5a84c8SPhilip Reames; CHECK-NEXT:    store i32 0, i32* [[ARRAY_I_PTR]]
393ad5a84c8SPhilip Reames; CHECK-NEXT:    [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
394ad5a84c8SPhilip Reames; CHECK-NEXT:    [[I_NEXT]] = add nuw i32 [[I]], 1
395ad5a84c8SPhilip Reames; CHECK-NEXT:    [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[N]]
396ad5a84c8SPhilip Reames; CHECK-NEXT:    br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT:%.*]]
397ad5a84c8SPhilip Reames; CHECK:       exit:
398ad5a84c8SPhilip Reames; CHECK-NEXT:    [[RESULT:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED2]] ]
399ad5a84c8SPhilip Reames; CHECK-NEXT:    ret i32 [[RESULT]]
400ad5a84c8SPhilip Reames;
401ad5a84c8SPhilip Reamesentry:
402ad5a84c8SPhilip Reames  %widenable_cond = call i1 @llvm.experimental.widenable.condition()
403ad5a84c8SPhilip Reames  %exiplicit_guard_cond = and i1 %cond_0, %widenable_cond
404ad5a84c8SPhilip Reames  br i1 %exiplicit_guard_cond, label %loop.preheader, label %deopt, !prof !0
405ad5a84c8SPhilip Reames
406ad5a84c8SPhilip Reamesdeopt:
407ad5a84c8SPhilip Reames  %deoptret = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
408ad5a84c8SPhilip Reames  ret i32 %deoptret
409ad5a84c8SPhilip Reames
410ad5a84c8SPhilip Reamesloop.preheader:
411ad5a84c8SPhilip Reames  br label %loop
412ad5a84c8SPhilip Reames
413ad5a84c8SPhilip Reamesloop:
414ad5a84c8SPhilip Reames  %loop.acc = phi i32 [ %loop.acc.next, %guarded2 ], [ 0, %loop.preheader ]
415ad5a84c8SPhilip Reames  %i = phi i32 [ %i.next, %guarded2 ], [ 0, %loop.preheader ]
416ad5a84c8SPhilip Reames  call void @unknown()
417ad5a84c8SPhilip Reames  %within.bounds = icmp ult i32 %i, %length
418ad5a84c8SPhilip Reames  br i1 %within.bounds, label %guarded, label %deopt2, !prof !0
419ad5a84c8SPhilip Reames
420ad5a84c8SPhilip Reamesdeopt2:
421ad5a84c8SPhilip Reames  call void @unknown()
422ad5a84c8SPhilip Reames  %deoptret2 = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
423ad5a84c8SPhilip Reames  ret i32 %deoptret2
424ad5a84c8SPhilip Reames
425ad5a84c8SPhilip Reamesguarded:
426ad5a84c8SPhilip Reames  %vol = load volatile i32, i32* @G
427ad5a84c8SPhilip Reames  %unknown = icmp eq i32 %vol, 0
428ad5a84c8SPhilip Reames  br i1 %unknown, label %guarded2, label %deopt3, !prof !0
429ad5a84c8SPhilip Reames
430ad5a84c8SPhilip Reamesdeopt3:
431ad5a84c8SPhilip Reames  call void @unknown()
432ad5a84c8SPhilip Reames  %deoptret3 = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
433ad5a84c8SPhilip Reames  ret i32 %deoptret3
434ad5a84c8SPhilip Reames
435ad5a84c8SPhilip Reamesguarded2:
436ad5a84c8SPhilip Reames  %i.i64 = zext i32 %i to i64
437ad5a84c8SPhilip Reames  %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
438ad5a84c8SPhilip Reames  %array.i = load i32, i32* %array.i.ptr, align 4
439ad5a84c8SPhilip Reames  store i32 0, i32* %array.i.ptr
440ad5a84c8SPhilip Reames  %loop.acc.next = add i32 %loop.acc, %array.i
441ad5a84c8SPhilip Reames  %i.next = add nuw i32 %i, 1
442ad5a84c8SPhilip Reames  %continue = icmp ult i32 %i.next, %n
443ad5a84c8SPhilip Reames  br i1 %continue, label %loop, label %exit
444ad5a84c8SPhilip Reames
445ad5a84c8SPhilip Reamesexit:
446ad5a84c8SPhilip Reames  %result = phi i32 [ %loop.acc.next, %guarded2 ]
447ad5a84c8SPhilip Reames  ret i32 %result
448ad5a84c8SPhilip Reames}
449ad5a84c8SPhilip Reames
450ad5a84c8SPhilip Reames
451ad5a84c8SPhilip Reamesdefine i32 @test_unanalyzeable_latch(i32* %array, i32 %length, i32 %n, i1 %cond_0) {
452ad5a84c8SPhilip Reames; CHECK-LABEL: @test_unanalyzeable_latch(
453ad5a84c8SPhilip Reames; CHECK-NEXT:  entry:
454ad5a84c8SPhilip Reames; CHECK-NEXT:    [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
455ad5a84c8SPhilip Reames; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[COND_0:%.*]], [[WIDENABLE_COND]]
456ad5a84c8SPhilip Reames; CHECK-NEXT:    br i1 [[EXIPLICIT_GUARD_COND]], label [[LOOP_PREHEADER:%.*]], label [[DEOPT:%.*]], !prof !0
457ad5a84c8SPhilip Reames; CHECK:       deopt:
458ad5a84c8SPhilip Reames; CHECK-NEXT:    [[DEOPTRET:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
459ad5a84c8SPhilip Reames; CHECK-NEXT:    ret i32 [[DEOPTRET]]
460ad5a84c8SPhilip Reames; CHECK:       loop.preheader:
461ad5a84c8SPhilip Reames; CHECK-NEXT:    br label [[LOOP:%.*]]
462ad5a84c8SPhilip Reames; CHECK:       loop:
463ad5a84c8SPhilip Reames; CHECK-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
464ad5a84c8SPhilip Reames; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ]
465ad5a84c8SPhilip Reames; CHECK-NEXT:    call void @unknown()
466ad5a84c8SPhilip Reames; CHECK-NEXT:    [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH:%.*]]
467ad5a84c8SPhilip Reames; CHECK-NEXT:    br i1 [[WITHIN_BOUNDS]], label [[GUARDED]], label [[DEOPT2:%.*]], !prof !0
468ad5a84c8SPhilip Reames; CHECK:       deopt2:
469ad5a84c8SPhilip Reames; CHECK-NEXT:    call void @unknown()
470ad5a84c8SPhilip Reames; CHECK-NEXT:    [[DEOPTRET2:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
471ad5a84c8SPhilip Reames; CHECK-NEXT:    ret i32 [[DEOPTRET2]]
472ad5a84c8SPhilip Reames; CHECK:       guarded:
473ad5a84c8SPhilip Reames; CHECK-NEXT:    [[I_I64:%.*]] = zext i32 [[I]] to i64
474ad5a84c8SPhilip Reames; CHECK-NEXT:    [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
475ad5a84c8SPhilip Reames; CHECK-NEXT:    [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
476ad5a84c8SPhilip Reames; CHECK-NEXT:    store i32 0, i32* [[ARRAY_I_PTR]]
477ad5a84c8SPhilip Reames; CHECK-NEXT:    [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
478ad5a84c8SPhilip Reames; CHECK-NEXT:    [[I_NEXT]] = add nuw i32 [[I]], 1
479ad5a84c8SPhilip Reames; CHECK-NEXT:    [[VOL:%.*]] = load volatile i32, i32* @G
480ad5a84c8SPhilip Reames; CHECK-NEXT:    [[UNKNOWN:%.*]] = icmp eq i32 [[VOL]], 0
481ad5a84c8SPhilip Reames; CHECK-NEXT:    br i1 [[UNKNOWN]], label [[LOOP]], label [[EXIT:%.*]]
482ad5a84c8SPhilip Reames; CHECK:       exit:
483ad5a84c8SPhilip Reames; CHECK-NEXT:    [[RESULT:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ]
484ad5a84c8SPhilip Reames; CHECK-NEXT:    ret i32 [[RESULT]]
485ad5a84c8SPhilip Reames;
486ad5a84c8SPhilip Reamesentry:
487ad5a84c8SPhilip Reames  %widenable_cond = call i1 @llvm.experimental.widenable.condition()
488ad5a84c8SPhilip Reames  %exiplicit_guard_cond = and i1 %cond_0, %widenable_cond
489ad5a84c8SPhilip Reames  br i1 %exiplicit_guard_cond, label %loop.preheader, label %deopt, !prof !0
490ad5a84c8SPhilip Reames
491ad5a84c8SPhilip Reamesdeopt:
492ad5a84c8SPhilip Reames  %deoptret = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
493ad5a84c8SPhilip Reames  ret i32 %deoptret
494ad5a84c8SPhilip Reames
495ad5a84c8SPhilip Reamesloop.preheader:
496ad5a84c8SPhilip Reames  br label %loop
497ad5a84c8SPhilip Reames
498ad5a84c8SPhilip Reamesloop:
499ad5a84c8SPhilip Reames  %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ]
500ad5a84c8SPhilip Reames  %i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ]
501ad5a84c8SPhilip Reames  call void @unknown()
502ad5a84c8SPhilip Reames  %within.bounds = icmp ult i32 %i, %length
503ad5a84c8SPhilip Reames  br i1 %within.bounds, label %guarded, label %deopt2, !prof !0
504ad5a84c8SPhilip Reames
505ad5a84c8SPhilip Reamesdeopt2:
506ad5a84c8SPhilip Reames  call void @unknown()
507ad5a84c8SPhilip Reames  %deoptret2 = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
508ad5a84c8SPhilip Reames  ret i32 %deoptret2
509ad5a84c8SPhilip Reames
510ad5a84c8SPhilip Reamesguarded:
511ad5a84c8SPhilip Reames  %i.i64 = zext i32 %i to i64
512ad5a84c8SPhilip Reames  %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
513ad5a84c8SPhilip Reames  %array.i = load i32, i32* %array.i.ptr, align 4
514ad5a84c8SPhilip Reames  store i32 0, i32* %array.i.ptr
515ad5a84c8SPhilip Reames  %loop.acc.next = add i32 %loop.acc, %array.i
516ad5a84c8SPhilip Reames  %i.next = add nuw i32 %i, 1
517ad5a84c8SPhilip Reames  %vol = load volatile i32, i32* @G
518ad5a84c8SPhilip Reames  %unknown = icmp eq i32 %vol, 0
519ad5a84c8SPhilip Reames  br i1 %unknown, label %loop, label %exit
520ad5a84c8SPhilip Reames
521ad5a84c8SPhilip Reamesexit:
522ad5a84c8SPhilip Reames  %result = phi i32 [ %loop.acc.next, %guarded ]
523ad5a84c8SPhilip Reames  ret i32 %result
524ad5a84c8SPhilip Reames}
525ad5a84c8SPhilip Reames
526ad5a84c8SPhilip Reames
527ad5a84c8SPhilip Reamesdefine i32 @provably_taken(i32* %array, i1 %cond_0) {
528ad5a84c8SPhilip Reames; CHECK-LABEL: @provably_taken(
529ad5a84c8SPhilip Reames; CHECK-NEXT:  entry:
530ad5a84c8SPhilip Reames; CHECK-NEXT:    [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
531ad5a84c8SPhilip Reames; CHECK-NEXT:    [[TMP0:%.*]] = freeze i1 false
532ad5a84c8SPhilip Reames; CHECK-NEXT:    [[TMP1:%.*]] = and i1 [[TMP0]], [[COND_0:%.*]]
533ad5a84c8SPhilip Reames; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[TMP1]], [[WIDENABLE_COND]]
534ad5a84c8SPhilip Reames; CHECK-NEXT:    br i1 [[EXIPLICIT_GUARD_COND]], label [[LOOP_PREHEADER:%.*]], label [[DEOPT:%.*]], !prof !0
535ad5a84c8SPhilip Reames; CHECK:       deopt:
536ad5a84c8SPhilip Reames; CHECK-NEXT:    [[DEOPTRET:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
537ad5a84c8SPhilip Reames; CHECK-NEXT:    ret i32 [[DEOPTRET]]
538ad5a84c8SPhilip Reames; CHECK:       loop.preheader:
539ad5a84c8SPhilip Reames; CHECK-NEXT:    br label [[LOOP:%.*]]
540ad5a84c8SPhilip Reames; CHECK:       loop:
541ad5a84c8SPhilip Reames; CHECK-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
542ad5a84c8SPhilip Reames; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ]
543ad5a84c8SPhilip Reames; CHECK-NEXT:    call void @unknown()
544ad5a84c8SPhilip Reames; CHECK-NEXT:    [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], 198
545ad5a84c8SPhilip Reames; CHECK-NEXT:    br i1 true, label [[GUARDED]], label [[DEOPT2:%.*]], !prof !0
546ad5a84c8SPhilip Reames; CHECK:       deopt2:
547ad5a84c8SPhilip Reames; CHECK-NEXT:    call void @unknown()
548ad5a84c8SPhilip Reames; CHECK-NEXT:    [[DEOPTRET2:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
549ad5a84c8SPhilip Reames; CHECK-NEXT:    ret i32 [[DEOPTRET2]]
550ad5a84c8SPhilip Reames; CHECK:       guarded:
551ad5a84c8SPhilip Reames; CHECK-NEXT:    [[I_I64:%.*]] = zext i32 [[I]] to i64
552ad5a84c8SPhilip Reames; CHECK-NEXT:    [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
553ad5a84c8SPhilip Reames; CHECK-NEXT:    [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
554ad5a84c8SPhilip Reames; CHECK-NEXT:    store i32 0, i32* [[ARRAY_I_PTR]]
555ad5a84c8SPhilip Reames; CHECK-NEXT:    [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
556ad5a84c8SPhilip Reames; CHECK-NEXT:    [[I_NEXT]] = add nuw i32 [[I]], 1
557ad5a84c8SPhilip Reames; CHECK-NEXT:    [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], 200
558ad5a84c8SPhilip Reames; CHECK-NEXT:    br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT:%.*]]
559ad5a84c8SPhilip Reames; CHECK:       exit:
560ad5a84c8SPhilip Reames; CHECK-NEXT:    [[RESULT:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ]
561ad5a84c8SPhilip Reames; CHECK-NEXT:    ret i32 [[RESULT]]
562ad5a84c8SPhilip Reames;
563ad5a84c8SPhilip Reamesentry:
564ad5a84c8SPhilip Reames  %widenable_cond = call i1 @llvm.experimental.widenable.condition()
565ad5a84c8SPhilip Reames  %exiplicit_guard_cond = and i1 %cond_0, %widenable_cond
566ad5a84c8SPhilip Reames  br i1 %exiplicit_guard_cond, label %loop.preheader, label %deopt, !prof !0
567ad5a84c8SPhilip Reames
568ad5a84c8SPhilip Reamesdeopt:
569ad5a84c8SPhilip Reames  %deoptret = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
570ad5a84c8SPhilip Reames  ret i32 %deoptret
571ad5a84c8SPhilip Reames
572ad5a84c8SPhilip Reamesloop.preheader:
573ad5a84c8SPhilip Reames  br label %loop
574ad5a84c8SPhilip Reames
575ad5a84c8SPhilip Reamesloop:
576ad5a84c8SPhilip Reames  %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ]
577ad5a84c8SPhilip Reames  %i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ]
578ad5a84c8SPhilip Reames  call void @unknown()
579ad5a84c8SPhilip Reames  %within.bounds = icmp ult i32 %i, 198
580ad5a84c8SPhilip Reames  br i1 %within.bounds, label %guarded, label %deopt2, !prof !0
581ad5a84c8SPhilip Reames
582ad5a84c8SPhilip Reamesdeopt2:
583ad5a84c8SPhilip Reames  call void @unknown()
584ad5a84c8SPhilip Reames  %deoptret2 = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
585ad5a84c8SPhilip Reames  ret i32 %deoptret2
586ad5a84c8SPhilip Reames
587ad5a84c8SPhilip Reamesguarded:
588ad5a84c8SPhilip Reames  %i.i64 = zext i32 %i to i64
589ad5a84c8SPhilip Reames  %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
590ad5a84c8SPhilip Reames  %array.i = load i32, i32* %array.i.ptr, align 4
591ad5a84c8SPhilip Reames  store i32 0, i32* %array.i.ptr
592ad5a84c8SPhilip Reames  %loop.acc.next = add i32 %loop.acc, %array.i
593ad5a84c8SPhilip Reames  %i.next = add nuw i32 %i, 1
594ad5a84c8SPhilip Reames  %continue = icmp ult i32 %i.next, 200
595ad5a84c8SPhilip Reames  br i1 %continue, label %loop, label %exit
596ad5a84c8SPhilip Reames
597ad5a84c8SPhilip Reamesexit:
598ad5a84c8SPhilip Reames  %result = phi i32 [ %loop.acc.next, %guarded ]
599ad5a84c8SPhilip Reames  ret i32 %result
600ad5a84c8SPhilip Reames}
601ad5a84c8SPhilip Reames
602ad5a84c8SPhilip Reamesdefine i32 @provably_not_taken(i32* %array, i1 %cond_0) {
603ad5a84c8SPhilip Reames; CHECK-LABEL: @provably_not_taken(
604ad5a84c8SPhilip Reames; CHECK-NEXT:  entry:
605ad5a84c8SPhilip Reames; CHECK-NEXT:    [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
606ad5a84c8SPhilip Reames; CHECK-NEXT:    [[TMP0:%.*]] = freeze i1 true
607ad5a84c8SPhilip Reames; CHECK-NEXT:    [[TMP1:%.*]] = and i1 [[TMP0]], [[COND_0:%.*]]
608ad5a84c8SPhilip Reames; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[TMP1]], [[WIDENABLE_COND]]
609ad5a84c8SPhilip Reames; CHECK-NEXT:    br i1 [[EXIPLICIT_GUARD_COND]], label [[LOOP_PREHEADER:%.*]], label [[DEOPT:%.*]], !prof !0
610ad5a84c8SPhilip Reames; CHECK:       deopt:
611ad5a84c8SPhilip Reames; CHECK-NEXT:    [[DEOPTRET:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
612ad5a84c8SPhilip Reames; CHECK-NEXT:    ret i32 [[DEOPTRET]]
613ad5a84c8SPhilip Reames; CHECK:       loop.preheader:
614ad5a84c8SPhilip Reames; CHECK-NEXT:    br label [[LOOP:%.*]]
615ad5a84c8SPhilip Reames; CHECK:       loop:
616ad5a84c8SPhilip Reames; CHECK-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
617ad5a84c8SPhilip Reames; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ]
618ad5a84c8SPhilip Reames; CHECK-NEXT:    call void @unknown()
619ad5a84c8SPhilip Reames; CHECK-NEXT:    [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], 205
620ad5a84c8SPhilip Reames; CHECK-NEXT:    br i1 true, label [[GUARDED]], label [[DEOPT2:%.*]], !prof !0
621ad5a84c8SPhilip Reames; CHECK:       deopt2:
622ad5a84c8SPhilip Reames; CHECK-NEXT:    call void @unknown()
623ad5a84c8SPhilip Reames; CHECK-NEXT:    [[DEOPTRET2:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
624ad5a84c8SPhilip Reames; CHECK-NEXT:    ret i32 [[DEOPTRET2]]
625ad5a84c8SPhilip Reames; CHECK:       guarded:
626ad5a84c8SPhilip Reames; CHECK-NEXT:    [[I_I64:%.*]] = zext i32 [[I]] to i64
627ad5a84c8SPhilip Reames; CHECK-NEXT:    [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
628ad5a84c8SPhilip Reames; CHECK-NEXT:    [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
629ad5a84c8SPhilip Reames; CHECK-NEXT:    store i32 0, i32* [[ARRAY_I_PTR]]
630ad5a84c8SPhilip Reames; CHECK-NEXT:    [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
631ad5a84c8SPhilip Reames; CHECK-NEXT:    [[I_NEXT]] = add nuw i32 [[I]], 1
632ad5a84c8SPhilip Reames; CHECK-NEXT:    [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], 200
633ad5a84c8SPhilip Reames; CHECK-NEXT:    br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT:%.*]]
634ad5a84c8SPhilip Reames; CHECK:       exit:
635ad5a84c8SPhilip Reames; CHECK-NEXT:    [[RESULT:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ]
636ad5a84c8SPhilip Reames; CHECK-NEXT:    ret i32 [[RESULT]]
637ad5a84c8SPhilip Reames;
638ad5a84c8SPhilip Reamesentry:
639ad5a84c8SPhilip Reames  %widenable_cond = call i1 @llvm.experimental.widenable.condition()
640ad5a84c8SPhilip Reames  %exiplicit_guard_cond = and i1 %cond_0, %widenable_cond
641ad5a84c8SPhilip Reames  br i1 %exiplicit_guard_cond, label %loop.preheader, label %deopt, !prof !0
642ad5a84c8SPhilip Reames
643ad5a84c8SPhilip Reamesdeopt:
644ad5a84c8SPhilip Reames  %deoptret = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
645ad5a84c8SPhilip Reames  ret i32 %deoptret
646ad5a84c8SPhilip Reames
647ad5a84c8SPhilip Reamesloop.preheader:
648ad5a84c8SPhilip Reames  br label %loop
649ad5a84c8SPhilip Reames
650ad5a84c8SPhilip Reamesloop:
651ad5a84c8SPhilip Reames  %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ]
652ad5a84c8SPhilip Reames  %i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ]
653ad5a84c8SPhilip Reames  call void @unknown()
654ad5a84c8SPhilip Reames  %within.bounds = icmp ult i32 %i, 205
655ad5a84c8SPhilip Reames  br i1 %within.bounds, label %guarded, label %deopt2, !prof !0
656ad5a84c8SPhilip Reames
657ad5a84c8SPhilip Reamesdeopt2:
658ad5a84c8SPhilip Reames  call void @unknown()
659ad5a84c8SPhilip Reames  %deoptret2 = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
660ad5a84c8SPhilip Reames  ret i32 %deoptret2
661ad5a84c8SPhilip Reames
662ad5a84c8SPhilip Reamesguarded:
663ad5a84c8SPhilip Reames  %i.i64 = zext i32 %i to i64
664ad5a84c8SPhilip Reames  %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
665ad5a84c8SPhilip Reames  %array.i = load i32, i32* %array.i.ptr, align 4
666ad5a84c8SPhilip Reames  store i32 0, i32* %array.i.ptr
667ad5a84c8SPhilip Reames  %loop.acc.next = add i32 %loop.acc, %array.i
668ad5a84c8SPhilip Reames  %i.next = add nuw i32 %i, 1
669ad5a84c8SPhilip Reames  %continue = icmp ult i32 %i.next, 200
670ad5a84c8SPhilip Reames  br i1 %continue, label %loop, label %exit
671ad5a84c8SPhilip Reames
672ad5a84c8SPhilip Reamesexit:
673ad5a84c8SPhilip Reames  %result = phi i32 [ %loop.acc.next, %guarded ]
674ad5a84c8SPhilip Reames  ret i32 %result
675ad5a84c8SPhilip Reames}
676ad5a84c8SPhilip Reames
677ad5a84c8SPhilip Reames
678*f3eb5deeSPhilip Reames;; Unswitch likes to produce some ugly exit blocks without simplifications
679*f3eb5deeSPhilip Reames;; being applied.  Make sure we can handle that form.
680*f3eb5deeSPhilip Reamesdefine i32 @unswitch_exit_form(i32* %array, i32 %length, i32 %n, i1 %cond_0) {
681*f3eb5deeSPhilip Reames; CHECK-LABEL: @unswitch_exit_form(
682*f3eb5deeSPhilip Reames; CHECK-NEXT:  entry:
683*f3eb5deeSPhilip Reames; CHECK-NEXT:    [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
684*f3eb5deeSPhilip Reames; CHECK-NEXT:    [[TMP0:%.*]] = icmp ugt i32 [[N:%.*]], 1
685*f3eb5deeSPhilip Reames; CHECK-NEXT:    [[UMAX:%.*]] = select i1 [[TMP0]], i32 [[N]], i32 1
686*f3eb5deeSPhilip Reames; CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[UMAX]], -1
687*f3eb5deeSPhilip Reames; CHECK-NEXT:    [[TMP2:%.*]] = icmp ult i32 [[LENGTH:%.*]], [[TMP1]]
688*f3eb5deeSPhilip Reames; CHECK-NEXT:    [[UMIN:%.*]] = select i1 [[TMP2]], i32 [[LENGTH]], i32 [[TMP1]]
689*f3eb5deeSPhilip Reames; CHECK-NEXT:    [[TMP3:%.*]] = icmp ugt i32 [[LENGTH]], [[UMIN]]
690*f3eb5deeSPhilip Reames; CHECK-NEXT:    [[TMP4:%.*]] = freeze i1 [[TMP3]]
691*f3eb5deeSPhilip Reames; CHECK-NEXT:    [[TMP5:%.*]] = and i1 [[TMP4]], [[COND_0:%.*]]
692*f3eb5deeSPhilip Reames; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[TMP5]], [[WIDENABLE_COND]]
693*f3eb5deeSPhilip Reames; CHECK-NEXT:    br i1 [[EXIPLICIT_GUARD_COND]], label [[LOOP_PREHEADER:%.*]], label [[DEOPT:%.*]], !prof !0
694*f3eb5deeSPhilip Reames; CHECK:       deopt.loopexit:
695*f3eb5deeSPhilip Reames; CHECK-NEXT:    br label [[DEOPT]]
696*f3eb5deeSPhilip Reames; CHECK:       deopt:
697*f3eb5deeSPhilip Reames; CHECK-NEXT:    [[PHI:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ 1, [[DEOPT_LOOPEXIT:%.*]] ]
698*f3eb5deeSPhilip Reames; CHECK-NEXT:    call void @unknown()
699*f3eb5deeSPhilip Reames; CHECK-NEXT:    br label [[ACTUAL_DEOPT:%.*]]
700*f3eb5deeSPhilip Reames; CHECK:       actual_deopt:
701*f3eb5deeSPhilip Reames; CHECK-NEXT:    [[DEOPTRET:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"(i32 [[PHI]]) ]
702*f3eb5deeSPhilip Reames; CHECK-NEXT:    ret i32 [[DEOPTRET]]
703*f3eb5deeSPhilip Reames; CHECK:       loop.preheader:
704*f3eb5deeSPhilip Reames; CHECK-NEXT:    br label [[LOOP:%.*]]
705*f3eb5deeSPhilip Reames; CHECK:       loop:
706*f3eb5deeSPhilip Reames; CHECK-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
707*f3eb5deeSPhilip Reames; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ]
708*f3eb5deeSPhilip Reames; CHECK-NEXT:    call void @unknown()
709*f3eb5deeSPhilip Reames; CHECK-NEXT:    [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH]]
710*f3eb5deeSPhilip Reames; CHECK-NEXT:    br i1 true, label [[GUARDED]], label [[DEOPT_LOOPEXIT]], !prof !0
711*f3eb5deeSPhilip Reames; CHECK:       guarded:
712*f3eb5deeSPhilip Reames; CHECK-NEXT:    [[I_I64:%.*]] = zext i32 [[I]] to i64
713*f3eb5deeSPhilip Reames; CHECK-NEXT:    [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
714*f3eb5deeSPhilip Reames; CHECK-NEXT:    [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
715*f3eb5deeSPhilip Reames; CHECK-NEXT:    store i32 0, i32* [[ARRAY_I_PTR]]
716*f3eb5deeSPhilip Reames; CHECK-NEXT:    [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
717*f3eb5deeSPhilip Reames; CHECK-NEXT:    [[I_NEXT]] = add nuw i32 [[I]], 1
718*f3eb5deeSPhilip Reames; CHECK-NEXT:    [[CONTINUE:%.*]] = icmp ult i32 [[I_NEXT]], [[N]]
719*f3eb5deeSPhilip Reames; CHECK-NEXT:    br i1 [[CONTINUE]], label [[LOOP]], label [[EXIT:%.*]]
720*f3eb5deeSPhilip Reames; CHECK:       exit:
721*f3eb5deeSPhilip Reames; CHECK-NEXT:    [[RESULT:%.*]] = phi i32 [ [[LOOP_ACC_NEXT]], [[GUARDED]] ]
722*f3eb5deeSPhilip Reames; CHECK-NEXT:    ret i32 [[RESULT]]
723*f3eb5deeSPhilip Reames;
724*f3eb5deeSPhilip Reamesentry:
725*f3eb5deeSPhilip Reames  %widenable_cond = call i1 @llvm.experimental.widenable.condition()
726*f3eb5deeSPhilip Reames  %exiplicit_guard_cond = and i1 %cond_0, %widenable_cond
727*f3eb5deeSPhilip Reames  br i1 %exiplicit_guard_cond, label %loop.preheader, label %deopt, !prof !0
728ad5a84c8SPhilip Reames
729*f3eb5deeSPhilip Reamesdeopt:
730*f3eb5deeSPhilip Reames  ;; This is written to look like an unsimplified loop exit after unswitch
731*f3eb5deeSPhilip Reames  ;; (i.e. phis, merge, and branch to actual block)
732*f3eb5deeSPhilip Reames  %phi = phi i32 [0, %entry], [1, %loop]
733*f3eb5deeSPhilip Reames  call void @unknown() ;; it's okay to skip possible throws
734*f3eb5deeSPhilip Reames  br label %actual_deopt
735ad5a84c8SPhilip Reames
736*f3eb5deeSPhilip Reamesactual_deopt:
737*f3eb5deeSPhilip Reames  %deoptret = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"(i32 %phi) ]
738*f3eb5deeSPhilip Reames  ret i32 %deoptret
739ad5a84c8SPhilip Reames
740*f3eb5deeSPhilip Reamesloop.preheader:
741*f3eb5deeSPhilip Reames  br label %loop
742ad5a84c8SPhilip Reames
743*f3eb5deeSPhilip Reamesloop:
744*f3eb5deeSPhilip Reames  %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ]
745*f3eb5deeSPhilip Reames  %i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ]
746*f3eb5deeSPhilip Reames  call void @unknown()
747*f3eb5deeSPhilip Reames  %within.bounds = icmp ult i32 %i, %length
748*f3eb5deeSPhilip Reames  br i1 %within.bounds, label %guarded, label %deopt, !prof !0
749ad5a84c8SPhilip Reames
750*f3eb5deeSPhilip Reamesguarded:
751*f3eb5deeSPhilip Reames  %i.i64 = zext i32 %i to i64
752*f3eb5deeSPhilip Reames  %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
753*f3eb5deeSPhilip Reames  %array.i = load i32, i32* %array.i.ptr, align 4
754*f3eb5deeSPhilip Reames  store i32 0, i32* %array.i.ptr
755*f3eb5deeSPhilip Reames  %loop.acc.next = add i32 %loop.acc, %array.i
756*f3eb5deeSPhilip Reames  %i.next = add nuw i32 %i, 1
757*f3eb5deeSPhilip Reames  %continue = icmp ult i32 %i.next, %n
758*f3eb5deeSPhilip Reames  br i1 %continue, label %loop, label %exit
759*f3eb5deeSPhilip Reames
760*f3eb5deeSPhilip Reamesexit:
761*f3eb5deeSPhilip Reames  %result = phi i32 [ %loop.acc.next, %guarded ]
762*f3eb5deeSPhilip Reames  ret i32 %result
763*f3eb5deeSPhilip Reames}
764ad5a84c8SPhilip Reames
765ad5a84c8SPhilip Reames; TODO: Non-latch exits can still be predicated
766ad5a84c8SPhilip Reames; This is currently prevented by an overly restrictive profitability check.
767ad5a84c8SPhilip Reamesdefine i32 @todo_unconditional_latch(i32* %array, i32 %length, i1 %cond_0) {
768ad5a84c8SPhilip Reames; CHECK-LABEL: @todo_unconditional_latch(
769ad5a84c8SPhilip Reames; CHECK-NEXT:  entry:
770ad5a84c8SPhilip Reames; CHECK-NEXT:    [[WIDENABLE_COND:%.*]] = call i1 @llvm.experimental.widenable.condition()
771ad5a84c8SPhilip Reames; CHECK-NEXT:    [[EXIPLICIT_GUARD_COND:%.*]] = and i1 [[COND_0:%.*]], [[WIDENABLE_COND]]
772ad5a84c8SPhilip Reames; CHECK-NEXT:    br i1 [[EXIPLICIT_GUARD_COND]], label [[LOOP_PREHEADER:%.*]], label [[DEOPT:%.*]], !prof !0
773ad5a84c8SPhilip Reames; CHECK:       deopt:
774ad5a84c8SPhilip Reames; CHECK-NEXT:    [[DEOPTRET:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
775ad5a84c8SPhilip Reames; CHECK-NEXT:    ret i32 [[DEOPTRET]]
776ad5a84c8SPhilip Reames; CHECK:       loop.preheader:
777ad5a84c8SPhilip Reames; CHECK-NEXT:    br label [[LOOP:%.*]]
778ad5a84c8SPhilip Reames; CHECK:       loop:
779ad5a84c8SPhilip Reames; CHECK-NEXT:    [[LOOP_ACC:%.*]] = phi i32 [ [[LOOP_ACC_NEXT:%.*]], [[GUARDED:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
780ad5a84c8SPhilip Reames; CHECK-NEXT:    [[I:%.*]] = phi i32 [ [[I_NEXT:%.*]], [[GUARDED]] ], [ 0, [[LOOP_PREHEADER]] ]
781ad5a84c8SPhilip Reames; CHECK-NEXT:    call void @unknown()
782ad5a84c8SPhilip Reames; CHECK-NEXT:    [[WITHIN_BOUNDS:%.*]] = icmp ult i32 [[I]], [[LENGTH:%.*]]
783ad5a84c8SPhilip Reames; CHECK-NEXT:    br i1 [[WITHIN_BOUNDS]], label [[GUARDED]], label [[DEOPT2:%.*]], !prof !0
784ad5a84c8SPhilip Reames; CHECK:       deopt2:
785ad5a84c8SPhilip Reames; CHECK-NEXT:    call void @unknown()
786ad5a84c8SPhilip Reames; CHECK-NEXT:    [[DEOPTRET2:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
787ad5a84c8SPhilip Reames; CHECK-NEXT:    ret i32 [[DEOPTRET2]]
788ad5a84c8SPhilip Reames; CHECK:       guarded:
789ad5a84c8SPhilip Reames; CHECK-NEXT:    [[I_I64:%.*]] = zext i32 [[I]] to i64
790ad5a84c8SPhilip Reames; CHECK-NEXT:    [[ARRAY_I_PTR:%.*]] = getelementptr inbounds i32, i32* [[ARRAY:%.*]], i64 [[I_I64]]
791ad5a84c8SPhilip Reames; CHECK-NEXT:    [[ARRAY_I:%.*]] = load i32, i32* [[ARRAY_I_PTR]], align 4
792ad5a84c8SPhilip Reames; CHECK-NEXT:    store i32 0, i32* [[ARRAY_I_PTR]]
793ad5a84c8SPhilip Reames; CHECK-NEXT:    [[LOOP_ACC_NEXT]] = add i32 [[LOOP_ACC]], [[ARRAY_I]]
794ad5a84c8SPhilip Reames; CHECK-NEXT:    [[I_NEXT]] = add nuw i32 [[I]], 1
795ad5a84c8SPhilip Reames; CHECK-NEXT:    br label [[LOOP]]
796ad5a84c8SPhilip Reames;
797ad5a84c8SPhilip Reamesentry:
798ad5a84c8SPhilip Reames  %widenable_cond = call i1 @llvm.experimental.widenable.condition()
799ad5a84c8SPhilip Reames  %exiplicit_guard_cond = and i1 %cond_0, %widenable_cond
800ad5a84c8SPhilip Reames  br i1 %exiplicit_guard_cond, label %loop.preheader, label %deopt, !prof !0
801ad5a84c8SPhilip Reames
802ad5a84c8SPhilip Reamesdeopt:
803ad5a84c8SPhilip Reames  %deoptret = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
804ad5a84c8SPhilip Reames  ret i32 %deoptret
805ad5a84c8SPhilip Reames
806ad5a84c8SPhilip Reamesloop.preheader:
807ad5a84c8SPhilip Reames  br label %loop
808ad5a84c8SPhilip Reames
809ad5a84c8SPhilip Reamesloop:
810ad5a84c8SPhilip Reames  %loop.acc = phi i32 [ %loop.acc.next, %guarded ], [ 0, %loop.preheader ]
811ad5a84c8SPhilip Reames  %i = phi i32 [ %i.next, %guarded ], [ 0, %loop.preheader ]
812ad5a84c8SPhilip Reames  call void @unknown()
813ad5a84c8SPhilip Reames  %within.bounds = icmp ult i32 %i, %length
814ad5a84c8SPhilip Reames  br i1 %within.bounds, label %guarded, label %deopt2, !prof !0
815ad5a84c8SPhilip Reames
816ad5a84c8SPhilip Reamesdeopt2:
817ad5a84c8SPhilip Reames  call void @unknown()
818ad5a84c8SPhilip Reames  %deoptret2 = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"() ]
819ad5a84c8SPhilip Reames  ret i32 %deoptret2
820ad5a84c8SPhilip Reames
821ad5a84c8SPhilip Reamesguarded:
822ad5a84c8SPhilip Reames  %i.i64 = zext i32 %i to i64
823ad5a84c8SPhilip Reames  %array.i.ptr = getelementptr inbounds i32, i32* %array, i64 %i.i64
824ad5a84c8SPhilip Reames  %array.i = load i32, i32* %array.i.ptr, align 4
825ad5a84c8SPhilip Reames  store i32 0, i32* %array.i.ptr
826ad5a84c8SPhilip Reames  %loop.acc.next = add i32 %loop.acc, %array.i
827ad5a84c8SPhilip Reames  %i.next = add nuw i32 %i, 1
828ad5a84c8SPhilip Reames  br label %loop
829ad5a84c8SPhilip Reames}
830ad5a84c8SPhilip Reames
831ad5a84c8SPhilip Reames
832ad5a84c8SPhilip Reamesdeclare void @unknown()
833ad5a84c8SPhilip Reames
834ad5a84c8SPhilip Reamesdeclare i1 @llvm.experimental.widenable.condition()
835ad5a84c8SPhilip Reamesdeclare i32 @llvm.experimental.deoptimize.i32(...)
836ad5a84c8SPhilip Reames
837ad5a84c8SPhilip Reames!0 = !{!"branch_weights", i32 1048576, i32 1}
838ad5a84c8SPhilip Reames!1 = !{i32 1, i32 -2147483648}
839ad5a84c8SPhilip Reames!2 = !{i32 0, i32 50}
840