Skip to content

Select immediate DIM encodings when LinxISA tile shape operands are ConstantInt #73

Description

@zhoubot

Summary

When valid column, valid row, and physical column are already compile-time
constants in optimized LLVM IR, preserve that fact through LinxISA tile
intrinsic selection and prefer the smallest legal immediate DIM encoding.

This issue owns the Linx LLVM ISel/combine/MIR/MC lowering contract. The
SuperNPUBench source/API audit is tracked by
PTO-ISA/SuperNPUBench#88.
That issue must provide a minimal C++ reproducer and optimized IR proving the
shape operands are ConstantInt. LLVM must not guess constants that were lost
before the intrinsic/backend boundary.

Artifact evidence

Authoritative historical disassembly:

  • FP32 multi-thread FA cube-layout .elf.diss
  • SuperNPUBench commit: f2ccec38c4cb4210143018a003b1fedc3a0ca251
  • Artifact toolchain: Clang 15.0.4
    linx64v5-musl-local e8242e9627c4634a09055c59f729a4482b297212,
    LLD 15.0.4

The function contains 116 B.DIM, 48 C.B.DIMI, and no B.DIMI. All 116
register-form dimensions use registers that are constant-materialized once:

Register Definition Uses
a7 addi zero, 128, ->a7 26
x2 c.movi 1, ->x2 15
a1 addi zero, 32, ->a1 45
s0 addi zero, 64, ->s0 30

Representative missed opportunities:

# 128, 128, 128
11406: BSTART.TLSU TLOAD, FP32
1140a: B.DIM a7, 0, ->lb0
1140e: B.DIM a7, 0, ->lb1
11412: C.B.DIMI 128, ->lb2

# 128, 64, 128
114d4: BSTART.CUBE TMATMUL, FP32
114e0: B.DIM a7, 0, ->lb0
114e4: B.DIM s0, 0, ->lb1
114e8: B.DIM a7, 0, ->lb2

# 1, 32, 8
1157c: BSTART.TEPL TMAX, FP32
11580: B.DIM x2, 0, ->lb0
11584: B.DIM a1, 0, ->lb1
11588: C.B.DIMI 8, ->lb2

The artifact shows the output shape, but its exact cube-layout source file is
not present on current SuperNPUBench main. Treat source-side constant visibility
as an explicit handoff requirement, not an assumption.

Current backend evidence

At current Linx LLVM HEAD:

  • LinxISAInstrInfo.td shape-carrying tile pseudos declare valid column, valid
    row, and physical column as GPR_Arch operands.
  • LinxISABlockify.cpp:2234-2249 has emitDim: values 0..255 become
    C_B_DIMI; larger immediates become B_DIM_LB* with R0 plus uimm.
  • LinxISABlockify.cpp:2251-2260 has emitDimReg, which always emits
    register-form B_DIM_LB*.
  • Shape paths such as TLOAD/TSTORE and TEPL call emitDimReg directly
    (~2400, ~2516, ~2835), so a constant that has already been coerced into
    a GPR pseudo operand cannot reach emitDim without a constant-aware combine
    or a better pseudo/intrinsic contract.

This is the likely compiler-side loss point only when optimized IR/MIR proves
the operand constant
. If the IR from #88 contains loads, runtime fields, or
opaque calls, return the issue to the benchmark/API owner instead of adding
value guessing.

Active ISA encoding contract

Use the repository-pinned v0.58 catalog as authority:

  • C.B.DIMI imm, ->LB{0,1,2} is the 16-bit compressed immediate form with an
    8-bit immediate field.
  • The current catalog's 32-bit non-compressed form is
    B.DIM RegSrc, uimm17, ->LB{0,1,2}.
  • The current catalog does not define a standalone B.DIMI mnemonic.

Therefore the selection contract is:

  1. If a constant fits C.B.DIMI, use the compressed form.
  2. Otherwise, if it fits the catalog's B.DIM immediate field, use
    B.DIM zero, uimm, ->LB* (or the exact canonical zero-register spelling).
  3. Use B.DIM <reg>, 0, ->LB* only for truly runtime values.
  4. If another pinned profile defines B.DIMI, select it only under that exact
    profile; do not invent or revive a spelling absent from v0.58.

Non-goals and semantic constraints

Do not change:

  • valid-row, valid-column, or physical-column meaning;
  • tail validity or out-of-bounds behavior;
  • Local versus Shared tile ownership;
  • CUBE layout or B.FPATR attributes;
  • per-PE partitioning, B.IOS/B.IOT masks, or TSize;
  • queue ordering, bundle boundaries, or numeric results.

Linx LLVM #72 tracks objdump indentation only and is not part of this semantic
optimization.

Required handoff from SuperNPUBench#88

Before treating this as an LLVM defect, attach:

  • the instantiated C++ command and all dependency pins;
  • Clang AST evidence for the static NTTP/constexpr shape;
  • unoptimized and optimized IR;
  • a minimal intrinsic call where valid col/row/physical col are literal
    ConstantInt operands;
  • a separate runtime-shape IR case for fallback behavior.

Acceptance criteria

  • Add IR/CodeGen tests with literal shape operands and verify:
    • compressed values select C.B.DIMI;
    • larger legal constants select B.DIM zero,uimm under v0.58;
    • no redundant GPR constant materialization remains for those dimensions.
  • Add a true dynamic test whose shape comes from a function parameter or load
    and remains B.DIM <reg>,0.
  • Cover valid column, valid row, and physical column independently.
  • Cover TLSU, Local/Shared tile operations, TEPL VEC/SFU operations, and CUBE
    TMATMUL headers.
  • Include tail/valid-shape cases proving runtime tails are not replaced by
    full-tile constants.
  • Add MIR or combine tests around the GPR shape pseudo boundary if constants
    arrive there after generic ISel.
  • Add MC/lit/FileCheck coverage for the catalog-legal immediate boundaries and
    negative overflow cases.
  • Run an integrated clang → ELF → matching llvm-objdump test and archive
    exact compiler/objdump --version output.
  • Compare object disassembly before/after and run the repository's current
    numerical/model regression lane for the handed-off FA reproducer.
  • Validate against current repository pins. The Clang 15 artifact is historical
    evidence only; do not use an incompatible LLVM 23 decoder to reinterpret its
    old encodings.

Duplicate audit

No existing open or closed issue specifically tracks ConstantInt-driven DIM
immediate selection. Related issues are not duplicates:

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions