[llvm] [LV] Tidy up early bail outs related to runtime checks (PR #228077)
David Sherwood via llvm-commits
llvm-commits at lists.llvm.org
Fri Oct 2 07:24:00 PDT 2026
https://github.com/david-arm updated https://github.com/llvm/llvm-project/pull/228077
>From 5411920cc0c67f5ce903962f0e17b080f49467cf Mon Sep 17 00:00:00 2001
From: David Sherwood <david.sherwood at arm.com>
Date: Thu, 1 Oct 2026 13:38:12 +0000
Subject: [PATCH 1/2] [LV] Tidy up early bail outs related to runtime checks
There was no debug or error reporting when bailing out due to
proving at compile time that we will fail the SCEV checks. I've
added debug and a report for this. Also, the early bail out for
runtime memory checks has no corresponding test and I cannot
find any test that breaks when I remove it. I also cannot
expose this code path when building the LLVM test suite, so I've
removed it as dead code.
---
llvm/lib/Transforms/Vectorize/LoopVectorize.cpp | 10 ++++++----
.../AArch64/runtime-check-size-based-threshold.ll | 6 +++++-
2 files changed, 11 insertions(+), 5 deletions(-)
diff --git a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
index b3db2f8de74327..df07ed2259e853 100644
--- a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
+++ b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
@@ -7922,11 +7922,13 @@ bool LoopVectorizePass::processLoop(Loop *L) {
// fail. In that case, the vector loop would never execute.
using namespace llvm::PatternMatch;
if (Checks.getSCEVChecks().first &&
- match(Checks.getSCEVChecks().first, m_One()))
- return false;
- if (Checks.getMemRuntimeChecks().first &&
- match(Checks.getMemRuntimeChecks().first, m_One()))
+ match(Checks.getSCEVChecks().first, m_One())) {
+ reportVectorizationFailure(
+ "runtime checks are known to fail, so we will never enter the "
+ "vector loop",
+ "RuntimeChecksNeverEnterVectorLoop", ORE, L);
return false;
+ }
}
// Check if it is profitable to vectorize with runtime checks.
diff --git a/llvm/test/Transforms/LoopVectorize/AArch64/runtime-check-size-based-threshold.ll b/llvm/test/Transforms/LoopVectorize/AArch64/runtime-check-size-based-threshold.ll
index 9ded4ccc2822cd..df4750abd6b4ad 100644
--- a/llvm/test/Transforms/LoopVectorize/AArch64/runtime-check-size-based-threshold.ll
+++ b/llvm/test/Transforms/LoopVectorize/AArch64/runtime-check-size-based-threshold.ll
@@ -1,7 +1,9 @@
; RUN: opt -passes=loop-vectorize -mtriple=arm64-apple-iphoneos -vectorizer-min-trip-count=8 \
; RUN: -enable-epilogue-vectorization=false -S %s | FileCheck --check-prefixes=CHECK,DEFAULT %s
; RUN: opt -passes=loop-vectorize -mtriple=arm64-apple-iphoneos -vectorizer-min-trip-count=8 \
-; RUN: -enable-epilogue-vectorization=false -vectorize-memory-check-threshold=1 -S %s | FileCheck --check-prefixes=CHECK,THRESHOLD %s
+; RUN: -enable-epilogue-vectorization=false -vectorize-memory-check-threshold=1 -S %s \
+; RUN: -debug-only=loop-vectorize 2> %t | FileCheck --check-prefixes=CHECK,THRESHOLD %s
+; RUN: cat %t | FileCheck --check-prefix=DEBUG %s
; Tests for loops with large numbers of runtime checks. Check that loops are
; vectorized, if the loop trip counts are large and the impact of the runtime
@@ -12,6 +14,8 @@
; CHECK-LABEL: define {{.*}} @test_tc_too_small
; CHECK-NOT: vector.memcheck
; CHECK-NOT: vector.body
+; DEBUG-LABEL: Checking a loop in 'test_tc_too_small'
+; DEBUG: LV: Not vectorizing: runtime checks are known to fail, so we will never enter the vector loop.
define void @test_tc_too_small(ptr %ptr.1, ptr %ptr.2, ptr %ptr.3, ptr %ptr.4, i64 %off.1, i64 %off.2) {
entry:
br label %loop
>From 9c33074b60e9f53560695fd75f723d4b12a57a97 Mon Sep 17 00:00:00 2001
From: David Sherwood <david.sherwood at arm.com>
Date: Fri, 2 Oct 2026 14:23:06 +0000
Subject: [PATCH 2/2] Address review comments
---
.../Transforms/Vectorize/LoopVectorize.cpp | 6 ++--
.../runtime-check-size-based-threshold.ll | 8 +++---
.../AArch64/runtime-mem-checks-will-fail.ll | 28 +++++++++++++++++++
3 files changed, 36 insertions(+), 6 deletions(-)
create mode 100644 llvm/test/Transforms/LoopVectorize/AArch64/runtime-mem-checks-will-fail.ll
diff --git a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
index df07ed2259e853..f03e470472eaa8 100644
--- a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
+++ b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
@@ -7921,8 +7921,10 @@ bool LoopVectorizePass::processLoop(Loop *L) {
// Bail out early if either the SCEV or memory runtime checks are known to
// fail. In that case, the vector loop would never execute.
using namespace llvm::PatternMatch;
- if (Checks.getSCEVChecks().first &&
- match(Checks.getSCEVChecks().first, m_One())) {
+ if ((Checks.getSCEVChecks().first &&
+ match(Checks.getSCEVChecks().first, m_One())) ||
+ (Checks.getMemRuntimeChecks().first &&
+ match(Checks.getMemRuntimeChecks().first, m_One()))) {
reportVectorizationFailure(
"runtime checks are known to fail, so we will never enter the "
"vector loop",
diff --git a/llvm/test/Transforms/LoopVectorize/AArch64/runtime-check-size-based-threshold.ll b/llvm/test/Transforms/LoopVectorize/AArch64/runtime-check-size-based-threshold.ll
index df4750abd6b4ad..a4110748a8f5a7 100644
--- a/llvm/test/Transforms/LoopVectorize/AArch64/runtime-check-size-based-threshold.ll
+++ b/llvm/test/Transforms/LoopVectorize/AArch64/runtime-check-size-based-threshold.ll
@@ -2,8 +2,8 @@
; RUN: -enable-epilogue-vectorization=false -S %s | FileCheck --check-prefixes=CHECK,DEFAULT %s
; RUN: opt -passes=loop-vectorize -mtriple=arm64-apple-iphoneos -vectorizer-min-trip-count=8 \
; RUN: -enable-epilogue-vectorization=false -vectorize-memory-check-threshold=1 -S %s \
-; RUN: -debug-only=loop-vectorize 2> %t | FileCheck --check-prefixes=CHECK,THRESHOLD %s
-; RUN: cat %t | FileCheck --check-prefix=DEBUG %s
+; RUN: -pass-remarks-analysis=loop-vectorize 2> %t | FileCheck --check-prefixes=CHECK,THRESHOLD %s
+; RUN: cat %t | FileCheck --check-prefix=REMARKS %s
; Tests for loops with large numbers of runtime checks. Check that loops are
; vectorized, if the loop trip counts are large and the impact of the runtime
@@ -14,8 +14,8 @@
; CHECK-LABEL: define {{.*}} @test_tc_too_small
; CHECK-NOT: vector.memcheck
; CHECK-NOT: vector.body
-; DEBUG-LABEL: Checking a loop in 'test_tc_too_small'
-; DEBUG: LV: Not vectorizing: runtime checks are known to fail, so we will never enter the vector loop.
+; REMARKS: remark: <unknown>:0:0: loop not vectorized: too many memory checks needed
+; REMARKS: remark: <unknown>:0:0: loop not vectorized: runtime checks are known to fail, so we will never enter the vector loop
define void @test_tc_too_small(ptr %ptr.1, ptr %ptr.2, ptr %ptr.3, ptr %ptr.4, i64 %off.1, i64 %off.2) {
entry:
br label %loop
diff --git a/llvm/test/Transforms/LoopVectorize/AArch64/runtime-mem-checks-will-fail.ll b/llvm/test/Transforms/LoopVectorize/AArch64/runtime-mem-checks-will-fail.ll
new file mode 100644
index 00000000000000..2a1c597f662bf0
--- /dev/null
+++ b/llvm/test/Transforms/LoopVectorize/AArch64/runtime-mem-checks-will-fail.ll
@@ -0,0 +1,28 @@
+; RUN: opt -passes=loop-vectorize -S -pass-remarks-analysis=loop-vectorize < %s 2>&1 | FileCheck %s
+
+target datalayout = "e-m:o-i64:64-i128:128-n32:64-S128"
+target triple = "arm64-apple-macosx"
+
+; CHECK: remark: <unknown>:0:0: loop not vectorized: runtime checks are known to fail, so we will never enter the vector loop
+define void @foo(ptr %a, i64 %off, i64 %n) {
+entry:
+ br label %loop
+
+loop:
+ %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
+ %iv.off = add i64 %iv, %off
+ %p.off = getelementptr i32, ptr %a, i64 %iv.off
+ %v0 = load i32, ptr %p.off
+ %p0 = getelementptr i32, ptr %a, i64 %iv
+ %v1 = load i16, ptr %p0
+ %v1.ext = sext i16 %v1 to i32
+ %s = add i32 %v0, %v1.ext
+ %iv.next = add i64 %iv, 1
+ %p1 = getelementptr i32, ptr %a, i64 %iv.next
+ store i32 %s, ptr %p1
+ %ec = icmp eq i64 %iv.next, %n
+ br i1 %ec, label %exit, label %loop
+
+exit:
+ ret void
+}
More information about the llvm-commits
mailing list