Skip to content

Commit 17677ad

Browse files
authored
[LV] Don't create WidePtrAdd recipes for scalar VFs (#169344)
While attempting to remove the use of undef from more loop vectoriser tests I discovered a bug where this assert was firing: ``` llvm::Constant* llvm::Constant::getSplatValue(bool) const: Assertion `this->getType()->isVectorTy() && "Only valid for vectors!"' failed. ... #8 0x0000aaaab9e2fba4 llvm::Constant::getSplatValue #9 0x0000aaaab9dfb844 llvm::ConstantFoldBinaryInstruction ``` This seems to be happening because we are incorrectly generating WidePtrAdd recipes for scalar VFs. The PR fixes this by checking whether a plan has a scalar VF only in legalizeAndOptimizeInductions. This PR also removes the use of undef from the test `both` in Transforms/LoopVectorize/iv_outside_user.ll, which is what started triggering the assert. Fixes #169334
1 parent 4d7abe5 commit 17677ad

File tree

2 files changed

+95
-47
lines changed

2 files changed

+95
-47
lines changed

llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -769,7 +769,8 @@ static void legalizeAndOptimizeInductions(VPlan &Plan) {
769769
// Replace wide pointer inductions which have only their scalars used by
770770
// PtrAdd(IndStart, ScalarIVSteps (0, Step)).
771771
if (auto *PtrIV = dyn_cast<VPWidenPointerInductionRecipe>(&Phi)) {
772-
if (!PtrIV->onlyScalarsGenerated(Plan.hasScalableVF()))
772+
if (!Plan.hasScalarVFOnly() &&
773+
!PtrIV->onlyScalarsGenerated(Plan.hasScalableVF()))
773774
continue;
774775

775776
VPValue *PtrAdd = scalarizeVPWidenPointerInduction(PtrIV, Plan, Builder);

llvm/test/Transforms/LoopVectorize/iv_outside_user.ll

Lines changed: 93 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -152,59 +152,106 @@ for.end:
152152
ret ptr %ptr.phi
153153
}
154154

155-
define ptr @both(i32 %k) {
156-
; CHECK-LABEL: define ptr @both(
157-
; CHECK-SAME: i32 [[K:%.*]]) {
158-
; CHECK-NEXT: [[ENTRY:.*]]:
159-
; CHECK-NEXT: [[BASE:%.*]] = getelementptr inbounds i32, ptr undef, i64 1
160-
; CHECK-NEXT: [[TMP0:%.*]] = add i32 [[K]], -1
161-
; CHECK-NEXT: [[TMP1:%.*]] = zext i32 [[TMP0]] to i64
162-
; CHECK-NEXT: [[TMP2:%.*]] = add nuw nsw i64 [[TMP1]], 1
163-
; CHECK-NEXT: [[MIN_ITERS_CHECK:%.*]] = icmp ult i64 [[TMP2]], 2
164-
; CHECK-NEXT: br i1 [[MIN_ITERS_CHECK]], label %[[SCALAR_PH:.*]], label %[[VECTOR_PH:.*]]
165-
; CHECK: [[VECTOR_PH]]:
166-
; CHECK-NEXT: [[N_MOD_VF:%.*]] = urem i64 [[TMP2]], 2
167-
; CHECK-NEXT: [[N_VEC:%.*]] = sub i64 [[TMP2]], [[N_MOD_VF]]
168-
; CHECK-NEXT: [[IND_END:%.*]] = trunc i64 [[N_VEC]] to i32
169-
; CHECK-NEXT: [[TMP3:%.*]] = mul i64 [[N_VEC]], 4
170-
; CHECK-NEXT: [[IND_END1:%.*]] = getelementptr i8, ptr [[BASE]], i64 [[TMP3]]
171-
; CHECK-NEXT: [[TMP4:%.*]] = mul i64 [[N_VEC]], 4
172-
; CHECK-NEXT: [[IND_END2:%.*]] = getelementptr i8, ptr undef, i64 [[TMP4]]
173-
; CHECK-NEXT: br label %[[VECTOR_BODY:.*]]
174-
; CHECK: [[VECTOR_BODY]]:
175-
; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, %[[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], %[[VECTOR_BODY]] ]
176-
; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 2
177-
; CHECK-NEXT: [[TMP5:%.*]] = icmp eq i64 [[INDEX_NEXT]], [[N_VEC]]
178-
; CHECK-NEXT: br i1 [[TMP5]], label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]], {{!llvm.loop ![0-9]+}}
179-
; CHECK: [[MIDDLE_BLOCK]]:
180-
; CHECK-NEXT: [[CMP_N:%.*]] = icmp eq i64 [[TMP2]], [[N_VEC]]
181-
; CHECK-NEXT: [[IND_ESCAPE:%.*]] = getelementptr i8, ptr [[IND_END1]], i64 -4
182-
; CHECK-NEXT: br i1 [[CMP_N]], label %[[FOR_END:.*]], label %[[SCALAR_PH]]
183-
; CHECK: [[SCALAR_PH]]:
184-
; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i32 [ [[IND_END]], %[[MIDDLE_BLOCK]] ], [ 0, %[[ENTRY]] ]
185-
; CHECK-NEXT: [[BC_RESUME_VAL1:%.*]] = phi ptr [ [[IND_END1]], %[[MIDDLE_BLOCK]] ], [ [[BASE]], %[[ENTRY]] ]
186-
; CHECK-NEXT: [[BC_RESUME_VAL2:%.*]] = phi ptr [ [[IND_END2]], %[[MIDDLE_BLOCK]] ], [ undef, %[[ENTRY]] ]
187-
; CHECK-NEXT: br label %[[FOR_BODY:.*]]
188-
; CHECK: [[FOR_BODY]]:
189-
; CHECK-NEXT: [[INC_PHI:%.*]] = phi i32 [ [[BC_RESUME_VAL]], %[[SCALAR_PH]] ], [ [[INC:%.*]], %[[FOR_BODY]] ]
190-
; CHECK-NEXT: [[INC_LAG1:%.*]] = phi ptr [ [[BC_RESUME_VAL1]], %[[SCALAR_PH]] ], [ [[TMP:%.*]], %[[FOR_BODY]] ]
191-
; CHECK-NEXT: [[INC_LAG2:%.*]] = phi ptr [ [[BC_RESUME_VAL2]], %[[SCALAR_PH]] ], [ [[INC_LAG1]], %[[FOR_BODY]] ]
192-
; CHECK-NEXT: [[TMP]] = getelementptr inbounds i32, ptr [[INC_LAG1]], i64 1
193-
; CHECK-NEXT: [[INC]] = add nsw i32 [[INC_PHI]], 1
194-
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[INC]], [[K]]
195-
; CHECK-NEXT: br i1 [[CMP]], label %[[FOR_END]], label %[[FOR_BODY]], {{!llvm.loop ![0-9]+}}
196-
; CHECK: [[FOR_END]]:
197-
; CHECK-NEXT: [[INC_LAG1_LCSSA:%.*]] = phi ptr [ [[INC_LAG1]], %[[FOR_BODY]] ], [ [[IND_ESCAPE]], %[[MIDDLE_BLOCK]] ]
198-
; CHECK-NEXT: ret ptr [[INC_LAG1_LCSSA]]
155+
define ptr @both(ptr %p, i32 %k) {
156+
; VEC-LABEL: define ptr @both(
157+
; VEC-SAME: ptr [[P:%.*]], i32 [[K:%.*]]) {
158+
; VEC-NEXT: [[ENTRY:.*]]:
159+
; VEC-NEXT: [[BASE:%.*]] = getelementptr inbounds i32, ptr [[P]], i64 1
160+
; VEC-NEXT: [[TMP0:%.*]] = add i32 [[K]], -1
161+
; VEC-NEXT: [[TMP1:%.*]] = zext i32 [[TMP0]] to i64
162+
; VEC-NEXT: [[TMP2:%.*]] = add nuw nsw i64 [[TMP1]], 1
163+
; VEC-NEXT: [[MIN_ITERS_CHECK:%.*]] = icmp ult i64 [[TMP2]], 2
164+
; VEC-NEXT: br i1 [[MIN_ITERS_CHECK]], label %[[SCALAR_PH:.*]], label %[[VECTOR_PH:.*]]
165+
; VEC: [[VECTOR_PH]]:
166+
; VEC-NEXT: [[N_MOD_VF:%.*]] = urem i64 [[TMP2]], 2
167+
; VEC-NEXT: [[N_VEC:%.*]] = sub i64 [[TMP2]], [[N_MOD_VF]]
168+
; VEC-NEXT: [[TMP3:%.*]] = trunc i64 [[N_VEC]] to i32
169+
; VEC-NEXT: [[TMP4:%.*]] = mul i64 [[N_VEC]], 4
170+
; VEC-NEXT: [[TMP5:%.*]] = getelementptr i8, ptr [[BASE]], i64 [[TMP4]]
171+
; VEC-NEXT: br label %[[VECTOR_BODY:.*]]
172+
; VEC: [[VECTOR_BODY]]:
173+
; VEC-NEXT: [[INDEX:%.*]] = phi i64 [ 0, %[[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], %[[VECTOR_BODY]] ]
174+
; VEC-NEXT: [[POINTER_PHI:%.*]] = phi ptr [ [[BASE]], %[[VECTOR_PH]] ], [ [[PTR_IND:%.*]], %[[VECTOR_BODY]] ]
175+
; VEC-NEXT: [[VECTOR_GEP:%.*]] = getelementptr i8, ptr [[POINTER_PHI]], <2 x i64> <i64 0, i64 4>
176+
; VEC-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 2
177+
; VEC-NEXT: [[PTR_IND]] = getelementptr i8, ptr [[POINTER_PHI]], i64 8
178+
; VEC-NEXT: [[TMP6:%.*]] = icmp eq i64 [[INDEX_NEXT]], [[N_VEC]]
179+
; VEC-NEXT: br i1 [[TMP6]], label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]], {{!llvm.loop ![0-9]+}}
180+
; VEC: [[MIDDLE_BLOCK]]:
181+
; VEC-NEXT: [[VECTOR_RECUR_EXTRACT:%.*]] = extractelement <2 x ptr> [[VECTOR_GEP]], i32 1
182+
; VEC-NEXT: [[CMP_N:%.*]] = icmp eq i64 [[TMP2]], [[N_VEC]]
183+
; VEC-NEXT: [[IND_ESCAPE:%.*]] = getelementptr i8, ptr [[TMP5]], i64 -4
184+
; VEC-NEXT: br i1 [[CMP_N]], label %[[FOR_END:.*]], label %[[SCALAR_PH]]
185+
; VEC: [[SCALAR_PH]]:
186+
; VEC-NEXT: [[BC_RESUME_VAL:%.*]] = phi i32 [ [[TMP3]], %[[MIDDLE_BLOCK]] ], [ 0, %[[ENTRY]] ]
187+
; VEC-NEXT: [[BC_RESUME_VAL1:%.*]] = phi ptr [ [[TMP5]], %[[MIDDLE_BLOCK]] ], [ [[BASE]], %[[ENTRY]] ]
188+
; VEC-NEXT: [[SCALAR_RECUR_INIT:%.*]] = phi ptr [ [[VECTOR_RECUR_EXTRACT]], %[[MIDDLE_BLOCK]] ], [ [[BASE]], %[[ENTRY]] ]
189+
; VEC-NEXT: br label %[[FOR_BODY:.*]]
190+
; VEC: [[FOR_BODY]]:
191+
; VEC-NEXT: [[INC_PHI:%.*]] = phi i32 [ [[BC_RESUME_VAL]], %[[SCALAR_PH]] ], [ [[INC:%.*]], %[[FOR_BODY]] ]
192+
; VEC-NEXT: [[INC_LAG1:%.*]] = phi ptr [ [[BC_RESUME_VAL1]], %[[SCALAR_PH]] ], [ [[TMP:%.*]], %[[FOR_BODY]] ]
193+
; VEC-NEXT: [[INC_LAG2:%.*]] = phi ptr [ [[SCALAR_RECUR_INIT]], %[[SCALAR_PH]] ], [ [[INC_LAG1]], %[[FOR_BODY]] ]
194+
; VEC-NEXT: [[TMP]] = getelementptr inbounds i32, ptr [[INC_LAG1]], i64 1
195+
; VEC-NEXT: [[INC]] = add nsw i32 [[INC_PHI]], 1
196+
; VEC-NEXT: [[CMP:%.*]] = icmp eq i32 [[INC]], [[K]]
197+
; VEC-NEXT: br i1 [[CMP]], label %[[FOR_END]], label %[[FOR_BODY]], {{!llvm.loop ![0-9]+}}
198+
; VEC: [[FOR_END]]:
199+
; VEC-NEXT: [[INC_LAG1_LCSSA:%.*]] = phi ptr [ [[INC_LAG1]], %[[FOR_BODY]] ], [ [[IND_ESCAPE]], %[[MIDDLE_BLOCK]] ]
200+
; VEC-NEXT: ret ptr [[INC_LAG1_LCSSA]]
201+
;
202+
; INTERLEAVE-LABEL: define ptr @both(
203+
; INTERLEAVE-SAME: ptr [[P:%.*]], i32 [[K:%.*]]) {
204+
; INTERLEAVE-NEXT: [[ENTRY:.*]]:
205+
; INTERLEAVE-NEXT: [[BASE:%.*]] = getelementptr inbounds i32, ptr [[P]], i64 1
206+
; INTERLEAVE-NEXT: [[TMP0:%.*]] = add i32 [[K]], -1
207+
; INTERLEAVE-NEXT: [[TMP1:%.*]] = zext i32 [[TMP0]] to i64
208+
; INTERLEAVE-NEXT: [[TMP2:%.*]] = add nuw nsw i64 [[TMP1]], 1
209+
; INTERLEAVE-NEXT: [[MIN_ITERS_CHECK:%.*]] = icmp ult i64 [[TMP2]], 2
210+
; INTERLEAVE-NEXT: br i1 [[MIN_ITERS_CHECK]], label %[[SCALAR_PH:.*]], label %[[VECTOR_PH:.*]]
211+
; INTERLEAVE: [[VECTOR_PH]]:
212+
; INTERLEAVE-NEXT: [[N_MOD_VF:%.*]] = urem i64 [[TMP2]], 2
213+
; INTERLEAVE-NEXT: [[N_VEC:%.*]] = sub i64 [[TMP2]], [[N_MOD_VF]]
214+
; INTERLEAVE-NEXT: [[TMP3:%.*]] = trunc i64 [[N_VEC]] to i32
215+
; INTERLEAVE-NEXT: [[TMP6:%.*]] = mul i64 [[N_VEC]], 4
216+
; INTERLEAVE-NEXT: [[NEXT_GEP:%.*]] = getelementptr i8, ptr [[BASE]], i64 [[TMP6]]
217+
; INTERLEAVE-NEXT: br label %[[VECTOR_BODY:.*]]
218+
; INTERLEAVE: [[VECTOR_BODY]]:
219+
; INTERLEAVE-NEXT: [[INDEX:%.*]] = phi i64 [ 0, %[[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], %[[VECTOR_BODY]] ]
220+
; INTERLEAVE-NEXT: [[OFFSET_IDX:%.*]] = mul i64 [[INDEX]], 4
221+
; INTERLEAVE-NEXT: [[TMP8:%.*]] = add i64 [[OFFSET_IDX]], 4
222+
; INTERLEAVE-NEXT: [[NEXT_GEP1:%.*]] = getelementptr i8, ptr [[BASE]], i64 [[TMP8]]
223+
; INTERLEAVE-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 2
224+
; INTERLEAVE-NEXT: [[TMP7:%.*]] = icmp eq i64 [[INDEX_NEXT]], [[N_VEC]]
225+
; INTERLEAVE-NEXT: br i1 [[TMP7]], label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]], {{!llvm.loop ![0-9]+}}
226+
; INTERLEAVE: [[MIDDLE_BLOCK]]:
227+
; INTERLEAVE-NEXT: [[CMP_N:%.*]] = icmp eq i64 [[TMP2]], [[N_VEC]]
228+
; INTERLEAVE-NEXT: [[IND_ESCAPE:%.*]] = getelementptr i8, ptr [[NEXT_GEP]], i64 -4
229+
; INTERLEAVE-NEXT: br i1 [[CMP_N]], label %[[FOR_END:.*]], label %[[SCALAR_PH]]
230+
; INTERLEAVE: [[SCALAR_PH]]:
231+
; INTERLEAVE-NEXT: [[BC_RESUME_VAL:%.*]] = phi i32 [ [[TMP3]], %[[MIDDLE_BLOCK]] ], [ 0, %[[ENTRY]] ]
232+
; INTERLEAVE-NEXT: [[BC_RESUME_VAL1:%.*]] = phi ptr [ [[NEXT_GEP]], %[[MIDDLE_BLOCK]] ], [ [[BASE]], %[[ENTRY]] ]
233+
; INTERLEAVE-NEXT: [[SCALAR_RECUR_INIT:%.*]] = phi ptr [ [[NEXT_GEP1]], %[[MIDDLE_BLOCK]] ], [ [[BASE]], %[[ENTRY]] ]
234+
; INTERLEAVE-NEXT: br label %[[FOR_BODY:.*]]
235+
; INTERLEAVE: [[FOR_BODY]]:
236+
; INTERLEAVE-NEXT: [[INC_PHI:%.*]] = phi i32 [ [[BC_RESUME_VAL]], %[[SCALAR_PH]] ], [ [[INC:%.*]], %[[FOR_BODY]] ]
237+
; INTERLEAVE-NEXT: [[INC_LAG1:%.*]] = phi ptr [ [[BC_RESUME_VAL1]], %[[SCALAR_PH]] ], [ [[TMP:%.*]], %[[FOR_BODY]] ]
238+
; INTERLEAVE-NEXT: [[INC_LAG2:%.*]] = phi ptr [ [[SCALAR_RECUR_INIT]], %[[SCALAR_PH]] ], [ [[INC_LAG1]], %[[FOR_BODY]] ]
239+
; INTERLEAVE-NEXT: [[TMP]] = getelementptr inbounds i32, ptr [[INC_LAG1]], i64 1
240+
; INTERLEAVE-NEXT: [[INC]] = add nsw i32 [[INC_PHI]], 1
241+
; INTERLEAVE-NEXT: [[CMP:%.*]] = icmp eq i32 [[INC]], [[K]]
242+
; INTERLEAVE-NEXT: br i1 [[CMP]], label %[[FOR_END]], label %[[FOR_BODY]], {{!llvm.loop ![0-9]+}}
243+
; INTERLEAVE: [[FOR_END]]:
244+
; INTERLEAVE-NEXT: [[INC_LAG1_LCSSA:%.*]] = phi ptr [ [[INC_LAG1]], %[[FOR_BODY]] ], [ [[IND_ESCAPE]], %[[MIDDLE_BLOCK]] ]
245+
; INTERLEAVE-NEXT: ret ptr [[INC_LAG1_LCSSA]]
199246
;
200247
entry:
201-
%base = getelementptr inbounds i32, ptr undef, i64 1
248+
%base = getelementptr inbounds i32, ptr %p, i64 1
202249
br label %for.body
203250

204251
for.body:
205252
%inc.phi = phi i32 [ 0, %entry ], [ %inc, %for.body ]
206253
%inc.lag1 = phi ptr [ %base, %entry ], [ %tmp, %for.body]
207-
%inc.lag2 = phi ptr [ undef, %entry ], [ %inc.lag1, %for.body]
254+
%inc.lag2 = phi ptr [ %base, %entry ], [ %inc.lag1, %for.body]
208255
%tmp = getelementptr inbounds i32, ptr %inc.lag1, i64 1
209256
%inc = add nsw i32 %inc.phi, 1
210257
%cmp = icmp eq i32 %inc, %k

0 commit comments

Comments
 (0)