[ir] Handle `let` in RenameConflicts
Let instructions were not getting renamed, leading to conflicts in
generated code.
Bug: 42251016
Change-Id: I38b2c4432806452158979e3688783d61ebfa7298
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/196358
Reviewed-by: dan sinclair <dsinclair@chromium.org>
diff --git a/src/tint/lang/core/ir/transform/rename_conflicts.cc b/src/tint/lang/core/ir/transform/rename_conflicts.cc
index fa32ced..f24cf87 100644
--- a/src/tint/lang/core/ir/transform/rename_conflicts.cc
+++ b/src/tint/lang/core/ir/transform/rename_conflicts.cc
@@ -32,6 +32,7 @@
#include "src/tint/lang/core/ir/core_builtin_call.h"
#include "src/tint/lang/core/ir/function.h"
#include "src/tint/lang/core/ir/instruction.h"
+#include "src/tint/lang/core/ir/let.h"
#include "src/tint/lang/core/ir/loop.h"
#include "src/tint/lang/core/ir/module.h"
#include "src/tint/lang/core/ir/multi_in_block.h"
@@ -103,7 +104,7 @@
/// Stack of scopes
Vector<Scope, 8> scopes{};
- /// Registers all the WGSL module-scope declarations in the root-scope.
+ /// Registers all the module-scope declarations in the root-scope.
/// Duplicate declarations with the same name will renamed.
void RegisterModuleScopeDecls() {
// Declare all the user types
@@ -188,6 +189,10 @@
// Ensure the var's type is resolvable
EnsureResolvable(inst->Result(0)->Type());
},
+ [&](core::ir::Let*) {
+ // Ensure the let's type is resolvable
+ EnsureResolvable(inst->Result(0)->Type());
+ },
[&](core::ir::Construct*) {
// Ensure the type of a type constructor is resolvable
EnsureResolvable(inst->Result(0)->Type());
diff --git a/src/tint/lang/core/ir/transform/rename_conflicts_test.cc b/src/tint/lang/core/ir/transform/rename_conflicts_test.cc
index 7e4a983..bd4cb60 100644
--- a/src/tint/lang/core/ir/transform/rename_conflicts_test.cc
+++ b/src/tint/lang/core/ir/transform/rename_conflicts_test.cc
@@ -392,6 +392,62 @@
EXPECT_EQ(expect, str());
}
+TEST_F(IRToProgramRenameConflictsTest, Conflict_FnLet_ShadowedBy_IfVar) {
+ auto* fn = b.Function("f", ty.i32());
+ b.Append(fn->Block(), [&] {
+ auto* outer = b.Var(ty.ptr<function, i32>());
+ b.ir.SetName(outer, "v");
+
+ auto* if_ = b.If(true);
+ b.Append(if_->True(), [&] {
+ auto* inner = b.Let("v", 42_i);
+ auto* load_outer = b.Load(outer);
+ b.Return(fn, b.Add(ty.i32(), load_outer, inner));
+ });
+
+ b.Unreachable();
+ });
+
+ auto* src = R"(
+%f = func():i32 {
+ $B1: {
+ %v:ptr<function, i32, read_write> = var
+ if true [t: $B2] { # if_1
+ $B2: { # true
+ %v_1:i32 = let 42i # %v_1: 'v'
+ %4:i32 = load %v
+ %5:i32 = add %4, %v_1
+ ret %5
+ }
+ }
+ unreachable
+ }
+}
+)";
+ EXPECT_EQ(src, str());
+
+ auto* expect = R"(
+%f = func():i32 {
+ $B1: {
+ %v:ptr<function, i32, read_write> = var
+ if true [t: $B2] { # if_1
+ $B2: { # true
+ %v_1:i32 = let 42i
+ %4:i32 = load %v
+ %5:i32 = add %4, %v_1
+ ret %5
+ }
+ }
+ unreachable
+ }
+}
+)";
+
+ Run();
+
+ EXPECT_EQ(expect, str());
+}
+
TEST_F(IRToProgramRenameConflictsTest, NoModify_LoopInitVar_ShadowedBy_LoopBodyVar) {
auto* fn = b.Function("f", ty.i32());
b.Append(fn->Block(), [&] {
diff --git a/test/tint/shadowing/struct/let.wgsl.expected.ir.msl b/test/tint/shadowing/struct/let.wgsl.expected.ir.msl
index de13c82..faba801 100644
--- a/test/tint/shadowing/struct/let.wgsl.expected.ir.msl
+++ b/test/tint/shadowing/struct/let.wgsl.expected.ir.msl
@@ -1,5 +1,3 @@
-SKIP: FAILED
-
#include <metal_stdlib>
using namespace metal;
@@ -10,24 +8,6 @@
void f() {
a const a_1 = a{};
a const b = a_1;
- a const a = a{};
- a const b_1 = a;
+ a const a_2 = a{};
+ a const b_1 = a_2;
}
-program_source:11:16: error: expected ';' at end of declaration
- a const a = a{};
- ^
- ;
-program_source:12:4: error: expected ';' after expression
- a const b_1 = a;
- ^
- ;
-program_source:12:11: error: C++ requires a type specifier for all declarations
- a const b_1 = a;
- ~~~~~ ^
-program_source:11:15: warning: variable 'a' is uninitialized when used within its own initialization [-Wuninitialized]
- a const a = a{};
- ~ ^
-program_source:12:3: warning: expression result unused [-Wunused-value]
- a const b_1 = a;
- ^
-
diff --git a/test/tint/shadowing/struct/param.wgsl.expected.ir.msl b/test/tint/shadowing/struct/param.wgsl.expected.ir.msl
index 82f3eed..6f928c8 100644
--- a/test/tint/shadowing/struct/param.wgsl.expected.ir.msl
+++ b/test/tint/shadowing/struct/param.wgsl.expected.ir.msl
@@ -1,5 +1,3 @@
-SKIP: FAILED
-
#include <metal_stdlib>
using namespace metal;
@@ -7,17 +5,6 @@
int a;
};
-void f(a a) {
- a const b = a;
+void f(a a_1) {
+ a const b = a_1;
}
-program_source:9:4: error: expected ';' after expression
- a const b = a;
- ^
- ;
-program_source:9:11: error: C++ requires a type specifier for all declarations
- a const b = a;
- ~~~~~ ^
-program_source:9:3: warning: expression result unused [-Wunused-value]
- a const b = a;
- ^
-