[TritonToLinalg](fix) Restore addptr foading - #1518
Open
CHNJZ wants to merge 1 commit into
Open
Conversation
Contributor
|
✅ OpenCodeReview: Review partially complete: 0 finding(s); 3 of 8 selected item(s) failed. |
CHNJZ
force-pushed
the
addptrop
branch
3 times, most recently
from
August 13, 2026 02:44
dae1825 to
235beb2
Compare
CHNJZ
force-pushed
the
addptrop
branch
2 times, most recently
from
August 13, 2026 09:26
420c6eb to
955ed1e
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.
Background
Upstream Triton defines a standard folder for
tt.addptr:tt.addptr(ptr, 0)is canonicalized to the original pointer.The Ascend backend previously used
tt.addptras the common entry point for pointer analysis and memory lowering. To prevent a synthetic zero-offsettt.addptrfrom being folded before reachingAddPtrConverter, the backend commented out bothTT_AddPtrOp::hasFolderandAddPtrOp::fold()in the shared Triton dialect. This changed upstream canonicalization behavior and introduced an invasive community-code modification.This PR restores the upstream implementation:
and re-enables:
Once the folder is restored, Ascend pointer lowering can no longer assume that every memory pointer is produced by
tt.addptr. This PR therefore also removes the backend dependency on syntheticAddPtr(ptr, 0)anchors.Problem
The previous
LoadStoreCanonicalizerinspected the pointer operands of Load, Store, AtomicRMW, and AtomicCAS operations. When a pointer was not produced bytt.addptr, the canonicalizer inserted a zero-offsettt.addptrto trigger the downstreamAddPtrConverter.Current TTIR:
The previous canonicalizer rewrote it as:
After restoring
AddPtrOp::fold(),%addris immediately folded back to%ptrs. UnderapplyPatternsGreedily(), this creates the following rewrite cycle:The rewrite never reaches a fixed point, so
TritonToLinalgcompilation hangs.The root cause is not the upstream
addptr(ptr, 0) -> ptrfold. The actual issue is that the Ascend backend treated a semantically redundant+0 AddPtras a mandatory pointer-lowering entry point.Solution
This PR separates pointer lowering into two paths:
tt.addptr(base, offset)exists: preserve the actual address calculation and continue usingAddPtrConverter.AddPtr(ptr, 0).Load, Store, Atomic, and indirect-memory consumers resolve their pointers at the consumption boundary. This also removes the dependency on the execution order of producer and consumer conversion patterns.
Covered scenarios
1. Recover a real AddPtr hidden by Splat
Optimizations such as
ReorderBroadcastmay transform tensor pointer arithmetic intosplat(addptr(base, offset)). The offset in this expression represents a real address calculation and must be preserved.Current TTIR:
It can be rewritten as:
The updated
LoadStoreCanonicalizeronly recovers this kind of real AddPtr. It no longer inserts a zero offset for ordinary pointers.2. Materialize a pointer Splat without a real AddPtr
A plain
splat(base)does not contain pointer arithmetic, so a synthetic+0must not be introduced.Current TTIR:
It is materialized directly as:
The zero stride means that all four lanes access the same base address.
BlockDataParserpreserves this layout, and the Load, Store, and Atomic converters consume%viewdirectly.3. Materialize a pointer Bitcast directly
Current TTIR:
It is materialized directly as:
Only the memref element type changes; the original offsets, sizes, and strides are preserved. Pointer Broadcast and ExpandDims expressions are recursively handled through the same materialization entry point.
4. Resolve Load, Store, and Atomic pointers through one entry point
This PR adds a shared pointer-resolution helper:
The helper uses the following order:
SrcPtrIndex, rematerialize its inherited layout first.BlockDataParser::materializePointer()on the original TTIR pointer expression.The helper is used by:
LoadConverterStoreConverterAtomicRMWConverterAtomicCASConverter5. Preserve Structured CustomOp pointer-result layouts
A Structured CustomOp may use
SrcPtrIndexto indicate that a pointer result inherits the address layout of a specific input.Current TTIR:
Converted IR:
resolveMemoryPointer()must not return immediately just because the converted CustomOp result already has a memref type. Doing so would lose the layout inherited throughSrcPtrIndex. The new implementation gives this case priority and invokesmaterializePointer().LoadConverteralso no longer assumes that every valid memref is produced bymemref.reinterpret_cast. When a pointer comes directly from a CustomOp or a function argument, the converter obtains the static innermost stride from the memref type instead of dereferencing a missingReinterpretCastOpproducer.6. Support
int_to_ptrindirect loadsThe previous
TritonToUnstructurepath wrappedtt.int_to_ptrin a synthetic scalar zero AddPtr:Because
%anchornecessarily disappears after the folder is restored, the updated implementation removes this wrapper and preserves the actual source directly:In
TritonToLinalg,IndirectLoadConvertermaterializes the pointer at the consumer boundary:requiresVolatileIndirectLoad()still examines the original load pointer, so volatile semantics for unknown integer addresses are preserved.7. Fold a zero AddPtr used as a CustomOp input
Input TTIR:
After restoring the folder, the zero AddPtr is removed according to upstream semantics, and the CustomOp receives the converted base memref directly:
The previous
memref<1xi64, strided<[1]>>input was a view created only because the synthetic zero AddPtr reachedAddPtrConverter. The old and new IR refer to the same underlying address. For this structural conversion test, the FileCheck expectation should be updated instead of recreating a+0 AddPtrmerely to preserve the old IR shape.If a real CustomOp ABI explicitly depends on size or stride descriptor values, the required view should be created explicitly at that ABI-lowering boundary.
8. Use an Atomic result as a dynamic address offset
In the following case, the old value returned by
atomic_addis used as a subsequent load or store offset:AtomicRMWConverternow invokes the resolver first and obtainsMemRefTypefrom the resolved value rather than from the pre-resolution pointer. The dynamic offset is then preserved inmemref.reinterpret_cast: