<feed xmlns='http://www.w3.org/2005/Atom'>
<title>slang.git/source/slang/slang-emit-vm.cpp, 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-15T01:00:47+00:00</updated>
<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>Fix `specializeRTTIObject` to use non-zero RTTI value to work with `Optional&lt;T&gt;`. (#8677)</title>
<updated>2025-10-10T21:34:56+00:00</updated>
<author>
<name>Yong He</name>
<email>yonghe@outlook.com</email>
</author>
<published>2025-10-10T21:34:56+00:00</published>
<link rel='alternate' type='text/html' href='https://git.yummers.dev/slang.git/commit/?id=462ea4e66569efa978e4057ea2d041c69d4a729b'/>
<id>urn:sha1:462ea4e66569efa978e4057ea2d041c69d4a729b</id>
<content type='text'>
Closes #8673.

The issue is that we use the RTTI field of an existential to check if it
is null. We have the logic to help the user to fill in a non-zero value
for the RTTI field when such an object is filled from the host. However,
when there is slang code creating an existential value, we still have
old logic in the compiler that just fills in 0 for the RTTI field,
causing an `Optional&lt;IFoo&gt;.hasValue` to always return false in such
cases.</content>
</entry>
<entry>
<title>Rename some symbols related to pointers types (#8592)</title>
<updated>2025-10-03T04:48:11+00:00</updated>
<author>
<name>Theresa Foley</name>
<email>10618364+tangent-vector@users.noreply.github.com</email>
</author>
<published>2025-10-03T04:48:11+00:00</published>
<link rel='alternate' type='text/html' href='https://git.yummers.dev/slang.git/commit/?id=cc8f6a241edb47c43c5698ee33abed4fe57d4566'/>
<id>urn:sha1:cc8f6a241edb47c43c5698ee33abed4fe57d4566</id>
<content type='text'>
Note that while this change touched a large numer of files, there are no
changes to functionality being made here. The only things being done are
renaming various symbols and, in a few cases, updating or adding
comments for consistency with the new names.

The core of the naming changes are:

* Most things named to refer to `OutType` (e.g., `IROutType`,
`IRBuilder::getOutType()`, etc.) have been consistently renamed to refer
to `OutParamType`, to emphasize that the relevant AST/IR node types are
only intended for use to represent `out` parameters.

* The same change as described above for `OutType` is also made for
`RefType`, which becomes `RefParamType` in most cases. One mess that
this exposes is the way that the `ExplicitRef&lt;T&gt;` type in the core
module currently lowers to `IRRefParamType`. This change sticks to the
rule of not making functional changes, so that mess is left as-is for
now.

* Names referring to `InOutType` have been changed to instead refer to
`BorrowInOutType`. The intention with this naming change is to emphasize
that the Slang rules for `inout` are semantically those of a borrow (or
at least our interpretation of what a borrow means).

* Names referring to `ConstRefType` have been changed to instead refer
to `BorrowInType`. This change starts work on clarifying that the
existing `__constref` modifier was never intended to be a read-only
analogue of `__ref`, and instead is the input-only analogue of `inout`.

* The `ParameterDirection` enum type has been changed to
`ParamPassingMode`, to reflect the fact that the concept of "direction"
fails to capture what is actually being encoded, particularly once we
have modes beyond simple `in`/`out`/`inout`.

While this change does not alter behavior in any case (the user-exposed
Slang language is unchanged), it is intended to set up subsequence
changes that will work to make the handling of these types in the
compiler more nuanced and correct. Breaking this part of the change out
separately is primarily motivated by a desire to minimize the effort for
reviewers.

---------

Co-authored-by: slangbot &lt;186143334+slangbot@users.noreply.github.com&gt;</content>
</entry>
<entry>
<title>extend fiddle to allow custom lua splices in more places (#7559)</title>
<updated>2025-07-01T19:03:41+00:00</updated>
<author>
<name>Ellie Hermaszewska</name>
<email>ellieh@nvidia.com</email>
</author>
<published>2025-07-01T19:03:41+00:00</published>
<link rel='alternate' type='text/html' href='https://git.yummers.dev/slang.git/commit/?id=5120c1cd072548654c9ce79fa85426a5e48736c4'/>
<id>urn:sha1:5120c1cd072548654c9ce79fa85426a5e48736c4</id>
<content type='text'>
* Add fkYAML submodule

* Generate slang-ir-inst-defs.h from slang-ir-inst-defs.yaml

* generate ir-inst-defs.h

* neaten things

* neaten inst def parser

* add rapidyaml submodule

* remove fkyaml

* remove fkyaml submodule

* remove use of ir-inst-defs.h

* format and warnings

* fix wasm build

* tidy

* remove rapidyaml

* Extend fiddle to allow custom splices in more places

* Use lua to describe ir insts

* fix

* neaten

* neaten

* neaten

* spelling

* neaten

* comment comment out assert

* merge</content>
</entry>
<entry>
<title>Disable Link-Time-Optimization by default (#7345)</title>
<updated>2025-06-06T17:48:06+00:00</updated>
<author>
<name>Jay Kwak</name>
<email>82421531+jkwak-work@users.noreply.github.com</email>
</author>
<published>2025-06-06T17:48:06+00:00</published>
<link rel='alternate' type='text/html' href='https://git.yummers.dev/slang.git/commit/?id=7f04adbfb9dc0c39c372809ea02cc740d484b291'/>
<id>urn:sha1:7f04adbfb9dc0c39c372809ea02cc740d484b291</id>
<content type='text'>
* Disable Link-Time-Optimization by default

LTO was requested for the release package a while ago.
When we added it, LTO was enabled by default although it was needed only for
the release packages.

Later we found that the Release build cannot be incrementally recompiled
when LTO is enabled. It sometimes works fine, but it required full recompilation
when it doesn't work. We added a new CMake option, `SLANG_ENABLE_RELEASE_LTO`,
to disable it for developers. But many Slang developers don't know the
option exists.

I was going to update the document, CONTRIBUTING.md, but I thought it
will be better to change the default behavior.

* Fix a compiler warning treated as an error on linux

A padding variable was uninitialized, which is fine, but the compiler
was complaining about it.

* Fix other gcc error for uninitialized variable

* Fix more compile warning treated as error

* Fix compiler warning from gcc 11

It appears that this is a valid warning that the `delete this` is done
on an offset 8 when the class uses multiple inheritance.

The compiler warning is following:
```
In file included from /home/runner/work/slang/slang/source/core/slang-memory-file-system.h:5,
                 from /home/runner/work/slang/slang/tools/slang-unit-test/unit-test-module-ptr.cpp:3:
In destructor ‘virtual Slang::ComBaseObject::~ComBaseObject()’,
    inlined from ‘uint32_t Slang::ComBaseObject::_releaseImpl()’ at /home/runner/work/slang/slang/source/core/slang-com-object.h:49:16,
    inlined from ‘virtual uint32_t Slang::MemoryFileSystem::release()’ at /home/runner/work/slang/slang/source/core/slang-memory-file-system.h:34:5:
/home/runner/work/slang/slang/source/core/slang-com-object.h:33:31: error: ‘void operator delete(void*, std::size_t)’ called on pointer ‘&lt;unknown&gt;’ with nonzero offset 8 [-Werror=free-nonheap-object]
   33 |     virtual ~ComBaseObject() {}
      |                               ^
In destructor ‘virtual Slang::ComBaseObject::~ComBaseObject()’,
    inlined from ‘uint32_t Slang::ComBaseObject::_releaseImpl()’ at /home/runner/work/slang/slang/source/core/slang-com-object.h:49:16,
    inlined from ‘virtual uint32_t Slang::MemoryFileSystem::release()’ at /home/runner/work/slang/slang/source/core/slang-memory-file-system.h:34:5,
    inlined from ‘Slang::ComPtr&lt;T&gt;::~ComPtr() [with T = ISlangMutableFileSystem]’ at /home/runner/work/slang/slang/include/slang-com-ptr.h:113:34,
    inlined from ‘void _modulePtr_impl(UnitTestContext*)’ at /home/runner/work/slang/slang/tools/slang-unit-test/unit-test-module-ptr.cpp:92:1:
/home/runner/work/slang/slang/source/core/slang-com-object.h:33:31: error: ‘void operator delete(void*, std::size_t)’ called on pointer ‘&lt;unknown&gt;’ with nonzero offset 8 [-Werror=free-nonheap-object]
   33 |     virtual ~ComBaseObject() {}
      |                               ^
/home/runner/work/slang/slang/tools/slang-unit-test/unit-test-module-ptr.cpp: In function ‘void _modulePtr_impl(UnitTestContext*)’:
/home/runner/work/slang/slang/tools/slang-unit-test/unit-test-module-ptr.cpp:36:69: note: returned from ‘void* operator new(std::size_t)’
   36 |         ComPtr&lt;ISlangMutableFileSystem&gt;(new Slang::MemoryFileSystem());
      |                                                                     ^
```

The problem is on the fact that `ComBaseObject` is not the first in the
multiple inheritance:
```
class MemoryFileSystem : public ISlangMutableFileSystem, public ComBaseObject
{
public:
    // ISlangUnknown
    SLANG_COM_BASE_IUNKNOWN_ALL
```

It should be:
```
class MemoryFileSystem : public ComBaseObject, public ISlangMutableFileSystem
```

The chain of ComObject release is little complicated and it is easy to
make a mistake. Here is summary with details,

1. `release()` is declared as a pure-virtual in ISlangUnknown, which is
one of the base classes of `ISlangMutableFileSystem`.
```
    struct ISlangUnknown
    {
        virtual SLANG_NO_THROW uint32_t SLANG_MCALL release() = 0;
```

2. `release()` is implemented with the macro
   `SLANG_COM_BASE_IUNKNOWN_RELEASE`.
```
    SLANG_NO_THROW uint32_t SLANG_MCALL release() SLANG_OVERRIDE \
    {                                                            \
        return _releaseImpl();                                   \
    }

inline uint32_t ComBaseObject::_releaseImpl()
{
    // Check there is a ref count to avoid underflow
    SLANG_ASSERT(m_refCount != 0);
    const uint32_t count = --m_refCount;
    if (count == 0)
    {
        delete this;
    }
    return count;
}
```

3. The instance of `MemoryFileSystem` is handled by ComPtr. And
   `ComPtr::~ComPtr()` calls the `release()`.
```
    ComPtr&lt;ISlangMutableFileSystem&gt; memoryFileSystem =
        ComPtr&lt;ISlangMutableFileSystem&gt;(new Slang::MemoryFileSystem());

    SLANG_FORCE_INLINE ~ComPtr()
    {
        if (m_ptr)
            ((Ptr)m_ptr)-&gt;release();
    }
```

4. When `delete this` is called, because ComBaseObject is not the first
   in the multiple inheritance, `this` is 8 byte off from the actual
   instance address.

A fix for this is to change the order of the inheritance and make
ComBaseObject to be the first in the order.</content>
</entry>
<entry>
<title>Add Slang Byte Code generation and interpreter. (#6896)</title>
<updated>2025-04-28T18:42:22+00:00</updated>
<author>
<name>Yong He</name>
<email>yonghe@outlook.com</email>
</author>
<published>2025-04-28T18:42:22+00:00</published>
<link rel='alternate' type='text/html' href='https://git.yummers.dev/slang.git/commit/?id=c39c29bf4c52a85d7c83cc8b66ae45e265f9e078'/>
<id>urn:sha1:c39c29bf4c52a85d7c83cc8b66ae45e265f9e078</id>
<content type='text'>
* Add Slang Byte Code generation and interpreter.

* Fix compile issues.

* format code

* More compile fix.

* Fix clang issue.

* Fix more clang issues.

* Another clang fix.

* Fix clang issues.

* Fix another clang issue.

* Fix wasm build.

* Update building.md

* Fix test-server.

* Fix compile error.

* Fix bug.

---------

Co-authored-by: slangbot &lt;186143334+slangbot@users.noreply.github.com&gt;</content>
</entry>
</feed>
