mirror of
https://github.com/encounter/dawn-cmake.git
synced 2025-12-11 22:44:04 +00:00
msl: Fold &* when converting module-scope vars
This transform was previously converting this code:
```
var<private> v : f32;
fn foo() {
bar(&v);
}
```
into this:
```
fn foo(vp : ptr<private, f32>) {
bar(&*vp); // Invalid, since ptr args must be &ident
}
```
Fixed: tint:1086
Change-Id: Ic9efafa219c89a11a4d6e1d11fc69b3c0b9a5464
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/60520
Kokoro: Kokoro <noreply+kokoro@google.com>
Auto-Submit: James Price <jrprice@google.com>
Reviewed-by: Ben Clayton <bclayton@google.com>
Commit-Queue: Ben Clayton <bclayton@google.com>
This commit is contained in:
committed by
Tint LUCI CQ
parent
98fbf241d8
commit
5c61d6d12c
@@ -181,6 +181,23 @@ void Msl::HandleModuleScopeVariables(CloneContext& ctx) const {
|
||||
}
|
||||
}
|
||||
|
||||
// Build a list of `&ident` expressions. We'll use this later to avoid
|
||||
// generating expressions of the form `&*ident`, which break WGSL validation
|
||||
// rules when this expression is passed to a function.
|
||||
// TODO(jrprice): We should add support for bidirectional SEM tree traversal
|
||||
// so that we can do this on the fly instead.
|
||||
std::unordered_map<ast::IdentifierExpression*, ast::UnaryOpExpression*>
|
||||
ident_to_address_of;
|
||||
for (auto* node : ctx.src->ASTNodes().Objects()) {
|
||||
auto* address_of = node->As<ast::UnaryOpExpression>();
|
||||
if (!address_of || address_of->op() != ast::UnaryOp::kAddressOf) {
|
||||
continue;
|
||||
}
|
||||
if (auto* ident = address_of->expr()->As<ast::IdentifierExpression>()) {
|
||||
ident_to_address_of[ident] = address_of;
|
||||
}
|
||||
}
|
||||
|
||||
for (auto* func_ast : functions_to_process) {
|
||||
auto* func_sem = ctx.src->Sem().Get(func_ast);
|
||||
bool is_entry_point = func_ast->IsEntryPoint();
|
||||
@@ -241,6 +258,15 @@ void Msl::HandleModuleScopeVariables(CloneContext& ctx) const {
|
||||
if (user->Stmt()->Function() == func_ast) {
|
||||
ast::Expression* expr = ctx.dst->Expr(new_var_symbol);
|
||||
if (!is_entry_point && !store_type->is_handle()) {
|
||||
// If this identifier is used by an address-of operator, just remove
|
||||
// the address-of instead of adding a deref, since we already have a
|
||||
// pointer.
|
||||
auto* ident = user->Declaration()->As<ast::IdentifierExpression>();
|
||||
if (ident_to_address_of.count(ident)) {
|
||||
ctx.Replace(ident_to_address_of[ident], expr);
|
||||
continue;
|
||||
}
|
||||
|
||||
expr = ctx.dst->Deref(expr);
|
||||
}
|
||||
ctx.Replace(user->Declaration(), expr);
|
||||
|
||||
Reference in New Issue
Block a user