llvm-project/llvm/test/Transforms/LoopVectorize/remarks-multi-exit-loops.ll
David Sherwood e762d4dac7
[LoopVectorize] Teach LoopVectorizationLegality about more early exits (#107004)
This patch is split off from PR #88385 and concerns only the code
related to the legality of vectorising early exit loops. It is the first
step in adding support for vectorisation of a simple class of loops that
typically involves searching for something, i.e.

  for (int i = 0; i < n; i++) {
    if (p[i] == val)
      return i;
  }
  return n;

or

  for (int i = 0; i < n; i++) {
    if (p1[i] != p2[i])
      return i;
  }
  return n;

In this initial commit LoopVectorizationLegality will only consider
early exit loops legal for vectorising if they follow these criteria:

1. There are no stores in the loop.
2. The loop must have only one early exit like those shown in the above
example. I have referred to such exits as speculative early exits, to
distinguish from existing support for early exits where the
exit-not-taken count is known exactly at compile time.
3. The early exit block dominates the latch block.
4. The latch block must have an exact exit count.
5. There are no loads after the early exit block.
6. The loop must not contain reductions or recurrences. I don't see
anything fundamental blocking vectorisation of such loops, but I just
haven't done the work to support them yet.
7. We must be able to prove at compile-time that loops will not contain
faulting loads.

Tests have been added here:

  Transforms/LoopVectorize/AArch64/simple_early_exit.ll
2024-09-19 09:41:25 +01:00

29 lines
1.0 KiB
LLVM

; RUN: opt -disable-output -passes=loop-vectorize -pass-remarks-analysis='.*' -force-vector-width=2 2>&1 %s | FileCheck %s
; Make sure LV does not crash when generating remarks for loops with non-unique
; exit blocks.
define i32 @test_non_unique_exit_blocks(ptr nocapture readonly align 4 dereferenceable(1024) %data, i32 %x) {
; CHECK: loop not vectorized: Cannot vectorize early exit loop
;
entry:
br label %for.header
for.header: ; preds = %for.cond.lr.ph, %for.body
%iv = phi i64 [ 0, %entry ], [ %iv.next, %for.latch ]
%iv.next = add nuw nsw i64 %iv, 1
%exitcond.not = icmp eq i64 %iv.next, 256
br i1 %exitcond.not, label %header.exit, label %for.latch
for.latch:
%arrayidx = getelementptr inbounds i32, ptr %data, i64 %iv
%lv = load i32, ptr %arrayidx, align 4
%cmp1 = icmp eq i32 %lv, %x
br i1 %cmp1, label %latch.exit, label %for.header
header.exit: ; preds = %for.body
ret i32 0
latch.exit: ; preds = %for.body
ret i32 %lv
}