1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
2 ; RUN: opt -p loop-vectorize -force-vector-width=2 -use-dereferenceable-at-point-semantics -S %s | FileCheck %s
4 declare void @llvm.assume(i1)
6 define void @deref_assumption_in_header_constant_trip_count(ptr noalias %a, ptr noalias %b, ptr noalias %c) nofree nosync{
7 ; CHECK-LABEL: define void @deref_assumption_in_header_constant_trip_count(
8 ; CHECK-SAME: ptr noalias [[A:%.*]], ptr noalias [[B:%.*]], ptr noalias [[C:%.*]]) #[[ATTR1:[0-9]+]] {
9 ; CHECK-NEXT: [[ENTRY:.*]]:
10 ; CHECK-NEXT: br i1 false, label %[[SCALAR_PH:.*]], label %[[VECTOR_PH:.*]]
11 ; CHECK: [[VECTOR_PH]]:
12 ; CHECK-NEXT: br label %[[VECTOR_BODY:.*]]
13 ; CHECK: [[VECTOR_BODY]]:
14 ; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, %[[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], %[[PRED_LOAD_CONTINUE2:.*]] ]
15 ; CHECK-NEXT: [[VEC_IND:%.*]] = phi <2 x i64> [ <i64 0, i64 1>, %[[VECTOR_PH]] ], [ [[VEC_IND_NEXT:%.*]], %[[PRED_LOAD_CONTINUE2]] ]
16 ; CHECK-NEXT: [[TMP0:%.*]] = add i64 [[INDEX]], 0
17 ; CHECK-NEXT: [[TMP1:%.*]] = getelementptr i32, ptr [[A]], <2 x i64> [[VEC_IND]]
18 ; CHECK-NEXT: [[TMP4:%.*]] = extractelement <2 x ptr> [[TMP1]], i32 0
19 ; CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[TMP4]], i64 4), "dereferenceable"(ptr [[TMP4]], i64 4) ]
20 ; CHECK-NEXT: [[TMP5:%.*]] = extractelement <2 x ptr> [[TMP1]], i32 1
21 ; CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[TMP5]], i64 4), "dereferenceable"(ptr [[TMP5]], i64 4) ]
22 ; CHECK-NEXT: [[TMP6:%.*]] = getelementptr inbounds i32, ptr [[B]], i64 [[TMP0]]
23 ; CHECK-NEXT: [[TMP7:%.*]] = getelementptr inbounds i32, ptr [[TMP6]], i32 0
24 ; CHECK-NEXT: [[WIDE_LOAD:%.*]] = load <2 x i32>, ptr [[TMP7]], align 4
25 ; CHECK-NEXT: [[TMP9:%.*]] = icmp sge <2 x i32> [[WIDE_LOAD]], zeroinitializer
26 ; CHECK-NEXT: [[TMP10:%.*]] = xor <2 x i1> [[TMP9]], splat (i1 true)
27 ; CHECK-NEXT: [[TMP8:%.*]] = extractelement <2 x i1> [[TMP10]], i32 0
28 ; CHECK-NEXT: br i1 [[TMP8]], label %[[PRED_LOAD_IF:.*]], label %[[PRED_LOAD_CONTINUE:.*]]
29 ; CHECK: [[PRED_LOAD_IF]]:
30 ; CHECK-NEXT: [[TMP21:%.*]] = extractelement <2 x ptr> [[TMP1]], i32 0
31 ; CHECK-NEXT: [[TMP22:%.*]] = load i32, ptr [[TMP21]], align 4
32 ; CHECK-NEXT: [[TMP11:%.*]] = insertelement <2 x i32> poison, i32 [[TMP22]], i32 0
33 ; CHECK-NEXT: br label %[[PRED_LOAD_CONTINUE]]
34 ; CHECK: [[PRED_LOAD_CONTINUE]]:
35 ; CHECK-NEXT: [[TMP12:%.*]] = phi <2 x i32> [ poison, %[[VECTOR_BODY]] ], [ [[TMP11]], %[[PRED_LOAD_IF]] ]
36 ; CHECK-NEXT: [[TMP13:%.*]] = extractelement <2 x i1> [[TMP10]], i32 1
37 ; CHECK-NEXT: br i1 [[TMP13]], label %[[PRED_LOAD_IF1:.*]], label %[[PRED_LOAD_CONTINUE2]]
38 ; CHECK: [[PRED_LOAD_IF1]]:
39 ; CHECK-NEXT: [[TMP26:%.*]] = extractelement <2 x ptr> [[TMP1]], i32 1
40 ; CHECK-NEXT: [[TMP27:%.*]] = load i32, ptr [[TMP26]], align 4
41 ; CHECK-NEXT: [[TMP16:%.*]] = insertelement <2 x i32> [[TMP12]], i32 [[TMP27]], i32 1
42 ; CHECK-NEXT: br label %[[PRED_LOAD_CONTINUE2]]
43 ; CHECK: [[PRED_LOAD_CONTINUE2]]:
44 ; CHECK-NEXT: [[TMP17:%.*]] = phi <2 x i32> [ [[TMP12]], %[[PRED_LOAD_CONTINUE]] ], [ [[TMP16]], %[[PRED_LOAD_IF1]] ]
45 ; CHECK-NEXT: [[PREDPHI:%.*]] = select <2 x i1> [[TMP9]], <2 x i32> [[WIDE_LOAD]], <2 x i32> [[TMP17]]
46 ; CHECK-NEXT: [[TMP30:%.*]] = getelementptr inbounds i32, ptr [[C]], i64 [[TMP0]]
47 ; CHECK-NEXT: [[TMP31:%.*]] = getelementptr inbounds i32, ptr [[TMP30]], i32 0
48 ; CHECK-NEXT: store <2 x i32> [[PREDPHI]], ptr [[TMP31]], align 4
49 ; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 2
50 ; CHECK-NEXT: [[VEC_IND_NEXT]] = add <2 x i64> [[VEC_IND]], splat (i64 2)
51 ; CHECK-NEXT: [[TMP32:%.*]] = icmp eq i64 [[INDEX_NEXT]], 1000
52 ; CHECK-NEXT: br i1 [[TMP32]], label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]], !llvm.loop [[LOOP0:![0-9]+]]
53 ; CHECK: [[MIDDLE_BLOCK]]:
54 ; CHECK-NEXT: br i1 true, label %[[EXIT:.*]], label %[[SCALAR_PH]]
55 ; CHECK: [[SCALAR_PH]]:
56 ; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i64 [ 1000, %[[MIDDLE_BLOCK]] ], [ 0, %[[ENTRY]] ]
57 ; CHECK-NEXT: br label %[[LOOP_HEADER:.*]]
58 ; CHECK: [[LOOP_HEADER]]:
59 ; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[BC_RESUME_VAL]], %[[SCALAR_PH]] ], [ [[IV_NEXT:%.*]], %[[LOOP_LATCH:.*]] ]
60 ; CHECK-NEXT: [[GEP_A:%.*]] = getelementptr i32, ptr [[A]], i64 [[IV]]
61 ; CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[GEP_A]], i64 4), "dereferenceable"(ptr [[GEP_A]], i64 4) ]
62 ; CHECK-NEXT: [[GEP_B:%.*]] = getelementptr inbounds i32, ptr [[B]], i64 [[IV]]
63 ; CHECK-NEXT: [[L_B:%.*]] = load i32, ptr [[GEP_B]], align 4
64 ; CHECK-NEXT: [[C_1:%.*]] = icmp sge i32 [[L_B]], 0
65 ; CHECK-NEXT: br i1 [[C_1]], label %[[LOOP_LATCH]], label %[[LOOP_THEN:.*]]
66 ; CHECK: [[LOOP_THEN]]:
67 ; CHECK-NEXT: [[L_A:%.*]] = load i32, ptr [[GEP_A]], align 4
68 ; CHECK-NEXT: br label %[[LOOP_LATCH]]
69 ; CHECK: [[LOOP_LATCH]]:
70 ; CHECK-NEXT: [[MERGE:%.*]] = phi i32 [ [[L_A]], %[[LOOP_THEN]] ], [ [[L_B]], %[[LOOP_HEADER]] ]
71 ; CHECK-NEXT: [[GEP_C:%.*]] = getelementptr inbounds i32, ptr [[C]], i64 [[IV]]
72 ; CHECK-NEXT: store i32 [[MERGE]], ptr [[GEP_C]], align 4
73 ; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
74 ; CHECK-NEXT: [[EC:%.*]] = icmp eq i64 [[IV_NEXT]], 1000
75 ; CHECK-NEXT: br i1 [[EC]], label %[[EXIT]], label %[[LOOP_HEADER]], !llvm.loop [[LOOP3:![0-9]+]]
77 ; CHECK-NEXT: ret void
83 %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop.latch ]
84 %gep.a = getelementptr i32, ptr %a, i64 %iv
85 call void @llvm.assume(i1 true) [ "align"(ptr %gep.a, i64 4), "dereferenceable"(ptr %gep.a, i64 4) ]
86 %gep.b = getelementptr inbounds i32, ptr %b, i64 %iv
87 %l.b = load i32, ptr %gep.b, align 4
88 %c.1 = icmp sge i32 %l.b, 0
89 br i1 %c.1, label %loop.latch, label %loop.then
92 %l.a = load i32, ptr %gep.a, align 4
96 %merge = phi i32 [ %l.a, %loop.then ], [ %l.b, %loop.header ]
97 %gep.c = getelementptr inbounds i32, ptr %c, i64 %iv
98 store i32 %merge, ptr %gep.c, align 4
99 %iv.next = add nuw nsw i64 %iv, 1
100 %ec = icmp eq i64 %iv.next, 1000
101 br i1 %ec, label %exit, label %loop.header
107 define void @align_deref_assumption_in_header_constant_trip_count_loop_invariant_ptr(ptr noalias %a, ptr noalias %b, ptr noalias %c) nofree nosync{
108 ; CHECK-LABEL: define void @align_deref_assumption_in_header_constant_trip_count_loop_invariant_ptr(
109 ; CHECK-SAME: ptr noalias [[A:%.*]], ptr noalias [[B:%.*]], ptr noalias [[C:%.*]]) #[[ATTR1]] {
110 ; CHECK-NEXT: [[ENTRY:.*]]:
111 ; CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[A]], i64 4), "dereferenceable"(ptr [[A]], i64 4) ]
112 ; CHECK-NEXT: br i1 false, label %[[SCALAR_PH:.*]], label %[[VECTOR_PH:.*]]
113 ; CHECK: [[VECTOR_PH]]:
114 ; CHECK-NEXT: br label %[[VECTOR_BODY:.*]]
115 ; CHECK: [[VECTOR_BODY]]:
116 ; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, %[[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], %[[VECTOR_BODY]] ]
117 ; CHECK-NEXT: [[TMP0:%.*]] = add i64 [[INDEX]], 0
118 ; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds i32, ptr [[B]], i64 [[TMP0]]
119 ; CHECK-NEXT: [[TMP2:%.*]] = getelementptr inbounds i32, ptr [[TMP1]], i32 0
120 ; CHECK-NEXT: [[WIDE_LOAD:%.*]] = load <2 x i32>, ptr [[TMP2]], align 4
121 ; CHECK-NEXT: [[TMP3:%.*]] = icmp sge <2 x i32> [[WIDE_LOAD]], zeroinitializer
122 ; CHECK-NEXT: [[TMP4:%.*]] = load i32, ptr [[A]], align 4
123 ; CHECK-NEXT: [[TMP5:%.*]] = load i32, ptr [[A]], align 4
124 ; CHECK-NEXT: [[TMP6:%.*]] = insertelement <2 x i32> poison, i32 [[TMP4]], i32 0
125 ; CHECK-NEXT: [[TMP7:%.*]] = insertelement <2 x i32> [[TMP6]], i32 [[TMP5]], i32 1
126 ; CHECK-NEXT: [[PREDPHI:%.*]] = select <2 x i1> [[TMP3]], <2 x i32> [[WIDE_LOAD]], <2 x i32> [[TMP7]]
127 ; CHECK-NEXT: [[TMP8:%.*]] = getelementptr inbounds i32, ptr [[C]], i64 [[TMP0]]
128 ; CHECK-NEXT: [[TMP9:%.*]] = getelementptr inbounds i32, ptr [[TMP8]], i32 0
129 ; CHECK-NEXT: store <2 x i32> [[PREDPHI]], ptr [[TMP9]], align 4
130 ; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 2
131 ; CHECK-NEXT: [[TMP10:%.*]] = icmp eq i64 [[INDEX_NEXT]], 1000
132 ; CHECK-NEXT: br i1 [[TMP10]], label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]], !llvm.loop [[LOOP4:![0-9]+]]
133 ; CHECK: [[MIDDLE_BLOCK]]:
134 ; CHECK-NEXT: br i1 true, label %[[EXIT:.*]], label %[[SCALAR_PH]]
135 ; CHECK: [[SCALAR_PH]]:
136 ; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i64 [ 1000, %[[MIDDLE_BLOCK]] ], [ 0, %[[ENTRY]] ]
137 ; CHECK-NEXT: br label %[[LOOP_HEADER:.*]]
138 ; CHECK: [[LOOP_HEADER]]:
139 ; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[BC_RESUME_VAL]], %[[SCALAR_PH]] ], [ [[IV_NEXT:%.*]], %[[LOOP_LATCH:.*]] ]
140 ; CHECK-NEXT: [[GEP_B:%.*]] = getelementptr inbounds i32, ptr [[B]], i64 [[IV]]
141 ; CHECK-NEXT: [[L_B:%.*]] = load i32, ptr [[GEP_B]], align 4
142 ; CHECK-NEXT: [[C_1:%.*]] = icmp sge i32 [[L_B]], 0
143 ; CHECK-NEXT: br i1 [[C_1]], label %[[LOOP_LATCH]], label %[[LOOP_THEN:.*]]
144 ; CHECK: [[LOOP_THEN]]:
145 ; CHECK-NEXT: [[L_A:%.*]] = load i32, ptr [[A]], align 4
146 ; CHECK-NEXT: br label %[[LOOP_LATCH]]
147 ; CHECK: [[LOOP_LATCH]]:
148 ; CHECK-NEXT: [[MERGE:%.*]] = phi i32 [ [[L_A]], %[[LOOP_THEN]] ], [ [[L_B]], %[[LOOP_HEADER]] ]
149 ; CHECK-NEXT: [[GEP_C:%.*]] = getelementptr inbounds i32, ptr [[C]], i64 [[IV]]
150 ; CHECK-NEXT: store i32 [[MERGE]], ptr [[GEP_C]], align 4
151 ; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
152 ; CHECK-NEXT: [[EC:%.*]] = icmp eq i64 [[IV_NEXT]], 1000
153 ; CHECK-NEXT: br i1 [[EC]], label %[[EXIT]], label %[[LOOP_HEADER]], !llvm.loop [[LOOP5:![0-9]+]]
155 ; CHECK-NEXT: ret void
158 call void @llvm.assume(i1 true) [ "align"(ptr %a, i64 4), "dereferenceable"(ptr %a, i64 4) ]
159 br label %loop.header
162 %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop.latch ]
163 %gep.b = getelementptr inbounds i32, ptr %b, i64 %iv
164 %l.b = load i32, ptr %gep.b, align 4
165 %c.1 = icmp sge i32 %l.b, 0
166 br i1 %c.1, label %loop.latch, label %loop.then
169 %l.a = load i32, ptr %a, align 4
173 %merge = phi i32 [ %l.a, %loop.then ], [ %l.b, %loop.header ]
174 %gep.c = getelementptr inbounds i32, ptr %c, i64 %iv
175 store i32 %merge, ptr %gep.c, align 4
176 %iv.next = add nuw nsw i64 %iv, 1
177 %ec = icmp eq i64 %iv.next, 1000
178 br i1 %ec, label %exit, label %loop.header
184 define void @deref_assumption_too_small_in_header_constant_trip_count(ptr noalias %a, ptr noalias %b, ptr noalias %c) nofree nosync{
185 ; CHECK-LABEL: define void @deref_assumption_too_small_in_header_constant_trip_count(
186 ; CHECK-SAME: ptr noalias [[A:%.*]], ptr noalias [[B:%.*]], ptr noalias [[C:%.*]]) #[[ATTR1]] {
187 ; CHECK-NEXT: [[ENTRY:.*]]:
188 ; CHECK-NEXT: br i1 false, label %[[SCALAR_PH:.*]], label %[[VECTOR_PH:.*]]
189 ; CHECK: [[VECTOR_PH]]:
190 ; CHECK-NEXT: br label %[[VECTOR_BODY:.*]]
191 ; CHECK: [[VECTOR_BODY]]:
192 ; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, %[[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], %[[PRED_LOAD_CONTINUE2:.*]] ]
193 ; CHECK-NEXT: [[VEC_IND:%.*]] = phi <2 x i64> [ <i64 0, i64 1>, %[[VECTOR_PH]] ], [ [[VEC_IND_NEXT:%.*]], %[[PRED_LOAD_CONTINUE2]] ]
194 ; CHECK-NEXT: [[TMP0:%.*]] = add i64 [[INDEX]], 0
195 ; CHECK-NEXT: [[TMP1:%.*]] = getelementptr i32, ptr [[A]], <2 x i64> [[VEC_IND]]
196 ; CHECK-NEXT: [[TMP4:%.*]] = extractelement <2 x ptr> [[TMP1]], i32 0
197 ; CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[TMP4]], i64 4), "dereferenceable"(ptr [[TMP4]], i64 2) ]
198 ; CHECK-NEXT: [[TMP5:%.*]] = extractelement <2 x ptr> [[TMP1]], i32 1
199 ; CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[TMP5]], i64 4), "dereferenceable"(ptr [[TMP5]], i64 2) ]
200 ; CHECK-NEXT: [[TMP6:%.*]] = getelementptr inbounds i32, ptr [[B]], i64 [[TMP0]]
201 ; CHECK-NEXT: [[TMP7:%.*]] = getelementptr inbounds i32, ptr [[TMP6]], i32 0
202 ; CHECK-NEXT: [[WIDE_LOAD:%.*]] = load <2 x i32>, ptr [[TMP7]], align 4
203 ; CHECK-NEXT: [[TMP9:%.*]] = icmp sge <2 x i32> [[WIDE_LOAD]], zeroinitializer
204 ; CHECK-NEXT: [[TMP10:%.*]] = xor <2 x i1> [[TMP9]], splat (i1 true)
205 ; CHECK-NEXT: [[TMP8:%.*]] = extractelement <2 x i1> [[TMP10]], i32 0
206 ; CHECK-NEXT: br i1 [[TMP8]], label %[[PRED_LOAD_IF:.*]], label %[[PRED_LOAD_CONTINUE:.*]]
207 ; CHECK: [[PRED_LOAD_IF]]:
208 ; CHECK-NEXT: [[TMP21:%.*]] = extractelement <2 x ptr> [[TMP1]], i32 0
209 ; CHECK-NEXT: [[TMP22:%.*]] = load i32, ptr [[TMP21]], align 4
210 ; CHECK-NEXT: [[TMP11:%.*]] = insertelement <2 x i32> poison, i32 [[TMP22]], i32 0
211 ; CHECK-NEXT: br label %[[PRED_LOAD_CONTINUE]]
212 ; CHECK: [[PRED_LOAD_CONTINUE]]:
213 ; CHECK-NEXT: [[TMP12:%.*]] = phi <2 x i32> [ poison, %[[VECTOR_BODY]] ], [ [[TMP11]], %[[PRED_LOAD_IF]] ]
214 ; CHECK-NEXT: [[TMP13:%.*]] = extractelement <2 x i1> [[TMP10]], i32 1
215 ; CHECK-NEXT: br i1 [[TMP13]], label %[[PRED_LOAD_IF1:.*]], label %[[PRED_LOAD_CONTINUE2]]
216 ; CHECK: [[PRED_LOAD_IF1]]:
217 ; CHECK-NEXT: [[TMP26:%.*]] = extractelement <2 x ptr> [[TMP1]], i32 1
218 ; CHECK-NEXT: [[TMP27:%.*]] = load i32, ptr [[TMP26]], align 4
219 ; CHECK-NEXT: [[TMP16:%.*]] = insertelement <2 x i32> [[TMP12]], i32 [[TMP27]], i32 1
220 ; CHECK-NEXT: br label %[[PRED_LOAD_CONTINUE2]]
221 ; CHECK: [[PRED_LOAD_CONTINUE2]]:
222 ; CHECK-NEXT: [[TMP17:%.*]] = phi <2 x i32> [ [[TMP12]], %[[PRED_LOAD_CONTINUE]] ], [ [[TMP16]], %[[PRED_LOAD_IF1]] ]
223 ; CHECK-NEXT: [[PREDPHI:%.*]] = select <2 x i1> [[TMP9]], <2 x i32> [[WIDE_LOAD]], <2 x i32> [[TMP17]]
224 ; CHECK-NEXT: [[TMP30:%.*]] = getelementptr inbounds i32, ptr [[C]], i64 [[TMP0]]
225 ; CHECK-NEXT: [[TMP31:%.*]] = getelementptr inbounds i32, ptr [[TMP30]], i32 0
226 ; CHECK-NEXT: store <2 x i32> [[PREDPHI]], ptr [[TMP31]], align 4
227 ; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 2
228 ; CHECK-NEXT: [[VEC_IND_NEXT]] = add <2 x i64> [[VEC_IND]], splat (i64 2)
229 ; CHECK-NEXT: [[TMP32:%.*]] = icmp eq i64 [[INDEX_NEXT]], 1000
230 ; CHECK-NEXT: br i1 [[TMP32]], label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]], !llvm.loop [[LOOP6:![0-9]+]]
231 ; CHECK: [[MIDDLE_BLOCK]]:
232 ; CHECK-NEXT: br i1 true, label %[[EXIT:.*]], label %[[SCALAR_PH]]
233 ; CHECK: [[SCALAR_PH]]:
234 ; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i64 [ 1000, %[[MIDDLE_BLOCK]] ], [ 0, %[[ENTRY]] ]
235 ; CHECK-NEXT: br label %[[LOOP_HEADER:.*]]
236 ; CHECK: [[LOOP_HEADER]]:
237 ; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[BC_RESUME_VAL]], %[[SCALAR_PH]] ], [ [[IV_NEXT:%.*]], %[[LOOP_LATCH:.*]] ]
238 ; CHECK-NEXT: [[GEP_A:%.*]] = getelementptr i32, ptr [[A]], i64 [[IV]]
239 ; CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[GEP_A]], i64 4), "dereferenceable"(ptr [[GEP_A]], i64 2) ]
240 ; CHECK-NEXT: [[GEP_B:%.*]] = getelementptr inbounds i32, ptr [[B]], i64 [[IV]]
241 ; CHECK-NEXT: [[L_B:%.*]] = load i32, ptr [[GEP_B]], align 4
242 ; CHECK-NEXT: [[C_1:%.*]] = icmp sge i32 [[L_B]], 0
243 ; CHECK-NEXT: br i1 [[C_1]], label %[[LOOP_LATCH]], label %[[LOOP_THEN:.*]]
244 ; CHECK: [[LOOP_THEN]]:
245 ; CHECK-NEXT: [[L_A:%.*]] = load i32, ptr [[GEP_A]], align 4
246 ; CHECK-NEXT: br label %[[LOOP_LATCH]]
247 ; CHECK: [[LOOP_LATCH]]:
248 ; CHECK-NEXT: [[MERGE:%.*]] = phi i32 [ [[L_A]], %[[LOOP_THEN]] ], [ [[L_B]], %[[LOOP_HEADER]] ]
249 ; CHECK-NEXT: [[GEP_C:%.*]] = getelementptr inbounds i32, ptr [[C]], i64 [[IV]]
250 ; CHECK-NEXT: store i32 [[MERGE]], ptr [[GEP_C]], align 4
251 ; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
252 ; CHECK-NEXT: [[EC:%.*]] = icmp eq i64 [[IV_NEXT]], 1000
253 ; CHECK-NEXT: br i1 [[EC]], label %[[EXIT]], label %[[LOOP_HEADER]], !llvm.loop [[LOOP7:![0-9]+]]
255 ; CHECK-NEXT: ret void
258 br label %loop.header
261 %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop.latch ]
262 %gep.a = getelementptr i32, ptr %a, i64 %iv
263 call void @llvm.assume(i1 true) [ "align"(ptr %gep.a, i64 4), "dereferenceable"(ptr %gep.a, i64 2) ]
264 %gep.b = getelementptr inbounds i32, ptr %b, i64 %iv
265 %l.b = load i32, ptr %gep.b, align 4
266 %c.1 = icmp sge i32 %l.b, 0
267 br i1 %c.1, label %loop.latch, label %loop.then
270 %l.a = load i32, ptr %gep.a, align 4
274 %merge = phi i32 [ %l.a, %loop.then ], [ %l.b, %loop.header ]
275 %gep.c = getelementptr inbounds i32, ptr %c, i64 %iv
276 store i32 %merge, ptr %gep.c, align 4
277 %iv.next = add nuw nsw i64 %iv, 1
278 %ec = icmp eq i64 %iv.next, 1000
279 br i1 %ec, label %exit, label %loop.header
285 define void @deref_assumption_in_header_constant_trip_count_align_1(ptr noalias %a, ptr noalias %b, ptr noalias %c) nofree nosync{
286 ; CHECK-LABEL: define void @deref_assumption_in_header_constant_trip_count_align_1(
287 ; CHECK-SAME: ptr noalias [[A:%.*]], ptr noalias [[B:%.*]], ptr noalias [[C:%.*]]) #[[ATTR1]] {
288 ; CHECK-NEXT: [[ENTRY:.*]]:
289 ; CHECK-NEXT: br i1 false, label %[[SCALAR_PH:.*]], label %[[VECTOR_PH:.*]]
290 ; CHECK: [[VECTOR_PH]]:
291 ; CHECK-NEXT: br label %[[VECTOR_BODY:.*]]
292 ; CHECK: [[VECTOR_BODY]]:
293 ; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, %[[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], %[[PRED_LOAD_CONTINUE2:.*]] ]
294 ; CHECK-NEXT: [[VEC_IND:%.*]] = phi <2 x i64> [ <i64 0, i64 1>, %[[VECTOR_PH]] ], [ [[VEC_IND_NEXT:%.*]], %[[PRED_LOAD_CONTINUE2]] ]
295 ; CHECK-NEXT: [[TMP0:%.*]] = add i64 [[INDEX]], 0
296 ; CHECK-NEXT: [[TMP1:%.*]] = getelementptr i32, ptr [[A]], <2 x i64> [[VEC_IND]]
297 ; CHECK-NEXT: [[TMP2:%.*]] = extractelement <2 x ptr> [[TMP1]], i32 0
298 ; CHECK-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(ptr [[TMP2]], i64 4) ]
299 ; CHECK-NEXT: [[TMP3:%.*]] = extractelement <2 x ptr> [[TMP1]], i32 1
300 ; CHECK-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(ptr [[TMP3]], i64 4) ]
301 ; CHECK-NEXT: [[TMP4:%.*]] = getelementptr inbounds i32, ptr [[B]], i64 [[TMP0]]
302 ; CHECK-NEXT: [[TMP5:%.*]] = getelementptr inbounds i32, ptr [[TMP4]], i32 0
303 ; CHECK-NEXT: [[WIDE_LOAD:%.*]] = load <2 x i32>, ptr [[TMP5]], align 4
304 ; CHECK-NEXT: [[TMP6:%.*]] = icmp sge <2 x i32> [[WIDE_LOAD]], zeroinitializer
305 ; CHECK-NEXT: [[TMP7:%.*]] = xor <2 x i1> [[TMP6]], splat (i1 true)
306 ; CHECK-NEXT: [[TMP8:%.*]] = extractelement <2 x i1> [[TMP7]], i32 0
307 ; CHECK-NEXT: br i1 [[TMP8]], label %[[PRED_LOAD_IF:.*]], label %[[PRED_LOAD_CONTINUE:.*]]
308 ; CHECK: [[PRED_LOAD_IF]]:
309 ; CHECK-NEXT: [[TMP9:%.*]] = extractelement <2 x ptr> [[TMP1]], i32 0
310 ; CHECK-NEXT: [[TMP10:%.*]] = load i32, ptr [[TMP9]], align 1
311 ; CHECK-NEXT: [[TMP11:%.*]] = insertelement <2 x i32> poison, i32 [[TMP10]], i32 0
312 ; CHECK-NEXT: br label %[[PRED_LOAD_CONTINUE]]
313 ; CHECK: [[PRED_LOAD_CONTINUE]]:
314 ; CHECK-NEXT: [[TMP12:%.*]] = phi <2 x i32> [ poison, %[[VECTOR_BODY]] ], [ [[TMP11]], %[[PRED_LOAD_IF]] ]
315 ; CHECK-NEXT: [[TMP13:%.*]] = extractelement <2 x i1> [[TMP7]], i32 1
316 ; CHECK-NEXT: br i1 [[TMP13]], label %[[PRED_LOAD_IF1:.*]], label %[[PRED_LOAD_CONTINUE2]]
317 ; CHECK: [[PRED_LOAD_IF1]]:
318 ; CHECK-NEXT: [[TMP14:%.*]] = extractelement <2 x ptr> [[TMP1]], i32 1
319 ; CHECK-NEXT: [[TMP15:%.*]] = load i32, ptr [[TMP14]], align 1
320 ; CHECK-NEXT: [[TMP16:%.*]] = insertelement <2 x i32> [[TMP12]], i32 [[TMP15]], i32 1
321 ; CHECK-NEXT: br label %[[PRED_LOAD_CONTINUE2]]
322 ; CHECK: [[PRED_LOAD_CONTINUE2]]:
323 ; CHECK-NEXT: [[TMP17:%.*]] = phi <2 x i32> [ [[TMP12]], %[[PRED_LOAD_CONTINUE]] ], [ [[TMP16]], %[[PRED_LOAD_IF1]] ]
324 ; CHECK-NEXT: [[PREDPHI:%.*]] = select <2 x i1> [[TMP6]], <2 x i32> [[WIDE_LOAD]], <2 x i32> [[TMP17]]
325 ; CHECK-NEXT: [[TMP18:%.*]] = getelementptr inbounds i32, ptr [[C]], i64 [[TMP0]]
326 ; CHECK-NEXT: [[TMP19:%.*]] = getelementptr inbounds i32, ptr [[TMP18]], i32 0
327 ; CHECK-NEXT: store <2 x i32> [[PREDPHI]], ptr [[TMP19]], align 4
328 ; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 2
329 ; CHECK-NEXT: [[VEC_IND_NEXT]] = add <2 x i64> [[VEC_IND]], splat (i64 2)
330 ; CHECK-NEXT: [[TMP20:%.*]] = icmp eq i64 [[INDEX_NEXT]], 1000
331 ; CHECK-NEXT: br i1 [[TMP20]], label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]], !llvm.loop [[LOOP8:![0-9]+]]
332 ; CHECK: [[MIDDLE_BLOCK]]:
333 ; CHECK-NEXT: br i1 true, label %[[EXIT:.*]], label %[[SCALAR_PH]]
334 ; CHECK: [[SCALAR_PH]]:
335 ; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i64 [ 1000, %[[MIDDLE_BLOCK]] ], [ 0, %[[ENTRY]] ]
336 ; CHECK-NEXT: br label %[[LOOP_HEADER:.*]]
337 ; CHECK: [[LOOP_HEADER]]:
338 ; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[BC_RESUME_VAL]], %[[SCALAR_PH]] ], [ [[IV_NEXT:%.*]], %[[LOOP_LATCH:.*]] ]
339 ; CHECK-NEXT: [[GEP_A:%.*]] = getelementptr i32, ptr [[A]], i64 [[IV]]
340 ; CHECK-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(ptr [[GEP_A]], i64 4) ]
341 ; CHECK-NEXT: [[GEP_B:%.*]] = getelementptr inbounds i32, ptr [[B]], i64 [[IV]]
342 ; CHECK-NEXT: [[L_B:%.*]] = load i32, ptr [[GEP_B]], align 4
343 ; CHECK-NEXT: [[C_1:%.*]] = icmp sge i32 [[L_B]], 0
344 ; CHECK-NEXT: br i1 [[C_1]], label %[[LOOP_LATCH]], label %[[LOOP_THEN:.*]]
345 ; CHECK: [[LOOP_THEN]]:
346 ; CHECK-NEXT: [[L_A:%.*]] = load i32, ptr [[GEP_A]], align 1
347 ; CHECK-NEXT: br label %[[LOOP_LATCH]]
348 ; CHECK: [[LOOP_LATCH]]:
349 ; CHECK-NEXT: [[MERGE:%.*]] = phi i32 [ [[L_A]], %[[LOOP_THEN]] ], [ [[L_B]], %[[LOOP_HEADER]] ]
350 ; CHECK-NEXT: [[GEP_C:%.*]] = getelementptr inbounds i32, ptr [[C]], i64 [[IV]]
351 ; CHECK-NEXT: store i32 [[MERGE]], ptr [[GEP_C]], align 4
352 ; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
353 ; CHECK-NEXT: [[EC:%.*]] = icmp eq i64 [[IV_NEXT]], 1000
354 ; CHECK-NEXT: br i1 [[EC]], label %[[EXIT]], label %[[LOOP_HEADER]], !llvm.loop [[LOOP9:![0-9]+]]
356 ; CHECK-NEXT: ret void
359 br label %loop.header
362 %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop.latch ]
363 %gep.a = getelementptr i32, ptr %a, i64 %iv
364 call void @llvm.assume(i1 true) [ "dereferenceable"(ptr %gep.a, i64 4) ]
365 %gep.b = getelementptr inbounds i32, ptr %b, i64 %iv
366 %l.b = load i32, ptr %gep.b, align 4
367 %c.1 = icmp sge i32 %l.b, 0
368 br i1 %c.1, label %loop.latch, label %loop.then
371 %l.a = load i32, ptr %gep.a, align 1
375 %merge = phi i32 [ %l.a, %loop.then ], [ %l.b, %loop.header ]
376 %gep.c = getelementptr inbounds i32, ptr %c, i64 %iv
377 store i32 %merge, ptr %gep.c, align 4
378 %iv.next = add nuw nsw i64 %iv, 1
379 %ec = icmp eq i64 %iv.next, 1000
380 br i1 %ec, label %exit, label %loop.header
386 define void @deref_assumption_in_header_constant_trip_count_align_via_arg_attribute(ptr noalias align 4 %a, ptr noalias %b, ptr noalias %c) nofree nosync{
387 ; CHECK-LABEL: define void @deref_assumption_in_header_constant_trip_count_align_via_arg_attribute(
388 ; CHECK-SAME: ptr noalias align 4 [[A:%.*]], ptr noalias [[B:%.*]], ptr noalias [[C:%.*]]) #[[ATTR1]] {
389 ; CHECK-NEXT: [[ENTRY:.*]]:
390 ; CHECK-NEXT: br i1 false, label %[[SCALAR_PH:.*]], label %[[VECTOR_PH:.*]]
391 ; CHECK: [[VECTOR_PH]]:
392 ; CHECK-NEXT: br label %[[VECTOR_BODY:.*]]
393 ; CHECK: [[VECTOR_BODY]]:
394 ; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, %[[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], %[[PRED_LOAD_CONTINUE2:.*]] ]
395 ; CHECK-NEXT: [[VEC_IND:%.*]] = phi <2 x i64> [ <i64 0, i64 1>, %[[VECTOR_PH]] ], [ [[VEC_IND_NEXT:%.*]], %[[PRED_LOAD_CONTINUE2]] ]
396 ; CHECK-NEXT: [[TMP0:%.*]] = add i64 [[INDEX]], 0
397 ; CHECK-NEXT: [[TMP1:%.*]] = getelementptr i32, ptr [[A]], <2 x i64> [[VEC_IND]]
398 ; CHECK-NEXT: [[TMP2:%.*]] = extractelement <2 x ptr> [[TMP1]], i32 0
399 ; CHECK-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(ptr [[TMP2]], i64 4) ]
400 ; CHECK-NEXT: [[TMP3:%.*]] = extractelement <2 x ptr> [[TMP1]], i32 1
401 ; CHECK-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(ptr [[TMP3]], i64 4) ]
402 ; CHECK-NEXT: [[TMP4:%.*]] = getelementptr inbounds i32, ptr [[B]], i64 [[TMP0]]
403 ; CHECK-NEXT: [[TMP5:%.*]] = getelementptr inbounds i32, ptr [[TMP4]], i32 0
404 ; CHECK-NEXT: [[WIDE_LOAD:%.*]] = load <2 x i32>, ptr [[TMP5]], align 4
405 ; CHECK-NEXT: [[TMP6:%.*]] = icmp sge <2 x i32> [[WIDE_LOAD]], zeroinitializer
406 ; CHECK-NEXT: [[TMP7:%.*]] = xor <2 x i1> [[TMP6]], splat (i1 true)
407 ; CHECK-NEXT: [[TMP8:%.*]] = extractelement <2 x i1> [[TMP7]], i32 0
408 ; CHECK-NEXT: br i1 [[TMP8]], label %[[PRED_LOAD_IF:.*]], label %[[PRED_LOAD_CONTINUE:.*]]
409 ; CHECK: [[PRED_LOAD_IF]]:
410 ; CHECK-NEXT: [[TMP9:%.*]] = extractelement <2 x ptr> [[TMP1]], i32 0
411 ; CHECK-NEXT: [[TMP10:%.*]] = load i32, ptr [[TMP9]], align 4
412 ; CHECK-NEXT: [[TMP11:%.*]] = insertelement <2 x i32> poison, i32 [[TMP10]], i32 0
413 ; CHECK-NEXT: br label %[[PRED_LOAD_CONTINUE]]
414 ; CHECK: [[PRED_LOAD_CONTINUE]]:
415 ; CHECK-NEXT: [[TMP12:%.*]] = phi <2 x i32> [ poison, %[[VECTOR_BODY]] ], [ [[TMP11]], %[[PRED_LOAD_IF]] ]
416 ; CHECK-NEXT: [[TMP13:%.*]] = extractelement <2 x i1> [[TMP7]], i32 1
417 ; CHECK-NEXT: br i1 [[TMP13]], label %[[PRED_LOAD_IF1:.*]], label %[[PRED_LOAD_CONTINUE2]]
418 ; CHECK: [[PRED_LOAD_IF1]]:
419 ; CHECK-NEXT: [[TMP14:%.*]] = extractelement <2 x ptr> [[TMP1]], i32 1
420 ; CHECK-NEXT: [[TMP15:%.*]] = load i32, ptr [[TMP14]], align 4
421 ; CHECK-NEXT: [[TMP16:%.*]] = insertelement <2 x i32> [[TMP12]], i32 [[TMP15]], i32 1
422 ; CHECK-NEXT: br label %[[PRED_LOAD_CONTINUE2]]
423 ; CHECK: [[PRED_LOAD_CONTINUE2]]:
424 ; CHECK-NEXT: [[TMP17:%.*]] = phi <2 x i32> [ [[TMP12]], %[[PRED_LOAD_CONTINUE]] ], [ [[TMP16]], %[[PRED_LOAD_IF1]] ]
425 ; CHECK-NEXT: [[PREDPHI:%.*]] = select <2 x i1> [[TMP6]], <2 x i32> [[WIDE_LOAD]], <2 x i32> [[TMP17]]
426 ; CHECK-NEXT: [[TMP18:%.*]] = getelementptr inbounds i32, ptr [[C]], i64 [[TMP0]]
427 ; CHECK-NEXT: [[TMP19:%.*]] = getelementptr inbounds i32, ptr [[TMP18]], i32 0
428 ; CHECK-NEXT: store <2 x i32> [[PREDPHI]], ptr [[TMP19]], align 4
429 ; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 2
430 ; CHECK-NEXT: [[VEC_IND_NEXT]] = add <2 x i64> [[VEC_IND]], splat (i64 2)
431 ; CHECK-NEXT: [[TMP20:%.*]] = icmp eq i64 [[INDEX_NEXT]], 1000
432 ; CHECK-NEXT: br i1 [[TMP20]], label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]], !llvm.loop [[LOOP10:![0-9]+]]
433 ; CHECK: [[MIDDLE_BLOCK]]:
434 ; CHECK-NEXT: br i1 true, label %[[EXIT:.*]], label %[[SCALAR_PH]]
435 ; CHECK: [[SCALAR_PH]]:
436 ; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i64 [ 1000, %[[MIDDLE_BLOCK]] ], [ 0, %[[ENTRY]] ]
437 ; CHECK-NEXT: br label %[[LOOP_HEADER:.*]]
438 ; CHECK: [[LOOP_HEADER]]:
439 ; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[BC_RESUME_VAL]], %[[SCALAR_PH]] ], [ [[IV_NEXT:%.*]], %[[LOOP_LATCH:.*]] ]
440 ; CHECK-NEXT: [[GEP_A:%.*]] = getelementptr i32, ptr [[A]], i64 [[IV]]
441 ; CHECK-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(ptr [[GEP_A]], i64 4) ]
442 ; CHECK-NEXT: [[GEP_B:%.*]] = getelementptr inbounds i32, ptr [[B]], i64 [[IV]]
443 ; CHECK-NEXT: [[L_B:%.*]] = load i32, ptr [[GEP_B]], align 4
444 ; CHECK-NEXT: [[C_1:%.*]] = icmp sge i32 [[L_B]], 0
445 ; CHECK-NEXT: br i1 [[C_1]], label %[[LOOP_LATCH]], label %[[LOOP_THEN:.*]]
446 ; CHECK: [[LOOP_THEN]]:
447 ; CHECK-NEXT: [[L_A:%.*]] = load i32, ptr [[GEP_A]], align 4
448 ; CHECK-NEXT: br label %[[LOOP_LATCH]]
449 ; CHECK: [[LOOP_LATCH]]:
450 ; CHECK-NEXT: [[MERGE:%.*]] = phi i32 [ [[L_A]], %[[LOOP_THEN]] ], [ [[L_B]], %[[LOOP_HEADER]] ]
451 ; CHECK-NEXT: [[GEP_C:%.*]] = getelementptr inbounds i32, ptr [[C]], i64 [[IV]]
452 ; CHECK-NEXT: store i32 [[MERGE]], ptr [[GEP_C]], align 4
453 ; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
454 ; CHECK-NEXT: [[EC:%.*]] = icmp eq i64 [[IV_NEXT]], 1000
455 ; CHECK-NEXT: br i1 [[EC]], label %[[EXIT]], label %[[LOOP_HEADER]], !llvm.loop [[LOOP11:![0-9]+]]
457 ; CHECK-NEXT: ret void
460 br label %loop.header
463 %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop.latch ]
464 %gep.a = getelementptr i32, ptr %a, i64 %iv
465 call void @llvm.assume(i1 true) [ "dereferenceable"(ptr %gep.a, i64 4) ]
466 %gep.b = getelementptr inbounds i32, ptr %b, i64 %iv
467 %l.b = load i32, ptr %gep.b, align 4
468 %c.1 = icmp sge i32 %l.b, 0
469 br i1 %c.1, label %loop.latch, label %loop.then
472 %l.a = load i32, ptr %gep.a, align 4
476 %merge = phi i32 [ %l.a, %loop.then ], [ %l.b, %loop.header ]
477 %gep.c = getelementptr inbounds i32, ptr %c, i64 %iv
478 store i32 %merge, ptr %gep.c, align 4
479 %iv.next = add nuw nsw i64 %iv, 1
480 %ec = icmp eq i64 %iv.next, 1000
481 br i1 %ec, label %exit, label %loop.header
487 define void @deref_assumption_in_header_constant_trip_count_align_not_known(ptr noalias %a, ptr noalias %b, ptr noalias %c) nofree nosync{
488 ; CHECK-LABEL: define void @deref_assumption_in_header_constant_trip_count_align_not_known(
489 ; CHECK-SAME: ptr noalias [[A:%.*]], ptr noalias [[B:%.*]], ptr noalias [[C:%.*]]) #[[ATTR1]] {
490 ; CHECK-NEXT: [[ENTRY:.*]]:
491 ; CHECK-NEXT: br i1 false, label %[[SCALAR_PH:.*]], label %[[VECTOR_PH:.*]]
492 ; CHECK: [[VECTOR_PH]]:
493 ; CHECK-NEXT: br label %[[VECTOR_BODY:.*]]
494 ; CHECK: [[VECTOR_BODY]]:
495 ; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, %[[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], %[[PRED_LOAD_CONTINUE2:.*]] ]
496 ; CHECK-NEXT: [[VEC_IND:%.*]] = phi <2 x i64> [ <i64 0, i64 1>, %[[VECTOR_PH]] ], [ [[VEC_IND_NEXT:%.*]], %[[PRED_LOAD_CONTINUE2]] ]
497 ; CHECK-NEXT: [[TMP0:%.*]] = add i64 [[INDEX]], 0
498 ; CHECK-NEXT: [[TMP1:%.*]] = getelementptr i32, ptr [[A]], <2 x i64> [[VEC_IND]]
499 ; CHECK-NEXT: [[TMP2:%.*]] = extractelement <2 x ptr> [[TMP1]], i32 0
500 ; CHECK-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(ptr [[TMP2]], i64 4) ]
501 ; CHECK-NEXT: [[TMP3:%.*]] = extractelement <2 x ptr> [[TMP1]], i32 1
502 ; CHECK-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(ptr [[TMP3]], i64 4) ]
503 ; CHECK-NEXT: [[TMP4:%.*]] = getelementptr inbounds i32, ptr [[B]], i64 [[TMP0]]
504 ; CHECK-NEXT: [[TMP5:%.*]] = getelementptr inbounds i32, ptr [[TMP4]], i32 0
505 ; CHECK-NEXT: [[WIDE_LOAD:%.*]] = load <2 x i32>, ptr [[TMP5]], align 4
506 ; CHECK-NEXT: [[TMP6:%.*]] = icmp sge <2 x i32> [[WIDE_LOAD]], zeroinitializer
507 ; CHECK-NEXT: [[TMP7:%.*]] = xor <2 x i1> [[TMP6]], splat (i1 true)
508 ; CHECK-NEXT: [[TMP8:%.*]] = extractelement <2 x i1> [[TMP7]], i32 0
509 ; CHECK-NEXT: br i1 [[TMP8]], label %[[PRED_LOAD_IF:.*]], label %[[PRED_LOAD_CONTINUE:.*]]
510 ; CHECK: [[PRED_LOAD_IF]]:
511 ; CHECK-NEXT: [[TMP9:%.*]] = extractelement <2 x ptr> [[TMP1]], i32 0
512 ; CHECK-NEXT: [[TMP10:%.*]] = load i32, ptr [[TMP9]], align 4
513 ; CHECK-NEXT: [[TMP11:%.*]] = insertelement <2 x i32> poison, i32 [[TMP10]], i32 0
514 ; CHECK-NEXT: br label %[[PRED_LOAD_CONTINUE]]
515 ; CHECK: [[PRED_LOAD_CONTINUE]]:
516 ; CHECK-NEXT: [[TMP12:%.*]] = phi <2 x i32> [ poison, %[[VECTOR_BODY]] ], [ [[TMP11]], %[[PRED_LOAD_IF]] ]
517 ; CHECK-NEXT: [[TMP13:%.*]] = extractelement <2 x i1> [[TMP7]], i32 1
518 ; CHECK-NEXT: br i1 [[TMP13]], label %[[PRED_LOAD_IF1:.*]], label %[[PRED_LOAD_CONTINUE2]]
519 ; CHECK: [[PRED_LOAD_IF1]]:
520 ; CHECK-NEXT: [[TMP14:%.*]] = extractelement <2 x ptr> [[TMP1]], i32 1
521 ; CHECK-NEXT: [[TMP15:%.*]] = load i32, ptr [[TMP14]], align 4
522 ; CHECK-NEXT: [[TMP16:%.*]] = insertelement <2 x i32> [[TMP12]], i32 [[TMP15]], i32 1
523 ; CHECK-NEXT: br label %[[PRED_LOAD_CONTINUE2]]
524 ; CHECK: [[PRED_LOAD_CONTINUE2]]:
525 ; CHECK-NEXT: [[TMP17:%.*]] = phi <2 x i32> [ [[TMP12]], %[[PRED_LOAD_CONTINUE]] ], [ [[TMP16]], %[[PRED_LOAD_IF1]] ]
526 ; CHECK-NEXT: [[PREDPHI:%.*]] = select <2 x i1> [[TMP6]], <2 x i32> [[WIDE_LOAD]], <2 x i32> [[TMP17]]
527 ; CHECK-NEXT: [[TMP18:%.*]] = getelementptr inbounds i32, ptr [[C]], i64 [[TMP0]]
528 ; CHECK-NEXT: [[TMP19:%.*]] = getelementptr inbounds i32, ptr [[TMP18]], i32 0
529 ; CHECK-NEXT: store <2 x i32> [[PREDPHI]], ptr [[TMP19]], align 4
530 ; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 2
531 ; CHECK-NEXT: [[VEC_IND_NEXT]] = add <2 x i64> [[VEC_IND]], splat (i64 2)
532 ; CHECK-NEXT: [[TMP20:%.*]] = icmp eq i64 [[INDEX_NEXT]], 1000
533 ; CHECK-NEXT: br i1 [[TMP20]], label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]], !llvm.loop [[LOOP12:![0-9]+]]
534 ; CHECK: [[MIDDLE_BLOCK]]:
535 ; CHECK-NEXT: br i1 true, label %[[EXIT:.*]], label %[[SCALAR_PH]]
536 ; CHECK: [[SCALAR_PH]]:
537 ; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i64 [ 1000, %[[MIDDLE_BLOCK]] ], [ 0, %[[ENTRY]] ]
538 ; CHECK-NEXT: br label %[[LOOP_HEADER:.*]]
539 ; CHECK: [[LOOP_HEADER]]:
540 ; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[BC_RESUME_VAL]], %[[SCALAR_PH]] ], [ [[IV_NEXT:%.*]], %[[LOOP_LATCH:.*]] ]
541 ; CHECK-NEXT: [[GEP_A:%.*]] = getelementptr i32, ptr [[A]], i64 [[IV]]
542 ; CHECK-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(ptr [[GEP_A]], i64 4) ]
543 ; CHECK-NEXT: [[GEP_B:%.*]] = getelementptr inbounds i32, ptr [[B]], i64 [[IV]]
544 ; CHECK-NEXT: [[L_B:%.*]] = load i32, ptr [[GEP_B]], align 4
545 ; CHECK-NEXT: [[C_1:%.*]] = icmp sge i32 [[L_B]], 0
546 ; CHECK-NEXT: br i1 [[C_1]], label %[[LOOP_LATCH]], label %[[LOOP_THEN:.*]]
547 ; CHECK: [[LOOP_THEN]]:
548 ; CHECK-NEXT: [[L_A:%.*]] = load i32, ptr [[GEP_A]], align 4
549 ; CHECK-NEXT: br label %[[LOOP_LATCH]]
550 ; CHECK: [[LOOP_LATCH]]:
551 ; CHECK-NEXT: [[MERGE:%.*]] = phi i32 [ [[L_A]], %[[LOOP_THEN]] ], [ [[L_B]], %[[LOOP_HEADER]] ]
552 ; CHECK-NEXT: [[GEP_C:%.*]] = getelementptr inbounds i32, ptr [[C]], i64 [[IV]]
553 ; CHECK-NEXT: store i32 [[MERGE]], ptr [[GEP_C]], align 4
554 ; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
555 ; CHECK-NEXT: [[EC:%.*]] = icmp eq i64 [[IV_NEXT]], 1000
556 ; CHECK-NEXT: br i1 [[EC]], label %[[EXIT]], label %[[LOOP_HEADER]], !llvm.loop [[LOOP13:![0-9]+]]
558 ; CHECK-NEXT: ret void
561 br label %loop.header
564 %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop.latch ]
565 %gep.a = getelementptr i32, ptr %a, i64 %iv
566 call void @llvm.assume(i1 true) [ "dereferenceable"(ptr %gep.a, i64 4) ]
567 %gep.b = getelementptr inbounds i32, ptr %b, i64 %iv
568 %l.b = load i32, ptr %gep.b, align 4
569 %c.1 = icmp sge i32 %l.b, 0
570 br i1 %c.1, label %loop.latch, label %loop.then
573 %l.a = load i32, ptr %gep.a, align 4
577 %merge = phi i32 [ %l.a, %loop.then ], [ %l.b, %loop.header ]
578 %gep.c = getelementptr inbounds i32, ptr %c, i64 %iv
579 store i32 %merge, ptr %gep.c, align 4
580 %iv.next = add nuw nsw i64 %iv, 1
581 %ec = icmp eq i64 %iv.next, 1000
582 br i1 %ec, label %exit, label %loop.header
588 define void @deref_assumption_in_then_constant_trip_count(ptr noalias %a, ptr noalias %b, ptr noalias %c) nofree nosync{
589 ; CHECK-LABEL: define void @deref_assumption_in_then_constant_trip_count(
590 ; CHECK-SAME: ptr noalias [[A:%.*]], ptr noalias [[B:%.*]], ptr noalias [[C:%.*]]) #[[ATTR1]] {
591 ; CHECK-NEXT: [[ENTRY:.*]]:
592 ; CHECK-NEXT: br i1 false, label %[[SCALAR_PH:.*]], label %[[VECTOR_PH:.*]]
593 ; CHECK: [[VECTOR_PH]]:
594 ; CHECK-NEXT: br label %[[VECTOR_BODY:.*]]
595 ; CHECK: [[VECTOR_BODY]]:
596 ; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, %[[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], %[[PRED_LOAD_CONTINUE2:.*]] ]
597 ; CHECK-NEXT: [[VEC_IND:%.*]] = phi <2 x i64> [ <i64 0, i64 1>, %[[VECTOR_PH]] ], [ [[VEC_IND_NEXT:%.*]], %[[PRED_LOAD_CONTINUE2]] ]
598 ; CHECK-NEXT: [[TMP0:%.*]] = add i64 [[INDEX]], 0
599 ; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds i32, ptr [[B]], i64 [[TMP0]]
600 ; CHECK-NEXT: [[TMP2:%.*]] = getelementptr inbounds i32, ptr [[TMP1]], i32 0
601 ; CHECK-NEXT: [[WIDE_LOAD:%.*]] = load <2 x i32>, ptr [[TMP2]], align 4
602 ; CHECK-NEXT: [[TMP3:%.*]] = icmp sge <2 x i32> [[WIDE_LOAD]], zeroinitializer
603 ; CHECK-NEXT: [[TMP4:%.*]] = xor <2 x i1> [[TMP3]], splat (i1 true)
604 ; CHECK-NEXT: [[TMP5:%.*]] = getelementptr i32, ptr [[A]], <2 x i64> [[VEC_IND]]
605 ; CHECK-NEXT: [[TMP6:%.*]] = extractelement <2 x i1> [[TMP4]], i32 0
606 ; CHECK-NEXT: br i1 [[TMP6]], label %[[PRED_LOAD_IF:.*]], label %[[PRED_LOAD_CONTINUE:.*]]
607 ; CHECK: [[PRED_LOAD_IF]]:
608 ; CHECK-NEXT: [[TMP17:%.*]] = extractelement <2 x ptr> [[TMP5]], i32 0
609 ; CHECK-NEXT: [[TMP18:%.*]] = load i32, ptr [[TMP17]], align 4
610 ; CHECK-NEXT: [[TMP9:%.*]] = insertelement <2 x i32> poison, i32 [[TMP18]], i32 0
611 ; CHECK-NEXT: br label %[[PRED_LOAD_CONTINUE]]
612 ; CHECK: [[PRED_LOAD_CONTINUE]]:
613 ; CHECK-NEXT: [[TMP10:%.*]] = phi <2 x i32> [ poison, %[[VECTOR_BODY]] ], [ [[TMP9]], %[[PRED_LOAD_IF]] ]
614 ; CHECK-NEXT: [[TMP11:%.*]] = extractelement <2 x i1> [[TMP4]], i32 1
615 ; CHECK-NEXT: br i1 [[TMP11]], label %[[PRED_LOAD_IF1:.*]], label %[[PRED_LOAD_CONTINUE2]]
616 ; CHECK: [[PRED_LOAD_IF1]]:
617 ; CHECK-NEXT: [[TMP22:%.*]] = extractelement <2 x ptr> [[TMP5]], i32 1
618 ; CHECK-NEXT: [[TMP23:%.*]] = load i32, ptr [[TMP22]], align 4
619 ; CHECK-NEXT: [[TMP14:%.*]] = insertelement <2 x i32> [[TMP10]], i32 [[TMP23]], i32 1
620 ; CHECK-NEXT: br label %[[PRED_LOAD_CONTINUE2]]
621 ; CHECK: [[PRED_LOAD_CONTINUE2]]:
622 ; CHECK-NEXT: [[TMP15:%.*]] = phi <2 x i32> [ [[TMP10]], %[[PRED_LOAD_CONTINUE]] ], [ [[TMP14]], %[[PRED_LOAD_IF1]] ]
623 ; CHECK-NEXT: [[PREDPHI:%.*]] = select <2 x i1> [[TMP3]], <2 x i32> [[WIDE_LOAD]], <2 x i32> [[TMP15]]
624 ; CHECK-NEXT: [[TMP26:%.*]] = getelementptr inbounds i32, ptr [[C]], i64 [[TMP0]]
625 ; CHECK-NEXT: [[TMP27:%.*]] = getelementptr inbounds i32, ptr [[TMP26]], i32 0
626 ; CHECK-NEXT: store <2 x i32> [[PREDPHI]], ptr [[TMP27]], align 4
627 ; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 2
628 ; CHECK-NEXT: [[VEC_IND_NEXT]] = add <2 x i64> [[VEC_IND]], splat (i64 2)
629 ; CHECK-NEXT: [[TMP28:%.*]] = icmp eq i64 [[INDEX_NEXT]], 1000
630 ; CHECK-NEXT: br i1 [[TMP28]], label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]], !llvm.loop [[LOOP14:![0-9]+]]
631 ; CHECK: [[MIDDLE_BLOCK]]:
632 ; CHECK-NEXT: br i1 true, label %[[EXIT:.*]], label %[[SCALAR_PH]]
633 ; CHECK: [[SCALAR_PH]]:
634 ; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i64 [ 1000, %[[MIDDLE_BLOCK]] ], [ 0, %[[ENTRY]] ]
635 ; CHECK-NEXT: br label %[[LOOP_HEADER:.*]]
636 ; CHECK: [[LOOP_HEADER]]:
637 ; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[BC_RESUME_VAL]], %[[SCALAR_PH]] ], [ [[IV_NEXT:%.*]], %[[LOOP_LATCH:.*]] ]
638 ; CHECK-NEXT: [[GEP_B:%.*]] = getelementptr inbounds i32, ptr [[B]], i64 [[IV]]
639 ; CHECK-NEXT: [[L_B:%.*]] = load i32, ptr [[GEP_B]], align 4
640 ; CHECK-NEXT: [[C_1:%.*]] = icmp sge i32 [[L_B]], 0
641 ; CHECK-NEXT: br i1 [[C_1]], label %[[LOOP_LATCH]], label %[[LOOP_THEN:.*]]
642 ; CHECK: [[LOOP_THEN]]:
643 ; CHECK-NEXT: [[GEP_A:%.*]] = getelementptr i32, ptr [[A]], i64 [[IV]]
644 ; CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[GEP_A]], i64 4), "dereferenceable"(ptr [[GEP_A]], i64 4) ]
645 ; CHECK-NEXT: [[L_A:%.*]] = load i32, ptr [[GEP_A]], align 4
646 ; CHECK-NEXT: br label %[[LOOP_LATCH]]
647 ; CHECK: [[LOOP_LATCH]]:
648 ; CHECK-NEXT: [[MERGE:%.*]] = phi i32 [ [[L_A]], %[[LOOP_THEN]] ], [ [[L_B]], %[[LOOP_HEADER]] ]
649 ; CHECK-NEXT: [[GEP_C:%.*]] = getelementptr inbounds i32, ptr [[C]], i64 [[IV]]
650 ; CHECK-NEXT: store i32 [[MERGE]], ptr [[GEP_C]], align 4
651 ; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
652 ; CHECK-NEXT: [[EC:%.*]] = icmp eq i64 [[IV_NEXT]], 1000
653 ; CHECK-NEXT: br i1 [[EC]], label %[[EXIT]], label %[[LOOP_HEADER]], !llvm.loop [[LOOP15:![0-9]+]]
655 ; CHECK-NEXT: ret void
658 br label %loop.header
661 %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop.latch ]
662 %gep.b = getelementptr inbounds i32, ptr %b, i64 %iv
663 %l.b = load i32, ptr %gep.b, align 4
664 %c.1 = icmp sge i32 %l.b, 0
665 br i1 %c.1, label %loop.latch, label %loop.then
668 %gep.a = getelementptr i32, ptr %a, i64 %iv
669 call void @llvm.assume(i1 true) [ "align"(ptr %gep.a, i64 4), "dereferenceable"(ptr %gep.a, i64 4) ]
670 %l.a = load i32, ptr %gep.a, align 4
674 %merge = phi i32 [ %l.a, %loop.then ], [ %l.b, %loop.header ]
675 %gep.c = getelementptr inbounds i32, ptr %c, i64 %iv
676 store i32 %merge, ptr %gep.c, align 4
677 %iv.next = add nuw nsw i64 %iv, 1
678 %ec = icmp eq i64 %iv.next, 1000
679 br i1 %ec, label %exit, label %loop.header
685 define void @deref_assumption_in_latch_constant_trip_count(ptr noalias %a, ptr noalias %b, ptr noalias %c) nofree nosync{
686 ; CHECK-LABEL: define void @deref_assumption_in_latch_constant_trip_count(
687 ; CHECK-SAME: ptr noalias [[A:%.*]], ptr noalias [[B:%.*]], ptr noalias [[C:%.*]]) #[[ATTR1]] {
688 ; CHECK-NEXT: [[ENTRY:.*]]:
689 ; CHECK-NEXT: br i1 false, label %[[SCALAR_PH:.*]], label %[[VECTOR_PH:.*]]
690 ; CHECK: [[VECTOR_PH]]:
691 ; CHECK-NEXT: br label %[[VECTOR_BODY:.*]]
692 ; CHECK: [[VECTOR_BODY]]:
693 ; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, %[[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], %[[PRED_LOAD_CONTINUE2:.*]] ]
694 ; CHECK-NEXT: [[VEC_IND:%.*]] = phi <2 x i64> [ <i64 0, i64 1>, %[[VECTOR_PH]] ], [ [[VEC_IND_NEXT:%.*]], %[[PRED_LOAD_CONTINUE2]] ]
695 ; CHECK-NEXT: [[TMP0:%.*]] = add i64 [[INDEX]], 0
696 ; CHECK-NEXT: [[TMP1:%.*]] = getelementptr i32, ptr [[A]], <2 x i64> [[VEC_IND]]
697 ; CHECK-NEXT: [[TMP2:%.*]] = getelementptr inbounds i32, ptr [[B]], i64 [[TMP0]]
698 ; CHECK-NEXT: [[TMP3:%.*]] = getelementptr inbounds i32, ptr [[TMP2]], i32 0
699 ; CHECK-NEXT: [[WIDE_LOAD:%.*]] = load <2 x i32>, ptr [[TMP3]], align 4
700 ; CHECK-NEXT: [[TMP4:%.*]] = icmp sge <2 x i32> [[WIDE_LOAD]], zeroinitializer
701 ; CHECK-NEXT: [[TMP5:%.*]] = xor <2 x i1> [[TMP4]], splat (i1 true)
702 ; CHECK-NEXT: [[TMP6:%.*]] = extractelement <2 x i1> [[TMP5]], i32 0
703 ; CHECK-NEXT: br i1 [[TMP6]], label %[[PRED_LOAD_IF:.*]], label %[[PRED_LOAD_CONTINUE:.*]]
704 ; CHECK: [[PRED_LOAD_IF]]:
705 ; CHECK-NEXT: [[TMP17:%.*]] = extractelement <2 x ptr> [[TMP1]], i32 0
706 ; CHECK-NEXT: [[TMP18:%.*]] = load i32, ptr [[TMP17]], align 4
707 ; CHECK-NEXT: [[TMP9:%.*]] = insertelement <2 x i32> poison, i32 [[TMP18]], i32 0
708 ; CHECK-NEXT: br label %[[PRED_LOAD_CONTINUE]]
709 ; CHECK: [[PRED_LOAD_CONTINUE]]:
710 ; CHECK-NEXT: [[TMP10:%.*]] = phi <2 x i32> [ poison, %[[VECTOR_BODY]] ], [ [[TMP9]], %[[PRED_LOAD_IF]] ]
711 ; CHECK-NEXT: [[TMP11:%.*]] = extractelement <2 x i1> [[TMP5]], i32 1
712 ; CHECK-NEXT: br i1 [[TMP11]], label %[[PRED_LOAD_IF1:.*]], label %[[PRED_LOAD_CONTINUE2]]
713 ; CHECK: [[PRED_LOAD_IF1]]:
714 ; CHECK-NEXT: [[TMP22:%.*]] = extractelement <2 x ptr> [[TMP1]], i32 1
715 ; CHECK-NEXT: [[TMP23:%.*]] = load i32, ptr [[TMP22]], align 4
716 ; CHECK-NEXT: [[TMP14:%.*]] = insertelement <2 x i32> [[TMP10]], i32 [[TMP23]], i32 1
717 ; CHECK-NEXT: br label %[[PRED_LOAD_CONTINUE2]]
718 ; CHECK: [[PRED_LOAD_CONTINUE2]]:
719 ; CHECK-NEXT: [[TMP15:%.*]] = phi <2 x i32> [ [[TMP10]], %[[PRED_LOAD_CONTINUE]] ], [ [[TMP14]], %[[PRED_LOAD_IF1]] ]
720 ; CHECK-NEXT: [[PREDPHI:%.*]] = select <2 x i1> [[TMP4]], <2 x i32> [[WIDE_LOAD]], <2 x i32> [[TMP15]]
721 ; CHECK-NEXT: [[TMP28:%.*]] = extractelement <2 x ptr> [[TMP1]], i32 0
722 ; CHECK-NEXT: [[TMP20:%.*]] = extractelement <2 x ptr> [[TMP1]], i32 0
723 ; CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[TMP28]], i64 4), "dereferenceable"(ptr [[TMP20]], i64 4) ]
724 ; CHECK-NEXT: [[TMP29:%.*]] = extractelement <2 x ptr> [[TMP1]], i32 1
725 ; CHECK-NEXT: [[TMP19:%.*]] = extractelement <2 x ptr> [[TMP1]], i32 1
726 ; CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[TMP29]], i64 4), "dereferenceable"(ptr [[TMP19]], i64 4) ]
727 ; CHECK-NEXT: [[TMP30:%.*]] = getelementptr inbounds i32, ptr [[C]], i64 [[TMP0]]
728 ; CHECK-NEXT: [[TMP31:%.*]] = getelementptr inbounds i32, ptr [[TMP30]], i32 0
729 ; CHECK-NEXT: store <2 x i32> [[PREDPHI]], ptr [[TMP31]], align 4
730 ; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 2
731 ; CHECK-NEXT: [[VEC_IND_NEXT]] = add <2 x i64> [[VEC_IND]], splat (i64 2)
732 ; CHECK-NEXT: [[TMP32:%.*]] = icmp eq i64 [[INDEX_NEXT]], 1000
733 ; CHECK-NEXT: br i1 [[TMP32]], label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]], !llvm.loop [[LOOP16:![0-9]+]]
734 ; CHECK: [[MIDDLE_BLOCK]]:
735 ; CHECK-NEXT: br i1 true, label %[[EXIT:.*]], label %[[SCALAR_PH]]
736 ; CHECK: [[SCALAR_PH]]:
737 ; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i64 [ 1000, %[[MIDDLE_BLOCK]] ], [ 0, %[[ENTRY]] ]
738 ; CHECK-NEXT: br label %[[LOOP_HEADER:.*]]
739 ; CHECK: [[LOOP_HEADER]]:
740 ; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[BC_RESUME_VAL]], %[[SCALAR_PH]] ], [ [[IV_NEXT:%.*]], %[[LOOP_LATCH:.*]] ]
741 ; CHECK-NEXT: [[GEP_A:%.*]] = getelementptr i32, ptr [[A]], i64 [[IV]]
742 ; CHECK-NEXT: [[GEP_B:%.*]] = getelementptr inbounds i32, ptr [[B]], i64 [[IV]]
743 ; CHECK-NEXT: [[L_B:%.*]] = load i32, ptr [[GEP_B]], align 4
744 ; CHECK-NEXT: [[C_1:%.*]] = icmp sge i32 [[L_B]], 0
745 ; CHECK-NEXT: br i1 [[C_1]], label %[[LOOP_LATCH]], label %[[LOOP_THEN:.*]]
746 ; CHECK: [[LOOP_THEN]]:
747 ; CHECK-NEXT: [[L_A:%.*]] = load i32, ptr [[GEP_A]], align 4
748 ; CHECK-NEXT: br label %[[LOOP_LATCH]]
749 ; CHECK: [[LOOP_LATCH]]:
750 ; CHECK-NEXT: [[MERGE:%.*]] = phi i32 [ [[L_A]], %[[LOOP_THEN]] ], [ [[L_B]], %[[LOOP_HEADER]] ]
751 ; CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[GEP_A]], i64 4), "dereferenceable"(ptr [[GEP_A]], i64 4) ]
752 ; CHECK-NEXT: [[GEP_C:%.*]] = getelementptr inbounds i32, ptr [[C]], i64 [[IV]]
753 ; CHECK-NEXT: store i32 [[MERGE]], ptr [[GEP_C]], align 4
754 ; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
755 ; CHECK-NEXT: [[EC:%.*]] = icmp eq i64 [[IV_NEXT]], 1000
756 ; CHECK-NEXT: br i1 [[EC]], label %[[EXIT]], label %[[LOOP_HEADER]], !llvm.loop [[LOOP17:![0-9]+]]
758 ; CHECK-NEXT: ret void
761 br label %loop.header
764 %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop.latch ]
765 %gep.a = getelementptr i32, ptr %a, i64 %iv
766 %gep.b = getelementptr inbounds i32, ptr %b, i64 %iv
767 %l.b = load i32, ptr %gep.b, align 4
768 %c.1 = icmp sge i32 %l.b, 0
769 br i1 %c.1, label %loop.latch, label %loop.then
772 %l.a = load i32, ptr %gep.a, align 4
776 %merge = phi i32 [ %l.a, %loop.then ], [ %l.b, %loop.header ]
777 call void @llvm.assume(i1 true) [ "align"(ptr %gep.a, i64 4), "dereferenceable"(ptr %gep.a, i64 4) ]
778 %gep.c = getelementptr inbounds i32, ptr %c, i64 %iv
779 store i32 %merge, ptr %gep.c, align 4
780 %iv.next = add nuw nsw i64 %iv, 1
781 %ec = icmp eq i64 %iv.next, 1000
782 br i1 %ec, label %exit, label %loop.header
788 define void @deref_assumption_in_header_variable_trip_count(ptr noalias %a, ptr noalias %b, ptr noalias %c, i64 %N) nofree nosync{
789 ; CHECK-LABEL: define void @deref_assumption_in_header_variable_trip_count(
790 ; CHECK-SAME: ptr noalias [[A:%.*]], ptr noalias [[B:%.*]], ptr noalias [[C:%.*]], i64 [[N:%.*]]) #[[ATTR1]] {
791 ; CHECK-NEXT: [[ENTRY:.*]]:
792 ; CHECK-NEXT: [[MIN_ITERS_CHECK:%.*]] = icmp ult i64 [[N]], 2
793 ; CHECK-NEXT: br i1 [[MIN_ITERS_CHECK]], label %[[SCALAR_PH:.*]], label %[[VECTOR_PH:.*]]
794 ; CHECK: [[VECTOR_PH]]:
795 ; CHECK-NEXT: [[N_MOD_VF:%.*]] = urem i64 [[N]], 2
796 ; CHECK-NEXT: [[N_VEC:%.*]] = sub i64 [[N]], [[N_MOD_VF]]
797 ; CHECK-NEXT: br label %[[VECTOR_BODY:.*]]
798 ; CHECK: [[VECTOR_BODY]]:
799 ; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, %[[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], %[[PRED_LOAD_CONTINUE2:.*]] ]
800 ; CHECK-NEXT: [[VEC_IND:%.*]] = phi <2 x i64> [ <i64 0, i64 1>, %[[VECTOR_PH]] ], [ [[VEC_IND_NEXT:%.*]], %[[PRED_LOAD_CONTINUE2]] ]
801 ; CHECK-NEXT: [[TMP0:%.*]] = add i64 [[INDEX]], 0
802 ; CHECK-NEXT: [[TMP1:%.*]] = getelementptr i32, ptr [[A]], <2 x i64> [[VEC_IND]]
803 ; CHECK-NEXT: [[TMP4:%.*]] = extractelement <2 x ptr> [[TMP1]], i32 0
804 ; CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[TMP4]], i64 4), "dereferenceable"(ptr [[TMP4]], i64 4) ]
805 ; CHECK-NEXT: [[TMP5:%.*]] = extractelement <2 x ptr> [[TMP1]], i32 1
806 ; CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[TMP5]], i64 4), "dereferenceable"(ptr [[TMP5]], i64 4) ]
807 ; CHECK-NEXT: [[TMP6:%.*]] = getelementptr inbounds i32, ptr [[B]], i64 [[TMP0]]
808 ; CHECK-NEXT: [[TMP7:%.*]] = getelementptr inbounds i32, ptr [[TMP6]], i32 0
809 ; CHECK-NEXT: [[WIDE_LOAD:%.*]] = load <2 x i32>, ptr [[TMP7]], align 4
810 ; CHECK-NEXT: [[TMP9:%.*]] = icmp sge <2 x i32> [[WIDE_LOAD]], zeroinitializer
811 ; CHECK-NEXT: [[TMP10:%.*]] = xor <2 x i1> [[TMP9]], splat (i1 true)
812 ; CHECK-NEXT: [[TMP8:%.*]] = extractelement <2 x i1> [[TMP10]], i32 0
813 ; CHECK-NEXT: br i1 [[TMP8]], label %[[PRED_LOAD_IF:.*]], label %[[PRED_LOAD_CONTINUE:.*]]
814 ; CHECK: [[PRED_LOAD_IF]]:
815 ; CHECK-NEXT: [[TMP21:%.*]] = extractelement <2 x ptr> [[TMP1]], i32 0
816 ; CHECK-NEXT: [[TMP22:%.*]] = load i32, ptr [[TMP21]], align 4
817 ; CHECK-NEXT: [[TMP11:%.*]] = insertelement <2 x i32> poison, i32 [[TMP22]], i32 0
818 ; CHECK-NEXT: br label %[[PRED_LOAD_CONTINUE]]
819 ; CHECK: [[PRED_LOAD_CONTINUE]]:
820 ; CHECK-NEXT: [[TMP12:%.*]] = phi <2 x i32> [ poison, %[[VECTOR_BODY]] ], [ [[TMP11]], %[[PRED_LOAD_IF]] ]
821 ; CHECK-NEXT: [[TMP13:%.*]] = extractelement <2 x i1> [[TMP10]], i32 1
822 ; CHECK-NEXT: br i1 [[TMP13]], label %[[PRED_LOAD_IF1:.*]], label %[[PRED_LOAD_CONTINUE2]]
823 ; CHECK: [[PRED_LOAD_IF1]]:
824 ; CHECK-NEXT: [[TMP26:%.*]] = extractelement <2 x ptr> [[TMP1]], i32 1
825 ; CHECK-NEXT: [[TMP27:%.*]] = load i32, ptr [[TMP26]], align 4
826 ; CHECK-NEXT: [[TMP16:%.*]] = insertelement <2 x i32> [[TMP12]], i32 [[TMP27]], i32 1
827 ; CHECK-NEXT: br label %[[PRED_LOAD_CONTINUE2]]
828 ; CHECK: [[PRED_LOAD_CONTINUE2]]:
829 ; CHECK-NEXT: [[TMP17:%.*]] = phi <2 x i32> [ [[TMP12]], %[[PRED_LOAD_CONTINUE]] ], [ [[TMP16]], %[[PRED_LOAD_IF1]] ]
830 ; CHECK-NEXT: [[PREDPHI:%.*]] = select <2 x i1> [[TMP9]], <2 x i32> [[WIDE_LOAD]], <2 x i32> [[TMP17]]
831 ; CHECK-NEXT: [[TMP30:%.*]] = getelementptr inbounds i32, ptr [[C]], i64 [[TMP0]]
832 ; CHECK-NEXT: [[TMP31:%.*]] = getelementptr inbounds i32, ptr [[TMP30]], i32 0
833 ; CHECK-NEXT: store <2 x i32> [[PREDPHI]], ptr [[TMP31]], align 4
834 ; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 2
835 ; CHECK-NEXT: [[VEC_IND_NEXT]] = add <2 x i64> [[VEC_IND]], splat (i64 2)
836 ; CHECK-NEXT: [[TMP32:%.*]] = icmp eq i64 [[INDEX_NEXT]], [[N_VEC]]
837 ; CHECK-NEXT: br i1 [[TMP32]], label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]], !llvm.loop [[LOOP18:![0-9]+]]
838 ; CHECK: [[MIDDLE_BLOCK]]:
839 ; CHECK-NEXT: [[CMP_N:%.*]] = icmp eq i64 [[N]], [[N_VEC]]
840 ; CHECK-NEXT: br i1 [[CMP_N]], label %[[EXIT:.*]], label %[[SCALAR_PH]]
841 ; CHECK: [[SCALAR_PH]]:
842 ; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i64 [ [[N_VEC]], %[[MIDDLE_BLOCK]] ], [ 0, %[[ENTRY]] ]
843 ; CHECK-NEXT: br label %[[LOOP_HEADER:.*]]
844 ; CHECK: [[LOOP_HEADER]]:
845 ; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[BC_RESUME_VAL]], %[[SCALAR_PH]] ], [ [[IV_NEXT:%.*]], %[[LOOP_LATCH:.*]] ]
846 ; CHECK-NEXT: [[GEP_A:%.*]] = getelementptr i32, ptr [[A]], i64 [[IV]]
847 ; CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[GEP_A]], i64 4), "dereferenceable"(ptr [[GEP_A]], i64 4) ]
848 ; CHECK-NEXT: [[GEP_B:%.*]] = getelementptr inbounds i32, ptr [[B]], i64 [[IV]]
849 ; CHECK-NEXT: [[L_B:%.*]] = load i32, ptr [[GEP_B]], align 4
850 ; CHECK-NEXT: [[C_1:%.*]] = icmp sge i32 [[L_B]], 0
851 ; CHECK-NEXT: br i1 [[C_1]], label %[[LOOP_LATCH]], label %[[LOOP_THEN:.*]]
852 ; CHECK: [[LOOP_THEN]]:
853 ; CHECK-NEXT: [[L_A:%.*]] = load i32, ptr [[GEP_A]], align 4
854 ; CHECK-NEXT: br label %[[LOOP_LATCH]]
855 ; CHECK: [[LOOP_LATCH]]:
856 ; CHECK-NEXT: [[MERGE:%.*]] = phi i32 [ [[L_A]], %[[LOOP_THEN]] ], [ [[L_B]], %[[LOOP_HEADER]] ]
857 ; CHECK-NEXT: [[GEP_C:%.*]] = getelementptr inbounds i32, ptr [[C]], i64 [[IV]]
858 ; CHECK-NEXT: store i32 [[MERGE]], ptr [[GEP_C]], align 4
859 ; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
860 ; CHECK-NEXT: [[EC:%.*]] = icmp eq i64 [[IV_NEXT]], [[N]]
861 ; CHECK-NEXT: br i1 [[EC]], label %[[EXIT]], label %[[LOOP_HEADER]], !llvm.loop [[LOOP19:![0-9]+]]
863 ; CHECK-NEXT: ret void
866 br label %loop.header
869 %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop.latch ]
870 %gep.a = getelementptr i32, ptr %a, i64 %iv
871 call void @llvm.assume(i1 true) [ "align"(ptr %gep.a, i64 4), "dereferenceable"(ptr %gep.a, i64 4) ]
872 %gep.b = getelementptr inbounds i32, ptr %b, i64 %iv
873 %l.b = load i32, ptr %gep.b, align 4
874 %c.1 = icmp sge i32 %l.b, 0
875 br i1 %c.1, label %loop.latch, label %loop.then
878 %l.a = load i32, ptr %gep.a, align 4
882 %merge = phi i32 [ %l.a, %loop.then ], [ %l.b, %loop.header ]
883 %gep.c = getelementptr inbounds i32, ptr %c, i64 %iv
884 store i32 %merge, ptr %gep.c, align 4
885 %iv.next = add nuw nsw i64 %iv, 1
886 %ec = icmp eq i64 %iv.next, %N
887 br i1 %ec, label %exit, label %loop.header
893 define void @deref_assumption_in_preheader_constant_trip_count_align_1(ptr noalias %a, ptr noalias %b, ptr noalias %c) nofree nosync{
894 ; CHECK-LABEL: define void @deref_assumption_in_preheader_constant_trip_count_align_1(
895 ; CHECK-SAME: ptr noalias [[A:%.*]], ptr noalias [[B:%.*]], ptr noalias [[C:%.*]]) #[[ATTR1]] {
896 ; CHECK-NEXT: [[ENTRY:.*]]:
897 ; CHECK-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(ptr [[A]], i64 4000) ]
898 ; CHECK-NEXT: br i1 false, label %[[SCALAR_PH:.*]], label %[[VECTOR_PH:.*]]
899 ; CHECK: [[VECTOR_PH]]:
900 ; CHECK-NEXT: br label %[[VECTOR_BODY:.*]]
901 ; CHECK: [[VECTOR_BODY]]:
902 ; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, %[[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], %[[VECTOR_BODY]] ]
903 ; CHECK-NEXT: [[TMP0:%.*]] = add i64 [[INDEX]], 0
904 ; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds i32, ptr [[B]], i64 [[TMP0]]
905 ; CHECK-NEXT: [[TMP2:%.*]] = getelementptr inbounds i32, ptr [[TMP1]], i32 0
906 ; CHECK-NEXT: [[WIDE_LOAD:%.*]] = load <2 x i32>, ptr [[TMP2]], align 4
907 ; CHECK-NEXT: [[TMP3:%.*]] = icmp sge <2 x i32> [[WIDE_LOAD]], zeroinitializer
908 ; CHECK-NEXT: [[TMP6:%.*]] = getelementptr i32, ptr [[A]], i64 [[TMP0]]
909 ; CHECK-NEXT: [[TMP5:%.*]] = getelementptr i32, ptr [[TMP6]], i32 0
910 ; CHECK-NEXT: [[TMP15:%.*]] = load <2 x i32>, ptr [[TMP5]], align 1
911 ; CHECK-NEXT: [[PREDPHI:%.*]] = select <2 x i1> [[TMP3]], <2 x i32> [[WIDE_LOAD]], <2 x i32> [[TMP15]]
912 ; CHECK-NEXT: [[TMP16:%.*]] = getelementptr inbounds i32, ptr [[C]], i64 [[TMP0]]
913 ; CHECK-NEXT: [[TMP17:%.*]] = getelementptr inbounds i32, ptr [[TMP16]], i32 0
914 ; CHECK-NEXT: store <2 x i32> [[PREDPHI]], ptr [[TMP17]], align 4
915 ; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 2
916 ; CHECK-NEXT: [[TMP18:%.*]] = icmp eq i64 [[INDEX_NEXT]], 1000
917 ; CHECK-NEXT: br i1 [[TMP18]], label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]], !llvm.loop [[LOOP20:![0-9]+]]
918 ; CHECK: [[MIDDLE_BLOCK]]:
919 ; CHECK-NEXT: br i1 true, label %[[EXIT:.*]], label %[[SCALAR_PH]]
920 ; CHECK: [[SCALAR_PH]]:
921 ; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i64 [ 1000, %[[MIDDLE_BLOCK]] ], [ 0, %[[ENTRY]] ]
922 ; CHECK-NEXT: br label %[[LOOP_HEADER:.*]]
923 ; CHECK: [[LOOP_HEADER]]:
924 ; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[BC_RESUME_VAL]], %[[SCALAR_PH]] ], [ [[IV_NEXT:%.*]], %[[LOOP_LATCH:.*]] ]
925 ; CHECK-NEXT: [[GEP_B:%.*]] = getelementptr inbounds i32, ptr [[B]], i64 [[IV]]
926 ; CHECK-NEXT: [[L_B:%.*]] = load i32, ptr [[GEP_B]], align 4
927 ; CHECK-NEXT: [[C_1:%.*]] = icmp sge i32 [[L_B]], 0
928 ; CHECK-NEXT: br i1 [[C_1]], label %[[LOOP_LATCH]], label %[[LOOP_THEN:.*]]
929 ; CHECK: [[LOOP_THEN]]:
930 ; CHECK-NEXT: [[GEP_A:%.*]] = getelementptr i32, ptr [[A]], i64 [[IV]]
931 ; CHECK-NEXT: [[L_A:%.*]] = load i32, ptr [[GEP_A]], align 1
932 ; CHECK-NEXT: br label %[[LOOP_LATCH]]
933 ; CHECK: [[LOOP_LATCH]]:
934 ; CHECK-NEXT: [[MERGE:%.*]] = phi i32 [ [[L_A]], %[[LOOP_THEN]] ], [ [[L_B]], %[[LOOP_HEADER]] ]
935 ; CHECK-NEXT: [[GEP_C:%.*]] = getelementptr inbounds i32, ptr [[C]], i64 [[IV]]
936 ; CHECK-NEXT: store i32 [[MERGE]], ptr [[GEP_C]], align 4
937 ; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
938 ; CHECK-NEXT: [[EC:%.*]] = icmp eq i64 [[IV_NEXT]], 1000
939 ; CHECK-NEXT: br i1 [[EC]], label %[[EXIT]], label %[[LOOP_HEADER]], !llvm.loop [[LOOP21:![0-9]+]]
941 ; CHECK-NEXT: ret void
944 call void @llvm.assume(i1 true) [ "dereferenceable"(ptr %a, i64 4000) ]
945 br label %loop.header
948 %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop.latch ]
949 %gep.b = getelementptr inbounds i32, ptr %b, i64 %iv
950 %l.b = load i32, ptr %gep.b, align 4
951 %c.1 = icmp sge i32 %l.b, 0
952 br i1 %c.1, label %loop.latch, label %loop.then
955 %gep.a = getelementptr i32, ptr %a, i64 %iv
956 %l.a = load i32, ptr %gep.a, align 1
960 %merge = phi i32 [ %l.a, %loop.then ], [ %l.b, %loop.header ]
961 %gep.c = getelementptr inbounds i32, ptr %c, i64 %iv
962 store i32 %merge, ptr %gep.c, align 4
963 %iv.next = add nuw nsw i64 %iv, 1
964 %ec = icmp eq i64 %iv.next, 1000
965 br i1 %ec, label %exit, label %loop.header
971 define void @deref_assumption_too_small_in_preheader_constant_trip_count_align_1(ptr noalias %a, ptr noalias %b, ptr noalias %c) nofree nosync{
972 ; CHECK-LABEL: define void @deref_assumption_too_small_in_preheader_constant_trip_count_align_1(
973 ; CHECK-SAME: ptr noalias [[A:%.*]], ptr noalias [[B:%.*]], ptr noalias [[C:%.*]]) #[[ATTR1]] {
974 ; CHECK-NEXT: [[ENTRY:.*]]:
975 ; CHECK-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(ptr [[A]], i64 3999) ]
976 ; CHECK-NEXT: br i1 false, label %[[SCALAR_PH:.*]], label %[[VECTOR_PH:.*]]
977 ; CHECK: [[VECTOR_PH]]:
978 ; CHECK-NEXT: br label %[[VECTOR_BODY:.*]]
979 ; CHECK: [[VECTOR_BODY]]:
980 ; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, %[[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], %[[PRED_LOAD_CONTINUE2:.*]] ]
981 ; CHECK-NEXT: [[TMP0:%.*]] = add i64 [[INDEX]], 0
982 ; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds i32, ptr [[B]], i64 [[TMP0]]
983 ; CHECK-NEXT: [[TMP2:%.*]] = getelementptr inbounds i32, ptr [[TMP1]], i32 0
984 ; CHECK-NEXT: [[WIDE_LOAD:%.*]] = load <2 x i32>, ptr [[TMP2]], align 4
985 ; CHECK-NEXT: [[TMP3:%.*]] = icmp sge <2 x i32> [[WIDE_LOAD]], zeroinitializer
986 ; CHECK-NEXT: [[TMP4:%.*]] = xor <2 x i1> [[TMP3]], splat (i1 true)
987 ; CHECK-NEXT: [[TMP5:%.*]] = extractelement <2 x i1> [[TMP4]], i32 0
988 ; CHECK-NEXT: br i1 [[TMP5]], label %[[PRED_LOAD_IF:.*]], label %[[PRED_LOAD_CONTINUE:.*]]
989 ; CHECK: [[PRED_LOAD_IF]]:
990 ; CHECK-NEXT: [[TMP6:%.*]] = getelementptr i32, ptr [[A]], i64 [[TMP0]]
991 ; CHECK-NEXT: [[TMP7:%.*]] = load i32, ptr [[TMP6]], align 1
992 ; CHECK-NEXT: [[TMP8:%.*]] = insertelement <2 x i32> poison, i32 [[TMP7]], i32 0
993 ; CHECK-NEXT: br label %[[PRED_LOAD_CONTINUE]]
994 ; CHECK: [[PRED_LOAD_CONTINUE]]:
995 ; CHECK-NEXT: [[TMP9:%.*]] = phi <2 x i32> [ poison, %[[VECTOR_BODY]] ], [ [[TMP8]], %[[PRED_LOAD_IF]] ]
996 ; CHECK-NEXT: [[TMP10:%.*]] = extractelement <2 x i1> [[TMP4]], i32 1
997 ; CHECK-NEXT: br i1 [[TMP10]], label %[[PRED_LOAD_IF1:.*]], label %[[PRED_LOAD_CONTINUE2]]
998 ; CHECK: [[PRED_LOAD_IF1]]:
999 ; CHECK-NEXT: [[TMP11:%.*]] = add i64 [[INDEX]], 1
1000 ; CHECK-NEXT: [[TMP12:%.*]] = getelementptr i32, ptr [[A]], i64 [[TMP11]]
1001 ; CHECK-NEXT: [[TMP13:%.*]] = load i32, ptr [[TMP12]], align 1
1002 ; CHECK-NEXT: [[TMP14:%.*]] = insertelement <2 x i32> [[TMP9]], i32 [[TMP13]], i32 1
1003 ; CHECK-NEXT: br label %[[PRED_LOAD_CONTINUE2]]
1004 ; CHECK: [[PRED_LOAD_CONTINUE2]]:
1005 ; CHECK-NEXT: [[TMP15:%.*]] = phi <2 x i32> [ [[TMP9]], %[[PRED_LOAD_CONTINUE]] ], [ [[TMP14]], %[[PRED_LOAD_IF1]] ]
1006 ; CHECK-NEXT: [[PREDPHI:%.*]] = select <2 x i1> [[TMP3]], <2 x i32> [[WIDE_LOAD]], <2 x i32> [[TMP15]]
1007 ; CHECK-NEXT: [[TMP16:%.*]] = getelementptr inbounds i32, ptr [[C]], i64 [[TMP0]]
1008 ; CHECK-NEXT: [[TMP17:%.*]] = getelementptr inbounds i32, ptr [[TMP16]], i32 0
1009 ; CHECK-NEXT: store <2 x i32> [[PREDPHI]], ptr [[TMP17]], align 4
1010 ; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 2
1011 ; CHECK-NEXT: [[TMP18:%.*]] = icmp eq i64 [[INDEX_NEXT]], 1000
1012 ; CHECK-NEXT: br i1 [[TMP18]], label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]], !llvm.loop [[LOOP22:![0-9]+]]
1013 ; CHECK: [[MIDDLE_BLOCK]]:
1014 ; CHECK-NEXT: br i1 true, label %[[EXIT:.*]], label %[[SCALAR_PH]]
1015 ; CHECK: [[SCALAR_PH]]:
1016 ; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i64 [ 1000, %[[MIDDLE_BLOCK]] ], [ 0, %[[ENTRY]] ]
1017 ; CHECK-NEXT: br label %[[LOOP_HEADER:.*]]
1018 ; CHECK: [[LOOP_HEADER]]:
1019 ; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[BC_RESUME_VAL]], %[[SCALAR_PH]] ], [ [[IV_NEXT:%.*]], %[[LOOP_LATCH:.*]] ]
1020 ; CHECK-NEXT: [[GEP_B:%.*]] = getelementptr inbounds i32, ptr [[B]], i64 [[IV]]
1021 ; CHECK-NEXT: [[L_B:%.*]] = load i32, ptr [[GEP_B]], align 4
1022 ; CHECK-NEXT: [[C_1:%.*]] = icmp sge i32 [[L_B]], 0
1023 ; CHECK-NEXT: br i1 [[C_1]], label %[[LOOP_LATCH]], label %[[LOOP_THEN:.*]]
1024 ; CHECK: [[LOOP_THEN]]:
1025 ; CHECK-NEXT: [[GEP_A:%.*]] = getelementptr i32, ptr [[A]], i64 [[IV]]
1026 ; CHECK-NEXT: [[L_A:%.*]] = load i32, ptr [[GEP_A]], align 1
1027 ; CHECK-NEXT: br label %[[LOOP_LATCH]]
1028 ; CHECK: [[LOOP_LATCH]]:
1029 ; CHECK-NEXT: [[MERGE:%.*]] = phi i32 [ [[L_A]], %[[LOOP_THEN]] ], [ [[L_B]], %[[LOOP_HEADER]] ]
1030 ; CHECK-NEXT: [[GEP_C:%.*]] = getelementptr inbounds i32, ptr [[C]], i64 [[IV]]
1031 ; CHECK-NEXT: store i32 [[MERGE]], ptr [[GEP_C]], align 4
1032 ; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
1033 ; CHECK-NEXT: [[EC:%.*]] = icmp eq i64 [[IV_NEXT]], 1000
1034 ; CHECK-NEXT: br i1 [[EC]], label %[[EXIT]], label %[[LOOP_HEADER]], !llvm.loop [[LOOP23:![0-9]+]]
1036 ; CHECK-NEXT: ret void
1039 call void @llvm.assume(i1 true) [ "dereferenceable"(ptr %a, i64 3999) ]
1040 br label %loop.header
1043 %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop.latch ]
1044 %gep.b = getelementptr inbounds i32, ptr %b, i64 %iv
1045 %l.b = load i32, ptr %gep.b, align 4
1046 %c.1 = icmp sge i32 %l.b, 0
1047 br i1 %c.1, label %loop.latch, label %loop.then
1050 %gep.a = getelementptr i32, ptr %a, i64 %iv
1051 %l.a = load i32, ptr %gep.a, align 1
1052 br label %loop.latch
1055 %merge = phi i32 [ %l.a, %loop.then ], [ %l.b, %loop.header ]
1056 %gep.c = getelementptr inbounds i32, ptr %c, i64 %iv
1057 store i32 %merge, ptr %gep.c, align 4
1058 %iv.next = add nuw nsw i64 %iv, 1
1059 %ec = icmp eq i64 %iv.next, 1000
1060 br i1 %ec, label %exit, label %loop.header
1066 define void @align_and_deref_assumption_in_preheader_constant_trip_count_align_4(ptr noalias %a, ptr noalias %b, ptr noalias %c) nofree nosync{
1067 ; CHECK-LABEL: define void @align_and_deref_assumption_in_preheader_constant_trip_count_align_4(
1068 ; CHECK-SAME: ptr noalias [[A:%.*]], ptr noalias [[B:%.*]], ptr noalias [[C:%.*]]) #[[ATTR1]] {
1069 ; CHECK-NEXT: [[ENTRY:.*]]:
1070 ; CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[A]], i64 4), "dereferenceable"(ptr [[A]], i64 4000) ]
1071 ; CHECK-NEXT: br i1 false, label %[[SCALAR_PH:.*]], label %[[VECTOR_PH:.*]]
1072 ; CHECK: [[VECTOR_PH]]:
1073 ; CHECK-NEXT: br label %[[VECTOR_BODY:.*]]
1074 ; CHECK: [[VECTOR_BODY]]:
1075 ; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, %[[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], %[[VECTOR_BODY]] ]
1076 ; CHECK-NEXT: [[TMP0:%.*]] = add i64 [[INDEX]], 0
1077 ; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds i32, ptr [[B]], i64 [[TMP0]]
1078 ; CHECK-NEXT: [[TMP2:%.*]] = getelementptr inbounds i32, ptr [[TMP1]], i32 0
1079 ; CHECK-NEXT: [[WIDE_LOAD:%.*]] = load <2 x i32>, ptr [[TMP2]], align 4
1080 ; CHECK-NEXT: [[TMP3:%.*]] = icmp sge <2 x i32> [[WIDE_LOAD]], zeroinitializer
1081 ; CHECK-NEXT: [[TMP4:%.*]] = getelementptr i32, ptr [[A]], i64 [[TMP0]]
1082 ; CHECK-NEXT: [[TMP5:%.*]] = getelementptr i32, ptr [[TMP4]], i32 0
1083 ; CHECK-NEXT: [[WIDE_LOAD1:%.*]] = load <2 x i32>, ptr [[TMP5]], align 4
1084 ; CHECK-NEXT: [[PREDPHI:%.*]] = select <2 x i1> [[TMP3]], <2 x i32> [[WIDE_LOAD]], <2 x i32> [[WIDE_LOAD1]]
1085 ; CHECK-NEXT: [[TMP6:%.*]] = getelementptr inbounds i32, ptr [[C]], i64 [[TMP0]]
1086 ; CHECK-NEXT: [[TMP7:%.*]] = getelementptr inbounds i32, ptr [[TMP6]], i32 0
1087 ; CHECK-NEXT: store <2 x i32> [[PREDPHI]], ptr [[TMP7]], align 4
1088 ; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 2
1089 ; CHECK-NEXT: [[TMP8:%.*]] = icmp eq i64 [[INDEX_NEXT]], 1000
1090 ; CHECK-NEXT: br i1 [[TMP8]], label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]], !llvm.loop [[LOOP24:![0-9]+]]
1091 ; CHECK: [[MIDDLE_BLOCK]]:
1092 ; CHECK-NEXT: br i1 true, label %[[EXIT:.*]], label %[[SCALAR_PH]]
1093 ; CHECK: [[SCALAR_PH]]:
1094 ; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i64 [ 1000, %[[MIDDLE_BLOCK]] ], [ 0, %[[ENTRY]] ]
1095 ; CHECK-NEXT: br label %[[LOOP_HEADER:.*]]
1096 ; CHECK: [[LOOP_HEADER]]:
1097 ; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[BC_RESUME_VAL]], %[[SCALAR_PH]] ], [ [[IV_NEXT:%.*]], %[[LOOP_LATCH:.*]] ]
1098 ; CHECK-NEXT: [[GEP_B:%.*]] = getelementptr inbounds i32, ptr [[B]], i64 [[IV]]
1099 ; CHECK-NEXT: [[L_B:%.*]] = load i32, ptr [[GEP_B]], align 4
1100 ; CHECK-NEXT: [[C_1:%.*]] = icmp sge i32 [[L_B]], 0
1101 ; CHECK-NEXT: br i1 [[C_1]], label %[[LOOP_LATCH]], label %[[LOOP_THEN:.*]]
1102 ; CHECK: [[LOOP_THEN]]:
1103 ; CHECK-NEXT: [[GEP_A:%.*]] = getelementptr i32, ptr [[A]], i64 [[IV]]
1104 ; CHECK-NEXT: [[L_A:%.*]] = load i32, ptr [[GEP_A]], align 4
1105 ; CHECK-NEXT: br label %[[LOOP_LATCH]]
1106 ; CHECK: [[LOOP_LATCH]]:
1107 ; CHECK-NEXT: [[MERGE:%.*]] = phi i32 [ [[L_A]], %[[LOOP_THEN]] ], [ [[L_B]], %[[LOOP_HEADER]] ]
1108 ; CHECK-NEXT: [[GEP_C:%.*]] = getelementptr inbounds i32, ptr [[C]], i64 [[IV]]
1109 ; CHECK-NEXT: store i32 [[MERGE]], ptr [[GEP_C]], align 4
1110 ; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
1111 ; CHECK-NEXT: [[EC:%.*]] = icmp eq i64 [[IV_NEXT]], 1000
1112 ; CHECK-NEXT: br i1 [[EC]], label %[[EXIT]], label %[[LOOP_HEADER]], !llvm.loop [[LOOP25:![0-9]+]]
1114 ; CHECK-NEXT: ret void
1117 call void @llvm.assume(i1 true) [ "align"(ptr %a, i64 4), "dereferenceable"(ptr %a, i64 4000) ]
1118 br label %loop.header
1121 %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop.latch ]
1122 %gep.b = getelementptr inbounds i32, ptr %b, i64 %iv
1123 %l.b = load i32, ptr %gep.b, align 4
1124 %c.1 = icmp sge i32 %l.b, 0
1125 br i1 %c.1, label %loop.latch, label %loop.then
1128 %gep.a = getelementptr i32, ptr %a, i64 %iv
1129 %l.a = load i32, ptr %gep.a, align 4
1130 br label %loop.latch
1133 %merge = phi i32 [ %l.a, %loop.then ], [ %l.b, %loop.header ]
1134 %gep.c = getelementptr inbounds i32, ptr %c, i64 %iv
1135 store i32 %merge, ptr %gep.c, align 4
1136 %iv.next = add nuw nsw i64 %iv, 1
1137 %ec = icmp eq i64 %iv.next, 1000
1138 br i1 %ec, label %exit, label %loop.header
1145 define void @deref_assumption_in_preheader_constant_trip_count_align_4_known_via_argument_attr(ptr noalias align 4 %a, ptr noalias %b, ptr noalias %c) nofree nosync{
1146 ; CHECK-LABEL: define void @deref_assumption_in_preheader_constant_trip_count_align_4_known_via_argument_attr(
1147 ; CHECK-SAME: ptr noalias align 4 [[A:%.*]], ptr noalias [[B:%.*]], ptr noalias [[C:%.*]]) #[[ATTR1]] {
1148 ; CHECK-NEXT: [[ENTRY:.*]]:
1149 ; CHECK-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(ptr [[A]], i64 4000) ]
1150 ; CHECK-NEXT: br i1 false, label %[[SCALAR_PH:.*]], label %[[VECTOR_PH:.*]]
1151 ; CHECK: [[VECTOR_PH]]:
1152 ; CHECK-NEXT: br label %[[VECTOR_BODY:.*]]
1153 ; CHECK: [[VECTOR_BODY]]:
1154 ; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, %[[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], %[[VECTOR_BODY]] ]
1155 ; CHECK-NEXT: [[TMP0:%.*]] = add i64 [[INDEX]], 0
1156 ; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds i32, ptr [[B]], i64 [[TMP0]]
1157 ; CHECK-NEXT: [[TMP2:%.*]] = getelementptr inbounds i32, ptr [[TMP1]], i32 0
1158 ; CHECK-NEXT: [[WIDE_LOAD:%.*]] = load <2 x i32>, ptr [[TMP2]], align 4
1159 ; CHECK-NEXT: [[TMP3:%.*]] = icmp sge <2 x i32> [[WIDE_LOAD]], zeroinitializer
1160 ; CHECK-NEXT: [[TMP6:%.*]] = getelementptr i32, ptr [[A]], i64 [[TMP0]]
1161 ; CHECK-NEXT: [[TMP5:%.*]] = getelementptr i32, ptr [[TMP6]], i32 0
1162 ; CHECK-NEXT: [[TMP15:%.*]] = load <2 x i32>, ptr [[TMP5]], align 4
1163 ; CHECK-NEXT: [[PREDPHI:%.*]] = select <2 x i1> [[TMP3]], <2 x i32> [[WIDE_LOAD]], <2 x i32> [[TMP15]]
1164 ; CHECK-NEXT: [[TMP16:%.*]] = getelementptr inbounds i32, ptr [[C]], i64 [[TMP0]]
1165 ; CHECK-NEXT: [[TMP17:%.*]] = getelementptr inbounds i32, ptr [[TMP16]], i32 0
1166 ; CHECK-NEXT: store <2 x i32> [[PREDPHI]], ptr [[TMP17]], align 4
1167 ; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 2
1168 ; CHECK-NEXT: [[TMP18:%.*]] = icmp eq i64 [[INDEX_NEXT]], 1000
1169 ; CHECK-NEXT: br i1 [[TMP18]], label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]], !llvm.loop [[LOOP26:![0-9]+]]
1170 ; CHECK: [[MIDDLE_BLOCK]]:
1171 ; CHECK-NEXT: br i1 true, label %[[EXIT:.*]], label %[[SCALAR_PH]]
1172 ; CHECK: [[SCALAR_PH]]:
1173 ; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i64 [ 1000, %[[MIDDLE_BLOCK]] ], [ 0, %[[ENTRY]] ]
1174 ; CHECK-NEXT: br label %[[LOOP_HEADER:.*]]
1175 ; CHECK: [[LOOP_HEADER]]:
1176 ; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[BC_RESUME_VAL]], %[[SCALAR_PH]] ], [ [[IV_NEXT:%.*]], %[[LOOP_LATCH:.*]] ]
1177 ; CHECK-NEXT: [[GEP_B:%.*]] = getelementptr inbounds i32, ptr [[B]], i64 [[IV]]
1178 ; CHECK-NEXT: [[L_B:%.*]] = load i32, ptr [[GEP_B]], align 4
1179 ; CHECK-NEXT: [[C_1:%.*]] = icmp sge i32 [[L_B]], 0
1180 ; CHECK-NEXT: br i1 [[C_1]], label %[[LOOP_LATCH]], label %[[LOOP_THEN:.*]]
1181 ; CHECK: [[LOOP_THEN]]:
1182 ; CHECK-NEXT: [[GEP_A:%.*]] = getelementptr i32, ptr [[A]], i64 [[IV]]
1183 ; CHECK-NEXT: [[L_A:%.*]] = load i32, ptr [[GEP_A]], align 4
1184 ; CHECK-NEXT: br label %[[LOOP_LATCH]]
1185 ; CHECK: [[LOOP_LATCH]]:
1186 ; CHECK-NEXT: [[MERGE:%.*]] = phi i32 [ [[L_A]], %[[LOOP_THEN]] ], [ [[L_B]], %[[LOOP_HEADER]] ]
1187 ; CHECK-NEXT: [[GEP_C:%.*]] = getelementptr inbounds i32, ptr [[C]], i64 [[IV]]
1188 ; CHECK-NEXT: store i32 [[MERGE]], ptr [[GEP_C]], align 4
1189 ; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
1190 ; CHECK-NEXT: [[EC:%.*]] = icmp eq i64 [[IV_NEXT]], 1000
1191 ; CHECK-NEXT: br i1 [[EC]], label %[[EXIT]], label %[[LOOP_HEADER]], !llvm.loop [[LOOP27:![0-9]+]]
1193 ; CHECK-NEXT: ret void
1196 call void @llvm.assume(i1 true) [ "dereferenceable"(ptr %a, i64 4000) ]
1197 br label %loop.header
1200 %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop.latch ]
1201 %gep.b = getelementptr inbounds i32, ptr %b, i64 %iv
1202 %l.b = load i32, ptr %gep.b, align 4
1203 %c.1 = icmp sge i32 %l.b, 0
1204 br i1 %c.1, label %loop.latch, label %loop.then
1207 %gep.a = getelementptr i32, ptr %a, i64 %iv
1208 %l.a = load i32, ptr %gep.a, align 4
1209 br label %loop.latch
1212 %merge = phi i32 [ %l.a, %loop.then ], [ %l.b, %loop.header ]
1213 %gep.c = getelementptr inbounds i32, ptr %c, i64 %iv
1214 store i32 %merge, ptr %gep.c, align 4
1215 %iv.next = add nuw nsw i64 %iv, 1
1216 %ec = icmp eq i64 %iv.next, 1000
1217 br i1 %ec, label %exit, label %loop.header
1223 define void @deref_assumption_in_preheader_constant_trip_count_align_4_not_known(ptr noalias %a, ptr noalias %b, ptr noalias %c) nofree nosync{
1224 ; CHECK-LABEL: define void @deref_assumption_in_preheader_constant_trip_count_align_4_not_known(
1225 ; CHECK-SAME: ptr noalias [[A:%.*]], ptr noalias [[B:%.*]], ptr noalias [[C:%.*]]) #[[ATTR1]] {
1226 ; CHECK-NEXT: [[ENTRY:.*]]:
1227 ; CHECK-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(ptr [[A]], i64 4000) ]
1228 ; CHECK-NEXT: br i1 false, label %[[SCALAR_PH:.*]], label %[[VECTOR_PH:.*]]
1229 ; CHECK: [[VECTOR_PH]]:
1230 ; CHECK-NEXT: br label %[[VECTOR_BODY:.*]]
1231 ; CHECK: [[VECTOR_BODY]]:
1232 ; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, %[[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], %[[PRED_LOAD_CONTINUE2:.*]] ]
1233 ; CHECK-NEXT: [[TMP0:%.*]] = add i64 [[INDEX]], 0
1234 ; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds i32, ptr [[B]], i64 [[TMP0]]
1235 ; CHECK-NEXT: [[TMP2:%.*]] = getelementptr inbounds i32, ptr [[TMP1]], i32 0
1236 ; CHECK-NEXT: [[WIDE_LOAD:%.*]] = load <2 x i32>, ptr [[TMP2]], align 4
1237 ; CHECK-NEXT: [[TMP3:%.*]] = icmp sge <2 x i32> [[WIDE_LOAD]], zeroinitializer
1238 ; CHECK-NEXT: [[TMP4:%.*]] = xor <2 x i1> [[TMP3]], splat (i1 true)
1239 ; CHECK-NEXT: [[TMP5:%.*]] = extractelement <2 x i1> [[TMP4]], i32 0
1240 ; CHECK-NEXT: br i1 [[TMP5]], label %[[PRED_LOAD_IF:.*]], label %[[PRED_LOAD_CONTINUE:.*]]
1241 ; CHECK: [[PRED_LOAD_IF]]:
1242 ; CHECK-NEXT: [[TMP6:%.*]] = getelementptr i32, ptr [[A]], i64 [[TMP0]]
1243 ; CHECK-NEXT: [[TMP7:%.*]] = load i32, ptr [[TMP6]], align 4
1244 ; CHECK-NEXT: [[TMP8:%.*]] = insertelement <2 x i32> poison, i32 [[TMP7]], i32 0
1245 ; CHECK-NEXT: br label %[[PRED_LOAD_CONTINUE]]
1246 ; CHECK: [[PRED_LOAD_CONTINUE]]:
1247 ; CHECK-NEXT: [[TMP9:%.*]] = phi <2 x i32> [ poison, %[[VECTOR_BODY]] ], [ [[TMP8]], %[[PRED_LOAD_IF]] ]
1248 ; CHECK-NEXT: [[TMP10:%.*]] = extractelement <2 x i1> [[TMP4]], i32 1
1249 ; CHECK-NEXT: br i1 [[TMP10]], label %[[PRED_LOAD_IF1:.*]], label %[[PRED_LOAD_CONTINUE2]]
1250 ; CHECK: [[PRED_LOAD_IF1]]:
1251 ; CHECK-NEXT: [[TMP11:%.*]] = add i64 [[INDEX]], 1
1252 ; CHECK-NEXT: [[TMP12:%.*]] = getelementptr i32, ptr [[A]], i64 [[TMP11]]
1253 ; CHECK-NEXT: [[TMP13:%.*]] = load i32, ptr [[TMP12]], align 4
1254 ; CHECK-NEXT: [[TMP14:%.*]] = insertelement <2 x i32> [[TMP9]], i32 [[TMP13]], i32 1
1255 ; CHECK-NEXT: br label %[[PRED_LOAD_CONTINUE2]]
1256 ; CHECK: [[PRED_LOAD_CONTINUE2]]:
1257 ; CHECK-NEXT: [[TMP15:%.*]] = phi <2 x i32> [ [[TMP9]], %[[PRED_LOAD_CONTINUE]] ], [ [[TMP14]], %[[PRED_LOAD_IF1]] ]
1258 ; CHECK-NEXT: [[PREDPHI:%.*]] = select <2 x i1> [[TMP3]], <2 x i32> [[WIDE_LOAD]], <2 x i32> [[TMP15]]
1259 ; CHECK-NEXT: [[TMP16:%.*]] = getelementptr inbounds i32, ptr [[C]], i64 [[TMP0]]
1260 ; CHECK-NEXT: [[TMP17:%.*]] = getelementptr inbounds i32, ptr [[TMP16]], i32 0
1261 ; CHECK-NEXT: store <2 x i32> [[PREDPHI]], ptr [[TMP17]], align 4
1262 ; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 2
1263 ; CHECK-NEXT: [[TMP18:%.*]] = icmp eq i64 [[INDEX_NEXT]], 1000
1264 ; CHECK-NEXT: br i1 [[TMP18]], label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]], !llvm.loop [[LOOP28:![0-9]+]]
1265 ; CHECK: [[MIDDLE_BLOCK]]:
1266 ; CHECK-NEXT: br i1 true, label %[[EXIT:.*]], label %[[SCALAR_PH]]
1267 ; CHECK: [[SCALAR_PH]]:
1268 ; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i64 [ 1000, %[[MIDDLE_BLOCK]] ], [ 0, %[[ENTRY]] ]
1269 ; CHECK-NEXT: br label %[[LOOP_HEADER:.*]]
1270 ; CHECK: [[LOOP_HEADER]]:
1271 ; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[BC_RESUME_VAL]], %[[SCALAR_PH]] ], [ [[IV_NEXT:%.*]], %[[LOOP_LATCH:.*]] ]
1272 ; CHECK-NEXT: [[GEP_B:%.*]] = getelementptr inbounds i32, ptr [[B]], i64 [[IV]]
1273 ; CHECK-NEXT: [[L_B:%.*]] = load i32, ptr [[GEP_B]], align 4
1274 ; CHECK-NEXT: [[C_1:%.*]] = icmp sge i32 [[L_B]], 0
1275 ; CHECK-NEXT: br i1 [[C_1]], label %[[LOOP_LATCH]], label %[[LOOP_THEN:.*]]
1276 ; CHECK: [[LOOP_THEN]]:
1277 ; CHECK-NEXT: [[GEP_A:%.*]] = getelementptr i32, ptr [[A]], i64 [[IV]]
1278 ; CHECK-NEXT: [[L_A:%.*]] = load i32, ptr [[GEP_A]], align 4
1279 ; CHECK-NEXT: br label %[[LOOP_LATCH]]
1280 ; CHECK: [[LOOP_LATCH]]:
1281 ; CHECK-NEXT: [[MERGE:%.*]] = phi i32 [ [[L_A]], %[[LOOP_THEN]] ], [ [[L_B]], %[[LOOP_HEADER]] ]
1282 ; CHECK-NEXT: [[GEP_C:%.*]] = getelementptr inbounds i32, ptr [[C]], i64 [[IV]]
1283 ; CHECK-NEXT: store i32 [[MERGE]], ptr [[GEP_C]], align 4
1284 ; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
1285 ; CHECK-NEXT: [[EC:%.*]] = icmp eq i64 [[IV_NEXT]], 1000
1286 ; CHECK-NEXT: br i1 [[EC]], label %[[EXIT]], label %[[LOOP_HEADER]], !llvm.loop [[LOOP29:![0-9]+]]
1288 ; CHECK-NEXT: ret void
1291 call void @llvm.assume(i1 true) [ "dereferenceable"(ptr %a, i64 4000) ]
1292 br label %loop.header
1295 %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop.latch ]
1296 %gep.b = getelementptr inbounds i32, ptr %b, i64 %iv
1297 %l.b = load i32, ptr %gep.b, align 4
1298 %c.1 = icmp sge i32 %l.b, 0
1299 br i1 %c.1, label %loop.latch, label %loop.then
1302 %gep.a = getelementptr i32, ptr %a, i64 %iv
1303 %l.a = load i32, ptr %gep.a, align 4
1304 br label %loop.latch
1307 %merge = phi i32 [ %l.a, %loop.then ], [ %l.b, %loop.header ]
1308 %gep.c = getelementptr inbounds i32, ptr %c, i64 %iv
1309 store i32 %merge, ptr %gep.c, align 4
1310 %iv.next = add nuw nsw i64 %iv, 1
1311 %ec = icmp eq i64 %iv.next, 1000
1312 br i1 %ec, label %exit, label %loop.header
1318 define void @deref_assumption_too_small_in_preheader_constant_trip_count_align_4(ptr noalias %a, ptr noalias %b, ptr noalias %c) nofree nosync{
1319 ; CHECK-LABEL: define void @deref_assumption_too_small_in_preheader_constant_trip_count_align_4(
1320 ; CHECK-SAME: ptr noalias [[A:%.*]], ptr noalias [[B:%.*]], ptr noalias [[C:%.*]]) #[[ATTR1]] {
1321 ; CHECK-NEXT: [[ENTRY:.*]]:
1322 ; CHECK-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(ptr [[A]], i64 3999) ]
1323 ; CHECK-NEXT: br i1 false, label %[[SCALAR_PH:.*]], label %[[VECTOR_PH:.*]]
1324 ; CHECK: [[VECTOR_PH]]:
1325 ; CHECK-NEXT: br label %[[VECTOR_BODY:.*]]
1326 ; CHECK: [[VECTOR_BODY]]:
1327 ; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, %[[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], %[[PRED_LOAD_CONTINUE2:.*]] ]
1328 ; CHECK-NEXT: [[TMP0:%.*]] = add i64 [[INDEX]], 0
1329 ; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds i32, ptr [[B]], i64 [[TMP0]]
1330 ; CHECK-NEXT: [[TMP2:%.*]] = getelementptr inbounds i32, ptr [[TMP1]], i32 0
1331 ; CHECK-NEXT: [[WIDE_LOAD:%.*]] = load <2 x i32>, ptr [[TMP2]], align 4
1332 ; CHECK-NEXT: [[TMP3:%.*]] = icmp sge <2 x i32> [[WIDE_LOAD]], zeroinitializer
1333 ; CHECK-NEXT: [[TMP4:%.*]] = xor <2 x i1> [[TMP3]], splat (i1 true)
1334 ; CHECK-NEXT: [[TMP5:%.*]] = extractelement <2 x i1> [[TMP4]], i32 0
1335 ; CHECK-NEXT: br i1 [[TMP5]], label %[[PRED_LOAD_IF:.*]], label %[[PRED_LOAD_CONTINUE:.*]]
1336 ; CHECK: [[PRED_LOAD_IF]]:
1337 ; CHECK-NEXT: [[TMP6:%.*]] = getelementptr i32, ptr [[A]], i64 [[TMP0]]
1338 ; CHECK-NEXT: [[TMP7:%.*]] = load i32, ptr [[TMP6]], align 4
1339 ; CHECK-NEXT: [[TMP8:%.*]] = insertelement <2 x i32> poison, i32 [[TMP7]], i32 0
1340 ; CHECK-NEXT: br label %[[PRED_LOAD_CONTINUE]]
1341 ; CHECK: [[PRED_LOAD_CONTINUE]]:
1342 ; CHECK-NEXT: [[TMP9:%.*]] = phi <2 x i32> [ poison, %[[VECTOR_BODY]] ], [ [[TMP8]], %[[PRED_LOAD_IF]] ]
1343 ; CHECK-NEXT: [[TMP10:%.*]] = extractelement <2 x i1> [[TMP4]], i32 1
1344 ; CHECK-NEXT: br i1 [[TMP10]], label %[[PRED_LOAD_IF1:.*]], label %[[PRED_LOAD_CONTINUE2]]
1345 ; CHECK: [[PRED_LOAD_IF1]]:
1346 ; CHECK-NEXT: [[TMP11:%.*]] = add i64 [[INDEX]], 1
1347 ; CHECK-NEXT: [[TMP12:%.*]] = getelementptr i32, ptr [[A]], i64 [[TMP11]]
1348 ; CHECK-NEXT: [[TMP13:%.*]] = load i32, ptr [[TMP12]], align 4
1349 ; CHECK-NEXT: [[TMP14:%.*]] = insertelement <2 x i32> [[TMP9]], i32 [[TMP13]], i32 1
1350 ; CHECK-NEXT: br label %[[PRED_LOAD_CONTINUE2]]
1351 ; CHECK: [[PRED_LOAD_CONTINUE2]]:
1352 ; CHECK-NEXT: [[TMP15:%.*]] = phi <2 x i32> [ [[TMP9]], %[[PRED_LOAD_CONTINUE]] ], [ [[TMP14]], %[[PRED_LOAD_IF1]] ]
1353 ; CHECK-NEXT: [[PREDPHI:%.*]] = select <2 x i1> [[TMP3]], <2 x i32> [[WIDE_LOAD]], <2 x i32> [[TMP15]]
1354 ; CHECK-NEXT: [[TMP16:%.*]] = getelementptr inbounds i32, ptr [[C]], i64 [[TMP0]]
1355 ; CHECK-NEXT: [[TMP17:%.*]] = getelementptr inbounds i32, ptr [[TMP16]], i32 0
1356 ; CHECK-NEXT: store <2 x i32> [[PREDPHI]], ptr [[TMP17]], align 4
1357 ; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 2
1358 ; CHECK-NEXT: [[TMP18:%.*]] = icmp eq i64 [[INDEX_NEXT]], 1000
1359 ; CHECK-NEXT: br i1 [[TMP18]], label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]], !llvm.loop [[LOOP30:![0-9]+]]
1360 ; CHECK: [[MIDDLE_BLOCK]]:
1361 ; CHECK-NEXT: br i1 true, label %[[EXIT:.*]], label %[[SCALAR_PH]]
1362 ; CHECK: [[SCALAR_PH]]:
1363 ; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i64 [ 1000, %[[MIDDLE_BLOCK]] ], [ 0, %[[ENTRY]] ]
1364 ; CHECK-NEXT: br label %[[LOOP_HEADER:.*]]
1365 ; CHECK: [[LOOP_HEADER]]:
1366 ; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[BC_RESUME_VAL]], %[[SCALAR_PH]] ], [ [[IV_NEXT:%.*]], %[[LOOP_LATCH:.*]] ]
1367 ; CHECK-NEXT: [[GEP_B:%.*]] = getelementptr inbounds i32, ptr [[B]], i64 [[IV]]
1368 ; CHECK-NEXT: [[L_B:%.*]] = load i32, ptr [[GEP_B]], align 4
1369 ; CHECK-NEXT: [[C_1:%.*]] = icmp sge i32 [[L_B]], 0
1370 ; CHECK-NEXT: br i1 [[C_1]], label %[[LOOP_LATCH]], label %[[LOOP_THEN:.*]]
1371 ; CHECK: [[LOOP_THEN]]:
1372 ; CHECK-NEXT: [[GEP_A:%.*]] = getelementptr i32, ptr [[A]], i64 [[IV]]
1373 ; CHECK-NEXT: [[L_A:%.*]] = load i32, ptr [[GEP_A]], align 4
1374 ; CHECK-NEXT: br label %[[LOOP_LATCH]]
1375 ; CHECK: [[LOOP_LATCH]]:
1376 ; CHECK-NEXT: [[MERGE:%.*]] = phi i32 [ [[L_A]], %[[LOOP_THEN]] ], [ [[L_B]], %[[LOOP_HEADER]] ]
1377 ; CHECK-NEXT: [[GEP_C:%.*]] = getelementptr inbounds i32, ptr [[C]], i64 [[IV]]
1378 ; CHECK-NEXT: store i32 [[MERGE]], ptr [[GEP_C]], align 4
1379 ; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
1380 ; CHECK-NEXT: [[EC:%.*]] = icmp eq i64 [[IV_NEXT]], 1000
1381 ; CHECK-NEXT: br i1 [[EC]], label %[[EXIT]], label %[[LOOP_HEADER]], !llvm.loop [[LOOP31:![0-9]+]]
1383 ; CHECK-NEXT: ret void
1386 call void @llvm.assume(i1 true) [ "dereferenceable"(ptr %a, i64 3999) ]
1387 br label %loop.header
1390 %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop.latch ]
1391 %gep.b = getelementptr inbounds i32, ptr %b, i64 %iv
1392 %l.b = load i32, ptr %gep.b, align 4
1393 %c.1 = icmp sge i32 %l.b, 0
1394 br i1 %c.1, label %loop.latch, label %loop.then
1397 %gep.a = getelementptr i32, ptr %a, i64 %iv
1398 %l.a = load i32, ptr %gep.a, align 4
1399 br label %loop.latch
1402 %merge = phi i32 [ %l.a, %loop.then ], [ %l.b, %loop.header ]
1403 %gep.c = getelementptr inbounds i32, ptr %c, i64 %iv
1404 store i32 %merge, ptr %gep.c, align 4
1405 %iv.next = add nuw nsw i64 %iv, 1
1406 %ec = icmp eq i64 %iv.next, 1000
1407 br i1 %ec, label %exit, label %loop.header
1413 ; %a may be freed between the dereferenceable assumption and accesses.
1414 ; It is not safe to use with -use-dereferenceable-at-point-semantics.
1415 define void @may_free_align_deref_assumption_in_header_constant_trip_count_loop_invariant_ptr(ptr noalias %a, ptr noalias %b, ptr noalias %c) {
1416 ; CHECK-LABEL: define void @may_free_align_deref_assumption_in_header_constant_trip_count_loop_invariant_ptr(
1417 ; CHECK-SAME: ptr noalias [[A:%.*]], ptr noalias [[B:%.*]], ptr noalias [[C:%.*]]) {
1418 ; CHECK-NEXT: [[ENTRY:.*]]:
1419 ; CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[A]], i64 4), "dereferenceable"(ptr [[A]], i64 4) ]
1420 ; CHECK-NEXT: call void @may_free()
1421 ; CHECK-NEXT: br i1 false, label %[[SCALAR_PH:.*]], label %[[VECTOR_PH:.*]]
1422 ; CHECK: [[VECTOR_PH]]:
1423 ; CHECK-NEXT: br label %[[VECTOR_BODY:.*]]
1424 ; CHECK: [[VECTOR_BODY]]:
1425 ; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, %[[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], %[[PRED_LOAD_CONTINUE2:.*]] ]
1426 ; CHECK-NEXT: [[TMP0:%.*]] = add i64 [[INDEX]], 0
1427 ; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds i32, ptr [[B]], i64 [[TMP0]]
1428 ; CHECK-NEXT: [[TMP2:%.*]] = getelementptr inbounds i32, ptr [[TMP1]], i32 0
1429 ; CHECK-NEXT: [[WIDE_LOAD:%.*]] = load <2 x i32>, ptr [[TMP2]], align 4
1430 ; CHECK-NEXT: [[TMP3:%.*]] = icmp sge <2 x i32> [[WIDE_LOAD]], zeroinitializer
1431 ; CHECK-NEXT: [[TMP4:%.*]] = xor <2 x i1> [[TMP3]], splat (i1 true)
1432 ; CHECK-NEXT: [[TMP5:%.*]] = extractelement <2 x i1> [[TMP4]], i32 0
1433 ; CHECK-NEXT: br i1 [[TMP5]], label %[[PRED_LOAD_IF:.*]], label %[[PRED_LOAD_CONTINUE:.*]]
1434 ; CHECK: [[PRED_LOAD_IF]]:
1435 ; CHECK-NEXT: [[TMP15:%.*]] = load i32, ptr [[A]], align 4
1436 ; CHECK-NEXT: [[TMP7:%.*]] = insertelement <2 x i32> poison, i32 [[TMP15]], i32 0
1437 ; CHECK-NEXT: br label %[[PRED_LOAD_CONTINUE]]
1438 ; CHECK: [[PRED_LOAD_CONTINUE]]:
1439 ; CHECK-NEXT: [[TMP12:%.*]] = phi <2 x i32> [ poison, %[[VECTOR_BODY]] ], [ [[TMP7]], %[[PRED_LOAD_IF]] ]
1440 ; CHECK-NEXT: [[TMP13:%.*]] = extractelement <2 x i1> [[TMP4]], i32 1
1441 ; CHECK-NEXT: br i1 [[TMP13]], label %[[PRED_LOAD_IF1:.*]], label %[[PRED_LOAD_CONTINUE2]]
1442 ; CHECK: [[PRED_LOAD_IF1]]:
1443 ; CHECK-NEXT: [[TMP14:%.*]] = load i32, ptr [[A]], align 4
1444 ; CHECK-NEXT: [[TMP16:%.*]] = insertelement <2 x i32> [[TMP12]], i32 [[TMP14]], i32 1
1445 ; CHECK-NEXT: br label %[[PRED_LOAD_CONTINUE2]]
1446 ; CHECK: [[PRED_LOAD_CONTINUE2]]:
1447 ; CHECK-NEXT: [[TMP11:%.*]] = phi <2 x i32> [ [[TMP12]], %[[PRED_LOAD_CONTINUE]] ], [ [[TMP16]], %[[PRED_LOAD_IF1]] ]
1448 ; CHECK-NEXT: [[PREDPHI:%.*]] = select <2 x i1> [[TMP3]], <2 x i32> [[WIDE_LOAD]], <2 x i32> [[TMP11]]
1449 ; CHECK-NEXT: [[TMP8:%.*]] = getelementptr inbounds i32, ptr [[C]], i64 [[TMP0]]
1450 ; CHECK-NEXT: [[TMP9:%.*]] = getelementptr inbounds i32, ptr [[TMP8]], i32 0
1451 ; CHECK-NEXT: store <2 x i32> [[PREDPHI]], ptr [[TMP9]], align 4
1452 ; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 2
1453 ; CHECK-NEXT: [[TMP10:%.*]] = icmp eq i64 [[INDEX_NEXT]], 1000
1454 ; CHECK-NEXT: br i1 [[TMP10]], label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]], !llvm.loop [[LOOP32:![0-9]+]]
1455 ; CHECK: [[MIDDLE_BLOCK]]:
1456 ; CHECK-NEXT: br i1 true, label %[[EXIT:.*]], label %[[SCALAR_PH]]
1457 ; CHECK: [[SCALAR_PH]]:
1458 ; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i64 [ 1000, %[[MIDDLE_BLOCK]] ], [ 0, %[[ENTRY]] ]
1459 ; CHECK-NEXT: br label %[[LOOP_HEADER:.*]]
1460 ; CHECK: [[LOOP_HEADER]]:
1461 ; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[BC_RESUME_VAL]], %[[SCALAR_PH]] ], [ [[IV_NEXT:%.*]], %[[LOOP_LATCH:.*]] ]
1462 ; CHECK-NEXT: [[GEP_B:%.*]] = getelementptr inbounds i32, ptr [[B]], i64 [[IV]]
1463 ; CHECK-NEXT: [[L_B:%.*]] = load i32, ptr [[GEP_B]], align 4
1464 ; CHECK-NEXT: [[C_1:%.*]] = icmp sge i32 [[L_B]], 0
1465 ; CHECK-NEXT: br i1 [[C_1]], label %[[LOOP_LATCH]], label %[[LOOP_THEN:.*]]
1466 ; CHECK: [[LOOP_THEN]]:
1467 ; CHECK-NEXT: [[L_A:%.*]] = load i32, ptr [[A]], align 4
1468 ; CHECK-NEXT: br label %[[LOOP_LATCH]]
1469 ; CHECK: [[LOOP_LATCH]]:
1470 ; CHECK-NEXT: [[MERGE:%.*]] = phi i32 [ [[L_A]], %[[LOOP_THEN]] ], [ [[L_B]], %[[LOOP_HEADER]] ]
1471 ; CHECK-NEXT: [[GEP_C:%.*]] = getelementptr inbounds i32, ptr [[C]], i64 [[IV]]
1472 ; CHECK-NEXT: store i32 [[MERGE]], ptr [[GEP_C]], align 4
1473 ; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
1474 ; CHECK-NEXT: [[EC:%.*]] = icmp eq i64 [[IV_NEXT]], 1000
1475 ; CHECK-NEXT: br i1 [[EC]], label %[[EXIT]], label %[[LOOP_HEADER]], !llvm.loop [[LOOP33:![0-9]+]]
1477 ; CHECK-NEXT: ret void
1480 call void @llvm.assume(i1 true) [ "align"(ptr %a, i64 4), "dereferenceable"(ptr %a, i64 4) ]
1481 call void @may_free()
1482 br label %loop.header
1485 %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop.latch ]
1486 %gep.b = getelementptr inbounds i32, ptr %b, i64 %iv
1487 %l.b = load i32, ptr %gep.b, align 4
1488 %c.1 = icmp sge i32 %l.b, 0
1489 br i1 %c.1, label %loop.latch, label %loop.then
1492 %l.a = load i32, ptr %a, align 4
1493 br label %loop.latch
1496 %merge = phi i32 [ %l.a, %loop.then ], [ %l.b, %loop.header ]
1497 %gep.c = getelementptr inbounds i32, ptr %c, i64 %iv
1498 store i32 %merge, ptr %gep.c, align 4
1499 %iv.next = add nuw nsw i64 %iv, 1
1500 %ec = icmp eq i64 %iv.next, 1000
1501 br i1 %ec, label %exit, label %loop.header
1507 ; %a may be freed between the dereferenceable assumption and accesses.
1508 ; It is not safe to use with -use-dereferenceable-at-point-semantics.
1509 define void @may_free_local_ptr_align_deref_assumption_in_header_constant_trip_count_loop_invariant_ptr(ptr noalias %b, ptr noalias %c) nofree nosync {
1510 ; CHECK-LABEL: define void @may_free_local_ptr_align_deref_assumption_in_header_constant_trip_count_loop_invariant_ptr(
1511 ; CHECK-SAME: ptr noalias [[B:%.*]], ptr noalias [[C:%.*]]) #[[ATTR1]] {
1512 ; CHECK-NEXT: [[ENTRY:.*]]:
1513 ; CHECK-NEXT: [[A:%.*]] = call ptr @get_ptr()
1514 ; CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[A]], i64 4), "dereferenceable"(ptr [[A]], i64 4) ]
1515 ; CHECK-NEXT: call void @may_free()
1516 ; CHECK-NEXT: br i1 false, label %[[SCALAR_PH:.*]], label %[[VECTOR_PH:.*]]
1517 ; CHECK: [[VECTOR_PH]]:
1518 ; CHECK-NEXT: br label %[[VECTOR_BODY:.*]]
1519 ; CHECK: [[VECTOR_BODY]]:
1520 ; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, %[[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], %[[PRED_LOAD_CONTINUE2:.*]] ]
1521 ; CHECK-NEXT: [[TMP0:%.*]] = add i64 [[INDEX]], 0
1522 ; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds i32, ptr [[B]], i64 [[TMP0]]
1523 ; CHECK-NEXT: [[TMP2:%.*]] = getelementptr inbounds i32, ptr [[TMP1]], i32 0
1524 ; CHECK-NEXT: [[WIDE_LOAD:%.*]] = load <2 x i32>, ptr [[TMP2]], align 4
1525 ; CHECK-NEXT: [[TMP3:%.*]] = icmp sge <2 x i32> [[WIDE_LOAD]], zeroinitializer
1526 ; CHECK-NEXT: [[TMP4:%.*]] = xor <2 x i1> [[TMP3]], splat (i1 true)
1527 ; CHECK-NEXT: [[TMP5:%.*]] = extractelement <2 x i1> [[TMP4]], i32 0
1528 ; CHECK-NEXT: br i1 [[TMP5]], label %[[PRED_LOAD_IF:.*]], label %[[PRED_LOAD_CONTINUE:.*]]
1529 ; CHECK: [[PRED_LOAD_IF]]:
1530 ; CHECK-NEXT: [[TMP6:%.*]] = load i32, ptr [[A]], align 4
1531 ; CHECK-NEXT: [[TMP7:%.*]] = insertelement <2 x i32> poison, i32 [[TMP6]], i32 0
1532 ; CHECK-NEXT: br label %[[PRED_LOAD_CONTINUE]]
1533 ; CHECK: [[PRED_LOAD_CONTINUE]]:
1534 ; CHECK-NEXT: [[TMP8:%.*]] = phi <2 x i32> [ poison, %[[VECTOR_BODY]] ], [ [[TMP7]], %[[PRED_LOAD_IF]] ]
1535 ; CHECK-NEXT: [[TMP9:%.*]] = extractelement <2 x i1> [[TMP4]], i32 1
1536 ; CHECK-NEXT: br i1 [[TMP9]], label %[[PRED_LOAD_IF1:.*]], label %[[PRED_LOAD_CONTINUE2]]
1537 ; CHECK: [[PRED_LOAD_IF1]]:
1538 ; CHECK-NEXT: [[TMP10:%.*]] = load i32, ptr [[A]], align 4
1539 ; CHECK-NEXT: [[TMP11:%.*]] = insertelement <2 x i32> [[TMP8]], i32 [[TMP10]], i32 1
1540 ; CHECK-NEXT: br label %[[PRED_LOAD_CONTINUE2]]
1541 ; CHECK: [[PRED_LOAD_CONTINUE2]]:
1542 ; CHECK-NEXT: [[TMP12:%.*]] = phi <2 x i32> [ [[TMP8]], %[[PRED_LOAD_CONTINUE]] ], [ [[TMP11]], %[[PRED_LOAD_IF1]] ]
1543 ; CHECK-NEXT: [[PREDPHI:%.*]] = select <2 x i1> [[TMP3]], <2 x i32> [[WIDE_LOAD]], <2 x i32> [[TMP12]]
1544 ; CHECK-NEXT: [[TMP13:%.*]] = getelementptr inbounds i32, ptr [[C]], i64 [[TMP0]]
1545 ; CHECK-NEXT: [[TMP14:%.*]] = getelementptr inbounds i32, ptr [[TMP13]], i32 0
1546 ; CHECK-NEXT: store <2 x i32> [[PREDPHI]], ptr [[TMP14]], align 4
1547 ; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 2
1548 ; CHECK-NEXT: [[TMP15:%.*]] = icmp eq i64 [[INDEX_NEXT]], 1000
1549 ; CHECK-NEXT: br i1 [[TMP15]], label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]], !llvm.loop [[LOOP34:![0-9]+]]
1550 ; CHECK: [[MIDDLE_BLOCK]]:
1551 ; CHECK-NEXT: br i1 true, label %[[EXIT:.*]], label %[[SCALAR_PH]]
1552 ; CHECK: [[SCALAR_PH]]:
1553 ; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i64 [ 1000, %[[MIDDLE_BLOCK]] ], [ 0, %[[ENTRY]] ]
1554 ; CHECK-NEXT: br label %[[LOOP_HEADER:.*]]
1555 ; CHECK: [[LOOP_HEADER]]:
1556 ; CHECK-NEXT: [[IV:%.*]] = phi i64 [ [[BC_RESUME_VAL]], %[[SCALAR_PH]] ], [ [[IV_NEXT:%.*]], %[[LOOP_LATCH:.*]] ]
1557 ; CHECK-NEXT: [[GEP_B:%.*]] = getelementptr inbounds i32, ptr [[B]], i64 [[IV]]
1558 ; CHECK-NEXT: [[L_B:%.*]] = load i32, ptr [[GEP_B]], align 4
1559 ; CHECK-NEXT: [[C_1:%.*]] = icmp sge i32 [[L_B]], 0
1560 ; CHECK-NEXT: br i1 [[C_1]], label %[[LOOP_LATCH]], label %[[LOOP_THEN:.*]]
1561 ; CHECK: [[LOOP_THEN]]:
1562 ; CHECK-NEXT: [[L_A:%.*]] = load i32, ptr [[A]], align 4
1563 ; CHECK-NEXT: br label %[[LOOP_LATCH]]
1564 ; CHECK: [[LOOP_LATCH]]:
1565 ; CHECK-NEXT: [[MERGE:%.*]] = phi i32 [ [[L_A]], %[[LOOP_THEN]] ], [ [[L_B]], %[[LOOP_HEADER]] ]
1566 ; CHECK-NEXT: [[GEP_C:%.*]] = getelementptr inbounds i32, ptr [[C]], i64 [[IV]]
1567 ; CHECK-NEXT: store i32 [[MERGE]], ptr [[GEP_C]], align 4
1568 ; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
1569 ; CHECK-NEXT: [[EC:%.*]] = icmp eq i64 [[IV_NEXT]], 1000
1570 ; CHECK-NEXT: br i1 [[EC]], label %[[EXIT]], label %[[LOOP_HEADER]], !llvm.loop [[LOOP35:![0-9]+]]
1572 ; CHECK-NEXT: ret void
1575 %a = call ptr @get_ptr()
1576 call void @llvm.assume(i1 true) [ "align"(ptr %a, i64 4), "dereferenceable"(ptr %a, i64 4) ]
1577 call void @may_free()
1578 br label %loop.header
1581 %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop.latch ]
1582 %gep.b = getelementptr inbounds i32, ptr %b, i64 %iv
1583 %l.b = load i32, ptr %gep.b, align 4
1584 %c.1 = icmp sge i32 %l.b, 0
1585 br i1 %c.1, label %loop.latch, label %loop.then
1588 %l.a = load i32, ptr %a, align 4
1589 br label %loop.latch
1592 %merge = phi i32 [ %l.a, %loop.then ], [ %l.b, %loop.header ]
1593 %gep.c = getelementptr inbounds i32, ptr %c, i64 %iv
1594 store i32 %merge, ptr %gep.c, align 4
1595 %iv.next = add nuw nsw i64 %iv, 1
1596 %ec = icmp eq i64 %iv.next, 1000
1597 br i1 %ec, label %exit, label %loop.header
1603 declare ptr @get_ptr()
1604 declare void @may_free()
1607 ; CHECK: [[LOOP0]] = distinct !{[[LOOP0]], [[META1:![0-9]+]], [[META2:![0-9]+]]}
1608 ; CHECK: [[META1]] = !{!"llvm.loop.isvectorized", i32 1}
1609 ; CHECK: [[META2]] = !{!"llvm.loop.unroll.runtime.disable"}
1610 ; CHECK: [[LOOP3]] = distinct !{[[LOOP3]], [[META2]], [[META1]]}
1611 ; CHECK: [[LOOP4]] = distinct !{[[LOOP4]], [[META1]], [[META2]]}
1612 ; CHECK: [[LOOP5]] = distinct !{[[LOOP5]], [[META2]], [[META1]]}
1613 ; CHECK: [[LOOP6]] = distinct !{[[LOOP6]], [[META1]], [[META2]]}
1614 ; CHECK: [[LOOP7]] = distinct !{[[LOOP7]], [[META2]], [[META1]]}
1615 ; CHECK: [[LOOP8]] = distinct !{[[LOOP8]], [[META1]], [[META2]]}
1616 ; CHECK: [[LOOP9]] = distinct !{[[LOOP9]], [[META2]], [[META1]]}
1617 ; CHECK: [[LOOP10]] = distinct !{[[LOOP10]], [[META1]], [[META2]]}
1618 ; CHECK: [[LOOP11]] = distinct !{[[LOOP11]], [[META2]], [[META1]]}
1619 ; CHECK: [[LOOP12]] = distinct !{[[LOOP12]], [[META1]], [[META2]]}
1620 ; CHECK: [[LOOP13]] = distinct !{[[LOOP13]], [[META2]], [[META1]]}
1621 ; CHECK: [[LOOP14]] = distinct !{[[LOOP14]], [[META1]], [[META2]]}
1622 ; CHECK: [[LOOP15]] = distinct !{[[LOOP15]], [[META2]], [[META1]]}
1623 ; CHECK: [[LOOP16]] = distinct !{[[LOOP16]], [[META1]], [[META2]]}
1624 ; CHECK: [[LOOP17]] = distinct !{[[LOOP17]], [[META2]], [[META1]]}
1625 ; CHECK: [[LOOP18]] = distinct !{[[LOOP18]], [[META1]], [[META2]]}
1626 ; CHECK: [[LOOP19]] = distinct !{[[LOOP19]], [[META2]], [[META1]]}
1627 ; CHECK: [[LOOP20]] = distinct !{[[LOOP20]], [[META1]], [[META2]]}
1628 ; CHECK: [[LOOP21]] = distinct !{[[LOOP21]], [[META2]], [[META1]]}
1629 ; CHECK: [[LOOP22]] = distinct !{[[LOOP22]], [[META1]], [[META2]]}
1630 ; CHECK: [[LOOP23]] = distinct !{[[LOOP23]], [[META2]], [[META1]]}
1631 ; CHECK: [[LOOP24]] = distinct !{[[LOOP24]], [[META1]], [[META2]]}
1632 ; CHECK: [[LOOP25]] = distinct !{[[LOOP25]], [[META2]], [[META1]]}
1633 ; CHECK: [[LOOP26]] = distinct !{[[LOOP26]], [[META1]], [[META2]]}
1634 ; CHECK: [[LOOP27]] = distinct !{[[LOOP27]], [[META2]], [[META1]]}
1635 ; CHECK: [[LOOP28]] = distinct !{[[LOOP28]], [[META1]], [[META2]]}
1636 ; CHECK: [[LOOP29]] = distinct !{[[LOOP29]], [[META2]], [[META1]]}
1637 ; CHECK: [[LOOP30]] = distinct !{[[LOOP30]], [[META1]], [[META2]]}
1638 ; CHECK: [[LOOP31]] = distinct !{[[LOOP31]], [[META2]], [[META1]]}
1639 ; CHECK: [[LOOP32]] = distinct !{[[LOOP32]], [[META1]], [[META2]]}
1640 ; CHECK: [[LOOP33]] = distinct !{[[LOOP33]], [[META2]], [[META1]]}
1641 ; CHECK: [[LOOP34]] = distinct !{[[LOOP34]], [[META1]], [[META2]]}
1642 ; CHECK: [[LOOP35]] = distinct !{[[LOOP35]], [[META2]], [[META1]]}