Skip to content

Commit 45c0b29

Browse files
[LV] Ignore user-specified interleave count when unsafe. (#153009)
When an VF is specified via a loop hint, it will be clamped to a safe VF or ignored if it is found to be unsafe. This is not the case for user-specified interleave counts, which can lead to loops such as the following with a memory dependence being vectorised with interleaving: ``` #pragma clang loop interleave_count(4) for (int i = 4; i < LEN; i++) b[i] = b[i - 4] + a[i]; ``` According to [1], loop hints are ignored if they are not safe to apply. This patch adds a check to prevent vectorisation with interleaving if isSafeForAnyVectorWidth() returns false. This is already checked in selectInterleaveCount(). [1] https://llvm.org/docs/LangRef.html#llvm-loop-vectorize-and-llvm-loop-interleave
1 parent f7bbcde commit 45c0b29

File tree

3 files changed

+46
-10
lines changed

3 files changed

+46
-10
lines changed

llvm/lib/Transforms/Vectorize/LoopVectorize.cpp

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9860,6 +9860,8 @@ bool LoopVectorizePass::processLoop(Loop *L) {
98609860
// Get user vectorization factor and interleave count.
98619861
ElementCount UserVF = Hints.getWidth();
98629862
unsigned UserIC = Hints.getInterleave();
9863+
if (UserIC > 1 && !LVL.isSafeForAnyVectorWidth())
9864+
UserIC = 1;
98639865

98649866
// Plan how to best vectorize.
98659867
LVP.plan(UserVF, UserIC);
@@ -9924,7 +9926,15 @@ bool LoopVectorizePass::processLoop(Loop *L) {
99249926
VectorizeLoop = false;
99259927
}
99269928

9927-
if (!LVP.hasPlanWithVF(VF.Width) && UserIC > 1) {
9929+
if (UserIC == 1 && Hints.getInterleave() > 1) {
9930+
assert(!LVL.isSafeForAnyVectorWidth() &&
9931+
"UserIC should only be ignored due to unsafe dependencies");
9932+
LLVM_DEBUG(dbgs() << "LV: Ignoring user-specified interleave count.\n");
9933+
IntDiagMsg = {"InterleavingUnsafe",
9934+
"Ignoring user-specified interleave count due to possibly "
9935+
"unsafe dependencies in the loop."};
9936+
InterleaveLoop = false;
9937+
} else if (!LVP.hasPlanWithVF(VF.Width) && UserIC > 1) {
99289938
// Tell the user interleaving was avoided up-front, despite being explicitly
99299939
// requested.
99309940
LLVM_DEBUG(dbgs() << "LV: Ignoring UserIC, because vectorization and "

llvm/test/Transforms/LoopVectorize/AArch64/scalable-reductions.ll

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -417,21 +417,17 @@ for.end: ; preds = %for.body, %entry
417417

418418
; Note: This test was added to ensure we always check the legality of reductions (end emit a warning if necessary) before checking for memory dependencies
419419
; CHECK-REMARK: Scalable vectorization not supported for the reduction operations found in this loop.
420-
; CHECK-REMARK: vectorized loop (vectorization width: 4, interleaved count: 2)
420+
; CHECK-REMARK: Ignoring user-specified interleave count due to possibly unsafe dependencies in the loop.
421+
; CHECK-REMARK: vectorized loop (vectorization width: 4, interleaved count: 1)
421422
define i32 @memory_dependence(ptr noalias nocapture %a, ptr noalias nocapture readonly %b, i64 %n) {
422423
; CHECK-LABEL: @memory_dependence
423424
; CHECK: vector.body:
424425
; CHECK: %[[LOAD1:.*]] = load <4 x i32>
425426
; CHECK: %[[LOAD2:.*]] = load <4 x i32>
426-
; CHECK: %[[LOAD3:.*]] = load <4 x i32>
427-
; CHECK: %[[LOAD4:.*]] = load <4 x i32>
428-
; CHECK: %[[ADD1:.*]] = add nsw <4 x i32> %[[LOAD3]], %[[LOAD1]]
429-
; CHECK: %[[ADD2:.*]] = add nsw <4 x i32> %[[LOAD4]], %[[LOAD2]]
430-
; CHECK: %[[MUL1:.*]] = mul <4 x i32> %[[LOAD3]]
431-
; CHECK: %[[MUL2:.*]] = mul <4 x i32> %[[LOAD4]]
427+
; CHECK: %[[ADD1:.*]] = add nsw <4 x i32> %[[LOAD2]], %[[LOAD1]]
428+
; CHECK: %[[MUL1:.*]] = mul <4 x i32> %[[LOAD2]]
432429
; CHECK: middle.block:
433-
; CHECK: %[[RDX:.*]] = mul <4 x i32> %[[MUL2]], %[[MUL1]]
434-
; CHECK: call i32 @llvm.vector.reduce.mul.v4i32(<4 x i32> %[[RDX]])
430+
; CHECK: call i32 @llvm.vector.reduce.mul.v4i32(<4 x i32> %[[MUL1]])
435431
entry:
436432
br label %for.body
437433

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
; RUN: opt -passes=loop-vectorize -pass-remarks-analysis=loop-vectorize -S < %s 2>&1 | FileCheck %s
2+
3+
; Make sure the unsafe user specified interleave count is ignored.
4+
5+
; CHECK: remark: <unknown>:0:0: Ignoring user-specified interleave count due to possibly unsafe dependencies in the loop.
6+
; CHECK-LABEL: @loop_distance_4
7+
define void @loop_distance_4(ptr %a, ptr %b) {
8+
entry:
9+
br label %loop
10+
11+
loop:
12+
%iv = phi i64 [ 4, %entry ], [ %iv.next, %loop ]
13+
%0 = getelementptr i32, ptr %b, i64 %iv
14+
%arrayidx = getelementptr i8, ptr %0, i64 -16
15+
%1 = load i32, ptr %arrayidx, align 4
16+
%arrayidx2 = getelementptr inbounds nuw i32, ptr %a, i64 %iv
17+
%2 = load i32, ptr %arrayidx2, align 4
18+
%add = add nsw i32 %2, %1
19+
store i32 %add, ptr %0, align 4
20+
%iv.next = add nuw nsw i64 %iv, 1
21+
%exitcond.not = icmp eq i64 %iv.next, 64
22+
br i1 %exitcond.not, label %for.end, label %loop, !llvm.loop !1
23+
24+
for.end:
25+
ret void
26+
}
27+
28+
!1 = !{!1, !2, !3}
29+
!2 = !{!"llvm.loop.interleave.count", i32 4}
30+
!3 = !{!"llvm.loop.vectorize.width", i32 4}

0 commit comments

Comments
 (0)