[llvm] [LV][NFC] Fix erroneous debug message emitted during legality checks (PR #226162)

via llvm-commits llvm-commits at lists.llvm.org
Thu Sep 24 06:29:43 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-llvm-transforms

Author: David Sherwood (david-arm)

<details>
<summary>Changes</summary>

We erroneously state that we can vectorise the loop, since LoopVectorizationLegality is no longer the oracle in matters of legality. Many of the legality checks have been moved to vplan construction, such as when attempting to vectorise some early exit loops. It's very confusing to see debug output that says:

We can vectorize this loop.
Not vectorising the loop because of ...

I've updated the debug message to be more ambiguous.

After this patch I intend to follow up with another one to fix the equally incorrect

LV: Vectorization is possible but not beneficial.

debug message, which assumes the reason for choosing a scalar VF is because of the cost model. However, for some early exit loops we simply failed to create any vector vplans!

---
Full diff: https://github.com/llvm/llvm-project/pull/226162.diff


6 Files Affected:

- (modified) llvm/lib/Transforms/Vectorize/LoopVectorizationLegality.cpp (+1-1) 
- (modified) llvm/lib/Transforms/Vectorize/LoopVectorize.cpp (+3) 
- (modified) llvm/test/Transforms/LoopVectorize/ARM/arm-ieee-vectorize.ll (+12-12) 
- (modified) llvm/test/Transforms/LoopVectorize/X86/already-vectorized.ll (+1-1) 
- (modified) llvm/test/Transforms/LoopVectorize/early_exit_legality.ll (+15-8) 
- (modified) llvm/test/Transforms/LoopVectorize/early_exit_store_legality.ll (+18-10) 


``````````diff
diff --git a/llvm/lib/Transforms/Vectorize/LoopVectorizationLegality.cpp b/llvm/lib/Transforms/Vectorize/LoopVectorizationLegality.cpp
index 953b1a41e9ee22..85d3cabc1feed1 100644
--- a/llvm/lib/Transforms/Vectorize/LoopVectorizationLegality.cpp
+++ b/llvm/lib/Transforms/Vectorize/LoopVectorizationLegality.cpp
@@ -1985,7 +1985,7 @@ bool LoopVectorizationLegality::canVectorize(bool UseVPlanNativePath) {
   }
 
   if (Result) {
-    LLVM_DEBUG(dbgs() << "LV: We can vectorize this loop"
+    LLVM_DEBUG(dbgs() << "LV: We may be able to vectorize this loop"
                       << (LAI->getRuntimePointerChecking()->Need
                               ? " (with a runtime bound check)"
                               : "")
diff --git a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
index d929af8afbd1da..3a3179baffc574 100644
--- a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
+++ b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
@@ -5369,6 +5369,9 @@ void LoopVectorizationPlanner::plan(ElementCount UserVF, unsigned UserIC) {
   if (!VPlan1)
     return;
 
+  LLVM_DEBUG(dbgs() << "LV: VPlan created successfully. Loop can be "
+                       "vectorized.\n");
+
   if (!OrigLoop->isInnermost()) {
     // For outer loops, computeMaxVF returns a single non-scalar VF; build a
     // plan for that VF only.
diff --git a/llvm/test/Transforms/LoopVectorize/ARM/arm-ieee-vectorize.ll b/llvm/test/Transforms/LoopVectorize/ARM/arm-ieee-vectorize.ll
index dcdbb0dcc0d753..dc2809fc1fc6c3 100644
--- a/llvm/test/Transforms/LoopVectorize/ARM/arm-ieee-vectorize.ll
+++ b/llvm/test/Transforms/LoopVectorize/ARM/arm-ieee-vectorize.ll
@@ -15,7 +15,7 @@ target datalayout = "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64"
 
 ; Integer loops are always vectorizeable
 ; CHECK: Checking a loop in 'sumi'
-; CHECK: We can vectorize this loop!
+; CHECK: We may be able to vectorize this loop!
 define void @sumi(ptr noalias nocapture readonly %A, ptr noalias nocapture readonly %B, ptr noalias nocapture %C, i32 %N) {
 entry:
   %cmp5 = icmp eq i32 %N, 0
@@ -48,9 +48,9 @@ for.end:
 ; LINUX: Checking a loop in 'sumf'
 ; LINUX: Potentially unsafe FP op prevents vectorization
 ; MVE: Checking a loop in 'sumf'
-; MVE: We can vectorize this loop!
+; MVE: We may be able to vectorize this loop!
 ; DARWIN: Checking a loop in 'sumf'
-; DARWIN: We can vectorize this loop!
+; DARWIN: We may be able to vectorize this loop!
 define void @sumf(ptr noalias nocapture readonly %A, ptr noalias nocapture readonly %B, ptr noalias nocapture %C, i32 %N) {
 entry:
   %cmp5 = icmp eq i32 %N, 0
@@ -81,7 +81,7 @@ for.end:
 
 ; Integer loops are always vectorizeable
 ; CHECK: Checking a loop in 'redi'
-; CHECK: We can vectorize this loop!
+; CHECK: We may be able to vectorize this loop!
 define i32 @redi(ptr noalias nocapture readonly %a, ptr noalias nocapture readonly %b, i32 %N) {
 entry:
   br label %for.body.preheader
@@ -114,9 +114,9 @@ for.end:
 ; LINUX: Checking a loop in 'redf'
 ; LINUX: Potentially unsafe FP op prevents vectorization
 ; MVE: Checking a loop in 'redf'
-; MVE: We can vectorize this loop!
+; MVE: We may be able to vectorize this loop!
 ; DARWIN: Checking a loop in 'redf'
-; DARWIN: We can vectorize this loop!
+; DARWIN: We may be able to vectorize this loop!
 define float @redf(ptr noalias nocapture readonly %a, ptr noalias nocapture readonly %b, i32 %N) {
 entry:
   br label %for.body.preheader
@@ -149,7 +149,7 @@ for.end:
 ; LINUX: Checking a loop in 'fabs'
 ; LINUX: Potentially unsafe FP op prevents vectorization
 ; DARWIN: Checking a loop in 'fabs'
-; DARWIN: We can vectorize this loop!
+; DARWIN: We may be able to vectorize this loop!
 define void @fabs(ptr noalias nocapture readonly %A, ptr noalias nocapture readonly %B, ptr noalias nocapture %C, i32 %N) {
 entry:
   %cmp10 = icmp eq i32 %N, 0
@@ -175,7 +175,7 @@ for.end:
 
 ; Integer loops are always vectorizeable
 ; CHECK: Checking a loop in 'sumi_fast'
-; CHECK: We can vectorize this loop!
+; CHECK: We may be able to vectorize this loop!
 define void @sumi_fast(ptr noalias nocapture readonly %A, ptr noalias nocapture readonly %B, ptr noalias nocapture %C, i32 %N) {
 entry:
   %cmp5 = icmp eq i32 %N, 0
@@ -206,7 +206,7 @@ for.end:
 
 ; Floating-point loops can be vectorizeable with fast-math
 ; CHECK: Checking a loop in 'sumf_fast'
-; CHECK: We can vectorize this loop!
+; CHECK: We may be able to vectorize this loop!
 define void @sumf_fast(ptr noalias nocapture readonly %A, ptr noalias nocapture readonly %B, ptr noalias nocapture %C, i32 %N) {
 entry:
   %cmp5 = icmp eq i32 %N, 0
@@ -237,7 +237,7 @@ for.end:
 
 ; Integer loops are always vectorizeable
 ; CHECK: Checking a loop in 'redi_fast'
-; CHECK: We can vectorize this loop!
+; CHECK: We may be able to vectorize this loop!
 define i32 @redi_fast(ptr noalias nocapture readonly %a, ptr noalias nocapture readonly %b, i32 %N) {
 entry:
   %cmp5 = icmp eq i32 %N, 0
@@ -270,7 +270,7 @@ for.end:
 
 ; Floating-point loops can be vectorizeable with fast-math
 ; CHECK: Checking a loop in 'redf_fast'
-; CHECK: We can vectorize this loop!
+; CHECK: We may be able to vectorize this loop!
 define float @redf_fast(ptr noalias nocapture readonly %a, ptr noalias nocapture readonly %b, i32 %N) {
 entry:
   br label %for.body.preheader
@@ -301,7 +301,7 @@ for.end:
 
 ; Make sure calls that turn into builtins are also covered
 ; CHECK: Checking a loop in 'fabs_fast'
-; CHECK: We can vectorize this loop!
+; CHECK: We may be able to vectorize this loop!
 define void @fabs_fast(ptr noalias nocapture readonly %A, ptr noalias nocapture readonly %B, ptr noalias nocapture %C, i32 %N) {
 entry:
   %cmp10 = icmp eq i32 %N, 0
diff --git a/llvm/test/Transforms/LoopVectorize/X86/already-vectorized.ll b/llvm/test/Transforms/LoopVectorize/X86/already-vectorized.ll
index 2d960ddaebac25..67494fb7bec2d0 100644
--- a/llvm/test/Transforms/LoopVectorize/X86/already-vectorized.ll
+++ b/llvm/test/Transforms/LoopVectorize/X86/already-vectorized.ll
@@ -19,7 +19,7 @@ entry:
 for.body:
 ; We need to make sure we did vectorize the loop
 ; CHECK: LV: Found a loop: for.body
-; CHECK: LV: We can vectorize this loop!
+; CHECK: LV: We may be able to vectorize this loop!
   %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
   %red.05 = phi i32 [ 0, %entry ], [ %add, %for.body ]
   %arrayidx = getelementptr inbounds [255 x i32], ptr @a, i64 0, i64 %indvars.iv
diff --git a/llvm/test/Transforms/LoopVectorize/early_exit_legality.ll b/llvm/test/Transforms/LoopVectorize/early_exit_legality.ll
index 4593cd30f63a4c..503657843f2c90 100644
--- a/llvm/test/Transforms/LoopVectorize/early_exit_legality.ll
+++ b/llvm/test/Transforms/LoopVectorize/early_exit_legality.ll
@@ -13,8 +13,9 @@ declare void @init_mem(ptr, i64) nofree
 define i32 @diff_exit_block_needs_scev_check(i32 %end) {
 ; CHECK-DEBUG-LABEL: LV: Checking a loop in 'diff_exit_block_needs_scev_check'
 ; CHECK-DEBUG:       Found an early exit loop with symbolic max backedge taken count: (-1 + (1 umax (zext i10 (trunc i32 %end to i10) to i32)))<nsw>
-; CHECK-DEBUG-NEXT:  LV: We can vectorize this loop!
+; CHECK-DEBUG-NEXT:  LV: We may be able to vectorize this loop!
 ; CHECK-DEBUG-NOT:   LV: Not vectorizing:
+; CHECK-DEBUG:       LV: VPlan created successfully. Loop can be vectorized.
 entry:
   %p1 = alloca [1024 x i32]
   %p2 = alloca [1024 x i32]
@@ -51,8 +52,9 @@ exit:
 define i64 @same_exit_block_pre_inc_use1() {
 ; CHECK-DEBUG-LABEL: LV: Checking a loop in 'same_exit_block_pre_inc_use1'
 ; CHECK-DEBUG:       LV: Found an early exit loop with symbolic max backedge taken count: 63
-; CHECK-DEBUG-NEXT:  LV: We can vectorize this loop!
+; CHECK-DEBUG-NEXT:  LV: We may be able to vectorize this loop!
 ; CHECK-DEBUG-NOT:   LV: Not vectorizing
+; CHECK-DEBUG:       LV: VPlan created successfully. Loop can be vectorized.
 entry:
   %p1 = alloca [1024 x i8]
   %p2 = alloca [1024 x i8]
@@ -83,7 +85,8 @@ loop.end:
 define i64 @loop_contains_safe_call() {
 ; CHECK-DEBUG-LABEL: LV: Checking a loop in 'loop_contains_safe_call'
 ; CHECK-DEBUG:       LV: Found an early exit loop with symbolic max backedge taken count: 63
-; CHECK-DEBUG-NEXT:  LV: We can vectorize this loop!
+; CHECK-DEBUG-NEXT:  LV: We may be able to vectorize this loop!
+; CHECK-DEBUG:       LV: VPlan created successfully. Loop can be vectorized.
 entry:
   %p1 = alloca [1024 x i8]
   %p2 = alloca [1024 x i8]
@@ -113,7 +116,8 @@ loop.end:
 define i64 @loop_contains_safe_div() {
 ; CHECK-DEBUG-LABEL: LV: Checking a loop in 'loop_contains_safe_div'
 ; CHECK-DEBUG:       LV: Found an early exit loop with symbolic max backedge taken count: 63
-; CHECK-DEBUG-NEXT:  LV: We can vectorize this loop!
+; CHECK-DEBUG-NEXT:  LV: We may be able to vectorize this loop!
+; CHECK-DEBUG:       LV: VPlan created successfully. Loop can be vectorized.
 entry:
   %p1 = alloca [1024 x i8]
   %p2 = alloca [1024 x i8]
@@ -143,8 +147,9 @@ loop.end:
 define i64 @loop_contains_load_after_early_exit(ptr dereferenceable(1024) align(8) %p2) {
 ; CHECK-DEBUG-LABEL: LV: Checking a loop in 'loop_contains_load_after_early_exit'
 ; CHECK-DEBUG:       LV: Found an early exit loop with symbolic max backedge taken count: 63
-; CHECK-DEBUG-NEXT:  LV: We can vectorize this loop!
+; CHECK-DEBUG-NEXT:  LV: We may be able to vectorize this loop!
 ; CHECK-DEBUG-NOT:   LV: Not vectorizing
+; CHECK-DEBUG:       LV: VPlan created successfully. Loop can be vectorized.
 entry:
   %p1 = alloca [1024 x i8]
   call void @init_mem(ptr %p1, i64 1024)
@@ -173,7 +178,7 @@ loop.end:
 define i64 @one_uncountable_two_countable_same_exit_phi_of_consts() !dbg !39 {
 ; CHECK-DEBUG-LABEL: LV: Checking a loop in 'one_uncountable_two_countable_same_exit_phi_of_consts'
 ; CHECK-DEBUG:       LV: Found an early exit loop with symbolic max backedge taken count: 61
-; CHECK-DEBUG-NEXT:  LV: We can vectorize this loop!
+; CHECK-DEBUG-NEXT:  LV: We may be able to vectorize this loop!
 ; CHECK-DEBUG-NEXT:  LV: Not vectorizing: Auto-vectorization of early exit loops requiring a scalar epilogue is unsupported.
 ; CHECK-REMARK:      foo.c:60:3: loop not vectorized: Auto-vectorization of early exit loops requiring a scalar epilogue is unsupported
 entry:
@@ -358,7 +363,8 @@ loop.end:
 ; Multiple uncountable early exits are now supported.
 define i64 @multiple_uncountable_exits() {
 ; CHECK-DEBUG-LABEL: LV: Checking a loop in 'multiple_uncountable_exits'
-; CHECK-DEBUG:       LV: We can vectorize this loop!
+; CHECK-DEBUG:       LV: We may be able to vectorize this loop!
+; CHECK-DEBUG:       LV: VPlan created successfully. Loop can be vectorized.
 entry:
   %p1 = alloca [1024 x i8]
   %p2 = alloca [1024 x i8]
@@ -612,7 +618,8 @@ loop.end:
 ; This is now supported with predicated early exits.
 define i64 @uncountable_exits_on_parallel_branches() {
 ; CHECK-DEBUG-LABEL: LV: Checking a loop in 'uncountable_exits_on_parallel_branches'
-; CHECK-DEBUG:       LV: We can vectorize this loop!
+; CHECK-DEBUG:       LV: We may be able to vectorize this loop!
+; CHECK-DEBUG:       LV: VPlan created successfully. Loop can be vectorized.
 entry:
   %p1 = alloca [1024 x i8]
   %p2 = alloca [1024 x i8]
diff --git a/llvm/test/Transforms/LoopVectorize/early_exit_store_legality.ll b/llvm/test/Transforms/LoopVectorize/early_exit_store_legality.ll
index 71650a4c365673..653121fa5f306d 100644
--- a/llvm/test/Transforms/LoopVectorize/early_exit_store_legality.ll
+++ b/llvm/test/Transforms/LoopVectorize/early_exit_store_legality.ll
@@ -34,7 +34,8 @@ loop.end:
 
 define void @loop_contains_store_condition_load_has_single_user(ptr dereferenceable(40) noalias %array, ptr align 2 dereferenceable(40) readonly %pred) {
 ; CHECK-DEBUG-LABEL: LV: Checking a loop in 'loop_contains_store_condition_load_has_single_user'
-; CHECK-DEBUG:       LV: We can vectorize this loop!
+; CHECK-DEBUG:       LV: We may be able to vectorize this loop!
+; CHECK-DEBUG:       LV: VPlan created successfully. Loop can be vectorized.
 entry:
   br label %for.body
 
@@ -88,7 +89,8 @@ exit:
 ;; Exit-condition load on the RHS of the icmp must still be accepted.
 define void @swapped_cmp_operands(ptr noalias %array, ptr %pred) {
 ; CHECK-DEBUG-LABEL: LV: Checking a loop in 'swapped_cmp_operands'
-; CHECK-DEBUG:       LV: We can vectorize this loop!
+; CHECK-DEBUG:       LV: We may be able to vectorize this loop!
+; CHECK-DEBUG:       LV: Not vectorizing: Early exit loop with side effects contains load used by the exit condition that may fault.
 entry:
   br label %loop
 
@@ -236,7 +238,8 @@ exit:
 ;; Alternatively, we could use masked.load.ff or vp.load.ff
 define void @loop_contains_store_assumed_bounds(ptr noalias %array, ptr readonly %pred, i64 %n) {
 ; CHECK-DEBUG-LABEL: LV: Checking a loop in 'loop_contains_store_assumed_bounds'
-; CHECK-DEBUG:       LV: We can vectorize this loop!
+; CHECK-DEBUG:       LV: We may be able to vectorize this loop!
+; CHECK-DEBUG:       LV: Not vectorizing: Early exit loop with side effects contains load used by the exit condition that may fault.
 entry:
   %n_bytes = mul nuw nsw i64 %n, 2
   call void @llvm.assume(i1 true) [ "align"(ptr %pred, i64 2), "dereferenceable"(ptr %pred, i64 %n_bytes) ]
@@ -264,7 +267,8 @@ exit:
 
 define void @loop_contains_store_to_pointer_with_no_deref_info(ptr align 2 dereferenceable(40) readonly %load.array, ptr align 2 noalias %array, ptr align 2 dereferenceable(40) readonly %pred) {
 ; CHECK-DEBUG-LABEL: LV: Checking a loop in 'loop_contains_store_to_pointer_with_no_deref_info'
-; CHECK-DEBUG:       LV: We can vectorize this loop!
+; CHECK-DEBUG:       LV: We may be able to vectorize this loop!
+; CHECK-DEBUG:       LV: VPlan created successfully. Loop can be vectorized.
 entry:
   br label %for.body
 
@@ -292,7 +296,8 @@ exit:
 ;; Vectorizeable, requires runtime checks and/or ff loads.
 define void @loop_contains_store_unknown_bounds(ptr align 2 dereferenceable(100) noalias %array, ptr align 2 dereferenceable(100) readonly %pred, i64 %n) {
 ; CHECK-DEBUG-LABEL: LV: Checking a loop in 'loop_contains_store_unknown_bounds'
-; CHECK-DEBUG:       LV: We can vectorize this loop!
+; CHECK-DEBUG:       LV: We may be able to vectorize this loop!
+; CHECK-DEBUG:       LV: Not vectorizing: Early exit loop with side effects contains load used by the exit condition that may fault.
 entry:
   br label %for.body
 
@@ -376,7 +381,8 @@ exit:
 
 define void @loop_contains_store_in_latch_block(ptr dereferenceable(40) noalias %array, ptr align 2 dereferenceable(40) readonly %pred) {
 ; CHECK-DEBUG-LABEL: LV: Checking a loop in 'loop_contains_store_in_latch_block'
-; CHECK-DEBUG:       LV: We can vectorize this loop!
+; CHECK-DEBUG:       LV: We may be able to vectorize this loop!
+; CHECK-DEBUG:       LV: VPlan created successfully. Loop can be vectorized.
 entry:
   br label %for.body
 
@@ -742,7 +748,8 @@ exit:
 
 define i16 @uncountable_exit_with_live_out(ptr dereferenceable(40) noalias %array, ptr align 2 dereferenceable(40) readonly %pred) {
 ; CHECK-DEBUG-LABEL: LV: Checking a loop in 'uncountable_exit_with_live_out'
-; CHECK-DEBUG:       LV: We can vectorize this loop!
+; CHECK-DEBUG:       LV: We may be able to vectorize this loop!
+; CHECK-DEBUG:       LV: VPlan created successfully. Loop can be vectorized.
 entry:
   br label %for.body
 
@@ -769,7 +776,7 @@ exit:
 ; Vectorizeable, requires improvements in dereferenceability checks
 define void @uncountable_exit_with_constant_nonunit_stride(ptr dereferenceable(4000) noalias %array, ptr align 2 dereferenceable(4000) readonly %pred) !dbg !60 {
 ; CHECK-DEBUG-LABEL: LV: Checking a loop in 'uncountable_exit_with_constant_nonunit_stride'
-; CHECK-DEBUG:       LV: We can vectorize this loop!
+; CHECK-DEBUG:       LV: We may be able to vectorize this loop!
 ; CHECK-DEBUG:       LV: Not vectorizing: unable to calculate the loop count due to complex control flow.
 ; CHECK-REMARK:      foo.c:260:3: loop not vectorized: unable to calculate the loop count due to complex control flow
 entry:
@@ -826,7 +833,8 @@ exit:
 
 define i32 @uncountable_exit_with_separate_exit_block(ptr dereferenceable(40) noalias %array, ptr align 2 dereferenceable(40) readonly %pred) {
 ; CHECK-DEBUG-LABEL: LV: Checking a loop in 'uncountable_exit_with_separate_exit_block'
-; CHECK-DEBUG:       LV: We can vectorize this loop!
+; CHECK-DEBUG:       LV: We may be able to vectorize this loop!
+; CHECK-DEBUG:       LV: VPlan created successfully. Loop can be vectorized.
 entry:
   br label %for.body
 
@@ -885,7 +893,7 @@ exit:
 
 define i32 @uncountable_exit_with_masked_ldst_separate_condition(ptr dereferenceable(40) noalias %array, ptr align 2 dereferenceable(40) readonly %pred, ptr align 2 readonly %st.pred) !dbg !66 {
 ; CHECK-DEBUG-LABEL: LV: Checking a loop in 'uncountable_exit_with_masked_ldst_separate_condition'
-; CHECK-DEBUG:       LV: We can vectorize this loop!
+; CHECK-DEBUG:       LV: We may be able to vectorize this loop!
 ; CHECK-DEBUG:       LV: Not vectorizing: Early exit loop with side effects contains unsupported conditional memory operations
 ; CHECK-DEBUG:       LV: Vectorization is possible but not beneficial.
 ; CHECK-REMARK:      foo.c:290:3: loop not vectorized: Early exit loop with side effects contains unsupported conditional memory operations

``````````

</details>


https://github.com/llvm/llvm-project/pull/226162


More information about the llvm-commits mailing list