xref: /llvm-project/llvm/test/Transforms/LoopVectorize/RISCV/divrem.ll (revision f0d5104c944b329c479802788571ed6df41e0e86)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt < %s -passes=loop-vectorize -scalable-vectorization=on -mtriple riscv64-linux-gnu -mattr=+v,+f -S 2>%t | FileCheck %s
3; RUN: opt < %s -passes=loop-vectorize -scalable-vectorization=off -riscv-v-vector-bits-min=-1 -mtriple riscv64-linux-gnu -mattr=+v,+f -S 2>%t | FileCheck --check-prefix=FIXED %s
4
5; Tests specific to div/rem handling - both predicated and not
6
7target datalayout = "e-m:e-p:64:64-i64:64-i128:128-n64-S128"
8target triple = "riscv64"
9
10define void @vector_udiv(ptr noalias nocapture %a, i64 %v, i64 %n) {
11; CHECK-LABEL: @vector_udiv(
12; CHECK-NEXT:  entry:
13; CHECK-NEXT:    [[TMP0:%.*]] = call i64 @llvm.vscale.i64()
14; CHECK-NEXT:    [[TMP1:%.*]] = mul i64 [[TMP0]], 2
15; CHECK-NEXT:    [[MIN_ITERS_CHECK:%.*]] = icmp ult i64 1024, [[TMP1]]
16; CHECK-NEXT:    br i1 [[MIN_ITERS_CHECK]], label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]
17; CHECK:       vector.ph:
18; CHECK-NEXT:    [[TMP2:%.*]] = call i64 @llvm.vscale.i64()
19; CHECK-NEXT:    [[TMP3:%.*]] = mul i64 [[TMP2]], 2
20; CHECK-NEXT:    [[N_MOD_VF:%.*]] = urem i64 1024, [[TMP3]]
21; CHECK-NEXT:    [[N_VEC:%.*]] = sub i64 1024, [[N_MOD_VF]]
22; CHECK-NEXT:    [[TMP4:%.*]] = call i64 @llvm.vscale.i64()
23; CHECK-NEXT:    [[TMP5:%.*]] = mul i64 [[TMP4]], 2
24; CHECK-NEXT:    [[BROADCAST_SPLATINSERT:%.*]] = insertelement <vscale x 2 x i64> poison, i64 [[V:%.*]], i64 0
25; CHECK-NEXT:    [[BROADCAST_SPLAT:%.*]] = shufflevector <vscale x 2 x i64> [[BROADCAST_SPLATINSERT]], <vscale x 2 x i64> poison, <vscale x 2 x i32> zeroinitializer
26; CHECK-NEXT:    br label [[VECTOR_BODY:%.*]]
27; CHECK:       vector.body:
28; CHECK-NEXT:    [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ]
29; CHECK-NEXT:    [[TMP6:%.*]] = add i64 [[INDEX]], 0
30; CHECK-NEXT:    [[TMP7:%.*]] = getelementptr inbounds i64, ptr [[A:%.*]], i64 [[TMP6]]
31; CHECK-NEXT:    [[TMP8:%.*]] = getelementptr inbounds i64, ptr [[TMP7]], i32 0
32; CHECK-NEXT:    [[WIDE_LOAD:%.*]] = load <vscale x 2 x i64>, ptr [[TMP8]], align 8
33; CHECK-NEXT:    [[TMP9:%.*]] = udiv <vscale x 2 x i64> [[WIDE_LOAD]], [[BROADCAST_SPLAT]]
34; CHECK-NEXT:    store <vscale x 2 x i64> [[TMP9]], ptr [[TMP8]], align 8
35; CHECK-NEXT:    [[INDEX_NEXT]] = add nuw i64 [[INDEX]], [[TMP5]]
36; CHECK-NEXT:    [[TMP10:%.*]] = icmp eq i64 [[INDEX_NEXT]], [[N_VEC]]
37; CHECK-NEXT:    br i1 [[TMP10]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP0:![0-9]+]]
38; CHECK:       middle.block:
39; CHECK-NEXT:    [[CMP_N:%.*]] = icmp eq i64 1024, [[N_VEC]]
40; CHECK-NEXT:    br i1 [[CMP_N]], label [[FOR_END:%.*]], label [[SCALAR_PH]]
41; CHECK:       scalar.ph:
42; CHECK-NEXT:    [[BC_RESUME_VAL:%.*]] = phi i64 [ [[N_VEC]], [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY:%.*]] ]
43; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
44; CHECK:       for.body:
45; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ], [ [[IV_NEXT:%.*]], [[FOR_BODY]] ]
46; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i64, ptr [[A]], i64 [[IV]]
47; CHECK-NEXT:    [[ELEM:%.*]] = load i64, ptr [[ARRAYIDX]], align 8
48; CHECK-NEXT:    [[DIVREM:%.*]] = udiv i64 [[ELEM]], [[V]]
49; CHECK-NEXT:    store i64 [[DIVREM]], ptr [[ARRAYIDX]], align 8
50; CHECK-NEXT:    [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
51; CHECK-NEXT:    [[EXITCOND_NOT:%.*]] = icmp eq i64 [[IV_NEXT]], 1024
52; CHECK-NEXT:    br i1 [[EXITCOND_NOT]], label [[FOR_END]], label [[FOR_BODY]], !llvm.loop [[LOOP3:![0-9]+]]
53; CHECK:       for.end:
54; CHECK-NEXT:    ret void
55;
56; FIXED-LABEL: @vector_udiv(
57; FIXED-NEXT:  entry:
58; FIXED-NEXT:    br i1 false, label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]
59; FIXED:       vector.ph:
60; FIXED-NEXT:    [[BROADCAST_SPLATINSERT:%.*]] = insertelement <4 x i64> poison, i64 [[V:%.*]], i64 0
61; FIXED-NEXT:    [[BROADCAST_SPLAT:%.*]] = shufflevector <4 x i64> [[BROADCAST_SPLATINSERT]], <4 x i64> poison, <4 x i32> zeroinitializer
62; FIXED-NEXT:    br label [[VECTOR_BODY:%.*]]
63; FIXED:       vector.body:
64; FIXED-NEXT:    [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ]
65; FIXED-NEXT:    [[TMP0:%.*]] = add i64 [[INDEX]], 0
66; FIXED-NEXT:    [[TMP1:%.*]] = getelementptr inbounds i64, ptr [[A:%.*]], i64 [[TMP0]]
67; FIXED-NEXT:    [[TMP2:%.*]] = getelementptr inbounds i64, ptr [[TMP1]], i32 0
68; FIXED-NEXT:    [[TMP3:%.*]] = getelementptr inbounds i64, ptr [[TMP1]], i32 4
69; FIXED-NEXT:    [[WIDE_LOAD:%.*]] = load <4 x i64>, ptr [[TMP2]], align 8
70; FIXED-NEXT:    [[WIDE_LOAD1:%.*]] = load <4 x i64>, ptr [[TMP3]], align 8
71; FIXED-NEXT:    [[TMP4:%.*]] = udiv <4 x i64> [[WIDE_LOAD]], [[BROADCAST_SPLAT]]
72; FIXED-NEXT:    [[TMP5:%.*]] = udiv <4 x i64> [[WIDE_LOAD1]], [[BROADCAST_SPLAT]]
73; FIXED-NEXT:    store <4 x i64> [[TMP4]], ptr [[TMP2]], align 8
74; FIXED-NEXT:    store <4 x i64> [[TMP5]], ptr [[TMP3]], align 8
75; FIXED-NEXT:    [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 8
76; FIXED-NEXT:    [[TMP6:%.*]] = icmp eq i64 [[INDEX_NEXT]], 1024
77; FIXED-NEXT:    br i1 [[TMP6]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP0:![0-9]+]]
78; FIXED:       middle.block:
79; FIXED-NEXT:    br i1 true, label [[FOR_END:%.*]], label [[SCALAR_PH]]
80; FIXED:       scalar.ph:
81; FIXED-NEXT:    [[BC_RESUME_VAL:%.*]] = phi i64 [ 1024, [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY:%.*]] ]
82; FIXED-NEXT:    br label [[FOR_BODY:%.*]]
83; FIXED:       for.body:
84; FIXED-NEXT:    [[IV:%.*]] = phi i64 [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ], [ [[IV_NEXT:%.*]], [[FOR_BODY]] ]
85; FIXED-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i64, ptr [[A]], i64 [[IV]]
86; FIXED-NEXT:    [[ELEM:%.*]] = load i64, ptr [[ARRAYIDX]], align 8
87; FIXED-NEXT:    [[DIVREM:%.*]] = udiv i64 [[ELEM]], [[V]]
88; FIXED-NEXT:    store i64 [[DIVREM]], ptr [[ARRAYIDX]], align 8
89; FIXED-NEXT:    [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
90; FIXED-NEXT:    [[EXITCOND_NOT:%.*]] = icmp eq i64 [[IV_NEXT]], 1024
91; FIXED-NEXT:    br i1 [[EXITCOND_NOT]], label [[FOR_END]], label [[FOR_BODY]], !llvm.loop [[LOOP3:![0-9]+]]
92; FIXED:       for.end:
93; FIXED-NEXT:    ret void
94;
95entry:
96  br label %for.body
97
98for.body:
99  %iv = phi i64 [ 0, %entry ], [ %iv.next, %for.body ]
100  %arrayidx = getelementptr inbounds i64, ptr %a, i64 %iv
101  %elem = load i64, ptr %arrayidx
102  %divrem = udiv i64 %elem, %v
103  store i64 %divrem, ptr %arrayidx
104  %iv.next = add nuw nsw i64 %iv, 1
105  %exitcond.not = icmp eq i64 %iv.next, 1024
106  br i1 %exitcond.not, label %for.end, label %for.body
107
108for.end:
109  ret void
110}
111
112define void @vector_sdiv(ptr noalias nocapture %a, i64 %v, i64 %n) {
113; CHECK-LABEL: @vector_sdiv(
114; CHECK-NEXT:  entry:
115; CHECK-NEXT:    [[TMP0:%.*]] = call i64 @llvm.vscale.i64()
116; CHECK-NEXT:    [[TMP1:%.*]] = mul i64 [[TMP0]], 2
117; CHECK-NEXT:    [[MIN_ITERS_CHECK:%.*]] = icmp ult i64 1024, [[TMP1]]
118; CHECK-NEXT:    br i1 [[MIN_ITERS_CHECK]], label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]
119; CHECK:       vector.ph:
120; CHECK-NEXT:    [[TMP2:%.*]] = call i64 @llvm.vscale.i64()
121; CHECK-NEXT:    [[TMP3:%.*]] = mul i64 [[TMP2]], 2
122; CHECK-NEXT:    [[N_MOD_VF:%.*]] = urem i64 1024, [[TMP3]]
123; CHECK-NEXT:    [[N_VEC:%.*]] = sub i64 1024, [[N_MOD_VF]]
124; CHECK-NEXT:    [[TMP4:%.*]] = call i64 @llvm.vscale.i64()
125; CHECK-NEXT:    [[TMP5:%.*]] = mul i64 [[TMP4]], 2
126; CHECK-NEXT:    [[BROADCAST_SPLATINSERT:%.*]] = insertelement <vscale x 2 x i64> poison, i64 [[V:%.*]], i64 0
127; CHECK-NEXT:    [[BROADCAST_SPLAT:%.*]] = shufflevector <vscale x 2 x i64> [[BROADCAST_SPLATINSERT]], <vscale x 2 x i64> poison, <vscale x 2 x i32> zeroinitializer
128; CHECK-NEXT:    br label [[VECTOR_BODY:%.*]]
129; CHECK:       vector.body:
130; CHECK-NEXT:    [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ]
131; CHECK-NEXT:    [[TMP6:%.*]] = add i64 [[INDEX]], 0
132; CHECK-NEXT:    [[TMP7:%.*]] = getelementptr inbounds i64, ptr [[A:%.*]], i64 [[TMP6]]
133; CHECK-NEXT:    [[TMP8:%.*]] = getelementptr inbounds i64, ptr [[TMP7]], i32 0
134; CHECK-NEXT:    [[WIDE_LOAD:%.*]] = load <vscale x 2 x i64>, ptr [[TMP8]], align 8
135; CHECK-NEXT:    [[TMP9:%.*]] = sdiv <vscale x 2 x i64> [[WIDE_LOAD]], [[BROADCAST_SPLAT]]
136; CHECK-NEXT:    store <vscale x 2 x i64> [[TMP9]], ptr [[TMP8]], align 8
137; CHECK-NEXT:    [[INDEX_NEXT]] = add nuw i64 [[INDEX]], [[TMP5]]
138; CHECK-NEXT:    [[TMP10:%.*]] = icmp eq i64 [[INDEX_NEXT]], [[N_VEC]]
139; CHECK-NEXT:    br i1 [[TMP10]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP4:![0-9]+]]
140; CHECK:       middle.block:
141; CHECK-NEXT:    [[CMP_N:%.*]] = icmp eq i64 1024, [[N_VEC]]
142; CHECK-NEXT:    br i1 [[CMP_N]], label [[FOR_END:%.*]], label [[SCALAR_PH]]
143; CHECK:       scalar.ph:
144; CHECK-NEXT:    [[BC_RESUME_VAL:%.*]] = phi i64 [ [[N_VEC]], [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY:%.*]] ]
145; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
146; CHECK:       for.body:
147; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ], [ [[IV_NEXT:%.*]], [[FOR_BODY]] ]
148; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i64, ptr [[A]], i64 [[IV]]
149; CHECK-NEXT:    [[ELEM:%.*]] = load i64, ptr [[ARRAYIDX]], align 8
150; CHECK-NEXT:    [[DIVREM:%.*]] = sdiv i64 [[ELEM]], [[V]]
151; CHECK-NEXT:    store i64 [[DIVREM]], ptr [[ARRAYIDX]], align 8
152; CHECK-NEXT:    [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
153; CHECK-NEXT:    [[EXITCOND_NOT:%.*]] = icmp eq i64 [[IV_NEXT]], 1024
154; CHECK-NEXT:    br i1 [[EXITCOND_NOT]], label [[FOR_END]], label [[FOR_BODY]], !llvm.loop [[LOOP5:![0-9]+]]
155; CHECK:       for.end:
156; CHECK-NEXT:    ret void
157;
158; FIXED-LABEL: @vector_sdiv(
159; FIXED-NEXT:  entry:
160; FIXED-NEXT:    br i1 false, label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]
161; FIXED:       vector.ph:
162; FIXED-NEXT:    [[BROADCAST_SPLATINSERT:%.*]] = insertelement <4 x i64> poison, i64 [[V:%.*]], i64 0
163; FIXED-NEXT:    [[BROADCAST_SPLAT:%.*]] = shufflevector <4 x i64> [[BROADCAST_SPLATINSERT]], <4 x i64> poison, <4 x i32> zeroinitializer
164; FIXED-NEXT:    br label [[VECTOR_BODY:%.*]]
165; FIXED:       vector.body:
166; FIXED-NEXT:    [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ]
167; FIXED-NEXT:    [[TMP0:%.*]] = add i64 [[INDEX]], 0
168; FIXED-NEXT:    [[TMP1:%.*]] = getelementptr inbounds i64, ptr [[A:%.*]], i64 [[TMP0]]
169; FIXED-NEXT:    [[TMP2:%.*]] = getelementptr inbounds i64, ptr [[TMP1]], i32 0
170; FIXED-NEXT:    [[TMP3:%.*]] = getelementptr inbounds i64, ptr [[TMP1]], i32 4
171; FIXED-NEXT:    [[WIDE_LOAD:%.*]] = load <4 x i64>, ptr [[TMP2]], align 8
172; FIXED-NEXT:    [[WIDE_LOAD1:%.*]] = load <4 x i64>, ptr [[TMP3]], align 8
173; FIXED-NEXT:    [[TMP4:%.*]] = sdiv <4 x i64> [[WIDE_LOAD]], [[BROADCAST_SPLAT]]
174; FIXED-NEXT:    [[TMP5:%.*]] = sdiv <4 x i64> [[WIDE_LOAD1]], [[BROADCAST_SPLAT]]
175; FIXED-NEXT:    store <4 x i64> [[TMP4]], ptr [[TMP2]], align 8
176; FIXED-NEXT:    store <4 x i64> [[TMP5]], ptr [[TMP3]], align 8
177; FIXED-NEXT:    [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 8
178; FIXED-NEXT:    [[TMP6:%.*]] = icmp eq i64 [[INDEX_NEXT]], 1024
179; FIXED-NEXT:    br i1 [[TMP6]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP4:![0-9]+]]
180; FIXED:       middle.block:
181; FIXED-NEXT:    br i1 true, label [[FOR_END:%.*]], label [[SCALAR_PH]]
182; FIXED:       scalar.ph:
183; FIXED-NEXT:    [[BC_RESUME_VAL:%.*]] = phi i64 [ 1024, [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY:%.*]] ]
184; FIXED-NEXT:    br label [[FOR_BODY:%.*]]
185; FIXED:       for.body:
186; FIXED-NEXT:    [[IV:%.*]] = phi i64 [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ], [ [[IV_NEXT:%.*]], [[FOR_BODY]] ]
187; FIXED-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i64, ptr [[A]], i64 [[IV]]
188; FIXED-NEXT:    [[ELEM:%.*]] = load i64, ptr [[ARRAYIDX]], align 8
189; FIXED-NEXT:    [[DIVREM:%.*]] = sdiv i64 [[ELEM]], [[V]]
190; FIXED-NEXT:    store i64 [[DIVREM]], ptr [[ARRAYIDX]], align 8
191; FIXED-NEXT:    [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
192; FIXED-NEXT:    [[EXITCOND_NOT:%.*]] = icmp eq i64 [[IV_NEXT]], 1024
193; FIXED-NEXT:    br i1 [[EXITCOND_NOT]], label [[FOR_END]], label [[FOR_BODY]], !llvm.loop [[LOOP5:![0-9]+]]
194; FIXED:       for.end:
195; FIXED-NEXT:    ret void
196;
197entry:
198  br label %for.body
199
200for.body:
201  %iv = phi i64 [ 0, %entry ], [ %iv.next, %for.body ]
202  %arrayidx = getelementptr inbounds i64, ptr %a, i64 %iv
203  %elem = load i64, ptr %arrayidx
204  %divrem = sdiv i64 %elem, %v
205  store i64 %divrem, ptr %arrayidx
206  %iv.next = add nuw nsw i64 %iv, 1
207  %exitcond.not = icmp eq i64 %iv.next, 1024
208  br i1 %exitcond.not, label %for.end, label %for.body
209
210for.end:
211  ret void
212}
213
214define void @vector_urem(ptr noalias nocapture %a, i64 %v, i64 %n) {
215; CHECK-LABEL: @vector_urem(
216; CHECK-NEXT:  entry:
217; CHECK-NEXT:    [[TMP0:%.*]] = call i64 @llvm.vscale.i64()
218; CHECK-NEXT:    [[TMP1:%.*]] = mul i64 [[TMP0]], 2
219; CHECK-NEXT:    [[MIN_ITERS_CHECK:%.*]] = icmp ult i64 1024, [[TMP1]]
220; CHECK-NEXT:    br i1 [[MIN_ITERS_CHECK]], label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]
221; CHECK:       vector.ph:
222; CHECK-NEXT:    [[TMP2:%.*]] = call i64 @llvm.vscale.i64()
223; CHECK-NEXT:    [[TMP3:%.*]] = mul i64 [[TMP2]], 2
224; CHECK-NEXT:    [[N_MOD_VF:%.*]] = urem i64 1024, [[TMP3]]
225; CHECK-NEXT:    [[N_VEC:%.*]] = sub i64 1024, [[N_MOD_VF]]
226; CHECK-NEXT:    [[TMP4:%.*]] = call i64 @llvm.vscale.i64()
227; CHECK-NEXT:    [[TMP5:%.*]] = mul i64 [[TMP4]], 2
228; CHECK-NEXT:    [[BROADCAST_SPLATINSERT:%.*]] = insertelement <vscale x 2 x i64> poison, i64 [[V:%.*]], i64 0
229; CHECK-NEXT:    [[BROADCAST_SPLAT:%.*]] = shufflevector <vscale x 2 x i64> [[BROADCAST_SPLATINSERT]], <vscale x 2 x i64> poison, <vscale x 2 x i32> zeroinitializer
230; CHECK-NEXT:    br label [[VECTOR_BODY:%.*]]
231; CHECK:       vector.body:
232; CHECK-NEXT:    [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ]
233; CHECK-NEXT:    [[TMP6:%.*]] = add i64 [[INDEX]], 0
234; CHECK-NEXT:    [[TMP7:%.*]] = getelementptr inbounds i64, ptr [[A:%.*]], i64 [[TMP6]]
235; CHECK-NEXT:    [[TMP8:%.*]] = getelementptr inbounds i64, ptr [[TMP7]], i32 0
236; CHECK-NEXT:    [[WIDE_LOAD:%.*]] = load <vscale x 2 x i64>, ptr [[TMP8]], align 8
237; CHECK-NEXT:    [[TMP9:%.*]] = urem <vscale x 2 x i64> [[WIDE_LOAD]], [[BROADCAST_SPLAT]]
238; CHECK-NEXT:    store <vscale x 2 x i64> [[TMP9]], ptr [[TMP8]], align 8
239; CHECK-NEXT:    [[INDEX_NEXT]] = add nuw i64 [[INDEX]], [[TMP5]]
240; CHECK-NEXT:    [[TMP10:%.*]] = icmp eq i64 [[INDEX_NEXT]], [[N_VEC]]
241; CHECK-NEXT:    br i1 [[TMP10]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP6:![0-9]+]]
242; CHECK:       middle.block:
243; CHECK-NEXT:    [[CMP_N:%.*]] = icmp eq i64 1024, [[N_VEC]]
244; CHECK-NEXT:    br i1 [[CMP_N]], label [[FOR_END:%.*]], label [[SCALAR_PH]]
245; CHECK:       scalar.ph:
246; CHECK-NEXT:    [[BC_RESUME_VAL:%.*]] = phi i64 [ [[N_VEC]], [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY:%.*]] ]
247; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
248; CHECK:       for.body:
249; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ], [ [[IV_NEXT:%.*]], [[FOR_BODY]] ]
250; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i64, ptr [[A]], i64 [[IV]]
251; CHECK-NEXT:    [[ELEM:%.*]] = load i64, ptr [[ARRAYIDX]], align 8
252; CHECK-NEXT:    [[DIVREM:%.*]] = urem i64 [[ELEM]], [[V]]
253; CHECK-NEXT:    store i64 [[DIVREM]], ptr [[ARRAYIDX]], align 8
254; CHECK-NEXT:    [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
255; CHECK-NEXT:    [[EXITCOND_NOT:%.*]] = icmp eq i64 [[IV_NEXT]], 1024
256; CHECK-NEXT:    br i1 [[EXITCOND_NOT]], label [[FOR_END]], label [[FOR_BODY]], !llvm.loop [[LOOP7:![0-9]+]]
257; CHECK:       for.end:
258; CHECK-NEXT:    ret void
259;
260; FIXED-LABEL: @vector_urem(
261; FIXED-NEXT:  entry:
262; FIXED-NEXT:    br i1 false, label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]
263; FIXED:       vector.ph:
264; FIXED-NEXT:    [[BROADCAST_SPLATINSERT:%.*]] = insertelement <4 x i64> poison, i64 [[V:%.*]], i64 0
265; FIXED-NEXT:    [[BROADCAST_SPLAT:%.*]] = shufflevector <4 x i64> [[BROADCAST_SPLATINSERT]], <4 x i64> poison, <4 x i32> zeroinitializer
266; FIXED-NEXT:    br label [[VECTOR_BODY:%.*]]
267; FIXED:       vector.body:
268; FIXED-NEXT:    [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ]
269; FIXED-NEXT:    [[TMP0:%.*]] = add i64 [[INDEX]], 0
270; FIXED-NEXT:    [[TMP1:%.*]] = getelementptr inbounds i64, ptr [[A:%.*]], i64 [[TMP0]]
271; FIXED-NEXT:    [[TMP2:%.*]] = getelementptr inbounds i64, ptr [[TMP1]], i32 0
272; FIXED-NEXT:    [[TMP3:%.*]] = getelementptr inbounds i64, ptr [[TMP1]], i32 4
273; FIXED-NEXT:    [[WIDE_LOAD:%.*]] = load <4 x i64>, ptr [[TMP2]], align 8
274; FIXED-NEXT:    [[WIDE_LOAD1:%.*]] = load <4 x i64>, ptr [[TMP3]], align 8
275; FIXED-NEXT:    [[TMP4:%.*]] = urem <4 x i64> [[WIDE_LOAD]], [[BROADCAST_SPLAT]]
276; FIXED-NEXT:    [[TMP5:%.*]] = urem <4 x i64> [[WIDE_LOAD1]], [[BROADCAST_SPLAT]]
277; FIXED-NEXT:    store <4 x i64> [[TMP4]], ptr [[TMP2]], align 8
278; FIXED-NEXT:    store <4 x i64> [[TMP5]], ptr [[TMP3]], align 8
279; FIXED-NEXT:    [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 8
280; FIXED-NEXT:    [[TMP6:%.*]] = icmp eq i64 [[INDEX_NEXT]], 1024
281; FIXED-NEXT:    br i1 [[TMP6]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP6:![0-9]+]]
282; FIXED:       middle.block:
283; FIXED-NEXT:    br i1 true, label [[FOR_END:%.*]], label [[SCALAR_PH]]
284; FIXED:       scalar.ph:
285; FIXED-NEXT:    [[BC_RESUME_VAL:%.*]] = phi i64 [ 1024, [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY:%.*]] ]
286; FIXED-NEXT:    br label [[FOR_BODY:%.*]]
287; FIXED:       for.body:
288; FIXED-NEXT:    [[IV:%.*]] = phi i64 [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ], [ [[IV_NEXT:%.*]], [[FOR_BODY]] ]
289; FIXED-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i64, ptr [[A]], i64 [[IV]]
290; FIXED-NEXT:    [[ELEM:%.*]] = load i64, ptr [[ARRAYIDX]], align 8
291; FIXED-NEXT:    [[DIVREM:%.*]] = urem i64 [[ELEM]], [[V]]
292; FIXED-NEXT:    store i64 [[DIVREM]], ptr [[ARRAYIDX]], align 8
293; FIXED-NEXT:    [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
294; FIXED-NEXT:    [[EXITCOND_NOT:%.*]] = icmp eq i64 [[IV_NEXT]], 1024
295; FIXED-NEXT:    br i1 [[EXITCOND_NOT]], label [[FOR_END]], label [[FOR_BODY]], !llvm.loop [[LOOP7:![0-9]+]]
296; FIXED:       for.end:
297; FIXED-NEXT:    ret void
298;
299entry:
300  br label %for.body
301
302for.body:
303  %iv = phi i64 [ 0, %entry ], [ %iv.next, %for.body ]
304  %arrayidx = getelementptr inbounds i64, ptr %a, i64 %iv
305  %elem = load i64, ptr %arrayidx
306  %divrem = urem i64 %elem, %v
307  store i64 %divrem, ptr %arrayidx
308  %iv.next = add nuw nsw i64 %iv, 1
309  %exitcond.not = icmp eq i64 %iv.next, 1024
310  br i1 %exitcond.not, label %for.end, label %for.body
311
312for.end:
313  ret void
314}
315
316define void @vector_srem(ptr noalias nocapture %a, i64 %v, i64 %n) {
317; CHECK-LABEL: @vector_srem(
318; CHECK-NEXT:  entry:
319; CHECK-NEXT:    [[TMP0:%.*]] = call i64 @llvm.vscale.i64()
320; CHECK-NEXT:    [[TMP1:%.*]] = mul i64 [[TMP0]], 2
321; CHECK-NEXT:    [[MIN_ITERS_CHECK:%.*]] = icmp ult i64 1024, [[TMP1]]
322; CHECK-NEXT:    br i1 [[MIN_ITERS_CHECK]], label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]
323; CHECK:       vector.ph:
324; CHECK-NEXT:    [[TMP2:%.*]] = call i64 @llvm.vscale.i64()
325; CHECK-NEXT:    [[TMP3:%.*]] = mul i64 [[TMP2]], 2
326; CHECK-NEXT:    [[N_MOD_VF:%.*]] = urem i64 1024, [[TMP3]]
327; CHECK-NEXT:    [[N_VEC:%.*]] = sub i64 1024, [[N_MOD_VF]]
328; CHECK-NEXT:    [[TMP4:%.*]] = call i64 @llvm.vscale.i64()
329; CHECK-NEXT:    [[TMP5:%.*]] = mul i64 [[TMP4]], 2
330; CHECK-NEXT:    [[BROADCAST_SPLATINSERT:%.*]] = insertelement <vscale x 2 x i64> poison, i64 [[V:%.*]], i64 0
331; CHECK-NEXT:    [[BROADCAST_SPLAT:%.*]] = shufflevector <vscale x 2 x i64> [[BROADCAST_SPLATINSERT]], <vscale x 2 x i64> poison, <vscale x 2 x i32> zeroinitializer
332; CHECK-NEXT:    br label [[VECTOR_BODY:%.*]]
333; CHECK:       vector.body:
334; CHECK-NEXT:    [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ]
335; CHECK-NEXT:    [[TMP6:%.*]] = add i64 [[INDEX]], 0
336; CHECK-NEXT:    [[TMP7:%.*]] = getelementptr inbounds i64, ptr [[A:%.*]], i64 [[TMP6]]
337; CHECK-NEXT:    [[TMP8:%.*]] = getelementptr inbounds i64, ptr [[TMP7]], i32 0
338; CHECK-NEXT:    [[WIDE_LOAD:%.*]] = load <vscale x 2 x i64>, ptr [[TMP8]], align 8
339; CHECK-NEXT:    [[TMP9:%.*]] = srem <vscale x 2 x i64> [[WIDE_LOAD]], [[BROADCAST_SPLAT]]
340; CHECK-NEXT:    store <vscale x 2 x i64> [[TMP9]], ptr [[TMP8]], align 8
341; CHECK-NEXT:    [[INDEX_NEXT]] = add nuw i64 [[INDEX]], [[TMP5]]
342; CHECK-NEXT:    [[TMP10:%.*]] = icmp eq i64 [[INDEX_NEXT]], [[N_VEC]]
343; CHECK-NEXT:    br i1 [[TMP10]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP8:![0-9]+]]
344; CHECK:       middle.block:
345; CHECK-NEXT:    [[CMP_N:%.*]] = icmp eq i64 1024, [[N_VEC]]
346; CHECK-NEXT:    br i1 [[CMP_N]], label [[FOR_END:%.*]], label [[SCALAR_PH]]
347; CHECK:       scalar.ph:
348; CHECK-NEXT:    [[BC_RESUME_VAL:%.*]] = phi i64 [ [[N_VEC]], [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY:%.*]] ]
349; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
350; CHECK:       for.body:
351; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ], [ [[IV_NEXT:%.*]], [[FOR_BODY]] ]
352; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i64, ptr [[A]], i64 [[IV]]
353; CHECK-NEXT:    [[ELEM:%.*]] = load i64, ptr [[ARRAYIDX]], align 8
354; CHECK-NEXT:    [[DIVREM:%.*]] = srem i64 [[ELEM]], [[V]]
355; CHECK-NEXT:    store i64 [[DIVREM]], ptr [[ARRAYIDX]], align 8
356; CHECK-NEXT:    [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
357; CHECK-NEXT:    [[EXITCOND_NOT:%.*]] = icmp eq i64 [[IV_NEXT]], 1024
358; CHECK-NEXT:    br i1 [[EXITCOND_NOT]], label [[FOR_END]], label [[FOR_BODY]], !llvm.loop [[LOOP9:![0-9]+]]
359; CHECK:       for.end:
360; CHECK-NEXT:    ret void
361;
362; FIXED-LABEL: @vector_srem(
363; FIXED-NEXT:  entry:
364; FIXED-NEXT:    br i1 false, label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]
365; FIXED:       vector.ph:
366; FIXED-NEXT:    [[BROADCAST_SPLATINSERT:%.*]] = insertelement <4 x i64> poison, i64 [[V:%.*]], i64 0
367; FIXED-NEXT:    [[BROADCAST_SPLAT:%.*]] = shufflevector <4 x i64> [[BROADCAST_SPLATINSERT]], <4 x i64> poison, <4 x i32> zeroinitializer
368; FIXED-NEXT:    br label [[VECTOR_BODY:%.*]]
369; FIXED:       vector.body:
370; FIXED-NEXT:    [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ]
371; FIXED-NEXT:    [[TMP0:%.*]] = add i64 [[INDEX]], 0
372; FIXED-NEXT:    [[TMP1:%.*]] = getelementptr inbounds i64, ptr [[A:%.*]], i64 [[TMP0]]
373; FIXED-NEXT:    [[TMP2:%.*]] = getelementptr inbounds i64, ptr [[TMP1]], i32 0
374; FIXED-NEXT:    [[TMP3:%.*]] = getelementptr inbounds i64, ptr [[TMP1]], i32 4
375; FIXED-NEXT:    [[WIDE_LOAD:%.*]] = load <4 x i64>, ptr [[TMP2]], align 8
376; FIXED-NEXT:    [[WIDE_LOAD1:%.*]] = load <4 x i64>, ptr [[TMP3]], align 8
377; FIXED-NEXT:    [[TMP4:%.*]] = srem <4 x i64> [[WIDE_LOAD]], [[BROADCAST_SPLAT]]
378; FIXED-NEXT:    [[TMP5:%.*]] = srem <4 x i64> [[WIDE_LOAD1]], [[BROADCAST_SPLAT]]
379; FIXED-NEXT:    store <4 x i64> [[TMP4]], ptr [[TMP2]], align 8
380; FIXED-NEXT:    store <4 x i64> [[TMP5]], ptr [[TMP3]], align 8
381; FIXED-NEXT:    [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 8
382; FIXED-NEXT:    [[TMP6:%.*]] = icmp eq i64 [[INDEX_NEXT]], 1024
383; FIXED-NEXT:    br i1 [[TMP6]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP8:![0-9]+]]
384; FIXED:       middle.block:
385; FIXED-NEXT:    br i1 true, label [[FOR_END:%.*]], label [[SCALAR_PH]]
386; FIXED:       scalar.ph:
387; FIXED-NEXT:    [[BC_RESUME_VAL:%.*]] = phi i64 [ 1024, [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY:%.*]] ]
388; FIXED-NEXT:    br label [[FOR_BODY:%.*]]
389; FIXED:       for.body:
390; FIXED-NEXT:    [[IV:%.*]] = phi i64 [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ], [ [[IV_NEXT:%.*]], [[FOR_BODY]] ]
391; FIXED-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i64, ptr [[A]], i64 [[IV]]
392; FIXED-NEXT:    [[ELEM:%.*]] = load i64, ptr [[ARRAYIDX]], align 8
393; FIXED-NEXT:    [[DIVREM:%.*]] = srem i64 [[ELEM]], [[V]]
394; FIXED-NEXT:    store i64 [[DIVREM]], ptr [[ARRAYIDX]], align 8
395; FIXED-NEXT:    [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
396; FIXED-NEXT:    [[EXITCOND_NOT:%.*]] = icmp eq i64 [[IV_NEXT]], 1024
397; FIXED-NEXT:    br i1 [[EXITCOND_NOT]], label [[FOR_END]], label [[FOR_BODY]], !llvm.loop [[LOOP9:![0-9]+]]
398; FIXED:       for.end:
399; FIXED-NEXT:    ret void
400;
401entry:
402  br label %for.body
403
404for.body:
405  %iv = phi i64 [ 0, %entry ], [ %iv.next, %for.body ]
406  %arrayidx = getelementptr inbounds i64, ptr %a, i64 %iv
407  %elem = load i64, ptr %arrayidx
408  %divrem = srem i64 %elem, %v
409  store i64 %divrem, ptr %arrayidx
410  %iv.next = add nuw nsw i64 %iv, 1
411  %exitcond.not = icmp eq i64 %iv.next, 1024
412  br i1 %exitcond.not, label %for.end, label %for.body
413
414for.end:
415  ret void
416}
417
418define void @predicated_udiv(ptr noalias nocapture %a, i64 %v, i64 %n) {
419; CHECK-LABEL: @predicated_udiv(
420; CHECK-NEXT:  entry:
421; CHECK-NEXT:    [[TMP0:%.*]] = call i64 @llvm.vscale.i64()
422; CHECK-NEXT:    [[TMP1:%.*]] = mul i64 [[TMP0]], 2
423; CHECK-NEXT:    [[MIN_ITERS_CHECK:%.*]] = icmp ult i64 1024, [[TMP1]]
424; CHECK-NEXT:    br i1 [[MIN_ITERS_CHECK]], label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]
425; CHECK:       vector.ph:
426; CHECK-NEXT:    [[TMP2:%.*]] = call i64 @llvm.vscale.i64()
427; CHECK-NEXT:    [[TMP3:%.*]] = mul i64 [[TMP2]], 2
428; CHECK-NEXT:    [[N_MOD_VF:%.*]] = urem i64 1024, [[TMP3]]
429; CHECK-NEXT:    [[N_VEC:%.*]] = sub i64 1024, [[N_MOD_VF]]
430; CHECK-NEXT:    [[TMP4:%.*]] = call i64 @llvm.vscale.i64()
431; CHECK-NEXT:    [[TMP5:%.*]] = mul i64 [[TMP4]], 2
432; CHECK-NEXT:    [[BROADCAST_SPLATINSERT:%.*]] = insertelement <vscale x 2 x i64> poison, i64 [[V:%.*]], i64 0
433; CHECK-NEXT:    [[BROADCAST_SPLAT:%.*]] = shufflevector <vscale x 2 x i64> [[BROADCAST_SPLATINSERT]], <vscale x 2 x i64> poison, <vscale x 2 x i32> zeroinitializer
434; CHECK-NEXT:    [[TMP6:%.*]] = icmp ne <vscale x 2 x i64> [[BROADCAST_SPLAT]], zeroinitializer
435; CHECK-NEXT:    [[TMP10:%.*]] = select <vscale x 2 x i1> [[TMP6]], <vscale x 2 x i64> [[BROADCAST_SPLAT]], <vscale x 2 x i64> splat (i64 1)
436; CHECK-NEXT:    br label [[VECTOR_BODY:%.*]]
437; CHECK:       vector.body:
438; CHECK-NEXT:    [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ]
439; CHECK-NEXT:    [[TMP7:%.*]] = add i64 [[INDEX]], 0
440; CHECK-NEXT:    [[TMP8:%.*]] = getelementptr inbounds i64, ptr [[A:%.*]], i64 [[TMP7]]
441; CHECK-NEXT:    [[TMP9:%.*]] = getelementptr inbounds i64, ptr [[TMP8]], i32 0
442; CHECK-NEXT:    [[WIDE_LOAD:%.*]] = load <vscale x 2 x i64>, ptr [[TMP9]], align 8
443; CHECK-NEXT:    [[TMP11:%.*]] = udiv <vscale x 2 x i64> [[WIDE_LOAD]], [[TMP10]]
444; CHECK-NEXT:    [[PREDPHI:%.*]] = select <vscale x 2 x i1> [[TMP6]], <vscale x 2 x i64> [[TMP11]], <vscale x 2 x i64> [[WIDE_LOAD]]
445; CHECK-NEXT:    store <vscale x 2 x i64> [[PREDPHI]], ptr [[TMP9]], align 8
446; CHECK-NEXT:    [[INDEX_NEXT]] = add nuw i64 [[INDEX]], [[TMP5]]
447; CHECK-NEXT:    [[TMP12:%.*]] = icmp eq i64 [[INDEX_NEXT]], [[N_VEC]]
448; CHECK-NEXT:    br i1 [[TMP12]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP10:![0-9]+]]
449; CHECK:       middle.block:
450; CHECK-NEXT:    [[CMP_N:%.*]] = icmp eq i64 1024, [[N_VEC]]
451; CHECK-NEXT:    br i1 [[CMP_N]], label [[FOR_END:%.*]], label [[SCALAR_PH]]
452; CHECK:       scalar.ph:
453; CHECK-NEXT:    [[BC_RESUME_VAL:%.*]] = phi i64 [ [[N_VEC]], [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY:%.*]] ]
454; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
455; CHECK:       for.body:
456; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ], [ [[IV_NEXT:%.*]], [[LATCH:%.*]] ]
457; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i64, ptr [[A]], i64 [[IV]]
458; CHECK-NEXT:    [[ELEM:%.*]] = load i64, ptr [[ARRAYIDX]], align 8
459; CHECK-NEXT:    [[C:%.*]] = icmp ne i64 [[V]], 0
460; CHECK-NEXT:    br i1 [[C]], label [[DO_OP:%.*]], label [[LATCH]]
461; CHECK:       do_op:
462; CHECK-NEXT:    [[DIVREM:%.*]] = udiv i64 [[ELEM]], [[V]]
463; CHECK-NEXT:    br label [[LATCH]]
464; CHECK:       latch:
465; CHECK-NEXT:    [[PHI:%.*]] = phi i64 [ [[ELEM]], [[FOR_BODY]] ], [ [[DIVREM]], [[DO_OP]] ]
466; CHECK-NEXT:    store i64 [[PHI]], ptr [[ARRAYIDX]], align 8
467; CHECK-NEXT:    [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
468; CHECK-NEXT:    [[EXITCOND_NOT:%.*]] = icmp eq i64 [[IV_NEXT]], 1024
469; CHECK-NEXT:    br i1 [[EXITCOND_NOT]], label [[FOR_END]], label [[FOR_BODY]], !llvm.loop [[LOOP11:![0-9]+]]
470; CHECK:       for.end:
471; CHECK-NEXT:    ret void
472;
473; FIXED-LABEL: @predicated_udiv(
474; FIXED-NEXT:  entry:
475; FIXED-NEXT:    br i1 false, label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]
476; FIXED:       vector.ph:
477; FIXED-NEXT:    [[BROADCAST_SPLATINSERT:%.*]] = insertelement <4 x i64> poison, i64 [[V:%.*]], i64 0
478; FIXED-NEXT:    [[BROADCAST_SPLAT:%.*]] = shufflevector <4 x i64> [[BROADCAST_SPLATINSERT]], <4 x i64> poison, <4 x i32> zeroinitializer
479; FIXED-NEXT:    [[TMP0:%.*]] = icmp ne <4 x i64> [[BROADCAST_SPLAT]], zeroinitializer
480; FIXED-NEXT:    [[TMP5:%.*]] = select <4 x i1> [[TMP0]], <4 x i64> [[BROADCAST_SPLAT]], <4 x i64> splat (i64 1)
481; FIXED-NEXT:    br label [[VECTOR_BODY:%.*]]
482; FIXED:       vector.body:
483; FIXED-NEXT:    [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ]
484; FIXED-NEXT:    [[TMP1:%.*]] = add i64 [[INDEX]], 0
485; FIXED-NEXT:    [[TMP2:%.*]] = getelementptr inbounds i64, ptr [[A:%.*]], i64 [[TMP1]]
486; FIXED-NEXT:    [[TMP3:%.*]] = getelementptr inbounds i64, ptr [[TMP2]], i32 0
487; FIXED-NEXT:    [[TMP4:%.*]] = getelementptr inbounds i64, ptr [[TMP2]], i32 4
488; FIXED-NEXT:    [[WIDE_LOAD:%.*]] = load <4 x i64>, ptr [[TMP3]], align 8
489; FIXED-NEXT:    [[WIDE_LOAD1:%.*]] = load <4 x i64>, ptr [[TMP4]], align 8
490; FIXED-NEXT:    [[TMP7:%.*]] = udiv <4 x i64> [[WIDE_LOAD]], [[TMP5]]
491; FIXED-NEXT:    [[TMP8:%.*]] = udiv <4 x i64> [[WIDE_LOAD1]], [[TMP5]]
492; FIXED-NEXT:    [[PREDPHI:%.*]] = select <4 x i1> [[TMP0]], <4 x i64> [[TMP7]], <4 x i64> [[WIDE_LOAD]]
493; FIXED-NEXT:    [[PREDPHI2:%.*]] = select <4 x i1> [[TMP0]], <4 x i64> [[TMP8]], <4 x i64> [[WIDE_LOAD1]]
494; FIXED-NEXT:    store <4 x i64> [[PREDPHI]], ptr [[TMP3]], align 8
495; FIXED-NEXT:    store <4 x i64> [[PREDPHI2]], ptr [[TMP4]], align 8
496; FIXED-NEXT:    [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 8
497; FIXED-NEXT:    [[TMP9:%.*]] = icmp eq i64 [[INDEX_NEXT]], 1024
498; FIXED-NEXT:    br i1 [[TMP9]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP10:![0-9]+]]
499; FIXED:       middle.block:
500; FIXED-NEXT:    br i1 true, label [[FOR_END:%.*]], label [[SCALAR_PH]]
501; FIXED:       scalar.ph:
502; FIXED-NEXT:    [[BC_RESUME_VAL:%.*]] = phi i64 [ 1024, [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY:%.*]] ]
503; FIXED-NEXT:    br label [[FOR_BODY:%.*]]
504; FIXED:       for.body:
505; FIXED-NEXT:    [[IV:%.*]] = phi i64 [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ], [ [[IV_NEXT:%.*]], [[LATCH:%.*]] ]
506; FIXED-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i64, ptr [[A]], i64 [[IV]]
507; FIXED-NEXT:    [[ELEM:%.*]] = load i64, ptr [[ARRAYIDX]], align 8
508; FIXED-NEXT:    [[C:%.*]] = icmp ne i64 [[V]], 0
509; FIXED-NEXT:    br i1 [[C]], label [[DO_OP:%.*]], label [[LATCH]]
510; FIXED:       do_op:
511; FIXED-NEXT:    [[DIVREM:%.*]] = udiv i64 [[ELEM]], [[V]]
512; FIXED-NEXT:    br label [[LATCH]]
513; FIXED:       latch:
514; FIXED-NEXT:    [[PHI:%.*]] = phi i64 [ [[ELEM]], [[FOR_BODY]] ], [ [[DIVREM]], [[DO_OP]] ]
515; FIXED-NEXT:    store i64 [[PHI]], ptr [[ARRAYIDX]], align 8
516; FIXED-NEXT:    [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
517; FIXED-NEXT:    [[EXITCOND_NOT:%.*]] = icmp eq i64 [[IV_NEXT]], 1024
518; FIXED-NEXT:    br i1 [[EXITCOND_NOT]], label [[FOR_END]], label [[FOR_BODY]], !llvm.loop [[LOOP11:![0-9]+]]
519; FIXED:       for.end:
520; FIXED-NEXT:    ret void
521;
522entry:
523  br label %for.body
524
525for.body:
526  %iv = phi i64 [ 0, %entry ], [ %iv.next, %latch ]
527  %arrayidx = getelementptr inbounds i64, ptr %a, i64 %iv
528  %elem = load i64, ptr %arrayidx
529  %c = icmp ne i64 %v, 0
530  br i1 %c, label %do_op, label %latch
531do_op:
532  %divrem = udiv i64 %elem, %v
533  br label %latch
534latch:
535  %phi = phi i64 [%elem, %for.body], [%divrem, %do_op]
536  store i64 %phi, ptr %arrayidx
537  %iv.next = add nuw nsw i64 %iv, 1
538  %exitcond.not = icmp eq i64 %iv.next, 1024
539  br i1 %exitcond.not, label %for.end, label %for.body
540
541for.end:
542  ret void
543}
544
545define void @predicated_sdiv(ptr noalias nocapture %a, i64 %v, i64 %n) {
546; CHECK-LABEL: @predicated_sdiv(
547; CHECK-NEXT:  entry:
548; CHECK-NEXT:    [[TMP0:%.*]] = call i64 @llvm.vscale.i64()
549; CHECK-NEXT:    [[TMP1:%.*]] = mul i64 [[TMP0]], 2
550; CHECK-NEXT:    [[MIN_ITERS_CHECK:%.*]] = icmp ult i64 1024, [[TMP1]]
551; CHECK-NEXT:    br i1 [[MIN_ITERS_CHECK]], label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]
552; CHECK:       vector.ph:
553; CHECK-NEXT:    [[TMP2:%.*]] = call i64 @llvm.vscale.i64()
554; CHECK-NEXT:    [[TMP3:%.*]] = mul i64 [[TMP2]], 2
555; CHECK-NEXT:    [[N_MOD_VF:%.*]] = urem i64 1024, [[TMP3]]
556; CHECK-NEXT:    [[N_VEC:%.*]] = sub i64 1024, [[N_MOD_VF]]
557; CHECK-NEXT:    [[TMP4:%.*]] = call i64 @llvm.vscale.i64()
558; CHECK-NEXT:    [[TMP5:%.*]] = mul i64 [[TMP4]], 2
559; CHECK-NEXT:    [[BROADCAST_SPLATINSERT:%.*]] = insertelement <vscale x 2 x i64> poison, i64 [[V:%.*]], i64 0
560; CHECK-NEXT:    [[BROADCAST_SPLAT:%.*]] = shufflevector <vscale x 2 x i64> [[BROADCAST_SPLATINSERT]], <vscale x 2 x i64> poison, <vscale x 2 x i32> zeroinitializer
561; CHECK-NEXT:    [[TMP6:%.*]] = icmp ne <vscale x 2 x i64> [[BROADCAST_SPLAT]], zeroinitializer
562; CHECK-NEXT:    [[TMP10:%.*]] = select <vscale x 2 x i1> [[TMP6]], <vscale x 2 x i64> [[BROADCAST_SPLAT]], <vscale x 2 x i64> splat (i64 1)
563; CHECK-NEXT:    br label [[VECTOR_BODY:%.*]]
564; CHECK:       vector.body:
565; CHECK-NEXT:    [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ]
566; CHECK-NEXT:    [[TMP7:%.*]] = add i64 [[INDEX]], 0
567; CHECK-NEXT:    [[TMP8:%.*]] = getelementptr inbounds i64, ptr [[A:%.*]], i64 [[TMP7]]
568; CHECK-NEXT:    [[TMP9:%.*]] = getelementptr inbounds i64, ptr [[TMP8]], i32 0
569; CHECK-NEXT:    [[WIDE_LOAD:%.*]] = load <vscale x 2 x i64>, ptr [[TMP9]], align 8
570; CHECK-NEXT:    [[TMP11:%.*]] = sdiv <vscale x 2 x i64> [[WIDE_LOAD]], [[TMP10]]
571; CHECK-NEXT:    [[PREDPHI:%.*]] = select <vscale x 2 x i1> [[TMP6]], <vscale x 2 x i64> [[TMP11]], <vscale x 2 x i64> [[WIDE_LOAD]]
572; CHECK-NEXT:    store <vscale x 2 x i64> [[PREDPHI]], ptr [[TMP9]], align 8
573; CHECK-NEXT:    [[INDEX_NEXT]] = add nuw i64 [[INDEX]], [[TMP5]]
574; CHECK-NEXT:    [[TMP12:%.*]] = icmp eq i64 [[INDEX_NEXT]], [[N_VEC]]
575; CHECK-NEXT:    br i1 [[TMP12]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP12:![0-9]+]]
576; CHECK:       middle.block:
577; CHECK-NEXT:    [[CMP_N:%.*]] = icmp eq i64 1024, [[N_VEC]]
578; CHECK-NEXT:    br i1 [[CMP_N]], label [[FOR_END:%.*]], label [[SCALAR_PH]]
579; CHECK:       scalar.ph:
580; CHECK-NEXT:    [[BC_RESUME_VAL:%.*]] = phi i64 [ [[N_VEC]], [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY:%.*]] ]
581; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
582; CHECK:       for.body:
583; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ], [ [[IV_NEXT:%.*]], [[LATCH:%.*]] ]
584; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i64, ptr [[A]], i64 [[IV]]
585; CHECK-NEXT:    [[ELEM:%.*]] = load i64, ptr [[ARRAYIDX]], align 8
586; CHECK-NEXT:    [[C:%.*]] = icmp ne i64 [[V]], 0
587; CHECK-NEXT:    br i1 [[C]], label [[DO_OP:%.*]], label [[LATCH]]
588; CHECK:       do_op:
589; CHECK-NEXT:    [[DIVREM:%.*]] = sdiv i64 [[ELEM]], [[V]]
590; CHECK-NEXT:    br label [[LATCH]]
591; CHECK:       latch:
592; CHECK-NEXT:    [[PHI:%.*]] = phi i64 [ [[ELEM]], [[FOR_BODY]] ], [ [[DIVREM]], [[DO_OP]] ]
593; CHECK-NEXT:    store i64 [[PHI]], ptr [[ARRAYIDX]], align 8
594; CHECK-NEXT:    [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
595; CHECK-NEXT:    [[EXITCOND_NOT:%.*]] = icmp eq i64 [[IV_NEXT]], 1024
596; CHECK-NEXT:    br i1 [[EXITCOND_NOT]], label [[FOR_END]], label [[FOR_BODY]], !llvm.loop [[LOOP13:![0-9]+]]
597; CHECK:       for.end:
598; CHECK-NEXT:    ret void
599;
600; FIXED-LABEL: @predicated_sdiv(
601; FIXED-NEXT:  entry:
602; FIXED-NEXT:    br i1 false, label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]
603; FIXED:       vector.ph:
604; FIXED-NEXT:    [[BROADCAST_SPLATINSERT:%.*]] = insertelement <4 x i64> poison, i64 [[V:%.*]], i64 0
605; FIXED-NEXT:    [[BROADCAST_SPLAT:%.*]] = shufflevector <4 x i64> [[BROADCAST_SPLATINSERT]], <4 x i64> poison, <4 x i32> zeroinitializer
606; FIXED-NEXT:    [[TMP0:%.*]] = icmp ne <4 x i64> [[BROADCAST_SPLAT]], zeroinitializer
607; FIXED-NEXT:    [[TMP5:%.*]] = select <4 x i1> [[TMP0]], <4 x i64> [[BROADCAST_SPLAT]], <4 x i64> splat (i64 1)
608; FIXED-NEXT:    br label [[VECTOR_BODY:%.*]]
609; FIXED:       vector.body:
610; FIXED-NEXT:    [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ]
611; FIXED-NEXT:    [[TMP1:%.*]] = add i64 [[INDEX]], 0
612; FIXED-NEXT:    [[TMP2:%.*]] = getelementptr inbounds i64, ptr [[A:%.*]], i64 [[TMP1]]
613; FIXED-NEXT:    [[TMP3:%.*]] = getelementptr inbounds i64, ptr [[TMP2]], i32 0
614; FIXED-NEXT:    [[TMP4:%.*]] = getelementptr inbounds i64, ptr [[TMP2]], i32 4
615; FIXED-NEXT:    [[WIDE_LOAD:%.*]] = load <4 x i64>, ptr [[TMP3]], align 8
616; FIXED-NEXT:    [[WIDE_LOAD1:%.*]] = load <4 x i64>, ptr [[TMP4]], align 8
617; FIXED-NEXT:    [[TMP7:%.*]] = sdiv <4 x i64> [[WIDE_LOAD]], [[TMP5]]
618; FIXED-NEXT:    [[TMP8:%.*]] = sdiv <4 x i64> [[WIDE_LOAD1]], [[TMP5]]
619; FIXED-NEXT:    [[PREDPHI:%.*]] = select <4 x i1> [[TMP0]], <4 x i64> [[TMP7]], <4 x i64> [[WIDE_LOAD]]
620; FIXED-NEXT:    [[PREDPHI2:%.*]] = select <4 x i1> [[TMP0]], <4 x i64> [[TMP8]], <4 x i64> [[WIDE_LOAD1]]
621; FIXED-NEXT:    store <4 x i64> [[PREDPHI]], ptr [[TMP3]], align 8
622; FIXED-NEXT:    store <4 x i64> [[PREDPHI2]], ptr [[TMP4]], align 8
623; FIXED-NEXT:    [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 8
624; FIXED-NEXT:    [[TMP9:%.*]] = icmp eq i64 [[INDEX_NEXT]], 1024
625; FIXED-NEXT:    br i1 [[TMP9]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP12:![0-9]+]]
626; FIXED:       middle.block:
627; FIXED-NEXT:    br i1 true, label [[FOR_END:%.*]], label [[SCALAR_PH]]
628; FIXED:       scalar.ph:
629; FIXED-NEXT:    [[BC_RESUME_VAL:%.*]] = phi i64 [ 1024, [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY:%.*]] ]
630; FIXED-NEXT:    br label [[FOR_BODY:%.*]]
631; FIXED:       for.body:
632; FIXED-NEXT:    [[IV:%.*]] = phi i64 [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ], [ [[IV_NEXT:%.*]], [[LATCH:%.*]] ]
633; FIXED-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i64, ptr [[A]], i64 [[IV]]
634; FIXED-NEXT:    [[ELEM:%.*]] = load i64, ptr [[ARRAYIDX]], align 8
635; FIXED-NEXT:    [[C:%.*]] = icmp ne i64 [[V]], 0
636; FIXED-NEXT:    br i1 [[C]], label [[DO_OP:%.*]], label [[LATCH]]
637; FIXED:       do_op:
638; FIXED-NEXT:    [[DIVREM:%.*]] = sdiv i64 [[ELEM]], [[V]]
639; FIXED-NEXT:    br label [[LATCH]]
640; FIXED:       latch:
641; FIXED-NEXT:    [[PHI:%.*]] = phi i64 [ [[ELEM]], [[FOR_BODY]] ], [ [[DIVREM]], [[DO_OP]] ]
642; FIXED-NEXT:    store i64 [[PHI]], ptr [[ARRAYIDX]], align 8
643; FIXED-NEXT:    [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
644; FIXED-NEXT:    [[EXITCOND_NOT:%.*]] = icmp eq i64 [[IV_NEXT]], 1024
645; FIXED-NEXT:    br i1 [[EXITCOND_NOT]], label [[FOR_END]], label [[FOR_BODY]], !llvm.loop [[LOOP13:![0-9]+]]
646; FIXED:       for.end:
647; FIXED-NEXT:    ret void
648;
649entry:
650  br label %for.body
651
652for.body:
653  %iv = phi i64 [ 0, %entry ], [ %iv.next, %latch ]
654  %arrayidx = getelementptr inbounds i64, ptr %a, i64 %iv
655  %elem = load i64, ptr %arrayidx
656  %c = icmp ne i64 %v, 0
657  br i1 %c, label %do_op, label %latch
658do_op:
659  %divrem = sdiv i64 %elem, %v
660  br label %latch
661latch:
662  %phi = phi i64 [%elem, %for.body], [%divrem, %do_op]
663  store i64 %phi, ptr %arrayidx
664  %iv.next = add nuw nsw i64 %iv, 1
665  %exitcond.not = icmp eq i64 %iv.next, 1024
666  br i1 %exitcond.not, label %for.end, label %for.body
667
668for.end:
669  ret void
670}
671
672define void @predicated_udiv_by_constant(ptr noalias nocapture %a, i64 %n) {
673; CHECK-LABEL: @predicated_udiv_by_constant(
674; CHECK-NEXT:  entry:
675; CHECK-NEXT:    [[TMP0:%.*]] = call i64 @llvm.vscale.i64()
676; CHECK-NEXT:    [[TMP1:%.*]] = mul i64 [[TMP0]], 2
677; CHECK-NEXT:    [[MIN_ITERS_CHECK:%.*]] = icmp ult i64 1024, [[TMP1]]
678; CHECK-NEXT:    br i1 [[MIN_ITERS_CHECK]], label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]
679; CHECK:       vector.ph:
680; CHECK-NEXT:    [[TMP2:%.*]] = call i64 @llvm.vscale.i64()
681; CHECK-NEXT:    [[TMP3:%.*]] = mul i64 [[TMP2]], 2
682; CHECK-NEXT:    [[N_MOD_VF:%.*]] = urem i64 1024, [[TMP3]]
683; CHECK-NEXT:    [[N_VEC:%.*]] = sub i64 1024, [[N_MOD_VF]]
684; CHECK-NEXT:    [[TMP4:%.*]] = call i64 @llvm.vscale.i64()
685; CHECK-NEXT:    [[TMP5:%.*]] = mul i64 [[TMP4]], 2
686; CHECK-NEXT:    br label [[VECTOR_BODY:%.*]]
687; CHECK:       vector.body:
688; CHECK-NEXT:    [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ]
689; CHECK-NEXT:    [[TMP6:%.*]] = add i64 [[INDEX]], 0
690; CHECK-NEXT:    [[TMP7:%.*]] = getelementptr inbounds i64, ptr [[A:%.*]], i64 [[TMP6]]
691; CHECK-NEXT:    [[TMP8:%.*]] = getelementptr inbounds i64, ptr [[TMP7]], i32 0
692; CHECK-NEXT:    [[WIDE_LOAD:%.*]] = load <vscale x 2 x i64>, ptr [[TMP8]], align 8
693; CHECK-NEXT:    [[TMP9:%.*]] = icmp ne <vscale x 2 x i64> [[WIDE_LOAD]], splat (i64 42)
694; CHECK-NEXT:    [[TMP10:%.*]] = udiv <vscale x 2 x i64> [[WIDE_LOAD]], splat (i64 27)
695; CHECK-NEXT:    [[PREDPHI:%.*]] = select <vscale x 2 x i1> [[TMP9]], <vscale x 2 x i64> [[TMP10]], <vscale x 2 x i64> [[WIDE_LOAD]]
696; CHECK-NEXT:    store <vscale x 2 x i64> [[PREDPHI]], ptr [[TMP8]], align 8
697; CHECK-NEXT:    [[INDEX_NEXT]] = add nuw i64 [[INDEX]], [[TMP5]]
698; CHECK-NEXT:    [[TMP11:%.*]] = icmp eq i64 [[INDEX_NEXT]], [[N_VEC]]
699; CHECK-NEXT:    br i1 [[TMP11]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP14:![0-9]+]]
700; CHECK:       middle.block:
701; CHECK-NEXT:    [[CMP_N:%.*]] = icmp eq i64 1024, [[N_VEC]]
702; CHECK-NEXT:    br i1 [[CMP_N]], label [[FOR_END:%.*]], label [[SCALAR_PH]]
703; CHECK:       scalar.ph:
704; CHECK-NEXT:    [[BC_RESUME_VAL:%.*]] = phi i64 [ [[N_VEC]], [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY:%.*]] ]
705; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
706; CHECK:       for.body:
707; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ], [ [[IV_NEXT:%.*]], [[LATCH:%.*]] ]
708; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i64, ptr [[A]], i64 [[IV]]
709; CHECK-NEXT:    [[ELEM:%.*]] = load i64, ptr [[ARRAYIDX]], align 8
710; CHECK-NEXT:    [[C:%.*]] = icmp ne i64 [[ELEM]], 42
711; CHECK-NEXT:    br i1 [[C]], label [[DO_OP:%.*]], label [[LATCH]]
712; CHECK:       do_op:
713; CHECK-NEXT:    [[DIVREM:%.*]] = udiv i64 [[ELEM]], 27
714; CHECK-NEXT:    br label [[LATCH]]
715; CHECK:       latch:
716; CHECK-NEXT:    [[PHI:%.*]] = phi i64 [ [[ELEM]], [[FOR_BODY]] ], [ [[DIVREM]], [[DO_OP]] ]
717; CHECK-NEXT:    store i64 [[PHI]], ptr [[ARRAYIDX]], align 8
718; CHECK-NEXT:    [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
719; CHECK-NEXT:    [[EXITCOND_NOT:%.*]] = icmp eq i64 [[IV_NEXT]], 1024
720; CHECK-NEXT:    br i1 [[EXITCOND_NOT]], label [[FOR_END]], label [[FOR_BODY]], !llvm.loop [[LOOP15:![0-9]+]]
721; CHECK:       for.end:
722; CHECK-NEXT:    ret void
723;
724; FIXED-LABEL: @predicated_udiv_by_constant(
725; FIXED-NEXT:  entry:
726; FIXED-NEXT:    br i1 false, label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]
727; FIXED:       vector.ph:
728; FIXED-NEXT:    br label [[VECTOR_BODY:%.*]]
729; FIXED:       vector.body:
730; FIXED-NEXT:    [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ]
731; FIXED-NEXT:    [[TMP0:%.*]] = add i64 [[INDEX]], 0
732; FIXED-NEXT:    [[TMP1:%.*]] = getelementptr inbounds i64, ptr [[A:%.*]], i64 [[TMP0]]
733; FIXED-NEXT:    [[TMP2:%.*]] = getelementptr inbounds i64, ptr [[TMP1]], i32 0
734; FIXED-NEXT:    [[TMP3:%.*]] = getelementptr inbounds i64, ptr [[TMP1]], i32 4
735; FIXED-NEXT:    [[WIDE_LOAD:%.*]] = load <4 x i64>, ptr [[TMP2]], align 8
736; FIXED-NEXT:    [[WIDE_LOAD1:%.*]] = load <4 x i64>, ptr [[TMP3]], align 8
737; FIXED-NEXT:    [[TMP4:%.*]] = icmp ne <4 x i64> [[WIDE_LOAD]], splat (i64 42)
738; FIXED-NEXT:    [[TMP5:%.*]] = icmp ne <4 x i64> [[WIDE_LOAD1]], splat (i64 42)
739; FIXED-NEXT:    [[TMP6:%.*]] = udiv <4 x i64> [[WIDE_LOAD]], splat (i64 27)
740; FIXED-NEXT:    [[TMP7:%.*]] = udiv <4 x i64> [[WIDE_LOAD1]], splat (i64 27)
741; FIXED-NEXT:    [[PREDPHI:%.*]] = select <4 x i1> [[TMP4]], <4 x i64> [[TMP6]], <4 x i64> [[WIDE_LOAD]]
742; FIXED-NEXT:    [[PREDPHI2:%.*]] = select <4 x i1> [[TMP5]], <4 x i64> [[TMP7]], <4 x i64> [[WIDE_LOAD1]]
743; FIXED-NEXT:    store <4 x i64> [[PREDPHI]], ptr [[TMP2]], align 8
744; FIXED-NEXT:    store <4 x i64> [[PREDPHI2]], ptr [[TMP3]], align 8
745; FIXED-NEXT:    [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 8
746; FIXED-NEXT:    [[TMP8:%.*]] = icmp eq i64 [[INDEX_NEXT]], 1024
747; FIXED-NEXT:    br i1 [[TMP8]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP14:![0-9]+]]
748; FIXED:       middle.block:
749; FIXED-NEXT:    br i1 true, label [[FOR_END:%.*]], label [[SCALAR_PH]]
750; FIXED:       scalar.ph:
751; FIXED-NEXT:    [[BC_RESUME_VAL:%.*]] = phi i64 [ 1024, [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY:%.*]] ]
752; FIXED-NEXT:    br label [[FOR_BODY:%.*]]
753; FIXED:       for.body:
754; FIXED-NEXT:    [[IV:%.*]] = phi i64 [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ], [ [[IV_NEXT:%.*]], [[LATCH:%.*]] ]
755; FIXED-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i64, ptr [[A]], i64 [[IV]]
756; FIXED-NEXT:    [[ELEM:%.*]] = load i64, ptr [[ARRAYIDX]], align 8
757; FIXED-NEXT:    [[C:%.*]] = icmp ne i64 [[ELEM]], 42
758; FIXED-NEXT:    br i1 [[C]], label [[DO_OP:%.*]], label [[LATCH]]
759; FIXED:       do_op:
760; FIXED-NEXT:    [[DIVREM:%.*]] = udiv i64 [[ELEM]], 27
761; FIXED-NEXT:    br label [[LATCH]]
762; FIXED:       latch:
763; FIXED-NEXT:    [[PHI:%.*]] = phi i64 [ [[ELEM]], [[FOR_BODY]] ], [ [[DIVREM]], [[DO_OP]] ]
764; FIXED-NEXT:    store i64 [[PHI]], ptr [[ARRAYIDX]], align 8
765; FIXED-NEXT:    [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
766; FIXED-NEXT:    [[EXITCOND_NOT:%.*]] = icmp eq i64 [[IV_NEXT]], 1024
767; FIXED-NEXT:    br i1 [[EXITCOND_NOT]], label [[FOR_END]], label [[FOR_BODY]], !llvm.loop [[LOOP15:![0-9]+]]
768; FIXED:       for.end:
769; FIXED-NEXT:    ret void
770;
771entry:
772  br label %for.body
773
774for.body:
775  %iv = phi i64 [ 0, %entry ], [ %iv.next, %latch ]
776  %arrayidx = getelementptr inbounds i64, ptr %a, i64 %iv
777  %elem = load i64, ptr %arrayidx
778  %c = icmp ne i64 %elem, 42
779  br i1 %c, label %do_op, label %latch
780do_op:
781  %divrem = udiv i64 %elem, 27
782  br label %latch
783latch:
784  %phi = phi i64 [%elem, %for.body], [%divrem, %do_op]
785  store i64 %phi, ptr %arrayidx
786  %iv.next = add nuw nsw i64 %iv, 1
787  %exitcond.not = icmp eq i64 %iv.next, 1024
788  br i1 %exitcond.not, label %for.end, label %for.body
789
790for.end:
791  ret void
792}
793
794define void @predicated_sdiv_by_constant(ptr noalias nocapture %a, i64 %n) {
795; CHECK-LABEL: @predicated_sdiv_by_constant(
796; CHECK-NEXT:  entry:
797; CHECK-NEXT:    [[TMP0:%.*]] = call i64 @llvm.vscale.i64()
798; CHECK-NEXT:    [[TMP1:%.*]] = mul i64 [[TMP0]], 2
799; CHECK-NEXT:    [[MIN_ITERS_CHECK:%.*]] = icmp ult i64 1024, [[TMP1]]
800; CHECK-NEXT:    br i1 [[MIN_ITERS_CHECK]], label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]
801; CHECK:       vector.ph:
802; CHECK-NEXT:    [[TMP2:%.*]] = call i64 @llvm.vscale.i64()
803; CHECK-NEXT:    [[TMP3:%.*]] = mul i64 [[TMP2]], 2
804; CHECK-NEXT:    [[N_MOD_VF:%.*]] = urem i64 1024, [[TMP3]]
805; CHECK-NEXT:    [[N_VEC:%.*]] = sub i64 1024, [[N_MOD_VF]]
806; CHECK-NEXT:    [[TMP4:%.*]] = call i64 @llvm.vscale.i64()
807; CHECK-NEXT:    [[TMP5:%.*]] = mul i64 [[TMP4]], 2
808; CHECK-NEXT:    br label [[VECTOR_BODY:%.*]]
809; CHECK:       vector.body:
810; CHECK-NEXT:    [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ]
811; CHECK-NEXT:    [[TMP6:%.*]] = add i64 [[INDEX]], 0
812; CHECK-NEXT:    [[TMP7:%.*]] = getelementptr inbounds i64, ptr [[A:%.*]], i64 [[TMP6]]
813; CHECK-NEXT:    [[TMP8:%.*]] = getelementptr inbounds i64, ptr [[TMP7]], i32 0
814; CHECK-NEXT:    [[WIDE_LOAD:%.*]] = load <vscale x 2 x i64>, ptr [[TMP8]], align 8
815; CHECK-NEXT:    [[TMP9:%.*]] = icmp ne <vscale x 2 x i64> [[WIDE_LOAD]], splat (i64 42)
816; CHECK-NEXT:    [[TMP10:%.*]] = sdiv <vscale x 2 x i64> [[WIDE_LOAD]], splat (i64 27)
817; CHECK-NEXT:    [[PREDPHI:%.*]] = select <vscale x 2 x i1> [[TMP9]], <vscale x 2 x i64> [[TMP10]], <vscale x 2 x i64> [[WIDE_LOAD]]
818; CHECK-NEXT:    store <vscale x 2 x i64> [[PREDPHI]], ptr [[TMP8]], align 8
819; CHECK-NEXT:    [[INDEX_NEXT]] = add nuw i64 [[INDEX]], [[TMP5]]
820; CHECK-NEXT:    [[TMP11:%.*]] = icmp eq i64 [[INDEX_NEXT]], [[N_VEC]]
821; CHECK-NEXT:    br i1 [[TMP11]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP16:![0-9]+]]
822; CHECK:       middle.block:
823; CHECK-NEXT:    [[CMP_N:%.*]] = icmp eq i64 1024, [[N_VEC]]
824; CHECK-NEXT:    br i1 [[CMP_N]], label [[FOR_END:%.*]], label [[SCALAR_PH]]
825; CHECK:       scalar.ph:
826; CHECK-NEXT:    [[BC_RESUME_VAL:%.*]] = phi i64 [ [[N_VEC]], [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY:%.*]] ]
827; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
828; CHECK:       for.body:
829; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ], [ [[IV_NEXT:%.*]], [[LATCH:%.*]] ]
830; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i64, ptr [[A]], i64 [[IV]]
831; CHECK-NEXT:    [[ELEM:%.*]] = load i64, ptr [[ARRAYIDX]], align 8
832; CHECK-NEXT:    [[C:%.*]] = icmp ne i64 [[ELEM]], 42
833; CHECK-NEXT:    br i1 [[C]], label [[DO_OP:%.*]], label [[LATCH]]
834; CHECK:       do_op:
835; CHECK-NEXT:    [[DIVREM:%.*]] = sdiv i64 [[ELEM]], 27
836; CHECK-NEXT:    br label [[LATCH]]
837; CHECK:       latch:
838; CHECK-NEXT:    [[PHI:%.*]] = phi i64 [ [[ELEM]], [[FOR_BODY]] ], [ [[DIVREM]], [[DO_OP]] ]
839; CHECK-NEXT:    store i64 [[PHI]], ptr [[ARRAYIDX]], align 8
840; CHECK-NEXT:    [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
841; CHECK-NEXT:    [[EXITCOND_NOT:%.*]] = icmp eq i64 [[IV_NEXT]], 1024
842; CHECK-NEXT:    br i1 [[EXITCOND_NOT]], label [[FOR_END]], label [[FOR_BODY]], !llvm.loop [[LOOP17:![0-9]+]]
843; CHECK:       for.end:
844; CHECK-NEXT:    ret void
845;
846; FIXED-LABEL: @predicated_sdiv_by_constant(
847; FIXED-NEXT:  entry:
848; FIXED-NEXT:    br i1 false, label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]
849; FIXED:       vector.ph:
850; FIXED-NEXT:    br label [[VECTOR_BODY:%.*]]
851; FIXED:       vector.body:
852; FIXED-NEXT:    [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ]
853; FIXED-NEXT:    [[TMP0:%.*]] = add i64 [[INDEX]], 0
854; FIXED-NEXT:    [[TMP1:%.*]] = getelementptr inbounds i64, ptr [[A:%.*]], i64 [[TMP0]]
855; FIXED-NEXT:    [[TMP2:%.*]] = getelementptr inbounds i64, ptr [[TMP1]], i32 0
856; FIXED-NEXT:    [[TMP3:%.*]] = getelementptr inbounds i64, ptr [[TMP1]], i32 4
857; FIXED-NEXT:    [[WIDE_LOAD:%.*]] = load <4 x i64>, ptr [[TMP2]], align 8
858; FIXED-NEXT:    [[WIDE_LOAD1:%.*]] = load <4 x i64>, ptr [[TMP3]], align 8
859; FIXED-NEXT:    [[TMP4:%.*]] = icmp ne <4 x i64> [[WIDE_LOAD]], splat (i64 42)
860; FIXED-NEXT:    [[TMP5:%.*]] = icmp ne <4 x i64> [[WIDE_LOAD1]], splat (i64 42)
861; FIXED-NEXT:    [[TMP6:%.*]] = sdiv <4 x i64> [[WIDE_LOAD]], splat (i64 27)
862; FIXED-NEXT:    [[TMP7:%.*]] = sdiv <4 x i64> [[WIDE_LOAD1]], splat (i64 27)
863; FIXED-NEXT:    [[PREDPHI:%.*]] = select <4 x i1> [[TMP4]], <4 x i64> [[TMP6]], <4 x i64> [[WIDE_LOAD]]
864; FIXED-NEXT:    [[PREDPHI2:%.*]] = select <4 x i1> [[TMP5]], <4 x i64> [[TMP7]], <4 x i64> [[WIDE_LOAD1]]
865; FIXED-NEXT:    store <4 x i64> [[PREDPHI]], ptr [[TMP2]], align 8
866; FIXED-NEXT:    store <4 x i64> [[PREDPHI2]], ptr [[TMP3]], align 8
867; FIXED-NEXT:    [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 8
868; FIXED-NEXT:    [[TMP8:%.*]] = icmp eq i64 [[INDEX_NEXT]], 1024
869; FIXED-NEXT:    br i1 [[TMP8]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP16:![0-9]+]]
870; FIXED:       middle.block:
871; FIXED-NEXT:    br i1 true, label [[FOR_END:%.*]], label [[SCALAR_PH]]
872; FIXED:       scalar.ph:
873; FIXED-NEXT:    [[BC_RESUME_VAL:%.*]] = phi i64 [ 1024, [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY:%.*]] ]
874; FIXED-NEXT:    br label [[FOR_BODY:%.*]]
875; FIXED:       for.body:
876; FIXED-NEXT:    [[IV:%.*]] = phi i64 [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ], [ [[IV_NEXT:%.*]], [[LATCH:%.*]] ]
877; FIXED-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i64, ptr [[A]], i64 [[IV]]
878; FIXED-NEXT:    [[ELEM:%.*]] = load i64, ptr [[ARRAYIDX]], align 8
879; FIXED-NEXT:    [[C:%.*]] = icmp ne i64 [[ELEM]], 42
880; FIXED-NEXT:    br i1 [[C]], label [[DO_OP:%.*]], label [[LATCH]]
881; FIXED:       do_op:
882; FIXED-NEXT:    [[DIVREM:%.*]] = sdiv i64 [[ELEM]], 27
883; FIXED-NEXT:    br label [[LATCH]]
884; FIXED:       latch:
885; FIXED-NEXT:    [[PHI:%.*]] = phi i64 [ [[ELEM]], [[FOR_BODY]] ], [ [[DIVREM]], [[DO_OP]] ]
886; FIXED-NEXT:    store i64 [[PHI]], ptr [[ARRAYIDX]], align 8
887; FIXED-NEXT:    [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
888; FIXED-NEXT:    [[EXITCOND_NOT:%.*]] = icmp eq i64 [[IV_NEXT]], 1024
889; FIXED-NEXT:    br i1 [[EXITCOND_NOT]], label [[FOR_END]], label [[FOR_BODY]], !llvm.loop [[LOOP17:![0-9]+]]
890; FIXED:       for.end:
891; FIXED-NEXT:    ret void
892;
893entry:
894  br label %for.body
895
896for.body:
897  %iv = phi i64 [ 0, %entry ], [ %iv.next, %latch ]
898  %arrayidx = getelementptr inbounds i64, ptr %a, i64 %iv
899  %elem = load i64, ptr %arrayidx
900  %c = icmp ne i64 %elem, 42
901  br i1 %c, label %do_op, label %latch
902do_op:
903  %divrem = sdiv i64 %elem, 27
904  br label %latch
905latch:
906  %phi = phi i64 [%elem, %for.body], [%divrem, %do_op]
907  store i64 %phi, ptr %arrayidx
908  %iv.next = add nuw nsw i64 %iv, 1
909  %exitcond.not = icmp eq i64 %iv.next, 1024
910  br i1 %exitcond.not, label %for.end, label %for.body
911
912for.end:
913  ret void
914}
915
916define void @predicated_sdiv_by_minus_one(ptr noalias nocapture %a, i64 %n) {
917; CHECK-LABEL: @predicated_sdiv_by_minus_one(
918; CHECK-NEXT:  entry:
919; CHECK-NEXT:    [[TMP0:%.*]] = call i64 @llvm.vscale.i64()
920; CHECK-NEXT:    [[TMP1:%.*]] = mul i64 [[TMP0]], 16
921; CHECK-NEXT:    [[MIN_ITERS_CHECK:%.*]] = icmp ult i64 1024, [[TMP1]]
922; CHECK-NEXT:    br i1 [[MIN_ITERS_CHECK]], label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]
923; CHECK:       vector.ph:
924; CHECK-NEXT:    [[TMP2:%.*]] = call i64 @llvm.vscale.i64()
925; CHECK-NEXT:    [[TMP3:%.*]] = mul i64 [[TMP2]], 16
926; CHECK-NEXT:    [[N_MOD_VF:%.*]] = urem i64 1024, [[TMP3]]
927; CHECK-NEXT:    [[N_VEC:%.*]] = sub i64 1024, [[N_MOD_VF]]
928; CHECK-NEXT:    [[TMP4:%.*]] = call i64 @llvm.vscale.i64()
929; CHECK-NEXT:    [[TMP5:%.*]] = mul i64 [[TMP4]], 16
930; CHECK-NEXT:    br label [[VECTOR_BODY:%.*]]
931; CHECK:       vector.body:
932; CHECK-NEXT:    [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ]
933; CHECK-NEXT:    [[TMP6:%.*]] = add i64 [[INDEX]], 0
934; CHECK-NEXT:    [[TMP7:%.*]] = getelementptr inbounds i8, ptr [[A:%.*]], i64 [[TMP6]]
935; CHECK-NEXT:    [[TMP8:%.*]] = getelementptr inbounds i8, ptr [[TMP7]], i32 0
936; CHECK-NEXT:    [[WIDE_LOAD:%.*]] = load <vscale x 16 x i8>, ptr [[TMP8]], align 1
937; CHECK-NEXT:    [[TMP9:%.*]] = icmp ne <vscale x 16 x i8> [[WIDE_LOAD]], splat (i8 -128)
938; CHECK-NEXT:    [[TMP10:%.*]] = select <vscale x 16 x i1> [[TMP9]], <vscale x 16 x i8> splat (i8 -1), <vscale x 16 x i8> splat (i8 1)
939; CHECK-NEXT:    [[TMP11:%.*]] = sdiv <vscale x 16 x i8> [[WIDE_LOAD]], [[TMP10]]
940; CHECK-NEXT:    [[PREDPHI:%.*]] = select <vscale x 16 x i1> [[TMP9]], <vscale x 16 x i8> [[TMP11]], <vscale x 16 x i8> [[WIDE_LOAD]]
941; CHECK-NEXT:    store <vscale x 16 x i8> [[PREDPHI]], ptr [[TMP8]], align 1
942; CHECK-NEXT:    [[INDEX_NEXT]] = add nuw i64 [[INDEX]], [[TMP5]]
943; CHECK-NEXT:    [[TMP12:%.*]] = icmp eq i64 [[INDEX_NEXT]], [[N_VEC]]
944; CHECK-NEXT:    br i1 [[TMP12]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP18:![0-9]+]]
945; CHECK:       middle.block:
946; CHECK-NEXT:    [[CMP_N:%.*]] = icmp eq i64 1024, [[N_VEC]]
947; CHECK-NEXT:    br i1 [[CMP_N]], label [[FOR_END:%.*]], label [[SCALAR_PH]]
948; CHECK:       scalar.ph:
949; CHECK-NEXT:    [[BC_RESUME_VAL:%.*]] = phi i64 [ [[N_VEC]], [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY:%.*]] ]
950; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
951; CHECK:       for.body:
952; CHECK-NEXT:    [[IV:%.*]] = phi i64 [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ], [ [[IV_NEXT:%.*]], [[LATCH:%.*]] ]
953; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[A]], i64 [[IV]]
954; CHECK-NEXT:    [[ELEM:%.*]] = load i8, ptr [[ARRAYIDX]], align 1
955; CHECK-NEXT:    [[C:%.*]] = icmp ne i8 [[ELEM]], -128
956; CHECK-NEXT:    br i1 [[C]], label [[DO_OP:%.*]], label [[LATCH]]
957; CHECK:       do_op:
958; CHECK-NEXT:    [[DIVREM:%.*]] = sdiv i8 [[ELEM]], -1
959; CHECK-NEXT:    br label [[LATCH]]
960; CHECK:       latch:
961; CHECK-NEXT:    [[PHI:%.*]] = phi i8 [ [[ELEM]], [[FOR_BODY]] ], [ [[DIVREM]], [[DO_OP]] ]
962; CHECK-NEXT:    store i8 [[PHI]], ptr [[ARRAYIDX]], align 1
963; CHECK-NEXT:    [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
964; CHECK-NEXT:    [[EXITCOND_NOT:%.*]] = icmp eq i64 [[IV_NEXT]], 1024
965; CHECK-NEXT:    br i1 [[EXITCOND_NOT]], label [[FOR_END]], label [[FOR_BODY]], !llvm.loop [[LOOP19:![0-9]+]]
966; CHECK:       for.end:
967; CHECK-NEXT:    ret void
968;
969; FIXED-LABEL: @predicated_sdiv_by_minus_one(
970; FIXED-NEXT:  entry:
971; FIXED-NEXT:    br i1 false, label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]
972; FIXED:       vector.ph:
973; FIXED-NEXT:    br label [[VECTOR_BODY:%.*]]
974; FIXED:       vector.body:
975; FIXED-NEXT:    [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ]
976; FIXED-NEXT:    [[TMP0:%.*]] = add i64 [[INDEX]], 0
977; FIXED-NEXT:    [[TMP1:%.*]] = getelementptr inbounds i8, ptr [[A:%.*]], i64 [[TMP0]]
978; FIXED-NEXT:    [[TMP2:%.*]] = getelementptr inbounds i8, ptr [[TMP1]], i32 0
979; FIXED-NEXT:    [[TMP3:%.*]] = getelementptr inbounds i8, ptr [[TMP1]], i32 32
980; FIXED-NEXT:    [[WIDE_LOAD:%.*]] = load <32 x i8>, ptr [[TMP2]], align 1
981; FIXED-NEXT:    [[WIDE_LOAD1:%.*]] = load <32 x i8>, ptr [[TMP3]], align 1
982; FIXED-NEXT:    [[TMP4:%.*]] = icmp ne <32 x i8> [[WIDE_LOAD]], splat (i8 -128)
983; FIXED-NEXT:    [[TMP5:%.*]] = icmp ne <32 x i8> [[WIDE_LOAD1]], splat (i8 -128)
984; FIXED-NEXT:    [[TMP6:%.*]] = select <32 x i1> [[TMP4]], <32 x i8> splat (i8 -1), <32 x i8> splat (i8 1)
985; FIXED-NEXT:    [[TMP7:%.*]] = select <32 x i1> [[TMP5]], <32 x i8> splat (i8 -1), <32 x i8> splat (i8 1)
986; FIXED-NEXT:    [[TMP8:%.*]] = sdiv <32 x i8> [[WIDE_LOAD]], [[TMP6]]
987; FIXED-NEXT:    [[TMP9:%.*]] = sdiv <32 x i8> [[WIDE_LOAD1]], [[TMP7]]
988; FIXED-NEXT:    [[PREDPHI:%.*]] = select <32 x i1> [[TMP4]], <32 x i8> [[TMP8]], <32 x i8> [[WIDE_LOAD]]
989; FIXED-NEXT:    [[PREDPHI2:%.*]] = select <32 x i1> [[TMP5]], <32 x i8> [[TMP9]], <32 x i8> [[WIDE_LOAD1]]
990; FIXED-NEXT:    store <32 x i8> [[PREDPHI]], ptr [[TMP2]], align 1
991; FIXED-NEXT:    store <32 x i8> [[PREDPHI2]], ptr [[TMP3]], align 1
992; FIXED-NEXT:    [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 64
993; FIXED-NEXT:    [[TMP10:%.*]] = icmp eq i64 [[INDEX_NEXT]], 1024
994; FIXED-NEXT:    br i1 [[TMP10]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP18:![0-9]+]]
995; FIXED:       middle.block:
996; FIXED-NEXT:    br i1 true, label [[FOR_END:%.*]], label [[SCALAR_PH]]
997; FIXED:       scalar.ph:
998; FIXED-NEXT:    [[BC_RESUME_VAL:%.*]] = phi i64 [ 1024, [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY:%.*]] ]
999; FIXED-NEXT:    br label [[FOR_BODY:%.*]]
1000; FIXED:       for.body:
1001; FIXED-NEXT:    [[IV:%.*]] = phi i64 [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ], [ [[IV_NEXT:%.*]], [[LATCH:%.*]] ]
1002; FIXED-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[A]], i64 [[IV]]
1003; FIXED-NEXT:    [[ELEM:%.*]] = load i8, ptr [[ARRAYIDX]], align 1
1004; FIXED-NEXT:    [[C:%.*]] = icmp ne i8 [[ELEM]], -128
1005; FIXED-NEXT:    br i1 [[C]], label [[DO_OP:%.*]], label [[LATCH]]
1006; FIXED:       do_op:
1007; FIXED-NEXT:    [[DIVREM:%.*]] = sdiv i8 [[ELEM]], -1
1008; FIXED-NEXT:    br label [[LATCH]]
1009; FIXED:       latch:
1010; FIXED-NEXT:    [[PHI:%.*]] = phi i8 [ [[ELEM]], [[FOR_BODY]] ], [ [[DIVREM]], [[DO_OP]] ]
1011; FIXED-NEXT:    store i8 [[PHI]], ptr [[ARRAYIDX]], align 1
1012; FIXED-NEXT:    [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
1013; FIXED-NEXT:    [[EXITCOND_NOT:%.*]] = icmp eq i64 [[IV_NEXT]], 1024
1014; FIXED-NEXT:    br i1 [[EXITCOND_NOT]], label [[FOR_END]], label [[FOR_BODY]], !llvm.loop [[LOOP19:![0-9]+]]
1015; FIXED:       for.end:
1016; FIXED-NEXT:    ret void
1017;
1018entry:
1019  br label %for.body
1020
1021for.body:
1022  %iv = phi i64 [ 0, %entry ], [ %iv.next, %latch ]
1023  %arrayidx = getelementptr inbounds i8, ptr %a, i64 %iv
1024  %elem = load i8, ptr %arrayidx
1025  %c = icmp ne i8 %elem, 128
1026  br i1 %c, label %do_op, label %latch
1027do_op:
1028  %divrem = sdiv i8 %elem, -1 ;; UB if %elem = INT_MIN
1029  br label %latch
1030latch:
1031  %phi = phi i8 [%elem, %for.body], [%divrem, %do_op]
1032  store i8 %phi, ptr %arrayidx
1033  %iv.next = add nuw nsw i64 %iv, 1
1034  %exitcond.not = icmp eq i64 %iv.next, 1024
1035  br i1 %exitcond.not, label %for.end, label %for.body
1036
1037for.end:
1038  ret void
1039}
1040