<feed xmlns='http://www.w3.org/2005/Atom'>
<title>slang.git/source/slang/slang-ir-util.h, branch master</title>
<subtitle>Making it easier to work with shaders</subtitle>
<id>https://git.yummers.dev/slang.git/atom?h=master</id>
<link rel='self' href='https://git.yummers.dev/slang.git/atom?h=master'/>
<link rel='alternate' type='text/html' href='https://git.yummers.dev/slang.git/'/>
<updated>2025-10-31T22:33:07+00:00</updated>
<entry>
<title>meow</title>
<updated>2025-10-31T22:33:07+00:00</updated>
<author>
<name>yum</name>
<email>yum.food.vr@gmail.com</email>
</author>
<published>2025-10-31T22:33:07+00:00</published>
<link rel='alternate' type='text/html' href='https://git.yummers.dev/slang.git/commit/?id=d680309ff1440333f2ab1537c63cb46f02e0b8a0'/>
<id>urn:sha1:d680309ff1440333f2ab1537c63cb46f02e0b8a0</id>
<content type='text'>
</content>
</entry>
<entry>
<title>non-exported public labels get namespaced now</title>
<updated>2025-10-29T02:45:29+00:00</updated>
<author>
<name>yum</name>
<email>yum.food.vr@gmail.com</email>
</author>
<published>2025-10-29T02:45:29+00:00</published>
<link rel='alternate' type='text/html' href='https://git.yummers.dev/slang.git/commit/?id=0a2506e2fce7d754489066c51f51574bdd428bc0'/>
<id>urn:sha1:0a2506e2fce7d754489066c51f51574bdd428bc0</id>
<content type='text'>
</content>
</entry>
<entry>
<title>Clean up Slang IR representation of undefined values (#8708)</title>
<updated>2025-10-15T01:00:47+00:00</updated>
<author>
<name>Theresa Foley</name>
<email>10618364+tangent-vector@users.noreply.github.com</email>
</author>
<published>2025-10-15T01:00:47+00:00</published>
<link rel='alternate' type='text/html' href='https://git.yummers.dev/slang.git/commit/?id=907410f6a52cf4e7538870ebf5aeb88858f97973'/>
<id>urn:sha1:907410f6a52cf4e7538870ebf5aeb88858f97973</id>
<content type='text'>
Prior to this change, the Slang IR used a single opcode
(`kIROp_Undefined`) to encode all cases of undefined values. The
particular motivation for this change was a need to distinguish those
undefined values that represent a load from an uninitialized memory
location versus other sorts of undefined values. If transforming a
variable into SSA form results in `undefined` values in cases where the
a `load` was executed without a prior `store`, that represents an error
on the programmer's part, and should be diagnosed. However, other cases
of undefined values can arise during program transformation and
optimization, and should not typically result in diagnostics being
emitted.

While it was not the original motivation for this change, it is also
worth noting that the LLVM project has transitioned from initially using
only a single `undef` instruction to having a more nuanced model, and
the same factors that motivated their shift also apply to the Slang IR.
Counter-intuitively, the semantics of undefined values actually need to
be carefully defined.

Concretely, this change splits the pre-existing `undefined` opcode into
two sub-cases:

- `kIROp_LoadFromUninitializedMemory`, to represent the case of loading
from a memory location (such as a local variable) that has not been
initialized.

- `kIROp_Poison`, corresponding to the LLVM `poison` value.

Our poison instruction is intended to have semantics comparable to
LLVM's equivalent. Conceptually, any operation that is invoked with a
poison value as input will (with a few exceptions) produce a poison
value as output. One can think of the behavior of `poison` as similar to
how not-a-number values propagate in floating-point computations: by
default they "infect" the result of any computation they are involved
in. This semantic choice helps to ensure that many optimizations end up
being correct in the presence of undefined values, even if they did not
specifically account for them.

The `kIROp_LoadFromUninitializedMemory` case is comparable to the
combination of `freeze` and `undef` in LLVM. An LLVM `undef` value has
semantics that allow *each* use of that value to be replaced with a
*different* arbitrary value; these semantics cause many optimizations to
only be correct in the absence of undefined values. An LLVM `freeze`
instruction can take an undefined value as input, and produces a single
value that is still arbitrary, but must be consistent across all uses.
The latter semantics are what we want, since a given `load` from an
uninitialized memory location will yield an arbitrary-but-fixed value.

Note that we intentionally do not have a direct analogue to LLVM's
`undef` instruction, because of the way that `undef` causes so many
complications when trying to write optimizations.

We also do not add a `kIROp_Freeze` instruction in this change, but that
is simply because we currently have no need for it.

Existing code that was creating `IRUndefined` values has been updated to
create either `IRPoison` or `IRLoadFromUninitializedMemory` values, as
appropriate to the use case. Code that was checking for the
`kIROp_Undefined` opcode has been updated to either check for both of
the new opcodes (in the case of `switch` statements), or to use
`as&lt;IRUndefined&gt;` to perform a dynamic cast to the common base type of
the two new instructions.

Note that this change does not alter the way that instructions
representing undefined values are typically emitted as ordinary
instructions in the block that produces an undefined value. While
emitting `IRLoadFromUninitializedMemory` as an ordinary instruction is
exactly what we want, the `IRPoison` case would actually be better
represented in Slang IR as a "hoistable" instruction, so that there
would only be a singular `poison` value of each type. Changing
`IRPoison` to be hoistable would be a good follow-up change, but might
run into more challenges depending on what assumptions (if any) the
codebase is making about where undefined values get emitted.

---------

Co-authored-by: slangbot &lt;186143334+slangbot@users.noreply.github.com&gt;</content>
</entry>
<entry>
<title>Relax the inst definition order rule (#8588)</title>
<updated>2025-10-02T22:24:46+00:00</updated>
<author>
<name>kaizhangNV</name>
<email>149626564+kaizhangNV@users.noreply.github.com</email>
</author>
<published>2025-10-02T22:24:46+00:00</published>
<link rel='alternate' type='text/html' href='https://git.yummers.dev/slang.git/commit/?id=0c778339d7e3c39f600af2cc049f13f661d3434b'/>
<id>urn:sha1:0c778339d7e3c39f600af2cc049f13f661d3434b</id>
<content type='text'>
Close #8572.

The root cause of the issue is that in `_replaceInstUsesWith` call,
if the use of the inst is a generic parameter, and the inst is the data
type of that generic parameter, we could end up of moving the data type
before the generic parameter. This will break the layout of generic
parameters, where all the generic parameters should be laid consecutively
at the beginning of the first block of the generic.

Therefore, we don't make that relocation for such case.</content>
</entry>
<entry>
<title>Enhance buffer load specialization pass to specialize past field extracts. (#8547)</title>
<updated>2025-10-01T02:08:23+00:00</updated>
<author>
<name>Yong He</name>
<email>yonghe@outlook.com</email>
</author>
<published>2025-10-01T02:08:23+00:00</published>
<link rel='alternate' type='text/html' href='https://git.yummers.dev/slang.git/commit/?id=e4611e2e30a3e5969d402f5ed7e72706a0e3b024'/>
<id>urn:sha1:e4611e2e30a3e5969d402f5ed7e72706a0e3b024</id>
<content type='text'>
This allows us to specialize functions whose argument is a sub element
of a constant buffer, instead of being only applicable to entire buffer
element. Closes #8421.

This change also implements a proper heuristic to determine when to
specialize the calls and defer the buffer loads.

This PR addresses a pathological case exposed in
`slangpy\slangpy\benchmarks\test_benchmark_tensor.py`, which used to
take 27ms to finish, and now takes 1.25ms.


For example, given:
```
struct Bottom
{
    float bigArray[1024];

    [mutating]
    void setVal(int index, float value) { bigArray[index] = value; }
}

struct Root
{
    Bottom top[2];
    [mutating]
    void setTopVal(int x, int y, float value)
    {
        top[x].setVal(y, value);
    }
}

RWStructuredBuffer&lt;Root&gt; sb;

[shader("compute")]
[numthreads(1, 1, 1)]
void compute_main(uint3 tid: SV_DispatchThreadID)
{
    sb[0].setTopVal(1, 2, 100.0f);
}
```

We are now able to specialize the call to `setTopVal` into:
```
void compute_main(uint3 tid: SV_DispatchThreadID)
{
    setTopVal_specialized(0, 1, 2, 100.0f);
}

void setTopVal_specialized(int sbIdx, int x, int y, float value)
{
      Bottom_setVal_specialized(sbIdx, x, y, value);
}

void Bottom_setVal_specialized(int sbIdx, int x, int y, float value)
{
     sb[sbIdx].top[x].bigArray[y] = value;
}
```

And get rid of all unnecessary loads. Achieving this requires a
combination of function call specialization and buffer-load-defer pass.
The buffer-load-defer pass has been completely rewritten to be more
correct and avoid introducing redundant loads.

This PR also adds tests to make sure pointers, bindless handles, and
loads from structured buffer or constant buffers works as expected.</content>
</entry>
<entry>
<title>Rewriting the lower-buffer-element-type pass to avoid unnecessary packing/unpacking. (#8526)</title>
<updated>2025-09-30T00:45:08+00:00</updated>
<author>
<name>Yong He</name>
<email>yonghe@outlook.com</email>
</author>
<published>2025-09-30T00:45:08+00:00</published>
<link rel='alternate' type='text/html' href='https://git.yummers.dev/slang.git/commit/?id=a6deb5ed82cb8fc6b4f4c5c5fee264e09f97ff89'/>
<id>urn:sha1:a6deb5ed82cb8fc6b4f4c5c5fee264e09f97ff89</id>
<content type='text'>
Part of the effort to improve the performance of generated SPIRV code.

The existing lower-buffer-element-type pass works by loading the entire
buffer element content from memory, and translate it to logical type
stored in a local variable at the earliest reference of a buffer handle.
This means that is can generate inefficient code that reads more than
necessary.

Consider this example:
```
struct BigStruct { bool values[1024]; }
ConstantBuffer&lt;BigStruct&gt; cb;

void test(BigStruct v)
{
      if (v.values[0]) { printf("ok"); }
}

[numthreads(1,1,1)]
void computeMain()
{
    test(cb);
}
```

In IR, the `computeMain` function before lower-buffer-element-type pass
is something like following:
```
func test:
   %v = param : BigStruct
   %barr = fieldExtract(%v, "values")
   %element = elementExtract(%barr, 0)
    ... // uses %element 

func computeMain:
  %v = load(cb)
  call %test %v
```

The existing lower-buffer-element-type pass will rewrite the bool array
in `BigStruct` into `int` array so it is legal in SPIRV. However, it
does so by inserting the translation on the first `load` of the constant
buffer:

```
struct BigStruct_std430 {
    int values[1024];
}
var cb : ConstantBuffer&lt;BigStruct_std430&gt;;
func computeMain:
   %tmpVar : var&lt;BigStruct&gt;
    call %unpackStorage(%tmpVar, cb)
   %v : BigStruct = load %tmpVar
   call %test %v
```

This means that the entire array will be loaded and translated to int,
before calling `test`, which only uses one element. It turns out that
the downstream compiler isn't always able to optimize out this
inefficient translation/copy.

This PR completely rewrites the way buffer-element-type lowering is
handled to avoid producing this inefficient code. It works in two parts:
first we turn on the `transformParamsToConstRef` pass for SPIRV target
as well, so we will translate the `test` function to take the `v`
parameter as `constref`. The second part is a redesigned
buffer-element-type pass that defers the storage-type to logical-type
translation until a value is actually used by a `load` instruction.

In this example, after `transformParamsToConstRef`, the IR is:

```
func test:
   %v = param : ConstRef&lt;BigStruct&gt;
   %barr = fieldAddr(%v, "values")
   %elementPtr = elementAddr(%barr, 0)
   %element = load(%elementPtr)
    ... // uses %element 

func computeMain:
  call %test %cb
```

The new `buffer-element-type-lowering` pass will take this IR, and
insert translation at latest possible time across the entire call graph,
and translate the IR into:

```
func test:
   %v = param : ConstRef&lt;BigStruct_std430&gt;
   %barr = fieldAddr(%v, "values")
   %elementPtr : ptr&lt;int&gt; = elementAddr(%barr, 0)
   %element_int = load(%elementPtr)
    %element = cast(%element_int) : %bool
    ... // uses %element 

func computeMain:
  call %test %cb
```

In this new IR, there is no longer a load and conversion of the entire
array.

See new comment in `slang-ir-lower-buffer-element-type.cpp` for more
details of how the pass works.

This PR also address many other issues surfaced by turning on
`transformParamsToConstRef` pass on SPIRV backend.

---------

Co-authored-by: slangbot &lt;186143334+slangbot@users.noreply.github.com&gt;</content>
</entry>
<entry>
<title>Fix `shouldEmitSPIRVDirectly` (#8019)</title>
<updated>2025-08-26T17:48:49+00:00</updated>
<author>
<name>ArielG-NV</name>
<email>159081215+ArielG-NV@users.noreply.github.com</email>
</author>
<published>2025-08-26T17:48:49+00:00</published>
<link rel='alternate' type='text/html' href='https://git.yummers.dev/slang.git/commit/?id=b36659eca38be716bee43c01c6584bda5f91166a'/>
<id>urn:sha1:b36659eca38be716bee43c01c6584bda5f91166a</id>
<content type='text'>
Fixes: #8018

Changes:
* Do not emit true for `shouldEmitSPIRVDirectly` with a GLSL target</content>
</entry>
<entry>
<title>Fix duplicate mangled names for interface requirements (#7764)</title>
<updated>2025-07-17T04:41:09+00:00</updated>
<author>
<name>Yong He</name>
<email>yonghe@outlook.com</email>
</author>
<published>2025-07-17T04:41:09+00:00</published>
<link rel='alternate' type='text/html' href='https://git.yummers.dev/slang.git/commit/?id=5937e1e6bb3afcf84b01abadcf1eb527933449f3'/>
<id>urn:sha1:5937e1e6bb3afcf84b01abadcf1eb527933449f3</id>
<content type='text'>
* Fix duplicate mangled names for interface requirements

Remove linkage decorations from interface method requirement values to prevent
duplicate mangled names and allow DCE to clean up unused functions.

Interface requirements only need the type information, not the linkage,
so the generated IRFunc with export decorations was causing conflicts.

Fixes #7761

Co-authored-by: Yong He &lt;csyonghe@users.noreply.github.com&gt;

* Move linkage decoration removal into default case of switch

Move the removeLinkageDecorations call into the default case of the
switch statement so it only applies to general requirements and not
special cases like associated types.

Co-authored-by: Yong He &lt;csyonghe@users.noreply.github.com&gt;

* Remove conditional check for linkage decoration removal

Apply removeLinkageDecorations unconditionally to interface requirement values
to ensure all requirement values have their linkage decorations removed.

Co-authored-by: Yong He &lt;csyonghe@users.noreply.github.com&gt;

* Change removeLinkageDecorations parameter type from IRGlobalValueWithCode* to IRInst*

This fixes build errors by allowing the function to accept the broader IRInst* type,
making it compatible with the unconditional call in the interface requirement processing.

Co-authored-by: Yong He &lt;csyonghe@users.noreply.github.com&gt;

* format code (#7787)

Co-authored-by: slangbot &lt;186143334+slangbot@users.noreply.github.com&gt;

---------

Co-authored-by: github-actions[bot] &lt;41898282+github-actions[bot]@users.noreply.github.com&gt;
Co-authored-by: Yong He &lt;csyonghe@users.noreply.github.com&gt;
Co-authored-by: slangbot &lt;ellieh+slangbot@nvidia.com&gt;
Co-authored-by: slangbot &lt;186143334+slangbot@users.noreply.github.com&gt;</content>
</entry>
<entry>
<title>Replace [KnownBuiltin] string-based comparisons with enum-based system (#7714)</title>
<updated>2025-07-15T10:11:39+00:00</updated>
<author>
<name>Copilot</name>
<email>198982749+Copilot@users.noreply.github.com</email>
</author>
<published>2025-07-15T10:11:39+00:00</published>
<link rel='alternate' type='text/html' href='https://git.yummers.dev/slang.git/commit/?id=d964555d2ee83fac2ba357e4ec81e2a393a7b12f'/>
<id>urn:sha1:d964555d2ee83fac2ba357e4ec81e2a393a7b12f</id>
<content type='text'>
* Initial plan

* Implement enum-based KnownBuiltin system to replace string comparisons

Co-authored-by: csyonghe &lt;2652293+csyonghe@users.noreply.github.com&gt;

* Add test for enum-based KnownBuiltin system and verify functionality

Co-authored-by: csyonghe &lt;2652293+csyonghe@users.noreply.github.com&gt;

* Implement enum-based KnownBuiltin system with direct integer values

Co-authored-by: csyonghe &lt;2652293+csyonghe@users.noreply.github.com&gt;

* Fix IntVal access and update tests for new enum-based KnownBuiltin system

Co-authored-by: csyonghe &lt;2652293+csyonghe@users.noreply.github.com&gt;

* Replace hardcoded KnownBuiltin integers with preprocessor enum syntax

- Updated all KnownBuiltin attributes to use $( (int)KnownBuiltinDeclName::EnumValue) syntax
- Added space between parentheses to avoid preprocessor bug: $( (int) instead of $((int)
- Updated both core.meta.slang and hlsl.meta.slang files
- Eliminates preprocessor-time integer conversion, baking enum values directly into meta files
- Maintains same functionality while using type-safe enum references

Co-authored-by: csyonghe &lt;2652293+csyonghe@users.noreply.github.com&gt;

* Fix IDifferentiablePtr KnownBuiltin mapping regression

Co-authored-by: csyonghe &lt;2652293+csyonghe@users.noreply.github.com&gt;

* Remove unused IDifferentiablePtrType enum case from KnownBuiltinDeclName

Co-authored-by: csyonghe &lt;2652293+csyonghe@users.noreply.github.com&gt;

* Clean up temporary AST dump files from testing

Co-authored-by: csyonghe &lt;2652293+csyonghe@users.noreply.github.com&gt;

* Replace hardcoded integer with descriptive constant in KnownBuiltin test

Replace the hardcoded [KnownBuiltin(0)] with a descriptive named constant
GEOMETRY_STREAM_APPEND_BUILTIN to improve code readability and maintainability.
The test now clearly indicates which builtin enum value is being tested.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-authored-by: Gangzheng Tong &lt;gtong-nv@users.noreply.github.com&gt;

---------

Co-authored-by: copilot-swe-agent[bot] &lt;198982749+Copilot@users.noreply.github.com&gt;
Co-authored-by: csyonghe &lt;2652293+csyonghe@users.noreply.github.com&gt;
Co-authored-by: github-actions[bot] &lt;41898282+github-actions[bot]@users.noreply.github.com&gt;
Co-authored-by: Gangzheng Tong &lt;gtong-nv@users.noreply.github.com&gt;
Co-authored-by: Gangzheng Tong &lt;tonggangzheng@gmail.com&gt;</content>
</entry>
<entry>
<title>Fix for emitting ArrayStride decoration for arrays of opaque types (#7568)</title>
<updated>2025-07-02T04:22:42+00:00</updated>
<author>
<name>Jerran Schmidt</name>
<email>jerrans@nvidia.com</email>
</author>
<published>2025-07-02T04:22:42+00:00</published>
<link rel='alternate' type='text/html' href='https://git.yummers.dev/slang.git/commit/?id=7ffb9f53e41c409a51c41318442067cc6c7e4f48'/>
<id>urn:sha1:7ffb9f53e41c409a51c41318442067cc6c7e4f48</id>
<content type='text'>
* WIP opaque type decoration fix

* Clearer intent

* Formatting

* Added test for fix</content>
</entry>
</feed>
