llvm / llvm/circt

[StandardToHandshake] Passing `memref` to a function will still use `memref.alloc`

Open
#3,268 10 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bug Handshake
Dominant language
C++
Stars
2.2k
Forks
524
Avg merge
3d 2h
Merged PRs (30d)
46

Description

Passing the following code to `--lower-std-to-handshake` produces a weird output.

```mlir
func.func @external_mem(%mem : memref<4xi32>) {
return
}

func.func @normal_mem() {
%mem = memref.alloc() : memref<4xi32>
func.call @external_mem(%mem) : (memref<4xi32>) -> ()
return
}
```

Output:

```mlir
handshake.func @external_mem(%arg0: memref<4xi32>, %arg1: none, ...) -> none attributes {argNames = ["in0", "inCtrl"], resNames = ["outCtrl"]} {
extmemory[ld = 0, st = 0] (%arg0 : memref<4xi32>) () {id = 0 : i32} : () -> ()
return %arg1 : none
}
handshake.func @normal_mem(%arg0: none, ...) -> none attributes {argNames = ["inCtrl"], resNames = ["outCtrl"]} {
%0:2 = fork [2] %arg0 : none
%1 = memref.alloc() : memref<4xi32>
%2 = instance @external_mem(%1, %0#0) : (memref<4xi32>, none) -> none
sink %2 : none
return %0#1 : none
}
```

As you can see, a `memref.alloc()` remains, which is not expected and thus breaks further transformations.

I would expect that a correct lowering would construct a `MemoryOp` in the `@normal_mem` function. How this exactly interacts with the external memory op is not clear to me, as this will cause cross function dependencies depending on the amount of memory operations in `@external_mem`.

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 at the --lower-std-to-handshake lowering entry point and trace how the shown @external_mem and @normal_mem functions handle memref.alloc and MemoryOp construction. Compare the generated handshake.func output with the expected lowering, including how external memory operations and cross-function dependencies should be represented; done means no memref.alloc remains and the transformation handles this case correctly.

Written by the indexing model from the issue text.

Assessment

Tech stack
cpp
Domain
compilers
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.