Skip to content

GPU target: if with two or more else-if branches and no else loses the first branch's assignment #21

Open

Description

@Erika98-be

On the GPU target, an if followed by two or more else if branches and no final else loses the assignment made in the first branch: the variable reads back as 0 instead of the assigned value (and not as its initial value either). The same function compiled for WebAssembly is correct.

Reproduction

A fragment shader that should draw four grey bands, left to right 1.0, 0.25, 0.75, 0.5:

import lib/shader_art.dl

to get the level for {floating-point number:kind}:
    set amount to 0.5
    if kind = 1.0:
        set amount to 1.0
    else if kind = 2.0:
        set amount to 0.25
    else if kind = 3.0:
        set amount to 0.75
    return amount

set band to (the floor of (((the fragment x coordinate) / (the shader width)) * 4.0)) + 1.0
set shade to the level for band
set the fragment color with a red channel of shade, a green channel of shade, a blue channel of shade and an alpha channel of 1.0

Open https://dynlex.com/ide/index.html?mode=shader, paste it, and look at the live preview. It compiles without diagnostics.

Expected and observed

Red channel read back from the preview canvas in the middle of each band (measured):

Variant of the branch chain Band 1 Band 2 Band 3 Band 4
Expected 255 64 191 128
if + 2 × else if (the code above) 0 64 191 128
if + 1 × else if (third branch removed; band 3 then expects 128) 255 64 128 128
if + else if + else (last branch as else; band 4 then expects 191) 255 64 191 191
three plain ifs 255 64 191 128

Only the first row of code is wrong, and only in its first branch.

The same function as a program (import lib/std.dl, print line the level for 1.0 … 4.0, run in the IDE, WebAssembly target) prints 1, 0.25, 0.75, 0.5, which is correct. An integer version prints 100, 25, 75, 50, also correct.

It is not specific to scalars: it was first seen in a function returning a color, where a chain of six branches returned black for the first one. There, later branches (second, fourth) were correct, and putting a never-taken branch in front of the chain made the former first branch correct.

Environment

  • dynlex.com IDE shader preview, release fb835f53298c82b304993c1a63c7ff5cde2fd563, on 2026-11-10
  • Chromium-based browser on Linux; navigator.gpu is present. Which preview backend was active (WebGPU or WebGL) was not checked.

Not determined

Whether the fault is in SPIR-V emission or in the translation of the emitted SPIR-V to WGSL/GLSL. The native compiler was not tried.

Workaround

End the chain with else, keep it to one else if, or use separate if statements when the conditions are mutually exclusive.

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

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions