[llvm] [LV] Simplify the latch branch before rewriting ALM for a scalar VF (PR #216257)

Florian Hahn via llvm-commits llvm-commits at lists.llvm.org
Fri Aug 14 13:03:34 PDT 2026


https://github.com/fhahn updated https://github.com/llvm/llvm-project/pull/216257

>From 028754c433b81a5c175442df04888c82143ba1b2 Mon Sep 17 00:00:00 2001
From: Florian Hahn <flo at fhahn.com>
Date: Thu, 13 Aug 2026 09:37:05 +0100
Subject: [PATCH] [LV] Simplify the latch branch before rewriting lane masks
 for a scalar VF

Run simplifyBranchConditionForVFAndUF before replaceMaskWithCompare before, so
the simplification triggers before replaceMaskWithCompare writes the
plan.
---
 .../Transforms/Vectorize/VPlanTransforms.cpp  |  5 +-
 ...limination-tail-folding-interleave-only.ll | 58 +++++--------------
 2 files changed, 19 insertions(+), 44 deletions(-)

diff --git a/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp b/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp
index eb5958c37043d..e75e9cf4e9103 100644
--- a/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp
+++ b/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp
@@ -2142,8 +2142,9 @@ void VPlanTransforms::optimizeForVFAndUF(VPlan &Plan, ElementCount BestVF,
   assert(Plan.hasVF(BestVF) && "BestVF is not available in Plan");
   assert(Plan.hasUF(BestUF) && "BestUF is not available in Plan");
 
-  bool MadeChange = replaceMaskWithCompare(Plan, BestVF);
-  MadeChange |= simplifyBranchConditionForVFAndUF(Plan, BestVF, BestUF, PSE);
+  bool MadeChange =
+      simplifyBranchConditionForVFAndUF(Plan, BestVF, BestUF, PSE);
+  MadeChange |= replaceMaskWithCompare(Plan, BestVF);
   MadeChange |= optimizeVectorInductionWidthForTCAndVFUF(Plan, BestVF, BestUF);
 
   if (MadeChange) {
diff --git a/llvm/test/Transforms/LoopVectorize/vector-loop-backedge-elimination-tail-folding-interleave-only.ll b/llvm/test/Transforms/LoopVectorize/vector-loop-backedge-elimination-tail-folding-interleave-only.ll
index a9eb11b609945..56c6d1c7421f9 100644
--- a/llvm/test/Transforms/LoopVectorize/vector-loop-backedge-elimination-tail-folding-interleave-only.ll
+++ b/llvm/test/Transforms/LoopVectorize/vector-loop-backedge-elimination-tail-folding-interleave-only.ll
@@ -10,63 +10,37 @@ define void @scalar_vf_single_iteration(ptr noalias %dst, ptr noalias %src) {
 ; CHECK:       [[VECTOR_PH]]:
 ; CHECK-NEXT:    br label %[[VECTOR_BODY:.*]]
 ; CHECK:       [[VECTOR_BODY]]:
-; CHECK-NEXT:    [[INDEX:%.*]] = phi i64 [ 0, %[[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], %[[PRED_STORE_CONTINUE9:.*]] ]
-; CHECK-NEXT:    [[ACTIVE_LANE_MASK:%.*]] = phi i1 [ true, %[[VECTOR_PH]] ], [ [[TMP19:%.*]], %[[PRED_STORE_CONTINUE9]] ]
-; CHECK-NEXT:    [[ACTIVE_LANE_MASK1:%.*]] = phi i1 [ true, %[[VECTOR_PH]] ], [ [[TMP21:%.*]], %[[PRED_STORE_CONTINUE9]] ]
-; CHECK-NEXT:    [[ACTIVE_LANE_MASK2:%.*]] = phi i1 [ true, %[[VECTOR_PH]] ], [ [[TMP23:%.*]], %[[PRED_STORE_CONTINUE9]] ]
-; CHECK-NEXT:    [[ACTIVE_LANE_MASK3:%.*]] = phi i1 [ false, %[[VECTOR_PH]] ], [ [[TMP25:%.*]], %[[PRED_STORE_CONTINUE9]] ]
-; CHECK-NEXT:    br i1 [[ACTIVE_LANE_MASK]], label %[[PRED_STORE_IF:.*]], label %[[PRED_STORE_CONTINUE:.*]]
-; CHECK:       [[PRED_STORE_IF]]:
-; CHECK-NEXT:    [[TMP0:%.*]] = getelementptr inbounds i64, ptr [[SRC]], i64 [[INDEX]]
-; CHECK-NEXT:    [[TMP1:%.*]] = load i64, ptr [[TMP0]], align 8
-; CHECK-NEXT:    [[TMP2:%.*]] = getelementptr inbounds i64, ptr [[DST]], i64 [[INDEX]]
-; CHECK-NEXT:    [[TMP3:%.*]] = mul i64 [[TMP1]], 3
-; CHECK-NEXT:    store i64 [[TMP3]], ptr [[TMP2]], align 8
-; CHECK-NEXT:    br label %[[PRED_STORE_CONTINUE]]
+; CHECK-NEXT:    br label %[[PRED_STORE_CONTINUE:.*]]
 ; CHECK:       [[PRED_STORE_CONTINUE]]:
-; CHECK-NEXT:    br i1 [[ACTIVE_LANE_MASK1]], label %[[PRED_STORE_IF4:.*]], label %[[PRED_STORE_CONTINUE5:.*]]
-; CHECK:       [[PRED_STORE_IF4]]:
-; CHECK-NEXT:    [[TMP4:%.*]] = add i64 [[INDEX]], 1
-; CHECK-NEXT:    [[TMP5:%.*]] = getelementptr inbounds i64, ptr [[SRC]], i64 [[TMP4]]
-; CHECK-NEXT:    [[TMP6:%.*]] = load i64, ptr [[TMP5]], align 8
-; CHECK-NEXT:    [[TMP7:%.*]] = getelementptr inbounds i64, ptr [[DST]], i64 [[TMP4]]
+; CHECK-NEXT:    [[TMP6:%.*]] = load i64, ptr [[SRC]], align 8
 ; CHECK-NEXT:    [[TMP8:%.*]] = mul i64 [[TMP6]], 3
-; CHECK-NEXT:    store i64 [[TMP8]], ptr [[TMP7]], align 8
-; CHECK-NEXT:    br label %[[PRED_STORE_CONTINUE5]]
+; CHECK-NEXT:    store i64 [[TMP8]], ptr [[DST]], align 8
+; CHECK-NEXT:    br label %[[PRED_STORE_CONTINUE5:.*]]
 ; CHECK:       [[PRED_STORE_CONTINUE5]]:
-; CHECK-NEXT:    br i1 [[ACTIVE_LANE_MASK2]], label %[[PRED_STORE_IF6:.*]], label %[[PRED_STORE_CONTINUE7:.*]]
+; CHECK-NEXT:    br label %[[PRED_STORE_IF6:.*]]
 ; CHECK:       [[PRED_STORE_IF6]]:
-; CHECK-NEXT:    [[TMP9:%.*]] = add i64 [[INDEX]], 2
-; CHECK-NEXT:    [[TMP10:%.*]] = getelementptr inbounds i64, ptr [[SRC]], i64 [[TMP9]]
+; CHECK-NEXT:    [[TMP10:%.*]] = getelementptr inbounds i64, ptr [[SRC]], i64 1
 ; CHECK-NEXT:    [[TMP11:%.*]] = load i64, ptr [[TMP10]], align 8
-; CHECK-NEXT:    [[TMP12:%.*]] = getelementptr inbounds i64, ptr [[DST]], i64 [[TMP9]]
+; CHECK-NEXT:    [[TMP12:%.*]] = getelementptr inbounds i64, ptr [[DST]], i64 1
 ; CHECK-NEXT:    [[TMP13:%.*]] = mul i64 [[TMP11]], 3
 ; CHECK-NEXT:    store i64 [[TMP13]], ptr [[TMP12]], align 8
-; CHECK-NEXT:    br label %[[PRED_STORE_CONTINUE7]]
+; CHECK-NEXT:    br label %[[PRED_STORE_CONTINUE7:.*]]
 ; CHECK:       [[PRED_STORE_CONTINUE7]]:
-; CHECK-NEXT:    br i1 [[ACTIVE_LANE_MASK3]], label %[[PRED_STORE_IF8:.*]], label %[[PRED_STORE_CONTINUE9]]
+; CHECK-NEXT:    br label %[[PRED_STORE_IF8:.*]]
 ; CHECK:       [[PRED_STORE_IF8]]:
-; CHECK-NEXT:    [[TMP14:%.*]] = add i64 [[INDEX]], 3
-; CHECK-NEXT:    [[TMP15:%.*]] = getelementptr inbounds i64, ptr [[SRC]], i64 [[TMP14]]
+; CHECK-NEXT:    [[TMP15:%.*]] = getelementptr inbounds i64, ptr [[SRC]], i64 2
 ; CHECK-NEXT:    [[TMP16:%.*]] = load i64, ptr [[TMP15]], align 8
-; CHECK-NEXT:    [[TMP17:%.*]] = getelementptr inbounds i64, ptr [[DST]], i64 [[TMP14]]
+; CHECK-NEXT:    [[TMP17:%.*]] = getelementptr inbounds i64, ptr [[DST]], i64 2
 ; CHECK-NEXT:    [[TMP18:%.*]] = mul i64 [[TMP16]], 3
 ; CHECK-NEXT:    store i64 [[TMP18]], ptr [[TMP17]], align 8
-; CHECK-NEXT:    br label %[[PRED_STORE_CONTINUE9]]
+; CHECK-NEXT:    br label %[[PRED_STORE_CONTINUE9:.*]]
 ; CHECK:       [[PRED_STORE_CONTINUE9]]:
-; CHECK-NEXT:    [[INDEX_NEXT]] = add i64 [[INDEX]], 4
-; CHECK-NEXT:    [[TMP19]] = icmp ult i64 [[INDEX_NEXT]], 3
-; CHECK-NEXT:    [[TMP20:%.*]] = add i64 [[INDEX_NEXT]], 1
-; CHECK-NEXT:    [[TMP21]] = icmp ult i64 [[TMP20]], 3
-; CHECK-NEXT:    [[TMP22:%.*]] = add i64 [[INDEX_NEXT]], 2
-; CHECK-NEXT:    [[TMP23]] = icmp ult i64 [[TMP22]], 3
-; CHECK-NEXT:    [[TMP24:%.*]] = add i64 [[INDEX_NEXT]], 3
-; CHECK-NEXT:    [[TMP25]] = icmp ult i64 [[TMP24]], 3
-; CHECK-NEXT:    [[TMP26:%.*]] = xor i1 [[TMP19]], true
-; CHECK-NEXT:    br i1 [[TMP26]], label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]], !llvm.loop [[LOOP0:![0-9]+]]
-; CHECK:       [[MIDDLE_BLOCK]]:
 ; CHECK-NEXT:    br label %[[EXIT:.*]]
 ; CHECK:       [[EXIT]]:
+; CHECK-NEXT:    br label %[[MIDDLE_BLOCK:.*]]
+; CHECK:       [[MIDDLE_BLOCK]]:
+; CHECK-NEXT:    br label %[[EXIT1:.*]]
+; CHECK:       [[EXIT1]]:
 ; CHECK-NEXT:    ret void
 ;
 entry:



More information about the llvm-commits mailing list