1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -passes=loop-vectorize -force-vector-interleave=4 -pass-remarks='loop-vectorize' -disable-output -S 2>&1 | FileCheck %s --check-prefix=CHECK-REMARKS
3 ; RUN: opt < %s -passes=loop-vectorize -force-vector-interleave=4 -S | FileCheck %s
5 ; These tests are to check that fold-tail procedure produces correct scalar code when
6 ; loop-vectorization is only unrolling but not vectorizing.
8 ; CHECK-REMARKS: remark: {{.*}} interleaved loop (interleaved count: 4)
9 ; CHECK-REMARKS-NEXT: remark: {{.*}} interleaved loop (interleaved count: 4)
10 ; CHECK-REMARKS-NOT: remark: {{.*}} vectorized loop
12 define void @VF1-VPlanExe(ptr %dst) {
13 ; CHECK-LABEL: @VF1-VPlanExe(
15 ; CHECK-NEXT: br i1 false, label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]
17 ; CHECK-NEXT: br label [[VECTOR_BODY:%.*]]
19 ; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[PRED_STORE_CONTINUE9:%.*]] ]
20 ; CHECK-NEXT: [[VEC_IV:%.*]] = add i64 [[INDEX]], 0
21 ; CHECK-NEXT: [[VEC_IV1:%.*]] = add i64 [[INDEX]], 1
22 ; CHECK-NEXT: [[VEC_IV2:%.*]] = add i64 [[INDEX]], 2
23 ; CHECK-NEXT: [[VEC_IV3:%.*]] = add i64 [[INDEX]], 3
24 ; CHECK-NEXT: [[TMP0:%.*]] = icmp ule i64 [[VEC_IV]], 14
25 ; CHECK-NEXT: [[TMP1:%.*]] = icmp ule i64 [[VEC_IV1]], 14
26 ; CHECK-NEXT: [[TMP2:%.*]] = icmp ule i64 [[VEC_IV2]], 14
27 ; CHECK-NEXT: [[TMP3:%.*]] = icmp ule i64 [[VEC_IV3]], 14
28 ; CHECK-NEXT: br i1 [[TMP0]], label [[PRED_STORE_IF:%.*]], label [[PRED_STORE_CONTINUE:%.*]]
29 ; CHECK: pred.store.if:
30 ; CHECK-NEXT: [[TMP4:%.*]] = add i64 [[INDEX]], 0
31 ; CHECK-NEXT: [[TMP5:%.*]] = getelementptr inbounds i32, ptr [[DST:%.*]], i64 [[TMP4]]
32 ; CHECK-NEXT: store i32 0, ptr [[TMP5]], align 4
33 ; CHECK-NEXT: br label [[PRED_STORE_CONTINUE]]
34 ; CHECK: pred.store.continue:
35 ; CHECK-NEXT: br i1 [[TMP1]], label [[PRED_STORE_IF4:%.*]], label [[PRED_STORE_CONTINUE5:%.*]]
36 ; CHECK: pred.store.if4:
37 ; CHECK-NEXT: [[TMP6:%.*]] = add i64 [[INDEX]], 1
38 ; CHECK-NEXT: [[TMP7:%.*]] = getelementptr inbounds i32, ptr [[DST]], i64 [[TMP6]]
39 ; CHECK-NEXT: store i32 0, ptr [[TMP7]], align 4
40 ; CHECK-NEXT: br label [[PRED_STORE_CONTINUE5]]
41 ; CHECK: pred.store.continue5:
42 ; CHECK-NEXT: br i1 [[TMP2]], label [[PRED_STORE_IF6:%.*]], label [[PRED_STORE_CONTINUE7:%.*]]
43 ; CHECK: pred.store.if6:
44 ; CHECK-NEXT: [[TMP8:%.*]] = add i64 [[INDEX]], 2
45 ; CHECK-NEXT: [[TMP9:%.*]] = getelementptr inbounds i32, ptr [[DST]], i64 [[TMP8]]
46 ; CHECK-NEXT: store i32 0, ptr [[TMP9]], align 4
47 ; CHECK-NEXT: br label [[PRED_STORE_CONTINUE7]]
48 ; CHECK: pred.store.continue7:
49 ; CHECK-NEXT: br i1 [[TMP3]], label [[PRED_STORE_IF8:%.*]], label [[PRED_STORE_CONTINUE9]]
50 ; CHECK: pred.store.if8:
51 ; CHECK-NEXT: [[TMP10:%.*]] = add i64 [[INDEX]], 3
52 ; CHECK-NEXT: [[TMP11:%.*]] = getelementptr inbounds i32, ptr [[DST]], i64 [[TMP10]]
53 ; CHECK-NEXT: store i32 0, ptr [[TMP11]], align 4
54 ; CHECK-NEXT: br label [[PRED_STORE_CONTINUE9]]
55 ; CHECK: pred.store.continue9:
56 ; CHECK-NEXT: [[INDEX_NEXT]] = add i64 [[INDEX]], 4
57 ; CHECK-NEXT: [[TMP12:%.*]] = icmp eq i64 [[INDEX_NEXT]], 16
58 ; CHECK-NEXT: br i1 [[TMP12]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP0:![0-9]+]]
59 ; CHECK: middle.block:
60 ; CHECK-NEXT: br i1 true, label [[FOR_COND_CLEANUP:%.*]], label [[SCALAR_PH]]
62 ; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i64 [ 16, [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY:%.*]] ]
63 ; CHECK-NEXT: br label [[FOR_BODY:%.*]]
64 ; CHECK: for.cond.cleanup:
65 ; CHECK-NEXT: ret void
67 ; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ], [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY]] ]
68 ; CHECK-NEXT: [[DST_PTR:%.*]] = getelementptr inbounds i32, ptr [[DST]], i64 [[INDVARS_IV]]
69 ; CHECK-NEXT: store i32 0, ptr [[DST_PTR]], align 4
70 ; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1
71 ; CHECK-NEXT: [[EXITCOND:%.*]] = icmp eq i64 [[INDVARS_IV_NEXT]], 15
72 ; CHECK-NEXT: br i1 [[EXITCOND]], label [[FOR_COND_CLEANUP]], label [[FOR_BODY]], !llvm.loop [[LOOP2:![0-9]+]]
81 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
82 %dst.ptr = getelementptr inbounds i32, ptr %dst, i64 %indvars.iv
83 store i32 0, ptr %dst.ptr
84 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
85 %exitcond = icmp eq i64 %indvars.iv.next, 15
86 br i1 %exitcond, label %for.cond.cleanup, label %for.body
89 define void @VF1-VPWidenCanonicalIVRecipeExe(ptr %ptr1) {
90 ; CHECK-LABEL: @VF1-VPWidenCanonicalIVRecipeExe(
92 ; CHECK-NEXT: [[PTR2:%.*]] = getelementptr inbounds double, ptr [[PTR1:%.*]], i64 15
93 ; CHECK-NEXT: br i1 false, label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]
95 ; CHECK-NEXT: [[IND_END:%.*]] = getelementptr i8, ptr [[PTR1]], i64 128
96 ; CHECK-NEXT: br label [[VECTOR_BODY:%.*]]
98 ; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[PRED_STORE_CONTINUE12:%.*]] ]
99 ; CHECK-NEXT: [[VEC_IV:%.*]] = add i64 [[INDEX]], 0
100 ; CHECK-NEXT: [[VEC_IV4:%.*]] = add i64 [[INDEX]], 1
101 ; CHECK-NEXT: [[VEC_IV5:%.*]] = add i64 [[INDEX]], 2
102 ; CHECK-NEXT: [[VEC_IV6:%.*]] = add i64 [[INDEX]], 3
103 ; CHECK-NEXT: [[TMP0:%.*]] = icmp ule i64 [[VEC_IV]], 14
104 ; CHECK-NEXT: [[TMP1:%.*]] = icmp ule i64 [[VEC_IV4]], 14
105 ; CHECK-NEXT: [[TMP2:%.*]] = icmp ule i64 [[VEC_IV5]], 14
106 ; CHECK-NEXT: [[TMP3:%.*]] = icmp ule i64 [[VEC_IV6]], 14
107 ; CHECK-NEXT: br i1 [[TMP0]], label [[PRED_STORE_IF:%.*]], label [[PRED_STORE_CONTINUE:%.*]]
108 ; CHECK: pred.store.if:
109 ; CHECK-NEXT: [[TMP4:%.*]] = add i64 [[INDEX]], 0
110 ; CHECK-NEXT: [[TMP5:%.*]] = mul i64 [[TMP4]], 8
111 ; CHECK-NEXT: [[NEXT_GEP:%.*]] = getelementptr i8, ptr [[PTR1]], i64 [[TMP5]]
112 ; CHECK-NEXT: store double 0.000000e+00, ptr [[NEXT_GEP]], align 8
113 ; CHECK-NEXT: br label [[PRED_STORE_CONTINUE]]
114 ; CHECK: pred.store.continue:
115 ; CHECK-NEXT: br i1 [[TMP1]], label [[PRED_STORE_IF7:%.*]], label [[PRED_STORE_CONTINUE8:%.*]]
116 ; CHECK: pred.store.if7:
117 ; CHECK-NEXT: [[TMP6:%.*]] = add i64 [[INDEX]], 1
118 ; CHECK-NEXT: [[TMP7:%.*]] = mul i64 [[TMP6]], 8
119 ; CHECK-NEXT: [[NEXT_GEP1:%.*]] = getelementptr i8, ptr [[PTR1]], i64 [[TMP7]]
120 ; CHECK-NEXT: store double 0.000000e+00, ptr [[NEXT_GEP1]], align 8
121 ; CHECK-NEXT: br label [[PRED_STORE_CONTINUE8]]
122 ; CHECK: pred.store.continue8:
123 ; CHECK-NEXT: br i1 [[TMP2]], label [[PRED_STORE_IF9:%.*]], label [[PRED_STORE_CONTINUE10:%.*]]
124 ; CHECK: pred.store.if9:
125 ; CHECK-NEXT: [[TMP8:%.*]] = add i64 [[INDEX]], 2
126 ; CHECK-NEXT: [[TMP9:%.*]] = mul i64 [[TMP8]], 8
127 ; CHECK-NEXT: [[NEXT_GEP2:%.*]] = getelementptr i8, ptr [[PTR1]], i64 [[TMP9]]
128 ; CHECK-NEXT: store double 0.000000e+00, ptr [[NEXT_GEP2]], align 8
129 ; CHECK-NEXT: br label [[PRED_STORE_CONTINUE10]]
130 ; CHECK: pred.store.continue10:
131 ; CHECK-NEXT: br i1 [[TMP3]], label [[PRED_STORE_IF11:%.*]], label [[PRED_STORE_CONTINUE12]]
132 ; CHECK: pred.store.if11:
133 ; CHECK-NEXT: [[TMP10:%.*]] = add i64 [[INDEX]], 3
134 ; CHECK-NEXT: [[TMP11:%.*]] = mul i64 [[TMP10]], 8
135 ; CHECK-NEXT: [[NEXT_GEP3:%.*]] = getelementptr i8, ptr [[PTR1]], i64 [[TMP11]]
136 ; CHECK-NEXT: store double 0.000000e+00, ptr [[NEXT_GEP3]], align 8
137 ; CHECK-NEXT: br label [[PRED_STORE_CONTINUE12]]
138 ; CHECK: pred.store.continue12:
139 ; CHECK-NEXT: [[INDEX_NEXT]] = add i64 [[INDEX]], 4
140 ; CHECK-NEXT: [[TMP12:%.*]] = icmp eq i64 [[INDEX_NEXT]], 16
141 ; CHECK-NEXT: br i1 [[TMP12]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP3:![0-9]+]]
142 ; CHECK: middle.block:
143 ; CHECK-NEXT: br i1 true, label [[FOR_COND_CLEANUP:%.*]], label [[SCALAR_PH]]
145 ; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi ptr [ [[IND_END]], [[MIDDLE_BLOCK]] ], [ [[PTR1]], [[ENTRY:%.*]] ]
146 ; CHECK-NEXT: br label [[FOR_BODY:%.*]]
147 ; CHECK: for.cond.cleanup:
148 ; CHECK-NEXT: ret void
150 ; CHECK-NEXT: [[ADDR:%.*]] = phi ptr [ [[PTR:%.*]], [[FOR_BODY]] ], [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ]
151 ; CHECK-NEXT: store double 0.000000e+00, ptr [[ADDR]], align 8
152 ; CHECK-NEXT: [[PTR]] = getelementptr inbounds double, ptr [[ADDR]], i64 1
153 ; CHECK-NEXT: [[COND:%.*]] = icmp eq ptr [[PTR]], [[PTR2]]
154 ; CHECK-NEXT: br i1 [[COND]], label [[FOR_COND_CLEANUP]], label [[FOR_BODY]], !llvm.loop [[LOOP4:![0-9]+]]
157 %ptr2 = getelementptr inbounds double, ptr %ptr1, i64 15
164 %addr = phi ptr [ %ptr, %for.body ], [ %ptr1, %entry ]
165 store double 0.0, ptr %addr
166 %ptr = getelementptr inbounds double, ptr %addr, i64 1
167 %cond = icmp eq ptr %ptr, %ptr2
168 br i1 %cond, label %for.cond.cleanup, label %for.body
170 ;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line:
171 ; CHECK-REMARKS: {{.*}}