Skip to content

[VPlan] Fold lhs | (headermask && rhs) -> vp.merge rhs, true, lhs, evl#193511

Merged
lukel97 merged 2 commits into
llvm:mainfrom
lukel97:loop-vectorize/optimizeMaskToEVL-logical-or
Apr 24, 2026
Merged

[VPlan] Fold lhs | (headermask && rhs) -> vp.merge rhs, true, lhs, evl#193511
lukel97 merged 2 commits into
llvm:mainfrom
lukel97:loop-vectorize/optimizeMaskToEVL-logical-or

Conversation

@lukel97

@lukel97 lukel97 commented Apr 22, 2026

Copy link
Copy Markdown
Contributor

This is a combine on mask vectors that can show up with EVL tail folding.

Split off from #190196

This is a combine on mask vectors that can show up with EVL tail folding.

Split off from llvm#190196
@llvmbot

llvmbot commented Apr 22, 2026

Copy link
Copy Markdown
Member

@llvm/pr-subscribers-vectorizers

@llvm/pr-subscribers-backend-risc-v

Author: Luke Lau (lukel97)

Changes

This is a combine on mask vectors that can show up with EVL tail folding.

Split off from #190196


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

2 Files Affected:

  • (modified) llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp (+8)
  • (modified) llvm/test/Transforms/LoopVectorize/RISCV/iv-select-cmp.ll (+1-2)
diff --git a/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp b/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp
index 242ff9e284ac9..946d8d240b7b3 100644
--- a/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp
+++ b/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp
@@ -3208,6 +3208,14 @@ static VPRecipeBase *optimizeMaskToEVL(VPValue *HeaderMask,
         VPIRFlags::getDefaultFlags(Instruction::Sub), {}, DL);
   }
 
+  // lhs | (headermask && rhs) -> vp.merge rhs, true, lhs, evl
+  if (match(&CurRecipe,
+            m_c_BinaryOr(m_VPValue(LHS),
+                         m_LogicalAnd(m_Specific(HeaderMask), m_VPValue(RHS)))))
+    return new VPWidenIntrinsicRecipe(
+        Intrinsic::vp_merge, {RHS, Plan->getTrue(), LHS, &EVL},
+        TypeInfo.inferScalarType(LHS), {}, {}, DL);
+
   return nullptr;
 }
 
diff --git a/llvm/test/Transforms/LoopVectorize/RISCV/iv-select-cmp.ll b/llvm/test/Transforms/LoopVectorize/RISCV/iv-select-cmp.ll
index c6b907d82ce02..b8a7fb7bda860 100644
--- a/llvm/test/Transforms/LoopVectorize/RISCV/iv-select-cmp.ll
+++ b/llvm/test/Transforms/LoopVectorize/RISCV/iv-select-cmp.ll
@@ -96,9 +96,8 @@ define i64 @select_decreasing_induction_icmp_non_const_start(ptr %a, ptr %b, i64
 ; CHECK-NEXT:    [[VP_OP_LOAD4:%.*]] = call <vscale x 4 x i64> @llvm.vp.load.nxv4i64.p0(ptr align 8 [[TMP14]], <vscale x 4 x i1> splat (i1 true), i32 [[TMP4]])
 ; CHECK-NEXT:    [[TMP15:%.*]] = call <vscale x 4 x i64> @llvm.experimental.vp.reverse.nxv4i64(<vscale x 4 x i64> [[VP_OP_LOAD4]], <vscale x 4 x i1> splat (i1 true), i32 [[TMP4]])
 ; CHECK-NEXT:    [[TMP16:%.*]] = icmp sgt <vscale x 4 x i64> [[TMP12]], [[TMP15]]
-; CHECK-NEXT:    [[TMP17:%.*]] = call <vscale x 4 x i1> @llvm.vp.merge.nxv4i1(<vscale x 4 x i1> splat (i1 true), <vscale x 4 x i1> [[TMP16]], <vscale x 4 x i1> zeroinitializer, i32 [[TMP4]])
 ; CHECK-NEXT:    [[TMP18]] = call <vscale x 4 x i64> @llvm.vp.merge.nxv4i64(<vscale x 4 x i1> [[TMP16]], <vscale x 4 x i64> [[VEC_IND]], <vscale x 4 x i64> [[VEC_PHI]], i32 [[TMP4]])
-; CHECK-NEXT:    [[TMP19]] = or <vscale x 4 x i1> [[VEC_PHI1]], [[TMP17]]
+; CHECK-NEXT:    [[TMP19]] = call <vscale x 4 x i1> @llvm.vp.merge.nxv4i1(<vscale x 4 x i1> [[TMP16]], <vscale x 4 x i1> splat (i1 true), <vscale x 4 x i1> [[VEC_PHI1]], i32 [[TMP4]])
 ; CHECK-NEXT:    [[CURRENT_ITERATION_NEXT]] = add i64 [[TMP5]], [[INDEX]]
 ; CHECK-NEXT:    [[AVL_NEXT]] = sub nuw i64 [[AVL]], [[TMP5]]
 ; CHECK-NEXT:    [[VEC_IND_NEXT]] = add nsw <vscale x 4 x i64> [[VEC_IND]], [[BROADCAST_SPLAT3]]

@fhahn fhahn left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thanks


// lhs | (headermask && rhs) -> vp.merge rhs, true, lhs, evl
if (match(&CurRecipe,
m_c_BinaryOr(m_VPValue(LHS),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's probably no way to the the variant where LHS is on the right size, exercising the commutative match, right?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure, I don't think VPlanPredicator will ever create a block-in mask with a header mask on only one arm of an or. This particular or comes from LoopVectorizationPlanner::addReductionResultComputation which always puts the header mask if any on the RHS.

@lukel97
lukel97 enabled auto-merge (squash) April 24, 2026 00:51
@lukel97
lukel97 merged commit 67e1411 into llvm:main Apr 24, 2026
9 of 10 checks passed
yingopq pushed a commit to yingopq/llvm-project that referenced this pull request Apr 29, 2026
llvm#193511)

This is a combine on mask vectors that can show up with EVL tail
folding.

Split off from llvm#190196
KHicketts pushed a commit to KHicketts/llvm-project that referenced this pull request Apr 30, 2026
llvm#193511)

This is a combine on mask vectors that can show up with EVL tail
folding.

Split off from llvm#190196
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants