wgsl: Add support for increment/decrement statements

Implemented in both the reader and writer with E2E tests. Other
backends will ICE for now.

Bug: tint:1488
Change-Id: Ied2afa55a338347f427dee98a4076643ac432d9c
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/86003
Reviewed-by: Ben Clayton <bclayton@google.com>
diff --git a/src/tint/CMakeLists.txt b/src/tint/CMakeLists.txt
index 88ca0ea..046b814 100644
--- a/src/tint/CMakeLists.txt
+++ b/src/tint/CMakeLists.txt
@@ -903,6 +903,7 @@
       reader/wgsl/parser_impl_global_variable_decl_test.cc
       reader/wgsl/parser_impl_if_stmt_test.cc
       reader/wgsl/parser_impl_inclusive_or_expression_test.cc
+      reader/wgsl/parser_impl_increment_decrement_stmt_test.cc
       reader/wgsl/parser_impl_logical_and_expression_test.cc
       reader/wgsl/parser_impl_logical_or_expression_test.cc
       reader/wgsl/parser_impl_loop_stmt_test.cc
diff --git a/src/tint/reader/wgsl/parser_impl.cc b/src/tint/reader/wgsl/parser_impl.cc
index 2798c77..c6ace99 100644
--- a/src/tint/reader/wgsl/parser_impl.cc
+++ b/src/tint/reader/wgsl/parser_impl.cc
@@ -25,6 +25,7 @@
 #include "src/tint/ast/fallthrough_statement.h"
 #include "src/tint/ast/id_attribute.h"
 #include "src/tint/ast/if_statement.h"
+#include "src/tint/ast/increment_decrement_statement.h"
 #include "src/tint/ast/invariant_attribute.h"
 #include "src/tint/ast/loop_statement.h"
 #include "src/tint/ast/return_statement.h"
@@ -1464,6 +1465,8 @@
 //      | continue_stmt SEMICOLON
 //      | DISCARD SEMICOLON
 //      | assignment_stmt SEMICOLON
