perf(vpto): non-negative ranges for SIMT hardware ID ops + range-driven arith opts (floordivsi/remsi by pow2) - #1497
Draft
jimmychou0 wants to merge 1 commit into
Conversation
jimmychou0
force-pushed
the
zjm/issue1493-tid-pow2-range
branch
from
September 9, 2026 07:35
c75288f to
ad1ad05
Compare
Contributor
Author
|
Review 意见已全部修复(ad1ad0551):
验证:238b 全量重建 0 error;lit 两个用例(tid + block_idx)FileCheck 实跑 PASS;真实 kernel 端到端 .text 仍与手改 and/lshr 版逐字节相同(md5 6e851189,P2 修复未改变 tid 路径产出);真机数值 AMAX+FP8 PASS,延迟 0.4919ms。 |
jimmychou0
force-pushed
the
zjm/issue1493-tid-pow2-range
branch
4 times, most recently
from
September 10, 2026 08:48
58a0c3c to
e20e481
Compare
Contributor
Author
|
新增:block query 的 AIC 编排路径(非 SIMT entry)现在也走 32 位 tpe intrinsic + zext,与 SIMT 路径和 CCE 前端语义一致( |
jimmychou0
force-pushed
the
zjm/issue1493-tid-pow2-range
branch
6 times, most recently
from
September 11, 2026 07:06
55af82a to
9dec823
Compare
Contributor
|
Warning: @jimmychou0, ci-sim exceeded its soft runtime budget.
This warning is advisory only and does not affect required checks. Please inspect the step timings for an unexpected regression. |
jimmychou0
force-pushed
the
zjm/issue1493-tid-pow2-range
branch
2 times, most recently
from
September 13, 2026 10:39
9b001be to
316068e
Compare
jimmychou0
force-pushed
the
zjm/issue1493-tid-pow2-range
branch
4 times, most recently
from
September 15, 2026 08:39
896f871 to
0ceed82
Compare
…en arith opts Implement InferIntRangeInterface on the provably non-negative hardware ID queries and run the upstream arith integer-range optimizations early in the VPTO backend pipeline, so floordivsi/remsi by a power of two on thread/block indices reach the LLVM backend as udiv/urem instead of the signed-division guard chain. Covers both dialects: the VPTO SIMT queries (get_tid_x/y/z with [0, dim-1] from section.simt launch dims, get_block_idx_x/y/z, get_block_dim_*, get_grid_dim_*, get_veccoreid, get_laneid) and the PTO-level i64 runtime queries (get_block_idx, get_subblock_idx [0,1], get_block_num, get_subblock_num) used by cube-side orchestrators. pto.get_block_idx reports [0, INT32_MAX]: the value is a 32-bit quantity on the hardware and the LLVM lowering rounds it through i32 on every path, so the tight claim matches what the lowered code actually computes. Counts stay at [0, INT64_SIGNED_MAX] so `cmpi sge block_num, 1` guards remain dynamic. Block queries are rounded through i32 on all paths (both emitters), matching the CCE frontend where __builtin_cce_get_block_idx/get_block_num are int32_t: inside simt_entry functions the query calls the 32-bit tpe intrinsic and zero-extends to the i64 PTO result; the AIC orchestrator path must keep the 64-bit intrinsic (the tpe form is only legal in simt_entry), so it truncates the result to i32 and zero-extends back. Building on those range facts, a second step narrows element-offset chains feeding pto.load/pto.store into i32 whenever a local recursive range evaluation proves the whole chain stays in [0, 2^32) — the chain is converted back with arith.index_castui at the offset operand, so the narrowed arithmetic includes any term that only ADDS the block index (e.g. `w*2048 + (tid/32)*64 + block_idx`), matching the all-int32 addressing the AscendC frontend emits. andi and pto.addptr chains are deliberately excluded: the MTE copy addresses they feed are strength-reduced by the backend into per-iteration recurrences, and inserting trunc/zext into those chains measurably regresses the kernel. On the SIMT-VF per-token cast-to-fp8 example (8192x8192) the narrowed kernel measures ~1.5% faster than both the un-narrowed build and the AscendC-backend build of the same program on a quiet A5 board (0.283 ms vs 0.288 ms across interleaved A/B rounds), with numerics unchanged. The evaluator keeps signed and unsigned semantics apart: a signed index_cast is only value-preserving when it does not widen with the sign bit reachable, and the signed div/rem flavors require the whole proven window (numerator and divisor) to keep the sign bit clear. Divisors are additionally required to fit u32 so the i32 mirror cannot truncate them into a different value or a division by zero. --pto-disable-offset-narrowing turns just the narrowing step off for field triage. Four existing lit tests are updated for the new canonical forms (extsi->extui on tid, floordivsi->divui on block queries, cmpi sge->uge on non-negative operands, tpe i32 callees on AIC queries); one tautological guard whose loop bound equals the guard bound is decoupled so the guard stays dynamic; a new test covers both the subchain and full-chain (block-index add included) narrowing outcomes plus the [0,1] subblock fold, the excluded wrapping/lanemask queries (which must keep sdiv/srem), the remaining ranged queries (laneid, veccoreid, block_dim, grid_dim), a signed widening cast with the sign bit reachable, divisors of 2^32 and 2^32+1, and the tautological-guard fold. The micro-ISA entries for laneid/veccoreid/block_dim/grid_dim now state their ranges so the non-negative claims have a written source. Closes hw-native-sys#1493.
jimmychou0
force-pushed
the
zjm/issue1493-tid-pow2-range
branch
from
September 15, 2026 11:01
0ceed82 to
c9b0039
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Closes #1493.
Range-driven arith optimizations for SIMT scalar index math, following the
approach agreed in the issue discussion:
InferIntRangeInterface—get_tid_x/y/z,get_block_idx_x/y/z,get_block_dim_x/y/z,get_grid_dim_x/y/z,get_veccoreid,get_laneidreport non-negativeresult ranges. Thread indices are tightened to
[0, dim-1]when theenclosing
pto.section.simt<<<...>>>carries static launch dims.Deliberately excluded (not provably non-negative):
get_clock32/64(wraps) and
get_lanemask_*(sign bit can be set).pto-arith-range-optimizepass wired into the VPTO backendpipeline (before
VPTOSplitCVModulePass, where the SIMT queries are stillpresent). It runs the upstream
arith::createIntRangeOptimizationsPass()+createArithUnsignedWhenEquivalentPass()+ canonicalize — no customrewrite rules, so ops whose range cannot be proven are left unchanged
(the "keep as-is when analysis fails" expectation from the issue).
With the non-negative ranges, the upstream passes rewrite
arith.floordivsi/remsi <tid>, 2^kintoudiv/urem, and the LLVM backendfolds those into shifts/masks — eliminating the 9-instruction
signed-division guard chain that currently reaches every SIMT warp.
Validation
test/lit/pto/issue1493_tid_pow2_range.pto: the issue's repro pattern(
tid % 32 == 0guard +(tid // 32) * 64addressing insidepto.section.simt) asserts the emitted VPTO LLVM IR containsudiv/uremand nosdiv/srem.issue, 8192x8192):
.ptoinput now emitsurem/udiv(guard chain gone);.textis byte-identical to the hand-verifiedand/lshrrewrite from the issue (1112 vs 1192 bytes, −20 instructionwords);
0.4936 ms baseline on the same box, consistent with the 0.3–0.5%
measured on three CANN versions).
ninjabuild of ptoas with the change on x86 CANN 9.1.0.