[llvm] [VPlan] Fold reverse(reverse(x)) -> x in simplifyRecipe() (PR #196900)
David Sherwood via llvm-commits
llvm-commits at lists.llvm.org
Mon May 11 02:13:43 PDT 2026
================
@@ -0,0 +1,84 @@
+; NOTE: Assertions have been autogenerated by utils/update_analyze_test_checks.py UTC_ARGS: --version 6
+; RUN: opt -passes=loop-vectorize -force-vector-width=4 \
+; RUN: -vplan-print-after="printFinalVPlan$" -disable-output %s 2>&1 | \
+; RUN: FileCheck %s
+
+; A descending-index copy loop with reverse-consecutive load and store
+; originally produces chained VPInstruction::Reverse recipes (one after the
+; load, one feeding the store). After VPlanTransforms::simplifyRecipes folds
+; reverse(reverse(x)) -> x the two cancel and are removed by the subsequent
+; dead-recipe cleanup, so no reverse recipe is emitted in the final VPlan.
+
+define void @reverse_copy(ptr noalias %dst, ptr noalias %src, i64 %n) {
+; CHECK-LABEL: VPlan for loop in 'reverse_copy'
+; CHECK: VPlan 'Final VPlan for VF={4},UF={1}' {
+; CHECK-NEXT: Live-in ir<%1> = original trip-count
+; CHECK-EMPTY:
+; CHECK-NEXT: ir-bb<entry>:
+; CHECK-NEXT: IR %0 = add nsw i64 %n, -1
+; CHECK-NEXT: IR %smin = call i64 @llvm.smin.i64(i64 %0, i64 0)
+; CHECK-NEXT: IR %1 = sub i64 %n, %smin
+; CHECK-NEXT: EMIT vp<%min.iters.check> = icmp ult ir<%1>, ir<4>
+; CHECK-NEXT: EMIT branch-on-cond vp<%min.iters.check>
+; CHECK-NEXT: Successor(s): ir-bb<scalar.ph>, vector.ph
+; CHECK-EMPTY:
+; CHECK-NEXT: vector.ph:
+; CHECK-NEXT: EMIT vp<%n.mod.vf> = urem ir<%1>, ir<4>
+; CHECK-NEXT: EMIT vp<%n.vec> = sub ir<%1>, vp<%n.mod.vf>
+; CHECK-NEXT: EMIT vp<[[VP3:%[0-9]+]]> = sub ir<%n>, vp<%n.vec>
+; CHECK-NEXT: Successor(s): vector.body
+; CHECK-EMPTY:
+; CHECK-NEXT: vector.body:
+; CHECK-NEXT: EMIT-SCALAR vp<%index> = phi [ ir<0>, vector.ph ], [ vp<%index.next>, vector.body ]
+; CHECK-NEXT: EMIT vp<[[VP4:%[0-9]+]]> = sub ir<%n>, vp<%index>
+; CHECK-NEXT: CLONE ir<%iv> = add nsw vp<[[VP4]]>, ir<-1>
+; CHECK-NEXT: CLONE ir<%gep.src> = getelementptr inbounds ir<%src>, ir<%iv>
+; CHECK-NEXT: vp<[[VP5:%[0-9]+]]> = vector-end-pointer inbounds ir<%gep.src>, ir<4>, ir<-3>
+; CHECK-NEXT: WIDEN ir<%l> = load vp<[[VP5]]>
+; CHECK-NEXT: CLONE ir<%gep.dst> = getelementptr inbounds ir<%dst>, ir<%iv>
+; CHECK-NEXT: vp<[[VP6:%[0-9]+]]> = vector-end-pointer inbounds ir<%gep.dst>, ir<4>, ir<-3>
+; CHECK-NEXT: WIDEN store vp<[[VP6]]>, ir<%l>
+; CHECK-NEXT: EMIT vp<%index.next> = add nuw vp<%index>, ir<4>
+; CHECK-NEXT: EMIT vp<[[VP7:%[0-9]+]]> = icmp eq vp<%index.next>, vp<%n.vec>
+; CHECK-NEXT: EMIT branch-on-cond vp<[[VP7]]>
+; CHECK-NEXT: Successor(s): middle.block, vector.body
+; CHECK-EMPTY:
+; CHECK-NEXT: middle.block:
----------------
david-arm wrote:
nit: You could reduce the number of CHECK lines by adding the flag `-filter-out-after=middle.block:` when running the update_test_checks.py script?
https://github.com/llvm/llvm-project/pull/196900
More information about the llvm-commits
mailing list