[llvm] [LV] Accept swapped operands in early-exit condition compare (PR #199989)
Madhur Amilkanthwar via llvm-commits
llvm-commits at lists.llvm.org
Thu Jun 11 22:06:07 PDT 2026
https://github.com/madhur13490 updated https://github.com/llvm/llvm-project/pull/199989
>From 9873bc29036feb818d8cac1ba2b45805e457effa Mon Sep 17 00:00:00 2001
From: Madhur Amilkanthwar <madhura at nvidia.com>
Date: Wed, 27 May 2026 00:42:29 -0700
Subject: [PATCH] [LV] Accept swapped operands in early-exit condition compare
Use m_c_ICmp so the load can be on either side of the icmp.
---
.../Vectorize/LoopVectorizationLegality.cpp | 6 ++---
.../early_exit_store_legality.ll | 25 +++++++++++++++++++
2 files changed, 28 insertions(+), 3 deletions(-)
diff --git a/llvm/lib/Transforms/Vectorize/LoopVectorizationLegality.cpp b/llvm/lib/Transforms/Vectorize/LoopVectorizationLegality.cpp
index 214b5cff8a03a..0b81b657a4c07 100644
--- a/llvm/lib/Transforms/Vectorize/LoopVectorizationLegality.cpp
+++ b/llvm/lib/Transforms/Vectorize/LoopVectorizationLegality.cpp
@@ -1788,16 +1788,16 @@ bool LoopVectorizationLegality::canUncountableExitConditionLoadBeMoved(
Instruction *L = nullptr;
Value *Ptr = nullptr;
Value *R = nullptr;
+ // The exit-condition load can appear on either side of the icmp.
if (!match(Br->getCondition(),
- m_OneUse(m_ICmp(m_OneUse(m_Instruction(L, m_Load(m_Value(Ptr)))),
- m_Value(R))))) {
+ m_OneUse(m_c_ICmp(m_OneUse(m_Instruction(L, m_Load(m_Value(Ptr)))),
+ m_Value(R))))) {
reportVectorizationFailure(
"Early exit loop with store but no supported condition load",
"NoConditionLoadForEarlyExitLoop", ORE, TheLoop);
return false;
}
- // FIXME: Don't rely on operand ordering for the comparison.
if (!TheLoop->isLoopInvariant(R)) {
reportVectorizationFailure(
"Early exit loop with store but no supported condition load",
diff --git a/llvm/test/Transforms/LoopVectorize/early_exit_store_legality.ll b/llvm/test/Transforms/LoopVectorize/early_exit_store_legality.ll
index 12065c01d47a4..dfa772887d73e 100644
--- a/llvm/test/Transforms/LoopVectorize/early_exit_store_legality.ll
+++ b/llvm/test/Transforms/LoopVectorize/early_exit_store_legality.ll
@@ -54,6 +54,31 @@ exit:
ret void
}
+;; Exit-condition load on the RHS of the icmp must still be accepted.
+define void @swapped_cmp_operands(ptr noalias %array, ptr %pred) {
+; CHECK-LABEL: LV: Checking a loop in 'swapped_cmp_operands'
+; CHECK: LV: We can vectorize this loop!
+entry:
+ br label %loop
+
+loop:
+ %iv = phi i64 [ 0, %entry ], [ %iv.next, %latch ]
+ %st.addr = getelementptr i16, ptr %array, i64 %iv
+ store i16 0, ptr %st.addr, align 2
+ %ee.addr = getelementptr i16, ptr %pred, i64 %iv
+ %ee.val = load i16, ptr %ee.addr, align 2
+ %ee.cond = icmp slt i16 500, %ee.val
+ br i1 %ee.cond, label %exit, label %latch
+
+latch:
+ %iv.next = add i64 %iv, 1
+ %latch.cond = icmp eq i64 %iv.next, 20
+ br i1 %latch.cond, label %exit, label %loop
+
+exit:
+ ret void
+}
+
;; Avoid vectorization because we will either exit on the first iteration, or
;; never exit early.
;; We shouldn't see IR like this if LV-LICM has done its job.
More information about the llvm-commits
mailing list