Remove KillStatement

This CL removes the KillStatement from the AST and replaces all test
usage with DiscardStatement.

Bug: tint:169
Change-Id: Ie68dd3cdd54056f144d10506f05cc1f6903d1cda
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/25605
Reviewed-by: David Neto <dneto@google.com>
diff --git a/BUILD.gn b/BUILD.gn
index a2a339b..888a974 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -273,8 +273,6 @@
     "src/ast/int_literal.h",
     "src/ast/intrinsic.cc",
     "src/ast/intrinsic.h",
-    "src/ast/kill_statement.cc",
-    "src/ast/kill_statement.h",
     "src/ast/literal.cc",
     "src/ast/literal.h",
     "src/ast/location_decoration.cc",
@@ -688,7 +686,6 @@
     "src/ast/if_statement_test.cc",
     "src/ast/import_test.cc",
     "src/ast/int_literal_test.cc",
-    "src/ast/kill_statement_test.cc",
     "src/ast/location_decoration_test.cc",
     "src/ast/loop_statement_test.cc",
     "src/ast/member_accessor_expression_test.cc",
@@ -811,7 +808,6 @@
     "src/writer/spirv/builder_ident_expression_test.cc",
     "src/writer/spirv/builder_if_test.cc",
     "src/writer/spirv/builder_intrinsic_test.cc",
-    "src/writer/spirv/builder_kill_test.cc",
     "src/writer/spirv/builder_literal_test.cc",
     "src/writer/spirv/builder_loop_test.cc",
     "src/writer/spirv/builder_return_test.cc",
@@ -951,7 +947,6 @@
     "src/writer/wgsl/generator_impl_identifier_test.cc",
     "src/writer/wgsl/generator_impl_if_test.cc",
     "src/writer/wgsl/generator_impl_import_test.cc",
-    "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_return_test.cc",
@@ -1001,7 +996,6 @@
     "src/writer/msl/generator_impl_identifier_test.cc",
     "src/writer/msl/generator_impl_if_test.cc",
     "src/writer/msl/generator_impl_import_test.cc",
-    "src/writer/msl/generator_impl_kill_test.cc",
     "src/writer/msl/generator_impl_loop_test.cc",
     "src/writer/msl/generator_impl_member_accessor_test.cc",
     "src/writer/msl/generator_impl_module_constant_test.cc",
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 062b0b5..5575b35 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -94,8 +94,6 @@
   ast/int_literal.h
   ast/intrinsic.cc
   ast/intrinsic.h
-  ast/kill_statement.cc
-  ast/kill_statement.h
   ast/literal.h
   ast/literal.cc
   ast/location_decoration.cc
@@ -300,7 +298,6 @@
   ast/if_statement_test.cc
   ast/import_test.cc
   ast/int_literal_test.cc
-  ast/kill_statement_test.cc
   ast/location_decoration_test.cc
   ast/loop_statement_test.cc
   ast/member_accessor_expression_test.cc
@@ -465,7 +462,6 @@
     writer/spirv/builder_ident_expression_test.cc
     writer/spirv/builder_if_test.cc
     writer/spirv/builder_intrinsic_test.cc
-    writer/spirv/builder_kill_test.cc
     writer/spirv/builder_literal_test.cc
     writer/spirv/builder_loop_test.cc
     writer/spirv/builder_return_test.cc
@@ -501,7 +497,6 @@
     writer/wgsl/generator_impl_identifier_test.cc
     writer/wgsl/generator_impl_if_test.cc
     writer/wgsl/generator_impl_import_test.cc
-    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_return_test.cc
@@ -532,7 +527,6 @@
     writer/msl/generator_impl_identifier_test.cc
     writer/msl/generator_impl_if_test.cc
     writer/msl/generator_impl_import_test.cc
-    writer/msl/generator_impl_kill_test.cc
     writer/msl/generator_impl_loop_test.cc
     writer/msl/generator_impl_member_accessor_test.cc
     writer/msl/generator_impl_module_constant_test.cc
diff --git a/src/ast/case_statement_test.cc b/src/ast/case_statement_test.cc
index 89d34a0..6d68db8 100644
--- a/src/ast/case_statement_test.cc
+++ b/src/ast/case_statement_test.cc
@@ -15,8 +15,8 @@
 #include "src/ast/case_statement.h"
 
 #include "gtest/gtest.h"
+#include "src/ast/discard_statement.h"
 #include "src/ast/if_statement.h"
-#include "src/ast/kill_statement.h"
 #include "src/ast/sint_literal.h"
 #include "src/ast/type/i32_type.h"
 #include "src/ast/type/u32_type.h"
@@ -35,16 +35,16 @@
   b.push_back(std::make_unique<SintLiteral>(&i32, 2));
 
   StatementList stmts;
-  stmts.push_back(std::make_unique<KillStatement>());
+  stmts.push_back(std::make_unique<DiscardStatement>());
 
   auto* int_ptr = b.back().get();
-  auto* kill_ptr = stmts[0].get();
+  auto* discard_ptr = stmts[0].get();
 
   CaseStatement c(std::move(b), std::move(stmts));
   ASSERT_EQ(c.selectors().size(), 1u);
   EXPECT_EQ(c.selectors()[0].get(), int_ptr);
   ASSERT_EQ(c.body().size(), 1u);
-  EXPECT_EQ(c.body()[0].get(), kill_ptr);
+  EXPECT_EQ(c.body()[0].get(), discard_ptr);
 }
 
 TEST_F(CaseStatementTest, Creation_u32) {
@@ -54,16 +54,16 @@
   b.push_back(std::make_unique<UintLiteral>(&u32, 2));
 
   StatementList stmts;
-  stmts.push_back(std::make_unique<KillStatement>());
+  stmts.push_back(std::make_unique<DiscardStatement>());
 
   auto* int_ptr = b.back().get();
-  auto* kill_ptr = stmts[0].get();
+  auto* discard_ptr = stmts[0].get();
 
   CaseStatement c(std::move(b), std::move(stmts));
   ASSERT_EQ(c.selectors().size(), 1u);
   EXPECT_EQ(c.selectors()[0].get(), int_ptr);
   ASSERT_EQ(c.body().size(), 1u);
-  EXPECT_EQ(c.body()[0].get(), kill_ptr);
+  EXPECT_EQ(c.body()[0].get(), discard_ptr);
 }
 
 TEST_F(CaseStatementTest, Creation_WithSource) {
@@ -72,7 +72,7 @@
   b.push_back(std::make_unique<SintLiteral>(&i32, 2));
 
   StatementList stmts;
-  stmts.push_back(std::make_unique<KillStatement>());
+  stmts.push_back(std::make_unique<DiscardStatement>());
 
   CaseStatement c(Source{20, 2}, std::move(b), std::move(stmts));
   auto src = c.source();
@@ -82,7 +82,7 @@
 
 TEST_F(CaseStatementTest, IsDefault_WithoutSelectors) {
   StatementList stmts;
-  stmts.push_back(std::make_unique<KillStatement>());
+  stmts.push_back(std::make_unique<DiscardStatement>());
 
   CaseStatement c;
   c.set_body(std::move(stmts));
@@ -115,7 +115,7 @@
   b.push_back(std::make_unique<SintLiteral>(&i32, 2));
 
   StatementList stmts;
-  stmts.push_back(std::make_unique<KillStatement>());
+  stmts.push_back(std::make_unique<DiscardStatement>());
   stmts.push_back(nullptr);
 
   CaseStatement c(std::move(b), std::move(stmts));
@@ -140,13 +140,13 @@
   b.push_back(std::make_unique<SintLiteral>(&i32, -2));
 
   StatementList stmts;
-  stmts.push_back(std::make_unique<KillStatement>());
+  stmts.push_back(std::make_unique<DiscardStatement>());
   CaseStatement c({std::move(b)}, std::move(stmts));
 
   std::ostringstream out;
   c.to_str(out, 2);
   EXPECT_EQ(out.str(), R"(  Case -2{
-    Kill{}
+    Discard{}
   }
 )");
 }
@@ -157,13 +157,13 @@
   b.push_back(std::make_unique<UintLiteral>(&u32, 2));
 
   StatementList stmts;
-  stmts.push_back(std::make_unique<KillStatement>());
+  stmts.push_back(std::make_unique<DiscardStatement>());
   CaseStatement c({std::move(b)}, std::move(stmts));
 
   std::ostringstream out;
   c.to_str(out, 2);
   EXPECT_EQ(out.str(), R"(  Case 2{
-    Kill{}
+    Discard{}
   }
 )");
 }
