Skip to content

Loop-carried ilist update inside for + if can drop previous state #614

@nkanazawa1989

Description

@nkanazawa1989

Summary

When updating a loop-carried ilist in an if body, the branch result can be lowered as a constant payload instead of prev + payload.
This changes semantics (accumulation is lost).

Environment

  • kirin-toolchain==0.22.6
  • Python 3.10.19
  • macOS 15.7.3 (arm64)

Reproducer

1) Bad pattern (can collapse accumulation)

# frontend-agnostic kernel pseudocode
@kernel
def helper_const():
    return [1]  # constant payload

@kernel
def bad(n: int):
    xs = []
    for i in range(n):
        if True:
            xs += helper_const()
    return len(xs)

print(bad(5))  # can be 1 (expected 5)

2) Good pattern (accumulates as expected)

# frontend-agnostic kernel pseudocode
@kernel
def helper_dynamic(v: int):
    return [v]  # payload depends on runtime value

@kernel
def good(n: int):
    xs = []
    v = n
    for i in range(n):
        if True:
            xs += helper_dynamic(v)
    return len(xs)

print(good(5))  # 5

Expected behavior

  • bad(5) should return 5.
  • good(5) should return 5.
  • Semantics should be equivalent to repeated xs = xs + payload in both cases.

Actual behavior

  • bad(5) can return 1.
  • good(5) returns 5.

Why this is a bug (not expected phi/merge behavior)

In SSA/control-flow terms, the branch should compute:

xs_then = xs_prev + const_payload

but observed behavior corresponds to:

xs_then = const_payload

This bypasses loop-carried state (xs_prev) and changes program meaning.

IR evidence

Observed risky shape in branch block:

^1(%i, %xs_2):
│ %xs_1 = py.constant.constant IList([1]) : ...

Expected shape:

^1(%i, %xs_2):
│ %tmp = py.constant.constant IList([1]) : ...
│ %xs_1 = py.binop.add(%xs_2, %tmp) : ...

Notes

  • This appears in for + if with loop-carried ilist updates when payload is (or is specialized into) a constant/literal list.
  • Non-literal/runtime-dependent payloads often keep correct py.binop.add form.
  • Reproduced through a Kirin-based kernel frontend; issue appears in Kirin IR semantics/optimization shape, not frontend-specific syntax.

Request

Please investigate lowering/optimization around branch outputs for loop-carried values in for + if control flow.

Metadata

Metadata

Assignees

No one assigned

    Labels

    area: dialect SCFArea: structural control flow related issues.category: bugCategory: this is a bug or something isn't working as expected.priority: highPriority: high priority issues and tasks, blocking milestones, time sensitive.

    Type

    No fields configured for Bug.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions