[ir] Add increment and decrement statements.

This CL adds increment and decrement statement support into the IR.

Bug: tint:1718
Change-Id: Ieba2ab7a4c9232dc9d76a8605637cd5ea46b0e08
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/133162
Reviewed-by: Ben Clayton <bclayton@google.com>
Commit-Queue: Dan Sinclair <dsinclair@chromium.org>
Kokoro: Kokoro <noreply+kokoro@google.com>
Reviewed-by: James Price <jrprice@google.com>
This commit is contained in:
dan sinclair 2023-05-17 02:04:55 +00:00 committed by Dawn LUCI CQ
parent 112b7fd856
commit f55d13b754
2 changed files with 72 additions and 0 deletions

View File

@ -41,6 +41,7 @@
#include "src/tint/ast/identifier.h"
#include "src/tint/ast/identifier_expression.h"
#include "src/tint/ast/if_statement.h"
#include "src/tint/ast/increment_decrement_statement.h"
#include "src/tint/ast/int_literal_expression.h"
#include "src/tint/ast/invariant_attribute.h"
#include "src/tint/ast/let.h"
@ -84,6 +85,8 @@
#include "src/tint/utils/result.h"
#include "src/tint/utils/scoped_assignment.h"
using namespace tint::number_suffixes; // NOLINT
namespace tint::ir {
namespace {
@ -376,6 +379,7 @@ class Impl {
[&](const ast::ReturnStatement* r) { EmitReturn(r); },
[&](const ast::SwitchStatement* s) { EmitSwitch(s); },
[&](const ast::VariableDeclStatement* v) { EmitVariable(v->variable); },
[&](const ast::IncrementDecrementStatement* i) { EmitIncrementDecrement(i); },
[&](const ast::ConstAssert*) {
// Not emitted
},
@ -399,6 +403,28 @@ class Impl {
current_flow_block_->instructions.Push(store);
}
void EmitIncrementDecrement(const ast::IncrementDecrementStatement* stmt) {
auto lhs = EmitExpression(stmt->lhs);
if (!lhs) {
return;
}
auto* ty = lhs.Get()->Type();
auto* rhs = ty->UnwrapRef()->is_signed_integer_scalar() ? builder_.Constant(1_i)
: builder_.Constant(1_u);
Binary* inst = nullptr;
if (stmt->increment) {
inst = builder_.Add(ty, lhs.Get(), rhs);
} else {
inst = builder_.Subtract(ty, lhs.Get(), rhs);
}
current_flow_block_->instructions.Push(inst);
auto store = builder_.Store(lhs.Get(), inst);
current_flow_block_->instructions.Push(store);
}
void EmitCompoundAssignment(const ast::CompoundAssignmentStatement* stmt) {
auto lhs = EmitExpression(stmt->lhs);
if (!lhs) {

View File

@ -49,6 +49,29 @@ TEST_F(IR_BuilderImplTest, EmitExpression_Binary_Add) {
)");
}
TEST_F(IR_BuilderImplTest, EmitExpression_Binary_Increment) {
GlobalVar("v1", builtin::AddressSpace::kPrivate, ty.u32());
auto* expr = Increment("v1");
WrapInFunction(expr);
auto m = Build();
ASSERT_TRUE(m) << (!m ? m.Failure() : "");
EXPECT_EQ(Disassemble(m.Get()), R"(%fn1 = block {
%v1:ref<private, u32, read_write> = var private, read_write
}
%fn2 = func test_function():void [@compute @workgroup_size(1, 1, 1)] {
%fn3 = block {
%2:ref<private, u32, read_write> = add %v1:ref<private, u32, read_write>, 1u
store %v1:ref<private, u32, read_write>, %2:ref<private, u32, read_write>
} -> %func_end # return
} %func_end
)");
}
TEST_F(IR_BuilderImplTest, EmitExpression_Binary_CompoundAdd) {
GlobalVar("v1", builtin::AddressSpace::kPrivate, ty.u32());
auto* expr = CompoundAssign("v1", 1_u, ast::BinaryOp::kAdd);
@ -95,6 +118,29 @@ TEST_F(IR_BuilderImplTest, EmitExpression_Binary_Subtract) {
)");
}
TEST_F(IR_BuilderImplTest, EmitExpression_Binary_Decrement) {
GlobalVar("v1", builtin::AddressSpace::kPrivate, ty.i32());
auto* expr = Decrement("v1");
WrapInFunction(expr);
auto m = Build();
ASSERT_TRUE(m) << (!m ? m.Failure() : "");
EXPECT_EQ(Disassemble(m.Get()), R"(%fn1 = block {
%v1:ref<private, i32, read_write> = var private, read_write
}
%fn2 = func test_function():void [@compute @workgroup_size(1, 1, 1)] {
%fn3 = block {
%2:ref<private, i32, read_write> = sub %v1:ref<private, i32, read_write>, 1i
store %v1:ref<private, i32, read_write>, %2:ref<private, i32, read_write>
} -> %func_end # return
} %func_end
)");
}
TEST_F(IR_BuilderImplTest, EmitExpression_Binary_CompoundSubtract) {
GlobalVar("v1", builtin::AddressSpace::kPrivate, ty.u32());
auto* expr = CompoundAssign("v1", 1_u, ast::BinaryOp::kSubtract);