llvm / llvm/llvm-project

[HLSL] transformInitList code should not remove side effecting operations from InitListExprs

Open
#188,309 2 comments 0 reactions 0 assignees View on GitHub
HLSL
Dominant language
LLVM
Stars
40.5k
Forks
18.7k
PR merge metrics
PR metrics pending

Description

HLSL is quite permissive with InitListExprs and allows, according to DXC, the following examples:
```hlsl
RWStructuredBuffer Out;
struct TwoFloats {
float X, Y;
};
struct Empty {
};
Empty foo() {
Out[0] = 14;
Empty E;
return E;
}

[numthreads(1,1,1)]
void case19() {
TwoFloats TF = {1,2, foo()};
Empty E = {foo(), foo()};
}
```
https://godbolt.org/z/MPnhnj3q8

When transforming the InitList for TF, Clang silently discards the call to foo() in the InitListExpr. DXC keeps this call because the size of the InitListExpr is still two elements, because the result type of foo, Empty provides zero elements.

In the case of transforming the InitListExpr for E, Clang keeps the calls to foo but later errors because C++ InitList code HLSL relies on can't handle this case. DXC also allows this, because Empty provides zero elements.

In a similar example where a void function is called in an InitListExpr, DXC crashes so I'm not sure if it meant to support this or if it is attempting to error, but it seems reasonable to error in this case. Clang however silently removes the call to foo2 in TF and leaves the calls to foo2 in E.
```hlsl
RWStructuredBuffer Out;
struct TwoFloats {
float X, Y;
};
struct Empty {
};
void foo2() {
Out[1] = 15;
}

[numthreads(1,1,1)]
void case19() {
TwoFloats TF = {1,2, foo2()};
Empty E = {foo2(), foo2()};
}
```
https://godbolt.org/z/jcE4519h6

Contributor guide

Open the contributing guide

Research direction

Start by tracing Clang's HLSL InitListExpr transformation for the two examples, comparing calls returning Empty with void-function calls. Completion means preserving side-effecting calls instead of silently dropping them and producing an appropriate diagnostic for unsupported void-function cases; add focused coverage in the relevant test area once located.

Written by the indexing model from the issue text.

Assessment

Tech stack
cpp
Domain
compilers
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.