Several tests seemed to require asserts despite not testing any debug output so I have removed the line.
91 lines
4.0 KiB
LLVM
91 lines
4.0 KiB
LLVM
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-globals none --filter-out-after "scalar.ph:" --version 6
|
|
; RUN: opt -passes='loop-vectorize' -force-vector-width=4 -S < %s | FileCheck %s
|
|
|
|
; This checks we don't crash when the inner loop we're trying to vectorize
|
|
; is a SCEV AddRec with respect to an outer loop.
|
|
|
|
; In this case, the problematic PHI is:
|
|
; %0 = phi i32 [ poison, %for.cond1.preheader ], [ %inc54, %for.body3 ]
|
|
; Since %inc54 is the IV of the outer loop, and %0 equivalent to it,
|
|
; we get the situation described above.
|
|
|
|
; Code that leads to this situation can look something like:
|
|
;
|
|
; int a, b[1], c;
|
|
; void fn1 ()
|
|
; {
|
|
; for (; c; c++)
|
|
; for (a = 0; a; a++)
|
|
; b[c] = 4;
|
|
; }
|
|
;
|
|
; The PHI is an artifact of the register promotion of c.
|
|
|
|
; Note that we can no longer get the vectorizer to actually see such PHIs,
|
|
; because LV now simplifies the loop internally, but the test is still
|
|
; useful as a regression test, and in case loop-simplify behavior changes.
|
|
|
|
@c = external global i32, align 4
|
|
@a = external global i32, align 4
|
|
@b = external global [1 x i32], align 4
|
|
|
|
; We can vectorize this loop because we are storing an invariant value into an
|
|
; invariant address.
|
|
|
|
define void @test() {
|
|
; CHECK-LABEL: define void @test() {
|
|
; CHECK-NEXT: [[ENTRY:.*]]:
|
|
; CHECK-NEXT: [[A_PROMOTED2:%.*]] = load i32, ptr @a, align 1
|
|
; CHECK-NEXT: [[C_PROMOTED:%.*]] = load i32, ptr @c, align 1
|
|
; CHECK-NEXT: br label %[[FOR_COND1_PREHEADER:.*]]
|
|
; CHECK: [[FOR_COND1_PREHEADER]]:
|
|
; CHECK-NEXT: [[INC54:%.*]] = phi i32 [ [[INC5:%.*]], %[[FOR_COND1_FOR_INC4_CRIT_EDGE:.*]] ], [ [[C_PROMOTED]], %[[ENTRY]] ]
|
|
; CHECK-NEXT: [[INC_LCSSA3:%.*]] = phi i32 [ [[INC_LCSSA:%.*]], %[[FOR_COND1_FOR_INC4_CRIT_EDGE]] ], [ [[A_PROMOTED2]], %[[ENTRY]] ]
|
|
; CHECK-NEXT: [[TMP0:%.*]] = mul i32 [[INC_LCSSA3]], -1
|
|
; CHECK-NEXT: [[MIN_ITERS_CHECK:%.*]] = icmp ult i32 [[TMP0]], 4
|
|
; CHECK-NEXT: br i1 [[MIN_ITERS_CHECK]], label %[[SCALAR_PH:.*]], label %[[VECTOR_PH:.*]]
|
|
; CHECK: [[VECTOR_PH]]:
|
|
; CHECK-NEXT: [[N_MOD_VF:%.*]] = urem i32 [[TMP0]], 4
|
|
; CHECK-NEXT: [[N_VEC:%.*]] = sub i32 [[TMP0]], [[N_MOD_VF]]
|
|
; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[INC_LCSSA3]], [[N_VEC]]
|
|
; CHECK-NEXT: [[TMP2:%.*]] = sext i32 [[INC54]] to i64
|
|
; CHECK-NEXT: [[TMP3:%.*]] = getelementptr inbounds [1 x i32], ptr @b, i64 0, i64 [[TMP2]]
|
|
; CHECK-NEXT: br label %[[VECTOR_BODY:.*]]
|
|
; CHECK: [[VECTOR_BODY]]:
|
|
; CHECK-NEXT: [[INDEX:%.*]] = phi i32 [ 0, %[[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], %[[VECTOR_BODY]] ]
|
|
; CHECK-NEXT: store i32 4, ptr [[TMP3]], align 4
|
|
; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i32 [[INDEX]], 4
|
|
; CHECK-NEXT: [[TMP4:%.*]] = icmp eq i32 [[INDEX_NEXT]], [[N_VEC]]
|
|
; CHECK-NEXT: br i1 [[TMP4]], label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]], !llvm.loop [[LOOP0:![0-9]+]]
|
|
; CHECK: [[MIDDLE_BLOCK]]:
|
|
; CHECK-NEXT: [[CMP_N:%.*]] = icmp eq i32 [[TMP0]], [[N_VEC]]
|
|
; CHECK-NEXT: br i1 [[CMP_N]], label %[[FOR_COND1_FOR_INC4_CRIT_EDGE]], label %[[SCALAR_PH]]
|
|
; CHECK: [[SCALAR_PH]]:
|
|
;
|
|
entry:
|
|
%a.promoted2 = load i32, ptr @a, align 1
|
|
%c.promoted = load i32, ptr @c, align 1
|
|
br label %for.cond1.preheader
|
|
|
|
for.cond1.preheader:
|
|
%inc54 = phi i32 [ %inc5, %for.cond1.for.inc4_crit_edge ], [ %c.promoted, %entry ]
|
|
%inc.lcssa3 = phi i32 [ %inc.lcssa, %for.cond1.for.inc4_crit_edge ], [ %a.promoted2, %entry ]
|
|
br label %for.body3
|
|
|
|
for.body3:
|
|
%inc1 = phi i32 [ %inc.lcssa3, %for.cond1.preheader ], [ %inc, %for.body3 ]
|
|
%0 = phi i32 [ poison, %for.cond1.preheader ], [ %inc54, %for.body3 ]
|
|
%idxprom = sext i32 %0 to i64
|
|
%arrayidx = getelementptr inbounds [1 x i32], ptr @b, i64 0, i64 %idxprom
|
|
store i32 4, ptr %arrayidx, align 4
|
|
%inc = add nsw i32 %inc1, 1
|
|
%tobool2 = icmp eq i32 %inc, 0
|
|
br i1 %tobool2, label %for.cond1.for.inc4_crit_edge, label %for.body3
|
|
|
|
for.cond1.for.inc4_crit_edge:
|
|
%inc.lcssa = phi i32 [ %inc, %for.body3 ]
|
|
%.lcssa = phi i32 [ %inc54, %for.body3 ]
|
|
%inc5 = add nsw i32 %.lcssa, 1
|
|
br label %for.cond1.preheader
|
|
}
|