google / google/xls

unroll_for does not unroll constants

Open
#1,721 2 comments 0 reactions 0 assignees View on GitHub
bug dslx
Dominant language
C++
Stars
1.9k
Forks
283
Avg merge
2d 10h
Merged PRs (30d)
135

Description

**Describe the bug**
Constants can not be declared in unroll_for loops, even though they work with `let` binding or used inline.

TypeMissingError: node: 0x30d27fe5f6c0 user: 0x30d27e4e4d98 internal error: AST node is missing a corresponding type: B 0x30d27fe5f6c0 (kind: NameDef) defined @ foo.x10:15-10:16. This may be due to recursion, which is not supported.

**To Reproduce**
```
fn main() -> bool {
unroll_for! (i, b): (u32, bool) in u32:0..u32:10 {
const B: bool = i == u32:1;
b ^ B
}(true)
}
```

The following work:

```
fn main() -> bool {
unroll_for! (i, b): (u32, bool) in u32:0..u32:10 {
let B: bool = i == u32:1;
b ^ B
}(true)
}
```

```
fn main() -> bool {
unroll_for! (i, b): (u32, bool) in u32:0..u32:10 {
b ^ (i == u32:1)
}(true)
}
```

**Expected behavior**
Since the loop index is constexpr, it seems reasonable to define a `const` that depends on it. I would expect it to work like variables.

**Additional context**
Above is for minimal repro, but a more realistic example would be where `B` is defined for multiple parametric function invocations.

```
fn foo(x: u32) -> u32 { if B { x } else { u32:0 } }

fn bar(x: u32) -> bool { if B { x != u32:0 } else { x != u32:1 } }

fn main(x: u32) {
unroll_for! (i, _): (u32, ()) in u32:0..u32:10 {
const B = (i % u32:2 == u32:1);
foo(x);
bar(x);
}(());
}
```

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.