[llvm] [VPlan] Skip VPInst where mask is only operand in chain in isUsed (NFC) (PR #206286)

Florian Hahn via llvm-commits llvm-commits at lists.llvm.org
Sat Jun 27 13:35:39 PDT 2026


https://github.com/fhahn created https://github.com/llvm/llvm-project/pull/206286

Update isUsedByLoadStoreAddress o skip VPInstruction where the operand in the use chain is only used as mask. Those do not contribute to the load address, so should not force scalarization.

Fixes a regression with f2459f9e
(https://github.com/llvm/llvm-project/pull/196842).

>From 4c0ce331d880714a1a9eaf70ebc29e6c0fb104f2 Mon Sep 17 00:00:00 2001
From: Florian Hahn <flo at fhahn.com>
Date: Sat, 27 Jun 2026 20:51:38 +0100
Subject: [PATCH] [VPlan] Skip VPInst where mask is only operand in chain in
 isUsedBy (NFC)

Update isUsedByLoadStoreAddress o skip VPInstruction where the operand
in the use chain is only used as mask. Those do not contribute to the
load address, so should not force scalarization.

Fixes a regression with f2459f9e
(https://github.com/llvm/llvm-project/pull/196842).
---
 llvm/lib/Transforms/Vectorize/VPlanUtils.cpp           | 10 +++++++---
 .../VPlan/X86/scalarize-wide-load-for-address-use.ll   |  7 ++++---
 2 files changed, 11 insertions(+), 6 deletions(-)

diff --git a/llvm/lib/Transforms/Vectorize/VPlanUtils.cpp b/llvm/lib/Transforms/Vectorize/VPlanUtils.cpp
index 33b5d785e787f..263480924b796 100644
--- a/llvm/lib/Transforms/Vectorize/VPlanUtils.cpp
+++ b/llvm/lib/Transforms/Vectorize/VPlanUtils.cpp
@@ -789,10 +789,14 @@ bool vputils::isUsedByLoadStoreAddress(const VPValue *V) {
       continue;
 
     // Only traverse further through users that also define a value (and can
-    // thus have their own users walked). Skip load VPInstructions: a loaded
-    // value does not depend on the load's operands, so reaching a load here
-    // (only possible via its mask operand) would be a false positive.
+    // thus have their own users walked). Skip when Cur is only used as mask ,
+    // as well as loads: a loaded value does not depend on the load's operand.
     for (VPUser *U : Cur->users()) {
+      auto *VPI = dyn_cast<VPInstruction>(U);
+      if (VPI && VPI->getMask() == Cur &&
+          none_of(VPI->operandsWithoutMask(),
+                  [Cur](VPValue *Op) { return Op == Cur; }))
+        continue;
       if (match(U, m_VPInstruction<Instruction::Load>()))
         continue;
       if (auto *SDR = dyn_cast<VPSingleDefRecipe>(U))
diff --git a/llvm/test/Transforms/LoopVectorize/VPlan/X86/scalarize-wide-load-for-address-use.ll b/llvm/test/Transforms/LoopVectorize/VPlan/X86/scalarize-wide-load-for-address-use.ll
index b5636476e350e..c23ec7c8a9e1f 100644
--- a/llvm/test/Transforms/LoopVectorize/VPlan/X86/scalarize-wide-load-for-address-use.ll
+++ b/llvm/test/Transforms/LoopVectorize/VPlan/X86/scalarize-wide-load-for-address-use.ll
@@ -199,15 +199,16 @@ define void @load_feeds_mask_reaching_address(ptr noalias %src, ptr noalias %dst
 ; CHECK-NEXT:    vector.body:
 ; CHECK-NEXT:      ir<%iv> = WIDEN-INDUCTION ir<0>, ir<1>, vp<[[VP0]]>
 ; CHECK-NEXT:      EMIT ir<%gep> = getelementptr ir<%src>, ir<%iv>
-; CHECK-NEXT:      REPLICATE ir<%val> = load ir<%gep>
+; CHECK-NEXT:      vp<[[VP4:%[0-9]+]]> = vector-pointer ir<%gep>, ir<1>
+; CHECK-NEXT:      WIDEN ir<%val> = load vp<[[VP4]]>
 ; CHECK-NEXT:      EMIT ir<%cmp> = fcmp ole ir<0.000000e+00>, ir<%val>
 ; CHECK-NEXT:    Successor(s): then
 ; CHECK-EMPTY:
 ; CHECK-NEXT:    then:
 ; CHECK-NEXT:      EMIT ir<%idx> = add ir<%iv>, ir<1>, ir<%cmp>
 ; CHECK-NEXT:      EMIT ir<%gep2> = getelementptr ir<@tbl.a>, ir<%idx>
-; CHECK-NEXT:      vp<[[VP4:%[0-9]+]]> = vector-pointer ir<%gep2>, ir<1>
-; CHECK-NEXT:      WIDEN ir<%val2> = load vp<[[VP4]]>, ir<%cmp>
+; CHECK-NEXT:      vp<[[VP5:%[0-9]+]]> = vector-pointer ir<%gep2>, ir<1>
+; CHECK-NEXT:      WIDEN ir<%val2> = load vp<[[VP5]]>, ir<%cmp>
 ; CHECK-NEXT:      REPLICATE store ir<%val2>, ir<%dst>, ir<%cmp>
 ; CHECK-NEXT:    Successor(s): latch
 ; CHECK-EMPTY:



More information about the llvm-commits mailing list