@@ -175,26 +175,26 @@
   b.push_back(std::make_unique<SintLiteral>(&i32, 1));
   b.push_back(std::make_unique<SintLiteral>(&i32, 2));
   StatementList stmts;
-  stmts.push_back(std::make_unique<KillStatement>());
+  stmts.push_back(std::make_unique<DiscardStatement>());
   CaseStatement c(std::move(b), std::move(stmts));
 
   std::ostringstream out;
   c.to_str(out, 2);
   EXPECT_EQ(out.str(), R"(  Case 1, 2{
-    Kill{}
+    Discard{}
   }
 )");
 }
 
 TEST_F(CaseStatementTest, ToStr_WithoutSelectors) {
   StatementList stmts;
-  stmts.push_back(std::make_unique<KillStatement>());
+  stmts.push_back(std::make_unique<DiscardStatement>());
   CaseStatement c(CaseSelectorList{}, std::move(stmts));
 
   std::ostringstream out;
   c.to_str(out, 2);
   EXPECT_EQ(out.str(), R"(  Default{
-    Kill{}
+    Discard{}
   }
 )");
 }
diff --git a/src/ast/else_statement_test.cc b/src/ast/else_statement_test.cc
index 05d04cb..9b729e8 100644
--- a/src/ast/else_statement_test.cc
+++ b/src/ast/else_statement_test.cc
@@ -16,8 +16,8 @@
 
 #include "gtest/gtest.h"
 #include "src/ast/bool_literal.h"
+#include "src/ast/discard_statement.h"
 #include "src/ast/if_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<KillStatement>());
+  body.push_back(std::make_unique<DiscardStatement>());
 
   auto* cond_ptr = cond.get();
-  auto* kill_ptr = body[0].get();
+  auto* discard_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(), kill_ptr);
+  EXPECT_EQ(e.body()[0].get(), discard_ptr);
 }
 
 TEST_F(ElseStatementTest, Creation_WithSource) {
@@ -75,7 +75,7 @@
 
 TEST_F(ElseStatementTest, IsValid_WithBody) {
   StatementList body;
-  body.push_back(std::make_unique<KillStatement>());
+  body.push_back(std::make_unique<DiscardStatement>());
 
   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<KillStatement>());
+  body.push_back(std::make_unique<DiscardStatement>());
   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<KillStatement>());
+  body.push_back(std::make_unique<DiscardStatement>());
 
   ElseStatement e(std::move(cond), std::move(body));
   std::ostringstream out;
@@ -119,7 +119,7 @@
       ScalarConstructor{true}
     )
     {
-      Kill{}
+      Discard{}
     }
   }
 )");
@@ -127,14 +127,14 @@
 
 TEST_F(ElseStatementTest, ToStr_NoCondition) {
   StatementList body;
-  body.push_back(std::make_unique<KillStatement>());
+  body.push_back(std::make_unique<DiscardStatement>());
 
   ElseStatement e(std::move(body));
   std::ostringstream out;
   e.to_str(out, 2);
   EXPECT_EQ(out.str(), R"(  Else{
     {
-      Kill{}
+      Discard{}
     }
   }
 )");
diff --git a/src/ast/function_test.cc b/src/ast/function_test.cc
index 72c39e1..a2c6471 100644
--- a/src/ast/function_test.cc
+++ b/src/ast/function_test.cc
@@ -17,7 +17,7 @@
 #include "gtest/gtest.h"
 #include "src/ast/builtin_decoration.h"
 #include "src/ast/decorated_variable.h"
-#include "src/ast/kill_statement.h"
+#include "src/ast/discard_statement.h"
 #include "src/ast/location_decoration.h"
 #include "src/ast/pipeline_stage.h"
 #include "src/ast/type/f32_type.h"
@@ -189,7 +189,7 @@
       std::make_unique<Variable>("var", StorageClass::kNone, &i32));
 
   StatementList body;
-  body.push_back(std::make_unique<KillStatement>());
+  body.push_back(std::make_unique<DiscardStatement>());
 
   Function f("func", std::move(params), &void_type);
   f.set_body(std::move(body));
@@ -252,7 +252,7 @@
       std::make_unique<Variable>("var", StorageClass::kNone, &i32));
 
   StatementList body;
-  body.push_back(std::make_unique<KillStatement>());
+  body.push_back(std::make_unique<DiscardStatement>());
   body.push_back(nullptr);
 
   Function f("func", std::move(params), &void_type);
@@ -269,7 +269,7 @@
       std::make_unique<Variable>("var", StorageClass::kNone, &i32));
 
   StatementList body;
-  body.push_back(std::make_unique<KillStatement>());
+  body.push_back(std::make_unique<DiscardStatement>());
   body.push_back(nullptr);
 
   Function f("func", std::move(params), &void_type);
@@ -282,7 +282,7 @@
   type::I32Type i32;
 
   StatementList body;
-  body.push_back(std::make_unique<KillStatement>());
+  body.push_back(std::make_unique<DiscardStatement>());
 
   Function f("func", {}, &void_type);
   f.set_body(std::move(body));
@@ -292,7 +292,7 @@
   EXPECT_EQ(out.str(), R"(  Function func -> __void
   ()
   {
-    Kill{}
+    Discard{}
   }
 )");
 }
@@ -306,7 +306,7 @@
       std::make_unique<Variable>("var", StorageClass::kNone, &i32));
 
   StatementList body;
-  body.push_back(std::make_unique<KillStatement>());
+  body.push_back(std::make_unique<DiscardStatement>());
 
   Function f("func", std::move(params), &void_type);
   f.set_body(std::move(body));
@@ -322,7 +322,7 @@
     }
   )
   {
-    Kill{}
+    Discard{}
   }
 )");
 }
diff --git a/src/ast/if_statement_test.cc b/src/ast/if_statement_test.cc
index e2fe840..087ebf7 100644
--- a/src/ast/if_statement_test.cc
+++ b/src/ast/if_statement_test.cc
@@ -15,8 +15,8 @@
 #include "src/ast/if_statement.h"
 
 #include "gtest/gtest.h"
+#include "src/ast/discard_statement.h"
 #include "src/ast/identifier_expression.h"
