[ir] Handle phony assignment.
This CL adds phony assignment to the IR. The assignment part is ignored
and the RHS of the expression is generated. This creates a result value
which is then never used.
Bug: tint:1918
Change-Id: Ic87fdcb387cb4d9783c4dbbe26ebc76f67a3cdd9
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/133260
Reviewed-by: Ben Clayton <bclayton@google.com>
Commit-Queue: Dan Sinclair <dsinclair@chromium.org>
Kokoro: Kokoro <noreply+kokoro@google.com>
diff --git a/src/tint/ir/from_program.cc b/src/tint/ir/from_program.cc
index 76c1519..d42ea0b 100644
--- a/src/tint/ir/from_program.cc
+++ b/src/tint/ir/from_program.cc
@@ -48,6 +48,7 @@
#include "src/tint/ast/literal_expression.h"
#include "src/tint/ast/loop_statement.h"
#include "src/tint/ast/override.h"
+#include "src/tint/ast/phony_expression.h"
#include "src/tint/ast/return_statement.h"
#include "src/tint/ast/statement.h"
#include "src/tint/ast/struct.h"
@@ -338,7 +339,6 @@
current_flow_block_ = ir_func->start_target;
EmitBlock(ast_func->body);
- // TODO(dsinclair): Store return type and attributes
// TODO(dsinclair): Store parameters
// If the branch target has already been set then a `return` was called. Only set in the
@@ -392,6 +392,16 @@
}
void EmitAssignment(const ast::AssignmentStatement* stmt) {
+ // If assigning to a phony, just generate the RHS and we're done. Note that, because this
+ // isn't used, a subsequent transform could remove it due to it being dead code. This could
+ // then change the interface for the program (i.e. a global var no longer used). If that
+ // happens we have to either fix this to store to a phony value, or make sure we pull the
+ // interface before doing the dead code elimination.
+ if (stmt->lhs->Is<ast::PhonyExpression>()) {
+ (void)EmitExpression(stmt->rhs);
+ return;
+ }
+
auto lhs = EmitExpression(stmt->lhs);
if (!lhs) {
return;
@@ -827,10 +837,9 @@
// [&](const ast::MemberAccessorExpression* m) {
// TODO(dsinclair): Implement
// },
- // [&](const ast::PhonyExpression*) {
- // TODO(dsinclair): Implement. The call may have side effects so has to be made.
- // },
[&](const ast::UnaryOpExpression* u) { return EmitUnary(u); },
+ // Note, ast::PhonyExpression is explicitly not handled here as it should never get into
+ // this method. The assignment statement should have filtered it out already.
[&](Default) {
add_error(expr->source,
"unknown expression type: " + std::string(expr->TypeInfo().name));
diff --git a/src/tint/ir/from_program_test.cc b/src/tint/ir/from_program_test.cc
index 234b6cc..47dc911 100644
--- a/src/tint/ir/from_program_test.cc
+++ b/src/tint/ir/from_program_test.cc
@@ -1427,5 +1427,27 @@
)");
}
+TEST_F(IR_BuilderImplTest, Emit_Phony) {
+ Func("b", utils::Empty, ty.i32(), Return(1_i));
+ WrapInFunction(Ignore(Call("b")));
+
+ auto m = Build();
+ ASSERT_TRUE(m) << (!m ? m.Failure() : "");
+
+ EXPECT_EQ(Disassemble(m.Get()),
+ R"(%fn1 = func b():i32 {
+ %fn2 = block {
+ } -> %func_end 1i # return
+} %func_end
+
+%fn3 = func test_function():void [@compute @workgroup_size(1, 1, 1)] {
+ %fn4 = block {
+ %1:i32 = call b
+ } -> %func_end # return
+} %func_end
+
+)");
+}
+
} // namespace
} // namespace tint::ir