[llvm] [VPlan] Simplify reverse(reverse(x)) -> x (PR #199057)
Luke Lau via llvm-commits
llvm-commits at lists.llvm.org
Wed Jun 10 08:26:51 PDT 2026
https://github.com/lukel97 updated https://github.com/llvm/llvm-project/pull/199057
>From c2e8481bfeeeb0f747dfb4cee4e709bb8947c7cc Mon Sep 17 00:00:00 2001
From: Luke Lau <luke at igalia.com>
Date: Thu, 21 May 2026 16:14:50 +0100
Subject: [PATCH 1/9] Precommit tests
---
.../VPlan/simplify-reverse-reverse.ll | 79 +++++++++++++++++++
1 file changed, 79 insertions(+)
create mode 100644 llvm/test/Transforms/LoopVectorize/VPlan/simplify-reverse-reverse.ll
diff --git a/llvm/test/Transforms/LoopVectorize/VPlan/simplify-reverse-reverse.ll b/llvm/test/Transforms/LoopVectorize/VPlan/simplify-reverse-reverse.ll
new file mode 100644
index 00000000000000..f864b713a1d673
--- /dev/null
+++ b/llvm/test/Transforms/LoopVectorize/VPlan/simplify-reverse-reverse.ll
@@ -0,0 +1,79 @@
+; NOTE: Assertions have been autogenerated by utils/update_analyze_test_checks.py UTC_ARGS: --version 6
+; RUN: opt -p loop-vectorize -force-vector-width=4 -disable-output -vplan-print-after=printOptimizedVPlan %s 2>&1 | FileCheck %s
+
+define void @reverse_copy(ptr noalias %src, ptr noalias %dst, i32 %n) {
+; CHECK-LABEL: VPlan for loop in 'reverse_copy'
+; CHECK: VPlan 'Initial VPlan for VF={4},UF>=1' {
+; CHECK-NEXT: Live-in vp<[[VP0:%[0-9]+]]> = VF
+; CHECK-NEXT: Live-in vp<[[VP1:%[0-9]+]]> = VF * UF
+; CHECK-NEXT: Live-in vp<[[VP2:%[0-9]+]]> = vector-trip-count
+; CHECK-NEXT: vp<[[VP3:%[0-9]+]]> = original trip-count
+; CHECK-EMPTY:
+; CHECK-NEXT: ir-bb<entry>:
+; CHECK-NEXT: EMIT vp<[[VP3]]> = EXPAND SCEV ((-1 * (0 smin (-1 + %n)<nsw>)) + %n)
+; CHECK-NEXT: Successor(s): scalar.ph, vector.ph
+; CHECK-EMPTY:
+; CHECK-NEXT: vector.ph:
+; CHECK-NEXT: vp<[[VP4:%[0-9]+]]> = DERIVED-IV ir<%n> + vp<[[VP2]]> * ir<-1>
+; CHECK-NEXT: Successor(s): vector loop
+; CHECK-EMPTY:
+; CHECK-NEXT: <x1> vector loop: {
+; CHECK-NEXT: vp<[[VP5:%[0-9]+]]> = CANONICAL-IV
+; CHECK-EMPTY:
+; CHECK-NEXT: vector.body:
+; CHECK-NEXT: vp<[[VP6:%[0-9]+]]> = DERIVED-IV ir<%n> + vp<[[VP5]]> * ir<-1>
+; CHECK-NEXT: vp<[[VP7:%[0-9]+]]> = SCALAR-STEPS vp<[[VP6]]>, ir<-1>, vp<[[VP0]]>
+; CHECK-NEXT: CLONE ir<%iv.next> = add nsw vp<[[VP7]]>, ir<-1>
+; CHECK-NEXT: CLONE ir<%gep.src> = getelementptr ir<%src>, ir<%iv.next>
+; CHECK-NEXT: vp<[[VP8:%[0-9]+]]> = vector-end-pointer ir<%gep.src>, vp<[[VP0]]>
+; CHECK-NEXT: WIDEN ir<%x> = load vp<[[VP8]]>
+; CHECK-NEXT: EMIT vp<[[VP9:%[0-9]+]]> = reverse ir<%x>
+; CHECK-NEXT: CLONE ir<%gep.dst> = getelementptr ir<%dst>, ir<%iv.next>
+; CHECK-NEXT: vp<[[VP10:%[0-9]+]]> = vector-end-pointer ir<%gep.dst>, vp<[[VP0]]>
+; CHECK-NEXT: EMIT vp<[[VP11:%[0-9]+]]> = reverse vp<[[VP9]]>
+; CHECK-NEXT: WIDEN store vp<[[VP10]]>, vp<[[VP11]]>
+; CHECK-NEXT: EMIT vp<%index.next> = add nuw vp<[[VP5]]>, vp<[[VP1]]>
+; CHECK-NEXT: EMIT branch-on-count vp<%index.next>, vp<[[VP2]]>
+; CHECK-NEXT: No successors
+; CHECK-NEXT: }
+; CHECK-NEXT: Successor(s): middle.block
+; CHECK-EMPTY:
+; CHECK-NEXT: middle.block:
+; CHECK-NEXT: EMIT vp<%cmp.n> = icmp eq vp<[[VP3]]>, vp<[[VP2]]>
+; CHECK-NEXT: EMIT branch-on-cond vp<%cmp.n>
+; CHECK-NEXT: Successor(s): ir-bb<exit>, scalar.ph
+; CHECK-EMPTY:
+; CHECK-NEXT: ir-bb<exit>:
+; CHECK-NEXT: No successors
+; CHECK-EMPTY:
+; CHECK-NEXT: scalar.ph:
+; CHECK-NEXT: EMIT-SCALAR vp<%bc.resume.val> = phi [ vp<[[VP4]]>, middle.block ], [ ir<%n>, ir-bb<entry> ]
+; CHECK-NEXT: Successor(s): ir-bb<loop>
+; CHECK-EMPTY:
+; CHECK-NEXT: ir-bb<loop>:
+; CHECK-NEXT: IR %iv = phi i32 [ %n, %entry ], [ %iv.next, %loop ] (extra operand: vp<%bc.resume.val> from scalar.ph)
+; CHECK-NEXT: IR %iv.next = add nsw i32 %iv, -1
+; CHECK-NEXT: IR %gep.src = getelementptr i32, ptr %src, i32 %iv.next
+; CHECK-NEXT: IR %x = load i32, ptr %gep.src, align 4
+; CHECK-NEXT: IR %gep.dst = getelementptr i32, ptr %dst, i32 %iv.next
+; CHECK-NEXT: IR store i32 %x, ptr %gep.dst, align 4
+; CHECK-NEXT: IR %ec = icmp sgt i32 %iv.next, 0
+; CHECK-NEXT: No successors
+; CHECK-NEXT: }
+;
+entry:
+ br label %loop
+
+loop:
+ %iv = phi i32 [%n, %entry], [%iv.next, %loop]
+ %iv.next = add nsw i32 %iv, -1
+ %gep.src = getelementptr i32, ptr %src, i32 %iv.next
+ %x = load i32, ptr %gep.src
+ %gep.dst = getelementptr i32, ptr %dst, i32 %iv.next
+ store i32 %x, ptr %gep.dst
+ %ec = icmp sgt i32 %iv.next, 0
+ br i1 %ec, label %loop, label %exit
+
+exit:
+ ret void
+}
>From 63bf475bfd28c654b3aa3e070667ddc757e688ff Mon Sep 17 00:00:00 2001
From: Luke Lau <luke at igalia.com>
Date: Thu, 21 May 2026 16:15:44 +0100
Subject: [PATCH 2/9] [VPlan] Simplify reverse(reverse(x)) -> x
This is a version of #196900 that performs the simplification as a separate transform after optimizeMasksToEVL.
This avoids regressions where cancelling out reverses prevents the header mask from being optimized into a vp intrinsic.
This also adds an equivalent vp_reverse(vp_reverse(x)) -> x transform.
Co-Authored-By: madhura at nvidia.com
---
.../Transforms/Vectorize/LoopVectorize.cpp | 1 +
.../Transforms/Vectorize/VPlanTransforms.cpp | 19 +++++++++++++++++++
.../Transforms/Vectorize/VPlanTransforms.h | 3 +++
.../RISCV/tail-folding-reverse-load-store.ll | 16 ++++------------
.../VPlan/simplify-reverse-reverse.ll | 3 +--
.../LoopVectorize/runtime-check-known-true.ll | 8 +++-----
6 files changed, 31 insertions(+), 19 deletions(-)
diff --git a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
index 3dd145e547e7da..c0de1bdc064525 100644
--- a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
+++ b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
@@ -6723,6 +6723,7 @@ void LoopVectorizationPlanner::buildVPlans(ElementCount MinVF,
Config.getMaxSafeElements());
RUN_VPLAN_PASS(VPlanTransforms::optimizeEVLMasks, *Plan);
}
+ RUN_VPLAN_PASS(VPlanTransforms::simplifyReverses, *Plan);
if (auto P = VPlanTransforms::narrowInterleaveGroups(*Plan, TTI))
VPlans.push_back(std::move(P));
diff --git a/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp b/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp
index b4229afc08d6ce..1881b15c570706 100644
--- a/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp
+++ b/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp
@@ -1802,6 +1802,25 @@ void VPlanTransforms::simplifyRecipes(VPlan &Plan) {
}
}
+void VPlanTransforms::simplifyReverses(VPlan &Plan) {
+ VPValue *X, *EVL;
+ PostOrderTraversal<VPBlockDeepTraversalWrapper<VPBlockBase *>> POT(
+ Plan.getEntry());
+ for (VPBasicBlock *VPBB : VPBlockUtils::blocksOnly<VPBasicBlock>(POT)) {
+ for (VPRecipeBase &R : make_early_inc_range(reverse(*VPBB))) {
+ if (match(&R,
+ m_CombineOr(m_Reverse(m_Reverse(m_VPValue(X))),
+ m_Intrinsic<Intrinsic::experimental_vp_reverse>(
+ m_Intrinsic<Intrinsic::experimental_vp_reverse>(
+ m_VPValue(X), m_VPValue(), m_VPValue(EVL)),
+ m_VPValue(), m_Deferred(EVL))))) {
+ R.getVPSingleValue()->replaceAllUsesWith(X);
+ R.eraseFromParent();
+ }
+ }
+ }
+}
+
/// Reassociate (headermask && x) && y -> headermask && (x && y) to allow the
/// header mask to be simplified further when tail folding, e.g. in
/// optimizeEVLMasks.
diff --git a/llvm/lib/Transforms/Vectorize/VPlanTransforms.h b/llvm/lib/Transforms/Vectorize/VPlanTransforms.h
index 45977814ee16c7..5056649c3cf87e 100644
--- a/llvm/lib/Transforms/Vectorize/VPlanTransforms.h
+++ b/llvm/lib/Transforms/Vectorize/VPlanTransforms.h
@@ -375,6 +375,9 @@ struct VPlanTransforms {
/// Perform instcombine-like simplifications on recipes in \p Plan.
static void simplifyRecipes(VPlan &Plan);
+ /// Cancel out redundant reverses in \p Plan, e.g. reverse(reverse(x)) -> x.
+ static void simplifyReverses(VPlan &Plan);
+
/// Remove BranchOnCond recipes with true or false conditions together with
/// removing dead edges to their successors. If \p OnlyLatches is true, only
/// process loop latches.
diff --git a/llvm/test/Transforms/LoopVectorize/RISCV/tail-folding-reverse-load-store.ll b/llvm/test/Transforms/LoopVectorize/RISCV/tail-folding-reverse-load-store.ll
index 4271ee80d366c6..7bcb4c055aac0b 100644
--- a/llvm/test/Transforms/LoopVectorize/RISCV/tail-folding-reverse-load-store.ll
+++ b/llvm/test/Transforms/LoopVectorize/RISCV/tail-folding-reverse-load-store.ll
@@ -25,11 +25,9 @@ define void @reverse_load_store(i64 %startval, ptr noalias %ptr, ptr noalias %pt
; IF-EVL-NEXT: [[TMP6:%.*]] = sub i64 0, [[TMP4]]
; IF-EVL-NEXT: [[TMP12:%.*]] = getelementptr i32, ptr [[TMP8]], i64 [[TMP6]]
; IF-EVL-NEXT: [[VP_OP_LOAD:%.*]] = call <vscale x 4 x i32> @llvm.vp.load.nxv4i32.p0(ptr align 4 [[TMP12]], <vscale x 4 x i1> splat (i1 true), i32 [[TMP5]])
-; IF-EVL-NEXT: [[VP_REVERSE:%.*]] = call <vscale x 4 x i32> @llvm.experimental.vp.reverse.nxv4i32(<vscale x 4 x i32> [[VP_OP_LOAD]], <vscale x 4 x i1> splat (i1 true), i32 [[TMP5]])
; IF-EVL-NEXT: [[TMP13:%.*]] = getelementptr inbounds i32, ptr [[PTR2:%.*]], i64 [[TMP7]]
; IF-EVL-NEXT: [[TMP17:%.*]] = getelementptr i32, ptr [[TMP13]], i64 [[TMP6]]
-; IF-EVL-NEXT: [[VP_REVERSE3:%.*]] = call <vscale x 4 x i32> @llvm.experimental.vp.reverse.nxv4i32(<vscale x 4 x i32> [[VP_REVERSE]], <vscale x 4 x i1> splat (i1 true), i32 [[TMP5]])
-; IF-EVL-NEXT: call void @llvm.vp.store.nxv4i32.p0(<vscale x 4 x i32> [[VP_REVERSE3]], ptr align 4 [[TMP17]], <vscale x 4 x i1> splat (i1 true), i32 [[TMP5]])
+; IF-EVL-NEXT: call void @llvm.vp.store.nxv4i32.p0(<vscale x 4 x i32> [[VP_OP_LOAD]], ptr align 4 [[TMP17]], <vscale x 4 x i1> splat (i1 true), i32 [[TMP5]])
; IF-EVL-NEXT: [[INDEX_EVL_NEXT]] = add nuw i64 [[TMP20]], [[EVL_BASED_IV]]
; IF-EVL-NEXT: [[AVL_NEXT]] = sub nuw i64 [[AVL]], [[TMP20]]
; IF-EVL-NEXT: [[TMP24:%.*]] = icmp eq i64 [[AVL_NEXT]], 0
@@ -63,11 +61,9 @@ define void @reverse_load_store(i64 %startval, ptr noalias %ptr, ptr noalias %pt
; NO-VP-NEXT: [[TMP12:%.*]] = sub i64 0, [[TMP9]]
; NO-VP-NEXT: [[TMP14:%.*]] = getelementptr inbounds i32, ptr [[TMP13]], i64 [[TMP12]]
; NO-VP-NEXT: [[WIDE_LOAD:%.*]] = load <vscale x 4 x i32>, ptr [[TMP14]], align 4
-; NO-VP-NEXT: [[REVERSE:%.*]] = call <vscale x 4 x i32> @llvm.vector.reverse.nxv4i32(<vscale x 4 x i32> [[WIDE_LOAD]])
; NO-VP-NEXT: [[TMP15:%.*]] = getelementptr inbounds i32, ptr [[PTR2:%.*]], i64 [[TMP8]]
; NO-VP-NEXT: [[TMP20:%.*]] = getelementptr inbounds i32, ptr [[TMP15]], i64 [[TMP12]]
-; NO-VP-NEXT: [[REVERSE1:%.*]] = call <vscale x 4 x i32> @llvm.vector.reverse.nxv4i32(<vscale x 4 x i32> [[REVERSE]])
-; NO-VP-NEXT: store <vscale x 4 x i32> [[REVERSE1]], ptr [[TMP20]], align 4
+; NO-VP-NEXT: store <vscale x 4 x i32> [[WIDE_LOAD]], ptr [[TMP20]], align 4
; NO-VP-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], [[TMP3]]
; NO-VP-NEXT: [[TMP21:%.*]] = icmp eq i64 [[INDEX_NEXT]], [[N_VEC]]
; NO-VP-NEXT: br i1 [[TMP21]], label [[MIDDLE_BLOCK:%.*]], label [[FOR_BODY]], !llvm.loop [[LOOP0:![0-9]+]]
@@ -134,11 +130,9 @@ define void @reverse_load_store_masked(i64 %startval, ptr noalias %ptr, ptr noal
; IF-EVL-NEXT: [[TMP7:%.*]] = sub i64 0, [[TMP15]]
; IF-EVL-NEXT: [[TMP20:%.*]] = getelementptr i32, ptr [[TMP16]], i64 [[TMP7]]
; IF-EVL-NEXT: [[VP_OP_LOAD4:%.*]] = call <vscale x 4 x i32> @llvm.vp.load.nxv4i32.p0(ptr align 4 [[TMP20]], <vscale x 4 x i1> [[VP_REVERSE_MASK]], i32 [[TMP5]])
-; IF-EVL-NEXT: [[VP_REVERSE:%.*]] = call <vscale x 4 x i32> @llvm.experimental.vp.reverse.nxv4i32(<vscale x 4 x i32> [[VP_OP_LOAD4]], <vscale x 4 x i1> splat (i1 true), i32 [[TMP5]])
; IF-EVL-NEXT: [[TMP21:%.*]] = getelementptr i32, ptr [[PTR2:%.*]], i64 [[TMP11]]
; IF-EVL-NEXT: [[TMP25:%.*]] = getelementptr i32, ptr [[TMP21]], i64 [[TMP7]]
-; IF-EVL-NEXT: [[TMP13:%.*]] = call <vscale x 4 x i32> @llvm.experimental.vp.reverse.nxv4i32(<vscale x 4 x i32> [[VP_REVERSE]], <vscale x 4 x i1> splat (i1 true), i32 [[TMP5]])
-; IF-EVL-NEXT: call void @llvm.vp.store.nxv4i32.p0(<vscale x 4 x i32> [[TMP13]], ptr align 4 [[TMP25]], <vscale x 4 x i1> [[VP_REVERSE_MASK]], i32 [[TMP5]])
+; IF-EVL-NEXT: call void @llvm.vp.store.nxv4i32.p0(<vscale x 4 x i32> [[VP_OP_LOAD4]], ptr align 4 [[TMP25]], <vscale x 4 x i1> [[VP_REVERSE_MASK]], i32 [[TMP5]])
; IF-EVL-NEXT: [[INDEX_EVL_NEXT]] = add nuw i64 [[TMP26]], [[EVL_BASED_IV]]
; IF-EVL-NEXT: [[AVL_NEXT]] = sub nuw i64 [[AVL]], [[TMP26]]
; IF-EVL-NEXT: [[TMP29:%.*]] = icmp eq i64 [[AVL_NEXT]], 0
@@ -177,11 +171,9 @@ define void @reverse_load_store_masked(i64 %startval, ptr noalias %ptr, ptr noal
; NO-VP-NEXT: [[TMP16:%.*]] = getelementptr i32, ptr [[TMP15]], i64 [[TMP14]]
; NO-VP-NEXT: [[REVERSE:%.*]] = call <vscale x 4 x i1> @llvm.vector.reverse.nxv4i1(<vscale x 4 x i1> [[TMP10]])
; NO-VP-NEXT: [[WIDE_MASKED_LOAD:%.*]] = call <vscale x 4 x i32> @llvm.masked.load.nxv4i32.p0(ptr align 4 [[TMP16]], <vscale x 4 x i1> [[REVERSE]], <vscale x 4 x i32> poison)
-; NO-VP-NEXT: [[REVERSE2:%.*]] = call <vscale x 4 x i32> @llvm.vector.reverse.nxv4i32(<vscale x 4 x i32> [[WIDE_MASKED_LOAD]])
; NO-VP-NEXT: [[TMP17:%.*]] = getelementptr i32, ptr [[PTR2:%.*]], i64 [[TMP8]]
; NO-VP-NEXT: [[TMP22:%.*]] = getelementptr i32, ptr [[TMP17]], i64 [[TMP14]]
-; NO-VP-NEXT: [[REVERSE4:%.*]] = call <vscale x 4 x i32> @llvm.vector.reverse.nxv4i32(<vscale x 4 x i32> [[REVERSE2]])
-; NO-VP-NEXT: call void @llvm.masked.store.nxv4i32.p0(<vscale x 4 x i32> [[REVERSE4]], ptr align 4 [[TMP22]], <vscale x 4 x i1> [[REVERSE]])
+; NO-VP-NEXT: call void @llvm.masked.store.nxv4i32.p0(<vscale x 4 x i32> [[WIDE_MASKED_LOAD]], ptr align 4 [[TMP22]], <vscale x 4 x i1> [[REVERSE]])
; NO-VP-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], [[TMP3]]
; NO-VP-NEXT: [[TMP23:%.*]] = icmp eq i64 [[INDEX_NEXT]], [[N_VEC]]
; NO-VP-NEXT: br i1 [[TMP23]], label [[MIDDLE_BLOCK:%.*]], label [[FOR_BODY]], !llvm.loop [[LOOP4:![0-9]+]]
diff --git a/llvm/test/Transforms/LoopVectorize/VPlan/simplify-reverse-reverse.ll b/llvm/test/Transforms/LoopVectorize/VPlan/simplify-reverse-reverse.ll
index f864b713a1d673..a6a3c8b92199ae 100644
--- a/llvm/test/Transforms/LoopVectorize/VPlan/simplify-reverse-reverse.ll
+++ b/llvm/test/Transforms/LoopVectorize/VPlan/simplify-reverse-reverse.ll
@@ -30,8 +30,7 @@ define void @reverse_copy(ptr noalias %src, ptr noalias %dst, i32 %n) {
; CHECK-NEXT: EMIT vp<[[VP9:%[0-9]+]]> = reverse ir<%x>
; CHECK-NEXT: CLONE ir<%gep.dst> = getelementptr ir<%dst>, ir<%iv.next>
; CHECK-NEXT: vp<[[VP10:%[0-9]+]]> = vector-end-pointer ir<%gep.dst>, vp<[[VP0]]>
-; CHECK-NEXT: EMIT vp<[[VP11:%[0-9]+]]> = reverse vp<[[VP9]]>
-; CHECK-NEXT: WIDEN store vp<[[VP10]]>, vp<[[VP11]]>
+; CHECK-NEXT: WIDEN store vp<[[VP10]]>, ir<%x>
; CHECK-NEXT: EMIT vp<%index.next> = add nuw vp<[[VP5]]>, vp<[[VP1]]>
; CHECK-NEXT: EMIT branch-on-count vp<%index.next>, vp<[[VP2]]>
; CHECK-NEXT: No successors
diff --git a/llvm/test/Transforms/LoopVectorize/runtime-check-known-true.ll b/llvm/test/Transforms/LoopVectorize/runtime-check-known-true.ll
index 66c848e045824c..98c80065c792bb 100644
--- a/llvm/test/Transforms/LoopVectorize/runtime-check-known-true.ll
+++ b/llvm/test/Transforms/LoopVectorize/runtime-check-known-true.ll
@@ -39,10 +39,8 @@ define void @test_runtime_check_known_false_after_construction(ptr %start.1, ptr
; CHECK-NEXT: [[NEXT_GEP3:%.*]] = getelementptr i8, ptr [[START_2_DIFF]], i64 [[OFFSET_IDX]]
; CHECK-NEXT: [[TMP14:%.*]] = getelementptr i64, ptr [[NEXT_GEP3]], i64 -3
; CHECK-NEXT: [[WIDE_LOAD:%.*]] = load <4 x i64>, ptr [[TMP14]], align 8
-; CHECK-NEXT: [[REVERSE:%.*]] = shufflevector <4 x i64> [[WIDE_LOAD]], <4 x i64> poison, <4 x i32> <i32 3, i32 2, i32 1, i32 0>
; CHECK-NEXT: [[TMP16:%.*]] = getelementptr i64, ptr [[NEXT_GEP]], i64 -3
-; CHECK-NEXT: [[REVERSE4:%.*]] = shufflevector <4 x i64> [[REVERSE]], <4 x i64> poison, <4 x i32> <i32 3, i32 2, i32 1, i32 0>
-; CHECK-NEXT: store <4 x i64> [[REVERSE4]], ptr [[TMP16]], align 8
+; CHECK-NEXT: store <4 x i64> [[WIDE_LOAD]], ptr [[TMP16]], align 8
; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 4
; CHECK-NEXT: [[TMP17:%.*]] = icmp eq i64 [[INDEX_NEXT]], [[N_VEC]]
; CHECK-NEXT: br i1 [[TMP17]], label %[[MIDDLE_BLOCK:.*]], label %[[VECTOR_BODY]], !llvm.loop [[LOOP0:![0-9]+]]
@@ -51,11 +49,11 @@ define void @test_runtime_check_known_false_after_construction(ptr %start.1, ptr
; CHECK-NEXT: br i1 [[CMP_N]], label %[[EXIT:.*]], label %[[SCALAR_PH]]
; CHECK: [[SCALAR_PH]]:
; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi ptr [ [[TMP10]], %[[MIDDLE_BLOCK]] ], [ [[START_1]], %[[ENTRY]] ], [ [[START_1]], %[[VECTOR_SCEVCHECK]] ]
-; CHECK-NEXT: [[BC_RESUME_VAL4:%.*]] = phi ptr [ [[TMP11]], %[[MIDDLE_BLOCK]] ], [ [[START_2_DIFF]], %[[ENTRY]] ], [ [[START_2_DIFF]], %[[VECTOR_SCEVCHECK]] ]
+; CHECK-NEXT: [[BC_RESUME_VAL3:%.*]] = phi ptr [ [[TMP11]], %[[MIDDLE_BLOCK]] ], [ [[START_2_DIFF]], %[[ENTRY]] ], [ [[START_2_DIFF]], %[[VECTOR_SCEVCHECK]] ]
; CHECK-NEXT: br label %[[LOOP:.*]]
; CHECK: [[LOOP]]:
; CHECK-NEXT: [[PTR_IV_1:%.*]] = phi ptr [ [[PTR_IV_1_NEXT:%.*]], %[[LOOP]] ], [ [[BC_RESUME_VAL]], %[[SCALAR_PH]] ]
-; CHECK-NEXT: [[PTR_IV_2:%.*]] = phi ptr [ [[PTR_IV_2_NEXT:%.*]], %[[LOOP]] ], [ [[BC_RESUME_VAL4]], %[[SCALAR_PH]] ]
+; CHECK-NEXT: [[PTR_IV_2:%.*]] = phi ptr [ [[PTR_IV_2_NEXT:%.*]], %[[LOOP]] ], [ [[BC_RESUME_VAL3]], %[[SCALAR_PH]] ]
; CHECK-NEXT: [[PTR_IV_2_NEXT]] = getelementptr i8, ptr [[PTR_IV_2]], i64 -8
; CHECK-NEXT: [[PTR_IV_1_NEXT]] = getelementptr i8, ptr [[PTR_IV_1]], i64 -8
; CHECK-NEXT: [[L:%.*]] = load i64, ptr [[PTR_IV_2]], align 8
>From 796ac9ca1b875714704b2f83be794ebb8e1827d1 Mon Sep 17 00:00:00 2001
From: Luke Lau <luke at igalia.com>
Date: Thu, 21 May 2026 16:53:03 +0100
Subject: [PATCH 3/9] Update vplan-print-after-all.ll
---
.../test/Transforms/LoopVectorize/VPlan/vplan-print-after-all.ll | 1 +
1 file changed, 1 insertion(+)
diff --git a/llvm/test/Transforms/LoopVectorize/VPlan/vplan-print-after-all.ll b/llvm/test/Transforms/LoopVectorize/VPlan/vplan-print-after-all.ll
index f41070eb5159df..d7c064088c1b73 100644
--- a/llvm/test/Transforms/LoopVectorize/VPlan/vplan-print-after-all.ll
+++ b/llvm/test/Transforms/LoopVectorize/VPlan/vplan-print-after-all.ll
@@ -49,6 +49,7 @@
; CHECK: VPlan for loop in 'foo' after mergeBlocksIntoPredecessors
; CHECK: VPlan for loop in 'foo' after licm
; CHECK: VPlan for loop in 'foo' after VPlanTransforms::optimize
+; CHECK: VPlan for loop in 'foo' after VPlanTransforms::simplifyReverses
; CHECK: VPlan for loop in 'foo' after printOptimizedVPlan
; CHECK: VPlan for loop in 'foo' after VPlanTransforms::addMinimumIterationCheck
; CHECK: VPlan for loop in 'foo' after VPlanTransforms::unrollByUF
>From cecaa912354b07e60a8a81f16b88dfa4a53eb588 Mon Sep 17 00:00:00 2001
From: Luke Lau <luke at igalia.com>
Date: Fri, 22 May 2026 13:39:51 +0100
Subject: [PATCH 4/9] Add m_vp_Reverse, m_ReverseReverse
---
.../Transforms/Vectorize/VPlanPatternMatch.h | 5 +++++
.../Transforms/Vectorize/VPlanTransforms.cpp | 17 ++++++++++-------
2 files changed, 15 insertions(+), 7 deletions(-)
diff --git a/llvm/lib/Transforms/Vectorize/VPlanPatternMatch.h b/llvm/lib/Transforms/Vectorize/VPlanPatternMatch.h
index f8631549bc1791..f6b30517c51090 100644
--- a/llvm/lib/Transforms/Vectorize/VPlanPatternMatch.h
+++ b/llvm/lib/Transforms/Vectorize/VPlanPatternMatch.h
@@ -1005,6 +1005,11 @@ inline auto m_WidenIntrinsic(const T &...Ops) {
return m_Isa<VPWidenIntrinsicRecipe>(m_Intrinsic<IntrID>(Ops...));
}
+template <typename Op0_t, typename Op1_t, typename Op2_t>
+inline auto m_vp_Reverse(const Op0_t &Op0, const Op1_t &Op1, const Op2_t &Op2) {
+ return m_Intrinsic<Intrinsic::experimental_vp_reverse>(Op0, Op1, Op2);
+}
+
inline auto m_LiveIn() { return m_Isa<VPIRValue, VPSymbolicValue>(); }
/// Match a GEP recipe (VPWidenGEPRecipe, VPInstruction, or VPReplicateRecipe)
diff --git a/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp b/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp
index 1881b15c570706..c6abb52f7ba314 100644
--- a/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp
+++ b/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp
@@ -1803,17 +1803,20 @@ void VPlanTransforms::simplifyRecipes(VPlan &Plan) {
}
void VPlanTransforms::simplifyReverses(VPlan &Plan) {
- VPValue *X, *EVL;
+ auto m_ReverseReverse = [](auto X) {
+ VPValue *EVL;
+ return m_CombineOr(
+ m_Reverse(m_Reverse(X)),
+ m_vp_Reverse(m_vp_Reverse(X, m_VPValue(), m_VPValue(EVL)), m_VPValue(),
+ m_Deferred(EVL)));
+ };
+
PostOrderTraversal<VPBlockDeepTraversalWrapper<VPBlockBase *>> POT(
Plan.getEntry());
for (VPBasicBlock *VPBB : VPBlockUtils::blocksOnly<VPBasicBlock>(POT)) {
for (VPRecipeBase &R : make_early_inc_range(reverse(*VPBB))) {
- if (match(&R,
- m_CombineOr(m_Reverse(m_Reverse(m_VPValue(X))),
- m_Intrinsic<Intrinsic::experimental_vp_reverse>(
- m_Intrinsic<Intrinsic::experimental_vp_reverse>(
- m_VPValue(X), m_VPValue(), m_VPValue(EVL)),
- m_VPValue(), m_Deferred(EVL))))) {
+ VPValue *X;
+ if (match(&R, m_ReverseReverse(m_VPValue(X)))) {
R.getVPSingleValue()->replaceAllUsesWith(X);
R.eraseFromParent();
}
>From 04ad90cfd26d1b4d64e732a53d32a7a16f64f610 Mon Sep 17 00:00:00 2001
From: Luke Lau <luke at igalia.com>
Date: Fri, 22 May 2026 13:42:14 +0100
Subject: [PATCH 5/9] Remove post order traversal
---
llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp | 7 +++----
1 file changed, 3 insertions(+), 4 deletions(-)
diff --git a/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp b/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp
index c6abb52f7ba314..49b8c07d19e571 100644
--- a/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp
+++ b/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp
@@ -1811,10 +1811,9 @@ void VPlanTransforms::simplifyReverses(VPlan &Plan) {
m_Deferred(EVL)));
};
- PostOrderTraversal<VPBlockDeepTraversalWrapper<VPBlockBase *>> POT(
- Plan.getEntry());
- for (VPBasicBlock *VPBB : VPBlockUtils::blocksOnly<VPBasicBlock>(POT)) {
- for (VPRecipeBase &R : make_early_inc_range(reverse(*VPBB))) {
+ for (VPBasicBlock *VPBB : VPBlockUtils::blocksOnly<VPBasicBlock>(
+ vp_depth_first_deep(Plan.getEntry()))) {
+ for (VPRecipeBase &R : make_early_inc_range(*VPBB)) {
VPValue *X;
if (match(&R, m_ReverseReverse(m_VPValue(X)))) {
R.getVPSingleValue()->replaceAllUsesWith(X);
>From ea078f02179b82cfd4ab5979842ee12231aaaf28 Mon Sep 17 00:00:00 2001
From: Luke Lau <luke at igalia.com>
Date: Fri, 22 May 2026 13:44:49 +0100
Subject: [PATCH 6/9] Add comment explaining ordering
---
llvm/lib/Transforms/Vectorize/LoopVectorize.cpp | 2 ++
1 file changed, 2 insertions(+)
diff --git a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
index c0de1bdc064525..c8d8e7709f92e8 100644
--- a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
+++ b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
@@ -6723,6 +6723,8 @@ void LoopVectorizationPlanner::buildVPlans(ElementCount MinVF,
Config.getMaxSafeElements());
RUN_VPLAN_PASS(VPlanTransforms::optimizeEVLMasks, *Plan);
}
+ // Remove reverses after optimizeEVLMasks to prevent interference with
+ // removing the header mask from reversed loads/stores.
RUN_VPLAN_PASS(VPlanTransforms::simplifyReverses, *Plan);
if (auto P = VPlanTransforms::narrowInterleaveGroups(*Plan, TTI))
>From de437f2af1825968f10421435e06e6ad3ac74b58 Mon Sep 17 00:00:00 2001
From: Luke Lau <luke at igalia.com>
Date: Fri, 22 May 2026 13:46:38 +0100
Subject: [PATCH 7/9] Filter out middle.block
---
.../VPlan/simplify-reverse-reverse.ll | 23 +------------------
1 file changed, 1 insertion(+), 22 deletions(-)
diff --git a/llvm/test/Transforms/LoopVectorize/VPlan/simplify-reverse-reverse.ll b/llvm/test/Transforms/LoopVectorize/VPlan/simplify-reverse-reverse.ll
index a6a3c8b92199ae..1dba566fc4487a 100644
--- a/llvm/test/Transforms/LoopVectorize/VPlan/simplify-reverse-reverse.ll
+++ b/llvm/test/Transforms/LoopVectorize/VPlan/simplify-reverse-reverse.ll
@@ -1,4 +1,4 @@
-; NOTE: Assertions have been autogenerated by utils/update_analyze_test_checks.py UTC_ARGS: --version 6
+; NOTE: Assertions have been autogenerated by utils/update_analyze_test_checks.py UTC_ARGS: --filter-out-after "middle.block:" --version 6
; RUN: opt -p loop-vectorize -force-vector-width=4 -disable-output -vplan-print-after=printOptimizedVPlan %s 2>&1 | FileCheck %s
define void @reverse_copy(ptr noalias %src, ptr noalias %dst, i32 %n) {
@@ -38,27 +38,6 @@ define void @reverse_copy(ptr noalias %src, ptr noalias %dst, i32 %n) {
; CHECK-NEXT: Successor(s): middle.block
; CHECK-EMPTY:
; CHECK-NEXT: middle.block:
-; CHECK-NEXT: EMIT vp<%cmp.n> = icmp eq vp<[[VP3]]>, vp<[[VP2]]>
-; CHECK-NEXT: EMIT branch-on-cond vp<%cmp.n>
-; CHECK-NEXT: Successor(s): ir-bb<exit>, scalar.ph
-; CHECK-EMPTY:
-; CHECK-NEXT: ir-bb<exit>:
-; CHECK-NEXT: No successors
-; CHECK-EMPTY:
-; CHECK-NEXT: scalar.ph:
-; CHECK-NEXT: EMIT-SCALAR vp<%bc.resume.val> = phi [ vp<[[VP4]]>, middle.block ], [ ir<%n>, ir-bb<entry> ]
-; CHECK-NEXT: Successor(s): ir-bb<loop>
-; CHECK-EMPTY:
-; CHECK-NEXT: ir-bb<loop>:
-; CHECK-NEXT: IR %iv = phi i32 [ %n, %entry ], [ %iv.next, %loop ] (extra operand: vp<%bc.resume.val> from scalar.ph)
-; CHECK-NEXT: IR %iv.next = add nsw i32 %iv, -1
-; CHECK-NEXT: IR %gep.src = getelementptr i32, ptr %src, i32 %iv.next
-; CHECK-NEXT: IR %x = load i32, ptr %gep.src, align 4
-; CHECK-NEXT: IR %gep.dst = getelementptr i32, ptr %dst, i32 %iv.next
-; CHECK-NEXT: IR store i32 %x, ptr %gep.dst, align 4
-; CHECK-NEXT: IR %ec = icmp sgt i32 %iv.next, 0
-; CHECK-NEXT: No successors
-; CHECK-NEXT: }
;
entry:
br label %loop
>From 9873d798f2f76316ceee4d9cc8896c03aed73f59 Mon Sep 17 00:00:00 2001
From: Luke Lau <luke at igalia.com>
Date: Fri, 22 May 2026 13:47:00 +0100
Subject: [PATCH 8/9] Print after simplifyReverses
---
.../Transforms/LoopVectorize/VPlan/simplify-reverse-reverse.ll | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/llvm/test/Transforms/LoopVectorize/VPlan/simplify-reverse-reverse.ll b/llvm/test/Transforms/LoopVectorize/VPlan/simplify-reverse-reverse.ll
index 1dba566fc4487a..d78b42640561ce 100644
--- a/llvm/test/Transforms/LoopVectorize/VPlan/simplify-reverse-reverse.ll
+++ b/llvm/test/Transforms/LoopVectorize/VPlan/simplify-reverse-reverse.ll
@@ -1,5 +1,5 @@
; NOTE: Assertions have been autogenerated by utils/update_analyze_test_checks.py UTC_ARGS: --filter-out-after "middle.block:" --version 6
-; RUN: opt -p loop-vectorize -force-vector-width=4 -disable-output -vplan-print-after=printOptimizedVPlan %s 2>&1 | FileCheck %s
+; RUN: opt -p loop-vectorize -force-vector-width=4 -disable-output -vplan-print-after=simplifyReverses %s 2>&1 | FileCheck %s
define void @reverse_copy(ptr noalias %src, ptr noalias %dst, i32 %n) {
; CHECK-LABEL: VPlan for loop in 'reverse_copy'
>From 2d4a060f0a4232a5876b0f12c6c3ef4be0a5ebb2 Mon Sep 17 00:00:00 2001
From: Luke Lau <luke at igalia.com>
Date: Wed, 10 Jun 2026 18:44:55 +0800
Subject: [PATCH 9/9] Move to VPlanTransforms::optimize
---
.../Transforms/Vectorize/LoopVectorize.cpp | 3 --
.../Transforms/Vectorize/VPlanPatternMatch.h | 5 ---
.../Transforms/Vectorize/VPlanTransforms.cpp | 37 +++++++++----------
.../VPlan/simplify-reverse-reverse.ll | 2 +
.../VPlan/vplan-print-after-all.ll | 1 +
5 files changed, 21 insertions(+), 27 deletions(-)
diff --git a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
index a545205a49d9d5..302d99a39ed34a 100644
--- a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
+++ b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
@@ -6591,9 +6591,6 @@ void LoopVectorizationPlanner::buildVPlans(VPlan &VPlan1, ElementCount MinVF,
Config.getMaxSafeElements());
RUN_VPLAN_PASS(VPlanTransforms::optimizeEVLMasks, *Plan);
}
- // Remove reverses after optimizeEVLMasks to prevent interference with
- // removing the header mask from reversed loads/stores.
- RUN_VPLAN_PASS(VPlanTransforms::simplifyReverses, *Plan);
if (auto P =
RUN_VPLAN_PASS(VPlanTransforms::narrowInterleaveGroups, *Plan, TTI))
diff --git a/llvm/lib/Transforms/Vectorize/VPlanPatternMatch.h b/llvm/lib/Transforms/Vectorize/VPlanPatternMatch.h
index 83714183a51c14..50a3e8abde71a9 100644
--- a/llvm/lib/Transforms/Vectorize/VPlanPatternMatch.h
+++ b/llvm/lib/Transforms/Vectorize/VPlanPatternMatch.h
@@ -1032,11 +1032,6 @@ inline auto m_WidenIntrinsic(const T &...Ops) {
return m_Isa<VPWidenIntrinsicRecipe>(m_Intrinsic<IntrID>(Ops...));
}
-template <typename Op0_t, typename Op1_t, typename Op2_t>
-inline auto m_vp_Reverse(const Op0_t &Op0, const Op1_t &Op1, const Op2_t &Op2) {
- return m_Intrinsic<Intrinsic::experimental_vp_reverse>(Op0, Op1, Op2);
-}
-
inline auto m_LiveIn() { return m_Isa<VPIRValue, VPSymbolicValue>(); }
/// Match a GEP recipe (VPWidenGEPRecipe, VPInstruction, or VPReplicateRecipe)
diff --git a/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp b/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp
index 19875eb788e277..88ed4368ef2965 100644
--- a/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp
+++ b/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp
@@ -1840,24 +1840,12 @@ void VPlanTransforms::simplifyRecipes(VPlan &Plan) {
}
void VPlanTransforms::simplifyReverses(VPlan &Plan) {
- auto m_ReverseReverse = [](auto X) {
- VPValue *EVL;
- return m_CombineOr(
- m_Reverse(m_Reverse(X)),
- m_vp_Reverse(m_vp_Reverse(X, m_VPValue(), m_VPValue(EVL)), m_VPValue(),
- m_Deferred(EVL)));
- };
-
+ VPValue *X;
for (VPBasicBlock *VPBB : VPBlockUtils::blocksOnly<VPBasicBlock>(
- vp_depth_first_deep(Plan.getEntry()))) {
- for (VPRecipeBase &R : make_early_inc_range(*VPBB)) {
- VPValue *X;
- if (match(&R, m_ReverseReverse(m_VPValue(X)))) {
+ vp_depth_first_deep(Plan.getEntry())))
+ for (VPRecipeBase &R : make_early_inc_range(*VPBB))
+ if (match(&R, m_Reverse(m_Reverse(m_VPValue(X)))))
R.getVPSingleValue()->replaceAllUsesWith(X);
- R.eraseFromParent();
- }
- }
- }
}
/// Reassociate (headermask && x) && y -> headermask && (x && y) to allow the
@@ -2824,6 +2812,7 @@ void VPlanTransforms::optimize(VPlan &Plan) {
RUN_VPLAN_PASS(reassociateHeaderMask, Plan);
RUN_VPLAN_PASS(simplifyRecipes, Plan);
RUN_VPLAN_PASS(removeBranchOnConst, Plan, /*OnlyLatches=*/false);
+ RUN_VPLAN_PASS(simplifyReverses, Plan);
RUN_VPLAN_PASS(removeDeadRecipes, Plan);
RUN_VPLAN_PASS(createAndOptimizeReplicateRegions, Plan);
@@ -3159,11 +3148,22 @@ void VPlanTransforms::optimizeEVLMasks(VPlan &Plan) {
}
}
- // Fold the following splice patterns into vp.reverse for reverse accesses:
+ // Fold the following splice patterns:
+ // splice.right(splice.left(poison, x, evl), poison, evl) -> x
// vector.reverse(splice.left(poison, x, evl)) -> vp.reverse(x, true, evl)
// splice.right(vector.reverse(x), poison, evl) -> vp.reverse(x, true, evl)
for (VPUser *U : collectUsersRecursively(EVL)) {
+ auto *Def = cast<VPRecipeBase>(U);
VPValue *X;
+ if (match(U, m_Intrinsic<Intrinsic::vector_splice_right>(
+ m_Intrinsic<Intrinsic::vector_splice_left>(
+ m_Poison(), m_VPValue(X), m_Specific(EVL)),
+ m_Poison(), m_Specific(EVL)))) {
+ Def->getVPSingleValue()->replaceAllUsesWith(X);
+ OldRecipes.push_back(Def);
+ continue;
+ }
+
if (!match(U,
m_CombineOr(
m_Reverse(m_Intrinsic<Intrinsic::vector_splice_left>(
@@ -3172,12 +3172,11 @@ void VPlanTransforms::optimizeEVLMasks(VPlan &Plan) {
m_Reverse(m_VPValue(X)), m_Poison(), m_Specific(EVL)))))
continue;
- auto *Def = cast<VPSingleDefRecipe>(U);
auto *VPReverse = new VPWidenIntrinsicRecipe(
Intrinsic::experimental_vp_reverse, {X, Plan.getTrue(), EVL},
X->getScalarType(), {}, {}, Def->getDebugLoc());
VPReverse->insertBefore(Def);
- Def->replaceAllUsesWith(VPReverse);
+ Def->getVPSingleValue()->replaceAllUsesWith(VPReverse);
OldRecipes.push_back(Def);
}
diff --git a/llvm/test/Transforms/LoopVectorize/VPlan/simplify-reverse-reverse.ll b/llvm/test/Transforms/LoopVectorize/VPlan/simplify-reverse-reverse.ll
index d78b42640561ce..7e122001d04204 100644
--- a/llvm/test/Transforms/LoopVectorize/VPlan/simplify-reverse-reverse.ll
+++ b/llvm/test/Transforms/LoopVectorize/VPlan/simplify-reverse-reverse.ll
@@ -21,6 +21,7 @@ define void @reverse_copy(ptr noalias %src, ptr noalias %dst, i32 %n) {
; CHECK-NEXT: vp<[[VP5:%[0-9]+]]> = CANONICAL-IV
; CHECK-EMPTY:
; CHECK-NEXT: vector.body:
+; CHECK-NEXT: ir<%iv> = WIDEN-INDUCTION nsw ir<%n>, ir<-1>, vp<[[VP0]]>
; CHECK-NEXT: vp<[[VP6:%[0-9]+]]> = DERIVED-IV ir<%n> + vp<[[VP5]]> * ir<-1>
; CHECK-NEXT: vp<[[VP7:%[0-9]+]]> = SCALAR-STEPS vp<[[VP6]]>, ir<-1>, vp<[[VP0]]>
; CHECK-NEXT: CLONE ir<%iv.next> = add nsw vp<[[VP7]]>, ir<-1>
@@ -30,6 +31,7 @@ define void @reverse_copy(ptr noalias %src, ptr noalias %dst, i32 %n) {
; CHECK-NEXT: EMIT vp<[[VP9:%[0-9]+]]> = reverse ir<%x>
; CHECK-NEXT: CLONE ir<%gep.dst> = getelementptr ir<%dst>, ir<%iv.next>
; CHECK-NEXT: vp<[[VP10:%[0-9]+]]> = vector-end-pointer ir<%gep.dst>, vp<[[VP0]]>
+; CHECK-NEXT: EMIT vp<[[VP11:%[0-9]+]]> = reverse vp<[[VP9]]>
; CHECK-NEXT: WIDEN store vp<[[VP10]]>, ir<%x>
; CHECK-NEXT: EMIT vp<%index.next> = add nuw vp<[[VP5]]>, vp<[[VP1]]>
; CHECK-NEXT: EMIT branch-on-count vp<%index.next>, vp<[[VP2]]>
diff --git a/llvm/test/Transforms/LoopVectorize/VPlan/vplan-print-after-all.ll b/llvm/test/Transforms/LoopVectorize/VPlan/vplan-print-after-all.ll
index 366d4c3e159f65..0de6c306fd36f0 100644
--- a/llvm/test/Transforms/LoopVectorize/VPlan/vplan-print-after-all.ll
+++ b/llvm/test/Transforms/LoopVectorize/VPlan/vplan-print-after-all.ll
@@ -44,6 +44,7 @@
; CHECK: VPlan for loop in 'foo' after reassociateHeaderMask
; CHECK: VPlan for loop in 'foo' after simplifyRecipes
; CHECK: VPlan for loop in 'foo' after removeBranchOnConst
+; CHECK: VPlan for loop in 'foo' after simplifyReverses
; CHECK: VPlan for loop in 'foo' after removeDeadRecipes
; CHECK: VPlan for loop in 'foo' after createAndOptimizeReplicateRegions
; CHECK: VPlan for loop in 'foo' after mergeBlocksIntoPredecessors
More information about the llvm-commits
mailing list