+//      | increment_stmt SEMICOLON
+//      | decrement_stmt SEMICOLON
 Maybe<const ast::Statement*> ParserImpl::statement() {
   while (match(Token::Type::kSemicolon)) {
     // Skip empty statements
@@ -1520,6 +1523,8 @@
 //   | continue_stmt SEMICOLON
 //   | DISCARD SEMICOLON
 //   | assignment_stmt SEMICOLON
+//   | increment_stmt SEMICOLON
+//   | decrement_stmt SEMICOLON
 Maybe<const ast::Statement*> ParserImpl::non_block_statement() {
   auto stmt = [&]() -> Maybe<const ast::Statement*> {
     auto ret_stmt = return_stmt();
@@ -1878,7 +1883,8 @@
 
 ForHeader::~ForHeader() = default;
 
-// (variable_stmt | assignment_stmt | func_call_stmt)?
+// (variable_stmt | increment_stmt | decrement_stmt | assignment_stmt |
+// func_call_stmt)?
 Maybe<const ast::Statement*> ParserImpl::for_header_initializer() {
   auto call = func_call_stmt();
   if (call.errored)
@@ -1901,7 +1907,7 @@
   return Failure::kNoMatch;
 }
 
-// (assignment_stmt | func_call_stmt)?
+// (increment_stmt | decrement_stmt | assignment_stmt | func_call_stmt)?
 Maybe<const ast::Statement*> ParserImpl::for_header_continuing() {
   auto call_stmt = func_call_stmt();
   if (call_stmt.errored)
@@ -2104,14 +2110,6 @@
   Source source;
 
   while (continue_parsing()) {
-    if (match(Token::Type::kPlusPlus, &source) ||
-        match(Token::Type::kMinusMinus, &source)) {
-      add_error(source,
-                "postfix increment and decrement operators are reserved for a "
-                "future WGSL version");
-      return Failure::kErrored;
-    }
-
     if (match(Token::Type::kBracketLeft, &source)) {
       auto res = sync(
           Token::Type::kBracketRight, [&]() -> Maybe<const ast::Expression*> {
@@ -2689,6 +2687,10 @@
 // assignment_stmt
 // | lhs_expression ( equal | compound_assignment_operator ) expression
 // | underscore equal expression
+// increment_stmt
+// | lhs_expression PLUS_PLUS
+// decrement_stmt
+// | lhs_expression MINUS_MINUS
 Maybe<const ast::Statement*> ParserImpl::assignment_stmt() {
   auto t = peek();
   auto source = t.source();
@@ -2712,6 +2714,16 @@
     lhs = create<ast::PhonyExpression>(source);
   }
 
+  // Handle increment and decrement statements.
+  // We do this here because the parsing of the LHS expression overlaps with
+  // the assignment statement, and we cannot tell which we are parsing until we
+  // hit the ++/--/= token.
+  if (match(Token::Type::kPlusPlus)) {
+    return create<ast::IncrementDecrementStatement>(source, lhs.value, true);
+  } else if (match(Token::Type::kMinusMinus)) {
+    return create<ast::IncrementDecrementStatement>(source, lhs.value, false);
+  }
+
   auto compound_op = compound_assignment_operator();
   if (compound_op.errored) {
     return Failure::kErrored;
diff --git a/src/tint/reader/wgsl/parser_impl_error_msg_test.cc b/src/tint/reader/wgsl/parser_impl_error_msg_test.cc
index f1444eb..60db589 100644
--- a/src/tint/reader/wgsl/parser_impl_error_msg_test.cc
+++ b/src/tint/reader/wgsl/parser_impl_error_msg_test.cc
@@ -1118,6 +1118,14 @@
 )");
 }
 
+TEST_F(ParserImplErrorTest, PostfixIncrementAsExpr) {
+  EXPECT("fn f() { var x : i32; let y = x++; }",
+         R"(test.wgsl:1:32 error: expected ';' for variable declaration
+fn f() { var x : i32; let y = x++; }
+                               ^^
+)");
+}
+
 TEST_F(ParserImplErrorTest, RelationalInvalidExpr) {
   EXPECT("fn f() { return 1 < >; }",
          R"(test.wgsl:1:21 error: unable to parse right side of < expression
diff --git a/src/tint/reader/wgsl/parser_impl_for_stmt_test.cc b/src/tint/reader/wgsl/parser_impl_for_stmt_test.cc
index fba74d7..da5ed54 100644
--- a/src/tint/reader/wgsl/parser_impl_for_stmt_test.cc
+++ b/src/tint/reader/wgsl/parser_impl_for_stmt_test.cc
@@ -112,6 +112,19 @@
   EXPECT_TRUE(fl->body->Empty());
 }
 
+// Test a for loop incrementing a variable in the initializer statement.
+TEST_F(ForStmtTest, InitializerStatementIncrement) {
+  auto p = parser("for (i++;;) { }");
+  auto fl = p->for_stmt();
+  EXPECT_FALSE(p->has_error()) << p->error();
+  EXPECT_FALSE(fl.errored);
+  ASSERT_TRUE(fl.matched);
+  EXPECT_TRUE(Is<ast::IncrementDecrementStatement>(fl->initializer));
+  EXPECT_EQ(fl->condition, nullptr);
+  EXPECT_EQ(fl->continuing, nullptr);
+  EXPECT_TRUE(fl->body->Empty());
+}
+
 // Test a for loop calling a function in the initializer statement.
 TEST_F(ForStmtTest, InitializerStatementFuncCall) {
   auto p = parser("for (a(b,c) ;;) { }");
@@ -151,6 +164,19 @@
   EXPECT_TRUE(fl->body->Empty());
 }
 
+// Test a for loop with an increment statement as the continuing statement.
+TEST_F(ForStmtTest, ContinuingIncrement) {
+  auto p = parser("for (;; x++) { }");
+  auto fl = p->for_stmt();
+  EXPECT_FALSE(p->has_error()) << p->error();
+  EXPECT_FALSE(fl.errored);
+  ASSERT_TRUE(fl.matched);
+  EXPECT_EQ(fl->initializer, nullptr);
+  EXPECT_EQ(fl->condition, nullptr);
+  EXPECT_TRUE(Is<ast::IncrementDecrementStatement>(fl->continuing));
+  EXPECT_TRUE(fl->body->Empty());
+}
+
 // Test a for loop calling a function in the continuing statement.
 TEST_F(ForStmtTest, ContinuingFuncCall) {
   auto p = parser("for (;; a(b,c)) { }");
diff --git a/src/tint/reader/wgsl/parser_impl_increment_decrement_stmt_test.cc b/src/tint/reader/wgsl/parser_impl_increment_decrement_stmt_test.cc
new file mode 100644
index 0000000..18f69a1
--- /dev/null
+++ b/src/tint/reader/wgsl/parser_impl_increment_decrement_stmt_test.cc
@@ -0,0 +1,132 @@
+// Copyright 2022 The Tint Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "src/tint/reader/wgsl/parser_impl_test_helper.h"
+
+namespace tint::reader::wgsl {
+namespace {
+
+TEST_F(ParserImplTest, IncrementDecrementStmt_Increment) {
+  auto p = parser("a++");
+  auto e = p->assignment_stmt();
+  EXPECT_TRUE(e.matched);
+  EXPECT_FALSE(e.errored);
+  EXPECT_FALSE(p->has_error()) << p->error();
+  ASSERT_NE(e.value, nullptr);
+
+  auto* i = e->As<ast::IncrementDecrementStatement>();
+  ASSERT_NE(i, nullptr);
+  ASSERT_NE(i->lhs, nullptr);
+
+  ASSERT_TRUE(i->lhs->Is<ast::IdentifierExpression>());
+  auto* ident = i->lhs->As<ast::IdentifierExpression>();
+  EXPECT_EQ(ident->symbol, p->builder().Symbols().Get("a"));
+
+  EXPECT_TRUE(i->increment);
+}
+
+TEST_F(ParserImplTest, IncrementDecrementStmt_Decrement) {
+  auto p = parser("a--");
+  auto e = p->assignment_stmt();
+  EXPECT_TRUE(e.matched);
+  EXPECT_FALSE(e.errored);
+  EXPECT_FALSE(p->has_error()) << p->error();
+  ASSERT_NE(e.value, nullptr);
+
+  auto* i = e->As<ast::IncrementDecrementStatement>();
+  ASSERT_NE(i, nullptr);
+  ASSERT_NE(i->lhs, nullptr);
+
+  ASSERT_TRUE(i->lhs->Is<ast::IdentifierExpression>());
+  auto* ident = i->lhs->As<ast::IdentifierExpression>();
+  EXPECT_EQ(ident->symbol, p->builder().Symbols().Get("a"));
+
+  EXPECT_FALSE(i->increment);
+}
+
+TEST_F(ParserImplTest, IncrementDecrementStmt_Parenthesized) {
+  auto p = parser("(a)++");
+  auto e = p->assignment_stmt();
+  EXPECT_TRUE(e.matched);
+  EXPECT_FALSE(e.errored);
+  EXPECT_FALSE(p->has_error()) << p->error();
+  ASSERT_NE(e.value, nullptr);
+
+  auto* i = e->As<ast::IncrementDecrementStatement>();
+  ASSERT_NE(i, nullptr);
+  ASSERT_NE(i->lhs, nullptr);
+
+  ASSERT_TRUE(i->lhs->Is<ast::IdentifierExpression>());
+  auto* ident = i->lhs->As<ast::IdentifierExpression>();
+  EXPECT_EQ(ident->symbol, p->builder().Symbols().Get("a"));
+
+  EXPECT_TRUE(i->increment);
+}
+
+TEST_F(ParserImplTest, IncrementDecrementStmt_ToMember) {
+  auto p = parser("a.b.c[2].d++");
+  auto e = p->assignment_stmt();
+  EXPECT_TRUE(e.matched);
+  EXPECT_FALSE(e.errored);
+  EXPECT_FALSE(p->has_error()) << p->error();
+  ASSERT_NE(e.value, nullptr);
+
+  auto* i = e->As<ast::IncrementDecrementStatement>();
+  ASSERT_NE(i, nullptr);
+  ASSERT_NE(i->lhs, nullptr);
+  EXPECT_TRUE(i->increment);
+
+  ASSERT_TRUE(i->lhs->Is<ast::MemberAccessorExpression>());
+  auto* mem = i->lhs->As<ast::MemberAccessorExpression>();
+
+  ASSERT_TRUE(mem->member->Is<ast::IdentifierExpression>());
+  auto* ident = mem->member->As<ast::IdentifierExpression>();
+  EXPECT_EQ(ident->symbol, p->builder().Symbols().Get("d"));
+
+  ASSERT_TRUE(mem->structure->Is<ast::IndexAccessorExpression>());
+  auto* idx = mem->structure->As<ast::IndexAccessorExpression>();
+
+  ASSERT_NE(idx->index, nullptr);
+  ASSERT_TRUE(idx->index->Is<ast::SintLiteralExpression>());
+  EXPECT_EQ(idx->index->As<ast::SintLiteralExpression>()->value, 2);
+
+  ASSERT_TRUE(idx->object->Is<ast::MemberAccessorExpression>());
+  mem = idx->object->As<ast::MemberAccessorExpression>();
+  ASSERT_TRUE(mem->member->Is<ast::IdentifierExpression>());
+  ident = mem->member->As<ast::IdentifierExpression>();
+  EXPECT_EQ(ident->symbol, p->builder().Symbols().Get("c"));
+
+  ASSERT_TRUE(mem->structure->Is<ast::MemberAccessorExpression>());
+  mem = mem->structure->As<ast::MemberAccessorExpression>();
+
+  ASSERT_TRUE(mem->structure->Is<ast::IdentifierExpression>());
+  ident = mem->structure->As<ast::IdentifierExpression>();
+  EXPECT_EQ(ident->symbol, p->builder().Symbols().Get("a"));
+
+  ASSERT_TRUE(mem->member->Is<ast::IdentifierExpression>());
+  ident = mem->member->As<ast::IdentifierExpression>();
+  EXPECT_EQ(ident->symbol, p->builder().Symbols().Get("b"));
+}
+
+TEST_F(ParserImplTest, IncrementDecrementStmt_InvalidLHS) {
+  auto p = parser("{}++");
+  auto e = p->assignment_stmt();
+  EXPECT_FALSE(e.matched);
+  EXPECT_FALSE(e.errored);
+  EXPECT_FALSE(p->has_error()) << p->error();
+  EXPECT_EQ(e.value, nullptr);
+}
+
+}  // namespace
+}  // namespace tint::reader::wgsl
diff --git a/src/tint/reader/wgsl/parser_impl_singular_expression_test.cc b/src/tint/reader/wgsl/parser_impl_singular_expression_test.cc
index 115f676..44950a3 100644
--- a/src/tint/reader/wgsl/parser_impl_singular_expression_test.cc
+++ b/src/tint/reader/wgsl/parser_impl_singular_expression_test.cc
@@ -233,30 +233,6 @@
   EXPECT_EQ(index_expr->symbol, p->builder().Symbols().Get("c"));
 }
 
-TEST_F(ParserImplTest, SingularExpression_PostfixPlusPlus) {
-  auto p = parser("a++");
-  auto e = p->singular_expression();
-  EXPECT_FALSE(e.matched);
-  EXPECT_TRUE(e.errored);
-  EXPECT_EQ(e.value, nullptr);
-  EXPECT_TRUE(p->has_error());
-  EXPECT_EQ(p->error(),
-            "1:2: postfix increment and decrement operators are reserved for a "
-            "future WGSL version");
-}
-
-TEST_F(ParserImplTest, SingularExpression_PostfixMinusMinus) {
-  auto p = parser("a--");
-  auto e = p->singular_expression();
-  EXPECT_FALSE(e.matched);
-  EXPECT_TRUE(e.errored);
-  EXPECT_EQ(e.value, nullptr);
-  EXPECT_TRUE(p->has_error());
-  EXPECT_EQ(p->error(),
-            "1:2: postfix increment and decrement operators are reserved for a "
-            "future WGSL version");
-}
-
 }  // namespace
 }  // namespace wgsl
 }  // namespace reader
diff --git a/src/tint/writer/wgsl/generator_impl.cc b/src/tint/writer/wgsl/generator_impl.cc
index 7f23195..d3174c1 100644
--- a/src/tint/writer/wgsl/generator_impl.cc
+++ b/src/tint/writer/wgsl/generator_impl.cc
@@ -922,6 +922,9 @@
       [&](const ast::DiscardStatement* d) { return EmitDiscard(d); },
       [&](const ast::FallthroughStatement* f) { return EmitFallthrough(f); },
       [&](const ast::IfStatement* i) { return EmitIf(i); },
+      [&](const ast::IncrementDecrementStatement* l) {
+        return EmitIncrementDecrement(l);
+      },
       [&](const ast::LoopStatement* l) { return EmitLoop(l); },
       [&](const ast::ForLoopStatement* l) { return EmitForLoop(l); },
       [&](const ast::ReturnStatement* r) { return EmitReturn(r); },
@@ -1072,6 +1075,16 @@
   return true;
 }
 
+bool GeneratorImpl::EmitIncrementDecrement(
+    const ast::IncrementDecrementStatement* stmt) {
+  auto out = line();
+  if (!EmitExpression(out, stmt->lhs)) {
+    return false;
+  }
+  out << (stmt->increment ? "++" : "--") << ";";
+  return true;
+}
+
 bool GeneratorImpl::EmitDiscard(const ast::DiscardStatement*) {
   line() << "discard;";
   return true;
diff --git a/src/tint/writer/wgsl/generator_impl.h b/src/tint/writer/wgsl/generator_impl.h
index 081bd33..bee8d65 100644
--- a/src/tint/writer/wgsl/generator_impl.h
+++ b/src/tint/writer/wgsl/generator_impl.h
@@ -133,6 +133,10 @@
   /// @param stmt the statement to emit
   /// @returns true if the statement was successfully emitted
   bool EmitIf(const ast::IfStatement* stmt);
+  /// Handles an increment/decrement statement
+  /// @param stmt the statement to emit
+  /// @returns true if the statement was successfully emitted
+  bool EmitIncrementDecrement(const ast::IncrementDecrementStatement* stmt);
   /// Handles generating a discard statement
   /// @param stmt the discard statement
   /// @returns true if the statement was successfully emitted
diff --git a/test/tint/BUILD.gn b/test/tint/BUILD.gn
index fa835d6..fcf85d1 100644
--- a/test/tint/BUILD.gn
+++ b/test/tint/BUILD.gn
@@ -499,6 +499,7 @@
     "../../src/tint/reader/wgsl/parser_impl_global_variable_decl_test.cc",
     "../../src/tint/reader/wgsl/parser_impl_if_stmt_test.cc",
     "../../src/tint/reader/wgsl/parser_impl_inclusive_or_expression_test.cc",
+    "../../src/tint/reader/wgsl/parser_impl_increment_decrement_stmt_test.cc",
     "../../src/tint/reader/wgsl/parser_impl_logical_and_expression_test.cc",
     "../../src/tint/reader/wgsl/parser_impl_logical_or_expression_test.cc",
     "../../src/tint/reader/wgsl/parser_impl_loop_stmt_test.cc",
diff --git a/test/tint/statements/decrement/array_element.wgsl b/test/tint/statements/decrement/array_element.wgsl
new file mode 100644
index 0000000..9ef01ec
--- /dev/null
+++ b/test/tint/statements/decrement/array_element.wgsl
@@ -0,0 +1,5 @@
+@group(0) @binding(0) var<storage, read_write> a : array<u32>;
+
+fn main() {
+  a[1]--;
+}
diff --git a/test/tint/statements/decrement/array_element.wgsl.expected.glsl b/test/tint/statements/decrement/array_element.wgsl.expected.glsl
new file mode 100644
index 0000000..9e5435d
--- /dev/null
+++ b/test/tint/statements/decrement/array_element.wgsl.expected.glsl
@@ -0,0 +1,10 @@
+SKIP: FAILED
+
+
+@group(0) @binding(0) var<storage, read_write> a : array<u32>;
+
+fn main() {
+  a[1]--;
+}
+
+Failed to generate: error: unknown statement type: tint::ast::IncrementDecrementStatement
diff --git a/test/tint/statements/decrement/array_element.wgsl.expected.hlsl b/test/tint/statements/decrement/array_element.wgsl.expected.hlsl
new file mode 100644
index 0000000..0f960c8
--- /dev/null
+++ b/test/tint/statements/decrement/array_element.wgsl.expected.hlsl
@@ -0,0 +1,10 @@
+SKIP: FAILED
+
+
+@group(0) @binding(0) var<storage, read_write> a : array<u32>;
+
+fn main() {
+  a[1]--;
+}
+
+Failed to generate: error: cannot modify value of type 'u32'
diff --git a/test/tint/statements/decrement/array_element.wgsl.expected.msl b/test/tint/statements/decrement/array_element.wgsl.expected.msl
new file mode 100644
index 0000000..f1cd0f6
--- /dev/null
+++ b/test/tint/statements/decrement/array_element.wgsl.expected.msl
@@ -0,0 +1,10 @@
+SKIP: FAILED
+
+
+@group(0) @binding(0) var<storage, read_write> a : array<u32>;
+
+fn tint_symbol() {
+  a[1]--;
+}
+
+Failed to generate: error: unknown statement type: tint::ast::IncrementDecrementStatement
diff --git a/test/tint/statements/decrement/array_element.wgsl.expected.spvasm b/test/tint/statements/decrement/array_element.wgsl.expected.spvasm
new file mode 100644
index 0000000..6cea2ce
--- /dev/null
+++ b/test/tint/statements/decrement/array_element.wgsl.expected.spvasm
@@ -0,0 +1,10 @@
+SKIP: FAILED
+
+
+@group(0) @binding(0) var<storage, read_write> a : array<u32>;
+
+fn main() {
+  a[1]--;
+}
+
+Failed to generate: Unknown statement: tint::ast::IncrementDecrementStatement
diff --git a/test/tint/statements/decrement/array_element.wgsl.expected.wgsl b/test/tint/statements/decrement/array_element.wgsl.expected.wgsl
new file mode 100644
index 0000000..9ef01ec
--- /dev/null
+++ b/test/tint/statements/decrement/array_element.wgsl.expected.wgsl
@@ -0,0 +1,5 @@
+@group(0) @binding(0) var<storage, read_write> a : array<u32>;
+
+fn main() {
+  a[1]--;
+}
diff --git a/test/tint/statements/decrement/complex.wgsl b/test/tint/statements/decrement/complex.wgsl
new file mode 100644
index 0000000..cc70319
--- /dev/null
+++ b/test/tint/statements/decrement/complex.wgsl
@@ -0,0 +1,44 @@
+struct S {
+  a : array<vec4<i32>, 4>
+}
+
+@group(0) @binding(0) var<storage, read_write>  buffer : array<S>;
+
+var<private> v : u32;
+
+fn idx1() -> i32 {
+  v--;
+  return 1;
+}
+
+fn idx2() -> i32 {
+  v--;
+  return 2;
+}
+
+fn idx3() -> i32 {
+  v--;
+  return 3;
+}
+
+fn idx4() -> i32 {
+  v--;
+  return 4;
+}
+
+fn idx5() -> i32 {
+  v--;
+  return 0;
+}
+
+fn idx6() -> i32 {
+  v--;
+  return 2;
+}
+
+fn main() {
+  for (buffer[idx1()].a[idx2()][idx3()]--;
+       v < 10u;
+       buffer[idx4()].a[idx5()][idx6()]--) {
+  }
+}
diff --git a/test/tint/statements/decrement/complex.wgsl.expected.glsl b/test/tint/statements/decrement/complex.wgsl.expected.glsl
new file mode 100644
index 0000000..67e2532
--- /dev/null
+++ b/test/tint/statements/decrement/complex.wgsl.expected.glsl
@@ -0,0 +1,47 @@
+SKIP: FAILED
+
+
+struct S {
+  a : array<vec4<i32>, 4>,
+}
+
+@group(0) @binding(0) var<storage, read_write> buffer : array<S>;
+
+var<private> v : u32;
+
+fn idx1() -> i32 {
+  v--;
+  return 1;
+}
+
+fn idx2() -> i32 {
+  v--;
+  return 2;
+}
+
+fn idx3() -> i32 {
+  v--;
+  return 3;
+}
+
+fn idx4() -> i32 {
+  v--;
+  return 4;
+}
+
+fn idx5() -> i32 {
+  v--;
+  return 0;
+}
+
+fn idx6() -> i32 {
+  v--;
+  return 2;
+}
+
+fn main() {
+  for(buffer[idx1()].a[idx2()][idx3()]--; (v < 10u); buffer[idx4()].a[idx5()][idx6()]--) {
+  }
+}
+
+Failed to generate: error: unknown statement type: tint::ast::IncrementDecrementStatement
diff --git a/test/tint/statements/decrement/complex.wgsl.expected.hlsl b/test/tint/statements/decrement/complex.wgsl.expected.hlsl
new file mode 100644
index 0000000..b5f16eb
--- /dev/null
+++ b/test/tint/statements/decrement/complex.wgsl.expected.hlsl
@@ -0,0 +1,47 @@
+SKIP: FAILED
+
+
+struct S {
+  a : array<vec4<i32>, 4>,
+}
+
+@group(0) @binding(0) var<storage, read_write> buffer : array<S>;
+
+var<private> v : u32;
+
+fn idx1() -> i32 {
+  v--;
+  return 1;
+}
+
+fn idx2() -> i32 {
+  v--;
+  return 2;
+}
+
+fn idx3() -> i32 {
+  v--;
+  return 3;
+}
+
+fn idx4() -> i32 {
+  v--;
+  return 4;
+}
+
+fn idx5() -> i32 {
+  v--;
+  return 0;
+}
+
+fn idx6() -> i32 {
+  v--;
+  return 2;
+}
+
+fn main() {
+  for(buffer[idx1()].a[idx2()][idx3()]--; (v < 10u); buffer[idx4()].a[idx5()][idx6()]--) {
+  }
+}
+
+Failed to generate: error: cannot modify value of type 'i32'
diff --git a/test/tint/statements/decrement/complex.wgsl.expected.msl b/test/tint/statements/decrement/complex.wgsl.expected.msl
new file mode 100644
index 0000000..ad5f5a6
--- /dev/null
+++ b/test/tint/statements/decrement/complex.wgsl.expected.msl
@@ -0,0 +1,47 @@
+SKIP: FAILED
+
+
+struct S {
+  a : array<vec4<i32>, 4>,
+}
+
+@group(0) @binding(0) var<storage, read_write> tint_symbol : array<S>;
+
+var<private> v : u32;
+
+fn idx1() -> i32 {
+  v--;
+  return 1;
+}
+
+fn idx2() -> i32 {
+  v--;
+  return 2;
+}
+
+fn idx3() -> i32 {
+  v--;
+  return 3;
+}
+
+fn idx4() -> i32 {
+  v--;
+  return 4;
+}
+
+fn idx5() -> i32 {
+  v--;
+  return 0;
+}
+
+fn idx6() -> i32 {
+  v--;
+  return 2;
+}
+
+fn tint_symbol_1() {
+  for(tint_symbol[idx1()].a[idx2()][idx3()]--; (v < 10u); tint_symbol[idx4()].a[idx5()][idx6()]--) {
+  }
+}
+
+Failed to generate: error: unknown statement type: tint::ast::IncrementDecrementStatement
diff --git a/test/tint/statements/decrement/complex.wgsl.expected.spvasm b/test/tint/statements/decrement/complex.wgsl.expected.spvasm
new file mode 100644
index 0000000..c5953fc
--- /dev/null
+++ b/test/tint/statements/decrement/complex.wgsl.expected.spvasm
@@ -0,0 +1,47 @@
+SKIP: FAILED
+
+
+struct S {
+  a : array<vec4<i32>, 4>,
+}
+
+@group(0) @binding(0) var<storage, read_write> buffer : array<S>;
+
+var<private> v : u32;
+
+fn idx1() -> i32 {
+  v--;
+  return 1;
+}
+
+fn idx2() -> i32 {
+  v--;
+  return 2;
+}
+
+fn idx3() -> i32 {
+  v--;
+  return 3;
+}
+
+fn idx4() -> i32 {
+  v--;
+  return 4;
+}
+
+fn idx5() -> i32 {
+  v--;
+  return 0;
+}
+
+fn idx6() -> i32 {
+  v--;
+  return 2;
+}
+
+fn main() {
+  for(buffer[idx1()].a[idx2()][idx3()]--; (v < 10u); buffer[idx4()].a[idx5()][idx6()]--) {
+  }
+}
+
+Failed to generate: Unknown statement: tint::ast::IncrementDecrementStatement
diff --git a/test/tint/statements/decrement/complex.wgsl.expected.wgsl b/test/tint/statements/decrement/complex.wgsl.expected.wgsl
new file mode 100644
index 0000000..d3b55f5
--- /dev/null
+++ b/test/tint/statements/decrement/complex.wgsl.expected.wgsl
@@ -0,0 +1,42 @@
+struct S {
+  a : array<vec4<i32>, 4>,
+}
+
+@group(0) @binding(0) var<storage, read_write> buffer : array<S>;
+
+var<private> v : u32;
+
+fn idx1() -> i32 {
+  v--;
+  return 1;
+}
+
+fn idx2() -> i32 {
+  v--;
+  return 2;
+}
+
+fn idx3() -> i32 {
+  v--;
+  return 3;
+}
+
+fn idx4() -> i32 {
+  v--;
+  return 4;
+}
+
+fn idx5() -> i32 {
+  v--;
+  return 0;
+}
+
+fn idx6() -> i32 {
+  v--;
+  return 2;
+}
+
+fn main() {
+  for(buffer[idx1()].a[idx2()][idx3()]--; (v < 10u); buffer[idx4()].a[idx5()][idx6()]--) {
+  }
+}
diff --git a/test/tint/statements/decrement/for_loop_continuing.wgsl b/test/tint/statements/decrement/for_loop_continuing.wgsl
new file mode 100644
index 0000000..2bf539a
--- /dev/null
+++ b/test/tint/statements/decrement/for_loop_continuing.wgsl
@@ -0,0 +1,6 @@
+@group(0) @binding(0) var<storage, read_write> i : u32;
+
+fn main() {
+  for (; i < 10u; i--) {
+  }
+}
diff --git a/test/tint/statements/decrement/for_loop_continuing.wgsl.expected.glsl b/test/tint/statements/decrement/for_loop_continuing.wgsl.expected.glsl
new file mode 100644
index 0000000..1f4cedf
--- /dev/null
+++ b/test/tint/statements/decrement/for_loop_continuing.wgsl.expected.glsl
@@ -0,0 +1,11 @@
+SKIP: FAILED
+
+
+@group(0) @binding(0) var<storage, read_write> i : u32;
+
+fn main() {
+  for(; (i < 10u); i--) {
+  }
+}
+
+Failed to generate: error: unknown statement type: tint::ast::IncrementDecrementStatement
diff --git a/test/tint/statements/decrement/for_loop_continuing.wgsl.expected.hlsl b/test/tint/statements/decrement/for_loop_continuing.wgsl.expected.hlsl
new file mode 100644
index 0000000..532428f
--- /dev/null
+++ b/test/tint/statements/decrement/for_loop_continuing.wgsl.expected.hlsl
@@ -0,0 +1,11 @@
+SKIP: FAILED
+
+
+@group(0) @binding(0) var<storage, read_write> i : u32;
+
+fn main() {
+  for(; (i < 10u); i--) {
+  }
+}
+
+Failed to generate: error: cannot modify value of type 'u32'
diff --git a/test/tint/statements/decrement/for_loop_continuing.wgsl.expected.msl b/test/tint/statements/decrement/for_loop_continuing.wgsl.expected.msl
new file mode 100644
index 0000000..c11b80d
--- /dev/null
+++ b/test/tint/statements/decrement/for_loop_continuing.wgsl.expected.msl
@@ -0,0 +1,11 @@
+SKIP: FAILED
+
+
+@group(0) @binding(0) var<storage, read_write> i : u32;
+
+fn tint_symbol() {
+  for(; (i < 10u); i--) {
+  }
+}
+
+Failed to generate: error: unknown statement type: tint::ast::IncrementDecrementStatement
diff --git a/test/tint/statements/decrement/for_loop_continuing.wgsl.expected.spvasm b/test/tint/statements/decrement/for_loop_continuing.wgsl.expected.spvasm
new file mode 100644
index 0000000..3e3ebd2
--- /dev/null
+++ b/test/tint/statements/decrement/for_loop_continuing.wgsl.expected.spvasm
@@ -0,0 +1,11 @@
+SKIP: FAILED
+
+
+@group(0) @binding(0) var<storage, read_write> i : u32;
+
+fn main() {
+  for(; (i < 10u); i--) {
+  }
+}
+
+Failed to generate: Unknown statement: tint::ast::IncrementDecrementStatement
diff --git a/test/tint/statements/decrement/for_loop_continuing.wgsl.expected.wgsl b/test/tint/statements/decrement/for_loop_continuing.wgsl.expected.wgsl
new file mode 100644
index 0000000..fadeaec
--- /dev/null
+++ b/test/tint/statements/decrement/for_loop_continuing.wgsl.expected.wgsl
@@ -0,0 +1,6 @@
+@group(0) @binding(0) var<storage, read_write> i : u32;
+
+fn main() {
+  for(; (i < 10u); i--) {
+  }
+}
diff --git a/test/tint/statements/decrement/for_loop_initializer.wgsl b/test/tint/statements/decrement/for_loop_initializer.wgsl
new file mode 100644
index 0000000..7551a7a1
--- /dev/null
+++ b/test/tint/statements/decrement/for_loop_initializer.wgsl
@@ -0,0 +1,6 @@
+@group(0) @binding(0) var<storage, read_write> i : u32;
+
+fn main() {
+  for (i--; i < 10u; ) {
+  }
+}
diff --git a/test/tint/statements/decrement/for_loop_initializer.wgsl.expected.glsl b/test/tint/statements/decrement/for_loop_initializer.wgsl.expected.glsl
new file mode 100644
index 0000000..941b4f3
--- /dev/null
+++ b/test/tint/statements/decrement/for_loop_initializer.wgsl.expected.glsl
@@ -0,0 +1,11 @@
+SKIP: FAILED
+
+
+@group(0) @binding(0) var<storage, read_write> i : u32;
+
+fn main() {
+  for(i--; (i < 10u); ) {
+  }
+}
+
+Failed to generate: error: unknown statement type: tint::ast::IncrementDecrementStatement
diff --git a/test/tint/statements/decrement/for_loop_initializer.wgsl.expected.hlsl b/test/tint/statements/decrement/for_loop_initializer.wgsl.expected.hlsl
new file mode 100644
index 0000000..9aff109
--- /dev/null
+++ b/test/tint/statements/decrement/for_loop_initializer.wgsl.expected.hlsl
@@ -0,0 +1,11 @@
+SKIP: FAILED
+
+
+@group(0) @binding(0) var<storage, read_write> i : u32;
+
+fn main() {
+  for(i--; (i < 10u); ) {
+  }
+}
+
+Failed to generate: error: cannot modify value of type 'u32'
diff --git a/test/tint/statements/decrement/for_loop_initializer.wgsl.expected.msl b/test/tint/statements/decrement/for_loop_initializer.wgsl.expected.msl
new file mode 100644
index 0000000..ebbacb6
--- /dev/null
+++ b/test/tint/statements/decrement/for_loop_initializer.wgsl.expected.msl
@@ -0,0 +1,11 @@
+SKIP: FAILED
+
+
+@group(0) @binding(0) var<storage, read_write> i : u32;
+
+fn tint_symbol() {
+  for(i--; (i < 10u); ) {
+  }
+}
+
+Failed to generate: error: unknown statement type: tint::ast::IncrementDecrementStatement
diff --git a/test/tint/statements/decrement/for_loop_initializer.wgsl.expected.spvasm b/test/tint/statements/decrement/for_loop_initializer.wgsl.expected.spvasm
new file mode 100644
index 0000000..a95225b
--- /dev/null
+++ b/test/tint/statements/decrement/for_loop_initializer.wgsl.expected.spvasm
@@ -0,0 +1,11 @@
+SKIP: FAILED
+
+
+@group(0) @binding(0) var<storage, read_write> i : u32;
+
+fn main() {
+  for(i--; (i < 10u); ) {
+  }
+}
+
+Failed to generate: Unknown statement: tint::ast::IncrementDecrementStatement
diff --git a/test/tint/statements/decrement/for_loop_initializer.wgsl.expected.wgsl b/test/tint/statements/decrement/for_loop_initializer.wgsl.expected.wgsl
new file mode 100644
index 0000000..19e7dcd
--- /dev/null
+++ b/test/tint/statements/decrement/for_loop_initializer.wgsl.expected.wgsl
@@ -0,0 +1,6 @@
+@group(0) @binding(0) var<storage, read_write> i : u32;
+
+fn main() {
+  for(i--; (i < 10u); ) {
+  }
+}
diff --git a/test/tint/statements/decrement/function.wgsl b/test/tint/statements/decrement/function.wgsl
new file mode 100644
index 0000000..3ea7d0b
--- /dev/null
+++ b/test/tint/statements/decrement/function.wgsl
@@ -0,0 +1,4 @@
+fn main() {
+  var i = 0;
+  i--;
+}
diff --git a/test/tint/statements/decrement/function.wgsl.expected.glsl b/test/tint/statements/decrement/function.wgsl.expected.glsl
new file mode 100644
index 0000000..ad95151
--- /dev/null
+++ b/test/tint/statements/decrement/function.wgsl.expected.glsl
@@ -0,0 +1,9 @@
+SKIP: FAILED
+
+
+fn main() {
+  var i = 0;
+  i--;
+}
+
+Failed to generate: error: unknown statement type: tint::ast::IncrementDecrementStatement
diff --git a/test/tint/statements/decrement/function.wgsl.expected.hlsl b/test/tint/statements/decrement/function.wgsl.expected.hlsl
new file mode 100644
index 0000000..ad95151
--- /dev/null
+++ b/test/tint/statements/decrement/function.wgsl.expected.hlsl
@@ -0,0 +1,9 @@
+SKIP: FAILED
+
+
+fn main() {
+  var i = 0;
+  i--;
+}
+
+Failed to generate: error: unknown statement type: tint::ast::IncrementDecrementStatement
diff --git a/test/tint/statements/decrement/function.wgsl.expected.msl b/test/tint/statements/decrement/function.wgsl.expected.msl
new file mode 100644
index 0000000..4242e3c
--- /dev/null
+++ b/test/tint/statements/decrement/function.wgsl.expected.msl
@@ -0,0 +1,9 @@
+SKIP: FAILED
+
+
+fn tint_symbol() {
+  var i = 0;
+  i--;
+}
+
+Failed to generate: error: unknown statement type: tint::ast::IncrementDecrementStatement
diff --git a/test/tint/statements/decrement/function.wgsl.expected.spvasm b/test/tint/statements/decrement/function.wgsl.expected.spvasm
new file mode 100644
index 0000000..f1adcdf
--- /dev/null
+++ b/test/tint/statements/decrement/function.wgsl.expected.spvasm
@@ -0,0 +1,9 @@
+SKIP: FAILED
+
+
+fn main() {
+  var i = 0;
+  i--;
+}
+
+Failed to generate: Unknown statement: tint::ast::IncrementDecrementStatement
diff --git a/test/tint/statements/decrement/function.wgsl.expected.wgsl b/test/tint/statements/decrement/function.wgsl.expected.wgsl
new file mode 100644
index 0000000..3ea7d0b
--- /dev/null
+++ b/test/tint/statements/decrement/function.wgsl.expected.wgsl
@@ -0,0 +1,4 @@
+fn main() {
+  var i = 0;
+  i--;
+}
diff --git a/test/tint/statements/decrement/private.wgsl b/test/tint/statements/decrement/private.wgsl
new file mode 100644
index 0000000..3989ae1
--- /dev/null
+++ b/test/tint/statements/decrement/private.wgsl
@@ -0,0 +1,5 @@
+var<private> i : i32 = 0;
+
+fn main() {
+  i--;
+}
diff --git a/test/tint/statements/decrement/private.wgsl.expected.glsl b/test/tint/statements/decrement/private.wgsl.expected.glsl
new file mode 100644
index 0000000..48cffdb
--- /dev/null
+++ b/test/tint/statements/decrement/private.wgsl.expected.glsl
@@ -0,0 +1,10 @@
+SKIP: FAILED
+
+
+var<private> i : i32 = 0;
+
+fn main() {
+  i--;
+}
+
+Failed to generate: error: unknown statement type: tint::ast::IncrementDecrementStatement
diff --git a/test/tint/statements/decrement/private.wgsl.expected.hlsl b/test/tint/statements/decrement/private.wgsl.expected.hlsl
new file mode 100644
index 0000000..48cffdb
--- /dev/null
+++ b/test/tint/statements/decrement/private.wgsl.expected.hlsl
@@ -0,0 +1,10 @@
+SKIP: FAILED
+
+
+var<private> i : i32 = 0;
+
+fn main() {
+  i--;
+}
+
+Failed to generate: error: unknown statement type: tint::ast::IncrementDecrementStatement
diff --git a/test/tint/statements/decrement/private.wgsl.expected.msl b/test/tint/statements/decrement/private.wgsl.expected.msl
new file mode 100644
index 0000000..c223434
--- /dev/null
+++ b/test/tint/statements/decrement/private.wgsl.expected.msl
@@ -0,0 +1,10 @@
+SKIP: FAILED
+
+
+var<private> i : i32 = 0;
+
+fn tint_symbol() {
+  i--;
+}
+
+Failed to generate: error: unknown statement type: tint::ast::IncrementDecrementStatement
diff --git a/test/tint/statements/decrement/private.wgsl.expected.spvasm b/test/tint/statements/decrement/private.wgsl.expected.spvasm
new file mode 100644
index 0000000..441401d
--- /dev/null
+++ b/test/tint/statements/decrement/private.wgsl.expected.spvasm
@@ -0,0 +1,10 @@
+SKIP: FAILED
+
+
+var<private> i : i32 = 0;
+
+fn main() {
+  i--;
+}
+
+Failed to generate: Unknown statement: tint::ast::IncrementDecrementStatement
diff --git a/test/tint/statements/decrement/private.wgsl.expected.wgsl b/test/tint/statements/decrement/private.wgsl.expected.wgsl
new file mode 100644
index 0000000..3989ae1
--- /dev/null
+++ b/test/tint/statements/decrement/private.wgsl.expected.wgsl
@@ -0,0 +1,5 @@
+var<private> i : i32 = 0;
+
+fn main() {
+  i--;
+}
diff --git a/test/tint/statements/decrement/storage.wgsl b/test/tint/statements/decrement/storage.wgsl
new file mode 100644
index 0000000..fd5d013
--- /dev/null
+++ b/test/tint/statements/decrement/storage.wgsl
@@ -0,0 +1,5 @@
+@group(0) @binding(0) var<storage, read_write> i : u32;
+
+fn main() {
+  i--;
+}
diff --git a/test/tint/statements/decrement/storage.wgsl.expected.glsl b/test/tint/statements/decrement/storage.wgsl.expected.glsl
new file mode 100644
index 0000000..4f603ea
--- /dev/null
+++ b/test/tint/statements/decrement/storage.wgsl.expected.glsl
@@ -0,0 +1,10 @@
+SKIP: FAILED
+
+
+@group(0) @binding(0) var<storage, read_write> i : u32;
+
+fn main() {
+  i--;
+}
+
+Failed to generate: error: unknown statement type: tint::ast::IncrementDecrementStatement
diff --git a/test/tint/statements/decrement/storage.wgsl.expected.hlsl b/test/tint/statements/decrement/storage.wgsl.expected.hlsl
new file mode 100644
index 0000000..28354c5
--- /dev/null
+++ b/test/tint/statements/decrement/storage.wgsl.expected.hlsl
@@ -0,0 +1,10 @@
+SKIP: FAILED
+
+
+@group(0) @binding(0) var<storage, read_write> i : u32;
+
+fn main() {
+  i--;
+}
+
+Failed to generate: error: cannot modify value of type 'u32'
diff --git a/test/tint/statements/decrement/storage.wgsl.expected.msl b/test/tint/statements/decrement/storage.wgsl.expected.msl
new file mode 100644
index 0000000..bd9b5d5
--- /dev/null
+++ b/test/tint/statements/decrement/storage.wgsl.expected.msl
@@ -0,0 +1,10 @@
+SKIP: FAILED
+
+
+@group(0) @binding(0) var<storage, read_write> i : u32;
+
+fn tint_symbol() {
+  i--;
+}
+
+Failed to generate: error: unknown statement type: tint::ast::IncrementDecrementStatement
diff --git a/test/tint/statements/decrement/storage.wgsl.expected.spvasm b/test/tint/statements/decrement/storage.wgsl.expected.spvasm
new file mode 100644
index 0000000..133d3f3
--- /dev/null
+++ b/test/tint/statements/decrement/storage.wgsl.expected.spvasm
@@ -0,0 +1,10 @@
+SKIP: FAILED
+
+
+@group(0) @binding(0) var<storage, read_write> i : u32;
+
+fn main() {
+  i--;
+}
+
+Failed to generate: Unknown statement: tint::ast::IncrementDecrementStatement
diff --git a/test/tint/statements/decrement/storage.wgsl.expected.wgsl b/test/tint/statements/decrement/storage.wgsl.expected.wgsl
new file mode 100644
index 0000000..fd5d013
--- /dev/null
+++ b/test/tint/statements/decrement/storage.wgsl.expected.wgsl
@@ -0,0 +1,5 @@
+@group(0) @binding(0) var<storage, read_write> i : u32;
+
+fn main() {
+  i--;
+}
diff --git a/test/tint/statements/decrement/vector_component.wgsl b/test/tint/statements/decrement/vector_component.wgsl
new file mode 100644
index 0000000..be48896
--- /dev/null
+++ b/test/tint/statements/decrement/vector_component.wgsl
@@ -0,0 +1,6 @@
+@group(0) @binding(0) var<storage, read_write> a : vec4<u32>;
+
+fn main() {
+  a[1]--;
+  a.z--;
+}
diff --git a/test/tint/statements/decrement/vector_component.wgsl.expected.glsl b/test/tint/statements/decrement/vector_component.wgsl.expected.glsl
new file mode 100644
index 0000000..f6d1854
--- /dev/null
+++ b/test/tint/statements/decrement/vector_component.wgsl.expected.glsl
@@ -0,0 +1,11 @@
+SKIP: FAILED
+
+
+@group(0) @binding(0) var<storage, read_write> a : vec4<u32>;
+
+fn main() {
+  a[1]--;
+  a.z--;
+}
+
+Failed to generate: error: unknown statement type: tint::ast::IncrementDecrementStatement
diff --git a/test/tint/statements/decrement/vector_component.wgsl.expected.hlsl b/test/tint/statements/decrement/vector_component.wgsl.expected.hlsl
new file mode 100644
index 0000000..60ca93b
--- /dev/null
+++ b/test/tint/statements/decrement/vector_component.wgsl.expected.hlsl
@@ -0,0 +1,11 @@
+SKIP: FAILED
+
+
+@group(0) @binding(0) var<storage, read_write> a : vec4<u32>;
+
+fn main() {
+  a[1]--;
+  a.z--;
+}
+
+Failed to generate: error: cannot modify value of type 'u32'
diff --git a/test/tint/statements/decrement/vector_component.wgsl.expected.msl b/test/tint/statements/decrement/vector_component.wgsl.expected.msl
new file mode 100644
index 0000000..4556d7b
--- /dev/null
+++ b/test/tint/statements/decrement/vector_component.wgsl.expected.msl
@@ -0,0 +1,11 @@
+SKIP: FAILED
+
+
+@group(0) @binding(0) var<storage, read_write> a : vec4<u32>;
+
+fn tint_symbol() {
+  a[1]--;
+  a.z--;
+}
+
+Failed to generate: error: unknown statement type: tint::ast::IncrementDecrementStatement
diff --git a/test/tint/statements/decrement/vector_component.wgsl.expected.spvasm b/test/tint/statements/decrement/vector_component.wgsl.expected.spvasm
new file mode 100644
index 0000000..1334066
--- /dev/null
+++ b/test/tint/statements/decrement/vector_component.wgsl.expected.spvasm
@@ -0,0 +1,11 @@
+SKIP: FAILED
+
+
+@group(0) @binding(0) var<storage, read_write> a : vec4<u32>;
+
+fn main() {
+  a[1]--;
+  a.z--;
+}
+
+Failed to generate: Unknown statement: tint::ast::IncrementDecrementStatement
diff --git a/test/tint/statements/decrement/vector_component.wgsl.expected.wgsl b/test/tint/statements/decrement/vector_component.wgsl.expected.wgsl
new file mode 100644
index 0000000..be48896
--- /dev/null
+++ b/test/tint/statements/decrement/vector_component.wgsl.expected.wgsl
@@ -0,0 +1,6 @@
+@group(0) @binding(0) var<storage, read_write> a : vec4<u32>;
+
+fn main() {
+  a[1]--;
+  a.z--;
+}
diff --git a/test/tint/statements/decrement/workgroup.wgsl b/test/tint/statements/decrement/workgroup.wgsl
new file mode 100644
index 0000000..bf0a50b
--- /dev/null
+++ b/test/tint/statements/decrement/workgroup.wgsl
@@ -0,0 +1,5 @@
+var<workgroup> i : i32;
+
+fn main() {
+  i--;
+}
diff --git a/test/tint/statements/decrement/workgroup.wgsl.expected.glsl b/test/tint/statements/decrement/workgroup.wgsl.expected.glsl
new file mode 100644
index 0000000..e3d1fac
--- /dev/null
+++ b/test/tint/statements/decrement/workgroup.wgsl.expected.glsl
@@ -0,0 +1,10 @@
+SKIP: FAILED
+
+
+var<workgroup> i : i32;
+
+fn main() {
+  i--;
+}
+
+Failed to generate: error: unknown statement type: tint::ast::IncrementDecrementStatement
diff --git a/test/tint/statements/decrement/workgroup.wgsl.expected.hlsl b/test/tint/statements/decrement/workgroup.wgsl.expected.hlsl
new file mode 100644
index 0000000..e3d1fac
--- /dev/null
+++ b/test/tint/statements/decrement/workgroup.wgsl.expected.hlsl
@@ -0,0 +1,10 @@
+SKIP: FAILED
+
+
+var<workgroup> i : i32;
+
+fn main() {
+  i--;
+}
+
+Failed to generate: error: unknown statement type: tint::ast::IncrementDecrementStatement
diff --git a/test/tint/statements/decrement/workgroup.wgsl.expected.msl b/test/tint/statements/decrement/workgroup.wgsl.expected.msl
new file mode 100644
index 0000000..66b73b1
--- /dev/null
+++ b/test/tint/statements/decrement/workgroup.wgsl.expected.msl
@@ -0,0 +1,10 @@
+SKIP: FAILED
+
+
+var<workgroup> i : i32;
+
+fn tint_symbol() {
+  i--;
+}
+
+Failed to generate: error: unknown statement type: tint::ast::IncrementDecrementStatement
diff --git a/test/tint/statements/decrement/workgroup.wgsl.expected.spvasm b/test/tint/statements/decrement/workgroup.wgsl.expected.spvasm
new file mode 100644
index 0000000..b6136ad
--- /dev/null
+++ b/test/tint/statements/decrement/workgroup.wgsl.expected.spvasm
@@ -0,0 +1,10 @@
+SKIP: FAILED
+
+
+var<workgroup> i : i32;
+
+fn main() {
+  i--;
+}
+
+Failed to generate: Unknown statement: tint::ast::IncrementDecrementStatement
diff --git a/test/tint/statements/decrement/workgroup.wgsl.expected.wgsl b/test/tint/statements/decrement/workgroup.wgsl.expected.wgsl
new file mode 100644
index 0000000..bf0a50b
--- /dev/null
+++ b/test/tint/statements/decrement/workgroup.wgsl.expected.wgsl
@@ -0,0 +1,5 @@
+var<workgroup> i : i32;
+
+fn main() {
+  i--;
+}
diff --git a/test/tint/statements/increment/array_element.wgsl b/test/tint/statements/increment/array_element.wgsl
new file mode 100644
index 0000000..0b2f03a
--- /dev/null
+++ b/test/tint/statements/increment/array_element.wgsl
@@ -0,0 +1,5 @@
+@group(0) @binding(0) var<storage, read_write> a : array<u32>;
+
+fn main() {
+  a[1]++;
+}
diff --git a/test/tint/statements/increment/array_element.wgsl.expected.glsl b/test/tint/statements/increment/array_element.wgsl.expected.glsl
new file mode 100644
index 0000000..5b3648a
--- /dev/null
+++ b/test/tint/statements/increment/array_element.wgsl.expected.glsl
@@ -0,0 +1,10 @@
+SKIP: FAILED
+
+
+@group(0) @binding(0) var<storage, read_write> a : array<u32>;
+
+fn main() {
+  a[1]++;
+}
+
+Failed to generate: error: unknown statement type: tint::ast::IncrementDecrementStatement
diff --git a/test/tint/statements/increment/array_element.wgsl.expected.hlsl b/test/tint/statements/increment/array_element.wgsl.expected.hlsl
new file mode 100644
index 0000000..0061781
--- /dev/null
+++ b/test/tint/statements/increment/array_element.wgsl.expected.hlsl
@@ -0,0 +1,10 @@
+SKIP: FAILED
+
+
+@group(0) @binding(0) var<storage, read_write> a : array<u32>;
+
+fn main() {
+  a[1]++;
+}
+
+Failed to generate: error: cannot modify value of type 'u32'
diff --git a/test/tint/statements/increment/array_element.wgsl.expected.msl b/test/tint/statements/increment/array_element.wgsl.expected.msl
new file mode 100644
index 0000000..d996613
--- /dev/null
+++ b/test/tint/statements/increment/array_element.wgsl.expected.msl
@@ -0,0 +1,10 @@
+SKIP: FAILED
+
+
+@group(0) @binding(0) var<storage, read_write> a : array<u32>;
+
+fn tint_symbol() {
+  a[1]++;
+}
+
+Failed to generate: error: unknown statement type: tint::ast::IncrementDecrementStatement
diff --git a/test/tint/statements/increment/array_element.wgsl.expected.spvasm b/test/tint/statements/increment/array_element.wgsl.expected.spvasm
new file mode 100644
index 0000000..250f739
--- /dev/null
+++ b/test/tint/statements/increment/array_element.wgsl.expected.spvasm
@@ -0,0 +1,10 @@
+SKIP: FAILED
+
+
+@group(0) @binding(0) var<storage, read_write> a : array<u32>;
+
+fn main() {
+  a[1]++;
+}
+
+Failed to generate: Unknown statement: tint::ast::IncrementDecrementStatement
diff --git a/test/tint/statements/increment/array_element.wgsl.expected.wgsl b/test/tint/statements/increment/array_element.wgsl.expected.wgsl
new file mode 100644
index 0000000..0b2f03a
--- /dev/null
+++ b/test/tint/statements/increment/array_element.wgsl.expected.wgsl
@@ -0,0 +1,5 @@
+@group(0) @binding(0) var<storage, read_write> a : array<u32>;
+
+fn main() {
+  a[1]++;
+}
diff --git a/test/tint/statements/increment/complex.wgsl b/test/tint/statements/increment/complex.wgsl
new file mode 100644
index 0000000..5c30aab
--- /dev/null
+++ b/test/tint/statements/increment/complex.wgsl
@@ -0,0 +1,44 @@
+struct S {
+  a : array<vec4<i32>, 4>
+}
+
+@group(0) @binding(0) var<storage, read_write>  buffer : array<S>;
+
+var<private> v : u32;
+
+fn idx1() -> i32 {
+  v++;
+  return 1;
+}
+
+fn idx2() -> i32 {
+  v++;
+  return 2;
+}
+
+fn idx3() -> i32 {
+  v++;
+  return 3;
+}
+
+fn idx4() -> i32 {
+  v++;
+  return 4;
+}
+
+fn idx5() -> i32 {
+  v++;
+  return 0;
+}
+
+fn idx6() -> i32 {
+  v++;
+  return 2;
+}
+
+fn main() {
+  for (buffer[idx1()].a[idx2()][idx3()]++;
+       v < 10u;
+       buffer[idx4()].a[idx5()][idx6()]++) {
+  }
+}
diff --git a/test/tint/statements/increment/complex.wgsl.expected.glsl b/test/tint/statements/increment/complex.wgsl.expected.glsl
new file mode 100644
index 0000000..f667cca
--- /dev/null
+++ b/test/tint/statements/increment/complex.wgsl.expected.glsl
@@ -0,0 +1,47 @@
+SKIP: FAILED
+
+
+struct S {
+  a : array<vec4<i32>, 4>,
+}
+
+@group(0) @binding(0) var<storage, read_write> buffer : array<S>;
+
+var<private> v : u32;
+
+fn idx1() -> i32 {
+  v++;
+  return 1;
+}
+
+fn idx2() -> i32 {
+  v++;
+  return 2;
+}
+
+fn idx3() -> i32 {
+  v++;
+  return 3;
+}
+
+fn idx4() -> i32 {
+  v++;
+  return 4;
+}
+
+fn idx5() -> i32 {
+  v++;
+  return 0;
+}
+
+fn idx6() -> i32 {
+  v++;
+  return 2;
+}
+
+fn main() {
+  for(buffer[idx1()].a[idx2()][idx3()]++; (v < 10u); buffer[idx4()].a[idx5()][idx6()]++) {
+  }
+}
+
+Failed to generate: error: unknown statement type: tint::ast::IncrementDecrementStatement
diff --git a/test/tint/statements/increment/complex.wgsl.expected.hlsl b/test/tint/statements/increment/complex.wgsl.expected.hlsl
new file mode 100644
index 0000000..bb3ce44
--- /dev/null
+++ b/test/tint/statements/increment/complex.wgsl.expected.hlsl
@@ -0,0 +1,47 @@
+SKIP: FAILED
+
+
+struct S {
+  a : array<vec4<i32>, 4>,
+}
+
+@group(0) @binding(0) var<storage, read_write> buffer : array<S>;
+
+var<private> v : u32;
+
+fn idx1() -> i32 {
+  v++;
+  return 1;
+}
+
+fn idx2() -> i32 {
+  v++;
+  return 2;
+}
+
+fn idx3() -> i32 {
+  v++;
+  return 3;
+}
+
+fn idx4() -> i32 {
+  v++;
+  return 4;
+}
+
+fn idx5() -> i32 {
+  v++;
+  return 0;
+}
+
+fn idx6() -> i32 {
+  v++;
+  return 2;
+}
+
+fn main() {
+  for(buffer[idx1()].a[idx2()][idx3()]++; (v < 10u); buffer[idx4()].a[idx5()][idx6()]++) {
+  }
+}
+
+Failed to generate: error: cannot modify value of type 'i32'
diff --git a/test/tint/statements/increment/complex.wgsl.expected.msl b/test/tint/statements/increment/complex.wgsl.expected.msl
new file mode 100644
index 0000000..45f0182
--- /dev/null
+++ b/test/tint/statements/increment/complex.wgsl.expected.msl
@@ -0,0 +1,47 @@
+SKIP: FAILED
+
+
+struct S {
+  a : array<vec4<i32>, 4>,
+}
+
+@group(0) @binding(0) var<storage, read_write> tint_symbol : array<S>;
+
+var<private> v : u32;
+
+fn idx1() -> i32 {
+  v++;
+  return 1;
+}
+
+fn idx2() -> i32 {
+  v++;
+  return 2;
+}
+
+fn idx3() -> i32 {
+  v++;
+  return 3;
+}
+
+fn idx4() -> i32 {
+  v++;
+  return 4;
+}
+
+fn idx5() -> i32 {
+  v++;
+  return 0;
+}
+
+fn idx6() -> i32 {
+  v++;
+  return 2;
+}
+
+fn tint_symbol_1() {
+  for(tint_symbol[idx1()].a[idx2()][idx3()]++; (v < 10u); tint_symbol[idx4()].a[idx5()][idx6()]++) {
+  }
+}
+
+Failed to generate: error: unknown statement type: tint::ast::IncrementDecrementStatement
diff --git a/test/tint/statements/increment/complex.wgsl.expected.spvasm b/test/tint/statements/increment/complex.wgsl.expected.spvasm
new file mode 100644
index 0000000..4f6b6c6
--- /dev/null
+++ b/test/tint/statements/increment/complex.wgsl.expected.spvasm
@@ -0,0 +1,47 @@
+SKIP: FAILED
+
+
+struct S {
+  a : array<vec4<i32>, 4>,
+}
+
+@group(0) @binding(0) var<storage, read_write> buffer : array<S>;
+
+var<private> v : u32;
+
+fn idx1() -> i32 {
+  v++;
+  return 1;
+}
+
+fn idx2() -> i32 {
+  v++;
+  return 2;
+}
+
+fn idx3() -> i32 {
+  v++;
+  return 3;
+}
+
+fn idx4() -> i32 {
+  v++;
+  return 4;
+}
+
+fn idx5() -> i32 {
+  v++;
+  return 0;
+}
+
+fn idx6() -> i32 {
+  v++;
+  return 2;
+}
+
+fn main() {
+  for(buffer[idx1()].a[idx2()][idx3()]++; (v < 10u); buffer[idx4()].a[idx5()][idx6()]++) {
+  }
+}
+
+Failed to generate: Unknown statement: tint::ast::IncrementDecrementStatement
diff --git a/test/tint/statements/increment/complex.wgsl.expected.wgsl b/test/tint/statements/increment/complex.wgsl.expected.wgsl
new file mode 100644
index 0000000..833a2bb
--- /dev/null
+++ b/test/tint/statements/increment/complex.wgsl.expected.wgsl
@@ -0,0 +1,42 @@
+struct S {
+  a : array<vec4<i32>, 4>,
+}
+
+@group(0) @binding(0) var<storage, read_write> buffer : array<S>;
+
+var<private> v : u32;
+
+fn idx1() -> i32 {
+  v++;
+  return 1;
+}
+
+fn idx2() -> i32 {
+  v++;
+  return 2;
+}
+
+fn idx3() -> i32 {
+  v++;
+  return 3;
+}
+
+fn idx4() -> i32 {
+  v++;
+  return 4;
+}
+
+fn idx5() -> i32 {
+  v++;
+  return 0;
+}
+
+fn idx6() -> i32 {
+  v++;
+  return 2;
+}
+
+fn main() {
+  for(buffer[idx1()].a[idx2()][idx3()]++; (v < 10u); buffer[idx4()].a[idx5()][idx6()]++) {
+  }
+}
diff --git a/test/tint/statements/increment/for_loop_continuing.wgsl b/test/tint/statements/increment/for_loop_continuing.wgsl
new file mode 100644
index 0000000..f84d3c7
--- /dev/null
+++ b/test/tint/statements/increment/for_loop_continuing.wgsl
@@ -0,0 +1,6 @@
+@group(0) @binding(0) var<storage, read_write> i : u32;
+
+fn main() {
+  for (; i < 10u; i++) {
+  }
+}
diff --git a/test/tint/statements/increment/for_loop_continuing.wgsl.expected.glsl b/test/tint/statements/increment/for_loop_continuing.wgsl.expected.glsl
new file mode 100644
index 0000000..d039199
--- /dev/null
+++ b/test/tint/statements/increment/for_loop_continuing.wgsl.expected.glsl
@@ -0,0 +1,11 @@
+SKIP: FAILED
+
+
+@group(0) @binding(0) var<storage, read_write> i : u32;
+
+fn main() {
+  for(; (i < 10u); i++) {
+  }
+}
+
+Failed to generate: error: unknown statement type: tint::ast::IncrementDecrementStatement
diff --git a/test/tint/statements/increment/for_loop_continuing.wgsl.expected.hlsl b/test/tint/statements/increment/for_loop_continuing.wgsl.expected.hlsl
new file mode 100644
index 0000000..ed0f720
--- /dev/null
+++ b/test/tint/statements/increment/for_loop_continuing.wgsl.expected.hlsl
@@ -0,0 +1,11 @@
+SKIP: FAILED
+
+
+@group(0) @binding(0) var<storage, read_write> i : u32;
+
+fn main() {
+  for(; (i < 10u); i++) {
+  }
+}
+
+Failed to generate: error: cannot modify value of type 'u32'
diff --git a/test/tint/statements/increment/for_loop_continuing.wgsl.expected.msl b/test/tint/statements/increment/for_loop_continuing.wgsl.expected.msl
new file mode 100644
index 0000000..e32c199
--- /dev/null
+++ b/test/tint/statements/increment/for_loop_continuing.wgsl.expected.msl
@@ -0,0 +1,11 @@
+SKIP: FAILED
+
+
+@group(0) @binding(0) var<storage, read_write> i : u32;
+
+fn tint_symbol() {
+  for(; (i < 10u); i++) {
+  }
+}
+
+Failed to generate: error: unknown statement type: tint::ast::IncrementDecrementStatement
diff --git a/test/tint/statements/increment/for_loop_continuing.wgsl.expected.spvasm b/test/tint/statements/increment/for_loop_continuing.wgsl.expected.spvasm
new file mode 100644
index 0000000..b8e09e5
--- /dev/null
+++ b/test/tint/statements/increment/for_loop_continuing.wgsl.expected.spvasm
@@ -0,0 +1,11 @@
+SKIP: FAILED
+
+
+@group(0) @binding(0) var<storage, read_write> i : u32;
+
+fn main() {
+  for(; (i < 10u); i++) {
+  }
+}
+
+Failed to generate: Unknown statement: tint::ast::IncrementDecrementStatement
diff --git a/test/tint/statements/increment/for_loop_continuing.wgsl.expected.wgsl b/test/tint/statements/increment/for_loop_continuing.wgsl.expected.wgsl
new file mode 100644
index 0000000..96af6bf
--- /dev/null
+++ b/test/tint/statements/increment/for_loop_continuing.wgsl.expected.wgsl
@@ -0,0 +1,6 @@
+@group(0) @binding(0) var<storage, read_write> i : u32;
+
+fn main() {
+  for(; (i < 10u); i++) {
+  }
+}
diff --git a/test/tint/statements/increment/for_loop_initializer.wgsl b/test/tint/statements/increment/for_loop_initializer.wgsl
new file mode 100644
index 0000000..f8df15d
--- /dev/null
+++ b/test/tint/statements/increment/for_loop_initializer.wgsl
@@ -0,0 +1,6 @@
+@group(0) @binding(0) var<storage, read_write> i : u32;
+
+fn main() {
+  for (i++; i < 10u;) {
+  }
+}
diff --git a/test/tint/statements/increment/for_loop_initializer.wgsl.expected.glsl b/test/tint/statements/increment/for_loop_initializer.wgsl.expected.glsl
new file mode 100644
index 0000000..40f942a
--- /dev/null
+++ b/test/tint/statements/increment/for_loop_initializer.wgsl.expected.glsl
@@ -0,0 +1,11 @@
+SKIP: FAILED
+
+
+@group(0) @binding(0) var<storage, read_write> i : u32;
+
+fn main() {
+  for(i++; (i < 10u); ) {
+  }
+}
+
+Failed to generate: error: unknown statement type: tint::ast::IncrementDecrementStatement
diff --git a/test/tint/statements/increment/for_loop_initializer.wgsl.expected.hlsl b/test/tint/statements/increment/for_loop_initializer.wgsl.expected.hlsl
new file mode 100644
index 0000000..1fa9624
--- /dev/null
+++ b/test/tint/statements/increment/for_loop_initializer.wgsl.expected.hlsl
@@ -0,0 +1,11 @@
+SKIP: FAILED
+
+
+@group(0) @binding(0) var<storage, read_write> i : u32;
+
+fn main() {
+  for(i++; (i < 10u); ) {
+  }
+}
+
+Failed to generate: error: cannot modify value of type 'u32'
diff --git a/test/tint/statements/increment/for_loop_initializer.wgsl.expected.msl b/test/tint/statements/increment/for_loop_initializer.wgsl.expected.msl
new file mode 100644
index 0000000..a780f32
--- /dev/null
+++ b/test/tint/statements/increment/for_loop_initializer.wgsl.expected.msl
@@ -0,0 +1,11 @@
+SKIP: FAILED
+
+
+@group(0) @binding(0) var<storage, read_write> i : u32;
+
+fn tint_symbol() {
+  for(i++; (i < 10u); ) {
+  }
+}
+
+Failed to generate: error: unknown statement type: tint::ast::IncrementDecrementStatement
diff --git a/test/tint/statements/increment/for_loop_initializer.wgsl.expected.spvasm b/test/tint/statements/increment/for_loop_initializer.wgsl.expected.spvasm
new file mode 100644
index 0000000..a9235f9
--- /dev/null
+++ b/test/tint/statements/increment/for_loop_initializer.wgsl.expected.spvasm
@@ -0,0 +1,11 @@
+SKIP: FAILED
+
+
+@group(0) @binding(0) var<storage, read_write> i : u32;
+
+fn main() {
+  for(i++; (i < 10u); ) {
+  }
+}
+
+Failed to generate: Unknown statement: tint::ast::IncrementDecrementStatement
diff --git a/test/tint/statements/increment/for_loop_initializer.wgsl.expected.wgsl b/test/tint/statements/increment/for_loop_initializer.wgsl.expected.wgsl
new file mode 100644
index 0000000..5cb2185
--- /dev/null
+++ b/test/tint/statements/increment/for_loop_initializer.wgsl.expected.wgsl
@@ -0,0 +1,6 @@
+@group(0) @binding(0) var<storage, read_write> i : u32;
+
+fn main() {
+  for(i++; (i < 10u); ) {
+  }
+}
diff --git a/test/tint/statements/increment/function.wgsl b/test/tint/statements/increment/function.wgsl
new file mode 100644
index 0000000..9c1589e
--- /dev/null
+++ b/test/tint/statements/increment/function.wgsl
@@ -0,0 +1,4 @@
+fn main() {
+  var i = 0;
+  i++;
+}
diff --git a/test/tint/statements/increment/function.wgsl.expected.glsl b/test/tint/statements/increment/function.wgsl.expected.glsl
new file mode 100644
index 0000000..141a0e7
--- /dev/null
+++ b/test/tint/statements/increment/function.wgsl.expected.glsl
@@ -0,0 +1,9 @@
+SKIP: FAILED
+
+
+fn main() {
+  var i = 0;
+  i++;
+}
+
+Failed to generate: error: unknown statement type: tint::ast::IncrementDecrementStatement
diff --git a/test/tint/statements/increment/function.wgsl.expected.hlsl b/test/tint/statements/increment/function.wgsl.expected.hlsl
new file mode 100644
index 0000000..141a0e7
--- /dev/null
+++ b/test/tint/statements/increment/function.wgsl.expected.hlsl
@@ -0,0 +1,9 @@
+SKIP: FAILED
+
+
+fn main() {
+  var i = 0;
+  i++;
+}
+
+Failed to generate: error: unknown statement type: tint::ast::IncrementDecrementStatement
diff --git a/test/tint/statements/increment/function.wgsl.expected.msl b/test/tint/statements/increment/function.wgsl.expected.msl
new file mode 100644
index 0000000..4c16d00
--- /dev/null
+++ b/test/tint/statements/increment/function.wgsl.expected.msl
@@ -0,0 +1,9 @@
+SKIP: FAILED
+
+
+fn tint_symbol() {
+  var i = 0;
+  i++;
+}
+
+Failed to generate: error: unknown statement type: tint::ast::IncrementDecrementStatement
diff --git a/test/tint/statements/increment/function.wgsl.expected.spvasm b/test/tint/statements/increment/function.wgsl.expected.spvasm
new file mode 100644
index 0000000..d48fc47
--- /dev/null
+++ b/test/tint/statements/increment/function.wgsl.expected.spvasm
@@ -0,0 +1,9 @@
+SKIP: FAILED
+
+
+fn main() {
+  var i = 0;
+  i++;
+}
+
+Failed to generate: Unknown statement: tint::ast::IncrementDecrementStatement
diff --git a/test/tint/statements/increment/function.wgsl.expected.wgsl b/test/tint/statements/increment/function.wgsl.expected.wgsl
new file mode 100644
index 0000000..9c1589e
--- /dev/null
+++ b/test/tint/statements/increment/function.wgsl.expected.wgsl
@@ -0,0 +1,4 @@
+fn main() {
+  var i = 0;
+  i++;
+}
diff --git a/test/tint/statements/increment/private.wgsl b/test/tint/statements/increment/private.wgsl
new file mode 100644
index 0000000..e06e713
--- /dev/null
+++ b/test/tint/statements/increment/private.wgsl
@@ -0,0 +1,5 @@
+var<private> i : i32 = 0;
+
+fn main() {
+  i++;
+}
diff --git a/test/tint/statements/increment/private.wgsl.expected.glsl b/test/tint/statements/increment/private.wgsl.expected.glsl
new file mode 100644
index 0000000..4975321
--- /dev/null
+++ b/test/tint/statements/increment/private.wgsl.expected.glsl
@@ -0,0 +1,10 @@
+SKIP: FAILED
+
+
+var<private> i : i32 = 0;
+
+fn main() {
+  i++;
+}
+
+Failed to generate: error: unknown statement type: tint::ast::IncrementDecrementStatement
diff --git a/test/tint/statements/increment/private.wgsl.expected.hlsl b/test/tint/statements/increment/private.wgsl.expected.hlsl
new file mode 100644
index 0000000..4975321
--- /dev/null
+++ b/test/tint/statements/increment/private.wgsl.expected.hlsl
@@ -0,0 +1,10 @@
+SKIP: FAILED
+
+
+var<private> i : i32 = 0;
+
+fn main() {
+  i++;
+}
+
+Failed to generate: error: unknown statement type: tint::ast::IncrementDecrementStatement
diff --git a/test/tint/statements/increment/private.wgsl.expected.msl b/test/tint/statements/increment/private.wgsl.expected.msl
new file mode 100644
index 0000000..abefe62
--- /dev/null
+++ b/test/tint/statements/increment/private.wgsl.expected.msl
@@ -0,0 +1,10 @@
+SKIP: FAILED
+
+
+var<private> i : i32 = 0;
+
+fn tint_symbol() {
+  i++;
+}
+
+Failed to generate: error: unknown statement type: tint::ast::IncrementDecrementStatement
diff --git a/test/tint/statements/increment/private.wgsl.expected.spvasm b/test/tint/statements/increment/private.wgsl.expected.spvasm
new file mode 100644
index 0000000..cc7f59a
--- /dev/null
+++ b/test/tint/statements/increment/private.wgsl.expected.spvasm
@@ -0,0 +1,10 @@
+SKIP: FAILED
+
+
+var<private> i : i32 = 0;
+
+fn main() {
+  i++;
+}
+
+Failed to generate: Unknown statement: tint::ast::IncrementDecrementStatement
diff --git a/test/tint/statements/increment/private.wgsl.expected.wgsl b/test/tint/statements/increment/private.wgsl.expected.wgsl
new file mode 100644
index 0000000..e06e713
--- /dev/null
+++ b/test/tint/statements/increment/private.wgsl.expected.wgsl
@@ -0,0 +1,5 @@
+var<private> i : i32 = 0;
+
+fn main() {
+  i++;
+}
diff --git a/test/tint/statements/increment/storage.wgsl b/test/tint/statements/increment/storage.wgsl
new file mode 100644
index 0000000..81007bc
--- /dev/null
+++ b/test/tint/statements/increment/storage.wgsl
@@ -0,0 +1,5 @@
+@group(0) @binding(0) var<storage, read_write> i : u32;
+
+fn main() {
+  i++;
+}
diff --git a/test/tint/statements/increment/storage.wgsl.expected.glsl b/test/tint/statements/increment/storage.wgsl.expected.glsl
new file mode 100644
index 0000000..fe12521
--- /dev/null
+++ b/test/tint/statements/increment/storage.wgsl.expected.glsl
@@ -0,0 +1,10 @@
+SKIP: FAILED
+
+
+@group(0) @binding(0) var<storage, read_write> i : u32;
+
+fn main() {
+  i++;
+}
+
+Failed to generate: error: unknown statement type: tint::ast::IncrementDecrementStatement
diff --git a/test/tint/statements/increment/storage.wgsl.expected.hlsl b/test/tint/statements/increment/storage.wgsl.expected.hlsl
new file mode 100644
index 0000000..7e72d16
--- /dev/null
+++ b/test/tint/statements/increment/storage.wgsl.expected.hlsl
@@ -0,0 +1,10 @@
+SKIP: FAILED
+
+
+@group(0) @binding(0) var<storage, read_write> i : u32;
+
+fn main() {
+  i++;
+}
+
+Failed to generate: error: cannot modify value of type 'u32'
diff --git a/test/tint/statements/increment/storage.wgsl.expected.msl b/test/tint/statements/increment/storage.wgsl.expected.msl
new file mode 100644
index 0000000..1807065
--- /dev/null
+++ b/test/tint/statements/increment/storage.wgsl.expected.msl
@@ -0,0 +1,10 @@
+SKIP: FAILED
+
+
+@group(0) @binding(0) var<storage, read_write> i : u32;
+
+fn tint_symbol() {
+  i++;
+}
+
+Failed to generate: error: unknown statement type: tint::ast::IncrementDecrementStatement
diff --git a/test/tint/statements/increment/storage.wgsl.expected.spvasm b/test/tint/statements/increment/storage.wgsl.expected.spvasm
new file mode 100644
index 0000000..a5dc087
--- /dev/null
+++ b/test/tint/statements/increment/storage.wgsl.expected.spvasm
@@ -0,0 +1,10 @@
+SKIP: FAILED
+
+
+@group(0) @binding(0) var<storage, read_write> i : u32;
+
+fn main() {
+  i++;
+}
+
+Failed to generate: Unknown statement: tint::ast::IncrementDecrementStatement
diff --git a/test/tint/statements/increment/storage.wgsl.expected.wgsl b/test/tint/statements/increment/storage.wgsl.expected.wgsl
new file mode 100644
index 0000000..81007bc
--- /dev/null
+++ b/test/tint/statements/increment/storage.wgsl.expected.wgsl
@@ -0,0 +1,5 @@
+@group(0) @binding(0) var<storage, read_write> i : u32;
+
+fn main() {
+  i++;
+}
diff --git a/test/tint/statements/increment/vector_component.wgsl b/test/tint/statements/increment/vector_component.wgsl
new file mode 100644
index 0000000..d03ca7d
--- /dev/null
+++ b/test/tint/statements/increment/vector_component.wgsl
@@ -0,0 +1,6 @@
+@group(0) @binding(0) var<storage, read_write> a : vec4<u32>;
+
+fn main() {
+  a[1]++;
+  a.z++;
+}
diff --git a/test/tint/statements/increment/vector_component.wgsl.expected.glsl b/test/tint/statements/increment/vector_component.wgsl.expected.glsl
new file mode 100644
index 0000000..3a8c651
--- /dev/null
+++ b/test/tint/statements/increment/vector_component.wgsl.expected.glsl
@@ -0,0 +1,11 @@
+SKIP: FAILED
+
+
+@group(0) @binding(0) var<storage, read_write> a : vec4<u32>;
+
+fn main() {
+  a[1]++;
+  a.z++;
+}
+
+Failed to generate: error: unknown statement type: tint::ast::IncrementDecrementStatement
diff --git a/test/tint/statements/increment/vector_component.wgsl.expected.hlsl b/test/tint/statements/increment/vector_component.wgsl.expected.hlsl
new file mode 100644
index 0000000..67ce149
--- /dev/null
+++ b/test/tint/statements/increment/vector_component.wgsl.expected.hlsl
@@ -0,0 +1,11 @@
+SKIP: FAILED
+
+
+@group(0) @binding(0) var<storage, read_write> a : vec4<u32>;
+
+fn main() {
+  a[1]++;
+  a.z++;
+}
+
+Failed to generate: error: cannot modify value of type 'u32'
diff --git a/test/tint/statements/increment/vector_component.wgsl.expected.msl b/test/tint/statements/increment/vector_component.wgsl.expected.msl
new file mode 100644
index 0000000..ec37cab
--- /dev/null
+++ b/test/tint/statements/increment/vector_component.wgsl.expected.msl
@@ -0,0 +1,11 @@
+SKIP: FAILED
+
+
+@group(0) @binding(0) var<storage, read_write> a : vec4<u32>;
+
+fn tint_symbol() {
+  a[1]++;
+  a.z++;
+}
+
+Failed to generate: error: unknown statement type: tint::ast::IncrementDecrementStatement
diff --git a/test/tint/statements/increment/vector_component.wgsl.expected.spvasm b/test/tint/statements/increment/vector_component.wgsl.expected.spvasm
new file mode 100644
index 0000000..67a7efc
--- /dev/null
+++ b/test/tint/statements/increment/vector_component.wgsl.expected.spvasm
@@ -0,0 +1,11 @@
+SKIP: FAILED
+
+
+@group(0) @binding(0) var<storage, read_write> a : vec4<u32>;
+
+fn main() {
+  a[1]++;
+  a.z++;
+}
+
+Failed to generate: Unknown statement: tint::ast::IncrementDecrementStatement
diff --git a/test/tint/statements/increment/vector_component.wgsl.expected.wgsl b/test/tint/statements/increment/vector_component.wgsl.expected.wgsl
new file mode 100644
index 0000000..d03ca7d
--- /dev/null
+++ b/test/tint/statements/increment/vector_component.wgsl.expected.wgsl
@@ -0,0 +1,6 @@
+@group(0) @binding(0) var<storage, read_write> a : vec4<u32>;
+
+fn main() {
+  a[1]++;
+  a.z++;
+}
diff --git a/test/tint/statements/increment/workgroup.wgsl b/test/tint/statements/increment/workgroup.wgsl
new file mode 100644
index 0000000..0b4752f
--- /dev/null
+++ b/test/tint/statements/increment/workgroup.wgsl
@@ -0,0 +1,5 @@
+var<workgroup> i : i32;
+
+fn main() {
+  i++;
+}
diff --git a/test/tint/statements/increment/workgroup.wgsl.expected.glsl b/test/tint/statements/increment/workgroup.wgsl.expected.glsl
new file mode 100644
index 0000000..8bf31af
--- /dev/null
+++ b/test/tint/statements/increment/workgroup.wgsl.expected.glsl
@@ -0,0 +1,10 @@
+SKIP: FAILED
+
+
+var<workgroup> i : i32;
+
+fn main() {
+  i++;
+}
+
+Failed to generate: error: unknown statement type: tint::ast::IncrementDecrementStatement
diff --git a/test/tint/statements/increment/workgroup.wgsl.expected.hlsl b/test/tint/statements/increment/workgroup.wgsl.expected.hlsl
new file mode 100644
index 0000000..8bf31af
--- /dev/null
+++ b/test/tint/statements/increment/workgroup.wgsl.expected.hlsl
@@ -0,0 +1,10 @@
+SKIP: FAILED
+
+
+var<workgroup> i : i32;
+
+fn main() {
+  i++;
+}
+
+Failed to generate: error: unknown statement type: tint::ast::IncrementDecrementStatement
diff --git a/test/tint/statements/increment/workgroup.wgsl.expected.msl b/test/tint/statements/increment/workgroup.wgsl.expected.msl
new file mode 100644
index 0000000..a1f382d
--- /dev/null
+++ b/test/tint/statements/increment/workgroup.wgsl.expected.msl
@@ -0,0 +1,10 @@
+SKIP: FAILED
+
+
+var<workgroup> i : i32;
+
+fn tint_symbol() {
+  i++;
+}
+
+Failed to generate: error: unknown statement type: tint::ast::IncrementDecrementStatement
diff --git a/test/tint/statements/increment/workgroup.wgsl.expected.spvasm b/test/tint/statements/increment/workgroup.wgsl.expected.spvasm
new file mode 100644
index 0000000..4cdda46
--- /dev/null
+++ b/test/tint/statements/increment/workgroup.wgsl.expected.spvasm
@@ -0,0 +1,10 @@
+SKIP: FAILED
+
+
+var<workgroup> i : i32;
+
+fn main() {
+  i++;
+}
+
+Failed to generate: Unknown statement: tint::ast::IncrementDecrementStatement
diff --git a/test/tint/statements/increment/workgroup.wgsl.expected.wgsl b/test/tint/statements/increment/workgroup.wgsl.expected.wgsl
new file mode 100644
index 0000000..0b4752f
--- /dev/null
+++ b/test/tint/statements/increment/workgroup.wgsl.expected.wgsl
@@ -0,0 +1,5 @@
+var<workgroup> i : i32;
+
+fn main() {
+  i++;
+}