Remove NOP.

The NOP command was added for complete SPIR-V bijectivity which is no
longer a goal of WGSL. The NOP command has been removed from the spec,
so remove from Tint.

Change-Id: Ic640d9d3b987a19668dc169ff549444921c5bbb8
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/22160
Reviewed-by: Ryan Harrison <rharrison@chromium.org>
diff --git a/BUILD.gn b/BUILD.gn
index 7764afc..93bc286 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -266,8 +266,6 @@
     "src/ast/module.h",
     "src/ast/node.cc",
     "src/ast/node.h",
-    "src/ast/nop_statement.cc",
-    "src/ast/nop_statement.h",
     "src/ast/null_literal.cc",
     "src/ast/null_literal.h",
     "src/ast/pipeline_stage.cc",
@@ -605,7 +603,6 @@
     "src/ast/loop_statement_test.cc",
     "src/ast/member_accessor_expression_test.cc",
     "src/ast/module_test.cc",
-    "src/ast/nop_statement_test.cc",
     "src/ast/null_literal_test.cc",
     "src/ast/return_statement_test.cc",
     "src/ast/scalar_constructor_expression_test.cc",
@@ -829,7 +826,6 @@
     "src/writer/wgsl/generator_impl_kill_test.cc",
     "src/writer/wgsl/generator_impl_loop_test.cc",
     "src/writer/wgsl/generator_impl_member_accessor_test.cc",
-    "src/writer/wgsl/generator_impl_nop_test.cc",
     "src/writer/wgsl/generator_impl_relational_test.cc",
     "src/writer/wgsl/generator_impl_return_test.cc",
     "src/writer/wgsl/generator_impl_switch_test.cc",
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index c07fdd9..a1637eb 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -103,8 +103,6 @@
   ast/module.h
   ast/node.cc
   ast/node.h
-  ast/nop_statement.cc
-  ast/nop_statement.h
   ast/null_literal.cc
   ast/null_literal.h
   ast/pipeline_stage.cc
@@ -284,7 +282,6 @@
   ast/loop_statement_test.cc
   ast/member_accessor_expression_test.cc
   ast/module_test.cc
-  ast/nop_statement_test.cc
   ast/null_literal_test.cc
   ast/binary_expression_test.cc
   ast/return_statement_test.cc
@@ -478,7 +475,6 @@
     writer/wgsl/generator_impl_kill_test.cc
     writer/wgsl/generator_impl_loop_test.cc
     writer/wgsl/generator_impl_member_accessor_test.cc
-    writer/wgsl/generator_impl_nop_test.cc
     writer/wgsl/generator_impl_relational_test.cc
     writer/wgsl/generator_impl_return_test.cc
     writer/wgsl/generator_impl_switch_test.cc
diff --git a/src/ast/case_statement_test.cc b/src/ast/case_statement_test.cc
index 8aad2ba..4e841ac 100644
--- a/src/ast/case_statement_test.cc
+++ b/src/ast/case_statement_test.cc
@@ -17,7 +17,7 @@
 #include "gtest/gtest.h"
 #include "src/ast/bool_literal.h"
 #include "src/ast/if_statement.h"
-#include "src/ast/nop_statement.h"
+#include "src/ast/kill_statement.h"
 #include "src/ast/type/bool_type.h"
 
 namespace tint {
@@ -30,22 +30,22 @@
   ast::type::BoolType bool_type;
   auto b = std::make_unique<BoolLiteral>(&bool_type, true);
   StatementList stmts;
-  stmts.push_back(std::make_unique<NopStatement>());
+  stmts.push_back(std::make_unique<KillStatement>());
 
   auto* bool_ptr = b.get();
-  auto* nop_ptr = stmts[0].get();
+  auto* kill_ptr = stmts[0].get();
 
   CaseStatement c(std::move(b), std::move(stmts));
   EXPECT_EQ(c.condition(), bool_ptr);
   ASSERT_EQ(c.body().size(), 1u);
-  EXPECT_EQ(c.body()[0].get(), nop_ptr);
+  EXPECT_EQ(c.body()[0].get(), kill_ptr);
 }
 
 TEST_F(CaseStatementTest, Creation_WithSource) {
   ast::type::BoolType bool_type;
   auto b = std::make_unique<BoolLiteral>(&bool_type, true);
   StatementList stmts;
-  stmts.push_back(std::make_unique<NopStatement>());
+  stmts.push_back(std::make_unique<KillStatement>());
 
   CaseStatement c(Source{20, 2}, std::move(b), std::move(stmts));
   auto src = c.source();
@@ -55,7 +55,7 @@
 
 TEST_F(CaseStatementTest, IsDefault_WithoutCondition) {
   StatementList stmts;
-  stmts.push_back(std::make_unique<NopStatement>());
+  stmts.push_back(std::make_unique<KillStatement>());
 
   CaseStatement c;
   c.set_body(std::move(stmts));
@@ -84,7 +84,7 @@
   ast::type::BoolType bool_type;
   auto b = std::make_unique<BoolLiteral>(&bool_type, true);
   StatementList stmts;
-  stmts.push_back(std::make_unique<NopStatement>());
+  stmts.push_back(std::make_unique<KillStatement>());
   stmts.push_back(nullptr);
 
   CaseStatement c(std::move(b), std::move(stmts));
@@ -105,26 +105,26 @@
   ast::type::BoolType bool_type;
   auto b = std::make_unique<BoolLiteral>(&bool_type, true);
   StatementList stmts;
-  stmts.push_back(std::make_unique<NopStatement>());
+  stmts.push_back(std::make_unique<KillStatement>());
   CaseStatement c(std::move(b), std::move(stmts));
 
   std::ostringstream out;
   c.to_str(out, 2);
   EXPECT_EQ(out.str(), R"(  Case true{
-    Nop{}
+    Kill{}
   }
 )");
 }
 
 TEST_F(CaseStatementTest, ToStr_WithoutCondition) {
   StatementList stmts;
-  stmts.push_back(std::make_unique<NopStatement>());
+  stmts.push_back(std::make_unique<KillStatement>());
   CaseStatement c(nullptr, std::move(stmts));
 
   std::ostringstream out;
   c.to_str(out, 2);
   EXPECT_EQ(out.str(), R"(  Default{
-    Nop{}
+    Kill{}
   }
 )");
 }
diff --git a/src/ast/else_statement_test.cc b/src/ast/else_statement_test.cc
index 07ee8ec..05d04cb 100644
--- a/src/ast/else_statement_test.cc
+++ b/src/ast/else_statement_test.cc
@@ -17,7 +17,7 @@
 #include "gtest/gtest.h"
 #include "src/ast/bool_literal.h"
 #include "src/ast/if_statement.h"
-#include "src/ast/nop_statement.h"
+#include "src/ast/kill_statement.h"
 #include "src/ast/scalar_constructor_expression.h"
 #include "src/ast/type/bool_type.h"
 
@@ -32,15 +32,15 @@
   auto cond = std::make_unique<ScalarConstructorExpression>(
       std::make_unique<BoolLiteral>(&bool_type, true));
   StatementList body;
-  body.push_back(std::make_unique<NopStatement>());
+  body.push_back(std::make_unique<KillStatement>());
 
   auto* cond_ptr = cond.get();
