diff options
| author | Tim Foley <tfoleyNV@users.noreply.github.com> | 2018-06-13 13:56:30 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2018-06-13 13:56:30 -0700 |
| commit | a4dd936ce05f4aa1342b4ce98dd0ac8c4272e331 (patch) | |
| tree | 0a071ffbf1888042ec303475c17a544f36298b5e /tools | |
| parent | 860b0d604377d3635f6fa994993371399327129f (diff) | |
Fix some issues around codegen for l-values and assignment (#601)
The problem here arose when a complicated l-value was formed like:
```hlsl
struct Foo { float4 a; }
RWStructuredBuffer<Foo> gBuffer;
gBuffer[index].a.xz += whatever;
```
In this case the `gBuffer[index].a.xz` expression is a complex l-value in multiple ways:
* The `gBuffer[index]` subscript could be routed to either a `get` accessor or a `ref` accessor (and maybe also a `set` accessor if we add one to the stdlib definition), and we defer the choice of which to call until as late as possible in codegen today.
* The `_.a` part then becomes a "bound member acess" because we can't actually produce a direct pointer until we've resolved how to implement the subscript operation.
* The `_.xz` part becomes a "swizzled l-value" because there is *no* way to materialize it as a pointer to contiguous storage in the orignal object (the `x` and `z` components of a vector aren't contiguous).
Recent changes to support atomic operations on buffer elements introduced the `ref` accessor on `RWStructuredBuffer`, which made it possible to form a pointer to a buffer element in the IR. This interacted with some code for the "bound member" case that was trying to only introduce a temporary when absolutely necessary, and was doing so by assuming anything with an address didn't need to be moved into a temporary.
The first fix is to clean up that logic in the bound-member case for assignment: always create a temporary, rather than do it conditionally.
The second fix here is more systemic: we add logic to try to coerce the representation of an l-value during codegen into being a simple address, and employ that in cases where we know an address is desired. In a case like the above this helps to get things into the form that is required, so that a swizzled store can be issued.
There is still some potential for cleanup in this logic, but I don't want to introduce more changes than seem necessary to fix the original problem.
Diffstat (limited to 'tools')
0 files changed, 0 insertions, 0 deletions
