AOT object emission fails on a placed matmul: DISubprogram attached to more than one function
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 14
- Forks
- 2
- Avg merge
- 12h 42m
- Merged PRs (30d)
- 61
Description
vxc -c (--action emit-obj) fails the LLVM verifier on any program containing a placed matrix multiply:
$ vxc mm.vx -c -o mm.o
DISubprogram attached to more than one function
!3 = distinct !DISubprogram(name: "main", scope: !1, file: !1, type: !4, spFlags: DISPFlagDefinition, unit: !0)
ptr @_mlir_ciface_main
Reduced reproducer:
fn main() -> i32 {
let mut a : Tensor<f32> = Tensor<f32>([ 2, 2 ]);
let mut b : Tensor<f32> = Tensor<f32>([ 2, 2 ]);
let mut c : Tensor<f32> = Tensor<f32>([ 2, 2 ]);
spawn on(Topology::GPU) {
c = a @b;
}
print(c[0][0]);
return 0;
}
Narrowed by bisection -- these all emit an object successfully:
- a program with no tensors at all
- a tensor written and read, no
spawn - a
spawn on(Topology::GPU)doing an element-wise copy
Replacing that copy with c = a @ b is what breaks it, so the trigger is the matmul lowering, not placement.
A distinct DISubprogram must be attached to exactly one function. Something in that path gives main an llvm.emit_c_interface, and the generated _mlir_ciface_main wrapper carries main's subprogram along with it rather than getting its own (or none). The JIT path does not verify the module the same way, which is why the whole test suite is green: every backend test JITs.
Why it matters beyond tidiness
AOT is what makes it possible to run a Vx program on a machine that has no Vx toolchain -- compile the object where the compiler lives, ship the object and link it there. For the GPU campaign (#321) that is the difference between copying a binary onto a rented pod and installing LLVM 22 on it.
It also means the AOT path has no test coverage for anything but the simplest programs. A test that emits an object for each of the shapes above would have caught this.
Suggested fix
Where the C-interface wrapper is created, drop or re-create the subprogram rather than cloning the attributes wholesale. Then add object-emission coverage: the reproducer above is a one-line test.
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by reproducing the failure with vxc -c and trace where the C-interface wrapper is created, especially the matmul lowering path. The fix is complete when the LLVM verifier accepts the object and object-emission coverage includes the provided reproducer and the simpler tensor and placement cases.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- build-system, compilers
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 68/100