-  auto* nop_ptr = body[0].get();
+  auto* kill_ptr = body[0].get();
 
   ElseStatement e(std::move(cond), std::move(body));
   EXPECT_EQ(e.condition(), cond_ptr);
   ASSERT_EQ(e.body().size(), 1u);
-  EXPECT_EQ(e.body()[0].get(), nop_ptr);
+  EXPECT_EQ(e.body()[0].get(), kill_ptr);
 }
 
 TEST_F(ElseStatementTest, Creation_WithSource) {
@@ -75,7 +75,7 @@
 
 TEST_F(ElseStatementTest, IsValid_WithBody) {
   StatementList body;
-  body.push_back(std::make_unique<NopStatement>());
+  body.push_back(std::make_unique<KillStatement>());
 
   ElseStatement e(std::move(body));
   EXPECT_TRUE(e.IsValid());
@@ -83,7 +83,7 @@
 
 TEST_F(ElseStatementTest, IsValid_WithNullBodyStatement) {
   StatementList body;
-  body.push_back(std::make_unique<NopStatement>());
+  body.push_back(std::make_unique<KillStatement>());
   body.push_back(nullptr);
 
   ElseStatement e(std::move(body));
@@ -109,7 +109,7 @@
   auto cond = std::make_unique<ScalarConstructorExpression>(
       std::make_unique<BoolLiteral>(&bool_type, true));
   StatementList body;
-  body.push_back(std::make_unique<NopStatement>());
+  body.push_back(std::make_unique<KillStatement>());
 
   ElseStatement e(std::move(cond), std::move(body));
   std::ostringstream out;
@@ -119,7 +119,7 @@
       ScalarConstructor{true}
     )
     {
-      Nop{}
+      Kill{}
     }
   }
 )");
@@ -127,14 +127,14 @@
 
 TEST_F(ElseStatementTest, ToStr_NoCondition) {
   StatementList body;
-  body.push_back(std::make_unique<NopStatement>());
+  body.push_back(std::make_unique<KillStatement>());
 
   ElseStatement e(std::move(body));
   std::ostringstream out;
   e.to_str(out, 2);
   EXPECT_EQ(out.str(), R"(  Else{
     {
-      Nop{}
+      Kill{}
     }
   }
 )");
diff --git a/src/ast/function_test.cc b/src/ast/function_test.cc
index faae8d1..300244c 100644
--- a/src/ast/function_test.cc
+++ b/src/ast/function_test.cc
@@ -15,7 +15,7 @@
 #include "src/ast/function.h"
 
 #include "gtest/gtest.h"
-#include "src/ast/nop_statement.h"
+#include "src/ast/kill_statement.h"
 #include "src/ast/type/f32_type.h"
 #include "src/ast/type/i32_type.h"
 #include "src/ast/type/void_type.h"
@@ -66,7 +66,7 @@
       std::make_unique<Variable>("var", StorageClass::kNone, &i32));
 
   StatementList body;
-  body.push_back(std::make_unique<NopStatement>());
+  body.push_back(std::make_unique<KillStatement>());
 
   Function f("func", std::move(params), &void_type);
   f.set_body(std::move(body));
@@ -129,7 +129,7 @@
       std::make_unique<Variable>("var", StorageClass::kNone, &i32));
 
   StatementList body;
-  body.push_back(std::make_unique<NopStatement>());
+  body.push_back(std::make_unique<KillStatement>());
   body.push_back(nullptr);
 
   Function f("func", std::move(params), &void_type);
@@ -146,7 +146,7 @@
       std::make_unique<Variable>("var", StorageClass::kNone, &i32));
 
   StatementList body;
-  body.push_back(std::make_unique<NopStatement>());
+  body.push_back(std::make_unique<KillStatement>());
   body.push_back(nullptr);
 
   Function f("func", std::move(params), &void_type);
@@ -159,7 +159,7 @@
   type::I32Type i32;
 
   StatementList body;
-  body.push_back(std::make_unique<NopStatement>());
+  body.push_back(std::make_unique<KillStatement>());
 
   Function f("func", {}, &void_type);
   f.set_body(std::move(body));
@@ -169,7 +169,7 @@
   EXPECT_EQ(out.str(), R"(  Function func -> __void
   ()
   {
-    Nop{}
+    Kill{}
   }
 )");
 }
@@ -183,7 +183,7 @@
       std::make_unique<Variable>("var", StorageClass::kNone, &i32));
 
   StatementList body;
-  body.push_back(std::make_unique<NopStatement>());
+  body.push_back(std::make_unique<KillStatement>());
 
   Function f("func", std::move(params), &void_type);
   f.set_body(std::move(body));
@@ -199,7 +199,7 @@
     }
   )
   {
-    Nop{}
+    Kill{}
   }
 )");
 }
diff --git a/src/ast/if_statement_test.cc b/src/ast/if_statement_test.cc
index 8455613..e2fe840 100644
--- a/src/ast/if_statement_test.cc
+++ b/src/ast/if_statement_test.cc
@@ -17,7 +17,6 @@
 #include "gtest/gtest.h"
 #include "src/ast/identifier_expression.h"
 #include "src/ast/kill_statement.h"
