Skip to content

Optimizer drops the side effects inside an addr() argument when it removes a call to an effect-free function #26

Closed

Description

@lookibed

The optimizer drops a call to a side-effect-free function together with the side effects inside its addr(...) argument. The dead-code elimination removes the call (correct: the callee does nothing) but takes the argument expression with it, including an i++ or a call with a var reference parameter inside the index of addr(arr[...]). Under -no-optimization every effect stays. A callee marked [sideeffects] keeps everything. A dead let/assignment whose value is addr(arr[i++]) is eliminated the same way, so the i++ is lost even though it is not part of the removed expression's value.

Repro (daslang repro.das, daScript at c4e4906, Linux x86_64):

options gen2
def h2(_a : int?) { pass }
[sideeffects]
def h4(_a : int?) { pass }
def bump(var i : int&) : int { i++; return i - 1 }
[export]
def main {
    var arr : int[3]
    var a = 0
    unsafe { var p = addr(arr[a++]); print("used: a={a} p_nonnull={p != null}\n") }
    var b = 0
    unsafe { h4(addr(arr[b++])) }
    print("sideeffects callee: b={b}\n")
    var c = 0
    unsafe { h2(addr(arr[bump(c)])) }
    print("call in index: c={c}\n")
    var d = 0
    unsafe { let q = addr(arr[d++]); h2(q); print("let then used: d={d}\n") }
    var e = 0
    unsafe { var r : int? = null; r = addr(arr[e++]); h2(r) }
    print("assign then call: e={e}\n")
}

Output (interpreter and -jit agree):

used: a=1 p_nonnull=true
sideeffects callee: b=1
call in index: c=0
let then used: d=0
assign then call: e=0

Expected (-no-optimization prints it): every counter is 1. h3(j++) with a plain int parameter keeps the j++, so the loss is specific to an addr() argument (or to a pointer-typed dead value) whose inner expression carries the effect.

Found by c2das-re's P5.1c: the converter's c_prefetch (the __builtin_prefetch shim, which does nothing) is marked [sideeffects] as the workaround, recorded as probe finding F70 (probes/test_functions.das, test_empty_call_effects).

Activity

  1. lookibed commented on Nov 9, 2026

    @lookibed
    OwnerAuthor

    Re-checked by the owner from this issue's reproducer on daScript abf1d40 (0.6.5): fixed upstream (GaijinEntertainment/daScript 2131620 GaijinEntertainment#4472 dasLLVM, 1404d5a GaijinEntertainment#4480 optimizer, f386f92 GaijinEntertainment#4482 cache and tools). The c2das-re probes were re-pinned in the repin PRs (lookibed/c2das-re#142-GaijinEntertainment#147; ruling 38 addendum 4).

  2. lookibed commented on Nov 9, 2026

    @lookibed
    OwnerAuthor

    Fixed upstream: GaijinEntertainment#4458 is closed and the fix is in master abf1d40e35 (0.6.5). Verified by running this issue's repro on a build of that commit.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions