Skip to content

Commit 0e28c9b

Browse files
committed
[LAA] Skip undef/poison strides in collectStridedAccess.
The map returned by collectStridedAccess is used to replace strides with their versioned values. This does not work for Undef/Poison, which don't have use-lists. Don't try to version them, as versioning won't be useful in practice. Fixes #162922.
1 parent a61e016 commit 0e28c9b

File tree

2 files changed

+97
-0
lines changed

2 files changed

+97
-0
lines changed

llvm/lib/Analysis/LoopAccessAnalysis.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2982,6 +2982,10 @@ void LoopAccessInfo::collectStridedAccess(Value *MemAccess) {
29822982
if (!StrideExpr)
29832983
return;
29842984

2985+
if (auto *Unknown = dyn_cast<SCEVUnknown>(StrideExpr))
2986+
if (isa<UndefValue>(Unknown->getValue()))
2987+
return;
2988+
29852989
LLVM_DEBUG(dbgs() << "LAA: Found a strided access that is a candidate for "
29862990
"versioning:");
29872991
LLVM_DEBUG(dbgs() << " Ptr: " << *Ptr << " Stride: " << *StrideExpr << "\n");

llvm/test/Transforms/LoopVectorize/version-mem-access.ll

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,3 +122,96 @@ loop:
122122
exit:
123123
ret void
124124
}
125+
126+
; Make sure we do not crash when the stride is poison.
127+
; Test for https://github.com/llvm/llvm-project/issues/162922.
128+
define void @stride_poison(ptr %dst) mustprogress {
129+
; CHECK-LABEL: define void @stride_poison(
130+
; CHECK-SAME: ptr [[DST:%.*]]) #[[ATTR0:[0-9]+]] {
131+
; CHECK-NEXT: [[ENTRY:.*:]]
132+
; CHECK-NEXT: [[UMAX:%.*]] = call i64 @llvm.umax.i64(i64 poison, i64 1)
133+
; CHECK-NEXT: [[TMP0:%.*]] = udiv i64 99, [[UMAX]]
134+
; CHECK-NEXT: [[TMP1:%.*]] = add nuw nsw i64 [[TMP0]], 2
135+
; CHECK-NEXT: br label %[[VECTOR_PH:.*]]
136+
; CHECK: [[VECTOR_PH]]:
137+
; CHECK-NEXT: [[N_MOD_VF:%.*]] = urem i64 [[TMP1]], 2
138+
; CHECK-NEXT: [[N_VEC:%.*]] = sub i64 [[TMP1]], [[N_MOD_VF]]
139+
; CHECK-NEXT: [[TMP2:%.*]] = mul i64 [[N_VEC]], poison
140+
; CHECK-NEXT: br label %[[VECTOR_BODY:.*]]
141+
; CHECK: [[VECTOR_BODY]]:
142+
; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, %[[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], %[[VECTOR_BODY]] ]
143+
; CHECK-NEXT: [[OFFSET_IDX:%.*]] = mul i64 [[INDEX]], poison
144+
; CHECK-NEXT: [[TMP3:%.*]] = add i64 [[OFFSET_IDX]], poison
145+
; CHECK-NEXT: [[TMP4:%.*]] = add i64 [[OFFSET_IDX]], poison
146+
; CHECK-NEXT: [[TMP5:%.*]] = getelementptr i8, ptr [[DST]], i64 [[TMP3]]
147+
; CHECK-NEXT: [[TMP6:%.*]] = getelementptr i8, ptr [[DST]], i64 [[TMP4]]
148+
; CHECK-NEXT: store i8 0, ptr [[TMP5]], align 1
149+
; CHECK-NEXT: store i8 0, ptr [[TMP6]], align 1
150+
; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 2
151+
; CHECK-NEXT: [[TMP7:%.*]] = icmp eq i64 [[INDEX_NEXT]], [[N_VEC]]
152+
; CHECK-NEXT: br i1 [[TMP7]], label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]], !llvm.loop [[LOOP6:![0-9]+]]
153+
; CHECK: [[MIDDLE_BLOCK]]:
154+
; CHECK-NEXT: [[CMP_N:%.*]] = icmp eq i64 [[TMP1]], [[N_VEC]]
155+
; CHECK-NEXT: br i1 [[CMP_N]], [[EXIT:label %.*]], label %[[SCALAR_PH:.*]]
156+
; CHECK: [[SCALAR_PH]]:
157+
;
158+
entry:
159+
br label %loop
160+
161+
loop:
162+
%iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
163+
%gep.dst = getelementptr i8, ptr %dst, i64 %iv
164+
store i8 0, ptr %gep.dst, align 1
165+
%iv.next = add nuw nsw i64 %iv, poison
166+
%ec = icmp samesign ult i64 %iv, 100
167+
br i1 %ec, label %loop, label %exit
168+
169+
exit:
170+
ret void
171+
}
172+
173+
; Make sure we do not crash when the stride is undef.
174+
define void @stride_undef(ptr %dst) mustprogress {
175+
; CHECK-LABEL: define void @stride_undef(
176+
; CHECK-SAME: ptr [[DST:%.*]]) #[[ATTR0]] {
177+
; CHECK-NEXT: [[ENTRY:.*:]]
178+
; CHECK-NEXT: [[UMAX:%.*]] = call i64 @llvm.umax.i64(i64 undef, i64 1)
179+
; CHECK-NEXT: [[TMP0:%.*]] = udiv i64 99, [[UMAX]]
180+
; CHECK-NEXT: [[TMP1:%.*]] = add nuw nsw i64 [[TMP0]], 2
181+
; CHECK-NEXT: br label %[[VECTOR_PH:.*]]
182+
; CHECK: [[VECTOR_PH]]:
183+
; CHECK-NEXT: [[N_MOD_VF:%.*]] = urem i64 [[TMP1]], 2
184+
; CHECK-NEXT: [[N_VEC:%.*]] = sub i64 [[TMP1]], [[N_MOD_VF]]
185+
; CHECK-NEXT: [[TMP2:%.*]] = mul i64 [[N_VEC]], undef
186+
; CHECK-NEXT: br label %[[VECTOR_BODY:.*]]
187+
; CHECK: [[VECTOR_BODY]]:
188+
; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, %[[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], %[[VECTOR_BODY]] ]
189+
; CHECK-NEXT: [[OFFSET_IDX:%.*]] = mul i64 [[INDEX]], undef
190+
; CHECK-NEXT: [[TMP3:%.*]] = add i64 [[OFFSET_IDX]], 0
191+
; CHECK-NEXT: [[TMP4:%.*]] = add i64 [[OFFSET_IDX]], undef
192+
; CHECK-NEXT: [[TMP5:%.*]] = getelementptr i8, ptr [[DST]], i64 [[TMP3]]
193+
; CHECK-NEXT: [[TMP6:%.*]] = getelementptr i8, ptr [[DST]], i64 [[TMP4]]
194+
; CHECK-NEXT: store i8 0, ptr [[TMP5]], align 1
195+
; CHECK-NEXT: store i8 0, ptr [[TMP6]], align 1
196+
; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 2
197+
; CHECK-NEXT: [[TMP7:%.*]] = icmp eq i64 [[INDEX_NEXT]], [[N_VEC]]
198+
; CHECK-NEXT: br i1 [[TMP7]], label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]], !llvm.loop [[LOOP8:![0-9]+]]
199+
; CHECK: [[MIDDLE_BLOCK]]:
200+
; CHECK-NEXT: [[CMP_N:%.*]] = icmp eq i64 [[TMP1]], [[N_VEC]]
201+
; CHECK-NEXT: br i1 [[CMP_N]], [[EXIT:label %.*]], label %[[SCALAR_PH:.*]]
202+
; CHECK: [[SCALAR_PH]]:
203+
;
204+
entry:
205+
br label %loop
206+
207+
loop:
208+
%iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
209+
%gep.dst = getelementptr i8, ptr %dst, i64 %iv
210+
store i8 0, ptr %gep.dst, align 1
211+
%iv.next = add nuw nsw i64 %iv, undef
212+
%ec = icmp samesign ult i64 %iv, 100
213+
br i1 %ec, label %loop, label %exit
214+
215+
exit:
216+
ret void
217+
}

0 commit comments

Comments
 (0)