-#include "src/ast/nop_statement.h"
 
 namespace tint {
 namespace ast {
@@ -28,7 +27,7 @@
 TEST_F(IfStatementTest, Creation) {
   auto cond = std::make_unique<IdentifierExpression>("cond");
   StatementList body;
-  body.push_back(std::make_unique<NopStatement>());
+  body.push_back(std::make_unique<KillStatement>());
 
   auto* cond_ptr = cond.get();
   auto* stmt_ptr = body[0].get();
@@ -42,7 +41,7 @@
 TEST_F(IfStatementTest, Creation_WithSource) {
   auto cond = std::make_unique<IdentifierExpression>("cond");
   StatementList body;
-  body.push_back(std::make_unique<NopStatement>());
+  body.push_back(std::make_unique<KillStatement>());
 
   IfStatement stmt(Source{20, 2}, std::move(cond), std::move(body));
   auto src = stmt.source();
@@ -58,7 +57,7 @@
 TEST_F(IfStatementTest, IsValid) {
   auto cond = std::make_unique<IdentifierExpression>("cond");
   StatementList body;
-  body.push_back(std::make_unique<NopStatement>());
+  body.push_back(std::make_unique<KillStatement>());
 
   IfStatement stmt(std::move(cond), std::move(body));
   EXPECT_TRUE(stmt.IsValid());
@@ -67,7 +66,7 @@
 TEST_F(IfStatementTest, IsValid_WithElseStatements) {
   auto cond = std::make_unique<IdentifierExpression>("cond");
   StatementList body;
-  body.push_back(std::make_unique<NopStatement>());
+  body.push_back(std::make_unique<KillStatement>());
 
   ElseStatementList else_stmts;
   else_stmts.push_back(std::make_unique<ElseStatement>());
@@ -81,7 +80,7 @@
 
 TEST_F(IfStatementTest, IsValid_MissingCondition) {
   StatementList body;
-  body.push_back(std::make_unique<NopStatement>());
+  body.push_back(std::make_unique<KillStatement>());
 
   IfStatement stmt(nullptr, std::move(body));
   EXPECT_FALSE(stmt.IsValid());
@@ -90,7 +89,7 @@
 TEST_F(IfStatementTest, IsValid_InvalidCondition) {
   auto cond = std::make_unique<IdentifierExpression>("");
   StatementList body;
-  body.push_back(std::make_unique<NopStatement>());
+  body.push_back(std::make_unique<KillStatement>());
 
   IfStatement stmt(std::move(cond), std::move(body));
   EXPECT_FALSE(stmt.IsValid());
@@ -99,7 +98,7 @@
 TEST_F(IfStatementTest, IsValid_NullBodyStatement) {
   auto cond = std::make_unique<IdentifierExpression>("cond");
   StatementList body;
-  body.push_back(std::make_unique<NopStatement>());
+  body.push_back(std::make_unique<KillStatement>());
   body.push_back(nullptr);
 
   IfStatement stmt(std::move(cond), std::move(body));
@@ -109,7 +108,7 @@
 TEST_F(IfStatementTest, IsValid_InvalidBodyStatement) {
   auto cond = std::make_unique<IdentifierExpression>("cond");
   StatementList body;
-  body.push_back(std::make_unique<NopStatement>());
+  body.push_back(std::make_unique<KillStatement>());
   body.push_back(std::make_unique<IfStatement>());
 
   IfStatement stmt(std::move(cond), std::move(body));
@@ -119,7 +118,7 @@
 TEST_F(IfStatementTest, IsValid_NullElseStatement) {
   auto cond = std::make_unique<IdentifierExpression>("cond");
   StatementList body;
-  body.push_back(std::make_unique<NopStatement>());
+  body.push_back(std::make_unique<KillStatement>());
 
   ElseStatementList else_stmts;
   else_stmts.push_back(std::make_unique<ElseStatement>());
@@ -135,7 +134,7 @@
 TEST_F(IfStatementTest, IsValid_InvalidElseStatement) {
   auto cond = std::make_unique<IdentifierExpression>("cond");
   StatementList body;
-  body.push_back(std::make_unique<NopStatement>());
+  body.push_back(std::make_unique<KillStatement>());
 
   ElseStatementList else_stmts;
   else_stmts.push_back(std::make_unique<ElseStatement>());
@@ -149,7 +148,7 @@
 TEST_F(IfStatementTest, IsValid_MultipleElseWiththoutCondition) {
   auto cond = std::make_unique<IdentifierExpression>("cond");
   StatementList body;
-  body.push_back(std::make_unique<NopStatement>());
+  body.push_back(std::make_unique<KillStatement>());
 
   ElseStatementList else_stmts;
   else_stmts.push_back(std::make_unique<ElseStatement>());
@@ -163,7 +162,7 @@
 TEST_F(IfStatementTest, IsValid_ElseNotLast) {
   auto cond = std::make_unique<IdentifierExpression>("cond");
   StatementList body;
-  body.push_back(std::make_unique<NopStatement>());
+  body.push_back(std::make_unique<KillStatement>());
 
   ElseStatementList else_stmts;
   else_stmts.push_back(std::make_unique<ElseStatement>());
@@ -178,7 +177,7 @@
 TEST_F(IfStatementTest, ToStr) {
   auto cond = std::make_unique<IdentifierExpression>("cond");
   StatementList body;
-  body.push_back(std::make_unique<NopStatement>());
+  body.push_back(std::make_unique<KillStatement>());
 
   IfStatement stmt(std::move(cond), std::move(body));
 
@@ -189,7 +188,7 @@
       Identifier{cond}
     )
     {
-      Nop{}
+      Kill{}
     }
   }
 )");
@@ -198,13 +197,13 @@
 TEST_F(IfStatementTest, ToStr_WithElseStatements) {
   auto cond = std::make_unique<IdentifierExpression>("cond");
   StatementList body;
-  body.push_back(std::make_unique<NopStatement>());
+  body.push_back(std::make_unique<KillStatement>());
 
   StatementList else_if_body;
   else_if_body.push_back(std::make_unique<KillStatement>());
 
   StatementList else_body;
-  else_body.push_back(std::make_unique<NopStatement>());
+  else_body.push_back(std::make_unique<KillStatement>());
   else_body.push_back(std::make_unique<KillStatement>());
 
   ElseStatementList else_stmts;
@@ -224,7 +223,7 @@
       Identifier{cond}
     )
     {
-      Nop{}
+      Kill{}
     }
   }
   Else{
@@ -237,7 +236,7 @@
   }
   Else{
     {
-      Nop{}
+      Kill{}
       Kill{}
     }
   }
diff --git a/src/ast/loop_statement_test.cc b/src/ast/loop_statement_test.cc
index a12b2f7..d7f2187 100644
--- a/src/ast/loop_statement_test.cc
+++ b/src/ast/loop_statement_test.cc
@@ -20,7 +20,6 @@
 #include "gtest/gtest.h"
 #include "src/ast/if_statement.h"
 #include "src/ast/kill_statement.h"
-#include "src/ast/nop_statement.h"
 
 namespace tint {
 namespace ast {
@@ -34,7 +33,7 @@
   auto* b_ptr = body[0].get();
 
   StatementList continuing;
-  continuing.push_back(std::make_unique<NopStatement>());
+  continuing.push_back(std::make_unique<KillStatement>());
   auto* c_ptr = continuing[0].get();
 
   LoopStatement l(std::move(body), std::move(continuing));
@@ -49,7 +48,7 @@
   body.push_back(std::make_unique<KillStatement>());
 
   StatementList continuing;
-  continuing.push_back(std::make_unique<NopStatement>());
+  continuing.push_back(std::make_unique<KillStatement>());
 
   LoopStatement l(Source{20, 2}, std::move(body), std::move(continuing));
   auto src = l.source();
@@ -75,7 +74,7 @@
   body.push_back(std::make_unique<KillStatement>());
 
   StatementList continuing;
-  continuing.push_back(std::make_unique<NopStatement>());
+  continuing.push_back(std::make_unique<KillStatement>());
 
   LoopStatement l(std::move(body), std::move(continuing));
   EXPECT_TRUE(l.has_continuing());
@@ -86,7 +85,7 @@
   body.push_back(std::make_unique<KillStatement>());
 
   StatementList continuing;
-  continuing.push_back(std::make_unique<NopStatement>());
+  continuing.push_back(std::make_unique<KillStatement>());
 
   LoopStatement l(std::move(body), std::move(continuing));
   EXPECT_TRUE(l.IsValid());
@@ -111,7 +110,7 @@
   body.push_back(nullptr);
 
   StatementList continuing;
-  continuing.push_back(std::make_unique<NopStatement>());
+  continuing.push_back(std::make_unique<KillStatement>());
 
   LoopStatement l(std::move(body), std::move(continuing));
   EXPECT_FALSE(l.IsValid());
@@ -123,7 +122,7 @@
   body.push_back(std::make_unique<IfStatement>());
 
   StatementList continuing;
-  continuing.push_back(std::make_unique<NopStatement>());
+  continuing.push_back(std::make_unique<KillStatement>());
 
   LoopStatement l(std::move(body), std::move(continuing));
   EXPECT_FALSE(l.IsValid());
@@ -134,7 +133,7 @@
   body.push_back(std::make_unique<KillStatement>());
 
   StatementList continuing;
-  continuing.push_back(std::make_unique<NopStatement>());
+  continuing.push_back(std::make_unique<KillStatement>());
   continuing.push_back(nullptr);
 
   LoopStatement l(std::move(body), std::move(continuing));
@@ -146,7 +145,7 @@
   body.push_back(std::make_unique<KillStatement>());
 
   StatementList continuing;
-  continuing.push_back(std::make_unique<NopStatement>());
+  continuing.push_back(std::make_unique<KillStatement>());
   continuing.push_back(std::make_unique<IfStatement>());
 
   LoopStatement l(std::move(body), std::move(continuing));
@@ -171,7 +170,7 @@
   body.push_back(std::make_unique<KillStatement>());
 
   StatementList continuing;
-  continuing.push_back(std::make_unique<NopStatement>());
+  continuing.push_back(std::make_unique<KillStatement>());
 
   LoopStatement l(std::move(body), std::move(continuing));
   std::ostringstream out;
@@ -179,7 +178,7 @@
   EXPECT_EQ(out.str(), R"(  Loop{
     Kill{}
     continuing {
-      Nop{}
+      Kill{}
     }
   }
 )");
diff --git a/src/ast/nop_statement.cc b/src/ast/nop_statement.cc
deleted file mode 100644
index 86699cb..0000000
--- a/src/ast/nop_statement.cc
+++ /dev/null
@@ -1,40 +0,0 @@
-// Copyright 2020 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/ast/nop_statement.h"
-
-namespace tint {
-namespace ast {
-
-NopStatement::NopStatement() : Statement() {}
-
-NopStatement::NopStatement(const Source& source) : Statement(source) {}
-
-NopStatement::~NopStatement() = default;
-
-bool NopStatement::IsNop() const {
-  return true;
-}
-
-bool NopStatement::IsValid() const {
-  return true;
-}
-
-void NopStatement::to_str(std::ostream& out, size_t indent) const {
-  make_indent(out, indent);
-  out << "Nop{}" << std::endl;
-}
-
-}  // namespace ast
-}  // namespace tint
diff --git a/src/ast/nop_statement.h b/src/ast/nop_statement.h
deleted file mode 100644
index eae7c60..0000000
--- a/src/ast/nop_statement.h
+++ /dev/null
@@ -1,53 +0,0 @@
-// Copyright 2020 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.
-
-#ifndef SRC_AST_NOP_STATEMENT_H_
-#define SRC_AST_NOP_STATEMENT_H_
-
-#include "src/ast/statement.h"
-
-namespace tint {
-namespace ast {
-
-/// A nop statement
-class NopStatement : public Statement {
- public:
-  /// Constructor
-  NopStatement();
-  /// Constructor
-  /// @param source the nop statement source
-  explicit NopStatement(const Source& source);
-  /// Move constructor
-  NopStatement(NopStatement&&) = default;
-  ~NopStatement() override;
-
-  /// @returns true if this is a nop statement
-  bool IsNop() const override;
-
-  /// @returns true if the node is valid
-  bool IsValid() const override;
-
-  /// Writes a representation of the node to the output stream
-  /// @param out the stream to write to
-  /// @param indent number of spaces to indent the node when writing
-  void to_str(std::ostream& out, size_t indent) const override;
-
- private:
-  NopStatement(const NopStatement&) = delete;
-};
-
-}  // namespace ast
-}  // namespace tint
-
-#endif  // SRC_AST_NOP_STATEMENT_H_
diff --git a/src/ast/nop_statement_test.cc b/src/ast/nop_statement_test.cc
deleted file mode 100644
index b7dda99..0000000
--- a/src/ast/nop_statement_test.cc
+++ /dev/null
@@ -1,59 +0,0 @@
-// Copyright 2020 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/ast/nop_statement.h"
-
-#include <sstream>
-
-#include "gtest/gtest.h"
-
-namespace tint {
-namespace ast {
-namespace {
-
-using NopStatementTest = testing::Test;
-
-TEST_F(NopStatementTest, Creation) {
-  NopStatement n;
-  EXPECT_EQ(n.line(), 0u);
-  EXPECT_EQ(n.column(), 0u);
-}
-
-TEST_F(NopStatementTest, Creation_WithSource) {
-  NopStatement n(Source{20, 2});
-  EXPECT_EQ(n.line(), 20u);
-  EXPECT_EQ(n.column(), 2u);
-}
-
-TEST_F(NopStatementTest, IsNop) {
-  NopStatement n;
-  EXPECT_TRUE(n.IsNop());
-}
-
-TEST_F(NopStatementTest, IsValid) {
-  NopStatement n;
-  EXPECT_TRUE(n.IsValid());
-}
-
-TEST_F(NopStatementTest, ToStr) {
-  NopStatement n;
-  std::ostringstream out;
-  n.to_str(out, 2);
-  EXPECT_EQ(out.str(), R"(  Nop{}
-)");
-}
-
-}  // namespace
-}  // namespace ast
-}  // namespace tint
diff --git a/src/ast/statement.cc b/src/ast/statement.cc
index a5d7f36..6aa1380 100644
--- a/src/ast/statement.cc
+++ b/src/ast/statement.cc
@@ -25,7 +25,6 @@
 #include "src/ast/if_statement.h"
 #include "src/ast/kill_statement.h"
 #include "src/ast/loop_statement.h"
-#include "src/ast/nop_statement.h"
 #include "src/ast/return_statement.h"
 #include "src/ast/switch_statement.h"
 #include "src/ast/unless_statement.h"
@@ -78,10 +77,6 @@
   return false;
 }
 
-bool Statement::IsNop() const {
-  return false;
-}
-
 bool Statement::IsReturn() const {
   return false;
 }
@@ -143,11 +138,6 @@
   return static_cast<const LoopStatement*>(this);
 }
 
-const NopStatement* Statement::AsNop() const {
-  assert(IsNop());
-  return static_cast<const NopStatement*>(this);
-}
-
 const ReturnStatement* Statement::AsReturn() const {
   assert(IsReturn());
   return static_cast<const ReturnStatement*>(this);
@@ -213,11 +203,6 @@
   return static_cast<LoopStatement*>(this);
 }
 
-NopStatement* Statement::AsNop() {
-  assert(IsNop());
-  return static_cast<NopStatement*>(this);
-}
-
 ReturnStatement* Statement::AsReturn() {
   assert(IsReturn());
   return static_cast<ReturnStatement*>(this);
diff --git a/src/ast/statement.h b/src/ast/statement.h
index c3188ac..a813818 100644
--- a/src/ast/statement.h
+++ b/src/ast/statement.h
@@ -32,7 +32,6 @@
 class IfStatement;
 class KillStatement;
 class LoopStatement;
-class NopStatement;
 class ReturnStatement;
 class SwitchStatement;
 class UnlessStatement;
@@ -61,8 +60,6 @@
   virtual bool IsKill() const;
   /// @returns true if this is a loop statement
   virtual bool IsLoop() const;
-  /// @returns true if this is a nop statement
-  virtual bool IsNop() const;
   /// @returns true if this is a return statement
   virtual bool IsReturn() const;
   /// @returns true if this is a switch statement
@@ -90,8 +87,6 @@
   const KillStatement* AsKill() const;
   /// @returns the statement as a const loop statement
   const LoopStatement* AsLoop() const;
-  /// @returns the statement as a const nop statement
-  const NopStatement* AsNop() const;
   /// @returns the statement as a const return statement
   const ReturnStatement* AsReturn() const;
   /// @returns the statement as a const switch statement
@@ -119,8 +114,6 @@
   KillStatement* AsKill();
   /// @returns the statement as a loop statement
   LoopStatement* AsLoop();
-  /// @returns the statement as a nop statement
-  NopStatement* AsNop();
   /// @returns the statement as a return statement
   ReturnStatement* AsReturn();
   /// @returns the statement as a switch statement
diff --git a/src/ast/unless_statement_test.cc b/src/ast/unless_statement_test.cc
index 45b7b7d..b3c1ae9 100644
--- a/src/ast/unless_statement_test.cc
+++ b/src/ast/unless_statement_test.cc
@@ -17,7 +17,7 @@
 #include "gtest/gtest.h"
 #include "src/ast/identifier_expression.h"
 #include "src/ast/if_statement.h"
-#include "src/ast/nop_statement.h"
+#include "src/ast/kill_statement.h"
 
 namespace tint {
 namespace ast {
@@ -28,21 +28,21 @@
 TEST_F(UnlessStatementTest, Creation) {
   auto ident = std::make_unique<IdentifierExpression>("ident");
   StatementList body;
-  body.push_back(std::make_unique<NopStatement>());
+  body.push_back(std::make_unique<KillStatement>());
 
   auto* ident_ptr = ident.get();
-  auto* nop_ptr = body[0].get();
+  auto* kill_ptr = body[0].get();
 
   UnlessStatement u(std::move(ident), std::move(body));
   EXPECT_EQ(u.condition(), ident_ptr);
   ASSERT_EQ(u.body().size(), 1u);
-  EXPECT_EQ(u.body()[0].get(), nop_ptr);
+  EXPECT_EQ(u.body()[0].get(), kill_ptr);
 }
 
 TEST_F(UnlessStatementTest, Creation_WithSource) {
   auto ident = std::make_unique<IdentifierExpression>("ident");
   StatementList body;
-  body.push_back(std::make_unique<NopStatement>());
+  body.push_back(std::make_unique<KillStatement>());
 
   UnlessStatement u(Source{20, 2}, std::move(ident), std::move(body));
   auto src = u.source();
@@ -58,7 +58,7 @@
 TEST_F(UnlessStatementTest, IsValid) {
   auto ident = std::make_unique<IdentifierExpression>("ident");
   StatementList body;
-  body.push_back(std::make_unique<NopStatement>());
+  body.push_back(std::make_unique<KillStatement>());
 
   UnlessStatement u(std::move(ident), std::move(body));
   EXPECT_TRUE(u.IsValid());
@@ -66,7 +66,7 @@
 
 TEST_F(UnlessStatementTest, IsValid_NullCondition) {
   StatementList body;
-  body.push_back(std::make_unique<NopStatement>());
+  body.push_back(std::make_unique<KillStatement>());
 
   UnlessStatement u;
   u.set_body(std::move(body));
@@ -76,7 +76,7 @@
 TEST_F(UnlessStatementTest, IsValid_InvalidCondition) {
   auto ident = std::make_unique<IdentifierExpression>("");
   StatementList body;
-  body.push_back(std::make_unique<NopStatement>());
+  body.push_back(std::make_unique<KillStatement>());
 
   UnlessStatement u(std::move(ident), std::move(body));
   EXPECT_FALSE(u.IsValid());
@@ -85,7 +85,7 @@
 TEST_F(UnlessStatementTest, IsValid_NullBodyStatement) {
   auto ident = std::make_unique<IdentifierExpression>("ident");
   StatementList body;
-  body.push_back(std::make_unique<NopStatement>());
+  body.push_back(std::make_unique<KillStatement>());
   body.push_back(nullptr);
 
   UnlessStatement u(std::move(ident), std::move(body));
@@ -95,7 +95,7 @@
 TEST_F(UnlessStatementTest, IsValid_InvalidBodyStatement) {
   auto ident = std::make_unique<IdentifierExpression>("ident");
   StatementList body;
-  body.push_back(std::make_unique<NopStatement>());
+  body.push_back(std::make_unique<KillStatement>());
   body.push_back(std::make_unique<IfStatement>());
 
   UnlessStatement u(std::move(ident), std::move(body));
@@ -105,7 +105,7 @@
 TEST_F(UnlessStatementTest, ToStr) {
   auto ident = std::make_unique<IdentifierExpression>("ident");
   StatementList body;
-  body.push_back(std::make_unique<NopStatement>());
+  body.push_back(std::make_unique<KillStatement>());
 
   UnlessStatement u(std::move(ident), std::move(body));
   std::ostringstream out;
@@ -115,7 +115,7 @@
       Identifier{ident}
     )
     {
-      Nop{}
+      Kill{}
     }
   }
 )");
diff --git a/src/reader/spirv/function.cc b/src/reader/spirv/function.cc
index 8b2617c..7970f84 100644
--- a/src/reader/spirv/function.cc
+++ b/src/reader/spirv/function.cc
@@ -1613,7 +1613,7 @@
   const auto* ptr_type = type_mgr_->GetType(ptr_ty_id);
   if (!ptr_type || !ptr_type->AsPointer()) {
     Fail() << "Access chain %" << inst.result_id()
-                  << " base pointer is not of pointer type";
+           << " base pointer is not of pointer type";
     return {};
   }
   const auto* pointee_type = ptr_type->AsPointer()->pointee_type();
@@ -1631,11 +1631,9 @@
           if (index_const_val < 0 ||
               pointee_type->AsVector()->element_count() <= index_const_val) {
             Fail() << "Access chain %" << inst.result_id() << " index %"
-                          << inst.GetSingleWordInOperand(index) << " value "
-                          << index_const_val
-                          << " is out of bounds for vector of "
-                          << pointee_type->AsVector()->element_count()
-                          << " elements";
+                   << inst.GetSingleWordInOperand(index) << " value "
+                   << index_const_val << " is out of bounds for vector of "
+                   << pointee_type->AsVector()->element_count() << " elements";
             return {};
           }
           if (uint64_t(index_const_val) >=
@@ -1659,36 +1657,38 @@
       case spvtools::opt::analysis::Type::kMatrix:
         // Use array syntax.
         next_expr = std::make_unique<ast::ArrayAccessorExpression>(
-            std::move(current_expr.expr), std::move(MakeOperand(inst, index).expr));
+            std::move(current_expr.expr),
+            std::move(MakeOperand(inst, index).expr));
         pointee_type = pointee_type->AsMatrix()->element_type();
         break;
       case spvtools::opt::analysis::Type::kArray:
         next_expr = std::make_unique<ast::ArrayAccessorExpression>(
-            std::move(current_expr.expr), std::move(MakeOperand(inst, index).expr));
+            std::move(current_expr.expr),
+            std::move(MakeOperand(inst, index).expr));
         pointee_type = pointee_type->AsArray()->element_type();
         break;
       case spvtools::opt::analysis::Type::kRuntimeArray:
         next_expr = std::make_unique<ast::ArrayAccessorExpression>(
-            std::move(current_expr.expr), std::move(MakeOperand(inst, index).expr));
+            std::move(current_expr.expr),
+            std::move(MakeOperand(inst, index).expr));
         pointee_type = pointee_type->AsRuntimeArray()->element_type();
         break;
       case spvtools::opt::analysis::Type::kStruct: {
         if (!index_const) {
           Fail() << "Access chain %" << inst.result_id() << " index %"
-                        << inst.GetSingleWordInOperand(index)
-                        << " is a non-constant index into a structure %"
-                        << type_mgr_->GetId(pointee_type);
+                 << inst.GetSingleWordInOperand(index)
+                 << " is a non-constant index into a structure %"
+                 << type_mgr_->GetId(pointee_type);
           return {};
         }
         if ((index_const_val < 0) ||
             pointee_type->AsStruct()->element_types().size() <=
                 uint64_t(index_const_val)) {
-          Fail() << "Access chain %" << inst.result_id()
-                        << " index value " << index_const_val
-                        << " is out of bounds for structure %"
-                        << type_mgr_->GetId(pointee_type) << " having "
-                        << pointee_type->AsStruct()->element_types().size()
-                        << " elements";
+          Fail() << "Access chain %" << inst.result_id() << " index value "
+                 << index_const_val << " is out of bounds for structure %"
+                 << type_mgr_->GetId(pointee_type) << " having "
+                 << pointee_type->AsStruct()->element_types().size()
+                 << " elements";
           return {};
         }
         auto member_access =
@@ -1700,16 +1700,15 @@
         pointee_type =
             pointee_type->AsStruct()->element_types()[index_const_val];
         break;
-     }
+      }
       default:
         Fail() << "Access chain with unknown pointee type %"
-                      << type_mgr_->GetId(pointee_type) << " "
-                      << pointee_type->str();
+               << type_mgr_->GetId(pointee_type) << " " << pointee_type->str();
         return {};
     }
     current_expr.reset(TypedExpression(
-          parser_impl_.ConvertType(type_mgr_->GetId(pointee_type)),
-          std::move(next_expr)));
+        parser_impl_.ConvertType(type_mgr_->GetId(pointee_type)),
+        std::move(next_expr)));
   }
   return current_expr;
 }
diff --git a/src/reader/wgsl/lexer.cc b/src/reader/wgsl/lexer.cc
index bb18f36..4c8545e 100644
--- a/src/reader/wgsl/lexer.cc
+++ b/src/reader/wgsl/lexer.cc
@@ -586,8 +586,6 @@
     return {Token::Type::kMat4x3, source, "mat4x3"};
   if (str == "mat4x4")
     return {Token::Type::kMat4x4, source, "mat4x4"};
-  if (str == "nop")
-    return {Token::Type::kNop, source, "nop"};
   if (str == "num_workgroups")
     return {Token::Type::kNumWorkgroups, source, "num_workgroups"};
   if (str == "offset")
diff --git a/src/reader/wgsl/lexer_test.cc b/src/reader/wgsl/lexer_test.cc
index c59e4fb..9944ee0 100644
--- a/src/reader/wgsl/lexer_test.cc
+++ b/src/reader/wgsl/lexer_test.cc
@@ -468,7 +468,6 @@
         TokenData{"mat4x2", Token::Type::kMat4x2},
         TokenData{"mat4x3", Token::Type::kMat4x3},
         TokenData{"mat4x4", Token::Type::kMat4x4},
-        TokenData{"nop", Token::Type::kNop},
         TokenData{"num_workgroups", Token::Type::kNumWorkgroups},
         TokenData{"offset", Token::Type::kOffset},
         TokenData{"out", Token::Type::kOut},
diff --git a/src/reader/wgsl/parser_impl.cc b/src/reader/wgsl/parser_impl.cc
index cf28229..e64a74b 100644
--- a/src/reader/wgsl/parser_impl.cc
+++ b/src/reader/wgsl/parser_impl.cc
@@ -38,7 +38,6 @@
 #include "src/ast/kill_statement.h"
 #include "src/ast/location_decoration.h"
 #include "src/ast/member_accessor_expression.h"
-#include "src/ast/nop_statement.h"
 #include "src/ast/return_statement.h"
 #include "src/ast/scalar_constructor_expression.h"
 #include "src/ast/set_decoration.h"
@@ -1450,7 +1449,6 @@
 //   | break_stmt SEMICOLON
 //   | continue_stmt SEMICOLON
 //   | KILL SEMICOLON
-//   | NOP SEMICOLON
 //   | assignment_expression SEMICOLON
 std::unique_ptr<ast::Statement> ParserImpl::statement() {
   auto t = peek();
@@ -1552,18 +1550,6 @@
     return std::make_unique<ast::KillStatement>(source);
   }
 
-  if (t.IsNop()) {
-    auto source = t.source();
-    next();  // Consume the peek
-
-    t = next();
-    if (!t.IsSemicolon()) {
-      set_error(t, "missing ;");
-      return nullptr;
-    }
-    return std::make_unique<ast::NopStatement>(source);
-  }
-
   auto assign = assignment_stmt();
   if (has_error())
     return nullptr;
diff --git a/src/reader/wgsl/parser_impl_body_stmt_test.cc b/src/reader/wgsl/parser_impl_body_stmt_test.cc
index 6f16508..90e0d73 100644
--- a/src/reader/wgsl/parser_impl_body_stmt_test.cc
+++ b/src/reader/wgsl/parser_impl_body_stmt_test.cc
@@ -24,15 +24,13 @@
 TEST_F(ParserImplTest, BodyStmt) {
   auto* p = parser(R"({
   kill;
-  nop;
   return 1 + b / 2;
 })");
   auto e = p->body_stmt();
   ASSERT_FALSE(p->has_error()) << p->error();
-  ASSERT_EQ(e.size(), 3u);
+  ASSERT_EQ(e.size(), 2u);
   EXPECT_TRUE(e[0]->IsKill());
-  EXPECT_TRUE(e[1]->IsNop());
-  EXPECT_TRUE(e[2]->IsReturn());
+  EXPECT_TRUE(e[1]->IsReturn());
 }
 
 TEST_F(ParserImplTest, BodyStmt_Empty) {
diff --git a/src/reader/wgsl/parser_impl_continuing_stmt_test.cc b/src/reader/wgsl/parser_impl_continuing_stmt_test.cc
index c996c84..9154312 100644
--- a/src/reader/wgsl/parser_impl_continuing_stmt_test.cc
+++ b/src/reader/wgsl/parser_impl_continuing_stmt_test.cc
@@ -22,19 +22,19 @@
 namespace {
 
 TEST_F(ParserImplTest, ContinuingStmt) {
-  auto* p = parser("continuing { nop; }");
+  auto* p = parser("continuing { kill; }");
   auto e = p->continuing_stmt();
   ASSERT_FALSE(p->has_error()) << p->error();
   ASSERT_EQ(e.size(), 1u);
-  ASSERT_TRUE(e[0]->IsNop());
+  ASSERT_TRUE(e[0]->IsKill());
 }
 
 TEST_F(ParserImplTest, ContinuingStmt_InvalidBody) {
-  auto* p = parser("continuing { nop }");
+  auto* p = parser("continuing { kill }");
   auto e = p->continuing_stmt();
   ASSERT_TRUE(p->has_error());
   ASSERT_EQ(e.size(), 0u);
-  EXPECT_EQ(p->error(), "1:18: missing ;");
+  EXPECT_EQ(p->error(), "1:19: missing ;");
 }
 
 }  // namespace
diff --git a/src/reader/wgsl/parser_impl_loop_stmt_test.cc b/src/reader/wgsl/parser_impl_loop_stmt_test.cc
index ea7a245..71bd39b 100644
--- a/src/reader/wgsl/parser_impl_loop_stmt_test.cc
+++ b/src/reader/wgsl/parser_impl_loop_stmt_test.cc
@@ -22,25 +22,25 @@
 namespace {
 
 TEST_F(ParserImplTest, LoopStmt_BodyNoContinuing) {
-  auto* p = parser("loop { nop; }");
+  auto* p = parser("loop { kill; }");
   auto e = p->loop_stmt();
   ASSERT_FALSE(p->has_error()) << p->error();
   ASSERT_NE(e, nullptr);
 
   ASSERT_EQ(e->body().size(), 1u);
-  EXPECT_TRUE(e->body()[0]->IsNop());
+  EXPECT_TRUE(e->body()[0]->IsKill());
 
   EXPECT_EQ(e->continuing().size(), 0u);
 }
 
 TEST_F(ParserImplTest, LoopStmt_BodyWithContinuing) {
-  auto* p = parser("loop { nop; continuing { kill; }}");
+  auto* p = parser("loop { kill; continuing { kill; }}");
   auto e = p->loop_stmt();
   ASSERT_FALSE(p->has_error()) << p->error();
   ASSERT_NE(e, nullptr);
 
   ASSERT_EQ(e->body().size(), 1u);
-  EXPECT_TRUE(e->body()[0]->IsNop());
+  EXPECT_TRUE(e->body()[0]->IsKill());
 
   EXPECT_EQ(e->continuing().size(), 1u);
   EXPECT_TRUE(e->continuing()[0]->IsKill());
diff --git a/src/reader/wgsl/parser_impl_statement_test.cc b/src/reader/wgsl/parser_impl_statement_test.cc
index f123437..40a8bfc 100644
--- a/src/reader/wgsl/parser_impl_statement_test.cc
+++ b/src/reader/wgsl/parser_impl_statement_test.cc
@@ -253,22 +253,6 @@
   EXPECT_EQ(p->error(), "1:5: missing ;");
 }
 
-TEST_F(ParserImplTest, Statement_Nop) {
-  auto* p = parser("nop;");
-  auto e = p->statement();
-  ASSERT_FALSE(p->has_error()) << p->error();
-  EXPECT_NE(e, nullptr);
-  ASSERT_TRUE(e->IsNop());
-}
-
-TEST_F(ParserImplTest, Statement_Nop_MissingSemicolon) {
-  auto* p = parser("nop");
-  auto e = p->statement();
-  ASSERT_TRUE(p->has_error());
-  EXPECT_EQ(e, nullptr);
-  EXPECT_EQ(p->error(), "1:4: missing ;");
-}
-
 }  // namespace
 }  // namespace wgsl
 }  // namespace reader
diff --git a/src/reader/wgsl/parser_impl_statements_test.cc b/src/reader/wgsl/parser_impl_statements_test.cc
index 3e6a959..343d501 100644
--- a/src/reader/wgsl/parser_impl_statements_test.cc
+++ b/src/reader/wgsl/parser_impl_statements_test.cc
@@ -23,13 +23,12 @@
 namespace {
 
 TEST_F(ParserImplTest, Statements) {
-  auto* p = parser("nop; kill; return;");
+  auto* p = parser("kill; return;");
   auto e = p->statements();
   ASSERT_FALSE(p->has_error()) << p->error();
-  ASSERT_EQ(e.size(), 3u);
-  EXPECT_TRUE(e[0]->IsNop());
-  EXPECT_TRUE(e[1]->IsKill());
-  EXPECT_TRUE(e[2]->IsReturn());
+  ASSERT_EQ(e.size(), 2u);
+  EXPECT_TRUE(e[0]->IsKill());
+  EXPECT_TRUE(e[1]->IsReturn());
 }
 
 TEST_F(ParserImplTest, Statements_Empty) {
diff --git a/src/reader/wgsl/token.cc b/src/reader/wgsl/token.cc
index 1481018..0d78a9c 100644
--- a/src/reader/wgsl/token.cc
+++ b/src/reader/wgsl/token.cc
@@ -223,8 +223,6 @@
       return "mat4x3";
     case Token::Type::kMat4x4:
       return "mat4x4";
-    case Token::Type::kNop:
-      return "nop";
     case Token::Type::kNumWorkgroups:
       return "num_workgroups";
     case Token::Type::kOffset:
diff --git a/src/reader/wgsl/token.h b/src/reader/wgsl/token.h
index b2cf05d..1953f6f 100644
--- a/src/reader/wgsl/token.h
+++ b/src/reader/wgsl/token.h
@@ -234,8 +234,6 @@
     kMat4x3,
     /// A 'mat4x4'
     kMat4x4,
-    /// A 'nop'
-    kNop,
     /// A 'num_workgroups'
     kNumWorkgroups,
     /// A 'offset'
@@ -547,8 +545,6 @@
   bool IsMat4x3() const { return type_ == Type::kMat4x3; }
   /// @returns true if token is a 'mat4x4'
   bool IsMat4x4() const { return type_ == Type::kMat4x4; }
-  /// @returns true if token is a 'nop'
-  bool IsNop() const { return type_ == Type::kNop; }
   /// @returns true if token is a 'num_workgroups'
   bool IsNumWorkgroups() const { return type_ == Type::kNumWorkgroups; }
   /// @returns true if token is a 'offset'
diff --git a/src/type_determiner.cc b/src/type_determiner.cc
index 31e66bd..0def870 100644
--- a/src/type_determiner.cc
+++ b/src/type_determiner.cc
@@ -183,9 +183,6 @@
     return DetermineStatements(l->body()) &&
            DetermineStatements(l->continuing());
   }
-  if (stmt->IsNop()) {
-    return true;
-  }
   if (stmt->IsReturn()) {
     auto* r = stmt->AsReturn();
     return DetermineResultType(r->value());
diff --git a/src/writer/spirv/binary_writer_test.cc b/src/writer/spirv/binary_writer_test.cc
index 4de1aae..63e6f04 100644
--- a/src/writer/spirv/binary_writer_test.cc
+++ b/src/writer/spirv/binary_writer_test.cc
@@ -45,7 +45,7 @@
 TEST_F(BinaryWriterTest, Float) {
   ast::Module mod;
   Builder b(&mod);
-  b.push_preamble(spv::Op::OpNop, {Operand::Float(2.4f)});
+  b.push_preamble(spv::Op::OpKill, {Operand::Float(2.4f)});
   BinaryWriter bw;
   bw.WriteBuilder(b);
 
@@ -59,7 +59,7 @@
 TEST_F(BinaryWriterTest, Int) {
   ast::Module mod;
   Builder b(&mod);
-  b.push_preamble(spv::Op::OpNop, {Operand::Int(2)});
+  b.push_preamble(spv::Op::OpKill, {Operand::Int(2)});
   BinaryWriter bw;
   bw.WriteBuilder(b);
 
@@ -71,7 +71,7 @@
 TEST_F(BinaryWriterTest, String) {
   ast::Module mod;
   Builder b(&mod);
-  b.push_preamble(spv::Op::OpNop, {Operand::String("my_string")});
+  b.push_preamble(spv::Op::OpKill, {Operand::String("my_string")});
   BinaryWriter bw;
   bw.WriteBuilder(b);
 
@@ -96,7 +96,7 @@
 TEST_F(BinaryWriterTest, String_Multiple4Length) {
   ast::Module mod;
   Builder b(&mod);
-  b.push_preamble(spv::Op::OpNop, {Operand::String("mystring")});
+  b.push_preamble(spv::Op::OpKill, {Operand::String("mystring")});
   BinaryWriter bw;
   bw.WriteBuilder(b);
 
@@ -119,8 +119,8 @@
 }
 
 TEST_F(BinaryWriterTest, TestInstructionWriter) {
-  Instruction i1{spv::Op::OpNop, {Operand::Int(2)}};
-  Instruction i2{spv::Op::OpNop, {Operand::Int(4)}};
+  Instruction i1{spv::Op::OpKill, {Operand::Int(2)}};
+  Instruction i2{spv::Op::OpKill, {Operand::Int(4)}};
 
   BinaryWriter bw;
   bw.WriteInstruction(i1);
diff --git a/src/writer/wgsl/generator_impl.cc b/src/writer/wgsl/generator_impl.cc
index d45a1a1..e3ddceb 100644
--- a/src/writer/wgsl/generator_impl.cc
+++ b/src/writer/wgsl/generator_impl.cc
@@ -736,9 +736,6 @@
   if (stmt->IsLoop()) {
     return EmitLoop(stmt->AsLoop());
   }
-  if (stmt->IsNop()) {
-    return EmitNop(stmt->AsNop());
-  }
   if (stmt->IsReturn()) {
     return EmitReturn(stmt->AsReturn());
   }
@@ -920,12 +917,6 @@
   return true;
 }
 
-bool GeneratorImpl::EmitNop(ast::NopStatement*) {
-  make_indent();
-  out_ << "nop;" << std::endl;
-  return true;
-}
-
 bool GeneratorImpl::EmitReturn(ast::ReturnStatement* stmt) {
   make_indent();
 
diff --git a/src/writer/wgsl/generator_impl.h b/src/writer/wgsl/generator_impl.h
index d4ee578..d9282bd 100644
--- a/src/writer/wgsl/generator_impl.h
+++ b/src/writer/wgsl/generator_impl.h
@@ -162,10 +162,6 @@
   /// @param expr the member accessor expression
   /// @returns true if the member accessor was emitted
   bool EmitMemberAccessor(ast::MemberAccessorExpression* expr);
-  /// Handles generating a nop statement
-  /// @param stmt the nop statement
-  /// @returns true if the statement was successfully emitted
-  bool EmitNop(ast::NopStatement* stmt);
   /// Handles return statements
   /// @param stmt the statement to emit
   /// @returns true if the statement was successfully emitted
diff --git a/src/writer/wgsl/generator_impl_loop_test.cc b/src/writer/wgsl/generator_impl_loop_test.cc
index 4ddc0da..bb21ff9 100644
--- a/src/writer/wgsl/generator_impl_loop_test.cc
+++ b/src/writer/wgsl/generator_impl_loop_test.cc
@@ -17,7 +17,6 @@
 #include "gtest/gtest.h"
 #include "src/ast/kill_statement.h"
 #include "src/ast/loop_statement.h"
-#include "src/ast/nop_statement.h"
 #include "src/writer/wgsl/generator_impl.h"
 
 namespace tint {
@@ -48,7 +47,7 @@
   body.push_back(std::make_unique<ast::KillStatement>());
 
   ast::StatementList continuing;
-  continuing.push_back(std::make_unique<ast::NopStatement>());
+  continuing.push_back(std::make_unique<ast::KillStatement>());
 
   ast::LoopStatement l(std::move(body), std::move(continuing));
 
@@ -60,7 +59,7 @@
     kill;
 
     continuing {
-      nop;
+      kill;
     }
   }
 )");
diff --git a/src/writer/wgsl/generator_impl_nop_test.cc b/src/writer/wgsl/generator_impl_nop_test.cc
deleted file mode 100644
index 0c50ea7..0000000
--- a/src/writer/wgsl/generator_impl_nop_test.cc
+++ /dev/null
@@ -1,39 +0,0 @@
-// Copyright 2020 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 "gtest/gtest.h"
-#include "src/ast/nop_statement.h"
-#include "src/writer/wgsl/generator_impl.h"
-
-namespace tint {
-namespace writer {
-namespace wgsl {
-namespace {
-
-using GeneratorImplTest = testing::Test;
-
-TEST_F(GeneratorImplTest, Emit_Nop) {
-  ast::NopStatement n;
-
-  GeneratorImpl g;
-  g.increment_indent();
-
-  ASSERT_TRUE(g.EmitStatement(&n)) << g.error();
-  EXPECT_EQ(g.result(), "  nop;\n");
-}
-
-}  // namespace
-}  // namespace wgsl
-}  // namespace writer
-}  // namespace tint
diff --git a/src/writer/wgsl/generator_impl_unless_test.cc b/src/writer/wgsl/generator_impl_unless_test.cc
index 721f877..413f3b5 100644
--- a/src/writer/wgsl/generator_impl_unless_test.cc
+++ b/src/writer/wgsl/generator_impl_unless_test.cc
@@ -17,7 +17,6 @@
 #include "gtest/gtest.h"
 #include "src/ast/identifier_expression.h"
 #include "src/ast/kill_statement.h"
-#include "src/ast/nop_statement.h"
 #include "src/ast/unless_statement.h"
 #include "src/writer/wgsl/generator_impl.h"
 
@@ -32,7 +31,7 @@
   auto cond = std::make_unique<ast::IdentifierExpression>("cond");
 
   ast::StatementList body;
-  body.push_back(std::make_unique<ast::NopStatement>());
+  body.push_back(std::make_unique<ast::KillStatement>());
   body.push_back(std::make_unique<ast::KillStatement>());
 
   ast::UnlessStatement u(std::move(cond), std::move(body));
@@ -42,7 +41,7 @@
 
   ASSERT_TRUE(g.EmitStatement(&u)) << g.error();
   EXPECT_EQ(g.result(), R"(  unless (cond) {
-    nop;
+    kill;
     kill;
   }
 )");