-#include "src/ast/kill_statement.h"
 
 namespace tint {
 namespace ast {
@@ -27,7 +27,7 @@
 TEST_F(IfStatementTest, Creation) {
   auto cond = std::make_unique<IdentifierExpression>("cond");
   StatementList body;
-  body.push_back(std::make_unique<KillStatement>());
+  body.push_back(std::make_unique<DiscardStatement>());
 
   auto* cond_ptr = cond.get();
   auto* stmt_ptr = body[0].get();
@@ -41,7 +41,7 @@
 TEST_F(IfStatementTest, Creation_WithSource) {
   auto cond = std::make_unique<IdentifierExpression>("cond");
   StatementList body;
-  body.push_back(std::make_unique<KillStatement>());
+  body.push_back(std::make_unique<DiscardStatement>());
 
   IfStatement stmt(Source{20, 2}, std::move(cond), std::move(body));
   auto src = stmt.source();
@@ -57,7 +57,7 @@
 TEST_F(IfStatementTest, IsValid) {
   auto cond = std::make_unique<IdentifierExpression>("cond");
   StatementList body;
-  body.push_back(std::make_unique<KillStatement>());
+  body.push_back(std::make_unique<DiscardStatement>());
 
   IfStatement stmt(std::move(cond), std::move(body));
   EXPECT_TRUE(stmt.IsValid());
@@ -66,7 +66,7 @@
 TEST_F(IfStatementTest, IsValid_WithElseStatements) {
   auto cond = std::make_unique<IdentifierExpression>("cond");
   StatementList body;
-  body.push_back(std::make_unique<KillStatement>());
+  body.push_back(std::make_unique<DiscardStatement>());
 
   ElseStatementList else_stmts;
   else_stmts.push_back(std::make_unique<ElseStatement>());
@@ -80,7 +80,7 @@
 
 TEST_F(IfStatementTest, IsValid_MissingCondition) {
   StatementList body;
-  body.push_back(std::make_unique<KillStatement>());
+  body.push_back(std::make_unique<DiscardStatement>());
 
   IfStatement stmt(nullptr, std::move(body));
   EXPECT_FALSE(stmt.IsValid());
@@ -89,7 +89,7 @@
 TEST_F(IfStatementTest, IsValid_InvalidCondition) {
   auto cond = std::make_unique<IdentifierExpression>("");
   StatementList body;
-  body.push_back(std::make_unique<KillStatement>());
+  body.push_back(std::make_unique<DiscardStatement>());
 
   IfStatement stmt(std::move(cond), std::move(body));
   EXPECT_FALSE(stmt.IsValid());
@@ -98,7 +98,7 @@
 TEST_F(IfStatementTest, IsValid_NullBodyStatement) {
   auto cond = std::make_unique<IdentifierExpression>("cond");
   StatementList body;
-  body.push_back(std::make_unique<KillStatement>());
+  body.push_back(std::make_unique<DiscardStatement>());
   body.push_back(nullptr);
 
   IfStatement stmt(std::move(cond), std::move(body));
@@ -108,7 +108,7 @@
 TEST_F(IfStatementTest, IsValid_InvalidBodyStatement) {
   auto cond = std::make_unique<IdentifierExpression>("cond");
   StatementList body;
-  body.push_back(std::make_unique<KillStatement>());
+  body.push_back(std::make_unique<DiscardStatement>());
   body.push_back(std::make_unique<IfStatement>());
 
   IfStatement stmt(std::move(cond), std::move(body));
@@ -118,7 +118,7 @@
 TEST_F(IfStatementTest, IsValid_NullElseStatement) {
   auto cond = std::make_unique<IdentifierExpression>("cond");
   StatementList body;
-  body.push_back(std::make_unique<KillStatement>());
+  body.push_back(std::make_unique<DiscardStatement>());
 
   ElseStatementList else_stmts;
   else_stmts.push_back(std::make_unique<ElseStatement>());
@@ -134,7 +134,7 @@
 TEST_F(IfStatementTest, IsValid_InvalidElseStatement) {
   auto cond = std::make_unique<IdentifierExpression>("cond");
   StatementList body;
-  body.push_back(std::make_unique<KillStatement>());
+  body.push_back(std::make_unique<DiscardStatement>());
 
   ElseStatementList else_stmts;
   else_stmts.push_back(std::make_unique<ElseStatement>());
@@ -148,7 +148,7 @@
 TEST_F(IfStatementTest, IsValid_MultipleElseWiththoutCondition) {
   auto cond = std::make_unique<IdentifierExpression>("cond");
   StatementList body;
-  body.push_back(std::make_unique<KillStatement>());
+  body.push_back(std::make_unique<DiscardStatement>());
 
   ElseStatementList else_stmts;
   else_stmts.push_back(std::make_unique<ElseStatement>());
@@ -162,7 +162,7 @@
 TEST_F(IfStatementTest, IsValid_ElseNotLast) {
   auto cond = std::make_unique<IdentifierExpression>("cond");
   StatementList body;
-  body.push_back(std::make_unique<KillStatement>());
+  body.push_back(std::make_unique<DiscardStatement>());
 
   ElseStatementList else_stmts;
   else_stmts.push_back(std::make_unique<ElseStatement>());
@@ -177,7 +177,7 @@
 TEST_F(IfStatementTest, ToStr) {
   auto cond = std::make_unique<IdentifierExpression>("cond");
   StatementList body;
-  body.push_back(std::make_unique<KillStatement>());
+  body.push_back(std::make_unique<DiscardStatement>());
 
   IfStatement stmt(std::move(cond), std::move(body));
 
@@ -188,7 +188,7 @@
       Identifier{cond}
     )
     {
-      Kill{}
+      Discard{}
     }
   }
 )");
@@ -197,14 +197,14 @@
 TEST_F(IfStatementTest, ToStr_WithElseStatements) {
   auto cond = std::make_unique<IdentifierExpression>("cond");
   StatementList body;
-  body.push_back(std::make_unique<KillStatement>());
+  body.push_back(std::make_unique<DiscardStatement>());
 
   StatementList else_if_body;
-  else_if_body.push_back(std::make_unique<KillStatement>());
+  else_if_body.push_back(std::make_unique<DiscardStatement>());
 
   StatementList else_body;
-  else_body.push_back(std::make_unique<KillStatement>());
-  else_body.push_back(std::make_unique<KillStatement>());
+  else_body.push_back(std::make_unique<DiscardStatement>());
+  else_body.push_back(std::make_unique<DiscardStatement>());
 
   ElseStatementList else_stmts;
   else_stmts.push_back(std::make_unique<ElseStatement>());
@@ -223,7 +223,7 @@
       Identifier{cond}
     )
     {
-      Kill{}
+      Discard{}
     }
   }
   Else{
@@ -231,13 +231,13 @@
       Identifier{ident}
     )
     {
-      Kill{}
+      Discard{}
     }
   }
   Else{
     {
-      Kill{}
-      Kill{}
+      Discard{}
+      Discard{}
     }
   }
 )");
diff --git a/src/ast/kill_statement.cc b/src/ast/kill_statement.cc
deleted file mode 100644
index 23612fc..0000000
--- a/src/ast/kill_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/kill_statement.h"
-
-namespace tint {
-namespace ast {
-
-KillStatement::KillStatement() : Statement() {}
-
-KillStatement::KillStatement(const Source& source) : Statement(source) {}
-
-KillStatement::~KillStatement() = default;
-
-bool KillStatement::IsKill() const {
-  return true;
-}
-
-bool KillStatement::IsValid() const {
-  return true;
-}
-
-void KillStatement::to_str(std::ostream& out, size_t indent) const {
-  make_indent(out, indent);
-  out << "Kill{}" << std::endl;
-}
-
-}  // namespace ast
-}  // namespace tint
diff --git a/src/ast/kill_statement.h b/src/ast/kill_statement.h
deleted file mode 100644
index 78d13e4..0000000
--- a/src/ast/kill_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_KILL_STATEMENT_H_
-#define SRC_AST_KILL_STATEMENT_H_
-
-#include "src/ast/statement.h"
-
-namespace tint {
-namespace ast {
-
-/// A kill statement
-class KillStatement : public Statement {
- public:
-  /// Constructor
-  KillStatement();
-  /// Constructor
-  /// @param source the kill statement source
-  explicit KillStatement(const Source& source);
-  /// Move constructor
-  KillStatement(KillStatement&&) = default;
-  ~KillStatement() override;
-
-  /// @returns true if this is a kill statement
-  bool IsKill() 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:
-  KillStatement(const KillStatement&) = delete;
-};
-
-}  // namespace ast
-}  // namespace tint
-
-#endif  // SRC_AST_KILL_STATEMENT_H_
diff --git a/src/ast/kill_statement_test.cc b/src/ast/kill_statement_test.cc
deleted file mode 100644
index 653b6ad..0000000
--- a/src/ast/kill_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/kill_statement.h"
-
-#include <sstream>
-
-#include "gtest/gtest.h"
-
-namespace tint {
-namespace ast {
-namespace {
-
-using KillStatementTest = testing::Test;
-
-TEST_F(KillStatementTest, Creation) {
-  KillStatement k;
-  EXPECT_EQ(k.line(), 0u);
-  EXPECT_EQ(k.column(), 0u);
-}
-
-TEST_F(KillStatementTest, Creation_WithSource) {
-  KillStatement k(Source{20, 2});
-  EXPECT_EQ(k.line(), 20u);
-  EXPECT_EQ(k.column(), 2u);
-}
-
-TEST_F(KillStatementTest, IsKill) {
-  KillStatement k;
-  EXPECT_TRUE(k.IsKill());
-}
-
-TEST_F(KillStatementTest, IsValid) {
-  KillStatement k;
-  EXPECT_TRUE(k.IsValid());
-}
-
-TEST_F(KillStatementTest, ToStr) {
-  KillStatement k;
-  std::ostringstream out;
-  k.to_str(out, 2);
-  EXPECT_EQ(out.str(), R"(  Kill{}
-)");
-}
-
-}  // namespace
-}  // namespace ast
-}  // namespace tint
diff --git a/src/ast/loop_statement_test.cc b/src/ast/loop_statement_test.cc
index d7f2187..dfde6f3 100644
--- a/src/ast/loop_statement_test.cc
+++ b/src/ast/loop_statement_test.cc
@@ -18,8 +18,8 @@
 #include <sstream>
 
 #include "gtest/gtest.h"
+#include "src/ast/discard_statement.h"
 #include "src/ast/if_statement.h"
-#include "src/ast/kill_statement.h"
 
 namespace tint {
 namespace ast {
@@ -29,11 +29,11 @@
 
 TEST_F(LoopStatementTest, Creation) {
   StatementList body;
-  body.push_back(std::make_unique<KillStatement>());
+  body.push_back(std::make_unique<DiscardStatement>());
   auto* b_ptr = body[0].get();
 
   StatementList continuing;
-  continuing.push_back(std::make_unique<KillStatement>());
+  continuing.push_back(std::make_unique<DiscardStatement>());
   auto* c_ptr = continuing[0].get();
 
   LoopStatement l(std::move(body), std::move(continuing));
@@ -45,10 +45,10 @@
 
 TEST_F(LoopStatementTest, Creation_WithSource) {
   StatementList body;
-  body.push_back(std::make_unique<KillStatement>());
+  body.push_back(std::make_unique<DiscardStatement>());
 
   StatementList continuing;
-  continuing.push_back(std::make_unique<KillStatement>());
+  continuing.push_back(std::make_unique<DiscardStatement>());
 
   LoopStatement l(Source{20, 2}, std::move(body), std::move(continuing));
   auto src = l.source();
@@ -63,7 +63,7 @@
 
 TEST_F(LoopStatementTest, HasContinuing_WithoutContinuing) {
   StatementList body;
-  body.push_back(std::make_unique<KillStatement>());
+  body.push_back(std::make_unique<DiscardStatement>());
 
   LoopStatement l(std::move(body), {});
   EXPECT_FALSE(l.has_continuing());
@@ -71,10 +71,10 @@
 
 TEST_F(LoopStatementTest, HasContinuing_WithContinuing) {
   StatementList body;
-  body.push_back(std::make_unique<KillStatement>());
+  body.push_back(std::make_unique<DiscardStatement>());
 
   StatementList continuing;
-  continuing.push_back(std::make_unique<KillStatement>());
+  continuing.push_back(std::make_unique<DiscardStatement>());
 
   LoopStatement l(std::move(body), std::move(continuing));
   EXPECT_TRUE(l.has_continuing());
@@ -82,10 +82,10 @@
 
 TEST_F(LoopStatementTest, IsValid) {
   StatementList body;
-  body.push_back(std::make_unique<KillStatement>());
+  body.push_back(std::make_unique<DiscardStatement>());
 
   StatementList continuing;
-  continuing.push_back(std::make_unique<KillStatement>());
+  continuing.push_back(std::make_unique<DiscardStatement>());
 
   LoopStatement l(std::move(body), std::move(continuing));
   EXPECT_TRUE(l.IsValid());
@@ -93,7 +93,7 @@
 
 TEST_F(LoopStatementTest, IsValid_WithoutContinuing) {
   StatementList body;
-  body.push_back(std::make_unique<KillStatement>());
+  body.push_back(std::make_unique<DiscardStatement>());
 
   LoopStatement l(std::move(body), {});
   EXPECT_TRUE(l.IsValid());
@@ -106,11 +106,11 @@
 
 TEST_F(LoopStatementTest, IsValid_NullBodyStatement) {
   StatementList body;
-  body.push_back(std::make_unique<KillStatement>());
+  body.push_back(std::make_unique<DiscardStatement>());
   body.push_back(nullptr);
 
   StatementList continuing;
-  continuing.push_back(std::make_unique<KillStatement>());
+  continuing.push_back(std::make_unique<DiscardStatement>());
 
   LoopStatement l(std::move(body), std::move(continuing));
   EXPECT_FALSE(l.IsValid());
@@ -118,11 +118,11 @@
 
 TEST_F(LoopStatementTest, IsValid_InvalidBodyStatement) {
   StatementList body;
-  body.push_back(std::make_unique<KillStatement>());
+  body.push_back(std::make_unique<DiscardStatement>());
   body.push_back(std::make_unique<IfStatement>());
 
   StatementList continuing;
-  continuing.push_back(std::make_unique<KillStatement>());
+  continuing.push_back(std::make_unique<DiscardStatement>());
 
   LoopStatement l(std::move(body), std::move(continuing));
   EXPECT_FALSE(l.IsValid());
@@ -130,10 +130,10 @@
 
 TEST_F(LoopStatementTest, IsValid_NullContinuingStatement) {
   StatementList body;
-  body.push_back(std::make_unique<KillStatement>());
+  body.push_back(std::make_unique<DiscardStatement>());
 
   StatementList continuing;
-  continuing.push_back(std::make_unique<KillStatement>());
+  continuing.push_back(std::make_unique<DiscardStatement>());
   continuing.push_back(nullptr);
 
   LoopStatement l(std::move(body), std::move(continuing));
@@ -142,10 +142,10 @@
 
 TEST_F(LoopStatementTest, IsValid_InvalidContinuingStatement) {
   StatementList body;
-  body.push_back(std::make_unique<KillStatement>());
+  body.push_back(std::make_unique<DiscardStatement>());
 
   StatementList continuing;
-  continuing.push_back(std::make_unique<KillStatement>());
+  continuing.push_back(std::make_unique<DiscardStatement>());
   continuing.push_back(std::make_unique<IfStatement>());
 
   LoopStatement l(std::move(body), std::move(continuing));
@@ -154,31 +154,31 @@
 
 TEST_F(LoopStatementTest, ToStr) {
   StatementList body;
-  body.push_back(std::make_unique<KillStatement>());
+  body.push_back(std::make_unique<DiscardStatement>());
 
   LoopStatement l(std::move(body), {});
   std::ostringstream out;
   l.to_str(out, 2);
   EXPECT_EQ(out.str(), R"(  Loop{
-    Kill{}
+    Discard{}
   }
 )");
 }
 
 TEST_F(LoopStatementTest, ToStr_WithContinuing) {
   StatementList body;
-  body.push_back(std::make_unique<KillStatement>());
+  body.push_back(std::make_unique<DiscardStatement>());
 
   StatementList continuing;
-  continuing.push_back(std::make_unique<KillStatement>());
+  continuing.push_back(std::make_unique<DiscardStatement>());
 
   LoopStatement l(std::move(body), std::move(continuing));
   std::ostringstream out;
   l.to_str(out, 2);
   EXPECT_EQ(out.str(), R"(  Loop{
-    Kill{}
+    Discard{}
     continuing {
-      Kill{}
+      Discard{}
     }
   }
 )");
diff --git a/src/ast/statement.cc b/src/ast/statement.cc
index af944ae..43441da 100644
--- a/src/ast/statement.cc
+++ b/src/ast/statement.cc
@@ -25,7 +25,6 @@
 #include "src/ast/else_statement.h"
 #include "src/ast/fallthrough_statement.h"
 #include "src/ast/if_statement.h"
-#include "src/ast/kill_statement.h"
 #include "src/ast/loop_statement.h"
 #include "src/ast/return_statement.h"
 #include "src/ast/switch_statement.h"
@@ -78,10 +77,6 @@
   return false;
 }
 
-bool Statement::IsKill() const {
-  return false;
-}
-
 bool Statement::IsLoop() const {
   return false;
 }
@@ -143,11 +138,6 @@
   return static_cast<const IfStatement*>(this);
 }
 
-const KillStatement* Statement::AsKill() const {
-  assert(IsKill());
-  return static_cast<const KillStatement*>(this);
-}
-
 const LoopStatement* Statement::AsLoop() const {
   assert(IsLoop());
   return static_cast<const LoopStatement*>(this);
@@ -213,11 +203,6 @@
   return static_cast<IfStatement*>(this);
 }
 
-KillStatement* Statement::AsKill() {
-  assert(IsKill());
-  return static_cast<KillStatement*>(this);
-}
-
 LoopStatement* Statement::AsLoop() {
   assert(IsLoop());
   return static_cast<LoopStatement*>(this);
diff --git a/src/ast/statement.h b/src/ast/statement.h
index b1511ab..4f259bb 100644
--- a/src/ast/statement.h
+++ b/src/ast/statement.h
@@ -32,7 +32,6 @@
 class ElseStatement;
 class FallthroughStatement;
 class IfStatement;
-class KillStatement;
 class LoopStatement;
 class ReturnStatement;
 class SwitchStatement;
@@ -61,8 +60,6 @@
   virtual bool IsFallthrough() const;
   /// @returns true if this is an if statement
   virtual bool IsIf() const;
-  /// @returns true if this is a kill statement
-  virtual bool IsKill() const;
   /// @returns true if this is a loop statement
   virtual bool IsLoop() const;
   /// @returns true if this is a return statement
@@ -90,8 +87,6 @@
   const FallthroughStatement* AsFallthrough() const;
   /// @returns the statement as a const if statement
   const IfStatement* AsIf() const;
-  /// @returns the statement as a const kill statement
-  const KillStatement* AsKill() const;
   /// @returns the statement as a const loop statement
   const LoopStatement* AsLoop() const;
   /// @returns the statement as a const return statement
@@ -119,8 +114,6 @@
   FallthroughStatement* AsFallthrough();
   /// @returns the statement as a if statement
   IfStatement* AsIf();
-  /// @returns the statement as a kill statement
-  KillStatement* AsKill();
   /// @returns the statement as a loop statement
   LoopStatement* AsLoop();
   /// @returns the statement as a return statement
diff --git a/src/reader/spirv/function.cc b/src/reader/spirv/function.cc
index 46dcec2..844cc01 100644
--- a/src/reader/spirv/function.cc
+++ b/src/reader/spirv/function.cc
@@ -2192,7 +2192,7 @@
     }
       return true;
     case SpvOpKill:
-      // For now, assume SPIR-V OpKill has same semantics as WGSL kill.
+      // For now, assume SPIR-V OpKill has same semantics as WGSL discard.
       // TODO(dneto): https://github.com/gpuweb/gpuweb/issues/676
       AddStatement(std::make_unique<ast::DiscardStatement>());
       return true;
diff --git a/src/reader/wgsl/lexer.cc b/src/reader/wgsl/lexer.cc
index c1263b7..224d30b 100644
--- a/src/reader/wgsl/lexer.cc
+++ b/src/reader/wgsl/lexer.cc
@@ -527,8 +527,6 @@
     return {Token::Type::kImport, source, "import"};
   if (str == "in")
     return {Token::Type::kIn, source, "in"};
-  if (str == "kill")
-    return {Token::Type::kKill, source, "kill"};
   if (str == "location")
     return {Token::Type::kLocation, source, "location"};
   if (str == "loop")
diff --git a/src/reader/wgsl/lexer_test.cc b/src/reader/wgsl/lexer_test.cc
index aa731af..3a19569 100644
--- a/src/reader/wgsl/lexer_test.cc
+++ b/src/reader/wgsl/lexer_test.cc
@@ -440,7 +440,6 @@
                     TokenData{"image", Token::Type::kImage},
                     TokenData{"import", Token::Type::kImport},
                     TokenData{"in", Token::Type::kIn},
-                    TokenData{"kill", Token::Type::kKill},
                     TokenData{"location", Token::Type::kLocation},
                     TokenData{"loop", Token::Type::kLoop},
                     TokenData{"mat2x2", Token::Type::kMat2x2},
diff --git a/src/reader/wgsl/parser_impl.cc b/src/reader/wgsl/parser_impl.cc
index dd4a625..b61d721 100644
--- a/src/reader/wgsl/parser_impl.cc
+++ b/src/reader/wgsl/parser_impl.cc
@@ -35,7 +35,6 @@
 #include "src/ast/float_literal.h"
 #include "src/ast/identifier_expression.h"
 #include "src/ast/if_statement.h"
-#include "src/ast/kill_statement.h"
 #include "src/ast/location_decoration.h"
 #include "src/ast/member_accessor_expression.h"
 #include "src/ast/return_statement.h"
@@ -1428,7 +1427,6 @@
 //   | break_stmt SEMICOLON
 //   | continue_stmt SEMICOLON
 //   | DISCARD SEMICOLON
-//   | KILL SEMICOLON
 //   | assignment_stmt SEMICOLON
 std::unique_ptr<ast::Statement> ParserImpl::statement() {
   auto t = peek();
@@ -1527,18 +1525,6 @@
     return std::make_unique<ast::DiscardStatement>(source);
   }
 
-  if (t.IsKill()) {
-    auto source = t.source();
-    next();  // Consume the peek
-
-    t = next();
-    if (!t.IsSemicolon()) {
-      set_error(t, "missing ;");
-      return nullptr;
-    }
-    return std::make_unique<ast::KillStatement>(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 90e0d73..ae0952b 100644
--- a/src/reader/wgsl/parser_impl_body_stmt_test.cc
+++ b/src/reader/wgsl/parser_impl_body_stmt_test.cc
@@ -23,13 +23,13 @@
 
 TEST_F(ParserImplTest, BodyStmt) {
   auto* p = parser(R"({
-  kill;
+  discard;
   return 1 + b / 2;
 })");
   auto e = p->body_stmt();
   ASSERT_FALSE(p->has_error()) << p->error();
   ASSERT_EQ(e.size(), 2u);
-  EXPECT_TRUE(e[0]->IsKill());
+  EXPECT_TRUE(e[0]->IsDiscard());
   EXPECT_TRUE(e[1]->IsReturn());
 }
 
diff --git a/src/reader/wgsl/parser_impl_continuing_stmt_test.cc b/src/reader/wgsl/parser_impl_continuing_stmt_test.cc
index 9154312..d67b326 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 { kill; }");
+  auto* p = parser("continuing { discard; }");
   auto e = p->continuing_stmt();
   ASSERT_FALSE(p->has_error()) << p->error();
   ASSERT_EQ(e.size(), 1u);
-  ASSERT_TRUE(e[0]->IsKill());
+  ASSERT_TRUE(e[0]->IsDiscard());
 }
 
 TEST_F(ParserImplTest, ContinuingStmt_InvalidBody) {
-  auto* p = parser("continuing { kill }");
+  auto* p = parser("continuing { discard }");
   auto e = p->continuing_stmt();
   ASSERT_TRUE(p->has_error());
   ASSERT_EQ(e.size(), 0u);
-  EXPECT_EQ(p->error(), "1:19: missing ;");
+  EXPECT_EQ(p->error(), "1:22: 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 71bd39b..f602714 100644
--- a/src/reader/wgsl/parser_impl_loop_stmt_test.cc
+++ b/src/reader/wgsl/parser_impl_loop_stmt_test.cc
@@ -22,28 +22,28 @@
 namespace {
 
 TEST_F(ParserImplTest, LoopStmt_BodyNoContinuing) {
-  auto* p = parser("loop { kill; }");
+  auto* p = parser("loop { discard; }");
   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]->IsKill());
+  EXPECT_TRUE(e->body()[0]->IsDiscard());
 
   EXPECT_EQ(e->continuing().size(), 0u);
 }
 
 TEST_F(ParserImplTest, LoopStmt_BodyWithContinuing) {
-  auto* p = parser("loop { kill; continuing { kill; }}");
+  auto* p = parser("loop { discard; continuing { discard; }}");
   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]->IsKill());
+  EXPECT_TRUE(e->body()[0]->IsDiscard());
 
   EXPECT_EQ(e->continuing().size(), 1u);
-  EXPECT_TRUE(e->continuing()[0]->IsKill());
+  EXPECT_TRUE(e->continuing()[0]->IsDiscard());
 }
 
 TEST_F(ParserImplTest, LoopStmt_NoBodyNoContinuing) {
@@ -56,17 +56,17 @@
 }
 
 TEST_F(ParserImplTest, LoopStmt_NoBodyWithContinuing) {
-  auto* p = parser("loop { continuing { kill; }}");
+  auto* p = parser("loop { continuing { discard; }}");
   auto e = p->loop_stmt();
   ASSERT_FALSE(p->has_error()) << p->error();
   ASSERT_NE(e, nullptr);
   ASSERT_EQ(e->body().size(), 0u);
   ASSERT_EQ(e->continuing().size(), 1u);
-  EXPECT_TRUE(e->continuing()[0]->IsKill());
+  EXPECT_TRUE(e->continuing()[0]->IsDiscard());
 }
 
 TEST_F(ParserImplTest, LoopStmt_MissingBracketLeft) {
-  auto* p = parser("loop kill; }");
+  auto* p = parser("loop discard; }");
   auto e = p->loop_stmt();
   ASSERT_TRUE(p->has_error());
   ASSERT_EQ(e, nullptr);
@@ -74,27 +74,27 @@
 }
 
 TEST_F(ParserImplTest, LoopStmt_MissingBracketRight) {
-  auto* p = parser("loop { kill; ");
+  auto* p = parser("loop { discard; ");
   auto e = p->loop_stmt();
   ASSERT_TRUE(p->has_error());
   ASSERT_EQ(e, nullptr);
-  EXPECT_EQ(p->error(), "1:14: missing } for loop");
+  EXPECT_EQ(p->error(), "1:17: missing } for loop");
 }
 
 TEST_F(ParserImplTest, LoopStmt_InvalidStatements) {
-  auto* p = parser("loop { kill }");
+  auto* p = parser("loop { discard }");
   auto e = p->loop_stmt();
   ASSERT_TRUE(p->has_error());
   ASSERT_EQ(e, nullptr);
-  EXPECT_EQ(p->error(), "1:13: missing ;");
+  EXPECT_EQ(p->error(), "1:16: missing ;");
 }
 
 TEST_F(ParserImplTest, LoopStmt_InvalidContinuing) {
-  auto* p = parser("loop { continuing { kill }}");
+  auto* p = parser("loop { continuing { discard }}");
   auto e = p->loop_stmt();
   ASSERT_TRUE(p->has_error());
   ASSERT_EQ(e, nullptr);
-  EXPECT_EQ(p->error(), "1:26: missing ;");
+  EXPECT_EQ(p->error(), "1:29: missing ;");
 }
 
 }  // namespace
diff --git a/src/reader/wgsl/parser_impl_statement_test.cc b/src/reader/wgsl/parser_impl_statement_test.cc
index f5f06f0..451588e 100644
--- a/src/reader/wgsl/parser_impl_statement_test.cc
+++ b/src/reader/wgsl/parser_impl_statement_test.cc
@@ -142,7 +142,7 @@
 }
 
 TEST_F(ParserImplTest, Statement_Loop_Invalid) {
-  auto* p = parser("loop kill; }");
+  auto* p = parser("loop discard; }");
   auto e = p->statement();
   ASSERT_TRUE(p->has_error());
   ASSERT_EQ(e, nullptr);
@@ -205,22 +205,6 @@
   EXPECT_EQ(p->error(), "1:9: missing ;");
 }
 
-TEST_F(ParserImplTest, Statement_Kill) {
-  auto* p = parser("kill;");
-  auto e = p->statement();
-  ASSERT_FALSE(p->has_error()) << p->error();
-  EXPECT_NE(e, nullptr);
-  ASSERT_TRUE(e->IsKill());
-}
-
-TEST_F(ParserImplTest, Statement_Kill_MissingSemicolon) {
-  auto* p = parser("kill");
-  auto e = p->statement();
-  ASSERT_TRUE(p->has_error());
-  EXPECT_EQ(e, nullptr);
-  EXPECT_EQ(p->error(), "1:5: missing ;");
-}
-
 TEST_F(ParserImplTest, Statement_Discard) {
   auto* p = parser("discard;");
   auto e = p->statement();
diff --git a/src/reader/wgsl/parser_impl_statements_test.cc b/src/reader/wgsl/parser_impl_statements_test.cc
index 343d501..23082d8 100644
--- a/src/reader/wgsl/parser_impl_statements_test.cc
+++ b/src/reader/wgsl/parser_impl_statements_test.cc
@@ -23,11 +23,11 @@
 namespace {
 
 TEST_F(ParserImplTest, Statements) {
-  auto* p = parser("kill; return;");
+  auto* p = parser("discard; return;");
   auto e = p->statements();
   ASSERT_FALSE(p->has_error()) << p->error();
   ASSERT_EQ(e.size(), 2u);
-  EXPECT_TRUE(e[0]->IsKill());
+  EXPECT_TRUE(e[0]->IsDiscard());
   EXPECT_TRUE(e[1]->IsReturn());
 }
 
diff --git a/src/reader/wgsl/token.cc b/src/reader/wgsl/token.cc
index 91c489a..8b82c6f 100644
--- a/src/reader/wgsl/token.cc
+++ b/src/reader/wgsl/token.cc
@@ -163,8 +163,6 @@
       return "import";
     case Token::Type::kIn:
       return "in";
-    case Token::Type::kKill:
-      return "kill";
     case Token::Type::kLocation:
       return "location";
     case Token::Type::kLoop:
diff --git a/src/reader/wgsl/token.h b/src/reader/wgsl/token.h
index 8e2ffec..1232260 100644
--- a/src/reader/wgsl/token.h
+++ b/src/reader/wgsl/token.h
@@ -174,8 +174,6 @@
     kImport,
     /// A 'in'
     kIn,
-    /// A 'kill'
-    kKill,
     /// A 'location'
     kLocation,
     /// A 'loop'
@@ -429,8 +427,6 @@
   bool IsImport() const { return type_ == Type::kImport; }
   /// @returns true if token is a 'in'
   bool IsIn() const { return type_ == Type::kIn; }
-  /// @returns true if token is a 'kill'
-  bool IsKill() const { return type_ == Type::kKill; }
   /// @returns true if token is a 'location'
   bool IsLocation() const { return type_ == Type::kLocation; }
   /// @returns true if token is a 'loop'
diff --git a/src/type_determiner.cc b/src/type_determiner.cc
index d4a597e..0de445d 100644
--- a/src/type_determiner.cc
+++ b/src/type_determiner.cc
@@ -295,6 +295,9 @@
   if (stmt->IsContinue()) {
     return true;
   }
+  if (stmt->IsDiscard()) {
+    return true;
+  }
   if (stmt->IsElse()) {
     auto* e = stmt->AsElse();
     return DetermineResultType(e->condition()) &&
@@ -317,9 +320,6 @@
     }
     return true;
   }
-  if (stmt->IsKill()) {
-    return true;
-  }
   if (stmt->IsLoop()) {
     auto* l = stmt->AsLoop();
     return DetermineStatements(l->body()) &&
diff --git a/src/writer/msl/generator_impl.cc b/src/writer/msl/generator_impl.cc
index 248a339..21848a8 100644
--- a/src/writer/msl/generator_impl.cc
+++ b/src/writer/msl/generator_impl.cc
@@ -1397,14 +1397,6 @@
   return true;
 }
 
-bool GeneratorImpl::EmitKill(ast::KillStatement*) {
-  make_indent();
-  // TODO(dsinclair): Verify this is correct when the kill semantics are defined
-  // for WGSL (https://github.com/gpuweb/gpuweb/issues/361)
-  out_ << "discard_fragment();" << std::endl;
-  return true;
-}
-
 bool GeneratorImpl::EmitElse(ast::ElseStatement* stmt) {
   if (stmt->HasCondition()) {
     out_ << " else if (";
@@ -1528,9 +1520,6 @@
   if (stmt->IsIf()) {
     return EmitIf(stmt->AsIf());
   }
-  if (stmt->IsKill()) {
-    return EmitKill(stmt->AsKill());
-  }
   if (stmt->IsLoop()) {
     return EmitLoop(stmt->AsLoop());
   }
diff --git a/src/writer/msl/generator_impl.h b/src/writer/msl/generator_impl.h
index 5f5b31c..3f0a29a 100644
--- a/src/writer/msl/generator_impl.h
+++ b/src/writer/msl/generator_impl.h
@@ -142,10 +142,6 @@
   /// @param expr the expression
   /// @returns true if the expression was successfully emitted.
   bool EmitImportFunction(ast::CallExpression* expr);
-  /// Handles generating a kill statement
-  /// @param stmt the kill statement
-  /// @returns true if the statement was successfully emitted
-  bool EmitKill(ast::KillStatement* stmt);
   /// Handles a literal
   /// @param lit the literal to emit
   /// @returns true if the literal was successfully emitted
diff --git a/src/writer/msl/generator_impl_kill_test.cc b/src/writer/msl/generator_impl_kill_test.cc
deleted file mode 100644
index 9445d95..0000000
--- a/src/writer/msl/generator_impl_kill_test.cc
+++ /dev/null
@@ -1,41 +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/kill_statement.h"
-#include "src/ast/module.h"
-#include "src/writer/msl/generator_impl.h"
-
-namespace tint {
-namespace writer {
-namespace msl {
-namespace {
-
-using MslGeneratorImplTest = testing::Test;
-
-TEST_F(MslGeneratorImplTest, Emit_Kill) {
-  ast::KillStatement k;
-
-  ast::Module m;
-  GeneratorImpl g(&m);
-  g.increment_indent();
-
-  ASSERT_TRUE(g.EmitStatement(&k)) << g.error();
-  EXPECT_EQ(g.result(), "  discard_fragment();\n");
-}
-
-}  // namespace
-}  // namespace msl
-}  // namespace writer
-}  // namespace tint
diff --git a/src/writer/msl/generator_impl_loop_test.cc b/src/writer/msl/generator_impl_loop_test.cc
index 8fa015c..049ed51 100644
--- a/src/writer/msl/generator_impl_loop_test.cc
+++ b/src/writer/msl/generator_impl_loop_test.cc
@@ -16,9 +16,9 @@
 
 #include "gtest/gtest.h"
 #include "src/ast/assignment_statement.h"
+#include "src/ast/discard_statement.h"
 #include "src/ast/float_literal.h"
 #include "src/ast/identifier_expression.h"
-#include "src/ast/kill_statement.h"
 #include "src/ast/loop_statement.h"
 #include "src/ast/module.h"
 #include "src/ast/return_statement.h"
@@ -36,7 +36,7 @@
 
 TEST_F(MslGeneratorImplTest, Emit_Loop) {
   ast::StatementList body;
-  body.push_back(std::make_unique<ast::KillStatement>());
+  body.push_back(std::make_unique<ast::DiscardStatement>());
 
   ast::LoopStatement l(std::move(body), {});
 
@@ -53,7 +53,7 @@
 
 TEST_F(MslGeneratorImplTest, Emit_LoopWithContinuing) {
   ast::StatementList body;
-  body.push_back(std::make_unique<ast::KillStatement>());
+  body.push_back(std::make_unique<ast::DiscardStatement>());
 
   ast::StatementList continuing;
   continuing.push_back(std::make_unique<ast::ReturnStatement>());
@@ -83,7 +83,7 @@
   ast::type::F32Type f32;
 
   ast::StatementList body;
-  body.push_back(std::make_unique<ast::KillStatement>());
+  body.push_back(std::make_unique<ast::DiscardStatement>());
 
   ast::StatementList continuing;
   continuing.push_back(std::make_unique<ast::ReturnStatement>());
diff --git a/src/writer/spirv/builder.cc b/src/writer/spirv/builder.cc
index c21288f..6f18c5c 100644
--- a/src/writer/spirv/builder.cc
+++ b/src/writer/spirv/builder.cc
@@ -106,7 +106,7 @@
 
   auto* last = stmts.back().get();
   return last->IsBreak() || last->IsContinue() || last->IsDiscard() ||
-         last->IsReturn() || last->IsKill() || last->IsFallthrough();
+         last->IsReturn() || last->IsFallthrough();
 }
 
 uint32_t IndexFromName(char name) {
@@ -281,14 +281,6 @@
   return true;
 }
 
-// TODO(dsinclair): This is generating an OpKill but the semantics of kill
-// haven't been defined for WGSL yet. So, this may need to change.
-// https://github.com/gpuweb/gpuweb/issues/676
-bool Builder::GenerateKillStatement(ast::KillStatement*) {
-  push_function_inst(spv::Op::OpKill, {});
-  return true;
-}
-
 bool Builder::GenerateEntryPoint(ast::EntryPoint* ep) {
   auto name = ep->name();
   if (name.empty()) {
@@ -1834,9 +1826,6 @@
   if (stmt->IsIf()) {
     return GenerateIfStatement(stmt->AsIf());
   }
-  if (stmt->IsKill()) {
-    return GenerateKillStatement(stmt->AsKill());
-  }
   if (stmt->IsLoop()) {
     return GenerateLoopStatement(stmt->AsLoop());
   }
diff --git a/src/writer/spirv/builder.h b/src/writer/spirv/builder.h
index 28f893a..50e63fa 100644
--- a/src/writer/spirv/builder.h
+++ b/src/writer/spirv/builder.h
@@ -179,10 +179,6 @@
   /// @param stmt the statement to generate
   /// @returns true if the statement was successfully generated
   bool GenerateDiscardStatement(ast::DiscardStatement* stmt);
-  /// Generates a kill statement
-  /// @param stmt the statement to generate
-  /// @returns true if the statement was successfully generated
-  bool GenerateKillStatement(ast::KillStatement* stmt);
   /// Generates an entry point instruction
   /// @param ep the entry point
   /// @returns true if the instruction was generated, false otherwise
diff --git a/src/writer/spirv/builder_kill_test.cc b/src/writer/spirv/builder_kill_test.cc
deleted file mode 100644
index fb83986..0000000
--- a/src/writer/spirv/builder_kill_test.cc
+++ /dev/null
@@ -1,43 +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/kill_statement.h"
-#include "src/context.h"
-#include "src/type_determiner.h"
-#include "src/writer/spirv/builder.h"
-#include "src/writer/spirv/spv_dump.h"
-
-namespace tint {
-namespace writer {
-namespace spirv {
-namespace {
-
-using BuilderTest = testing::Test;
-
-TEST_F(BuilderTest, Kill) {
-  ast::KillStatement expr;
-
-  ast::Module mod;
-  Builder b(&mod);
-  b.push_function(Function{});
-  EXPECT_EQ(b.GenerateKillStatement(&expr), 1u) << b.error();
-  EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(OpKill
-)");
-}
-
-}  // namespace
-}  // namespace spirv
-}  // namespace writer
-}  // namespace tint
diff --git a/src/writer/wgsl/generator_impl.cc b/src/writer/wgsl/generator_impl.cc
index 7d6c0f4..036306b 100644
--- a/src/writer/wgsl/generator_impl.cc
+++ b/src/writer/wgsl/generator_impl.cc
@@ -652,9 +652,6 @@
   if (stmt->IsIf()) {
     return EmitIf(stmt->AsIf());
   }
-  if (stmt->IsKill()) {
-    return EmitKill(stmt->AsKill());
-  }
   if (stmt->IsLoop()) {
     return EmitLoop(stmt->AsLoop());
   }
@@ -777,12 +774,6 @@
   return true;
 }
 
-bool GeneratorImpl::EmitKill(ast::KillStatement*) {
-  make_indent();
-  out_ << "kill;" << std::endl;
-  return true;
-}
-
 bool GeneratorImpl::EmitLoop(ast::LoopStatement* stmt) {
   make_indent();
 
diff --git a/src/writer/wgsl/generator_impl.h b/src/writer/wgsl/generator_impl.h
index 69243c4..7df7262 100644
--- a/src/writer/wgsl/generator_impl.h
+++ b/src/writer/wgsl/generator_impl.h
@@ -131,10 +131,6 @@
   /// @param stmt the discard statement
   /// @returns true if the statement was successfully emitted
   bool EmitDiscard(ast::DiscardStatement* stmt);
-  /// Handles generating a kill statement
-  /// @param stmt the kill statement
-  /// @returns true if the statement was successfully emitted
-  bool EmitKill(ast::KillStatement* stmt);
   /// Handles a literal
   /// @param lit the literal to emit
   /// @returns true if the literal was successfully emitted
diff --git a/src/writer/wgsl/generator_impl_function_test.cc b/src/writer/wgsl/generator_impl_function_test.cc
index ab9ccb6..c650e93 100644
--- a/src/writer/wgsl/generator_impl_function_test.cc
+++ b/src/writer/wgsl/generator_impl_function_test.cc
@@ -13,8 +13,8 @@
 // limitations under the License.
 
 #include "gtest/gtest.h"
+#include "src/ast/discard_statement.h"
 #include "src/ast/function.h"
-#include "src/ast/kill_statement.h"
 #include "src/ast/return_statement.h"
 #include "src/ast/type/f32_type.h"
 #include "src/ast/type/i32_type.h"
@@ -31,7 +31,7 @@
 
 TEST_F(WgslGeneratorImplTest, Emit_Function) {
   ast::StatementList body;
-  body.push_back(std::make_unique<ast::KillStatement>());
+  body.push_back(std::make_unique<ast::DiscardStatement>());
   body.push_back(std::make_unique<ast::ReturnStatement>());
 
   ast::type::VoidType void_type;
@@ -43,7 +43,7 @@
 
   ASSERT_TRUE(g.EmitFunction(&func));
   EXPECT_EQ(g.result(), R"(  fn my_func() -> void {
-    kill;
+    discard;
     return;
   }
 )");
@@ -51,7 +51,7 @@
 
 TEST_F(WgslGeneratorImplTest, Emit_Function_WithParams) {
   ast::StatementList body;
-  body.push_back(std::make_unique<ast::KillStatement>());
+  body.push_back(std::make_unique<ast::DiscardStatement>());
   body.push_back(std::make_unique<ast::ReturnStatement>());
 
   ast::type::F32Type f32;
@@ -71,7 +71,7 @@
 
   ASSERT_TRUE(g.EmitFunction(&func));
   EXPECT_EQ(g.result(), R"(  fn my_func(a : f32, b : i32) -> void {
-    kill;
+    discard;
     return;
   }
 )");
diff --git a/src/writer/wgsl/generator_impl_if_test.cc b/src/writer/wgsl/generator_impl_if_test.cc
index f5a7575..2c8e340 100644
--- a/src/writer/wgsl/generator_impl_if_test.cc
+++ b/src/writer/wgsl/generator_impl_if_test.cc
@@ -13,10 +13,10 @@
 // limitations under the License.
 
 #include "gtest/gtest.h"
+#include "src/ast/discard_statement.h"
 #include "src/ast/else_statement.h"
 #include "src/ast/identifier_expression.h"
 #include "src/ast/if_statement.h"
-#include "src/ast/kill_statement.h"
 #include "src/writer/wgsl/generator_impl.h"
 
 namespace tint {
@@ -29,7 +29,7 @@
 TEST_F(WgslGeneratorImplTest, Emit_If) {
   auto cond = std::make_unique<ast::IdentifierExpression>("cond");
   ast::StatementList body;
-  body.push_back(std::make_unique<ast::KillStatement>());
+  body.push_back(std::make_unique<ast::DiscardStatement>());
 
   ast::IfStatement i(std::move(cond), std::move(body));
 
@@ -38,7 +38,7 @@
 
   ASSERT_TRUE(g.EmitStatement(&i)) << g.error();
   EXPECT_EQ(g.result(), R"(  if (cond) {
-    kill;
+    discard;
   }
 )");
 }
@@ -47,7 +47,7 @@
   auto else_cond = std::make_unique<ast::IdentifierExpression>("else_cond");
 
   ast::StatementList else_body;
-  else_body.push_back(std::make_unique<ast::KillStatement>());
+  else_body.push_back(std::make_unique<ast::DiscardStatement>());
 
   ast::ElseStatementList elses;
   elses.push_back(std::make_unique<ast::ElseStatement>(std::move(else_cond),
@@ -55,7 +55,7 @@
 
   auto cond = std::make_unique<ast::IdentifierExpression>("cond");
   ast::StatementList body;
-  body.push_back(std::make_unique<ast::KillStatement>());
+  body.push_back(std::make_unique<ast::DiscardStatement>());
 
   ast::IfStatement i(std::move(cond), std::move(body));
   i.set_else_statements(std::move(elses));
@@ -65,23 +65,23 @@
 
   ASSERT_TRUE(g.EmitStatement(&i)) << g.error();
   EXPECT_EQ(g.result(), R"(  if (cond) {
-    kill;
+    discard;
   } elseif (else_cond) {
-    kill;
+    discard;
   }
 )");
 }
 
 TEST_F(WgslGeneratorImplTest, Emit_IfWithElse) {
   ast::StatementList else_body;
-  else_body.push_back(std::make_unique<ast::KillStatement>());
+  else_body.push_back(std::make_unique<ast::DiscardStatement>());
 
   ast::ElseStatementList elses;
   elses.push_back(std::make_unique<ast::ElseStatement>(std::move(else_body)));
 
   auto cond = std::make_unique<ast::IdentifierExpression>("cond");
   ast::StatementList body;
-  body.push_back(std::make_unique<ast::KillStatement>());
+  body.push_back(std::make_unique<ast::DiscardStatement>());
 
   ast::IfStatement i(std::move(cond), std::move(body));
   i.set_else_statements(std::move(elses));
@@ -91,9 +91,9 @@
 
   ASSERT_TRUE(g.EmitStatement(&i)) << g.error();
   EXPECT_EQ(g.result(), R"(  if (cond) {
-    kill;
+    discard;
   } else {
-    kill;
+    discard;
   }
 )");
 }
@@ -102,10 +102,10 @@
   auto else_cond = std::make_unique<ast::IdentifierExpression>("else_cond");
 
   ast::StatementList else_body;
-  else_body.push_back(std::make_unique<ast::KillStatement>());
+  else_body.push_back(std::make_unique<ast::DiscardStatement>());
 
   ast::StatementList else_body_2;
-  else_body_2.push_back(std::make_unique<ast::KillStatement>());
+  else_body_2.push_back(std::make_unique<ast::DiscardStatement>());
 
   ast::ElseStatementList elses;
   elses.push_back(std::make_unique<ast::ElseStatement>(std::move(else_cond),
@@ -114,7 +114,7 @@
 
   auto cond = std::make_unique<ast::IdentifierExpression>("cond");
   ast::StatementList body;
-  body.push_back(std::make_unique<ast::KillStatement>());
+  body.push_back(std::make_unique<ast::DiscardStatement>());
 
   ast::IfStatement i(std::move(cond), std::move(body));
   i.set_else_statements(std::move(elses));
@@ -124,11 +124,11 @@
 
   ASSERT_TRUE(g.EmitStatement(&i)) << g.error();
   EXPECT_EQ(g.result(), R"(  if (cond) {
-    kill;
+    discard;
   } elseif (else_cond) {
-    kill;
+    discard;
   } else {
-    kill;
+    discard;
   }
 )");
 }
diff --git a/src/writer/wgsl/generator_impl_kill_test.cc b/src/writer/wgsl/generator_impl_kill_test.cc
deleted file mode 100644
index 6ebee1c..0000000
--- a/src/writer/wgsl/generator_impl_kill_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/kill_statement.h"
-#include "src/writer/wgsl/generator_impl.h"
-
-namespace tint {
-namespace writer {
-namespace wgsl {
-namespace {
-
-using WgslGeneratorImplTest = testing::Test;
-
-TEST_F(WgslGeneratorImplTest, Emit_kill) {
-  ast::KillStatement k;
-
-  GeneratorImpl g;
-  g.increment_indent();
-
-  ASSERT_TRUE(g.EmitStatement(&k)) << g.error();
-  EXPECT_EQ(g.result(), "  kill;\n");
-}
-
-}  // namespace
-}  // namespace wgsl
-}  // namespace writer
-}  // namespace tint
diff --git a/src/writer/wgsl/generator_impl_loop_test.cc b/src/writer/wgsl/generator_impl_loop_test.cc
index 47fc3ef..7b3e92c 100644
--- a/src/writer/wgsl/generator_impl_loop_test.cc
+++ b/src/writer/wgsl/generator_impl_loop_test.cc
@@ -15,7 +15,7 @@
 #include <memory>
 
 #include "gtest/gtest.h"
-#include "src/ast/kill_statement.h"
+#include "src/ast/discard_statement.h"
 #include "src/ast/loop_statement.h"
 #include "src/writer/wgsl/generator_impl.h"
 
@@ -28,7 +28,7 @@
 
 TEST_F(WgslGeneratorImplTest, Emit_Loop) {
   ast::StatementList body;
-  body.push_back(std::make_unique<ast::KillStatement>());
+  body.push_back(std::make_unique<ast::DiscardStatement>());
 
   ast::LoopStatement l(std::move(body), {});
 
@@ -37,17 +37,17 @@
 
   ASSERT_TRUE(g.EmitStatement(&l)) << g.error();
   EXPECT_EQ(g.result(), R"(  loop {
-    kill;
+    discard;
   }
 )");
 }
 
 TEST_F(WgslGeneratorImplTest, Emit_LoopWithContinuing) {
   ast::StatementList body;
-  body.push_back(std::make_unique<ast::KillStatement>());
+  body.push_back(std::make_unique<ast::DiscardStatement>());
 
   ast::StatementList continuing;
-  continuing.push_back(std::make_unique<ast::KillStatement>());
+  continuing.push_back(std::make_unique<ast::DiscardStatement>());
 
   ast::LoopStatement l(std::move(body), std::move(continuing));
 
@@ -56,10 +56,10 @@
 
   ASSERT_TRUE(g.EmitStatement(&l)) << g.error();
   EXPECT_EQ(g.result(), R"(  loop {
-    kill;
+    discard;
 
     continuing {
-      kill;
+      discard;
     }
   }
 )");