Skip to content

Commit 2729284

Browse files
committed
[LV] Add early-exit tests with deref assumptions and scaled sizes.
Add tests where the size of dereferenceable assumption is multiplied by a constant.
1 parent 9d9a714 commit 2729284

File tree

1 file changed

+123
-9
lines changed

1 file changed

+123
-9
lines changed

llvm/test/Transforms/LoopVectorize/single-early-exit-deref-assumptions.ll

Lines changed: 123 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -129,21 +129,21 @@ define i64 @early_exit_alignment_and_deref_known_via_assumption_n_not_zero(ptr n
129129
; CHECK-NEXT: [[C:%.*]] = icmp ne i64 [[N]], 0
130130
; CHECK-NEXT: br i1 [[C]], label [[LOOP_PREHEADER:%.*]], label [[LOOP_END:%.*]]
131131
; CHECK: loop.preheader:
132-
; CHECK-NEXT: br label [[LOOP:%.*]]
132+
; CHECK-NEXT: br label [[LOOP1:%.*]]
133133
; CHECK: loop:
134-
; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ [[INDEX_NEXT:%.*]], [[LOOP_INC:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
135-
; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[P1]], i64 [[INDEX]]
134+
; CHECK-NEXT: [[INDEX2:%.*]] = phi i64 [ [[INDEX_NEXT1:%.*]], [[LOOP_INC1:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
135+
; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[P1]], i64 [[INDEX2]]
136136
; CHECK-NEXT: [[LD1:%.*]] = load i8, ptr [[ARRAYIDX]], align 1
137-
; CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds i8, ptr [[P2]], i64 [[INDEX]]
137+
; CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds i8, ptr [[P2]], i64 [[INDEX2]]
138138
; CHECK-NEXT: [[LD2:%.*]] = load i8, ptr [[ARRAYIDX1]], align 1
139139
; CHECK-NEXT: [[CMP3:%.*]] = icmp eq i8 [[LD1]], [[LD2]]
140-
; CHECK-NEXT: br i1 [[CMP3]], label [[LOOP_INC]], label [[LOOP_END_LOOPEXIT:%.*]]
140+
; CHECK-NEXT: br i1 [[CMP3]], label [[LOOP_INC1]], label [[LOOP_END_LOOPEXIT:%.*]]
141141
; CHECK: loop.inc:
142-
; CHECK-NEXT: [[INDEX_NEXT]] = add i64 [[INDEX]], 1
143-
; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDEX_NEXT]], [[N]]
144-
; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[LOOP_END_LOOPEXIT]]
142+
; CHECK-NEXT: [[INDEX_NEXT1]] = add i64 [[INDEX2]], 1
143+
; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDEX_NEXT1]], [[N]]
144+
; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP1]], label [[LOOP_END_LOOPEXIT]]
145145
; CHECK: loop.end.loopexit:
146-
; CHECK-NEXT: [[RETVAL_PH:%.*]] = phi i64 [ -1, [[LOOP_INC]] ], [ [[INDEX]], [[LOOP]] ]
146+
; CHECK-NEXT: [[RETVAL_PH:%.*]] = phi i64 [ -1, [[LOOP_INC1]] ], [ [[INDEX2]], [[LOOP1]] ]
147147
; CHECK-NEXT: br label [[LOOP_END]]
148148
; CHECK: loop.end:
149149
; CHECK-NEXT: [[RETVAL:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[RETVAL_PH]], [[LOOP_END_LOOPEXIT]] ]
@@ -220,3 +220,117 @@ loop.end:
220220
%retval = phi i64 [ %index, %loop ], [ -1, %loop.inc ]
221221
ret i64 %retval
222222
}
223+
224+
define i64 @early_exit_alignment_and_deref_known_via_assumption_n_not_zero_i16(ptr noalias %p1, ptr noalias %p2, i32 %n) nofree nosync {
225+
; CHECK-LABEL: define i64 @early_exit_alignment_and_deref_known_via_assumption_n_not_zero_i16(
226+
; CHECK-SAME: ptr noalias [[P1:%.*]], ptr noalias [[P2:%.*]], i32 [[N:%.*]]) #[[ATTR0]] {
227+
; CHECK-NEXT: entry:
228+
; CHECK-NEXT: [[N_EXT:%.*]] = zext i32 [[N]] to i64
229+
; CHECK-NEXT: [[N_SCALED:%.*]] = shl nuw nsw i64 [[N_EXT]], 1
230+
; CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[P1]], i64 4), "dereferenceable"(ptr [[P1]], i64 [[N_SCALED]]) ]
231+
; CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[P2]], i64 4), "dereferenceable"(ptr [[P2]], i64 [[N_SCALED]]) ]
232+
; CHECK-NEXT: [[C:%.*]] = icmp ne i64 [[N_EXT]], 0
233+
; CHECK-NEXT: br i1 [[C]], label [[LOOP_PREHEADER:%.*]], label [[LOOP_END:%.*]]
234+
; CHECK: loop.preheader:
235+
; CHECK-NEXT: br label [[LOOP:%.*]]
236+
; CHECK: loop:
237+
; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ [[INDEX_NEXT:%.*]], [[LOOP_INC:%.*]] ], [ 0, [[LOOP_PREHEADER]] ]
238+
; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[P1]], i64 [[INDEX]]
239+
; CHECK-NEXT: [[LD1:%.*]] = load i8, ptr [[ARRAYIDX]], align 1
240+
; CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds i8, ptr [[P2]], i64 [[INDEX]]
241+
; CHECK-NEXT: [[LD2:%.*]] = load i8, ptr [[ARRAYIDX1]], align 1
242+
; CHECK-NEXT: [[CMP3:%.*]] = icmp eq i8 [[LD1]], [[LD2]]
243+
; CHECK-NEXT: br i1 [[CMP3]], label [[LOOP_INC]], label [[LOOP_END_LOOPEXIT:%.*]]
244+
; CHECK: loop.inc:
245+
; CHECK-NEXT: [[INDEX_NEXT]] = add i64 [[INDEX]], 1
246+
; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDEX_NEXT]], [[N_EXT]]
247+
; CHECK-NEXT: br i1 [[EXITCOND]], label [[LOOP]], label [[LOOP_END_LOOPEXIT]]
248+
; CHECK: loop.end.loopexit:
249+
; CHECK-NEXT: [[RETVAL_PH:%.*]] = phi i64 [ -1, [[LOOP_INC]] ], [ [[INDEX]], [[LOOP]] ]
250+
; CHECK-NEXT: br label [[LOOP_END]]
251+
; CHECK: loop.end:
252+
; CHECK-NEXT: [[RETVAL:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[RETVAL_PH]], [[LOOP_END_LOOPEXIT]] ]
253+
; CHECK-NEXT: ret i64 [[RETVAL]]
254+
;
255+
entry:
256+
%n.ext = zext i32 %n to i64
257+
%n.scaled = shl nuw nsw i64 %n.ext, 1
258+
call void @llvm.assume(i1 true) [ "align"(ptr %p1, i64 4), "dereferenceable"(ptr %p1, i64 %n.scaled) ]
259+
call void @llvm.assume(i1 true) [ "align"(ptr %p2, i64 4), "dereferenceable"(ptr %p2, i64 %n.scaled) ]
260+
%c = icmp ne i64 %n.ext, 0
261+
br i1 %c, label %loop, label %loop.end
262+
263+
loop:
264+
%index = phi i64 [ 0, %entry ], [ %index.next, %loop.inc ]
265+
%gep.p1 = getelementptr inbounds i8, ptr %p1, i64 %index
266+
%ld1 = load i8, ptr %gep.p1, align 1
267+
%gep.p2 = getelementptr inbounds i8, ptr %p2, i64 %index
268+
%ld2 = load i8, ptr %gep.p2, align 1
269+
%c.0 = icmp eq i8 %ld1, %ld2
270+
br i1 %c.0, label %loop.inc, label %loop.end
271+
272+
loop.inc:
273+
%index.next = add i64 %index, 1
274+
%exitcond = icmp ne i64 %index.next, %n.ext
275+
br i1 %exitcond, label %loop, label %loop.end
276+
277+
loop.end:
278+
%retval = phi i64 [ 0, %entry ], [ %index, %loop ], [ -1, %loop.inc ]
279+
ret i64 %retval
280+
}
281+
282+
define i64 @early_exit_alignment_and_deref_known_via_assumption_n_not_zero_i16_ptr_iv(ptr %A, i32 noundef %n) nofree nosync {
283+
; CHECK-LABEL: define i64 @early_exit_alignment_and_deref_known_via_assumption_n_not_zero_i16_ptr_iv(
284+
; CHECK-SAME: ptr [[A:%.*]], i32 noundef [[N:%.*]]) #[[ATTR0]] {
285+
; CHECK-NEXT: entry:
286+
; CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[A]], i64 2) ]
287+
; CHECK-NEXT: [[N_EXT:%.*]] = zext i32 [[N]] to i64
288+
; CHECK-NEXT: [[MUL:%.*]] = shl nuw nsw i64 [[N_EXT]], 1
289+
; CHECK-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(ptr [[A]], i64 [[MUL]]) ]
290+
; CHECK-NEXT: [[A_END:%.*]] = getelementptr i8, ptr [[A]], i64 [[MUL]]
291+
; CHECK-NEXT: [[PRE:%.*]] = icmp eq i32 [[N]], 0
292+
; CHECK-NEXT: br i1 [[PRE]], label [[EXIT:%.*]], label [[LOOP_HEADER_PREHEADER:%.*]]
293+
; CHECK: loop.header.preheader:
294+
; CHECK-NEXT: br label [[LOOP_HEADER:%.*]]
295+
; CHECK: loop.header:
296+
; CHECK-NEXT: [[IV:%.*]] = phi ptr [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ], [ [[A]], [[LOOP_HEADER_PREHEADER]] ]
297+
; CHECK-NEXT: [[L:%.*]] = load i16, ptr [[IV]], align 2
298+
; CHECK-NEXT: [[C_0:%.*]] = icmp eq i16 [[L]], 0
299+
; CHECK-NEXT: br i1 [[C_0]], label [[EXIT_LOOPEXIT:%.*]], label [[LOOP_LATCH]]
300+
; CHECK: loop.latch:
301+
; CHECK-NEXT: [[IV_NEXT]] = getelementptr inbounds nuw i8, ptr [[IV]], i64 2
302+
; CHECK-NEXT: [[EC:%.*]] = icmp eq ptr [[IV_NEXT]], [[A_END]]
303+
; CHECK-NEXT: br i1 [[EC]], label [[EXIT_LOOPEXIT]], label [[LOOP_HEADER]]
304+
; CHECK: exit.loopexit:
305+
; CHECK-NEXT: [[P_PH:%.*]] = phi ptr [ [[A_END]], [[LOOP_LATCH]] ], [ [[IV]], [[LOOP_HEADER]] ]
306+
; CHECK-NEXT: br label [[EXIT]]
307+
; CHECK: exit:
308+
; CHECK-NEXT: [[P:%.*]] = phi ptr [ [[A]], [[ENTRY:%.*]] ], [ [[P_PH]], [[EXIT_LOOPEXIT]] ]
309+
; CHECK-NEXT: [[RES:%.*]] = ptrtoint ptr [[P]] to i64
310+
; CHECK-NEXT: ret i64 [[RES]]
311+
;
312+
entry:
313+
call void @llvm.assume(i1 true) [ "align"(ptr %A, i64 2) ]
314+
%n.ext = zext i32 %n to i64
315+
%mul = shl nuw nsw i64 %n.ext, 1
316+
call void @llvm.assume(i1 true) [ "dereferenceable"(ptr %A, i64 %mul) ]
317+
%A.end = getelementptr i8, ptr %A, i64 %mul
318+
%pre = icmp eq i32 %n, 0
319+
br i1 %pre, label %exit, label %loop.header
320+
321+
loop.header:
322+
%iv = phi ptr [ %iv.next, %loop.latch ], [ %A, %entry ]
323+
%l = load i16, ptr %iv, align 2
324+
%c.0 = icmp eq i16 %l, 0
325+
br i1 %c.0, label %exit, label %loop.latch
326+
327+
loop.latch:
328+
%iv.next = getelementptr inbounds nuw i8, ptr %iv, i64 2
329+
%ec = icmp eq ptr %iv.next, %A.end
330+
br i1 %ec, label %exit, label %loop.header
331+
332+
exit:
333+
%p = phi ptr [ %A, %entry ], [ %iv, %loop.header ], [ %A.end, %loop.latch ]
334+
%res = ptrtoint ptr %p to i64
335+
ret i64 %res
336+
}

0 commit comments

Comments
 (0)