vx-lang / vx-lang/Vx

AST path: `Tensor<T>(n)` with a run-time extent allocates one element, then bitcasts a scalar into a memref descriptor

Open
#646 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bug codegen
Dominant language
Rust
Stars
14
Forks
2
Avg merge
12h 42m
Merged PRs (30d)
61

Description

On the AST path, a tensor whose extent is a run-time value is built as a rank-0 buffer, and
the declared shape arrives by bitcasting the element type to a memref.

import std::tensor;

fn main() -> i32 {
  let n = 4;
  let t = Tensor<f32>(n);
  return 0;
}
$ vxc repro.vx --emit-mlir --legacy-codegen
  func.func @main() -> i32 {
    %alloc = memref.alloc() : memref<f32>

One element, not n. The extent is dropped entirely: memref.alloc() takes no operand, so
whatever n was never reaches the allocation.

Returning such a tensor makes the second half visible, because the signature then names the
shape the body does not have:

fn make_dyn(n : i32) -> Tensor<f32, [?]> {
  let t = Tensor<f32>(n);
  return t;
}
Warning: Falling back to bitcast from f32 to memref<?xf32>
  func.func @make_dyn(%arg0: i32) -> memref<?xf32> {
    %alloc = memref.alloc() : memref<f32>
    %0 = memref.load %alloc[] : memref<f32>
    %1 = builtin.unrealized_conversion_cast %0 : f32 to memref<?xf32>
    return %1 : memref<?xf32>
  }

The rank-0 buffer is loaded as an f32 and that scalar is cast to memref<?xf32> -- the
caller receives a memref descriptor built out of a float. Anything that indexes it reads
from an address that was never a pointer.

The flat path compiles the same program correctly (memref.alloc(%0) : memref<?xf32>, the
extent index-cast from the argument), so this only bites a program that has been sent to the
oracle -- forced with --legacy-codegen, or carried there because something else in the file
declined.

Found while writing tests/frontend/pass/tensor_return_dynamic_shape.vx for #643, which is
marked REQUIRES: flat-codegen because of this. It is not about returns: the local case above
has no return at all.

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with tests/frontend/pass/tensor_return_dynamic_shape.vx and reproduce with --emit-mlir --legacy-codegen, then trace the AST/oracle path that lowers Tensor(n). Done means the runtime extent reaches memref.alloc as in the flat path and no scalar-to-memref bitcast is emitted; verify both the local and return cases.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
compilers
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
65/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.