From a66ab22eaa55a7f1b892de6fc4c871828d774b6f Mon Sep 17 00:00:00 2001 From: liuzidi Date: Sat, 29 Aug 2026 17:00:41 +0800 Subject: [PATCH] test(vexpdif): rewrite pto_vexpdif_fusion as vreg-level pto-test-opt case The end-to-end ptoas RUN drove the test through TileLib template expansion, where tsub/texp fall back to ordinary PTODSL templates in separate local-boundary loops. The intervening vsts/vlds broke the vsub->vexp SSA chain that PTOVexpdifFusion matches, so the pass never fired and the lit failed on a clean main-llvm19-build checkout. Rewrite the case as hand-written vreg IR exercised via pto-test-opt, the same pattern used by the mask/f16/multiuse siblings. A single-use f32 vsub feeding vexp inside one fusion_region with one shared mask SSA now fuses into pto.vexpdif "ODD" as intended. This decouples the positive f32 fusion case from the ptoas pipeline, TileLib templates, and local-boundary fallback behavior. Drop the second RUN that lowered to LLVM IR; it depended on the full ptoas pipeline and its coverage is already provided by test/lit/vmi_new/vmi_to_vpto_vexpdif_f16.pto and vmi_layout_assignment_vexpdif.pto. --- test/lit/tile_fusion/pto_vexpdif_fusion.pto | 71 +++++++-------------- 1 file changed, 22 insertions(+), 49 deletions(-) diff --git a/test/lit/tile_fusion/pto_vexpdif_fusion.pto b/test/lit/tile_fusion/pto_vexpdif_fusion.pto index a6767e807b..ce9614bb6f 100644 --- a/test/lit/tile_fusion/pto_vexpdif_fusion.pto +++ b/test/lit/tile_fusion/pto_vexpdif_fusion.pto @@ -2,63 +2,36 @@ // This program is free software; you can redistribute it and/or modify it under the terms and conditions of // CANN Open Software License Agreement Version 2.0 (the "License"). // Please refer to the License for details. THIS SOFTWARE IS PROVIDED ON AN -// "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, -// INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS -// FOR A PARTICULAR PURPOSE. See LICENSE in the root of the software repository +// "AS IS" BASIS, WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING +// BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR +// A PARTICULAR PURPOSE. See LICENSE in the root of the software repository // for the full text of the License. -// Positive case for the pto-vexpdif-fusion pass over a real ptoas pipeline. -// A single-use f32 tsub + texp sequence lowers to vsub + vexp inside a -// pto.fusion_region and is fused into pto.vexpdif ("ODD"). vexpdif fusion is -// enabled by default; pass --enable-vexpdif-fusion=false to opt out. +// Positive case for the pto-vexpdif-fusion pass. A single-use f32 `vsub` +// followed by a f32 `vexp`, both sharing one mask SSA inside a +// pto.fusion_region, fuses into `pto.vexpdif "ODD"`. vexpdif fusion is enabled +// by default; pass --enable-vexpdif-fusion=false to opt out. +// +// Unlike the mask/f16/multiuse siblings, this is a direct vreg-level positive +// case: the pass is exercised on hand-written vector IR through pto-test-opt, +// so it stays decoupled from the full ptoas pipeline and the TileLib template +// / local-boundary behavior that only the end-to-end path exercises. -// RUN: ptoas --pto-backend=vpto --pto-arch=a5 --pto-level=level2 --enable-op-fusion --enable-vexpdif-fusion --emit-vpto %s --mlir-print-ir-after=pto-vexpdif-fusion -o /dev/null 2>&1 | FileCheck %s -// RUN: ptoas --pto-backend=vpto --pto-arch=a5 --pto-level=level2 --enable-op-fusion --enable-vexpdif-fusion --emit-vpto-llvm-ir %s -o - 2>&1 | FileCheck %s --check-prefix=LLVM +// RUN: pto-test-opt %s -pto-vexpdif-fusion | FileCheck %s -module attributes {pto.kernel_kind = #pto.kernel_kind} { - func.func @vexpdif_fusion(%dst_ptr : !pto.ptr) { - %c0 = arith.constant 0 : index - %c1 = arith.constant 1 : index - %c16 = arith.constant 16 : index - %c64 = arith.constant 64 : index - %c1024 = arith.constant 1024 : index - %dst_view = pto.make_tensor_view %dst_ptr, - shape = [%c1, %c1, %c1, %c16, %c64], - strides = [%c1024, %c1024, %c1024, %c64, %c1] - : !pto.tensor_view<1x1x1x16x64xf32> - %dst_part = pto.partition_view %dst_view, - offsets = [%c0, %c0, %c0, %c0, %c0], - sizes = [%c1, %c1, %c1, %c16, %c64] - : !pto.tensor_view<1x1x1x16x64xf32> -> !pto.partition_tensor_view<1x1x1x16x64xf32> - %a = pto.alloc_tile - : !pto.tile_buf - %b = pto.alloc_tile - : !pto.tile_buf - %sub = pto.alloc_tile - : !pto.tile_buf - %result = pto.alloc_tile - : !pto.tile_buf - - pto.tsub ins(%a, %b : !pto.tile_buf, - !pto.tile_buf) - outs(%sub : !pto.tile_buf) - pto.texp ins(%sub : !pto.tile_buf) - outs(%result : !pto.tile_buf) - pto.tstore ins(%result : !pto.tile_buf) - outs(%dst_part : !pto.partition_tensor_view<1x1x1x16x64xf32>) - return +module { + func.func @vexpdif_fusion(%a : !pto.vreg<64xf32>, %b : !pto.vreg<64xf32>) -> !pto.vreg<64xf32> { + %res = pto.fusion_region { + %m = pto.pset_b32 "PAT_ALL" : !pto.mask + %sub = pto.vsub %a, %b, %m : !pto.vreg<64xf32>, !pto.vreg<64xf32>, !pto.mask -> !pto.vreg<64xf32> + %exp = pto.vexp %sub, %m : !pto.vreg<64xf32>, !pto.mask -> !pto.vreg<64xf32> + pto.yield(%exp) : (!pto.vreg<64xf32>) -> () + } : !pto.vreg<64xf32> + return %res : !pto.vreg<64xf32> } } // CHECK-LABEL: func.func @vexpdif_fusion( -// CHECK: pto.fusion_region // CHECK: pto.vexpdif {{.*}} "ODD" // CHECK-NOT: pto.vsub // CHECK-NOT: pto.vexp {{.*}} : - -// LLVM-LABEL: define void @vexpdif_fusion -// LLVM: call {{.*}} @llvm.hivm.vexpdif