Bump version to 19.1.0-rc3
[llvm-project.git] / llvm / test / Transforms / LoopVectorize / RISCV / low-trip-count.ll
blobec50b0cac038293f648450b1f94ff1deb0bc3236
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt -passes=loop-vectorize -riscv-v-vector-bits-min=128 -scalable-vectorization=on -force-target-instruction-cost=1 -S < %s | FileCheck %s
4 target triple = "riscv64"
6 define void @trip1_i8(ptr noalias nocapture noundef %dst, ptr noalias nocapture noundef readonly %src) #0 {
7 ; CHECK-LABEL: @trip1_i8(
8 ; CHECK-NEXT:  entry:
9 ; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
10 ; CHECK:       for.body:
11 ; CHECK-NEXT:    [[I_08:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[INC:%.*]], [[FOR_BODY]] ]
12 ; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[SRC:%.*]], i64 [[I_08]]
13 ; CHECK-NEXT:    [[TMP0:%.*]] = load i8, ptr [[ARRAYIDX]], align 1
14 ; CHECK-NEXT:    [[MUL:%.*]] = shl i8 [[TMP0]], 1
15 ; CHECK-NEXT:    [[ARRAYIDX1:%.*]] = getelementptr inbounds i8, ptr [[DST:%.*]], i64 [[I_08]]
16 ; CHECK-NEXT:    [[TMP1:%.*]] = load i8, ptr [[ARRAYIDX1]], align 1
17 ; CHECK-NEXT:    [[ADD:%.*]] = add i8 [[MUL]], [[TMP1]]
18 ; CHECK-NEXT:    store i8 [[ADD]], ptr [[ARRAYIDX1]], align 1
19 ; CHECK-NEXT:    [[INC]] = add nuw nsw i64 [[I_08]], 1
20 ; CHECK-NEXT:    [[EXITCOND_NOT:%.*]] = icmp eq i64 [[INC]], 1
21 ; CHECK-NEXT:    br i1 [[EXITCOND_NOT]], label [[FOR_END:%.*]], label [[FOR_BODY]]
22 ; CHECK:       for.end:
23 ; CHECK-NEXT:    ret void
25 entry:
26   br label %for.body
28 for.body:                                         ; preds = %entry, %for.body
29   %i.08 = phi i64 [ 0, %entry ], [ %inc, %for.body ]
30   %arrayidx = getelementptr inbounds i8, ptr %src, i64 %i.08
31   %0 = load i8, ptr %arrayidx, align 1
32   %mul = shl i8 %0, 1
33   %arrayidx1 = getelementptr inbounds i8, ptr %dst, i64 %i.08
34   %1 = load i8, ptr %arrayidx1, align 1
35   %add = add i8 %mul, %1
36   store i8 %add, ptr %arrayidx1, align 1
37   %inc = add nuw nsw i64 %i.08, 1
38   %exitcond.not = icmp eq i64 %inc, 1
39   br i1 %exitcond.not, label %for.end, label %for.body
41 for.end:                                          ; preds = %for.body
42   ret void
45 define void @trip3_i8(ptr noalias nocapture noundef %dst, ptr noalias nocapture noundef readonly %src) #0 {
46 ; CHECK-LABEL: @trip3_i8(
47 ; CHECK-NEXT:  entry:
48 ; CHECK-NEXT:    br i1 false, label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]
49 ; CHECK:       vector.ph:
50 ; CHECK-NEXT:    [[TMP0:%.*]] = call i64 @llvm.vscale.i64()
51 ; CHECK-NEXT:    [[TMP1:%.*]] = mul i64 [[TMP0]], 2
52 ; CHECK-NEXT:    [[TMP4:%.*]] = sub i64 [[TMP1]], 1
53 ; CHECK-NEXT:    [[N_RND_UP:%.*]] = add i64 3, [[TMP4]]
54 ; CHECK-NEXT:    [[N_MOD_VF:%.*]] = urem i64 [[N_RND_UP]], [[TMP1]]
55 ; CHECK-NEXT:    [[N_VEC:%.*]] = sub i64 [[N_RND_UP]], [[N_MOD_VF]]
56 ; CHECK-NEXT:    [[TMP5:%.*]] = call i64 @llvm.vscale.i64()
57 ; CHECK-NEXT:    [[TMP6:%.*]] = mul i64 [[TMP5]], 2
58 ; CHECK-NEXT:    br label [[VECTOR_BODY:%.*]]
59 ; CHECK:       vector.body:
60 ; CHECK-NEXT:    [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ]
61 ; CHECK-NEXT:    [[TMP7:%.*]] = add i64 [[INDEX]], 0
62 ; CHECK-NEXT:    [[ACTIVE_LANE_MASK:%.*]] = call <vscale x 2 x i1> @llvm.get.active.lane.mask.nxv2i1.i64(i64 [[TMP7]], i64 3)
63 ; CHECK-NEXT:    [[TMP8:%.*]] = getelementptr inbounds i8, ptr [[SRC:%.*]], i64 [[TMP7]]
64 ; CHECK-NEXT:    [[TMP9:%.*]] = getelementptr inbounds i8, ptr [[TMP8]], i32 0
65 ; CHECK-NEXT:    [[WIDE_MASKED_LOAD:%.*]] = call <vscale x 2 x i8> @llvm.masked.load.nxv2i8.p0(ptr [[TMP9]], i32 1, <vscale x 2 x i1> [[ACTIVE_LANE_MASK]], <vscale x 2 x i8> poison)
66 ; CHECK-NEXT:    [[TMP10:%.*]] = shl <vscale x 2 x i8> [[WIDE_MASKED_LOAD]], shufflevector (<vscale x 2 x i8> insertelement (<vscale x 2 x i8> poison, i8 1, i64 0), <vscale x 2 x i8> poison, <vscale x 2 x i32> zeroinitializer)
67 ; CHECK-NEXT:    [[TMP11:%.*]] = getelementptr inbounds i8, ptr [[DST:%.*]], i64 [[TMP7]]
68 ; CHECK-NEXT:    [[TMP12:%.*]] = getelementptr inbounds i8, ptr [[TMP11]], i32 0
69 ; CHECK-NEXT:    [[WIDE_MASKED_LOAD1:%.*]] = call <vscale x 2 x i8> @llvm.masked.load.nxv2i8.p0(ptr [[TMP12]], i32 1, <vscale x 2 x i1> [[ACTIVE_LANE_MASK]], <vscale x 2 x i8> poison)
70 ; CHECK-NEXT:    [[TMP13:%.*]] = add <vscale x 2 x i8> [[TMP10]], [[WIDE_MASKED_LOAD1]]
71 ; CHECK-NEXT:    call void @llvm.masked.store.nxv2i8.p0(<vscale x 2 x i8> [[TMP13]], ptr [[TMP12]], i32 1, <vscale x 2 x i1> [[ACTIVE_LANE_MASK]])
72 ; CHECK-NEXT:    [[INDEX_NEXT]] = add i64 [[INDEX]], [[TMP6]]
73 ; CHECK-NEXT:    br i1 true, label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP0:![0-9]+]]
74 ; CHECK:       middle.block:
75 ; CHECK-NEXT:    br i1 true, label [[FOR_END:%.*]], label [[SCALAR_PH]]
76 ; CHECK:       scalar.ph:
77 ; CHECK-NEXT:    [[BC_RESUME_VAL:%.*]] = phi i64 [ [[N_VEC]], [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY:%.*]] ]
78 ; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
79 ; CHECK:       for.body:
80 ; CHECK-NEXT:    [[I_08:%.*]] = phi i64 [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ], [ [[INC:%.*]], [[FOR_BODY]] ]
81 ; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[SRC]], i64 [[I_08]]
82 ; CHECK-NEXT:    [[TMP14:%.*]] = load i8, ptr [[ARRAYIDX]], align 1
83 ; CHECK-NEXT:    [[MUL:%.*]] = shl i8 [[TMP14]], 1
84 ; CHECK-NEXT:    [[ARRAYIDX1:%.*]] = getelementptr inbounds i8, ptr [[DST]], i64 [[I_08]]
85 ; CHECK-NEXT:    [[TMP15:%.*]] = load i8, ptr [[ARRAYIDX1]], align 1
86 ; CHECK-NEXT:    [[ADD:%.*]] = add i8 [[MUL]], [[TMP15]]
87 ; CHECK-NEXT:    store i8 [[ADD]], ptr [[ARRAYIDX1]], align 1
88 ; CHECK-NEXT:    [[INC]] = add nuw nsw i64 [[I_08]], 1
89 ; CHECK-NEXT:    [[EXITCOND_NOT:%.*]] = icmp eq i64 [[INC]], 3
90 ; CHECK-NEXT:    br i1 [[EXITCOND_NOT]], label [[FOR_END]], label [[FOR_BODY]], !llvm.loop [[LOOP3:![0-9]+]]
91 ; CHECK:       for.end:
92 ; CHECK-NEXT:    ret void
94 entry:
95   br label %for.body
97 for.body:                                         ; preds = %entry, %for.body
98   %i.08 = phi i64 [ 0, %entry ], [ %inc, %for.body ]
99   %arrayidx = getelementptr inbounds i8, ptr %src, i64 %i.08
100   %0 = load i8, ptr %arrayidx, align 1
101   %mul = shl i8 %0, 1
102   %arrayidx1 = getelementptr inbounds i8, ptr %dst, i64 %i.08
103   %1 = load i8, ptr %arrayidx1, align 1
104   %add = add i8 %mul, %1
105   store i8 %add, ptr %arrayidx1, align 1
106   %inc = add nuw nsw i64 %i.08, 1
107   %exitcond.not = icmp eq i64 %inc, 3
108   br i1 %exitcond.not, label %for.end, label %for.body
110 for.end:                                          ; preds = %for.body
111   ret void
114 define void @trip5_i8(ptr noalias nocapture noundef %dst, ptr noalias nocapture noundef readonly %src) #0 {
115 ; CHECK-LABEL: @trip5_i8(
116 ; CHECK-NEXT:  entry:
117 ; CHECK-NEXT:    br i1 false, label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]
118 ; CHECK:       vector.ph:
119 ; CHECK-NEXT:    [[TMP0:%.*]] = call i64 @llvm.vscale.i64()
120 ; CHECK-NEXT:    [[TMP1:%.*]] = mul i64 [[TMP0]], 4
121 ; CHECK-NEXT:    [[TMP4:%.*]] = sub i64 [[TMP1]], 1
122 ; CHECK-NEXT:    [[N_RND_UP:%.*]] = add i64 5, [[TMP4]]
123 ; CHECK-NEXT:    [[N_MOD_VF:%.*]] = urem i64 [[N_RND_UP]], [[TMP1]]
124 ; CHECK-NEXT:    [[N_VEC:%.*]] = sub i64 [[N_RND_UP]], [[N_MOD_VF]]
125 ; CHECK-NEXT:    [[TMP5:%.*]] = call i64 @llvm.vscale.i64()
126 ; CHECK-NEXT:    [[TMP6:%.*]] = mul i64 [[TMP5]], 4
127 ; CHECK-NEXT:    br label [[VECTOR_BODY:%.*]]
128 ; CHECK:       vector.body:
129 ; CHECK-NEXT:    [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ]
130 ; CHECK-NEXT:    [[TMP7:%.*]] = add i64 [[INDEX]], 0
131 ; CHECK-NEXT:    [[ACTIVE_LANE_MASK:%.*]] = call <vscale x 4 x i1> @llvm.get.active.lane.mask.nxv4i1.i64(i64 [[TMP7]], i64 5)
132 ; CHECK-NEXT:    [[TMP8:%.*]] = getelementptr inbounds i8, ptr [[SRC:%.*]], i64 [[TMP7]]
133 ; CHECK-NEXT:    [[TMP9:%.*]] = getelementptr inbounds i8, ptr [[TMP8]], i32 0
134 ; CHECK-NEXT:    [[WIDE_MASKED_LOAD:%.*]] = call <vscale x 4 x i8> @llvm.masked.load.nxv4i8.p0(ptr [[TMP9]], i32 1, <vscale x 4 x i1> [[ACTIVE_LANE_MASK]], <vscale x 4 x i8> poison)
135 ; CHECK-NEXT:    [[TMP10:%.*]] = shl <vscale x 4 x i8> [[WIDE_MASKED_LOAD]], shufflevector (<vscale x 4 x i8> insertelement (<vscale x 4 x i8> poison, i8 1, i64 0), <vscale x 4 x i8> poison, <vscale x 4 x i32> zeroinitializer)
136 ; CHECK-NEXT:    [[TMP11:%.*]] = getelementptr inbounds i8, ptr [[DST:%.*]], i64 [[TMP7]]
137 ; CHECK-NEXT:    [[TMP12:%.*]] = getelementptr inbounds i8, ptr [[TMP11]], i32 0
138 ; CHECK-NEXT:    [[WIDE_MASKED_LOAD1:%.*]] = call <vscale x 4 x i8> @llvm.masked.load.nxv4i8.p0(ptr [[TMP12]], i32 1, <vscale x 4 x i1> [[ACTIVE_LANE_MASK]], <vscale x 4 x i8> poison)
139 ; CHECK-NEXT:    [[TMP13:%.*]] = add <vscale x 4 x i8> [[TMP10]], [[WIDE_MASKED_LOAD1]]
140 ; CHECK-NEXT:    call void @llvm.masked.store.nxv4i8.p0(<vscale x 4 x i8> [[TMP13]], ptr [[TMP12]], i32 1, <vscale x 4 x i1> [[ACTIVE_LANE_MASK]])
141 ; CHECK-NEXT:    [[INDEX_NEXT]] = add i64 [[INDEX]], [[TMP6]]
142 ; CHECK-NEXT:    br i1 true, label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP4:![0-9]+]]
143 ; CHECK:       middle.block:
144 ; CHECK-NEXT:    br i1 true, label [[FOR_END:%.*]], label [[SCALAR_PH]]
145 ; CHECK:       scalar.ph:
146 ; CHECK-NEXT:    [[BC_RESUME_VAL:%.*]] = phi i64 [ [[N_VEC]], [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY:%.*]] ]
147 ; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
148 ; CHECK:       for.body:
149 ; CHECK-NEXT:    [[I_08:%.*]] = phi i64 [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ], [ [[INC:%.*]], [[FOR_BODY]] ]
150 ; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[SRC]], i64 [[I_08]]
151 ; CHECK-NEXT:    [[TMP14:%.*]] = load i8, ptr [[ARRAYIDX]], align 1
152 ; CHECK-NEXT:    [[MUL:%.*]] = shl i8 [[TMP14]], 1
153 ; CHECK-NEXT:    [[ARRAYIDX1:%.*]] = getelementptr inbounds i8, ptr [[DST]], i64 [[I_08]]
154 ; CHECK-NEXT:    [[TMP15:%.*]] = load i8, ptr [[ARRAYIDX1]], align 1
155 ; CHECK-NEXT:    [[ADD:%.*]] = add i8 [[MUL]], [[TMP15]]
156 ; CHECK-NEXT:    store i8 [[ADD]], ptr [[ARRAYIDX1]], align 1
157 ; CHECK-NEXT:    [[INC]] = add nuw nsw i64 [[I_08]], 1
158 ; CHECK-NEXT:    [[EXITCOND_NOT:%.*]] = icmp eq i64 [[INC]], 5
159 ; CHECK-NEXT:    br i1 [[EXITCOND_NOT]], label [[FOR_END]], label [[FOR_BODY]], !llvm.loop [[LOOP5:![0-9]+]]
160 ; CHECK:       for.end:
161 ; CHECK-NEXT:    ret void
163 entry:
164   br label %for.body
166 for.body:                                         ; preds = %entry, %for.body
167   %i.08 = phi i64 [ 0, %entry ], [ %inc, %for.body ]
168   %arrayidx = getelementptr inbounds i8, ptr %src, i64 %i.08
169   %0 = load i8, ptr %arrayidx, align 1
170   %mul = shl i8 %0, 1
171   %arrayidx1 = getelementptr inbounds i8, ptr %dst, i64 %i.08
172   %1 = load i8, ptr %arrayidx1, align 1
173   %add = add i8 %mul, %1
174   store i8 %add, ptr %arrayidx1, align 1
175   %inc = add nuw nsw i64 %i.08, 1
176   %exitcond.not = icmp eq i64 %inc, 5
177   br i1 %exitcond.not, label %for.end, label %for.body
179 for.end:                                          ; preds = %for.body
180   ret void
183 define void @trip8_i8(ptr noalias nocapture noundef %dst, ptr noalias nocapture noundef readonly %src) #0 {
184 ; CHECK-LABEL: @trip8_i8(
185 ; CHECK-NEXT:  entry:
186 ; CHECK-NEXT:    br i1 false, label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]
187 ; CHECK:       vector.ph:
188 ; CHECK-NEXT:    [[TMP0:%.*]] = call i64 @llvm.vscale.i64()
189 ; CHECK-NEXT:    [[TMP1:%.*]] = mul i64 [[TMP0]], 4
190 ; CHECK-NEXT:    [[TMP4:%.*]] = sub i64 [[TMP1]], 1
191 ; CHECK-NEXT:    [[N_RND_UP:%.*]] = add i64 8, [[TMP4]]
192 ; CHECK-NEXT:    [[N_MOD_VF:%.*]] = urem i64 [[N_RND_UP]], [[TMP1]]
193 ; CHECK-NEXT:    [[N_VEC:%.*]] = sub i64 [[N_RND_UP]], [[N_MOD_VF]]
194 ; CHECK-NEXT:    [[TMP5:%.*]] = call i64 @llvm.vscale.i64()
195 ; CHECK-NEXT:    [[TMP6:%.*]] = mul i64 [[TMP5]], 4
196 ; CHECK-NEXT:    br label [[VECTOR_BODY:%.*]]
197 ; CHECK:       vector.body:
198 ; CHECK-NEXT:    [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ]
199 ; CHECK-NEXT:    [[TMP7:%.*]] = add i64 [[INDEX]], 0
200 ; CHECK-NEXT:    [[ACTIVE_LANE_MASK:%.*]] = call <vscale x 4 x i1> @llvm.get.active.lane.mask.nxv4i1.i64(i64 [[TMP7]], i64 8)
201 ; CHECK-NEXT:    [[TMP8:%.*]] = getelementptr inbounds i8, ptr [[SRC:%.*]], i64 [[TMP7]]
202 ; CHECK-NEXT:    [[TMP9:%.*]] = getelementptr inbounds i8, ptr [[TMP8]], i32 0
203 ; CHECK-NEXT:    [[WIDE_MASKED_LOAD:%.*]] = call <vscale x 4 x i8> @llvm.masked.load.nxv4i8.p0(ptr [[TMP9]], i32 1, <vscale x 4 x i1> [[ACTIVE_LANE_MASK]], <vscale x 4 x i8> poison)
204 ; CHECK-NEXT:    [[TMP10:%.*]] = shl <vscale x 4 x i8> [[WIDE_MASKED_LOAD]], shufflevector (<vscale x 4 x i8> insertelement (<vscale x 4 x i8> poison, i8 1, i64 0), <vscale x 4 x i8> poison, <vscale x 4 x i32> zeroinitializer)
205 ; CHECK-NEXT:    [[TMP11:%.*]] = getelementptr inbounds i8, ptr [[DST:%.*]], i64 [[TMP7]]
206 ; CHECK-NEXT:    [[TMP12:%.*]] = getelementptr inbounds i8, ptr [[TMP11]], i32 0
207 ; CHECK-NEXT:    [[WIDE_MASKED_LOAD1:%.*]] = call <vscale x 4 x i8> @llvm.masked.load.nxv4i8.p0(ptr [[TMP12]], i32 1, <vscale x 4 x i1> [[ACTIVE_LANE_MASK]], <vscale x 4 x i8> poison)
208 ; CHECK-NEXT:    [[TMP13:%.*]] = add <vscale x 4 x i8> [[TMP10]], [[WIDE_MASKED_LOAD1]]
209 ; CHECK-NEXT:    call void @llvm.masked.store.nxv4i8.p0(<vscale x 4 x i8> [[TMP13]], ptr [[TMP12]], i32 1, <vscale x 4 x i1> [[ACTIVE_LANE_MASK]])
210 ; CHECK-NEXT:    [[INDEX_NEXT]] = add i64 [[INDEX]], [[TMP6]]
211 ; CHECK-NEXT:    br i1 true, label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP6:![0-9]+]]
212 ; CHECK:       middle.block:
213 ; CHECK-NEXT:    br i1 true, label [[FOR_END:%.*]], label [[SCALAR_PH]]
214 ; CHECK:       scalar.ph:
215 ; CHECK-NEXT:    [[BC_RESUME_VAL:%.*]] = phi i64 [ [[N_VEC]], [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY:%.*]] ]
216 ; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
217 ; CHECK:       for.body:
218 ; CHECK-NEXT:    [[I_08:%.*]] = phi i64 [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ], [ [[INC:%.*]], [[FOR_BODY]] ]
219 ; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[SRC]], i64 [[I_08]]
220 ; CHECK-NEXT:    [[TMP14:%.*]] = load i8, ptr [[ARRAYIDX]], align 1
221 ; CHECK-NEXT:    [[MUL:%.*]] = shl i8 [[TMP14]], 1
222 ; CHECK-NEXT:    [[ARRAYIDX1:%.*]] = getelementptr inbounds i8, ptr [[DST]], i64 [[I_08]]
223 ; CHECK-NEXT:    [[TMP15:%.*]] = load i8, ptr [[ARRAYIDX1]], align 1
224 ; CHECK-NEXT:    [[ADD:%.*]] = add i8 [[MUL]], [[TMP15]]
225 ; CHECK-NEXT:    store i8 [[ADD]], ptr [[ARRAYIDX1]], align 1
226 ; CHECK-NEXT:    [[INC]] = add nuw nsw i64 [[I_08]], 1
227 ; CHECK-NEXT:    [[EXITCOND_NOT:%.*]] = icmp eq i64 [[INC]], 8
228 ; CHECK-NEXT:    br i1 [[EXITCOND_NOT]], label [[FOR_END]], label [[FOR_BODY]], !llvm.loop [[LOOP7:![0-9]+]]
229 ; CHECK:       for.end:
230 ; CHECK-NEXT:    ret void
232 entry:
233   br label %for.body
235 for.body:                                         ; preds = %entry, %for.body
236   %i.08 = phi i64 [ 0, %entry ], [ %inc, %for.body ]
237   %arrayidx = getelementptr inbounds i8, ptr %src, i64 %i.08
238   %0 = load i8, ptr %arrayidx, align 1
239   %mul = shl i8 %0, 1
240   %arrayidx1 = getelementptr inbounds i8, ptr %dst, i64 %i.08
241   %1 = load i8, ptr %arrayidx1, align 1
242   %add = add i8 %mul, %1
243   store i8 %add, ptr %arrayidx1, align 1
244   %inc = add nuw nsw i64 %i.08, 1
245   %exitcond.not = icmp eq i64 %inc, 8
246   br i1 %exitcond.not, label %for.end, label %for.body
248 for.end:                                          ; preds = %for.body
249   ret void
252 define void @trip16_i8(ptr noalias nocapture noundef %dst, ptr noalias nocapture noundef readonly %src) #0 {
253 ; CHECK-LABEL: @trip16_i8(
254 ; CHECK-NEXT:  entry:
255 ; CHECK-NEXT:    br i1 false, label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]
256 ; CHECK:       vector.ph:
257 ; CHECK-NEXT:    br label [[VECTOR_BODY:%.*]]
258 ; CHECK:       vector.body:
259 ; CHECK-NEXT:    [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ]
260 ; CHECK-NEXT:    [[TMP0:%.*]] = add i64 [[INDEX]], 0
261 ; CHECK-NEXT:    [[TMP1:%.*]] = getelementptr inbounds i8, ptr [[SRC:%.*]], i64 [[TMP0]]
262 ; CHECK-NEXT:    [[TMP2:%.*]] = getelementptr inbounds i8, ptr [[TMP1]], i32 0
263 ; CHECK-NEXT:    [[WIDE_LOAD:%.*]] = load <16 x i8>, ptr [[TMP2]], align 1
264 ; CHECK-NEXT:    [[TMP3:%.*]] = shl <16 x i8> [[WIDE_LOAD]], <i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1>
265 ; CHECK-NEXT:    [[TMP4:%.*]] = getelementptr inbounds i8, ptr [[DST:%.*]], i64 [[TMP0]]
266 ; CHECK-NEXT:    [[TMP5:%.*]] = getelementptr inbounds i8, ptr [[TMP4]], i32 0
267 ; CHECK-NEXT:    [[WIDE_LOAD1:%.*]] = load <16 x i8>, ptr [[TMP5]], align 1
268 ; CHECK-NEXT:    [[TMP6:%.*]] = add <16 x i8> [[TMP3]], [[WIDE_LOAD1]]
269 ; CHECK-NEXT:    store <16 x i8> [[TMP6]], ptr [[TMP5]], align 1
270 ; CHECK-NEXT:    [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 16
271 ; CHECK-NEXT:    br i1 true, label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP8:![0-9]+]]
272 ; CHECK:       middle.block:
273 ; CHECK-NEXT:    br i1 true, label [[FOR_END:%.*]], label [[SCALAR_PH]]
274 ; CHECK:       scalar.ph:
275 ; CHECK-NEXT:    [[BC_RESUME_VAL:%.*]] = phi i64 [ 16, [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY:%.*]] ]
276 ; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
277 ; CHECK:       for.body:
278 ; CHECK-NEXT:    [[I_08:%.*]] = phi i64 [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ], [ [[INC:%.*]], [[FOR_BODY]] ]
279 ; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[SRC]], i64 [[I_08]]
280 ; CHECK-NEXT:    [[TMP7:%.*]] = load i8, ptr [[ARRAYIDX]], align 1
281 ; CHECK-NEXT:    [[MUL:%.*]] = shl i8 [[TMP7]], 1
282 ; CHECK-NEXT:    [[ARRAYIDX1:%.*]] = getelementptr inbounds i8, ptr [[DST]], i64 [[I_08]]
283 ; CHECK-NEXT:    [[TMP8:%.*]] = load i8, ptr [[ARRAYIDX1]], align 1
284 ; CHECK-NEXT:    [[ADD:%.*]] = add i8 [[MUL]], [[TMP8]]
285 ; CHECK-NEXT:    store i8 [[ADD]], ptr [[ARRAYIDX1]], align 1
286 ; CHECK-NEXT:    [[INC]] = add nuw nsw i64 [[I_08]], 1
287 ; CHECK-NEXT:    [[EXITCOND_NOT:%.*]] = icmp eq i64 [[INC]], 16
288 ; CHECK-NEXT:    br i1 [[EXITCOND_NOT]], label [[FOR_END]], label [[FOR_BODY]], !llvm.loop [[LOOP9:![0-9]+]]
289 ; CHECK:       for.end:
290 ; CHECK-NEXT:    ret void
292 entry:
293   br label %for.body
295 for.body:                                         ; preds = %entry, %for.body
296   %i.08 = phi i64 [ 0, %entry ], [ %inc, %for.body ]
297   %arrayidx = getelementptr inbounds i8, ptr %src, i64 %i.08
298   %0 = load i8, ptr %arrayidx, align 1
299   %mul = shl i8 %0, 1
300   %arrayidx1 = getelementptr inbounds i8, ptr %dst, i64 %i.08
301   %1 = load i8, ptr %arrayidx1, align 1
302   %add = add i8 %mul, %1
303   store i8 %add, ptr %arrayidx1, align 1
304   %inc = add nuw nsw i64 %i.08, 1
305   %exitcond.not = icmp eq i64 %inc, 16
306   br i1 %exitcond.not, label %for.end, label %for.body
308 for.end:                                          ; preds = %for.body
309   ret void
313 define void @trip32_i8(ptr noalias nocapture noundef %dst, ptr noalias nocapture noundef readonly %src) #0 {
314 ; CHECK-LABEL: @trip32_i8(
315 ; CHECK-NEXT:  entry:
316 ; CHECK-NEXT:    br i1 false, label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]
317 ; CHECK:       vector.ph:
318 ; CHECK-NEXT:    br label [[VECTOR_BODY:%.*]]
319 ; CHECK:       vector.body:
320 ; CHECK-NEXT:    [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ]
321 ; CHECK-NEXT:    [[TMP0:%.*]] = add i64 [[INDEX]], 0
322 ; CHECK-NEXT:    [[TMP1:%.*]] = getelementptr inbounds i8, ptr [[SRC:%.*]], i64 [[TMP0]]
323 ; CHECK-NEXT:    [[TMP2:%.*]] = getelementptr inbounds i8, ptr [[TMP1]], i32 0
324 ; CHECK-NEXT:    [[WIDE_LOAD:%.*]] = load <32 x i8>, ptr [[TMP2]], align 1
325 ; CHECK-NEXT:    [[TMP3:%.*]] = shl <32 x i8> [[WIDE_LOAD]], <i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1>
326 ; CHECK-NEXT:    [[TMP4:%.*]] = getelementptr inbounds i8, ptr [[DST:%.*]], i64 [[TMP0]]
327 ; CHECK-NEXT:    [[TMP5:%.*]] = getelementptr inbounds i8, ptr [[TMP4]], i32 0
328 ; CHECK-NEXT:    [[WIDE_LOAD1:%.*]] = load <32 x i8>, ptr [[TMP5]], align 1
329 ; CHECK-NEXT:    [[TMP6:%.*]] = add <32 x i8> [[TMP3]], [[WIDE_LOAD1]]
330 ; CHECK-NEXT:    store <32 x i8> [[TMP6]], ptr [[TMP5]], align 1
331 ; CHECK-NEXT:    [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 32
332 ; CHECK-NEXT:    br i1 true, label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP10:![0-9]+]]
333 ; CHECK:       middle.block:
334 ; CHECK-NEXT:    br i1 true, label [[FOR_END:%.*]], label [[SCALAR_PH]]
335 ; CHECK:       scalar.ph:
336 ; CHECK-NEXT:    [[BC_RESUME_VAL:%.*]] = phi i64 [ 32, [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY:%.*]] ]
337 ; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
338 ; CHECK:       for.body:
339 ; CHECK-NEXT:    [[I_08:%.*]] = phi i64 [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ], [ [[INC:%.*]], [[FOR_BODY]] ]
340 ; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[SRC]], i64 [[I_08]]
341 ; CHECK-NEXT:    [[TMP7:%.*]] = load i8, ptr [[ARRAYIDX]], align 1
342 ; CHECK-NEXT:    [[MUL:%.*]] = shl i8 [[TMP7]], 1
343 ; CHECK-NEXT:    [[ARRAYIDX1:%.*]] = getelementptr inbounds i8, ptr [[DST]], i64 [[I_08]]
344 ; CHECK-NEXT:    [[TMP8:%.*]] = load i8, ptr [[ARRAYIDX1]], align 1
345 ; CHECK-NEXT:    [[ADD:%.*]] = add i8 [[MUL]], [[TMP8]]
346 ; CHECK-NEXT:    store i8 [[ADD]], ptr [[ARRAYIDX1]], align 1
347 ; CHECK-NEXT:    [[INC]] = add nuw nsw i64 [[I_08]], 1
348 ; CHECK-NEXT:    [[EXITCOND_NOT:%.*]] = icmp eq i64 [[INC]], 32
349 ; CHECK-NEXT:    br i1 [[EXITCOND_NOT]], label [[FOR_END]], label [[FOR_BODY]], !llvm.loop [[LOOP11:![0-9]+]]
350 ; CHECK:       for.end:
351 ; CHECK-NEXT:    ret void
353 entry:
354   br label %for.body
356 for.body:                                         ; preds = %entry, %for.body
357   %i.08 = phi i64 [ 0, %entry ], [ %inc, %for.body ]
358   %arrayidx = getelementptr inbounds i8, ptr %src, i64 %i.08
359   %0 = load i8, ptr %arrayidx, align 1
360   %mul = shl i8 %0, 1
361   %arrayidx1 = getelementptr inbounds i8, ptr %dst, i64 %i.08
362   %1 = load i8, ptr %arrayidx1, align 1
363   %add = add i8 %mul, %1
364   store i8 %add, ptr %arrayidx1, align 1
365   %inc = add nuw nsw i64 %i.08, 1
366   %exitcond.not = icmp eq i64 %inc, 32
367   br i1 %exitcond.not, label %for.end, label %for.body
369 for.end:                                          ; preds = %for.body
370   ret void
373 define void @trip24_i8(ptr noalias nocapture noundef %dst, ptr noalias nocapture noundef readonly %src) #0 {
374 ; CHECK-LABEL: @trip24_i8(
375 ; CHECK-NEXT:  entry:
376 ; CHECK-NEXT:    br i1 false, label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]
377 ; CHECK:       vector.ph:
378 ; CHECK-NEXT:    br label [[VECTOR_BODY:%.*]]
379 ; CHECK:       vector.body:
380 ; CHECK-NEXT:    [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ]
381 ; CHECK-NEXT:    [[TMP0:%.*]] = add i64 [[INDEX]], 0
382 ; CHECK-NEXT:    [[TMP1:%.*]] = getelementptr inbounds i8, ptr [[SRC:%.*]], i64 [[TMP0]]
383 ; CHECK-NEXT:    [[TMP2:%.*]] = getelementptr inbounds i8, ptr [[TMP1]], i32 0
384 ; CHECK-NEXT:    [[WIDE_LOAD:%.*]] = load <8 x i8>, ptr [[TMP2]], align 1
385 ; CHECK-NEXT:    [[TMP3:%.*]] = shl <8 x i8> [[WIDE_LOAD]], <i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1, i8 1>
386 ; CHECK-NEXT:    [[TMP4:%.*]] = getelementptr inbounds i8, ptr [[DST:%.*]], i64 [[TMP0]]
387 ; CHECK-NEXT:    [[TMP5:%.*]] = getelementptr inbounds i8, ptr [[TMP4]], i32 0
388 ; CHECK-NEXT:    [[WIDE_LOAD1:%.*]] = load <8 x i8>, ptr [[TMP5]], align 1
389 ; CHECK-NEXT:    [[TMP6:%.*]] = add <8 x i8> [[TMP3]], [[WIDE_LOAD1]]
390 ; CHECK-NEXT:    store <8 x i8> [[TMP6]], ptr [[TMP5]], align 1
391 ; CHECK-NEXT:    [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 8
392 ; CHECK-NEXT:    [[TMP7:%.*]] = icmp eq i64 [[INDEX_NEXT]], 24
393 ; CHECK-NEXT:    br i1 [[TMP7]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP12:![0-9]+]]
394 ; CHECK:       middle.block:
395 ; CHECK-NEXT:    br i1 true, label [[FOR_END:%.*]], label [[SCALAR_PH]]
396 ; CHECK:       scalar.ph:
397 ; CHECK-NEXT:    [[BC_RESUME_VAL:%.*]] = phi i64 [ 24, [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY:%.*]] ]
398 ; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
399 ; CHECK:       for.body:
400 ; CHECK-NEXT:    [[I_08:%.*]] = phi i64 [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ], [ [[INC:%.*]], [[FOR_BODY]] ]
401 ; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[SRC]], i64 [[I_08]]
402 ; CHECK-NEXT:    [[TMP8:%.*]] = load i8, ptr [[ARRAYIDX]], align 1
403 ; CHECK-NEXT:    [[MUL:%.*]] = shl i8 [[TMP8]], 1
404 ; CHECK-NEXT:    [[ARRAYIDX1:%.*]] = getelementptr inbounds i8, ptr [[DST]], i64 [[I_08]]
405 ; CHECK-NEXT:    [[TMP9:%.*]] = load i8, ptr [[ARRAYIDX1]], align 1
406 ; CHECK-NEXT:    [[ADD:%.*]] = add i8 [[MUL]], [[TMP9]]
407 ; CHECK-NEXT:    store i8 [[ADD]], ptr [[ARRAYIDX1]], align 1
408 ; CHECK-NEXT:    [[INC]] = add nuw nsw i64 [[I_08]], 1
409 ; CHECK-NEXT:    [[EXITCOND_NOT:%.*]] = icmp eq i64 [[INC]], 24
410 ; CHECK-NEXT:    br i1 [[EXITCOND_NOT]], label [[FOR_END]], label [[FOR_BODY]], !llvm.loop [[LOOP13:![0-9]+]]
411 ; CHECK:       for.end:
412 ; CHECK-NEXT:    ret void
414 entry:
415   br label %for.body
417 for.body:                                         ; preds = %entry, %for.body
418   %i.08 = phi i64 [ 0, %entry ], [ %inc, %for.body ]
419   %arrayidx = getelementptr inbounds i8, ptr %src, i64 %i.08
420   %0 = load i8, ptr %arrayidx, align 1
421   %mul = shl i8 %0, 1
422   %arrayidx1 = getelementptr inbounds i8, ptr %dst, i64 %i.08
423   %1 = load i8, ptr %arrayidx1, align 1
424   %add = add i8 %mul, %1
425   store i8 %add, ptr %arrayidx1, align 1
426   %inc = add nuw nsw i64 %i.08, 1
427   %exitcond.not = icmp eq i64 %inc, 24
428   br i1 %exitcond.not, label %for.end, label %for.body
430 for.end:                                          ; preds = %for.body
431   ret void
434 attributes #0 = { "target-features"="+v,+d" vscale_range(2, 1024) }