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