代码分支 / 版本
本机 checkout(不是远程 default),用于复现 clang ICE:
| 仓 |
分支 |
HEAD (short hash + subject) / 版本说明 |
| SuperNPUBench |
main |
f38ee5f Merge pull request #65 from wangyuascend-spec/add-one-level-norm-static |
| SuperScalarModel |
main |
3e1ebf2f Merge pull request llvm#286 from LinxISA/chore/untrack-local-exec-logs |
| Linx-TileOP-API |
本机 src linx tip c02dae6;本 repro 编译用 overlay 6369707(toolchain 默认 pin 分支 linx) |
src:c02dae6 Enforce Group TMATMUL shape contracts。overlay:6369707 Fix TPREFETCH and TSORT bindings(clang++ -resource-dir …/clang_res_6369707)。tip c02dae6 与当前 clang 组合会在 TQUANT %Z 上编不过,故 demo 用 overlay。 |
| llvm-project |
verify/dev-llvm15_56 |
b945a5d01323 [handoff] Record Group TMATMUL Issue 18 acceptance。clang++:15.0.4 (linx64v5-musl-local b945a5d01323de2f38989288d0a4c423abff3ad1) Target linx64v5-unknown-linux-musl |
| linx-toolchain-build |
main |
e6a31ef macOS: install GNU tar for the package step |
| pto-spec |
main |
0b8ce516 arch: add extension first-use profile hook (llvm#101) |
gfrun mtime:2026-08-20 14:15:51(SuperScalarModel/bin/gfrun;本 issue 是 compile-only ICE,不必跑仿真)
- TileOP include 来源:
linx-toolchain-build/src/Linx-TileOP-API 的 linx 分支;demo 实际 -resource-dir 指向 commit 6369707 的头文件树
问题描述与分析
场景抽象
要把 Local tile 数组 当成二分累加 cache:cid = ctz(idx+1) 是运行期整数,需要
TMOV(updateTile[cid], cur) // 把当前部分和写到第 cid 档
TMOV 要求 src/dst 是同一 C++ Tile 类型且各有独立 Local 描述符。运行期下标 upd[cid] 在 SoftCore 上会断言描述符不一致;于是改成编译期展开:
#pragma unroll
for (j = 0; j < N; ++j)
if (j == cid) TMOV(upd[j], cur); // 展开后每条 TMOV 的 dest 是常量槽位
同时还有进位:
#pragma unroll
for (j = 0; j < N; ++j)
if (j < cid) TADD(cur, cur, upd[j]);
这段会 inline 进带循环的 caller。
期望
对 N=6(rms_norm_binary 的 cache 档数)应能编过:展开后每条 TMOV/TADD 的 tile 操作数是静态可知的 Local 寄存器。
实际
clang frontend abort(exit 134):
LinxV5TRegToOffset.cpp:1112
Assertion `ResRegOp == CurRegOp && "Liveouts sync-up error!"' failed.
Running pass 'LinxV5 Treg to Offset' on function '@main'
CFG 是 runtime cid 上的 N 路钻石:每个 if (j==cid) / if (j<cid) 写不同 tile 寄存器,join 时 getLiveoutLimits 认为各前驱 live-out 的 Treg 不一致。
同文件改 kN 的边界(同一 compile.sh):
kN |
结果 |
| 2 |
编过 |
| 3、4 |
template_asm.hpp TMOV:Match Instruction Error!(另一条 lowering 失败) |
| 5、6 |
本 ICE(Liveouts sync-up error) |
相关(不是本 ICE,但是同一需求)
TMOV(upd[cid], cur)(运行期下标、不展开)当前 能编过,但 gfrun -f 立刻:
ASSERTION FAILED: ... srcTile[0]->tileInfo->row == dstTile[0]->tileInfo->row ...
"PTO 0.58 Local TMOV requires matching source/destination descriptors"
ValidateOperandContract SuperScalarModel/isa/Block.cpp:1099
说明动态 dest 的 TMOV 被编成了描述符不匹配的 TLSU。更理想的修复是:数组槽位有独立、匹配的 Local tileInfo,或前端拒绝无法证明匹配的 TMOV。
kernel 侧 workaround:不用 TMOV,改 TMULS(dst, src, 1.0f) 做同类型拷贝(device 无 TCOPY,#ifndef __linx)。
触发背景:SuperNPUBench rms_norm_binary 想把 UpdateCache 从 GM TLOAD/TSTORE 改成本地 tile list。
复现方式
独立 demo(不依赖 rms_norm 本体),本机已跑通 ICE:
SuperNPUBench/Daily/2026-08-20/tmov_select_treg_liveout/
tmov_select_treg.cpp
compile.sh
compile.log
export COMPILER_DIR=/path/to/linx_blockisa_llvm_musl/bin
# TileOP 头用 6369707 overlay(见版本表);或等价 -resource-dir
bash Daily/2026-08-20/tmov_select_treg_liveout/compile.sh
最小源码:
#include <common/pto_tileop.hpp>
#include <cstdint>
using namespace pto;
constexpr int kN = 6;
using TileV = Tile<Location::Vec, float, 1, 128, BLayout::RowMajor, 1, 1>;
inline int cache_id(int64_t idx) {
return static_cast<int>(
__builtin_ctzll(static_cast<unsigned long long>(idx + 1)));
}
inline void update_cache(TileV (&upd)[kN], TileV &cur, int64_t &r) {
const int cid = cache_id(r);
#pragma clang loop unroll(full)
for (int j = 0; j < kN; ++j) {
if (j < cid) {
TADD(cur, cur, upd[j]);
}
}
#pragma clang loop unroll(full)
for (int j = 0; j < kN; ++j) {
if (j == cid) {
TMOV(upd[j], cur);
}
}
++r;
}
int main() {
TileV upd[kN];
TileV cur, sum;
int64_t r = 0;
for (int i = 0; i < 8; ++i) {
TEXPANDS(cur, 1.0f);
update_cache(upd, cur, r);
}
TMULS(sum, upd[cache_id(r - 1)], 1.0f);
float buf[128];
using gm_t = global_tensor<float, RowMajor<1, 128>>;
gm_t g(buf);
TSTORE(g, sum);
}
编译要点(与 one-level Makefile 一致):-c -mlxbc -fenable-matrix -O2 -mllvm -enable-all-vector-as-tilereg=true 以及 LinxV5 HL/dim/simt 那组 -mllvm,-D__linx -DENABLE_TENSOR_INSTR,-std=c++20。只需 -c,不需要 link / gfrun。
__attribute__((noinline)) 且去掉 TADD 循环、只留 if (j==cid) TMOV 时,本机 N=4 能编过;必须把 TADD 进位 + TMOV 选择一起 inline 进带循环的 caller,且 N≥5,才会打到这条 Treg live-out ICE。
代码分支 / 版本
本机 checkout(不是远程 default),用于复现 clang ICE:
mainf38ee5fMerge pull request #65 from wangyuascend-spec/add-one-level-norm-staticmain3e1ebf2fMerge pull request llvm#286 from LinxISA/chore/untrack-local-exec-logslinxtipc02dae6;本 repro 编译用 overlay6369707(toolchain 默认 pin 分支linx)c02dae6Enforce Group TMATMUL shape contracts。overlay:6369707Fix TPREFETCH and TSORT bindings(clang++ -resource-dir …/clang_res_6369707)。tipc02dae6与当前 clang 组合会在 TQUANT%Z上编不过,故 demo 用 overlay。verify/dev-llvm15_56b945a5d01323[handoff] Record Group TMATMUL Issue 18 acceptance。clang++:15.0.4 (linx64v5-musl-local b945a5d01323de2f38989288d0a4c423abff3ad1)Targetlinx64v5-unknown-linux-muslmaine6a31efmacOS: install GNU tar for the package stepmain0b8ce516arch: add extension first-use profile hook (llvm#101)gfrunmtime:2026-08-20 14:15:51(SuperScalarModel/bin/gfrun;本 issue 是 compile-only ICE,不必跑仿真)linx-toolchain-build/src/Linx-TileOP-API的linx分支;demo 实际-resource-dir指向 commit6369707的头文件树问题描述与分析
场景抽象
要把 Local tile 数组 当成二分累加 cache:
cid = ctz(idx+1)是运行期整数,需要TMOV要求 src/dst 是同一 C++ Tile 类型且各有独立 Local 描述符。运行期下标upd[cid]在 SoftCore 上会断言描述符不一致;于是改成编译期展开:同时还有进位:
这段会 inline 进带循环的 caller。
期望
对
N=6(rms_norm_binary 的 cache 档数)应能编过:展开后每条TMOV/TADD的 tile 操作数是静态可知的 Local 寄存器。实际
clang frontend abort(exit 134):
CFG 是 runtime
cid上的 N 路钻石:每个if (j==cid)/if (j<cid)写不同 tile 寄存器,join 时getLiveoutLimits认为各前驱 live-out 的 Treg 不一致。同文件改
kN的边界(同一 compile.sh):kNtemplate_asm.hppTMOV:Match Instruction Error!(另一条 lowering 失败)Liveouts sync-up error)相关(不是本 ICE,但是同一需求)
TMOV(upd[cid], cur)(运行期下标、不展开)当前 能编过,但gfrun -f立刻:说明动态 dest 的 TMOV 被编成了描述符不匹配的 TLSU。更理想的修复是:数组槽位有独立、匹配的 Local tileInfo,或前端拒绝无法证明匹配的 TMOV。
kernel 侧 workaround:不用 TMOV,改
TMULS(dst, src, 1.0f)做同类型拷贝(device 无TCOPY,#ifndef __linx)。触发背景:
SuperNPUBenchrms_norm_binary想把 UpdateCache 从 GMTLOAD/TSTORE改成本地 tile list。复现方式
独立 demo(不依赖 rms_norm 本体),本机已跑通 ICE:
最小源码:
编译要点(与 one-level Makefile 一致):
-c -mlxbc -fenable-matrix -O2 -mllvm -enable-all-vector-as-tilereg=true以及 LinxV5 HL/dim/simt 那组-mllvm,-D__linx -DENABLE_TENSOR_INSTR,-std=c++20。只需-c,不需要 link / gfrun。__attribute__((noinline))且去掉 TADD 循环、只留if (j==cid) TMOV时,本机 N=4 能编过;必须把 TADD 进位 + TMOV 选择一起 inline 进带循环的 caller,且 N≥5,才会打到这条 Treg live-out ICE。