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