[llvm] [VPlan] Constant-fold ActiveLaneMask intrinsics (PR #208852)
Ramkumar Ramachandra via llvm-commits
llvm-commits at lists.llvm.org
Fri Aug 14 11:51:35 PDT 2026
https://github.com/artagnon updated https://github.com/llvm/llvm-project/pull/208852
>From 99faf66fc658a95cee2a16269261be37cf84abea Mon Sep 17 00:00:00 2001
From: Ramkumar Ramachandra <artagnon at tenstorrent.com>
Date: Sun, 2 Aug 2026 11:53:43 +0100
Subject: [PATCH 1/3] [LV] Pre-commit ALM tests
---
.../vplan-scalable-active-lane-mask.ll | 29 +++++++++++++++++++
.../VPlan/vplan-foldable-active-lane-mask.ll | 26 +++++++++++++++++
2 files changed, 55 insertions(+)
create mode 100644 llvm/test/Transforms/LoopVectorize/VPlan/AArch64/vplan-scalable-active-lane-mask.ll
create mode 100644 llvm/test/Transforms/LoopVectorize/VPlan/vplan-foldable-active-lane-mask.ll
diff --git a/llvm/test/Transforms/LoopVectorize/VPlan/AArch64/vplan-scalable-active-lane-mask.ll b/llvm/test/Transforms/LoopVectorize/VPlan/AArch64/vplan-scalable-active-lane-mask.ll
new file mode 100644
index 0000000000000..10a952683119b
--- /dev/null
+++ b/llvm/test/Transforms/LoopVectorize/VPlan/AArch64/vplan-scalable-active-lane-mask.ll
@@ -0,0 +1,29 @@
+; NOTE: Assertions have been autogenerated by utils/update_analyze_test_checks.py UTC_ARGS: --filter "active.lane.mask" --version 6
+; RUN: opt -mtriple=aarch64 -mcpu=neoverse-v1 -passes=loop-vectorize -force-vector-width="vscale x 4" -force-vector-interleave=1 -tail-folding-policy=prefer-fold-tail -disable-output -vplan-print-after=printOptimizedVPlan %s 2>&1 | FileCheck %s
+
+; We never emit a scalable active.lane.mask that can be folded to a constant.
+define i32 @scalable_alm_liveins(ptr %A, ptr noalias %B) {
+; CHECK-LABEL: VPlan for loop in 'scalable_alm_liveins'
+; CHECK: EMIT vp<%active.lane.mask.entry> = active lane mask vp<%index.part.next>, ir<1002>, ir<1>
+; CHECK: ACTIVE-LANE-MASK-PHI vp<[[VP5:%[0-9]+]]> = phi vp<%active.lane.mask.entry>, vp<%active.lane.mask.next>
+; CHECK: EMIT vp<%active.lane.mask.next> = active lane mask vp<[[VP8:%[0-9]+]]>, ir<1002>, ir<1>
+; CHECK: EMIT vp<[[VP9:%[0-9]+]]> = not vp<%active.lane.mask.next>
+;
+entry:
+ br label %loop
+
+loop:
+ %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
+ %for = phi i16 [ 0, %entry ], [ %for.next, %loop ]
+ %sext = sext i16 %for to i32
+ %iv.next = add i64 %iv, 1
+ %gep.A = getelementptr i32, ptr %A, i64 %iv.next
+ %for.next = load i16, ptr %gep.A, align 2
+ %gep.B = getelementptr i32, ptr %B, i64 %iv.next
+ store i32 %sext, ptr %gep.B
+ %ec = icmp eq i64 %iv, 1001
+ br i1 %ec, label %exit, label %loop
+
+exit:
+ ret i32 0
+}
diff --git a/llvm/test/Transforms/LoopVectorize/VPlan/vplan-foldable-active-lane-mask.ll b/llvm/test/Transforms/LoopVectorize/VPlan/vplan-foldable-active-lane-mask.ll
new file mode 100644
index 0000000000000..b2fdc9e79cad7
--- /dev/null
+++ b/llvm/test/Transforms/LoopVectorize/VPlan/vplan-foldable-active-lane-mask.ll
@@ -0,0 +1,26 @@
+; NOTE: Assertions have been autogenerated by utils/update_analyze_test_checks.py UTC_ARGS: --filter "active.lane.mask" --version 6
+; RUN: opt -passes=loop-vectorize -tail-folding-policy=must-fold-tail -force-tail-folding-style=data -force-vector-width=4 -disable-output -vplan-print-after=printOptimizedVPlan %s 2>&1 | FileCheck %s --check-prefix=FIXED
+; RUN: opt -passes=loop-vectorize -tail-folding-policy=must-fold-tail -force-tail-folding-style=data -force-vector-width="vscale x 4" -disable-output -vplan-print-after=printOptimizedVPlan %s 2>&1 | FileCheck %s --check-prefix=SCALABLE
+
+; We never emit fixed-vector active.lane.masks foldable to false.
+define i16 @foldable_fixed_alm(i32 %x) {
+; FIXED-LABEL: VPlan for loop in 'foldable_fixed_alm'
+; SCALABLE-LABEL: VPlan for loop in 'foldable_fixed_alm'
+; SCALABLE: EMIT vp<%active.lane.mask> = active lane mask vp<[[VP5:%[0-9]+]]>, ir<4>, ir<1>
+; SCALABLE: EMIT vp<[[VP7:%[0-9]+]]> = last-active-lane vp<%active.lane.mask>
+;
+entry:
+ br label %loop
+
+loop:
+ %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
+ %red = phi i32 [ 0, %entry ], [ %add, %loop ]
+ %t = trunc i32 %red to i16
+ %add = add i32 %red, %x
+ %iv.next = add i64 %iv, 1
+ %ec = icmp eq i64 %iv, 3
+ br i1 %ec, label %exit, label %loop
+
+exit:
+ ret i16 %t
+}
>From 37f56c7da1fd0b6f919d7910d783326b37ac59c0 Mon Sep 17 00:00:00 2001
From: Ramkumar Ramachandra <artagnon at tenstorrent.com>
Date: Mon, 22 Jun 2026 18:18:42 +0100
Subject: [PATCH 2/3] [VPlan] Constant-fold ActiveLaneMask intrinsics
Constant-fold fixed-vector types via llvm::simplifyIntrinsic, making it
accessible from InstSimplifyFolder, and use it for folding
get.active.lane.mask in VPlan.
---
llvm/lib/Transforms/Vectorize/VPlanUtils.cpp | 17 +++++++++++++++++
.../AArch64/first-order-recurrence-fold-tail.ll | 3 +--
2 files changed, 18 insertions(+), 2 deletions(-)
diff --git a/llvm/lib/Transforms/Vectorize/VPlanUtils.cpp b/llvm/lib/Transforms/Vectorize/VPlanUtils.cpp
index daf8114d482d0..599e912b4758f 100644
--- a/llvm/lib/Transforms/Vectorize/VPlanUtils.cpp
+++ b/llvm/lib/Transforms/Vectorize/VPlanUtils.cpp
@@ -1120,6 +1120,23 @@ VPIRValue *vputils::tryToFoldLiveIns(VPSingleDefRecipe &R,
case Instruction::ExtractElement:
assert(!Ops[0]->getType()->isVectorTy() && "Live-ins should be scalar");
return Ops[0];
+ case VPInstruction::ActiveLaneMask: {
+ uint64_t Multiplier = cast<ConstantInt>(Ops[2])->getZExtValue();
+ Type *I1Ty = IntegerType::getInt1Ty(Plan.getContext());
+ if (Plan.hasScalableVF())
+ // We do not produce foldable scalable ALMs at the moment.
+ return nullptr;
+
+ // We do not produce ALMs foldable to false at the moment.
+ unsigned MaxVF = Multiplier * max_element(Plan.vectorFactors(),
+ ElementCount::isKnownLT)
+ ->getFixedValue();
+ if (auto *C = dyn_cast_if_present<Constant>(Folder.FoldIntrinsic(
+ Intrinsic::get_active_lane_mask, drop_end(Ops),
+ FixedVectorType::get(I1Ty, MaxVF))))
+ if (C->isOneValue())
+ return ConstantInt::getTrue(I1Ty);
+ }
}
return nullptr;
};
diff --git a/llvm/test/Transforms/LoopVectorize/AArch64/first-order-recurrence-fold-tail.ll b/llvm/test/Transforms/LoopVectorize/AArch64/first-order-recurrence-fold-tail.ll
index 380554dd22b64..ed4fcb31f9dda 100644
--- a/llvm/test/Transforms/LoopVectorize/AArch64/first-order-recurrence-fold-tail.ll
+++ b/llvm/test/Transforms/LoopVectorize/AArch64/first-order-recurrence-fold-tail.ll
@@ -9,11 +9,10 @@ define i32 @test_phi_iterator_invalidation(ptr %A, ptr noalias %B) {
; CHECK-NEXT: entry:
; CHECK-NEXT: br label [[VECTOR_PH:%.*]]
; CHECK: vector.ph:
-; CHECK-NEXT: [[ACTIVE_LANE_MASK_ENTRY:%.*]] = call <4 x i1> @llvm.get.active.lane.mask.v4i1.i64(i64 0, i64 1002)
; CHECK-NEXT: br label [[VECTOR_BODY:%.*]]
; CHECK: vector.body:
; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[PRED_LOAD_CONTINUE6:%.*]] ]
-; CHECK-NEXT: [[ACTIVE_LANE_MASK:%.*]] = phi <4 x i1> [ [[ACTIVE_LANE_MASK_ENTRY]], [[VECTOR_PH]] ], [ [[ACTIVE_LANE_MASK_NEXT:%.*]], [[PRED_LOAD_CONTINUE6]] ]
+; CHECK-NEXT: [[ACTIVE_LANE_MASK:%.*]] = phi <4 x i1> [ splat (i1 true), [[VECTOR_PH]] ], [ [[ACTIVE_LANE_MASK_NEXT:%.*]], [[PRED_LOAD_CONTINUE6]] ]
; CHECK-NEXT: [[VEC_IND:%.*]] = phi <4 x i64> [ <i64 0, i64 1, i64 2, i64 3>, [[VECTOR_PH]] ], [ [[VEC_IND_NEXT:%.*]], [[PRED_LOAD_CONTINUE6]] ]
; CHECK-NEXT: [[VECTOR_RECUR:%.*]] = phi <4 x i16> [ <i16 poison, i16 poison, i16 poison, i16 0>, [[VECTOR_PH]] ], [ [[TMP24:%.*]], [[PRED_LOAD_CONTINUE6]] ]
; CHECK-NEXT: [[TMP0:%.*]] = add <4 x i64> [[VEC_IND]], splat (i64 1)
>From 0e3e749d3eda22e5baa7d21793ad5d72779bf0e4 Mon Sep 17 00:00:00 2001
From: Ramkumar Ramachandra <artagnon at tenstorrent.com>
Date: Fri, 14 Aug 2026 19:27:03 +0100
Subject: [PATCH 3/3] [VPlan] Note fold-true scalable ALMs, WideALM
---
llvm/lib/Transforms/Vectorize/VPlanUtils.cpp | 19 +++--
.../AArch64/fixed-wide-lane-mask.ll | 3 +-
.../LoopVectorize/AArch64/wide-alm-const.ll | 7 +-
.../vplan-scalable-active-lane-mask.ll | 14 ++--
.../VPlan/vplan-foldable-active-lane-mask.ll | 77 ++++++++++++++++++-
5 files changed, 97 insertions(+), 23 deletions(-)
diff --git a/llvm/lib/Transforms/Vectorize/VPlanUtils.cpp b/llvm/lib/Transforms/Vectorize/VPlanUtils.cpp
index 599e912b4758f..cb9543d607632 100644
--- a/llvm/lib/Transforms/Vectorize/VPlanUtils.cpp
+++ b/llvm/lib/Transforms/Vectorize/VPlanUtils.cpp
@@ -1120,20 +1120,27 @@ VPIRValue *vputils::tryToFoldLiveIns(VPSingleDefRecipe &R,
case Instruction::ExtractElement:
assert(!Ops[0]->getType()->isVectorTy() && "Live-ins should be scalar");
return Ops[0];
- case VPInstruction::ActiveLaneMask: {
- uint64_t Multiplier = cast<ConstantInt>(Ops[2])->getZExtValue();
+ case VPInstruction::ActiveLaneMask:
+ case VPInstruction::WideActiveLaneMask: {
+ uint64_t Multiplier = 1;
+ if (Opcode == VPInstruction::WideActiveLaneMask) {
+ Multiplier = cast<ConstantInt>(Ops[2])->getZExtValue();
+ Ops.pop_back();
+ }
Type *I1Ty = IntegerType::getInt1Ty(Plan.getContext());
if (Plan.hasScalableVF())
- // We do not produce foldable scalable ALMs at the moment.
+ // We never produce scalable ALMs foldable to false at the moment.
+ // TODO: We do produce scalable ALMs foldable to true, but we would need
+ // access to the vscale range to fold it.
return nullptr;
// We do not produce ALMs foldable to false at the moment.
unsigned MaxVF = Multiplier * max_element(Plan.vectorFactors(),
ElementCount::isKnownLT)
->getFixedValue();
- if (auto *C = dyn_cast_if_present<Constant>(Folder.FoldIntrinsic(
- Intrinsic::get_active_lane_mask, drop_end(Ops),
- FixedVectorType::get(I1Ty, MaxVF))))
+ if (auto *C = dyn_cast_if_present<Constant>(
+ Folder.FoldIntrinsic(Intrinsic::get_active_lane_mask, Ops,
+ FixedVectorType::get(I1Ty, MaxVF))))
if (C->isOneValue())
return ConstantInt::getTrue(I1Ty);
}
diff --git a/llvm/test/Transforms/LoopVectorize/AArch64/fixed-wide-lane-mask.ll b/llvm/test/Transforms/LoopVectorize/AArch64/fixed-wide-lane-mask.ll
index b59fc73ebbf0f..e8bb479f0f78c 100644
--- a/llvm/test/Transforms/LoopVectorize/AArch64/fixed-wide-lane-mask.ll
+++ b/llvm/test/Transforms/LoopVectorize/AArch64/fixed-wide-lane-mask.ll
@@ -193,11 +193,10 @@ define void @fixed_known_tc(ptr noalias readonly %dst, ptr noalias readonly %src
; CHECK-UF1-NEXT: entry:
; CHECK-UF1-NEXT: br label [[VECTOR_BODY:%.*]]
; CHECK-UF1: vector.ph:
-; CHECK-UF1-NEXT: [[ACTIVE_LANE_MASK_ENTRY:%.*]] = call <4 x i1> @llvm.get.active.lane.mask.v4i1.i64(i64 0, i64 15)
; CHECK-UF1-NEXT: br label [[VECTOR_BODY1:%.*]]
; CHECK-UF1: vector.body:
; CHECK-UF1-NEXT: [[IV:%.*]] = phi i64 [ 0, [[VECTOR_BODY]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY1]] ]
-; CHECK-UF1-NEXT: [[ACTIVE_LANE_MASK:%.*]] = phi <4 x i1> [ [[ACTIVE_LANE_MASK_ENTRY]], [[VECTOR_BODY]] ], [ [[ACTIVE_LANE_MASK_NEXT:%.*]], [[VECTOR_BODY1]] ]
+; CHECK-UF1-NEXT: [[ACTIVE_LANE_MASK:%.*]] = phi <4 x i1> [ splat (i1 true), [[VECTOR_BODY]] ], [ [[ACTIVE_LANE_MASK_NEXT:%.*]], [[VECTOR_BODY1]] ]
; CHECK-UF1-NEXT: [[X:%.*]] = load i32, ptr [[SRC]], align 4
; CHECK-UF1-NEXT: [[BROADCAST_SPLATINSERT:%.*]] = insertelement <4 x i32> poison, i32 [[X]], i64 0
; CHECK-UF1-NEXT: [[BROADCAST_SPLAT:%.*]] = shufflevector <4 x i32> [[BROADCAST_SPLATINSERT]], <4 x i32> poison, <4 x i32> zeroinitializer
diff --git a/llvm/test/Transforms/LoopVectorize/AArch64/wide-alm-const.ll b/llvm/test/Transforms/LoopVectorize/AArch64/wide-alm-const.ll
index 7243a4b56358d..fd61f56cbc01c 100644
--- a/llvm/test/Transforms/LoopVectorize/AArch64/wide-alm-const.ll
+++ b/llvm/test/Transforms/LoopVectorize/AArch64/wide-alm-const.ll
@@ -12,14 +12,11 @@ define void @scalable_wide_active_lane_mask_double(ptr noalias %dst, ptr readonl
; CHECK-UF4: [[FOR_BODY_PREHEADER]]:
; CHECK-UF4-NEXT: br label %[[VECTOR_PH:.*]]
; CHECK-UF4: [[VECTOR_PH]]:
-; CHECK-UF4-NEXT: [[ACTIVE_LANE_MASK_ENTRY:%.*]] = call <8 x i1> @llvm.get.active.lane.mask.v8i1.i64(i64 0, i64 9)
-; CHECK-UF4-NEXT: [[EXTRACT_ENTRY_ALM_PART:%.*]] = call <4 x i1> @llvm.vector.extract.v4i1.v8i1(<8 x i1> [[ACTIVE_LANE_MASK_ENTRY]], i64 0)
-; CHECK-UF4-NEXT: [[EXTRACT_ENTRY_ALM_PART1:%.*]] = call <4 x i1> @llvm.vector.extract.v4i1.v8i1(<8 x i1> [[ACTIVE_LANE_MASK_ENTRY]], i64 4)
; CHECK-UF4-NEXT: br label %[[VECTOR_BODY:.*]]
; CHECK-UF4: [[VECTOR_BODY]]:
; CHECK-UF4-NEXT: [[INDEX:%.*]] = phi i64 [ 0, %[[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], %[[VECTOR_BODY]] ]
-; CHECK-UF4-NEXT: [[ACTIVE_LANE_MASK:%.*]] = phi <4 x i1> [ [[EXTRACT_ENTRY_ALM_PART]], %[[VECTOR_PH]] ], [ [[EXTRACT_NEXT_ALM_PART:%.*]], %[[VECTOR_BODY]] ]
-; CHECK-UF4-NEXT: [[ACTIVE_LANE_MASK2:%.*]] = phi <4 x i1> [ [[EXTRACT_ENTRY_ALM_PART1]], %[[VECTOR_PH]] ], [ [[EXTRACT_NEXT_ALM_PART4:%.*]], %[[VECTOR_BODY]] ]
+; CHECK-UF4-NEXT: [[ACTIVE_LANE_MASK:%.*]] = phi <4 x i1> [ splat (i1 true), %[[VECTOR_PH]] ], [ [[EXTRACT_NEXT_ALM_PART:%.*]], %[[VECTOR_BODY]] ]
+; CHECK-UF4-NEXT: [[ACTIVE_LANE_MASK2:%.*]] = phi <4 x i1> [ splat (i1 true), %[[VECTOR_PH]] ], [ [[EXTRACT_NEXT_ALM_PART4:%.*]], %[[VECTOR_BODY]] ]
; CHECK-UF4-NEXT: [[TMP0:%.*]] = getelementptr inbounds double, ptr [[SRC]], i64 [[INDEX]]
; CHECK-UF4-NEXT: [[TMP1:%.*]] = getelementptr inbounds double, ptr [[TMP0]], i64 4
; CHECK-UF4-NEXT: [[WIDE_MASKED_LOAD:%.*]] = call <4 x double> @llvm.masked.load.v4f64.p0(ptr align 8 [[TMP0]], <4 x i1> [[ACTIVE_LANE_MASK]], <4 x double> poison)
diff --git a/llvm/test/Transforms/LoopVectorize/VPlan/AArch64/vplan-scalable-active-lane-mask.ll b/llvm/test/Transforms/LoopVectorize/VPlan/AArch64/vplan-scalable-active-lane-mask.ll
index 10a952683119b..d2fc40040b875 100644
--- a/llvm/test/Transforms/LoopVectorize/VPlan/AArch64/vplan-scalable-active-lane-mask.ll
+++ b/llvm/test/Transforms/LoopVectorize/VPlan/AArch64/vplan-scalable-active-lane-mask.ll
@@ -1,13 +1,15 @@
; NOTE: Assertions have been autogenerated by utils/update_analyze_test_checks.py UTC_ARGS: --filter "active.lane.mask" --version 6
; RUN: opt -mtriple=aarch64 -mcpu=neoverse-v1 -passes=loop-vectorize -force-vector-width="vscale x 4" -force-vector-interleave=1 -tail-folding-policy=prefer-fold-tail -disable-output -vplan-print-after=printOptimizedVPlan %s 2>&1 | FileCheck %s
-; We never emit a scalable active.lane.mask that can be folded to a constant.
-define i32 @scalable_alm_liveins(ptr %A, ptr noalias %B) {
+; TODO: We should be able to fold the active lane mask to a constant based on the
+; maximum value of vscale, since `%index.part.next` is equal to `vscale x 4` which has
+; a max value of 64. It can be proven that active_lane_mask(64, 1002) is all true.
+define i32 @scalable_alm_liveins(ptr %A, ptr noalias %B) vscale_range(1, 16) {
; CHECK-LABEL: VPlan for loop in 'scalable_alm_liveins'
-; CHECK: EMIT vp<%active.lane.mask.entry> = active lane mask vp<%index.part.next>, ir<1002>, ir<1>
-; CHECK: ACTIVE-LANE-MASK-PHI vp<[[VP5:%[0-9]+]]> = phi vp<%active.lane.mask.entry>, vp<%active.lane.mask.next>
-; CHECK: EMIT vp<%active.lane.mask.next> = active lane mask vp<[[VP8:%[0-9]+]]>, ir<1002>, ir<1>
-; CHECK: EMIT vp<[[VP9:%[0-9]+]]> = not vp<%active.lane.mask.next>
+; CHECK: EMIT vp<%active.lane.mask.entry> = wide active lane mask ir<0>, ir<1002>, ir<1>
+; CHECK: EMIT vp<%extract.entry.alm.part> = extract-vector-for-part vp<%active.lane.mask.entry>, ir<0>
+; CHECK: EMIT vp<%active.lane.mask.next> = wide active lane mask vp<%index.next>, ir<1002>, ir<1>
+; CHECK: EMIT vp<%extract.next.alm.part> = extract-vector-for-part vp<%active.lane.mask.next>, ir<0>
;
entry:
br label %loop
diff --git a/llvm/test/Transforms/LoopVectorize/VPlan/vplan-foldable-active-lane-mask.ll b/llvm/test/Transforms/LoopVectorize/VPlan/vplan-foldable-active-lane-mask.ll
index b2fdc9e79cad7..e925dd3d75eff 100644
--- a/llvm/test/Transforms/LoopVectorize/VPlan/vplan-foldable-active-lane-mask.ll
+++ b/llvm/test/Transforms/LoopVectorize/VPlan/vplan-foldable-active-lane-mask.ll
@@ -1,13 +1,82 @@
-; NOTE: Assertions have been autogenerated by utils/update_analyze_test_checks.py UTC_ARGS: --filter "active.lane.mask" --version 6
-; RUN: opt -passes=loop-vectorize -tail-folding-policy=must-fold-tail -force-tail-folding-style=data -force-vector-width=4 -disable-output -vplan-print-after=printOptimizedVPlan %s 2>&1 | FileCheck %s --check-prefix=FIXED
+; NOTE: Assertions have been autogenerated by utils/update_analyze_test_checks.py UTC_ARGS: --filter-out-after "^scalar.ph" --version 6
+; RUN: opt -passes=loop-vectorize -tail-folding-policy=must-fold-tail -force-tail-folding-style=data -force-vector-width=4 -disable-output -vplan-print-after=printOptimizedVPlan %s 2>&1 | FileCheck %s --check-prefix=FIXED
; RUN: opt -passes=loop-vectorize -tail-folding-policy=must-fold-tail -force-tail-folding-style=data -force-vector-width="vscale x 4" -disable-output -vplan-print-after=printOptimizedVPlan %s 2>&1 | FileCheck %s --check-prefix=SCALABLE
; We never emit fixed-vector active.lane.masks foldable to false.
define i16 @foldable_fixed_alm(i32 %x) {
; FIXED-LABEL: VPlan for loop in 'foldable_fixed_alm'
+; FIXED: VPlan 'Initial VPlan for VF={4},UF>=1' {
+; FIXED-NEXT: Live-in vp<[[VP0:%[0-9]+]]> = VF * UF
+; FIXED-NEXT: Live-in vp<[[VP1:%[0-9]+]]> = vector-trip-count
+; FIXED-NEXT: Live-in ir<4> = original trip-count
+; FIXED-EMPTY:
+; FIXED-NEXT: ir-bb<entry>:
+; FIXED-NEXT: Successor(s): scalar.ph, vector.ph
+; FIXED-EMPTY:
+; FIXED-NEXT: vector.ph:
+; FIXED-NEXT: vp<[[VP2:%[0-9]+]]> = DERIVED-IV ir<0> + vp<[[VP1]]> * ir<%x>
+; FIXED-NEXT: Successor(s): vector loop
+; FIXED-EMPTY:
+; FIXED-NEXT: <x1> vector loop: {
+; FIXED-NEXT: vp<[[VP3:%[0-9]+]]> = CANONICAL-IV
+; FIXED-EMPTY:
+; FIXED-NEXT: vector.body:
+; FIXED-NEXT: EMIT vp<%index.next> = add nuw vp<[[VP3]]>, vp<[[VP0]]>
+; FIXED-NEXT: EMIT branch-on-count vp<%index.next>, vp<[[VP1]]>
+; FIXED-NEXT: No successors
+; FIXED-NEXT: }
+; FIXED-NEXT: Successor(s): middle.block
+; FIXED-EMPTY:
+; FIXED-NEXT: middle.block:
+; FIXED-NEXT: EMIT-SCALAR vp<[[VP5:%[0-9]+]]> = trunc ir<%x> to i16
+; FIXED-NEXT: EMIT vp<[[VP6:%[0-9]+]]> = sub nuw vp<[[VP1]]>, ir<1>
+; FIXED-NEXT: vp<[[VP7:%[0-9]+]]> = DERIVED-IV ir<0> + vp<[[VP6]]> * vp<[[VP5]]>
+; FIXED-NEXT: EMIT vp<%cmp.n> = icmp eq ir<4>, vp<[[VP1]]>
+; FIXED-NEXT: EMIT branch-on-cond vp<%cmp.n>
+; FIXED-NEXT: Successor(s): ir-bb<exit>, scalar.ph
+; FIXED-EMPTY:
+; FIXED-NEXT: ir-bb<exit>:
+; FIXED-NEXT: IR %t.lcssa = phi i16 [ %t, %loop ] (extra operand: vp<[[VP7]]> from middle.block)
+; FIXED-NEXT: No successors
+; FIXED-EMPTY:
+; FIXED-NEXT: scalar.ph:
+;
; SCALABLE-LABEL: VPlan for loop in 'foldable_fixed_alm'
-; SCALABLE: EMIT vp<%active.lane.mask> = active lane mask vp<[[VP5:%[0-9]+]]>, ir<4>, ir<1>
-; SCALABLE: EMIT vp<[[VP7:%[0-9]+]]> = last-active-lane vp<%active.lane.mask>
+; SCALABLE: VPlan 'Initial VPlan for VF={vscale x 4},UF>=1' {
+; SCALABLE-NEXT: Live-in vp<[[VP0:%[0-9]+]]> = VF
+; SCALABLE-NEXT: Live-in vp<[[VP1:%[0-9]+]]> = VF * UF
+; SCALABLE-NEXT: Live-in vp<[[VP2:%[0-9]+]]> = vector-trip-count
+; SCALABLE-NEXT: Live-in ir<4> = original trip-count
+; SCALABLE-EMPTY:
+; SCALABLE-NEXT: ir-bb<entry>:
+; SCALABLE-NEXT: Successor(s): scalar.ph, vector.ph
+; SCALABLE-EMPTY:
+; SCALABLE-NEXT: vector.ph:
+; SCALABLE-NEXT: Successor(s): vector loop
+; SCALABLE-EMPTY:
+; SCALABLE-NEXT: <x1> vector loop: {
+; SCALABLE-NEXT: vp<[[VP3:%[0-9]+]]> = CANONICAL-IV
+; SCALABLE-EMPTY:
+; SCALABLE-NEXT: vector.body:
+; SCALABLE-NEXT: ir<%red> = WIDEN-INDUCTION ir<0>, ir<%x>, vp<[[VP0]]> (truncated to i16)
+; SCALABLE-NEXT: EMIT vp<[[VP5:%[0-9]+]]> = WIDEN-CANONICAL-INDUCTION nuw vp<[[VP3]]>
+; SCALABLE-NEXT: EMIT vp<%active.lane.mask> = active lane mask vp<[[VP5]]>, ir<4>
+; SCALABLE-NEXT: EMIT vp<%index.next> = add vp<[[VP3]]>, vp<[[VP1]]>
+; SCALABLE-NEXT: EMIT branch-on-count vp<%index.next>, vp<[[VP2]]>
+; SCALABLE-NEXT: No successors
+; SCALABLE-NEXT: }
+; SCALABLE-NEXT: Successor(s): middle.block
+; SCALABLE-EMPTY:
+; SCALABLE-NEXT: middle.block:
+; SCALABLE-NEXT: EMIT vp<[[VP7:%[0-9]+]]> = last-active-lane vp<%active.lane.mask>
+; SCALABLE-NEXT: EMIT vp<[[VP8:%[0-9]+]]> = extract-lane vp<[[VP7]]>, ir<%red>
+; SCALABLE-NEXT: Successor(s): ir-bb<exit>
+; SCALABLE-EMPTY:
+; SCALABLE-NEXT: ir-bb<exit>:
+; SCALABLE-NEXT: IR %t.lcssa = phi i16 [ %t, %loop ] (extra operand: vp<[[VP8]]> from middle.block)
+; SCALABLE-NEXT: No successors
+; SCALABLE-EMPTY:
+; SCALABLE-NEXT: scalar.ph:
;
entry:
br label %loop
More information about the llvm-commits
mailing list