Skip to content

Commit 9133fc8

Browse files
committed
[LAA,LV] Add early-exit tests with deref assumes and nofree via context.
Add tests with early exits and dereferenceable assumptions that need proving no-free via the context.
1 parent 1f22567 commit 9133fc8

File tree

2 files changed

+173
-0
lines changed

2 files changed

+173
-0
lines changed

llvm/test/Analysis/LoopAccessAnalysis/early-exit-runtime-checks.ll

Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -756,3 +756,129 @@ e.1:
756756
e.2:
757757
ret void
758758
}
759+
760+
define void @all_exits_dominate_latch_countable_exits_at_most_500_iterations_known_deref_via_assumption_nofree_via_context(ptr %A, ptr %B) nosync {
761+
; CHECK-LABEL: 'all_exits_dominate_latch_countable_exits_at_most_500_iterations_known_deref_via_assumption_nofree_via_context'
762+
; CHECK-NEXT: loop.header:
763+
; CHECK-NEXT: Memory dependences are safe with run-time checks
764+
; CHECK-NEXT: Dependences:
765+
; CHECK-NEXT: Run-time memory checks:
766+
; CHECK-NEXT: Check 0:
767+
; CHECK-NEXT: Comparing group GRP0:
768+
; CHECK-NEXT: %gep.B = getelementptr inbounds i32, ptr %B, i64 %iv
769+
; CHECK-NEXT: Against group GRP1:
770+
; CHECK-NEXT: %gep.A = getelementptr inbounds i32, ptr %A, i64 %iv
771+
; CHECK-NEXT: Grouped accesses:
772+
; CHECK-NEXT: Group GRP0:
773+
; CHECK-NEXT: (Low: %B High: inttoptr (i64 -1 to ptr))
774+
; CHECK-NEXT: Member: {%B,+,4}<nuw><%loop.header>
775+
; CHECK-NEXT: Group GRP1:
776+
; CHECK-NEXT: (Low: %A High: inttoptr (i64 -1 to ptr))
777+
; CHECK-NEXT: Member: {%A,+,4}<nuw><%loop.header>
778+
; CHECK-EMPTY:
779+
; CHECK-NEXT: Non vectorizable stores to invariant address were not found in loop.
780+
; CHECK-NEXT: SCEV assumptions:
781+
; CHECK-EMPTY:
782+
; CHECK-NEXT: Expressions re-written:
783+
;
784+
entry:
785+
call void @llvm.assume(i1 true) [ "dereferenceable"(ptr %A, i64 2000) ]
786+
call void @llvm.assume(i1 true) [ "dereferenceable"(ptr %B, i64 2000) ]
787+
br label %loop.header
788+
789+
loop.header:
790+
%iv = phi i64 [ 0, %entry ], [ %iv.next, %latch ]
791+
%gep.A = getelementptr inbounds i32, ptr %A, i64 %iv
792+
%gep.B = getelementptr inbounds i32, ptr %B, i64 %iv
793+
%l = load i32, ptr %gep.A, align 4
794+
store i32 0, ptr %gep.B, align 4
795+
%cntable.c.1 = icmp ult i64 %iv, 1000
796+
%iv.next = add nuw nsw i64 %iv, 1
797+
br i1 %cntable.c.1, label %b2, label %e.1
798+
799+
b2:
800+
%uncntable.c.0 = icmp eq i32 %l, 0
801+
br i1 %uncntable.c.0, label %e.2, label %b3
802+
803+
b3:
804+
%cntable.c.2 = icmp eq i64 %iv.next, 500
805+
br i1 %cntable.c.2, label %cleanup4, label %latch
806+
807+
latch:
808+
br label %loop.header
809+
810+
cleanup4:
811+
ret void
812+
813+
e.1:
814+
ret void
815+
816+
e.2:
817+
ret void
818+
}
819+
820+
define void @all_exits_dominate_latch_countable_exits_at_most_500_iterations_known_deref_via_assumption_missing_nofree_multiple_predecessors(ptr %A, ptr %B, i1 %c) nosync {
821+
; CHECK-LABEL: 'all_exits_dominate_latch_countable_exits_at_most_500_iterations_known_deref_via_assumption_missing_nofree_multiple_predecessors'
822+
; CHECK-NEXT: loop.header:
823+
; CHECK-NEXT: Memory dependences are safe with run-time checks
824+
; CHECK-NEXT: Dependences:
825+
; CHECK-NEXT: Run-time memory checks:
826+
; CHECK-NEXT: Check 0:
827+
; CHECK-NEXT: Comparing group GRP0:
828+
; CHECK-NEXT: %gep.B = getelementptr inbounds i32, ptr %B, i64 %iv
829+
; CHECK-NEXT: Against group GRP1:
830+
; CHECK-NEXT: %gep.A = getelementptr inbounds i32, ptr %A, i64 %iv
831+
; CHECK-NEXT: Grouped accesses:
832+
; CHECK-NEXT: Group GRP0:
833+
; CHECK-NEXT: (Low: %B High: inttoptr (i64 -1 to ptr))
834+
; CHECK-NEXT: Member: {%B,+,4}<nuw><%loop.header>
835+
; CHECK-NEXT: Group GRP1:
836+
; CHECK-NEXT: (Low: %A High: inttoptr (i64 -1 to ptr))
837+
; CHECK-NEXT: Member: {%A,+,4}<nuw><%loop.header>
838+
; CHECK-EMPTY:
839+
; CHECK-NEXT: Non vectorizable stores to invariant address were not found in loop.
840+
; CHECK-NEXT: SCEV assumptions:
841+
; CHECK-EMPTY:
842+
; CHECK-NEXT: Expressions re-written:
843+
;
844+
entry:
845+
call void @llvm.assume(i1 true) [ "dereferenceable"(ptr %A, i64 2000) ]
846+
call void @llvm.assume(i1 true) [ "dereferenceable"(ptr %B, i64 2000) ]
847+
br i1 %c, label %then, label %else
848+
849+
then:
850+
br label %loop.header
851+
852+
else:
853+
br label %loop.header
854+
855+
loop.header:
856+
%iv = phi i64 [ 0, %then ], [ 0, %else ], [ %iv.next, %latch ]
857+
%gep.A = getelementptr inbounds i32, ptr %A, i64 %iv
858+
%gep.B = getelementptr inbounds i32, ptr %B, i64 %iv
859+
%l = load i32, ptr %gep.A, align 4
860+
store i32 0, ptr %gep.B, align 4
861+
%cntable.c.1 = icmp ult i64 %iv, 1000
862+
%iv.next = add nuw nsw i64 %iv, 1
863+
br i1 %cntable.c.1, label %b2, label %e.1
864+
865+
b2:
866+
%uncntable.c.0 = icmp eq i32 %l, 0
867+
br i1 %uncntable.c.0, label %e.2, label %b3
868+
869+
b3:
870+
%cntable.c.2 = icmp eq i64 %iv.next, 500
871+
br i1 %cntable.c.2, label %cleanup4, label %latch
872+
873+
latch:
874+
br label %loop.header
875+
876+
cleanup4:
877+
ret void
878+
879+
e.1:
880+
ret void
881+
882+
e.2:
883+
ret void
884+
}

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

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -500,3 +500,50 @@ exit:
500500
%first.addr.0.lcssa.i = phi ptr [ %first, %entry ], [ %iv, %loop.header ], [ %iv.next, %loop.latch ]
501501
ret ptr %first.addr.0.lcssa.i
502502
}
503+
504+
define i64 @early_exit_alignment_and_deref_known_via_assumption_with_constant_size_nofree_via_context(ptr noalias %p1, ptr noalias %p2) nosync {
505+
; CHECK-LABEL: define i64 @early_exit_alignment_and_deref_known_via_assumption_with_constant_size_nofree_via_context(
506+
; CHECK-SAME: ptr noalias [[P1:%.*]], ptr noalias [[P2:%.*]]) #[[ATTR1:[0-9]+]] {
507+
; CHECK-NEXT: [[ENTRY:.*]]:
508+
; CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[P1]], i64 4), "dereferenceable"(ptr [[P1]], i64 1024) ]
509+
; CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(ptr [[P2]], i64 4), "dereferenceable"(ptr [[P2]], i64 1024) ]
510+
; CHECK-NEXT: br label %[[LOOP:.*]]
511+
; CHECK: [[LOOP]]:
512+
; CHECK-NEXT: [[INDEX1:%.*]] = phi i64 [ [[INDEX_NEXT:%.*]], %[[LOOP_INC:.*]] ], [ 0, %[[ENTRY]] ]
513+
; CHECK-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds i8, ptr [[P1]], i64 [[INDEX1]]
514+
; CHECK-NEXT: [[LD1:%.*]] = load i8, ptr [[ARRAYIDX2]], align 1
515+
; CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds i8, ptr [[P2]], i64 [[INDEX1]]
516+
; CHECK-NEXT: [[LD2:%.*]] = load i8, ptr [[ARRAYIDX1]], align 1
517+
; CHECK-NEXT: [[CMP3:%.*]] = icmp eq i8 [[LD1]], [[LD2]]
518+
; CHECK-NEXT: br i1 [[CMP3]], label %[[LOOP_INC]], label %[[LOOP_END:.*]]
519+
; CHECK: [[LOOP_INC]]:
520+
; CHECK-NEXT: [[INDEX_NEXT]] = add i64 [[INDEX1]], 1
521+
; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INDEX_NEXT]], 1024
522+
; CHECK-NEXT: br i1 [[EXITCOND]], label %[[LOOP]], label %[[LOOP_END]]
523+
; CHECK: [[LOOP_END]]:
524+
; CHECK-NEXT: [[RETVAL:%.*]] = phi i64 [ [[INDEX1]], %[[LOOP]] ], [ -1, %[[LOOP_INC]] ]
525+
; CHECK-NEXT: ret i64 [[RETVAL]]
526+
;
527+
entry:
528+
call void @llvm.assume(i1 true) [ "align"(ptr %p1, i64 4), "dereferenceable"(ptr %p1, i64 1024) ]
529+
call void @llvm.assume(i1 true) [ "align"(ptr %p2, i64 4), "dereferenceable"(ptr %p2, i64 1024) ]
530+
br label %loop
531+
532+
loop:
533+
%index = phi i64 [ %index.next, %loop.inc ], [ 0, %entry ]
534+
%arrayidx = getelementptr inbounds i8, ptr %p1, i64 %index
535+
%ld1 = load i8, ptr %arrayidx, align 1
536+
%arrayidx1 = getelementptr inbounds i8, ptr %p2, i64 %index
537+
%ld2 = load i8, ptr %arrayidx1, align 1
538+
%cmp3 = icmp eq i8 %ld1, %ld2
539+
br i1 %cmp3, label %loop.inc, label %loop.end
540+
541+
loop.inc:
542+
%index.next = add i64 %index, 1
543+
%exitcond = icmp ne i64 %index.next, 1024
544+
br i1 %exitcond, label %loop, label %loop.end
545+
546+
loop.end:
547+
%retval = phi i64 [ %index, %loop ], [ -1, %loop.inc ]
548+
ret i64 %retval
549+
}

0 commit comments

Comments
 (0)