validation: Error on obviously infinite loops

Most of this change is fixing up the numerious tests that violated this rule.

Fixed: tint:1365
Issue: tint:1374
Change-Id: I38da27c7367277fe60857208170fec017e80bd25
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/76400
Kokoro: Kokoro <noreply+kokoro@google.com>
Reviewed-by: David Neto <dneto@google.com>
Commit-Queue: Ben Clayton <bclayton@google.com>
diff --git a/docs/origin-trial-changes.md b/docs/origin-trial-changes.md
index e83ef1b..61c4e3c 100644
--- a/docs/origin-trial-changes.md
+++ b/docs/origin-trial-changes.md
@@ -2,6 +2,10 @@
 
 ## Changes for M99
 
+### Breaking changes
+
+Obviously infinite loops (no condition, no break) are now a validation error.
+
 ### Deprecated Features
 
 The following features have been deprecated and will be removed in M102:
diff --git a/src/resolver/compound_statement_test.cc b/src/resolver/compound_statement_test.cc
index 1eb4f0f..27e2126 100644
--- a/src/resolver/compound_statement_test.cc
+++ b/src/resolver/compound_statement_test.cc
@@ -82,15 +82,15 @@
 TEST_F(ResolverCompoundStatementTest, Loop) {
   // fn F() {
   //   loop {
-  //     stmt_a;
+  //     break;
   //     continuing {
-  //       stmt_b;
+  //       stmt;
   //     }
   //   }
   // }
-  auto* stmt_a = Ignore(1);
-  auto* stmt_b = Ignore(1);
-  auto* loop = Loop(Block(stmt_a), Block(stmt_b));
+  auto* brk = Break();
+  auto* stmt = Ignore(1);
+  auto* loop = Loop(Block(brk), Block(stmt));
   auto* f = Func("F", {}, ty.void_(), {loop});
 
   ASSERT_TRUE(r()->Resolve()) << r()->error();
@@ -103,7 +103,7 @@
     EXPECT_EQ(s->Parent(), s->Block());
   }
   {
-    auto* s = Sem().Get(stmt_a);
+    auto* s = Sem().Get(brk);
     ASSERT_NE(s, nullptr);
     ASSERT_NE(s->Block(), nullptr);
     EXPECT_EQ(s->Parent(), s->Block());
@@ -122,7 +122,7 @@
     EXPECT_EQ(s->Parent()->Parent()->Parent()->Parent(), nullptr);
   }
   {
-    auto* s = Sem().Get(stmt_b);
+    auto* s = Sem().Get(stmt);
     ASSERT_NE(s, nullptr);
     ASSERT_NE(s->Block(), nullptr);
     EXPECT_EQ(s->Parent(), s->Block());
diff --git a/src/resolver/control_block_validation_test.cc b/src/resolver/control_block_validation_test.cc
index 65f3f71..40d5e5c 100644
--- a/src/resolver/control_block_validation_test.cc
+++ b/src/resolver/control_block_validation_test.cc
@@ -86,6 +86,7 @@
 
 TEST_F(ResolverControlBlockValidationTest, UnreachableCode_Loop_continue) {
   // loop {
+  //   if (false) { break; }
   //   var z: i32;
   //   continue;
   //   z = 1;
@@ -93,7 +94,8 @@
   auto* decl_z = Decl(Var("z", ty.i32()));
   auto* cont = Continue();
   auto* assign_z = Assign(Source{{12, 34}}, "z", 1);
-  WrapInFunction(Loop(Block(decl_z, cont, assign_z)));
+  WrapInFunction(
+      Loop(Block(If(false, Block(Break())), decl_z, cont, assign_z)));
 
   ASSERT_TRUE(r()->Resolve()) << r()->error();
   EXPECT_EQ(r()->error(), "12:34 warning: code is unreachable");
@@ -105,6 +107,7 @@
 TEST_F(ResolverControlBlockValidationTest,
        UnreachableCode_Loop_continue_InBlocks) {
   // loop {
+  //   if (false) { break; }
   //   var z: i32;
   //   {{{continue;}}}
   //   z = 1;
@@ -112,7 +115,8 @@
   auto* decl_z = Decl(Var("z", ty.i32()));
   auto* cont = Continue();
   auto* assign_z = Assign(Source{{12, 34}}, "z", 1);
-  WrapInFunction(Loop(Block(decl_z, Block(Block(Block(cont))), assign_z)));
+  WrapInFunction(Loop(Block(If(false, Block(Break())), decl_z,
+                            Block(Block(Block(cont))), assign_z)));
 
   ASSERT_TRUE(r()->Resolve()) << r()->error();
   EXPECT_EQ(r()->error(), "12:34 warning: code is unreachable");
@@ -122,7 +126,7 @@
 }
 
 TEST_F(ResolverControlBlockValidationTest, UnreachableCode_ForLoop_continue) {
-  // for (;;) {
+  // for (;false;) {
   //   var z: i32;
   //   continue;
   //   z = 1;
@@ -130,7 +134,7 @@
   auto* decl_z = Decl(Var("z", ty.i32()));
   auto* cont = Continue();
   auto* assign_z = Assign(Source{{12, 34}}, "z", 1);
-  WrapInFunction(For(nullptr, nullptr, nullptr,  //
+  WrapInFunction(For(nullptr, false, nullptr,  //
                      Block(decl_z, cont, assign_z)));
 
   ASSERT_TRUE(r()->Resolve()) << r()->error();
@@ -142,7 +146,7 @@
 
 TEST_F(ResolverControlBlockValidationTest,
        UnreachableCode_ForLoop_continue_InBlocks) {
-  // for (;;) {
+  // for (;false;) {
   //   var z: i32;
   //   {{{continue;}}}
   //   z = 1;
@@ -150,7 +154,7 @@
   auto* decl_z = Decl(Var("z", ty.i32()));
   auto* cont = Continue();
   auto* assign_z = Assign(Source{{12, 34}}, "z", 1);
-  WrapInFunction(For(nullptr, nullptr, nullptr,
+  WrapInFunction(For(nullptr, false, nullptr,
                      Block(decl_z, Block(Block(Block(cont))), assign_z)));
 
   ASSERT_TRUE(r()->Resolve()) << r()->error();
@@ -171,10 +175,10 @@
   auto* decl_z = Decl(Var("z", ty.i32()));
   auto* brk = Break();
   auto* assign_z = Assign(Source{{12, 34}}, "z", 1);
-  WrapInFunction(                                                     //
-      Loop(Block(Switch(1,                                            //
-                        Case(Expr(1), Block(decl_z, brk, assign_z)),  //
-                        DefaultCase()))));
+  WrapInFunction(                                                //
+      Block(Switch(1,                                            //
+                   Case(Expr(1), Block(decl_z, brk, assign_z)),  //
+                   DefaultCase())));
 
   ASSERT_TRUE(r()->Resolve()) << r()->error();
   EXPECT_EQ(r()->error(), "12:34 warning: code is unreachable");
@@ -189,6 +193,7 @@
   //     case 1: { {{{break;}}} var a : u32 = 2;}
   //     default: {}
   //   }
+  //   break;
   // }
   auto* decl_z = Decl(Var("z", ty.i32()));
   auto* brk = Break();
@@ -196,7 +201,8 @@
   WrapInFunction(Loop(Block(
       Switch(1,  //
              Case(Expr(1), Block(decl_z, Block(Block(Block(brk))), assign_z)),
-             DefaultCase()))));
+             DefaultCase()),  //
+      Break())));
 
   ASSERT_TRUE(r()->Resolve()) << r()->error();
   EXPECT_EQ(r()->error(), "12:34 warning: code is unreachable");
diff --git a/src/resolver/resolver.cc b/src/resolver/resolver.cc
index d732f0c..434f7ff 100644
--- a/src/resolver/resolver.cc
+++ b/src/resolver/resolver.cc
@@ -1039,7 +1039,7 @@
       }
       behaviors.Remove(sem::Behavior::kBreak, sem::Behavior::kContinue);
 
-      return true;
+      return ValidateLoopStatement(sem);
     });
   });
 }
diff --git a/src/resolver/resolver.h b/src/resolver/resolver.h
index 8aed028..89c2808 100644
--- a/src/resolver/resolver.h
+++ b/src/resolver/resolver.h
@@ -264,6 +264,7 @@
                                   std::unordered_set<uint32_t>& locations,
                                   const Source& source,
                                   const bool is_input = false);
+  bool ValidateLoopStatement(const sem::LoopStatement* stmt);
   bool ValidateMatrix(const sem::Matrix* ty, const Source& source);
   bool ValidateFunctionParameter(const ast::Function* func,
                                  const sem::Variable* var);
diff --git a/src/resolver/resolver_behavior_test.cc b/src/resolver/resolver_behavior_test.cc
index 9c5da9a..991a065 100644
--- a/src/resolver/resolver_behavior_test.cc
+++ b/src/resolver/resolver_behavior_test.cc
@@ -216,7 +216,8 @@
 
 TEST_F(ResolverBehaviorTest, StmtContinue) {
   auto* stmt = Continue();
-  WrapInFunction(Loop(Block(stmt)));
+  WrapInFunction(Loop(Block(If(true, Block(Break())),  //
+                            stmt)));
 
   ASSERT_TRUE(r()->Resolve()) << r()->error();
 
@@ -234,14 +235,12 @@
   EXPECT_EQ(sem->Behaviors(), sem::Behavior::kDiscard);
 }
 
-TEST_F(ResolverBehaviorTest, StmtForLoopEmpty) {
-  auto* stmt = For(nullptr, nullptr, nullptr, Block());
+TEST_F(ResolverBehaviorTest, StmtForLoopEmpty_NoExit) {
+  auto* stmt = For(Source{{12, 34}}, nullptr, nullptr, nullptr, Block());
   WrapInFunction(stmt);
 
-  ASSERT_TRUE(r()->Resolve()) << r()->error();
-
-  auto* sem = Sem().Get(stmt);
-  EXPECT_TRUE(sem->Behaviors().Empty());
+  EXPECT_FALSE(r()->Resolve());
+  EXPECT_EQ(r()->error(), "12:34 error: for-loop does not exit");
 }
 
 TEST_F(ResolverBehaviorTest, StmtForLoopBreak) {
@@ -254,14 +253,13 @@
   EXPECT_EQ(sem->Behaviors(), sem::Behavior::kNext);
 }
 
-TEST_F(ResolverBehaviorTest, StmtForLoopContinue) {
-  auto* stmt = For(nullptr, nullptr, nullptr, Block(Continue()));
+TEST_F(ResolverBehaviorTest, StmtForLoopContinue_NoExit) {
+  auto* stmt =
+      For(Source{{12, 34}}, nullptr, nullptr, nullptr, Block(Continue()));
   WrapInFunction(stmt);
 
-  ASSERT_TRUE(r()->Resolve()) << r()->error();
-
-  auto* sem = Sem().Get(stmt);
-  EXPECT_TRUE(sem->Behaviors().Empty());
+  EXPECT_FALSE(r()->Resolve());
+  EXPECT_EQ(r()->error(), "12:34 error: for-loop does not exit");
 }
 
 TEST_F(ResolverBehaviorTest, StmtForLoopDiscard) {
@@ -414,14 +412,12 @@
             sem::Behaviors(sem::Behavior::kDiscard, sem::Behavior::kNext));
 }
 
-TEST_F(ResolverBehaviorTest, StmtLoopEmpty) {
-  auto* stmt = Loop(Block());
+TEST_F(ResolverBehaviorTest, StmtLoopEmpty_NoExit) {
+  auto* stmt = Loop(Source{{12, 34}}, Block());
   WrapInFunction(stmt);
 
-  ASSERT_TRUE(r()->Resolve()) << r()->error();
-
-  auto* sem = Sem().Get(stmt);
-  EXPECT_TRUE(sem->Behaviors().Empty());
+  EXPECT_FALSE(r()->Resolve());
+  EXPECT_EQ(r()->error(), "12:34 error: loop does not exit");
 }
 
 TEST_F(ResolverBehaviorTest, StmtLoopBreak) {
@@ -434,14 +430,12 @@
   EXPECT_EQ(sem->Behaviors(), sem::Behavior::kNext);
 }
 
-TEST_F(ResolverBehaviorTest, StmtLoopContinue) {
-  auto* stmt = Loop(Block(Continue()));
+TEST_F(ResolverBehaviorTest, StmtLoopContinue_NoExit) {
+  auto* stmt = Loop(Source{{12, 34}}, Block(Continue()));
   WrapInFunction(stmt);
 
-  ASSERT_TRUE(r()->Resolve()) << r()->error();
-
-  auto* sem = Sem().Get(stmt);
-  EXPECT_TRUE(sem->Behaviors().Empty());
+  EXPECT_FALSE(r()->Resolve());
+  EXPECT_EQ(r()->error(), "12:34 error: loop does not exit");
 }
 
 TEST_F(ResolverBehaviorTest, StmtLoopDiscard) {
@@ -464,14 +458,12 @@
   EXPECT_EQ(sem->Behaviors(), sem::Behavior::kReturn);
 }
 
-TEST_F(ResolverBehaviorTest, StmtLoopEmpty_ContEmpty) {
-  auto* stmt = Loop(Block(), Block());
+TEST_F(ResolverBehaviorTest, StmtLoopEmpty_ContEmpty_NoExit) {
+  auto* stmt = Loop(Source{{12, 34}}, Block(), Block());
   WrapInFunction(stmt);
 
-  ASSERT_TRUE(r()->Resolve()) << r()->error();
-
-  auto* sem = Sem().Get(stmt);
-  EXPECT_TRUE(sem->Behaviors().Empty());
+  EXPECT_FALSE(r()->Resolve());
+  EXPECT_EQ(r()->error(), "12:34 error: loop does not exit");
 }
 
 TEST_F(ResolverBehaviorTest, StmtLoopEmpty_ContBreak) {
diff --git a/src/resolver/resolver_test.cc b/src/resolver/resolver_test.cc
index 2656abe..a32f563 100644
--- a/src/resolver/resolver_test.cc
+++ b/src/resolver/resolver_test.cc
@@ -200,7 +200,7 @@
   auto* body_lhs = Expr("v");
   auto* body_rhs = Expr(2.3f);
 
-  auto* body = Block(Assign(body_lhs, body_rhs));
+  auto* body = Block(Assign(body_lhs, body_rhs), Break());
   auto* continuing_lhs = Expr("v");
   auto* continuing_rhs = Expr(2.3f);
 
diff --git a/src/resolver/resolver_validation.cc b/src/resolver/resolver_validation.cc
index 12e3b34..bc70f94 100644
--- a/src/resolver/resolver_validation.cc
+++ b/src/resolver/resolver_validation.cc
@@ -1426,7 +1426,19 @@
   return true;
 }
 
+bool Resolver::ValidateLoopStatement(const sem::LoopStatement* stmt) {
+  if (stmt->Behaviors().Empty()) {
+    AddError("loop does not exit", stmt->Declaration()->source.Begin());
+    return false;
+  }
+  return true;
+}
+
 bool Resolver::ValidateForLoopStatement(const sem::ForLoopStatement* stmt) {
+  if (stmt->Behaviors().Empty()) {
+    AddError("for-loop does not exit", stmt->Declaration()->source.Begin());
+    return false;
+  }
   if (auto* cond = stmt->Condition()) {
     auto* cond_ty = cond->Type()->UnwrapRef();
     if (!cond_ty->Is<sem::Bool>()) {
diff --git a/src/resolver/validation_test.cc b/src/resolver/validation_test.cc
index 7d8706d..0b3152a 100644
--- a/src/resolver/validation_test.cc
+++ b/src/resolver/validation_test.cc
@@ -481,6 +481,7 @@
 TEST_F(ResolverValidationTest,
        Stmt_Loop_ContinueInLoopBodyAfterDecl_UsageInContinuing_InBlocks) {
   // loop  {
+  //     if (false) { break; }
   //     var z : i32;
   //     {{{continue;}}}
   //     continue; // Ok
@@ -490,7 +491,8 @@
   //     }
   // }
 
-  auto* body = Block(Decl(Var("z", ty.i32(), ast::StorageClass::kNone)),
+  auto* body = Block(If(false, Block(Break())),  //
+                     Decl(Var("z", ty.i32(), ast::StorageClass::kNone)),
                      Block(Block(Block(Continue()))));
   auto* continuing = Block(Assign(Expr("z"), 2));
   auto* loop_stmt = Loop(body, continuing);
@@ -636,7 +638,7 @@
   //         break;
   //     }
   //     var z : i32;
-  //
+  //     break;
   //     continuing {
   //         z = 2;
   //     }
@@ -645,8 +647,9 @@
   auto* inner_loop = Loop(Block(    //
       If(true, Block(Continue())),  //
       Break()));
-  auto* body =
-      Block(inner_loop, Decl(Var("z", ty.i32(), ast::StorageClass::kNone)));
+  auto* body = Block(inner_loop,                                          //
+                     Decl(Var("z", ty.i32(), ast::StorageClass::kNone)),  //
+                     Break());
   auto* continuing = Block(Assign("z", 2));
   auto* loop_stmt = Loop(body, continuing);
   WrapInFunction(loop_stmt);
@@ -662,7 +665,7 @@
   //         break;
   //     }
   //     var z : i32;
-  //
+  //     break;
   //     continuing {
   //         if (true) {
   //             z = 2;
@@ -672,8 +675,9 @@
 
   auto* inner_loop = Loop(Block(If(true, Block(Continue())),  //
                                 Break()));
-  auto* body =
-      Block(inner_loop, Decl(Var("z", ty.i32(), ast::StorageClass::kNone)));
+  auto* body = Block(inner_loop,                                          //
+                     Decl(Var("z", ty.i32(), ast::StorageClass::kNone)),  //
+                     Break());
   auto* continuing = Block(If(Expr(true), Block(Assign("z", 2))));
   auto* loop_stmt = Loop(body, continuing);
   WrapInFunction(loop_stmt);
@@ -689,19 +693,22 @@
   //         break;
   //     }
   //     var z : i32;
-  //
+  //     break;
   //     continuing {
   //         loop {
   //             z = 2;
+  //             break;
   //         }
   //     }
   // }
 
   auto* inner_loop = Loop(Block(If(true, Block(Continue())),  //
                                 Break()));
-  auto* body =
-      Block(inner_loop, Decl(Var("z", ty.i32(), ast::StorageClass::kNone)));
-  auto* continuing = Block(Loop(Block(Assign("z", 2))));
+  auto* body = Block(inner_loop,                                          //
+                     Decl(Var("z", ty.i32(), ast::StorageClass::kNone)),  //
+                     Break());
+  auto* continuing = Block(Loop(Block(Assign("z", 2),  //
+                                      Break())));
   auto* loop_stmt = Loop(body, continuing);
   WrapInFunction(loop_stmt);
 
@@ -712,7 +719,7 @@
   // loop  {
   //     var z : i32;
   //     if (true) { continue; }
-  //
+  //     break;
   //     continuing {
   //         z = 2;
   //     }
@@ -720,7 +727,8 @@
 
   auto error_loc = Source{{12, 34}};
   auto* body = Block(Decl(Var("z", ty.i32(), ast::StorageClass::kNone)),
-                     If(true, Block(Continue())));
+                     If(true, Block(Continue())),  //
+                     Break());
   auto* continuing = Block(Assign(Expr(error_loc, "z"), 2));
   auto* loop_stmt = Loop(body, continuing);
   WrapInFunction(loop_stmt);
@@ -748,6 +756,7 @@
 
 TEST_F(ResolverTest, Stmt_Loop_ReturnInContinuing_Indirect) {
   // loop {
+  //   if (false) { break; }
   //   continuing {
   //     loop {
   //       return;
@@ -755,11 +764,11 @@
   //   }
   // }
 
-  WrapInFunction(Loop(         // outer loop
-      Block(),                 //   outer loop block
-      Block(Source{{56, 78}},  //   outer loop continuing block
-            Loop(              //     inner loop
-                Block(         //       inner loop block
+  WrapInFunction(Loop(                   // outer loop
+      Block(If(false, Block(Break()))),  //   outer loop block
+      Block(Source{{56, 78}},            //   outer loop continuing block
+            Loop(                        //     inner loop
+                Block(                   //       inner loop block
                     Return(Source{{12, 34}}))))));
 
   EXPECT_FALSE(r()->Resolve());
@@ -789,16 +798,17 @@
 
 TEST_F(ResolverTest, Stmt_Loop_DiscardInContinuing_Indirect) {
   // loop {
+  //   if (false) { break; }
   //   continuing {
   //     loop { discard; }
   //   }
   // }
 
-  WrapInFunction(Loop(         // outer loop
-      Block(),                 //   outer loop block
-      Block(Source{{56, 78}},  //   outer loop continuing block
-            Loop(              //     inner loop
-                Block(         //       inner loop block
+  WrapInFunction(Loop(                   // outer loop
+      Block(If(false, Block(Break()))),  //   outer loop block
+      Block(Source{{56, 78}},            //   outer loop continuing block
+            Loop(                        //     inner loop
+                Block(                   //       inner loop block
                     Discard(Source{{12, 34}}))))));
 
   EXPECT_FALSE(r()->Resolve());
@@ -854,19 +864,23 @@
 
 TEST_F(ResolverTest, Stmt_Loop_ContinueInContinuing_Indirect) {
   // loop {
+  //   if (false) { break; }
   //   continuing {
   //     loop {
+  //       if (false) { break; }
   //       continue;
   //     }
   //   }
   // }
 
-  WrapInFunction(Loop(  // outer loop
-      Block(),          //   outer loop block
-      Block(            //   outer loop continuing block
-          Loop(         //     inner loop
-              Block(    //       inner loop block
-                  Continue(Source{{12, 34}}))))));
+  WrapInFunction(Loop(                        // outer loop
+      Block(                                  //   outer loop block
+          If(false, Block(Break()))),         //     if (false) { break; }
+      Block(                                  //   outer loop continuing block
+          Loop(                               //     inner loop
+              Block(                          //       inner loop block
+                  If(false, Block(Break())),  //          if (false) { break; }
+                  Continue(Source{{12, 34}}))))));  //    continue
 
   EXPECT_TRUE(r()->Resolve()) << r()->error();
 }
@@ -970,13 +984,14 @@
 }
 
 TEST_F(ResolverTest, Stmt_ForLoop_ContinueInContinuing_Indirect) {
-  // for(;; loop { continue }) {
+  // for(;; loop { if (false) { break; } continue }) {
   //   break;
   // }
 
   WrapInFunction(For(nullptr, nullptr,
                      Loop(                                    //
-                         Block(Continue(Source{{12, 34}}))),  //
+                         Block(If(false, Block(Break())),     //
+                               Continue(Source{{12, 34}}))),  //
                      Block(Break())));
 
   EXPECT_TRUE(r()->Resolve()) << r()->error();
@@ -1004,7 +1019,8 @@
 }
 
 TEST_F(ResolverValidationTest, Stmt_ContinueInLoop) {
-  WrapInFunction(Loop(Block(Continue(Source{{12, 34}}))));
+  WrapInFunction(Loop(Block(If(false, Block(Break())),  //
+                            Continue(Source{{12, 34}}))));
   EXPECT_TRUE(r()->Resolve()) << r()->error();
 }
 
@@ -1015,20 +1031,21 @@
 }
 
 TEST_F(ResolverValidationTest, Stmt_BreakInLoop) {
-  WrapInFunction(Loop(Block(create<ast::BreakStatement>(Source{{12, 34}}))));
+  WrapInFunction(Loop(Block(Break(Source{{12, 34}}))));
   EXPECT_TRUE(r()->Resolve()) << r()->error();
 }
 
 TEST_F(ResolverValidationTest, Stmt_BreakInSwitch) {
-  WrapInFunction(Loop(Block(Switch(
-      Expr(1),
-      Case(Expr(1), Block(create<ast::BreakStatement>(Source{{12, 34}}))),
-      DefaultCase()))));
+  WrapInFunction(Loop(Block(Switch(Expr(1),               //
+                                   Case(Expr(1),          //
+                                        Block(Break())),  //
+                                   DefaultCase()),        //
+                            Break())));                   //
   EXPECT_TRUE(r()->Resolve()) << r()->error();
 }
 
 TEST_F(ResolverValidationTest, Stmt_BreakNotInLoopOrSwitch) {
-  WrapInFunction(create<ast::BreakStatement>(Source{{12, 34}}));
+  WrapInFunction(Break(Source{{12, 34}}));
   EXPECT_FALSE(r()->Resolve());
   EXPECT_EQ(r()->error(),
             "12:34 error: break statement must be in a loop or switch case");
diff --git a/src/transform/for_loop_to_loop_test.cc b/src/transform/for_loop_to_loop_test.cc
index aab88ec..d8b2f1f 100644
--- a/src/transform/for_loop_to_loop_test.cc
+++ b/src/transform/for_loop_to_loop_test.cc
@@ -36,6 +36,7 @@
   auto* src = R"(
 fn f() {
   for (;;) {
+    break;
   }
 }
 )";
@@ -43,6 +44,7 @@
   auto* expect = R"(
 fn f() {
   loop {
+    break;
   }
 }
 )";
@@ -80,7 +82,7 @@
   auto* src = R"(
 fn f() {
   for (var i: i32;;) {
-
+    break;
   }
 }
 )";
@@ -90,6 +92,7 @@
   {
     var i : i32;
     loop {
+      break;
     }
   }
 }
@@ -106,6 +109,7 @@
   auto* src = R"(
 fn f() {
   for (var i: i32 = 0;;) {
+    break;
   }
 }
 )";
@@ -115,6 +119,7 @@
   {
     var i : i32 = 0;
     loop {
+      break;
     }
   }
 }
@@ -130,6 +135,7 @@
   auto* src = R"(
 fn f() {
   for (let i: i32 = 0;;) {
+    break;
   }
 }
 )";
@@ -139,6 +145,7 @@
   {
     let i : i32 = 0;
     loop {
+      break;
     }
   }
 }
@@ -155,7 +162,7 @@
 fn f() {
   var i: i32;
   for (i = 0;;) {
-
+    break;
   }
 }
 )";
@@ -166,6 +173,7 @@
   {
     i = 0;
     loop {
+      break;
     }
   }
 }
@@ -185,7 +193,9 @@
 fn f() {
   var b : i32;
   var c : i32;
-  for (a(b,c);;) { }
+  for (a(b,c);;) {
+    break;
+  }
 }
 )";
 
@@ -199,6 +209,7 @@
   {
     a(b, c);
     loop {
+      break;
     }
   }
 }
@@ -239,6 +250,7 @@
 fn f() {
   var x: i32;
   for (;;x = 2) {
+    break;
   }
 }
 )";
@@ -247,6 +259,7 @@
 fn f() {
   var x : i32;
   loop {
+    break;
 
     continuing {
       x = 2;
@@ -270,6 +283,7 @@
   var b : i32;
   var c : i32;
   for (;;a(b,c)) {
+    break;
   }
 }
 )";
@@ -282,6 +296,7 @@
   var b : i32;
   var c : i32;
   loop {
+    break;
 
     continuing {
       a(b, c);
diff --git a/src/transform/promote_initializers_to_const_var_test.cc b/src/transform/promote_initializers_to_const_var_test.cc
index c303fce..b32d153 100644
--- a/src/transform/promote_initializers_to_const_var_test.cc
+++ b/src/transform/promote_initializers_to_const_var_test.cc
@@ -85,6 +85,7 @@
 fn f() {
   var insert_after = 1;
   for(var i = array<f32, 4u>(0.0, 1.0, 2.0, 3.0)[2]; ; ) {
+    break;
   }
 }
 )";
@@ -94,6 +95,7 @@
   var insert_after = 1;
   let tint_symbol = array<f32, 4u>(0.0, 1.0, 2.0, 3.0);
   for(var i = tint_symbol[2]; ; ) {
+    break;
   }
 }
 )";
@@ -114,6 +116,7 @@
 fn f() {
   var insert_after = 1;
   for(var x = S(1, 2.0, vec3<f32>()).b; ; ) {
+    break;
   }
 }
 )";
@@ -129,6 +132,7 @@
   var insert_after = 1;
   let tint_symbol = S(1, 2.0, vec3<f32>());
   for(var x = tint_symbol.b; ; ) {
+    break;
   }
 }
 )";
diff --git a/src/transform/remove_unreachable_statements_test.cc b/src/transform/remove_unreachable_statements_test.cc
index 9124c62..874bbf2 100644
--- a/src/transform/remove_unreachable_statements_test.cc
+++ b/src/transform/remove_unreachable_statements_test.cc
@@ -331,11 +331,13 @@
   EXPECT_EQ(expect, str(got));
 }
 
-TEST_F(RemoveUnreachableStatementsTest, LoopWithNoBreak) {
+TEST_F(RemoveUnreachableStatementsTest, LoopWithDiscard) {
   auto* src = R"(
 fn f() {
   loop {
     var a = 1;
+    discard;
+
     continuing {
       var b = 2;
     }
@@ -351,6 +353,7 @@
 fn f() {
   loop {
     var a = 1;
+    discard;
 
     continuing {
       var b = 2;
diff --git a/src/transform/simplify_pointers_test.cc b/src/transform/simplify_pointers_test.cc
index d6fde98..0fdf806 100644
--- a/src/transform/simplify_pointers_test.cc
+++ b/src/transform/simplify_pointers_test.cc
@@ -254,6 +254,7 @@
   var arr = array<f32, 4>();
   for (let a = &arr[foo()]; ;) {
     let x = *a;
+    break;
   }
 }
 )";
@@ -269,6 +270,7 @@
   let a_save = foo();
   for(; ; ) {
     let x = arr[a_save];
+    break;
   }
 }
 )";
diff --git a/src/writer/glsl/generator_impl_continue_test.cc b/src/writer/glsl/generator_impl_continue_test.cc
index 66cd37d..68f01b0 100644
--- a/src/writer/glsl/generator_impl_continue_test.cc
+++ b/src/writer/glsl/generator_impl_continue_test.cc
@@ -22,7 +22,8 @@
 using GlslGeneratorImplTest_Continue = TestHelper;
 
 TEST_F(GlslGeneratorImplTest_Continue, Emit_Continue) {
-  auto* loop = Loop(Block(create<ast::ContinueStatement>()));
+  auto* loop = Loop(Block(If(false, Block(Break())),  //
+                          Continue()));
   WrapInFunction(loop);
 
   GeneratorImpl& gen = Build();
@@ -31,6 +32,9 @@
 
   ASSERT_TRUE(gen.EmitStatement(loop)) << gen.error();
   EXPECT_EQ(gen.result(), R"(  while (true) {
+    if (false) {
+      break;
+    }
     continue;
   }
 )");
diff --git a/src/writer/glsl/generator_impl_loop_test.cc b/src/writer/glsl/generator_impl_loop_test.cc
index fb65108..7f718f0 100644
--- a/src/writer/glsl/generator_impl_loop_test.cc
+++ b/src/writer/glsl/generator_impl_loop_test.cc
@@ -106,34 +106,18 @@
   // loop {
   //   var lhs : f32 = 2.4;
   //   var other : f32;
+  //   break;
   //   continuing {
   //     lhs = rhs
   //   }
   // }
-  //
-  // ->
-  // {
-  //   float lhs;
-  //   float other;
-  //   for (;;) {
-  //     if (continuing) {
-  //       lhs = rhs;
-  //     }
-  //     lhs = 2.4f;
-  //     other = 0.0f;
-  //   }
-  // }
 
   Global("rhs", ty.f32(), ast::StorageClass::kPrivate);
 
-  auto* var = Var("lhs", ty.f32(), ast::StorageClass::kNone, Expr(2.4f));
-
-  auto* body = Block(Decl(var), Decl(Var("other", ty.f32())));
-
-  auto* lhs = Expr("lhs");
-  auto* rhs = Expr("rhs");
-
-  auto* continuing = Block(Assign(lhs, rhs));
+  auto* body = Block(Decl(Var("lhs", ty.f32(), Expr(2.4f))),  //
+                     Decl(Var("other", ty.f32())),            //
+                     Break());
+  auto* continuing = Block(Assign("lhs", "rhs"));
   auto* outer = Loop(body, continuing);
   WrapInFunction(outer);
 
@@ -145,6 +129,7 @@
   EXPECT_EQ(gen.result(), R"(  while (true) {
     float lhs = 2.400000095f;
     float other = 0.0f;
+    break;
     {
       lhs = rhs;
     }
@@ -157,10 +142,8 @@
   //   return;
   // }
 
-  Func("a_statement", {}, ty.void_(), {});
-
-  auto* f =
-      For(nullptr, nullptr, nullptr, Block(CallStmt(Call("a_statement"))));
+  auto* f = For(nullptr, nullptr, nullptr,  //
+                Block(Return()));
   WrapInFunction(f);
 
   GeneratorImpl& gen = Build();
@@ -170,7 +153,7 @@
   ASSERT_TRUE(gen.EmitStatement(f)) << gen.error();
   EXPECT_EQ(gen.result(), R"(  {
     for(; ; ) {
-      a_statement();
+      return;
     }
   }
 )");
@@ -181,10 +164,8 @@
   //   return;
   // }
 
-  Func("a_statement", {}, ty.void_(), {});
-
-  auto* f = For(Decl(Var("i", ty.i32())), nullptr, nullptr,
-                Block(CallStmt(Call("a_statement"))));
+  auto* f = For(Decl(Var("i", ty.i32())), nullptr, nullptr,  //
+                Block(Return()));
   WrapInFunction(f);
 
   GeneratorImpl& gen = Build();
@@ -194,7 +175,7 @@
   ASSERT_TRUE(gen.EmitStatement(f)) << gen.error();
   EXPECT_EQ(gen.result(), R"(  {
     for(int i = 0; ; ) {
-      a_statement();
+      return;
     }
   }
 )");
@@ -204,12 +185,11 @@
   // for(var b = true && false; ; ) {
   //   return;
   // }
-  Func("a_statement", {}, ty.void_(), {});
 
   auto* multi_stmt = create<ast::BinaryExpression>(ast::BinaryOp::kLogicalAnd,
                                                    Expr(true), Expr(false));
   auto* f = For(Decl(Var("b", nullptr, multi_stmt)), nullptr, nullptr,
-                Block(CallStmt(Call("a_statement"))));
+                Block(Return()));
   WrapInFunction(f);
 
   GeneratorImpl& gen = Build();
@@ -224,7 +204,7 @@
     }
     bool b = (tint_tmp);
     for(; ; ) {
-      a_statement();
+      return;
     }
   }
 )");
@@ -289,11 +269,9 @@
   //   return;
   // }
 
-  Func("a_statement", {}, ty.void_(), {});
-
   auto* v = Decl(Var("i", ty.i32()));
-  auto* f = For(nullptr, nullptr, Assign("i", Add("i", 1)),
-                Block(CallStmt(Call("a_statement"))));
+  auto* f = For(nullptr, nullptr, Assign("i", Add("i", 1)),  //
+                Block(Return()));
   WrapInFunction(v, f);
 
   GeneratorImpl& gen = Build();
@@ -303,7 +281,7 @@
   ASSERT_TRUE(gen.EmitStatement(f)) << gen.error();
   EXPECT_EQ(gen.result(), R"(  {
     for(; ; i = (i + 1)) {
-      a_statement();
+      return;
     }
   }
 )");
@@ -314,13 +292,11 @@
   //   return;
   // }
 
-  Func("a_statement", {}, ty.void_(), {});
-
   auto* multi_stmt = create<ast::BinaryExpression>(ast::BinaryOp::kLogicalAnd,
                                                    Expr(true), Expr(false));
   auto* v = Decl(Var("i", ty.bool_()));
-  auto* f = For(nullptr, nullptr, Assign("i", multi_stmt),
-                Block(CallStmt(Call("a_statement"))));
+  auto* f = For(nullptr, nullptr, Assign("i", multi_stmt),  //
+                Block(Return()));
   WrapInFunction(v, f);
 
   GeneratorImpl& gen = Build();
@@ -330,7 +306,7 @@
   ASSERT_TRUE(gen.EmitStatement(f)) << gen.error();
   EXPECT_EQ(gen.result(), R"(  {
     while (true) {
-      a_statement();
+      return;
       bool tint_tmp = true;
       if (tint_tmp) {
         tint_tmp = false;
@@ -346,10 +322,8 @@
   //   return;
   // }
 
-  Func("a_statement", {}, ty.void_(), {});
-
   auto* f = For(Decl(Var("i", ty.i32())), true, Assign("i", Add("i", 1)),
-                Block(CallStmt(Call("a_statement"))));
+                Block(Return()));
   WrapInFunction(f);
 
   GeneratorImpl& gen = Build();
@@ -359,7 +333,7 @@
   ASSERT_TRUE(gen.EmitStatement(f)) << gen.error();
   EXPECT_EQ(gen.result(), R"(  {
     for(int i = 0; true; i = (i + 1)) {
-      a_statement();
+      return;
     }
   }
 )");
@@ -369,7 +343,6 @@
   // for(var i = true && false; true && false; i = true && false) {
   //   return;
   // }
-  Func("a_statement", {}, ty.void_(), {});
 
   auto* multi_stmt_a = create<ast::BinaryExpression>(ast::BinaryOp::kLogicalAnd,
                                                      Expr(true), Expr(false));
@@ -378,9 +351,9 @@
   auto* multi_stmt_c = create<ast::BinaryExpression>(ast::BinaryOp::kLogicalAnd,
                                                      Expr(true), Expr(false));
 
-  auto* f =
-      For(Decl(Var("i", nullptr, multi_stmt_a)), multi_stmt_b,
-          Assign("i", multi_stmt_c), Block(CallStmt(Call("a_statement"))));
+  auto* f = For(Decl(Var("i", nullptr, multi_stmt_a)), multi_stmt_b,
+                Assign("i", multi_stmt_c),  //
+                Block(Return()));
   WrapInFunction(f);
 
   GeneratorImpl& gen = Build();
@@ -400,7 +373,7 @@
         tint_tmp_1 = false;
       }
       if (!((tint_tmp_1))) { break; }
-      a_statement();
+      return;
       bool tint_tmp_2 = true;
       if (tint_tmp_2) {
         tint_tmp_2 = false;
diff --git a/src/writer/hlsl/generator_impl_continue_test.cc b/src/writer/hlsl/generator_impl_continue_test.cc
index 80baf57..277e6a4 100644
--- a/src/writer/hlsl/generator_impl_continue_test.cc
+++ b/src/writer/hlsl/generator_impl_continue_test.cc
@@ -22,7 +22,8 @@
 using HlslGeneratorImplTest_Continue = TestHelper;
 
 TEST_F(HlslGeneratorImplTest_Continue, Emit_Continue) {
-  auto* loop = Loop(Block(create<ast::ContinueStatement>()));
+  auto* loop = Loop(Block(If(false, Block(Break())),  //
+                          Continue()));
   WrapInFunction(loop);
 
   GeneratorImpl& gen = Build();
@@ -31,6 +32,9 @@
 
   ASSERT_TRUE(gen.EmitStatement(loop)) << gen.error();
   EXPECT_EQ(gen.result(), R"(  [loop] while (true) {
+    if (false) {
+      break;
+    }
     continue;
   }
 )");
diff --git a/src/writer/hlsl/generator_impl_loop_test.cc b/src/writer/hlsl/generator_impl_loop_test.cc
index c6a919f..2962b28 100644
--- a/src/writer/hlsl/generator_impl_loop_test.cc
+++ b/src/writer/hlsl/generator_impl_loop_test.cc
@@ -106,34 +106,19 @@
   // loop {
   //   var lhs : f32 = 2.4;
   //   var other : f32;
+  //   break;
   //   continuing {
   //     lhs = rhs
   //   }
   // }
-  //
-  // ->
-  // {
-  //   float lhs;
-  //   float other;
-  //   for (;;) {
-  //     if (continuing) {
-  //       lhs = rhs;
-  //     }
-  //     lhs = 2.4f;
-  //     other = 0.0f;
-  //   }
-  // }
 
   Global("rhs", ty.f32(), ast::StorageClass::kPrivate);
 
-  auto* var = Var("lhs", ty.f32(), ast::StorageClass::kNone, Expr(2.4f));
+  auto* body = Block(Decl(Var("lhs", ty.f32(), Expr(2.4f))),  //
+                     Decl(Var("other", ty.f32())),            //
+                     Break());
 
-  auto* body = Block(Decl(var), Decl(Var("other", ty.f32())));
-
-  auto* lhs = Expr("lhs");
-  auto* rhs = Expr("rhs");
-
-  auto* continuing = Block(Assign(lhs, rhs));
+  auto* continuing = Block(Assign("lhs", "rhs"));
   auto* outer = Loop(body, continuing);
   WrapInFunction(outer);
 
@@ -145,6 +130,7 @@
   EXPECT_EQ(gen.result(), R"(  [loop] while (true) {
     float lhs = 2.400000095f;
     float other = 0.0f;
+    break;
     {
       lhs = rhs;
     }
@@ -157,10 +143,7 @@
   //   return;
   // }
 
-  Func("a_statement", {}, ty.void_(), {});
-
-  auto* f =
-      For(nullptr, nullptr, nullptr, Block(CallStmt(Call("a_statement"))));
+  auto* f = For(nullptr, nullptr, nullptr, Block(Return()));
   WrapInFunction(f);
 
   GeneratorImpl& gen = Build();
@@ -170,7 +153,7 @@
   ASSERT_TRUE(gen.EmitStatement(f)) << gen.error();
   EXPECT_EQ(gen.result(), R"(  {
     [loop] for(; ; ) {
-      a_statement();
+      return;
     }
   }
 )");
@@ -181,10 +164,7 @@
   //   return;
   // }
 
-  Func("a_statement", {}, ty.void_(), {});
-
-  auto* f = For(Decl(Var("i", ty.i32())), nullptr, nullptr,
-                Block(CallStmt(Call("a_statement"))));
+  auto* f = For(Decl(Var("i", ty.i32())), nullptr, nullptr, Block(Return()));
   WrapInFunction(f);
 
   GeneratorImpl& gen = Build();
@@ -194,7 +174,7 @@
   ASSERT_TRUE(gen.EmitStatement(f)) << gen.error();
   EXPECT_EQ(gen.result(), R"(  {
     [loop] for(int i = 0; ; ) {
-      a_statement();
+      return;
     }
   }
 )");
@@ -204,12 +184,11 @@
   // for(var b = true && false; ; ) {
   //   return;
   // }
-  Func("a_statement", {}, ty.void_(), {});
 
   auto* multi_stmt = create<ast::BinaryExpression>(ast::BinaryOp::kLogicalAnd,
                                                    Expr(true), Expr(false));
   auto* f = For(Decl(Var("b", nullptr, multi_stmt)), nullptr, nullptr,
-                Block(CallStmt(Call("a_statement"))));
+                Block(Return()));
   WrapInFunction(f);
 
   GeneratorImpl& gen = Build();
@@ -224,7 +203,7 @@
     }
     bool b = (tint_tmp);
     [loop] for(; ; ) {
-      a_statement();
+      return;
     }
   }
 )");
@@ -235,9 +214,7 @@
   //   return;
   // }
 
-  Func("a_statement", {}, ty.void_(), {});
-
-  auto* f = For(nullptr, true, nullptr, Block(CallStmt(Call("a_statement"))));
+  auto* f = For(nullptr, true, nullptr, Block(Return()));
   WrapInFunction(f);
 
   GeneratorImpl& gen = Build();
@@ -247,7 +224,7 @@
   ASSERT_TRUE(gen.EmitStatement(f)) << gen.error();
   EXPECT_EQ(gen.result(), R"(  {
     [loop] for(; true; ) {
-      a_statement();
+      return;
     }
   }
 )");
@@ -258,12 +235,9 @@
   //   return;
   // }
 
-  Func("a_statement", {}, ty.void_(), {});
-
   auto* multi_stmt = create<ast::BinaryExpression>(ast::BinaryOp::kLogicalAnd,
                                                    Expr(true), Expr(false));
-  auto* f =
-      For(nullptr, multi_stmt, nullptr, Block(CallStmt(Call("a_statement"))));
+  auto* f = For(nullptr, multi_stmt, nullptr, Block(Return()));
   WrapInFunction(f);
 
   GeneratorImpl& gen = Build();
@@ -278,7 +252,7 @@
         tint_tmp = false;
       }
       if (!((tint_tmp))) { break; }
-      a_statement();
+      return;
     }
   }
 )");
@@ -289,11 +263,8 @@
   //   return;
   // }
 
-  Func("a_statement", {}, ty.void_(), {});
-
   auto* v = Decl(Var("i", ty.i32()));
-  auto* f = For(nullptr, nullptr, Assign("i", Add("i", 1)),
-                Block(CallStmt(Call("a_statement"))));
+  auto* f = For(nullptr, nullptr, Assign("i", Add("i", 1)), Block(Return()));
   WrapInFunction(v, f);
 
   GeneratorImpl& gen = Build();
@@ -303,7 +274,7 @@
   ASSERT_TRUE(gen.EmitStatement(f)) << gen.error();
   EXPECT_EQ(gen.result(), R"(  {
     [loop] for(; ; i = (i + 1)) {
-      a_statement();
+      return;
     }
   }
 )");
@@ -314,13 +285,10 @@
   //   return;
   // }
 
-  Func("a_statement", {}, ty.void_(), {});
-
   auto* multi_stmt = create<ast::BinaryExpression>(ast::BinaryOp::kLogicalAnd,
                                                    Expr(true), Expr(false));
   auto* v = Decl(Var("i", ty.bool_()));
-  auto* f = For(nullptr, nullptr, Assign("i", multi_stmt),
-                Block(CallStmt(Call("a_statement"))));
+  auto* f = For(nullptr, nullptr, Assign("i", multi_stmt), Block(Return()));
   WrapInFunction(v, f);
 
   GeneratorImpl& gen = Build();
@@ -330,7 +298,7 @@
   ASSERT_TRUE(gen.EmitStatement(f)) << gen.error();
   EXPECT_EQ(gen.result(), R"(  {
     [loop] while (true) {
-      a_statement();
+      return;
       bool tint_tmp = true;
       if (tint_tmp) {
         tint_tmp = false;
@@ -346,10 +314,8 @@
   //   return;
   // }
 
-  Func("a_statement", {}, ty.void_(), {});
-
   auto* f = For(Decl(Var("i", ty.i32())), true, Assign("i", Add("i", 1)),
-                Block(CallStmt(Call("a_statement"))));
+                Block(Return()));
   WrapInFunction(f);
 
   GeneratorImpl& gen = Build();
@@ -359,7 +325,7 @@
   ASSERT_TRUE(gen.EmitStatement(f)) << gen.error();
   EXPECT_EQ(gen.result(), R"(  {
     [loop] for(int i = 0; true; i = (i + 1)) {
-      a_statement();
+      return;
     }
   }
 )");
@@ -369,7 +335,6 @@
   // for(var i = true && false; true && false; i = true && false) {
   //   return;
   // }
-  Func("a_statement", {}, ty.void_(), {});
 
   auto* multi_stmt_a = create<ast::BinaryExpression>(ast::BinaryOp::kLogicalAnd,
                                                      Expr(true), Expr(false));
@@ -378,9 +343,8 @@
   auto* multi_stmt_c = create<ast::BinaryExpression>(ast::BinaryOp::kLogicalAnd,
                                                      Expr(true), Expr(false));
 
-  auto* f =
-      For(Decl(Var("i", nullptr, multi_stmt_a)), multi_stmt_b,
-          Assign("i", multi_stmt_c), Block(CallStmt(Call("a_statement"))));
+  auto* f = For(Decl(Var("i", nullptr, multi_stmt_a)), multi_stmt_b,
+                Assign("i", multi_stmt_c), Block(Return()));
   WrapInFunction(f);
 
   GeneratorImpl& gen = Build();
@@ -400,7 +364,7 @@
         tint_tmp_1 = false;
       }
       if (!((tint_tmp_1))) { break; }
-      a_statement();
+      return;
       bool tint_tmp_2 = true;
       if (tint_tmp_2) {
         tint_tmp_2 = false;
diff --git a/src/writer/msl/generator_impl_continue_test.cc b/src/writer/msl/generator_impl_continue_test.cc
index 72eb505..cb3b932 100644
--- a/src/writer/msl/generator_impl_continue_test.cc
+++ b/src/writer/msl/generator_impl_continue_test.cc
@@ -22,7 +22,8 @@
 using MslGeneratorImplTest = TestHelper;
 
 TEST_F(MslGeneratorImplTest, Emit_Continue) {
-  auto* loop = Loop(Block(create<ast::ContinueStatement>()));
+  auto* loop = Loop(Block(If(false, Block(Break())),  //
+                          Continue()));
   WrapInFunction(loop);
 
   GeneratorImpl& gen = Build();
@@ -31,6 +32,9 @@
 
   ASSERT_TRUE(gen.EmitStatement(loop)) << gen.error();
   EXPECT_EQ(gen.result(), R"(  while (true) {
+    if (false) {
+      break;
+    }
     continue;
   }
 )");
diff --git a/src/writer/msl/generator_impl_loop_test.cc b/src/writer/msl/generator_impl_loop_test.cc
index 7cbf492..de0603f 100644
--- a/src/writer/msl/generator_impl_loop_test.cc
+++ b/src/writer/msl/generator_impl_loop_test.cc
@@ -106,27 +106,14 @@
   //   }
   // }
   //
-  // ->
-  // {
-  //   float lhs;
-  //   float other;
-  //   for (;;) {
-  //     if (continuing) {
-  //       lhs = rhs;
-  //     }
-  //     lhs = 2.4f;
-  //     other = 0.0f;
-  //   }
-  // }
 
   Global("rhs", ty.f32(), ast::StorageClass::kPrivate);
 
-  auto* var = Var("lhs", ty.f32(), ast::StorageClass::kNone, Expr(2.4f));
-
-  auto* body = Block(Decl(var), Decl(Var("other", ty.f32())));
+  auto* body = Block(Decl(Var("lhs", ty.f32(), Expr(2.4f))),  //
+                     Decl(Var("other", ty.f32())),            //
+                     Break());
 
   auto* continuing = Block(Assign("lhs", "rhs"));
-
   auto* outer = Loop(body, continuing);
   WrapInFunction(outer);
 
@@ -138,6 +125,7 @@
   EXPECT_EQ(gen.result(), R"(  while (true) {
     float lhs = 2.400000095f;
     float other = 0.0f;
+    break;
     {
       lhs = rhs;
     }
@@ -150,10 +138,8 @@
   //   return;
   // }
 
-  Func("a_statement", {}, ty.void_(), {});
-
-  auto* f =
-      For(nullptr, nullptr, nullptr, Block(CallStmt(Call("a_statement"))));
+  auto* f = For(nullptr, nullptr, nullptr,  //
+                Block(Return()));
   WrapInFunction(f);
 
   GeneratorImpl& gen = Build();
@@ -162,7 +148,7 @@
 
   ASSERT_TRUE(gen.EmitStatement(f)) << gen.error();
   EXPECT_EQ(gen.result(), R"(  for(; ; ) {
-    a_statement();
+    return;
   }
 )");
 }
@@ -172,10 +158,8 @@
   //   return;
   // }
 
-  Func("a_statement", {}, ty.void_(), {});
-
-  auto* f = For(Decl(Var("i", ty.i32())), nullptr, nullptr,
-                Block(CallStmt(Call("a_statement"))));
+  auto* f = For(Decl(Var("i", ty.i32())), nullptr, nullptr,  //
+                Block(Return()));
   WrapInFunction(f);
 
   GeneratorImpl& gen = Build();
@@ -184,7 +168,7 @@
 
   ASSERT_TRUE(gen.EmitStatement(f)) << gen.error();
   EXPECT_EQ(gen.result(), R"(  for(int i = 0; ; ) {
-    a_statement();
+    return;
   }
 )");
 }
@@ -200,12 +184,10 @@
   Func("f", {Param("i", ty.i32())}, ty.void_(), {});
   auto f = [&](auto&& expr) { return CallStmt(Call("f", expr)); };
 
-  Func("a_statement", {}, ty.void_(), {});
-
   Global("a", ty.atomic<i32>(), ast::StorageClass::kWorkgroup);
   auto* multi_stmt = Block(f(1), f(2));
-  auto* loop =
-      For(multi_stmt, nullptr, nullptr, Block(CallStmt(Call("a_statement"))));
+  auto* loop = For(multi_stmt, nullptr, nullptr,  //
+                   Block(Return()));
   WrapInFunction(loop);
 
   GeneratorImpl& gen = Build();
@@ -219,7 +201,7 @@
       f(2);
     }
     for(; ; ) {
-      a_statement();
+      return;
     }
   }
 )");
@@ -230,9 +212,8 @@
   //   return;
   // }
 
-  Func("a_statement", {}, ty.void_(), {});
-
-  auto* f = For(nullptr, true, nullptr, Block(CallStmt(Call("a_statement"))));
+  auto* f = For(nullptr, true, nullptr,  //
+                Block(Return()));
   WrapInFunction(f);
 
   GeneratorImpl& gen = Build();
@@ -241,7 +222,7 @@
 
   ASSERT_TRUE(gen.EmitStatement(f)) << gen.error();
   EXPECT_EQ(gen.result(), R"(  for(; true; ) {
-    a_statement();
+    return;
   }
 )");
 }
@@ -251,11 +232,9 @@
   //   return;
   // }
 
-  Func("a_statement", {}, ty.void_(), {});
-
   auto* v = Decl(Var("i", ty.i32()));
-  auto* f = For(nullptr, nullptr, Assign("i", Add("i", 1)),
-                Block(CallStmt(Call("a_statement"))));
+  auto* f = For(nullptr, nullptr, Assign("i", Add("i", 1)),  //
+                Block(Return()));
   WrapInFunction(v, f);
 
   GeneratorImpl& gen = Build();
@@ -266,7 +245,7 @@
   EXPECT_EQ(
       gen.result(),
       R"(  for(; ; i = as_type<int>((as_type<uint>(i) + as_type<uint>(1)))) {
-    a_statement();
+    return;
   }
 )");
 }
@@ -282,12 +261,10 @@
   Func("f", {Param("i", ty.i32())}, ty.void_(), {});
   auto f = [&](auto&& expr) { return CallStmt(Call("f", expr)); };
 
-  Func("a_statement", {}, ty.void_(), {});
-
   Global("a", ty.atomic<i32>(), ast::StorageClass::kWorkgroup);
   auto* multi_stmt = Block(f(1), f(2));
-  auto* loop =
-      For(nullptr, nullptr, multi_stmt, Block(CallStmt(Call("a_statement"))));
+  auto* loop = For(nullptr, nullptr, multi_stmt,  //
+                   Block(Return()));
   WrapInFunction(loop);
 
   GeneratorImpl& gen = Build();
@@ -296,7 +273,7 @@
 
   ASSERT_TRUE(gen.EmitStatement(loop)) << gen.error();
   EXPECT_EQ(gen.result(), R"(  while (true) {
-    a_statement();
+    return;
     {
       f(1);
       f(2);
@@ -340,13 +317,11 @@
   Func("f", {Param("i", ty.i32())}, ty.void_(), {});
   auto f = [&](auto&& expr) { return CallStmt(Call("f", expr)); };
 
-  Func("a_statement", {}, ty.void_(), {});
-
   Global("a", ty.atomic<i32>(), ast::StorageClass::kWorkgroup);
   auto* multi_stmt_a = Block(f(1), f(2));
   auto* multi_stmt_b = Block(f(3), f(4));
-  auto* loop = For(multi_stmt_a, Expr(true), multi_stmt_b,
-                   Block(CallStmt(Call("a_statement"))));
+  auto* loop = For(multi_stmt_a, Expr(true), multi_stmt_b,  //
+                   Block(Return()));
   WrapInFunction(loop);
 
   GeneratorImpl& gen = Build();
@@ -361,7 +336,7 @@
     }
     while (true) {
       if (!(true)) { break; }
-      a_statement();
+      return;
       {
         f(3);
         f(4);
diff --git a/src/writer/spirv/builder_if_test.cc b/src/writer/spirv/builder_if_test.cc
index b67a4aa..f03d373 100644
--- a/src/writer/spirv/builder_if_test.cc
+++ b/src/writer/spirv/builder_if_test.cc
@@ -25,10 +25,7 @@
 TEST_F(BuilderTest, If_Empty) {
   // if (true) {
   // }
-  auto* cond = Expr(true);
-
-  auto* expr =
-      create<ast::IfStatement>(cond, Block(), ast::ElseStatementList{});
+  auto* expr = If(true, Block());
   WrapInFunction(expr);
 
   spirv::Builder& b = Build();
@@ -52,11 +49,9 @@
   // Outside a function.
   // if (true) {
   // }
-  auto* cond = Expr(true);
 
-  ast::ElseStatementList elses;
   auto* block = Block();
-  auto* expr = create<ast::IfStatement>(cond, block, elses);
+  auto* expr = If(true, block);
   WrapInFunction(expr);
 
   spirv::Builder& b = Build();
@@ -75,8 +70,7 @@
 
   auto* var = Global("v", ty.i32(), ast::StorageClass::kPrivate);
   auto* body = Block(Assign("v", 2));
-  auto* expr =
-      create<ast::IfStatement>(Expr(true), body, ast::ElseStatementList{});
+  auto* expr = If(true, body);
   WrapInFunction(expr);
 
   spirv::Builder& b = Build();
@@ -114,9 +108,7 @@
   auto* body = Block(Assign("v", 2));
   auto* else_body = Block(Assign("v", 3));
 
-  auto* expr = create<ast::IfStatement>(
-      Expr(true), body,
-      ast::ElseStatementList{create<ast::ElseStatement>(nullptr, else_body)});
+  auto* expr = If(true, body, Else(else_body));
   WrapInFunction(expr);
 
   spirv::Builder& b = Build();
@@ -158,11 +150,7 @@
   auto* body = Block(Assign("v", 2));
   auto* else_body = Block(Assign("v", 3));
 
-  auto* expr = create<ast::IfStatement>(
-      Expr(true), body,
-      ast::ElseStatementList{
-          create<ast::ElseStatement>(Expr(true), else_body),
-      });
+  auto* expr = If(true, body, Else(true, else_body));
   WrapInFunction(expr);
 
   spirv::Builder& b = Build();
@@ -215,13 +203,10 @@
   auto* elseif_2_body = Block(Assign("v", 4));
   auto* else_body = Block(Assign("v", 5));
 
-  auto* expr = create<ast::IfStatement>(
-      Expr(true), body,
-      ast::ElseStatementList{
-          create<ast::ElseStatement>(Expr(true), elseif_1_body),
-          create<ast::ElseStatement>(Expr(false), elseif_2_body),
-          create<ast::ElseStatement>(nullptr, else_body),
-      });
+  auto* expr = If(true, body,                  //
+                  Else(true, elseif_1_body),   //
+                  Else(false, elseif_2_body),  //
+                  Else(else_body));
   WrapInFunction(expr);
 
   spirv::Builder& b = Build();
@@ -278,10 +263,9 @@
   //   }
   // }
 
-  auto* if_body = Block(create<ast::BreakStatement>());
+  auto* if_body = Block(Break());
 
-  auto* if_stmt =
-      create<ast::IfStatement>(Expr(true), if_body, ast::ElseStatementList{});
+  auto* if_stmt = If(true, if_body);
 
   auto* loop_body = Block(if_stmt);
 
@@ -321,11 +305,9 @@
   //     break;
   //   }
   // }
-  auto* else_body = Block(create<ast::BreakStatement>());
+  auto* else_body = Block(Break());
 
-  auto* if_stmt = create<ast::IfStatement>(
-      Expr(true), Block(),
-      ast::ElseStatementList{create<ast::ElseStatement>(nullptr, else_body)});
+  auto* if_stmt = If(true, Block(), Else(else_body));
 
   auto* loop_body = Block(if_stmt);
 
@@ -360,20 +342,18 @@
 )");
 }
 
-TEST_F(BuilderTest, If_WithContinue) {
+TEST_F(BuilderTest, If_WithContinueAndBreak) {
   // loop {
   //   if (true) {
   //     continue;
+  //   } else {
+  //     break;
   //   }
   // }
-  auto* if_body = Block(create<ast::ContinueStatement>());
 
-  auto* if_stmt =
-      create<ast::IfStatement>(Expr(true), if_body, ast::ElseStatementList{});
+  auto* if_stmt = If(true, Block(Continue()), Else(Block(Break())));
 
-  auto* loop_body = Block(if_stmt);
-
-  auto* expr = Loop(loop_body, Block());
+  auto* expr = Loop(Block(if_stmt), Block());
   WrapInFunction(expr);
 
   spirv::Builder& b = Build();
@@ -391,9 +371,11 @@
 OpBranch %4
 %4 = OpLabel
 OpSelectionMerge %7 None
-OpBranchConditional %6 %8 %7
+OpBranchConditional %6 %8 %9
 %8 = OpLabel
 OpBranch %3
+%9 = OpLabel
+OpBranch %2
 %7 = OpLabel
 OpBranch %3
 %3 = OpLabel
@@ -408,14 +390,13 @@
   //   } else {
   //     continue;
   //   }
+  //   break;
   // }
   auto* else_body = Block(create<ast::ContinueStatement>());
 
-  auto* if_stmt = create<ast::IfStatement>(
-      Expr(true), Block(),
-      ast::ElseStatementList{create<ast::ElseStatement>(nullptr, else_body)});
+  auto* if_stmt = If(true, Block(), Else(else_body));
 
-  auto* loop_body = Block(if_stmt);
+  auto* loop_body = Block(if_stmt, Break());
 
   auto* expr = Loop(loop_body, Block());
   WrapInFunction(expr);
@@ -441,7 +422,7 @@
 %9 = OpLabel
 OpBranch %3
 %7 = OpLabel
-OpBranch %3
+OpBranch %2
 %3 = OpLabel
 OpBranch %1
 %2 = OpLabel
@@ -610,8 +591,7 @@
   //   return;
   // }
 
-  auto* if_stmt = If(Expr(false), Block(),
-                     ast::ElseStatementList{Else(Expr(true), Block(Return()))});
+  auto* if_stmt = If(false, Block(), Else(true, Block(Return())));
   auto* fn = Func("f", {}, ty.void_(), {if_stmt});
 
   spirv::Builder& b = Build();
@@ -649,8 +629,7 @@
   //   }
   // }
 
-  auto* if_stmt = If(Expr(false), Block(),
-                     ast::ElseStatementList{Else(Expr(true), Block(Break()))});
+  auto* if_stmt = If(false, Block(), Else(true, Block(Break())));
   auto* fn = Func("f", {}, ty.void_(), {Loop(Block(if_stmt))});
 
   spirv::Builder& b = Build();
diff --git a/src/writer/spirv/builder_loop_test.cc b/src/writer/spirv/builder_loop_test.cc
index a074461..93b1a02 100644
--- a/src/writer/spirv/builder_loop_test.cc
+++ b/src/writer/spirv/builder_loop_test.cc
@@ -24,9 +24,10 @@
 
 TEST_F(BuilderTest, Loop_Empty) {
   // loop {
+  //   break;
   // }
 
-  auto* loop = Loop(Block(), Block());
+  auto* loop = Loop(Block(Break()), Block());
   WrapInFunction(loop);
 
   spirv::Builder& b = Build();
@@ -40,7 +41,7 @@
 OpLoopMerge %2 %3 None
 OpBranch %4
 %4 = OpLabel
-OpBranch %3
+OpBranch %2
 %3 = OpLabel
 OpBranch %1
 %2 = OpLabel
@@ -50,10 +51,12 @@
 TEST_F(BuilderTest, Loop_WithoutContinuing) {
   // loop {
   //   v = 2;
+  //   break;
   // }
 
   auto* var = Global("v", ty.i32(), ast::StorageClass::kPrivate);
-  auto* body = Block(Assign("v", 2));
+  auto* body = Block(Assign("v", 2),  //
+                     Break());
 
   auto* loop = Loop(body, Block());
   WrapInFunction(loop);
@@ -77,7 +80,7 @@
 OpBranch %8
 %8 = OpLabel
 OpStore %1 %9
-OpBranch %7
+OpBranch %6
 %7 = OpLabel
 OpBranch %5
 %6 = OpLabel
@@ -87,13 +90,15 @@
 TEST_F(BuilderTest, Loop_WithContinuing) {
   // loop {
   //   a = 2;
+  //   break;
   //   continuing {
   //     a = 3;
   //   }
   // }
 
   auto* var = Global("v", ty.i32(), ast::StorageClass::kPrivate);
-  auto* body = Block(Assign("v", 2));
+  auto* body = Block(Assign("v", 2),  //
+                     Break());
   auto* continuing = Block(Assign("v", 3));
 
   auto* loop = Loop(body, continuing);
@@ -119,7 +124,7 @@
 OpBranch %8
 %8 = OpLabel
 OpStore %1 %9
-OpBranch %7
+OpBranch %6
 %7 = OpLabel
 OpStore %1 %10
 OpBranch %5
@@ -130,14 +135,14 @@
 TEST_F(BuilderTest, Loop_WithBodyVariableAccessInContinuing) {
   // loop {
   //   var a : i32;
+  //   break;
   //   continuing {
   //     a = 3;
   //   }
   // }
 
-  auto* var = Var("a", ty.i32());
-  auto* var_decl = WrapInStatement(var);
-  auto* body = Block(var_decl);
+  auto* body = Block(Decl(Var("a", ty.i32())),  //
+                     Break());
   auto* continuing = Block(Assign("a", 3));
 
   auto* loop = Loop(body, continuing);
@@ -159,7 +164,7 @@
 OpLoopMerge %2 %3 None
 OpBranch %4
 %4 = OpLabel
-OpBranch %3
+OpBranch %2
 %3 = OpLabel
 OpStore %5 %9
 OpBranch %1
@@ -169,9 +174,11 @@
 
 TEST_F(BuilderTest, Loop_WithContinue) {
   // loop {
+  //   if (false) { break; }
   //   continue;
   // }
-  auto* body = Block(create<ast::ContinueStatement>());
+  auto* body = Block(If(false, Block(Break())),  //
+                     Continue());
   auto* loop = Loop(body, Block());
   WrapInFunction(loop);
 
@@ -186,6 +193,11 @@
 OpLoopMerge %2 %3 None
 OpBranch %4
 %4 = OpLabel
+OpSelectionMerge %7 None
+OpBranchConditional %6 %8 %7
+%8 = OpLabel
+OpBranch %2
+%7 = OpLabel
 OpBranch %3
 %3 = OpLabel
 OpBranch %1
diff --git a/src/writer/wgsl/generator_impl_continue_test.cc b/src/writer/wgsl/generator_impl_continue_test.cc
index 497acee..d73c3d5 100644
--- a/src/writer/wgsl/generator_impl_continue_test.cc
+++ b/src/writer/wgsl/generator_impl_continue_test.cc
@@ -22,8 +22,10 @@
 using WgslGeneratorImplTest = TestHelper;
 
 TEST_F(WgslGeneratorImplTest, Emit_Continue) {
-  auto* c = create<ast::ContinueStatement>();
-  WrapInFunction(Loop(Block(c)));
+  auto* c = Continue();
+
+  WrapInFunction(Loop(Block(If(false, Block(Break())),  //
+                            c)));
 
   GeneratorImpl& gen = Build();
 
diff --git a/test/bug/tint/990.wgsl b/test/bug/tint/990.wgsl
index 3f31b56..8931dbb 100644
--- a/test/bug/tint/990.wgsl
+++ b/test/bug/tint/990.wgsl
@@ -1,4 +1,4 @@
 fn f() {
     var i : i32;
-    for (let p = &i;;) {}
+    for (let p = &i; false;) {}
 }
diff --git a/test/bug/tint/990.wgsl.expected.hlsl b/test/bug/tint/990.wgsl.expected.hlsl
index 49ec198..43e268e 100644
--- a/test/bug/tint/990.wgsl.expected.hlsl
+++ b/test/bug/tint/990.wgsl.expected.hlsl
@@ -6,7 +6,7 @@
 void f() {
   int i = 0;
   {
-    [loop] for(; ; ) {
+    [loop] for(; false; ) {
     }
   }
 }
diff --git a/test/bug/tint/990.wgsl.expected.msl b/test/bug/tint/990.wgsl.expected.msl
index 62e37ce..1725260 100644
--- a/test/bug/tint/990.wgsl.expected.msl
+++ b/test/bug/tint/990.wgsl.expected.msl
@@ -3,7 +3,7 @@
 using namespace metal;
 void f() {
   int i = 0;
-  for(; ; ) {
+  for(; false; ) {
   }
 }
 
diff --git a/test/bug/tint/990.wgsl.expected.spvasm b/test/bug/tint/990.wgsl.expected.spvasm
index a63370b..90b0f54 100644
--- a/test/bug/tint/990.wgsl.expected.spvasm
+++ b/test/bug/tint/990.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 0
-; Bound: 15
+; Bound: 20
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
@@ -15,6 +15,8 @@
         %int = OpTypeInt 32 1
 %_ptr_Function_int = OpTypePointer Function %int
          %10 = OpConstantNull %int
+       %bool = OpTypeBool
+      %false = OpConstantFalse %bool
 %unused_entry_point = OpFunction %void None %1
           %4 = OpLabel
                OpReturn
@@ -27,6 +29,12 @@
                OpLoopMerge %12 %13 None
                OpBranch %14
          %14 = OpLabel
+         %15 = OpLogicalNot %bool %false
+               OpSelectionMerge %18 None
+               OpBranchConditional %15 %19 %18
+         %19 = OpLabel
+               OpBranch %12
+         %18 = OpLabel
                OpBranch %13
          %13 = OpLabel
                OpBranch %11
diff --git a/test/bug/tint/990.wgsl.expected.wgsl b/test/bug/tint/990.wgsl.expected.wgsl
index e51a467..7062a59 100644
--- a/test/bug/tint/990.wgsl.expected.wgsl
+++ b/test/bug/tint/990.wgsl.expected.wgsl
@@ -1,5 +1,5 @@
 fn f() {
   var i : i32;
-  for(let p = &(i); ; ) {
+  for(let p = &(i); false; ) {
   }
 }
diff --git a/test/loops/continue_in_switch.wgsl.expected.hlsl b/test/loops/continue_in_switch.wgsl.expected.hlsl
index 9c3feb7..773a4ce 100644
--- a/test/loops/continue_in_switch.wgsl.expected.hlsl
+++ b/test/loops/continue_in_switch.wgsl.expected.hlsl
@@ -18,4 +18,3 @@
   return;
 }
 C:\src\tint\test\Shader@0x000001A817AB3700(7,11-19): error X3708: continue cannot be used in a switch
-
diff --git a/test/statements/for/continuing/array_ctor.wgsl b/test/statements/for/continuing/array_ctor.wgsl
index 821777d..fcaa6f7 100644
--- a/test/statements/for/continuing/array_ctor.wgsl
+++ b/test/statements/for/continuing/array_ctor.wgsl
@@ -1,4 +1,4 @@
 fn f() {
   var i : i32;
-  for (;;i = i + array<i32, 1>(1)[0]) {}
+  for (; false; i = i + array<i32, 1>(1)[0]) {}
 }
diff --git a/test/statements/for/continuing/array_ctor.wgsl.expected.hlsl b/test/statements/for/continuing/array_ctor.wgsl.expected.hlsl
index df66919..e24b634 100644
--- a/test/statements/for/continuing/array_ctor.wgsl.expected.hlsl
+++ b/test/statements/for/continuing/array_ctor.wgsl.expected.hlsl
@@ -6,6 +6,9 @@
 void f() {
   int i = 0;
   [loop] while (true) {
+    if (!(false)) {
+      break;
+    }
     {
       const int tint_symbol[1] = {1};
       i = (i + tint_symbol[0]);
diff --git a/test/statements/for/continuing/array_ctor.wgsl.expected.msl b/test/statements/for/continuing/array_ctor.wgsl.expected.msl
index cb9f3f6..5339dfa 100644
--- a/test/statements/for/continuing/array_ctor.wgsl.expected.msl
+++ b/test/statements/for/continuing/array_ctor.wgsl.expected.msl
@@ -8,6 +8,9 @@
 void f() {
   int i = 0;
   while (true) {
+    if (!(false)) {
+      break;
+    }
     {
       tint_array_wrapper const tint_symbol = {.arr={1}};
       i = as_type<int>((as_type<uint>(i) + as_type<uint>(tint_symbol.arr[0])));
diff --git a/test/statements/for/continuing/array_ctor.wgsl.expected.spvasm b/test/statements/for/continuing/array_ctor.wgsl.expected.spvasm
index 8c32307..8584109 100644
--- a/test/statements/for/continuing/array_ctor.wgsl.expected.spvasm
+++ b/test/statements/for/continuing/array_ctor.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 0
-; Bound: 24
+; Bound: 29
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
@@ -16,11 +16,13 @@
         %int = OpTypeInt 32 1
 %_ptr_Function_int = OpTypePointer Function %int
          %10 = OpConstantNull %int
+       %bool = OpTypeBool
+      %false = OpConstantFalse %bool
        %uint = OpTypeInt 32 0
      %uint_1 = OpConstant %uint 1
 %_arr_int_uint_1 = OpTypeArray %int %uint_1
       %int_1 = OpConstant %int 1
-         %20 = OpConstantComposite %_arr_int_uint_1 %int_1
+         %25 = OpConstantComposite %_arr_int_uint_1 %int_1
       %int_0 = OpConstant %int 0
 %unused_entry_point = OpFunction %void None %1
           %4 = OpLabel
@@ -34,12 +36,18 @@
                OpLoopMerge %12 %13 None
                OpBranch %14
          %14 = OpLabel
+         %15 = OpLogicalNot %bool %false
+               OpSelectionMerge %18 None
+               OpBranchConditional %15 %19 %18
+         %19 = OpLabel
+               OpBranch %12
+         %18 = OpLabel
                OpBranch %13
          %13 = OpLabel
-         %15 = OpLoad %int %i
-         %22 = OpCompositeExtract %int %20 0
-         %23 = OpIAdd %int %15 %22
-               OpStore %i %23
+         %20 = OpLoad %int %i
+         %27 = OpCompositeExtract %int %25 0
+         %28 = OpIAdd %int %20 %27
+               OpStore %i %28
                OpBranch %11
          %12 = OpLabel
                OpReturn
diff --git a/test/statements/for/continuing/array_ctor.wgsl.expected.wgsl b/test/statements/for/continuing/array_ctor.wgsl.expected.wgsl
index 21d2c5a..a3ceb4a 100644
--- a/test/statements/for/continuing/array_ctor.wgsl.expected.wgsl
+++ b/test/statements/for/continuing/array_ctor.wgsl.expected.wgsl
@@ -1,5 +1,5 @@
 fn f() {
   var i : i32;
-  for(; ; i = (i + array<i32, 1>(1)[0])) {
+  for(; false; i = (i + array<i32, 1>(1)[0])) {
   }
 }
diff --git a/test/statements/for/continuing/basic.wgsl b/test/statements/for/continuing/basic.wgsl
index 745661c..5ea0540 100644
--- a/test/statements/for/continuing/basic.wgsl
+++ b/test/statements/for/continuing/basic.wgsl
@@ -1,4 +1,4 @@
 fn f() {
   var i : i32;
-  for (;;i = i + 1) {}
+  for (; false; i = i + 1) {}
 }
diff --git a/test/statements/for/continuing/basic.wgsl.expected.hlsl b/test/statements/for/continuing/basic.wgsl.expected.hlsl
index 3e2e847..6b8fc8f 100644
--- a/test/statements/for/continuing/basic.wgsl.expected.hlsl
+++ b/test/statements/for/continuing/basic.wgsl.expected.hlsl
@@ -6,7 +6,7 @@
 void f() {
   int i = 0;
   {
-    [loop] for(; ; i = (i + 1)) {
+    [loop] for(; false; i = (i + 1)) {
     }
   }
 }
diff --git a/test/statements/for/continuing/basic.wgsl.expected.msl b/test/statements/for/continuing/basic.wgsl.expected.msl
index 6426654..3130ddd 100644
--- a/test/statements/for/continuing/basic.wgsl.expected.msl
+++ b/test/statements/for/continuing/basic.wgsl.expected.msl
@@ -3,7 +3,7 @@
 using namespace metal;
 void f() {
   int i = 0;
-  for(; ; i = as_type<int>((as_type<uint>(i) + as_type<uint>(1)))) {
+  for(; false; i = as_type<int>((as_type<uint>(i) + as_type<uint>(1)))) {
   }
 }
 
diff --git a/test/statements/for/continuing/basic.wgsl.expected.spvasm b/test/statements/for/continuing/basic.wgsl.expected.spvasm
index 572838e..a7378a0 100644
--- a/test/statements/for/continuing/basic.wgsl.expected.spvasm
+++ b/test/statements/for/continuing/basic.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 0
-; Bound: 18
+; Bound: 23
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
@@ -15,6 +15,8 @@
         %int = OpTypeInt 32 1
 %_ptr_Function_int = OpTypePointer Function %int
          %10 = OpConstantNull %int
+       %bool = OpTypeBool
+      %false = OpConstantFalse %bool
       %int_1 = OpConstant %int 1
 %unused_entry_point = OpFunction %void None %1
           %4 = OpLabel
@@ -28,11 +30,17 @@
                OpLoopMerge %12 %13 None
                OpBranch %14
          %14 = OpLabel
+         %15 = OpLogicalNot %bool %false
+               OpSelectionMerge %18 None
+               OpBranchConditional %15 %19 %18
+         %19 = OpLabel
+               OpBranch %12
+         %18 = OpLabel
                OpBranch %13
          %13 = OpLabel
-         %15 = OpLoad %int %i
-         %17 = OpIAdd %int %15 %int_1
-               OpStore %i %17
+         %20 = OpLoad %int %i
+         %22 = OpIAdd %int %20 %int_1
+               OpStore %i %22
                OpBranch %11
          %12 = OpLabel
                OpReturn
diff --git a/test/statements/for/continuing/basic.wgsl.expected.wgsl b/test/statements/for/continuing/basic.wgsl.expected.wgsl
index c76b514..d5320b4 100644
--- a/test/statements/for/continuing/basic.wgsl.expected.wgsl
+++ b/test/statements/for/continuing/basic.wgsl.expected.wgsl
@@ -1,5 +1,5 @@
 fn f() {
   var i : i32;
-  for(; ; i = (i + 1)) {
+  for(; false; i = (i + 1)) {
   }
 }
diff --git a/test/statements/for/continuing/struct_ctor.wgsl b/test/statements/for/continuing/struct_ctor.wgsl
index cf02a48..362becd 100644
--- a/test/statements/for/continuing/struct_ctor.wgsl
+++ b/test/statements/for/continuing/struct_ctor.wgsl
@@ -3,5 +3,5 @@
 };
 
 fn f() {
-  for (var i = 0;; i = i + S(1).i) {}
+  for (var i = 0; false; i = i + S(1).i) {}
 }
diff --git a/test/statements/for/continuing/struct_ctor.wgsl.expected.hlsl b/test/statements/for/continuing/struct_ctor.wgsl.expected.hlsl
index 1612668..671f26f 100644
--- a/test/statements/for/continuing/struct_ctor.wgsl.expected.hlsl
+++ b/test/statements/for/continuing/struct_ctor.wgsl.expected.hlsl
@@ -11,6 +11,9 @@
   {
     int i = 0;
     [loop] while (true) {
+      if (!(false)) {
+        break;
+      }
       {
         const S tint_symbol = {1};
         i = (i + tint_symbol.i);
diff --git a/test/statements/for/continuing/struct_ctor.wgsl.expected.msl b/test/statements/for/continuing/struct_ctor.wgsl.expected.msl
index d19c0d2..a022488 100644
--- a/test/statements/for/continuing/struct_ctor.wgsl.expected.msl
+++ b/test/statements/for/continuing/struct_ctor.wgsl.expected.msl
@@ -9,6 +9,9 @@
   {
     int i = 0;
     while (true) {
+      if (!(false)) {
+        break;
+      }
       {
         S const tint_symbol = {.i=1};
         i = as_type<int>((as_type<uint>(i) + as_type<uint>(tint_symbol.i)));
diff --git a/test/statements/for/continuing/struct_ctor.wgsl.expected.spvasm b/test/statements/for/continuing/struct_ctor.wgsl.expected.spvasm
index a7942c3..11f198c 100644
--- a/test/statements/for/continuing/struct_ctor.wgsl.expected.spvasm
+++ b/test/statements/for/continuing/struct_ctor.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 0
-; Bound: 22
+; Bound: 27
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
@@ -19,9 +19,11 @@
       %int_0 = OpConstant %int 0
 %_ptr_Function_int = OpTypePointer Function %int
          %11 = OpConstantNull %int
+       %bool = OpTypeBool
+      %false = OpConstantFalse %bool
           %S = OpTypeStruct %int
       %int_1 = OpConstant %int 1
-         %19 = OpConstantComposite %S %int_1
+         %24 = OpConstantComposite %S %int_1
 %unused_entry_point = OpFunction %void None %1
           %4 = OpLabel
                OpReturn
@@ -35,12 +37,18 @@
                OpLoopMerge %13 %14 None
                OpBranch %15
          %15 = OpLabel
+         %16 = OpLogicalNot %bool %false
+               OpSelectionMerge %19 None
+               OpBranchConditional %16 %20 %19
+         %20 = OpLabel
+               OpBranch %13
+         %19 = OpLabel
                OpBranch %14
          %14 = OpLabel
-         %16 = OpLoad %int %i
-         %20 = OpCompositeExtract %int %19 0
-         %21 = OpIAdd %int %16 %20
-               OpStore %i %21
+         %21 = OpLoad %int %i
+         %25 = OpCompositeExtract %int %24 0
+         %26 = OpIAdd %int %21 %25
+               OpStore %i %26
                OpBranch %12
          %13 = OpLabel
                OpReturn
diff --git a/test/statements/for/continuing/struct_ctor.wgsl.expected.wgsl b/test/statements/for/continuing/struct_ctor.wgsl.expected.wgsl
index c51ce52..7baa234 100644
--- a/test/statements/for/continuing/struct_ctor.wgsl.expected.wgsl
+++ b/test/statements/for/continuing/struct_ctor.wgsl.expected.wgsl
@@ -3,6 +3,6 @@
 };
 
 fn f() {
-  for(var i = 0; ; i = (i + S(1).i)) {
+  for(var i = 0; false; i = (i + S(1).i)) {
   }
 }
diff --git a/test/statements/for/empty.wgsl b/test/statements/for/empty.wgsl
index 5e08648..1301561 100644
--- a/test/statements/for/empty.wgsl
+++ b/test/statements/for/empty.wgsl
@@ -1,3 +1,3 @@
 fn f() {
-    for (;;) {}
+    for (; false;) {}
 }
diff --git a/test/statements/for/empty.wgsl.expected.hlsl b/test/statements/for/empty.wgsl.expected.hlsl
index fe6edee..dcc6c45 100644
--- a/test/statements/for/empty.wgsl.expected.hlsl
+++ b/test/statements/for/empty.wgsl.expected.hlsl
@@ -5,7 +5,7 @@
 
 void f() {
   {
-    [loop] for(; ; ) {
+    [loop] for(; false; ) {
     }
   }
 }
diff --git a/test/statements/for/empty.wgsl.expected.msl b/test/statements/for/empty.wgsl.expected.msl
index e716521..a8d3f51 100644
--- a/test/statements/for/empty.wgsl.expected.msl
+++ b/test/statements/for/empty.wgsl.expected.msl
@@ -2,7 +2,7 @@
 
 using namespace metal;
 void f() {
-  for(; ; ) {
+  for(; false; ) {
   }
 }
 
diff --git a/test/statements/for/empty.wgsl.expected.spvasm b/test/statements/for/empty.wgsl.expected.spvasm
index 4cbeee3..da1d1d0 100644
--- a/test/statements/for/empty.wgsl.expected.spvasm
+++ b/test/statements/for/empty.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 0
-; Bound: 11
+; Bound: 16
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
@@ -11,6 +11,8 @@
                OpName %f "f"
        %void = OpTypeVoid
           %1 = OpTypeFunction %void
+       %bool = OpTypeBool
+      %false = OpConstantFalse %bool
 %unused_entry_point = OpFunction %void None %1
           %4 = OpLabel
                OpReturn
@@ -22,6 +24,12 @@
                OpLoopMerge %8 %9 None
                OpBranch %10
          %10 = OpLabel
+         %11 = OpLogicalNot %bool %false
+               OpSelectionMerge %14 None
+               OpBranchConditional %11 %15 %14
+         %15 = OpLabel
+               OpBranch %8
+         %14 = OpLabel
                OpBranch %9
           %9 = OpLabel
                OpBranch %7
diff --git a/test/statements/for/empty.wgsl.expected.wgsl b/test/statements/for/empty.wgsl.expected.wgsl
index 9f110c8..ed53a04 100644
--- a/test/statements/for/empty.wgsl.expected.wgsl
+++ b/test/statements/for/empty.wgsl.expected.wgsl
@@ -1,4 +1,4 @@
 fn f() {
-  for(; ; ) {
+  for(; false; ) {
   }
 }
diff --git a/test/statements/for/initializer/array_ctor.wgsl b/test/statements/for/initializer/array_ctor.wgsl
index 06f1d9b..20f8617 100644
--- a/test/statements/for/initializer/array_ctor.wgsl
+++ b/test/statements/for/initializer/array_ctor.wgsl
@@ -1,3 +1,3 @@
 fn f() {
-    for (var i : i32 = array<i32, 1>(1)[0];;) {}
+    for (var i : i32 = array<i32, 1>(1)[0]; false;) {}
 }
diff --git a/test/statements/for/initializer/array_ctor.wgsl.expected.hlsl b/test/statements/for/initializer/array_ctor.wgsl.expected.hlsl
index 4f60bdb..1de4bce 100644
--- a/test/statements/for/initializer/array_ctor.wgsl.expected.hlsl
+++ b/test/statements/for/initializer/array_ctor.wgsl.expected.hlsl
@@ -6,7 +6,7 @@
 void f() {
   const int tint_symbol[1] = {1};
   {
-    [loop] for(int i = tint_symbol[0]; ; ) {
+    [loop] for(int i = tint_symbol[0]; false; ) {
     }
   }
 }
diff --git a/test/statements/for/initializer/array_ctor.wgsl.expected.msl b/test/statements/for/initializer/array_ctor.wgsl.expected.msl
index d4427b2..aa3d065 100644
--- a/test/statements/for/initializer/array_ctor.wgsl.expected.msl
+++ b/test/statements/for/initializer/array_ctor.wgsl.expected.msl
@@ -7,7 +7,7 @@
 
 void f() {
   tint_array_wrapper const tint_symbol = {.arr={1}};
-  for(int i = tint_symbol.arr[0]; ; ) {
+  for(int i = tint_symbol.arr[0]; false; ) {
   }
 }
 
diff --git a/test/statements/for/initializer/array_ctor.wgsl.expected.spvasm b/test/statements/for/initializer/array_ctor.wgsl.expected.spvasm
index 5587397..1cd44b8 100644
--- a/test/statements/for/initializer/array_ctor.wgsl.expected.spvasm
+++ b/test/statements/for/initializer/array_ctor.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 0
-; Bound: 22
+; Bound: 27
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
@@ -22,6 +22,8 @@
       %int_0 = OpConstant %int 0
 %_ptr_Function_int = OpTypePointer Function %int
          %17 = OpConstantNull %int
+       %bool = OpTypeBool
+      %false = OpConstantFalse %bool
 %unused_entry_point = OpFunction %void None %1
           %4 = OpLabel
                OpReturn
@@ -36,6 +38,12 @@
                OpLoopMerge %19 %20 None
                OpBranch %21
          %21 = OpLabel
+         %22 = OpLogicalNot %bool %false
+               OpSelectionMerge %25 None
+               OpBranchConditional %22 %26 %25
+         %26 = OpLabel
+               OpBranch %19
+         %25 = OpLabel
                OpBranch %20
          %20 = OpLabel
                OpBranch %18
diff --git a/test/statements/for/initializer/array_ctor.wgsl.expected.wgsl b/test/statements/for/initializer/array_ctor.wgsl.expected.wgsl
index 91b2f5b..fd5da0c 100644
--- a/test/statements/for/initializer/array_ctor.wgsl.expected.wgsl
+++ b/test/statements/for/initializer/array_ctor.wgsl.expected.wgsl
@@ -1,4 +1,4 @@
 fn f() {
-  for(var i : i32 = array<i32, 1>(1)[0]; ; ) {
+  for(var i : i32 = array<i32, 1>(1)[0]; false; ) {
   }
 }
diff --git a/test/statements/for/initializer/basic.wgsl b/test/statements/for/initializer/basic.wgsl
index cf5a1fd..12aeace 100644
--- a/test/statements/for/initializer/basic.wgsl
+++ b/test/statements/for/initializer/basic.wgsl
@@ -1,3 +1,3 @@
 fn f() {
-  for (var i : i32 = 0;;) {}
+  for (var i : i32 = 0; false;) {}
 }
diff --git a/test/statements/for/initializer/basic.wgsl.expected.hlsl b/test/statements/for/initializer/basic.wgsl.expected.hlsl
index 57b4e10..2ae9892 100644
--- a/test/statements/for/initializer/basic.wgsl.expected.hlsl
+++ b/test/statements/for/initializer/basic.wgsl.expected.hlsl
@@ -5,7 +5,7 @@
 
 void f() {
   {
-    [loop] for(int i = 0; ; ) {
+    [loop] for(int i = 0; false; ) {
     }
   }
 }
diff --git a/test/statements/for/initializer/basic.wgsl.expected.msl b/test/statements/for/initializer/basic.wgsl.expected.msl
index 90082d6..caf48e3 100644
--- a/test/statements/for/initializer/basic.wgsl.expected.msl
+++ b/test/statements/for/initializer/basic.wgsl.expected.msl
@@ -2,7 +2,7 @@
 
 using namespace metal;
 void f() {
-  for(int i = 0; ; ) {
+  for(int i = 0; false; ) {
   }
 }
 
diff --git a/test/statements/for/initializer/basic.wgsl.expected.spvasm b/test/statements/for/initializer/basic.wgsl.expected.spvasm
index d0158fb..70e3005 100644
--- a/test/statements/for/initializer/basic.wgsl.expected.spvasm
+++ b/test/statements/for/initializer/basic.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 0
-; Bound: 16
+; Bound: 21
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
@@ -16,6 +16,8 @@
       %int_0 = OpConstant %int 0
 %_ptr_Function_int = OpTypePointer Function %int
          %11 = OpConstantNull %int
+       %bool = OpTypeBool
+      %false = OpConstantFalse %bool
 %unused_entry_point = OpFunction %void None %1
           %4 = OpLabel
                OpReturn
@@ -29,6 +31,12 @@
                OpLoopMerge %13 %14 None
                OpBranch %15
          %15 = OpLabel
+         %16 = OpLogicalNot %bool %false
+               OpSelectionMerge %19 None
+               OpBranchConditional %16 %20 %19
+         %20 = OpLabel
+               OpBranch %13
+         %19 = OpLabel
                OpBranch %14
          %14 = OpLabel
                OpBranch %12
diff --git a/test/statements/for/initializer/basic.wgsl.expected.wgsl b/test/statements/for/initializer/basic.wgsl.expected.wgsl
index 797a92f..f92f080 100644
--- a/test/statements/for/initializer/basic.wgsl.expected.wgsl
+++ b/test/statements/for/initializer/basic.wgsl.expected.wgsl
@@ -1,4 +1,4 @@
 fn f() {
-  for(var i : i32 = 0; ; ) {
+  for(var i : i32 = 0; false; ) {
   }
 }
diff --git a/test/statements/for/initializer/struct_ctor.wgsl b/test/statements/for/initializer/struct_ctor.wgsl
index 5b0b5ba..40e0913 100644
--- a/test/statements/for/initializer/struct_ctor.wgsl
+++ b/test/statements/for/initializer/struct_ctor.wgsl
@@ -3,5 +3,5 @@
 };
 
 fn f() {
-  for (var i : i32 = S(1).i;;) {}
+  for (var i : i32 = S(1).i; false;) {}
 }
diff --git a/test/statements/for/initializer/struct_ctor.wgsl.expected.hlsl b/test/statements/for/initializer/struct_ctor.wgsl.expected.hlsl
index 9cbe791..657fdbe 100644
--- a/test/statements/for/initializer/struct_ctor.wgsl.expected.hlsl
+++ b/test/statements/for/initializer/struct_ctor.wgsl.expected.hlsl
@@ -10,7 +10,7 @@
 void f() {
   const S tint_symbol = {1};
   {
-    [loop] for(int i = tint_symbol.i; ; ) {
+    [loop] for(int i = tint_symbol.i; false; ) {
     }
   }
 }
diff --git a/test/statements/for/initializer/struct_ctor.wgsl.expected.msl b/test/statements/for/initializer/struct_ctor.wgsl.expected.msl
index f0ebc83..eb152f7 100644
--- a/test/statements/for/initializer/struct_ctor.wgsl.expected.msl
+++ b/test/statements/for/initializer/struct_ctor.wgsl.expected.msl
@@ -7,7 +7,7 @@
 
 void f() {
   S const tint_symbol = {.i=1};
-  for(int i = tint_symbol.i; ; ) {
+  for(int i = tint_symbol.i; false; ) {
   }
 }
 
diff --git a/test/statements/for/initializer/struct_ctor.wgsl.expected.spvasm b/test/statements/for/initializer/struct_ctor.wgsl.expected.spvasm
index 1cabffb..8e7605a 100644
--- a/test/statements/for/initializer/struct_ctor.wgsl.expected.spvasm
+++ b/test/statements/for/initializer/struct_ctor.wgsl.expected.spvasm
@@ -1,7 +1,7 @@
 ; SPIR-V
 ; Version: 1.3
 ; Generator: Google Tint Compiler; 0
-; Bound: 19
+; Bound: 24
 ; Schema: 0
                OpCapability Shader
                OpMemoryModel Logical GLSL450
@@ -21,6 +21,8 @@
          %10 = OpConstantComposite %S %int_1
 %_ptr_Function_int = OpTypePointer Function %int
          %14 = OpConstantNull %int
+       %bool = OpTypeBool
+      %false = OpConstantFalse %bool
 %unused_entry_point = OpFunction %void None %1
           %4 = OpLabel
                OpReturn
@@ -35,6 +37,12 @@
                OpLoopMerge %16 %17 None
                OpBranch %18
          %18 = OpLabel
+         %19 = OpLogicalNot %bool %false
+               OpSelectionMerge %22 None
+               OpBranchConditional %19 %23 %22
+         %23 = OpLabel
+               OpBranch %16
+         %22 = OpLabel
                OpBranch %17
          %17 = OpLabel
                OpBranch %15
diff --git a/test/statements/for/initializer/struct_ctor.wgsl.expected.wgsl b/test/statements/for/initializer/struct_ctor.wgsl.expected.wgsl
index 9e32474..312aad5 100644
--- a/test/statements/for/initializer/struct_ctor.wgsl.expected.wgsl
+++ b/test/statements/for/initializer/struct_ctor.wgsl.expected.wgsl
@@ -3,6 +3,6 @@
 };
 
 fn f() {
-  for(var i : i32 = S(1).i; ; ) {
+  for(var i : i32 = S(1).i; false; ) {
   }
 }
diff --git a/test/unittest/reader/spirv/SpvLogicalTest_IsNan_Vector.spvasm.expected.hlsl b/test/unittest/reader/spirv/SpvLogicalTest_IsNan_Vector.spvasm.expected.hlsl
index 47b7188..1c4f659 100644
--- a/test/unittest/reader/spirv/SpvLogicalTest_IsNan_Vector.spvasm.expected.hlsl
+++ b/test/unittest/reader/spirv/SpvLogicalTest_IsNan_Vector.spvasm.expected.hlsl
@@ -1,5 +1,6 @@
 SKIP: FAILED
 
+warning: use of deprecated intrinsic
 void main_1() {
   const bool2 x_1 = isnan(float2(50.0f, 60.0f));
   return;
@@ -9,6 +10,3 @@
   main_1();
   return;
 }
-Internal Compiler error: cast<X>() argument of incompatible type!
-
-
diff --git a/test/unittest/reader/spirv/SpvParserCFGTest_ClassifyCFGEdges_LoopBreak_FromLoopBodyDirect.spvasm.expected.hlsl b/test/unittest/reader/spirv/SpvParserCFGTest_ClassifyCFGEdges_LoopBreak_FromLoopBodyDirect.spvasm.expected.hlsl
index 427d211..1c29d0b 100644
--- a/test/unittest/reader/spirv/SpvParserCFGTest_ClassifyCFGEdges_LoopBreak_FromLoopBodyDirect.spvasm.expected.hlsl
+++ b/test/unittest/reader/spirv/SpvParserCFGTest_ClassifyCFGEdges_LoopBreak_FromLoopBodyDirect.spvasm.expected.hlsl
@@ -3,7 +3,7 @@
 static uint var_1 = 0u;
 
 void main_1() {
-  while (true) {
+  [loop] while (true) {
     if (false) {
     } else {
       break;
diff --git a/test/unittest/reader/spirv/SpvParserCFGTest_ClassifyCFGEdges_LoopBreak_FromLoopHeader_SingleBlockLoop_TrueBranch.spvasm.expected.hlsl b/test/unittest/reader/spirv/SpvParserCFGTest_ClassifyCFGEdges_LoopBreak_FromLoopHeader_SingleBlockLoop_TrueBranch.spvasm.expected.hlsl
index 32f9b36..b44e025 100644
--- a/test/unittest/reader/spirv/SpvParserCFGTest_ClassifyCFGEdges_LoopBreak_FromLoopHeader_SingleBlockLoop_TrueBranch.spvasm.expected.hlsl
+++ b/test/unittest/reader/spirv/SpvParserCFGTest_ClassifyCFGEdges_LoopBreak_FromLoopHeader_SingleBlockLoop_TrueBranch.spvasm.expected.hlsl
@@ -4,7 +4,7 @@
 
 void main_1() {
   {
-    for(; !(false); ) {
+    [loop] for(; !(false); ) {
     }
   }
   return;
@@ -17,7 +17,7 @@
 warning: DXIL.dll not found.  Resulting DXIL will not be signed for use in release environments.
 
 error: validation errors
-tint_Pui8tf:11: error: Loop must have break.
+/tmp/tint_ePdsZG:11: error: Loop must have break.
 Validation failed.
 
 
diff --git a/test/unittest/reader/spirv/SpvParserCFGTest_ComputeBlockOrder_Loop_BodyHasBreak.spvasm.expected.hlsl b/test/unittest/reader/spirv/SpvParserCFGTest_ComputeBlockOrder_Loop_BodyHasBreak.spvasm.expected.hlsl
index 427d211..1c29d0b 100644
--- a/test/unittest/reader/spirv/SpvParserCFGTest_ComputeBlockOrder_Loop_BodyHasBreak.spvasm.expected.hlsl
+++ b/test/unittest/reader/spirv/SpvParserCFGTest_ComputeBlockOrder_Loop_BodyHasBreak.spvasm.expected.hlsl
@@ -3,7 +3,7 @@
 static uint var_1 = 0u;
 
 void main_1() {
-  while (true) {
+  [loop] while (true) {
     if (false) {
     } else {
       break;
diff --git a/test/unittest/reader/spirv/SpvParserCFGTest_ComputeBlockOrder_Loop_HeaderHasBreakUnless.spvasm.expected.hlsl b/test/unittest/reader/spirv/SpvParserCFGTest_ComputeBlockOrder_Loop_HeaderHasBreakUnless.spvasm.expected.hlsl
index baba211..edb22e4 100644
--- a/test/unittest/reader/spirv/SpvParserCFGTest_ComputeBlockOrder_Loop_HeaderHasBreakUnless.spvasm.expected.hlsl
+++ b/test/unittest/reader/spirv/SpvParserCFGTest_ComputeBlockOrder_Loop_HeaderHasBreakUnless.spvasm.expected.hlsl
@@ -3,7 +3,7 @@
 static uint var_1 = 0u;
 
 void main_1() {
-  while (true) {
+  [loop] while (true) {
     if (false) {
       break;
     }
@@ -18,7 +18,7 @@
 warning: DXIL.dll not found.  Resulting DXIL will not be signed for use in release environments.
 
 error: validation errors
-tint_5BECUW:12: error: Loop must have break.
+/tmp/tint_1aGHmE:12: error: Loop must have break.
 Validation failed.
 
 
diff --git a/test/unittest/reader/spirv/SpvParserCFGTest_ComputeBlockOrder_Loop_SingleBlock_DupInfinite.spvasm b/test/unittest/reader/spirv/SpvParserCFGTest_ComputeBlockOrder_Loop_SingleBlock_DupInfinite.spvasm
deleted file mode 100644
index ed99bd2..0000000
--- a/test/unittest/reader/spirv/SpvParserCFGTest_ComputeBlockOrder_Loop_SingleBlock_DupInfinite.spvasm
+++ /dev/null
@@ -1,51 +0,0 @@
-; Test: SpvParserCFGTest_ComputeBlockOrder_Loop_SingleBlock_DupInfinite.spvasm
-; SPIR-V
-; Version: 1.0
-; Generator: Khronos SPIR-V Tools Assembler; 0
-; Bound: 1000
-; Schema: 0
-OpCapability Shader
-OpMemoryModel Logical Simple
-OpEntryPoint Fragment %100 "main"
-OpExecutionMode %100 OriginUpperLeft
-OpName %var "var"
-%void = OpTypeVoid
-%3 = OpTypeFunction %void
-%bool = OpTypeBool
-%5 = OpConstantNull %bool
-%true = OpConstantTrue %bool
-%false = OpConstantFalse %bool
-%uint = OpTypeInt 32 0
-%int = OpTypeInt 32 1
-%uint_42 = OpConstant %uint 42
-%int_42 = OpConstant %int 42
-%13 = OpTypeFunction %uint
-%uint_0 = OpConstant %uint 0
-%uint_1 = OpConstant %uint 1
-%uint_2 = OpConstant %uint 2
-%uint_3 = OpConstant %uint 3
-%uint_4 = OpConstant %uint 4
-%uint_5 = OpConstant %uint 5
-%uint_6 = OpConstant %uint 6
-%uint_7 = OpConstant %uint 7
-%uint_8 = OpConstant %uint 8
-%uint_10 = OpConstant %uint 10
-%uint_20 = OpConstant %uint 20
-%uint_30 = OpConstant %uint 30
-%uint_40 = OpConstant %uint 40
-%uint_50 = OpConstant %uint 50
-%uint_90 = OpConstant %uint 90
-%uint_99 = OpConstant %uint 99
-%_ptr_Private_uint = OpTypePointer Private %uint
-%var = OpVariable %_ptr_Private_uint Private
-%uint_999 = OpConstant %uint 999
-%100 = OpFunction %void None %3
-%10 = OpLabel
-OpBranch %20
-%20 = OpLabel
-OpLoopMerge %99 %20 None
-OpBranchConditional %5 %20 %20
-%99 = OpLabel
-OpReturn
-OpFunctionEnd
-
diff --git a/test/unittest/reader/spirv/SpvParserCFGTest_ComputeBlockOrder_Loop_SingleBlock_DupInfinite.spvasm.expected.hlsl b/test/unittest/reader/spirv/SpvParserCFGTest_ComputeBlockOrder_Loop_SingleBlock_DupInfinite.spvasm.expected.hlsl
deleted file mode 100644
index 59b0654..0000000
--- a/test/unittest/reader/spirv/SpvParserCFGTest_ComputeBlockOrder_Loop_SingleBlock_DupInfinite.spvasm.expected.hlsl
+++ /dev/null
@@ -1,22 +0,0 @@
-SKIP: FAILED
-
-static uint var_1 = 0u;
-
-void main_1() {
-  while (true) {
-  }
-  return;
-}
-
-void main() {
-  main_1();
-  return;
-}
-warning: DXIL.dll not found.  Resulting DXIL will not be signed for use in release environments.
-
-error: validation errors
-tint_ow9VQQ:9: error: Loop must have break.
-Validation failed.
-
-
-
diff --git a/test/unittest/reader/spirv/SpvParserCFGTest_ComputeBlockOrder_Loop_SingleBlock_Infinite.spvasm b/test/unittest/reader/spirv/SpvParserCFGTest_ComputeBlockOrder_Loop_SingleBlock_Infinite.spvasm
deleted file mode 100644
index 6970ee6..0000000
--- a/test/unittest/reader/spirv/SpvParserCFGTest_ComputeBlockOrder_Loop_SingleBlock_Infinite.spvasm
+++ /dev/null
@@ -1,51 +0,0 @@
-; Test: SpvParserCFGTest_ComputeBlockOrder_Loop_SingleBlock_Infinite.spvasm
-; SPIR-V
-; Version: 1.0
-; Generator: Khronos SPIR-V Tools Assembler; 0
-; Bound: 1000
-; Schema: 0
-OpCapability Shader
-OpMemoryModel Logical Simple
-OpEntryPoint Fragment %100 "main"
-OpExecutionMode %100 OriginUpperLeft
-OpName %var "var"
-%void = OpTypeVoid
-%3 = OpTypeFunction %void
-%bool = OpTypeBool
-%5 = OpConstantNull %bool
-%true = OpConstantTrue %bool
-%false = OpConstantFalse %bool
-%uint = OpTypeInt 32 0
-%int = OpTypeInt 32 1
-%uint_42 = OpConstant %uint 42
-%int_42 = OpConstant %int 42
-%13 = OpTypeFunction %uint
-%uint_0 = OpConstant %uint 0
-%uint_1 = OpConstant %uint 1
-%uint_2 = OpConstant %uint 2
-%uint_3 = OpConstant %uint 3
-%uint_4 = OpConstant %uint 4
-%uint_5 = OpConstant %uint 5
-%uint_6 = OpConstant %uint 6
-%uint_7 = OpConstant %uint 7
-%uint_8 = OpConstant %uint 8
-%uint_10 = OpConstant %uint 10
-%uint_20 = OpConstant %uint 20
-%uint_30 = OpConstant %uint 30
-%uint_40 = OpConstant %uint 40
-%uint_50 = OpConstant %uint 50
-%uint_90 = OpConstant %uint 90
-%uint_99 = OpConstant %uint 99
-%_ptr_Private_uint = OpTypePointer Private %uint
-%var = OpVariable %_ptr_Private_uint Private
-%uint_999 = OpConstant %uint 999
-%100 = OpFunction %void None %3
-%10 = OpLabel
-OpBranch %20
-%20 = OpLabel
-OpLoopMerge %99 %20 None
-OpBranch %20
-%99 = OpLabel
-OpReturn
-OpFunctionEnd
-
diff --git a/test/unittest/reader/spirv/SpvParserCFGTest_ComputeBlockOrder_Loop_SingleBlock_Infinite.spvasm.expected.hlsl b/test/unittest/reader/spirv/SpvParserCFGTest_ComputeBlockOrder_Loop_SingleBlock_Infinite.spvasm.expected.hlsl
deleted file mode 100644
index b47009a..0000000
--- a/test/unittest/reader/spirv/SpvParserCFGTest_ComputeBlockOrder_Loop_SingleBlock_Infinite.spvasm.expected.hlsl
+++ /dev/null
@@ -1,22 +0,0 @@
-SKIP: FAILED
-
-static uint var_1 = 0u;
-
-void main_1() {
-  while (true) {
-  }
-  return;
-}
-
-void main() {
-  main_1();
-  return;
-}
-warning: DXIL.dll not found.  Resulting DXIL will not be signed for use in release environments.
-
-error: validation errors
-tint_py60tZ:9: error: Loop must have break.
-Validation failed.
-
-
-
diff --git a/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_Back_MultiBlock_LoopBreak_OnTrue.spvasm.expected.hlsl b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_Back_MultiBlock_LoopBreak_OnTrue.spvasm.expected.hlsl
index 30bb238..34e3579 100644
--- a/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_Back_MultiBlock_LoopBreak_OnTrue.spvasm.expected.hlsl
+++ b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_Back_MultiBlock_LoopBreak_OnTrue.spvasm.expected.hlsl
@@ -4,7 +4,7 @@
 
 void main_1() {
   var_1 = 0u;
-  while (true) {
+  [loop] while (true) {
     var_1 = 1u;
     {
       if (false) {
@@ -23,7 +23,7 @@
 warning: DXIL.dll not found.  Resulting DXIL will not be signed for use in release environments.
 
 error: validation errors
-tint_7IQZev:17: error: Loop must have break.
+/tmp/tint_M0JS53:17: error: Loop must have break.
 Validation failed.
 
 
diff --git a/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_Back_SingleBlock_Back.spvasm.expected.hlsl b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_Back_SingleBlock_Back.spvasm.expected.hlsl
index e913ddb..ad191b8 100644
--- a/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_Back_SingleBlock_Back.spvasm.expected.hlsl
+++ b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_Back_SingleBlock_Back.spvasm.expected.hlsl
@@ -1,25 +1,20 @@
 SKIP: FAILED
 
-static uint var_1 = 0u;
 
-void main_1() {
+var<private> var_1 : u32;
+
+fn main_1() {
   var_1 = 0u;
-  while (true) {
+  loop {
     var_1 = 1u;
   }
   var_1 = 5u;
   return;
 }
 
-void main() {
+[[stage(fragment)]]
+fn main() {
   main_1();
-  return;
 }
-warning: DXIL.dll not found.  Resulting DXIL will not be signed for use in release environments.
 
-error: validation errors
-tint_43uiR4:12: error: Loop must have break.
-Validation failed.
-
-
-
+error: loop does not exit
diff --git a/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_Back_SingleBlock_Back.spvasm.expected.msl b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_Back_SingleBlock_Back.spvasm.expected.msl
new file mode 100644
index 0000000..ad191b8
--- /dev/null
+++ b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_Back_SingleBlock_Back.spvasm.expected.msl
@@ -0,0 +1,20 @@
+SKIP: FAILED
+
+
+var<private> var_1 : u32;
+
+fn main_1() {
+  var_1 = 0u;
+  loop {
+    var_1 = 1u;
+  }
+  var_1 = 5u;
+  return;
+}
+
+[[stage(fragment)]]
+fn main() {
+  main_1();
+}
+
+error: loop does not exit
diff --git a/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_Back_SingleBlock_Back.spvasm.expected.spvasm b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_Back_SingleBlock_Back.spvasm.expected.spvasm
new file mode 100644
index 0000000..ad191b8
--- /dev/null
+++ b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_Back_SingleBlock_Back.spvasm.expected.spvasm
@@ -0,0 +1,20 @@
+SKIP: FAILED
+
+
+var<private> var_1 : u32;
+
+fn main_1() {
+  var_1 = 0u;
+  loop {
+    var_1 = 1u;
+  }
+  var_1 = 5u;
+  return;
+}
+
+[[stage(fragment)]]
+fn main() {
+  main_1();
+}
+
+error: loop does not exit
diff --git a/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_Back_SingleBlock_Back.spvasm.expected.wgsl b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_Back_SingleBlock_Back.spvasm.expected.wgsl
new file mode 100644
index 0000000..ad191b8
--- /dev/null
+++ b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_Back_SingleBlock_Back.spvasm.expected.wgsl
@@ -0,0 +1,20 @@
+SKIP: FAILED
+
+
+var<private> var_1 : u32;
+
+fn main_1() {
+  var_1 = 0u;
+  loop {
+    var_1 = 1u;
+  }
+  var_1 = 5u;
+  return;
+}
+
+[[stage(fragment)]]
+fn main() {
+  main_1();
+}
+
+error: loop does not exit
diff --git a/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_Back_SingleBlock_LoopBreak_OnTrue.spvasm.expected.hlsl b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_Back_SingleBlock_LoopBreak_OnTrue.spvasm.expected.hlsl
index 48e71c6..c7387bd 100644
--- a/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_Back_SingleBlock_LoopBreak_OnTrue.spvasm.expected.hlsl
+++ b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_Back_SingleBlock_LoopBreak_OnTrue.spvasm.expected.hlsl
@@ -4,7 +4,7 @@
 
 void main_1() {
   var_1 = 0u;
-  while (true) {
+  [loop] while (true) {
     var_1 = 1u;
     if (false) {
       break;
@@ -21,7 +21,7 @@
 warning: DXIL.dll not found.  Resulting DXIL will not be signed for use in release environments.
 
 error: validation errors
-tint_ZN83ug:15: error: Loop must have break.
+/tmp/tint_9dTIlS:15: error: Loop must have break.
 Validation failed.
 
 
diff --git a/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_Continue_Continue_AfterHeader_Conditional.spvasm.expected.hlsl b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_Continue_Continue_AfterHeader_Conditional.spvasm.expected.hlsl
index 620d969..791ac1a 100644
--- a/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_Continue_Continue_AfterHeader_Conditional.spvasm.expected.hlsl
+++ b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_Continue_Continue_AfterHeader_Conditional.spvasm.expected.hlsl
@@ -1,21 +1,20 @@
 SKIP: FAILED
 
-static uint var_1 = 0u;
 
-void main_1() {
+var<private> var_1 : u32;
+
+fn main_1() {
   var_1 = 0u;
-  while (true) {
+  loop {
     var_1 = 1u;
     var_1 = 2u;
     if (true) {
       var_1 = 3u;
-      {
-        var_1 = 5u;
-      }
       continue;
     }
     var_1 = 4u;
-    {
+
+    continuing {
       var_1 = 5u;
     }
   }
@@ -23,15 +22,9 @@
   return;
 }
 
-void main() {
+[[stage(fragment)]]
+fn main() {
   main_1();
-  return;
 }
-warning: DXIL.dll not found.  Resulting DXIL will not be signed for use in release environments.
 
-error: validation errors
-tint_8eZRxk:24: error: Loop must have break.
-Validation failed.
-
-
-
+error: loop does not exit
diff --git a/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_Continue_Continue_AfterHeader_Conditional.spvasm.expected.msl b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_Continue_Continue_AfterHeader_Conditional.spvasm.expected.msl
new file mode 100644
index 0000000..791ac1a
--- /dev/null
+++ b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_Continue_Continue_AfterHeader_Conditional.spvasm.expected.msl
@@ -0,0 +1,30 @@
+SKIP: FAILED
+
+
+var<private> var_1 : u32;
+
+fn main_1() {
+  var_1 = 0u;
+  loop {
+    var_1 = 1u;
+    var_1 = 2u;
+    if (true) {
+      var_1 = 3u;
+      continue;
+    }
+    var_1 = 4u;
+
+    continuing {
+      var_1 = 5u;
+    }
+  }
+  var_1 = 6u;
+  return;
+}
+
+[[stage(fragment)]]
+fn main() {
+  main_1();
+}
+
+error: loop does not exit
diff --git a/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_Continue_Continue_AfterHeader_Conditional.spvasm.expected.spvasm b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_Continue_Continue_AfterHeader_Conditional.spvasm.expected.spvasm
new file mode 100644
index 0000000..791ac1a
--- /dev/null
+++ b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_Continue_Continue_AfterHeader_Conditional.spvasm.expected.spvasm
@@ -0,0 +1,30 @@
+SKIP: FAILED
+
+
+var<private> var_1 : u32;
+
+fn main_1() {
+  var_1 = 0u;
+  loop {
+    var_1 = 1u;
+    var_1 = 2u;
+    if (true) {
+      var_1 = 3u;
+      continue;
+    }
+    var_1 = 4u;
+
+    continuing {
+      var_1 = 5u;
+    }
+  }
+  var_1 = 6u;
+  return;
+}
+
+[[stage(fragment)]]
+fn main() {
+  main_1();
+}
+
+error: loop does not exit
diff --git a/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_Continue_Continue_AfterHeader_Conditional.spvasm.expected.wgsl b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_Continue_Continue_AfterHeader_Conditional.spvasm.expected.wgsl
new file mode 100644
index 0000000..791ac1a
--- /dev/null
+++ b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_Continue_Continue_AfterHeader_Conditional.spvasm.expected.wgsl
@@ -0,0 +1,30 @@
+SKIP: FAILED
+
+
+var<private> var_1 : u32;
+
+fn main_1() {
+  var_1 = 0u;
+  loop {
+    var_1 = 1u;
+    var_1 = 2u;
+    if (true) {
+      var_1 = 3u;
+      continue;
+    }
+    var_1 = 4u;
+
+    continuing {
+      var_1 = 5u;
+    }
+  }
+  var_1 = 6u;
+  return;
+}
+
+[[stage(fragment)]]
+fn main() {
+  main_1();
+}
+
+error: loop does not exit
diff --git a/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_Continue_Continue_AfterHeader_Conditional_EmptyContinuing.spvasm.expected.hlsl b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_Continue_Continue_AfterHeader_Conditional_EmptyContinuing.spvasm.expected.hlsl
index 4f7296d..776810f 100644
--- a/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_Continue_Continue_AfterHeader_Conditional_EmptyContinuing.spvasm.expected.hlsl
+++ b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_Continue_Continue_AfterHeader_Conditional_EmptyContinuing.spvasm.expected.hlsl
@@ -1,10 +1,11 @@
 SKIP: FAILED
 
-static uint var_1 = 0u;
 
-void main_1() {
+var<private> var_1 : u32;
+
+fn main_1() {
   var_1 = 0u;
-  while (true) {
+  loop {
     var_1 = 1u;
     var_1 = 2u;
     if (true) {
@@ -17,15 +18,9 @@
   return;
 }
 
-void main() {
+[[stage(fragment)]]
+fn main() {
   main_1();
-  return;
 }
-warning: DXIL.dll not found.  Resulting DXIL will not be signed for use in release environments.
 
-error: validation errors
-tint_qTM1ZY:18: error: Loop must have break.
-Validation failed.
-
-
-
+error: loop does not exit
diff --git a/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_Continue_Continue_AfterHeader_Conditional_EmptyContinuing.spvasm.expected.msl b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_Continue_Continue_AfterHeader_Conditional_EmptyContinuing.spvasm.expected.msl
new file mode 100644
index 0000000..776810f
--- /dev/null
+++ b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_Continue_Continue_AfterHeader_Conditional_EmptyContinuing.spvasm.expected.msl
@@ -0,0 +1,26 @@
+SKIP: FAILED
+
+
+var<private> var_1 : u32;
+
+fn main_1() {
+  var_1 = 0u;
+  loop {
+    var_1 = 1u;
+    var_1 = 2u;
+    if (true) {
+      var_1 = 3u;
+      continue;
+    }
+    var_1 = 4u;
+  }
+  var_1 = 6u;
+  return;
+}
+
+[[stage(fragment)]]
+fn main() {
+  main_1();
+}
+
+error: loop does not exit
diff --git a/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_Continue_Continue_AfterHeader_Conditional_EmptyContinuing.spvasm.expected.spvasm b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_Continue_Continue_AfterHeader_Conditional_EmptyContinuing.spvasm.expected.spvasm
new file mode 100644
index 0000000..776810f
--- /dev/null
+++ b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_Continue_Continue_AfterHeader_Conditional_EmptyContinuing.spvasm.expected.spvasm
@@ -0,0 +1,26 @@
+SKIP: FAILED
+
+
+var<private> var_1 : u32;
+
+fn main_1() {
+  var_1 = 0u;
+  loop {
+    var_1 = 1u;
+    var_1 = 2u;
+    if (true) {
+      var_1 = 3u;
+      continue;
+    }
+    var_1 = 4u;
+  }
+  var_1 = 6u;
+  return;
+}
+
+[[stage(fragment)]]
+fn main() {
+  main_1();
+}
+
+error: loop does not exit
diff --git a/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_Continue_Continue_AfterHeader_Conditional_EmptyContinuing.spvasm.expected.wgsl b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_Continue_Continue_AfterHeader_Conditional_EmptyContinuing.spvasm.expected.wgsl
new file mode 100644
index 0000000..776810f
--- /dev/null
+++ b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_Continue_Continue_AfterHeader_Conditional_EmptyContinuing.spvasm.expected.wgsl
@@ -0,0 +1,26 @@
+SKIP: FAILED
+
+
+var<private> var_1 : u32;
+
+fn main_1() {
+  var_1 = 0u;
+  loop {
+    var_1 = 1u;
+    var_1 = 2u;
+    if (true) {
+      var_1 = 3u;
+      continue;
+    }
+    var_1 = 4u;
+  }
+  var_1 = 6u;
+  return;
+}
+
+[[stage(fragment)]]
+fn main() {
+  main_1();
+}
+
+error: loop does not exit
diff --git a/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_Continue_Continue_AfterHeader_Unconditional.spvasm.expected.hlsl b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_Continue_Continue_AfterHeader_Unconditional.spvasm.expected.hlsl
index 1cd6ad5..99d5de3 100644
--- a/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_Continue_Continue_AfterHeader_Unconditional.spvasm.expected.hlsl
+++ b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_Continue_Continue_AfterHeader_Unconditional.spvasm.expected.hlsl
@@ -1,13 +1,15 @@
 SKIP: FAILED
 
-static uint var_1 = 0u;
 
-void main_1() {
+var<private> var_1 : u32;
+
+fn main_1() {
   var_1 = 0u;
-  while (true) {
+  loop {
     var_1 = 1u;
     var_1 = 2u;
-    {
+
+    continuing {
       var_1 = 4u;
     }
   }
@@ -15,15 +17,9 @@
   return;
 }
 
-void main() {
+[[stage(fragment)]]
+fn main() {
   main_1();
-  return;
 }
-warning: DXIL.dll not found.  Resulting DXIL will not be signed for use in release environments.
 
-error: validation errors
-tint_TECAbG:16: error: Loop must have break.
-Validation failed.
-
-
-
+error: loop does not exit
diff --git a/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_Continue_Continue_AfterHeader_Unconditional.spvasm.expected.msl b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_Continue_Continue_AfterHeader_Unconditional.spvasm.expected.msl
new file mode 100644
index 0000000..99d5de3
--- /dev/null
+++ b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_Continue_Continue_AfterHeader_Unconditional.spvasm.expected.msl
@@ -0,0 +1,25 @@
+SKIP: FAILED
+
+
+var<private> var_1 : u32;
+
+fn main_1() {
+  var_1 = 0u;
+  loop {
+    var_1 = 1u;
+    var_1 = 2u;
+
+    continuing {
+      var_1 = 4u;
+    }
+  }
+  var_1 = 5u;
+  return;
+}
+
+[[stage(fragment)]]
+fn main() {
+  main_1();
+}
+
+error: loop does not exit
diff --git a/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_Continue_Continue_AfterHeader_Unconditional.spvasm.expected.spvasm b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_Continue_Continue_AfterHeader_Unconditional.spvasm.expected.spvasm
new file mode 100644
index 0000000..99d5de3
--- /dev/null
+++ b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_Continue_Continue_AfterHeader_Unconditional.spvasm.expected.spvasm
@@ -0,0 +1,25 @@
+SKIP: FAILED
+
+
+var<private> var_1 : u32;
+
+fn main_1() {
+  var_1 = 0u;
+  loop {
+    var_1 = 1u;
+    var_1 = 2u;
+
+    continuing {
+      var_1 = 4u;
+    }
+  }
+  var_1 = 5u;
+  return;
+}
+
+[[stage(fragment)]]
+fn main() {
+  main_1();
+}
+
+error: loop does not exit
diff --git a/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_Continue_Continue_AfterHeader_Unconditional.spvasm.expected.wgsl b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_Continue_Continue_AfterHeader_Unconditional.spvasm.expected.wgsl
new file mode 100644
index 0000000..99d5de3
--- /dev/null
+++ b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_Continue_Continue_AfterHeader_Unconditional.spvasm.expected.wgsl
@@ -0,0 +1,25 @@
+SKIP: FAILED
+
+
+var<private> var_1 : u32;
+
+fn main_1() {
+  var_1 = 0u;
+  loop {
+    var_1 = 1u;
+    var_1 = 2u;
+
+    continuing {
+      var_1 = 4u;
+    }
+  }
+  var_1 = 5u;
+  return;
+}
+
+[[stage(fragment)]]
+fn main() {
+  main_1();
+}
+
+error: loop does not exit
diff --git a/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_Continue_Continue_FromHeader.spvasm.expected.hlsl b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_Continue_Continue_FromHeader.spvasm.expected.hlsl
index 0d10617..d64a6b8 100644
--- a/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_Continue_Continue_FromHeader.spvasm.expected.hlsl
+++ b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_Continue_Continue_FromHeader.spvasm.expected.hlsl
@@ -1,12 +1,14 @@
 SKIP: FAILED
 
-static uint var_1 = 0u;
 
-void main_1() {
+var<private> var_1 : u32;
+
+fn main_1() {
   var_1 = 0u;
-  while (true) {
+  loop {
     var_1 = 1u;
-    {
+
+    continuing {
       var_1 = 4u;
     }
   }
@@ -14,15 +16,9 @@
   return;
 }
 
-void main() {
+[[stage(fragment)]]
+fn main() {
   main_1();
-  return;
 }
-warning: DXIL.dll not found.  Resulting DXIL will not be signed for use in release environments.
 
-error: validation errors
-tint_U669Fi:15: error: Loop must have break.
-Validation failed.
-
-
-
+error: loop does not exit
diff --git a/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_Continue_Continue_FromHeader.spvasm.expected.msl b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_Continue_Continue_FromHeader.spvasm.expected.msl
new file mode 100644
index 0000000..d64a6b8
--- /dev/null
+++ b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_Continue_Continue_FromHeader.spvasm.expected.msl
@@ -0,0 +1,24 @@
+SKIP: FAILED
+
+
+var<private> var_1 : u32;
+
+fn main_1() {
+  var_1 = 0u;
+  loop {
+    var_1 = 1u;
+
+    continuing {
+      var_1 = 4u;
+    }
+  }
+  var_1 = 5u;
+  return;
+}
+
+[[stage(fragment)]]
+fn main() {
+  main_1();
+}
+
+error: loop does not exit
diff --git a/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_Continue_Continue_FromHeader.spvasm.expected.spvasm b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_Continue_Continue_FromHeader.spvasm.expected.spvasm
new file mode 100644
index 0000000..d64a6b8
--- /dev/null
+++ b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_Continue_Continue_FromHeader.spvasm.expected.spvasm
@@ -0,0 +1,24 @@
+SKIP: FAILED
+
+
+var<private> var_1 : u32;
+
+fn main_1() {
+  var_1 = 0u;
+  loop {
+    var_1 = 1u;
+
+    continuing {
+      var_1 = 4u;
+    }
+  }
+  var_1 = 5u;
+  return;
+}
+
+[[stage(fragment)]]
+fn main() {
+  main_1();
+}
+
+error: loop does not exit
diff --git a/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_Continue_Continue_FromHeader.spvasm.expected.wgsl b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_Continue_Continue_FromHeader.spvasm.expected.wgsl
new file mode 100644
index 0000000..d64a6b8
--- /dev/null
+++ b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_Continue_Continue_FromHeader.spvasm.expected.wgsl
@@ -0,0 +1,24 @@
+SKIP: FAILED
+
+
+var<private> var_1 : u32;
+
+fn main_1() {
+  var_1 = 0u;
+  loop {
+    var_1 = 1u;
+
+    continuing {
+      var_1 = 4u;
+    }
+  }
+  var_1 = 5u;
+  return;
+}
+
+[[stage(fragment)]]
+fn main() {
+  main_1();
+}
+
+error: loop does not exit
diff --git a/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_Continue_Fallthrough_OnFalse.spvasm.expected.hlsl b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_Continue_Fallthrough_OnFalse.spvasm.expected.hlsl
index dded8a5..d678069 100644
--- a/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_Continue_Fallthrough_OnFalse.spvasm.expected.hlsl
+++ b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_Continue_Fallthrough_OnFalse.spvasm.expected.hlsl
@@ -1,33 +1,30 @@
 SKIP: FAILED
 
-static uint var_1 = 0u;
 
-void main_1() {
+var<private> var_1 : u32;
+
+fn main_1() {
   var_1 = 0u;
-  while (true) {
+  loop {
     var_1 = 1u;
     var_1 = 2u;
     switch(42u) {
       case 40u: {
         var_1 = 40u;
         if (false) {
-          {
-            var_1 = 4u;
-          }
           continue;
         }
-        /* fallthrough */
+        fallthrough;
       }
       case 50u: {
         var_1 = 50u;
-        break;
       }
       default: {
-        break;
       }
     }
     var_1 = 3u;
-    {
+
+    continuing {
       var_1 = 4u;
     }
   }
@@ -35,15 +32,9 @@
   return;
 }
 
-void main() {
+[[stage(fragment)]]
+fn main() {
   main_1();
-  return;
 }
-warning: DXIL.dll not found.  Resulting DXIL will not be signed for use in release environments.
 
-error: validation errors
-tint_cTIG3E:36: error: Loop must have break.
-Validation failed.
-
-
-
+error: loop does not exit
diff --git a/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_Continue_Fallthrough_OnFalse.spvasm.expected.msl b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_Continue_Fallthrough_OnFalse.spvasm.expected.msl
new file mode 100644
index 0000000..d678069
--- /dev/null
+++ b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_Continue_Fallthrough_OnFalse.spvasm.expected.msl
@@ -0,0 +1,40 @@
+SKIP: FAILED
+
+
+var<private> var_1 : u32;
+
+fn main_1() {
+  var_1 = 0u;
+  loop {
+    var_1 = 1u;
+    var_1 = 2u;
+    switch(42u) {
+      case 40u: {
+        var_1 = 40u;
+        if (false) {
+          continue;
+        }
+        fallthrough;
+      }
+      case 50u: {
+        var_1 = 50u;
+      }
+      default: {
+      }
+    }
+    var_1 = 3u;
+
+    continuing {
+      var_1 = 4u;
+    }
+  }
+  var_1 = 5u;
+  return;
+}
+
+[[stage(fragment)]]
+fn main() {
+  main_1();
+}
+
+error: loop does not exit
diff --git a/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_Continue_Fallthrough_OnFalse.spvasm.expected.spvasm b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_Continue_Fallthrough_OnFalse.spvasm.expected.spvasm
new file mode 100644
index 0000000..d678069
--- /dev/null
+++ b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_Continue_Fallthrough_OnFalse.spvasm.expected.spvasm
@@ -0,0 +1,40 @@
+SKIP: FAILED
+
+
+var<private> var_1 : u32;
+
+fn main_1() {
+  var_1 = 0u;
+  loop {
+    var_1 = 1u;
+    var_1 = 2u;
+    switch(42u) {
+      case 40u: {
+        var_1 = 40u;
+        if (false) {
+          continue;
+        }
+        fallthrough;
+      }
+      case 50u: {
+        var_1 = 50u;
+      }
+      default: {
+      }
+    }
+    var_1 = 3u;
+
+    continuing {
+      var_1 = 4u;
+    }
+  }
+  var_1 = 5u;
+  return;
+}
+
+[[stage(fragment)]]
+fn main() {
+  main_1();
+}
+
+error: loop does not exit
diff --git a/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_Continue_Fallthrough_OnFalse.spvasm.expected.wgsl b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_Continue_Fallthrough_OnFalse.spvasm.expected.wgsl
new file mode 100644
index 0000000..d678069
--- /dev/null
+++ b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_Continue_Fallthrough_OnFalse.spvasm.expected.wgsl
@@ -0,0 +1,40 @@
+SKIP: FAILED
+
+
+var<private> var_1 : u32;
+
+fn main_1() {
+  var_1 = 0u;
+  loop {
+    var_1 = 1u;
+    var_1 = 2u;
+    switch(42u) {
+      case 40u: {
+        var_1 = 40u;
+        if (false) {
+          continue;
+        }
+        fallthrough;
+      }
+      case 50u: {
+        var_1 = 50u;
+      }
+      default: {
+      }
+    }
+    var_1 = 3u;
+
+    continuing {
+      var_1 = 4u;
+    }
+  }
+  var_1 = 5u;
+  return;
+}
+
+[[stage(fragment)]]
+fn main() {
+  main_1();
+}
+
+error: loop does not exit
diff --git a/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_Continue_Fallthrough_OnTrue.spvasm.expected.hlsl b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_Continue_Fallthrough_OnTrue.spvasm.expected.hlsl
index bda3a5e..6ee0306 100644
--- a/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_Continue_Fallthrough_OnTrue.spvasm.expected.hlsl
+++ b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_Continue_Fallthrough_OnTrue.spvasm.expected.hlsl
@@ -1,10 +1,11 @@
 SKIP: FAILED
 
-static uint var_1 = 0u;
 
-void main_1() {
+var<private> var_1 : u32;
+
+fn main_1() {
   var_1 = 0u;
-  while (true) {
+  loop {
     var_1 = 1u;
     var_1 = 2u;
     switch(42u) {
@@ -12,23 +13,19 @@
         var_1 = 40u;
         if (false) {
         } else {
-          {
-            var_1 = 4u;
-          }
           continue;
         }
-        /* fallthrough */
+        fallthrough;
       }
       case 50u: {
         var_1 = 50u;
-        break;
       }
       default: {
-        break;
       }
     }
     var_1 = 3u;
-    {
+
+    continuing {
       var_1 = 4u;
     }
   }
@@ -36,15 +33,9 @@
   return;
 }
 
-void main() {
+[[stage(fragment)]]
+fn main() {
   main_1();
-  return;
 }
-warning: DXIL.dll not found.  Resulting DXIL will not be signed for use in release environments.
 
-error: validation errors
-tint_KckIVH:37: error: Loop must have break.
-Validation failed.
-
-
-
+error: loop does not exit
diff --git a/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_Continue_Fallthrough_OnTrue.spvasm.expected.msl b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_Continue_Fallthrough_OnTrue.spvasm.expected.msl
new file mode 100644
index 0000000..6ee0306
--- /dev/null
+++ b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_Continue_Fallthrough_OnTrue.spvasm.expected.msl
@@ -0,0 +1,41 @@
+SKIP: FAILED
+
+
+var<private> var_1 : u32;
+
+fn main_1() {
+  var_1 = 0u;
+  loop {
+    var_1 = 1u;
+    var_1 = 2u;
+    switch(42u) {
+      case 40u: {
+        var_1 = 40u;
+        if (false) {
+        } else {
+          continue;
+        }
+        fallthrough;
+      }
+      case 50u: {
+        var_1 = 50u;
+      }
+      default: {
+      }
+    }
+    var_1 = 3u;
+
+    continuing {
+      var_1 = 4u;
+    }
+  }
+  var_1 = 5u;
+  return;
+}
+
+[[stage(fragment)]]
+fn main() {
+  main_1();
+}
+
+error: loop does not exit
diff --git a/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_Continue_Fallthrough_OnTrue.spvasm.expected.spvasm b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_Continue_Fallthrough_OnTrue.spvasm.expected.spvasm
new file mode 100644
index 0000000..6ee0306
--- /dev/null
+++ b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_Continue_Fallthrough_OnTrue.spvasm.expected.spvasm
@@ -0,0 +1,41 @@
+SKIP: FAILED
+
+
+var<private> var_1 : u32;
+
+fn main_1() {
+  var_1 = 0u;
+  loop {
+    var_1 = 1u;
+    var_1 = 2u;
+    switch(42u) {
+      case 40u: {
+        var_1 = 40u;
+        if (false) {
+        } else {
+          continue;
+        }
+        fallthrough;
+      }
+      case 50u: {
+        var_1 = 50u;
+      }
+      default: {
+      }
+    }
+    var_1 = 3u;
+
+    continuing {
+      var_1 = 4u;
+    }
+  }
+  var_1 = 5u;
+  return;
+}
+
+[[stage(fragment)]]
+fn main() {
+  main_1();
+}
+
+error: loop does not exit
diff --git a/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_Continue_Fallthrough_OnTrue.spvasm.expected.wgsl b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_Continue_Fallthrough_OnTrue.spvasm.expected.wgsl
new file mode 100644
index 0000000..6ee0306
--- /dev/null
+++ b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_Continue_Fallthrough_OnTrue.spvasm.expected.wgsl
@@ -0,0 +1,41 @@
+SKIP: FAILED
+
+
+var<private> var_1 : u32;
+
+fn main_1() {
+  var_1 = 0u;
+  loop {
+    var_1 = 1u;
+    var_1 = 2u;
+    switch(42u) {
+      case 40u: {
+        var_1 = 40u;
+        if (false) {
+        } else {
+          continue;
+        }
+        fallthrough;
+      }
+      case 50u: {
+        var_1 = 50u;
+      }
+      default: {
+      }
+    }
+    var_1 = 3u;
+
+    continuing {
+      var_1 = 4u;
+    }
+  }
+  var_1 = 5u;
+  return;
+}
+
+[[stage(fragment)]]
+fn main() {
+  main_1();
+}
+
+error: loop does not exit
diff --git a/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_Continue_Forward_OnFalse.spvasm.expected.hlsl b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_Continue_Forward_OnFalse.spvasm.expected.hlsl
index 7e3f69f..f1f3c5d 100644
--- a/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_Continue_Forward_OnFalse.spvasm.expected.hlsl
+++ b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_Continue_Forward_OnFalse.spvasm.expected.hlsl
@@ -1,20 +1,19 @@
 SKIP: FAILED
 
-static uint var_1 = 0u;
 
-void main_1() {
+var<private> var_1 : u32;
+
+fn main_1() {
   var_1 = 0u;
-  while (true) {
+  loop {
     var_1 = 1u;
     var_1 = 2u;
     if (false) {
-      {
-        var_1 = 4u;
-      }
       continue;
     }
     var_1 = 3u;
-    {
+
+    continuing {
       var_1 = 4u;
     }
   }
@@ -22,15 +21,9 @@
   return;
 }
 
-void main() {
+[[stage(fragment)]]
+fn main() {
   main_1();
-  return;
 }
-warning: DXIL.dll not found.  Resulting DXIL will not be signed for use in release environments.
 
-error: validation errors
-tint_Zkgxp1:23: error: Loop must have break.
-Validation failed.
-
-
-
+error: loop does not exit
diff --git a/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_Continue_Forward_OnFalse.spvasm.expected.msl b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_Continue_Forward_OnFalse.spvasm.expected.msl
new file mode 100644
index 0000000..f1f3c5d
--- /dev/null
+++ b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_Continue_Forward_OnFalse.spvasm.expected.msl
@@ -0,0 +1,29 @@
+SKIP: FAILED
+
+
+var<private> var_1 : u32;
+
+fn main_1() {
+  var_1 = 0u;
+  loop {
+    var_1 = 1u;
+    var_1 = 2u;
+    if (false) {
+      continue;
+    }
+    var_1 = 3u;
+
+    continuing {
+      var_1 = 4u;
+    }
+  }
+  var_1 = 5u;
+  return;
+}
+
+[[stage(fragment)]]
+fn main() {
+  main_1();
+}
+
+error: loop does not exit
diff --git a/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_Continue_Forward_OnFalse.spvasm.expected.spvasm b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_Continue_Forward_OnFalse.spvasm.expected.spvasm
new file mode 100644
index 0000000..f1f3c5d
--- /dev/null
+++ b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_Continue_Forward_OnFalse.spvasm.expected.spvasm
@@ -0,0 +1,29 @@
+SKIP: FAILED
+
+
+var<private> var_1 : u32;
+
+fn main_1() {
+  var_1 = 0u;
+  loop {
+    var_1 = 1u;
+    var_1 = 2u;
+    if (false) {
+      continue;
+    }
+    var_1 = 3u;
+
+    continuing {
+      var_1 = 4u;
+    }
+  }
+  var_1 = 5u;
+  return;
+}
+
+[[stage(fragment)]]
+fn main() {
+  main_1();
+}
+
+error: loop does not exit
diff --git a/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_Continue_Forward_OnFalse.spvasm.expected.wgsl b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_Continue_Forward_OnFalse.spvasm.expected.wgsl
new file mode 100644
index 0000000..f1f3c5d
--- /dev/null
+++ b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_Continue_Forward_OnFalse.spvasm.expected.wgsl
@@ -0,0 +1,29 @@
+SKIP: FAILED
+
+
+var<private> var_1 : u32;
+
+fn main_1() {
+  var_1 = 0u;
+  loop {
+    var_1 = 1u;
+    var_1 = 2u;
+    if (false) {
+      continue;
+    }
+    var_1 = 3u;
+
+    continuing {
+      var_1 = 4u;
+    }
+  }
+  var_1 = 5u;
+  return;
+}
+
+[[stage(fragment)]]
+fn main() {
+  main_1();
+}
+
+error: loop does not exit
diff --git a/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_Continue_Forward_OnTrue.spvasm.expected.hlsl b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_Continue_Forward_OnTrue.spvasm.expected.hlsl
index 24a925b..d3f4646 100644
--- a/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_Continue_Forward_OnTrue.spvasm.expected.hlsl
+++ b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_Continue_Forward_OnTrue.spvasm.expected.hlsl
@@ -1,21 +1,20 @@
 SKIP: FAILED
 
-static uint var_1 = 0u;
 
-void main_1() {
+var<private> var_1 : u32;
+
+fn main_1() {
   var_1 = 0u;
-  while (true) {
+  loop {
     var_1 = 1u;
     var_1 = 2u;
     if (false) {
     } else {
-      {
-        var_1 = 4u;
-      }
       continue;
     }
     var_1 = 3u;
-    {
+
+    continuing {
       var_1 = 4u;
     }
   }
@@ -23,15 +22,9 @@
   return;
 }
 
-void main() {
+[[stage(fragment)]]
+fn main() {
   main_1();
-  return;
 }
-warning: DXIL.dll not found.  Resulting DXIL will not be signed for use in release environments.
 
-error: validation errors
-tint_OTzREg:24: error: Loop must have break.
-Validation failed.
-
-
-
+error: loop does not exit
diff --git a/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_Continue_Forward_OnTrue.spvasm.expected.msl b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_Continue_Forward_OnTrue.spvasm.expected.msl
new file mode 100644
index 0000000..d3f4646
--- /dev/null
+++ b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_Continue_Forward_OnTrue.spvasm.expected.msl
@@ -0,0 +1,30 @@
+SKIP: FAILED
+
+
+var<private> var_1 : u32;
+
+fn main_1() {
+  var_1 = 0u;
+  loop {
+    var_1 = 1u;
+    var_1 = 2u;
+    if (false) {
+    } else {
+      continue;
+    }
+    var_1 = 3u;
+
+    continuing {
+      var_1 = 4u;
+    }
+  }
+  var_1 = 5u;
+  return;
+}
+
+[[stage(fragment)]]
+fn main() {
+  main_1();
+}
+
+error: loop does not exit
diff --git a/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_Continue_Forward_OnTrue.spvasm.expected.spvasm b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_Continue_Forward_OnTrue.spvasm.expected.spvasm
new file mode 100644
index 0000000..d3f4646
--- /dev/null
+++ b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_Continue_Forward_OnTrue.spvasm.expected.spvasm
@@ -0,0 +1,30 @@
+SKIP: FAILED
+
+
+var<private> var_1 : u32;
+
+fn main_1() {
+  var_1 = 0u;
+  loop {
+    var_1 = 1u;
+    var_1 = 2u;
+    if (false) {
+    } else {
+      continue;
+    }
+    var_1 = 3u;
+
+    continuing {
+      var_1 = 4u;
+    }
+  }
+  var_1 = 5u;
+  return;
+}
+
+[[stage(fragment)]]
+fn main() {
+  main_1();
+}
+
+error: loop does not exit
diff --git a/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_Continue_Forward_OnTrue.spvasm.expected.wgsl b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_Continue_Forward_OnTrue.spvasm.expected.wgsl
new file mode 100644
index 0000000..d3f4646
--- /dev/null
+++ b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_Continue_Forward_OnTrue.spvasm.expected.wgsl
@@ -0,0 +1,30 @@
+SKIP: FAILED
+
+
+var<private> var_1 : u32;
+
+fn main_1() {
+  var_1 = 0u;
+  loop {
+    var_1 = 1u;
+    var_1 = 2u;
+    if (false) {
+    } else {
+      continue;
+    }
+    var_1 = 3u;
+
+    continuing {
+      var_1 = 4u;
+    }
+  }
+  var_1 = 5u;
+  return;
+}
+
+[[stage(fragment)]]
+fn main() {
+  main_1();
+}
+
+error: loop does not exit
diff --git a/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_Continue_IfBreak_OnFalse.spvasm.expected.hlsl b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_Continue_IfBreak_OnFalse.spvasm.expected.hlsl
index 2feb422..7f23c27 100644
--- a/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_Continue_IfBreak_OnFalse.spvasm.expected.hlsl
+++ b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_Continue_IfBreak_OnFalse.spvasm.expected.hlsl
@@ -1,23 +1,22 @@
 SKIP: FAILED
 
-static uint var_1 = 0u;
 
-void main_1() {
+var<private> var_1 : u32;
+
+fn main_1() {
   var_1 = 0u;
-  while (true) {
+  loop {
     var_1 = 1u;
     var_1 = 2u;
     if (true) {
       var_1 = 3u;
       if (false) {
-        {
-          var_1 = 5u;
-        }
         continue;
       }
     }
     var_1 = 4u;
-    {
+
+    continuing {
       var_1 = 5u;
     }
   }
@@ -25,15 +24,9 @@
   return;
 }
 
-void main() {
+[[stage(fragment)]]
+fn main() {
   main_1();
-  return;
 }
-warning: DXIL.dll not found.  Resulting DXIL will not be signed for use in release environments.
 
-error: validation errors
-tint_pSVapr:26: error: Loop must have break.
-Validation failed.
-
-
-
+error: loop does not exit
diff --git a/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_Continue_IfBreak_OnFalse.spvasm.expected.msl b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_Continue_IfBreak_OnFalse.spvasm.expected.msl
new file mode 100644
index 0000000..7f23c27
--- /dev/null
+++ b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_Continue_IfBreak_OnFalse.spvasm.expected.msl
@@ -0,0 +1,32 @@
+SKIP: FAILED
+
+
+var<private> var_1 : u32;
+
+fn main_1() {
+  var_1 = 0u;
+  loop {
+    var_1 = 1u;
+    var_1 = 2u;
+    if (true) {
+      var_1 = 3u;
+      if (false) {
+        continue;
+      }
+    }
+    var_1 = 4u;
+
+    continuing {
+      var_1 = 5u;
+    }
+  }
+  var_1 = 6u;
+  return;
+}
+
+[[stage(fragment)]]
+fn main() {
+  main_1();
+}
+
+error: loop does not exit
diff --git a/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_Continue_IfBreak_OnFalse.spvasm.expected.spvasm b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_Continue_IfBreak_OnFalse.spvasm.expected.spvasm
new file mode 100644
index 0000000..7f23c27
--- /dev/null
+++ b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_Continue_IfBreak_OnFalse.spvasm.expected.spvasm
@@ -0,0 +1,32 @@
+SKIP: FAILED
+
+
+var<private> var_1 : u32;
+
+fn main_1() {
+  var_1 = 0u;
+  loop {
+    var_1 = 1u;
+    var_1 = 2u;
+    if (true) {
+      var_1 = 3u;
+      if (false) {
+        continue;
+      }
+    }
+    var_1 = 4u;
+
+    continuing {
+      var_1 = 5u;
+    }
+  }
+  var_1 = 6u;
+  return;
+}
+
+[[stage(fragment)]]
+fn main() {
+  main_1();
+}
+
+error: loop does not exit
diff --git a/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_Continue_IfBreak_OnFalse.spvasm.expected.wgsl b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_Continue_IfBreak_OnFalse.spvasm.expected.wgsl
new file mode 100644
index 0000000..7f23c27
--- /dev/null
+++ b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_Continue_IfBreak_OnFalse.spvasm.expected.wgsl
@@ -0,0 +1,32 @@
+SKIP: FAILED
+
+
+var<private> var_1 : u32;
+
+fn main_1() {
+  var_1 = 0u;
+  loop {
+    var_1 = 1u;
+    var_1 = 2u;
+    if (true) {
+      var_1 = 3u;
+      if (false) {
+        continue;
+      }
+    }
+    var_1 = 4u;
+
+    continuing {
+      var_1 = 5u;
+    }
+  }
+  var_1 = 6u;
+  return;
+}
+
+[[stage(fragment)]]
+fn main() {
+  main_1();
+}
+
+error: loop does not exit
diff --git a/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_Continue_IfBreak_OnTrue.spvasm.expected.hlsl b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_Continue_IfBreak_OnTrue.spvasm.expected.hlsl
index 8029f8d..b80786e 100644
--- a/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_Continue_IfBreak_OnTrue.spvasm.expected.hlsl
+++ b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_Continue_IfBreak_OnTrue.spvasm.expected.hlsl
@@ -1,24 +1,23 @@
 SKIP: FAILED
 
-static uint var_1 = 0u;
 
-void main_1() {
+var<private> var_1 : u32;
+
+fn main_1() {
   var_1 = 0u;
-  while (true) {
+  loop {
     var_1 = 1u;
     var_1 = 2u;
     if (true) {
       var_1 = 3u;
       if (false) {
       } else {
-        {
-          var_1 = 5u;
-        }
         continue;
       }
     }
     var_1 = 4u;
-    {
+
+    continuing {
       var_1 = 5u;
     }
   }
@@ -26,15 +25,9 @@
   return;
 }
 
-void main() {
+[[stage(fragment)]]
+fn main() {
   main_1();
-  return;
 }
-warning: DXIL.dll not found.  Resulting DXIL will not be signed for use in release environments.
 
-error: validation errors
-tint_3cKDSw:27: error: Loop must have break.
-Validation failed.
-
-
-
+error: loop does not exit
diff --git a/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_Continue_IfBreak_OnTrue.spvasm.expected.msl b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_Continue_IfBreak_OnTrue.spvasm.expected.msl
new file mode 100644
index 0000000..b80786e
--- /dev/null
+++ b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_Continue_IfBreak_OnTrue.spvasm.expected.msl
@@ -0,0 +1,33 @@
+SKIP: FAILED
+
+
+var<private> var_1 : u32;
+
+fn main_1() {
+  var_1 = 0u;
+  loop {
+    var_1 = 1u;
+    var_1 = 2u;
+    if (true) {
+      var_1 = 3u;
+      if (false) {
+      } else {
+        continue;
+      }
+    }
+    var_1 = 4u;
+
+    continuing {
+      var_1 = 5u;
+    }
+  }
+  var_1 = 6u;
+  return;
+}
+
+[[stage(fragment)]]
+fn main() {
+  main_1();
+}
+
+error: loop does not exit
diff --git a/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_Continue_IfBreak_OnTrue.spvasm.expected.spvasm b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_Continue_IfBreak_OnTrue.spvasm.expected.spvasm
new file mode 100644
index 0000000..b80786e
--- /dev/null
+++ b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_Continue_IfBreak_OnTrue.spvasm.expected.spvasm
@@ -0,0 +1,33 @@
+SKIP: FAILED
+
+
+var<private> var_1 : u32;
+
+fn main_1() {
+  var_1 = 0u;
+  loop {
+    var_1 = 1u;
+    var_1 = 2u;
+    if (true) {
+      var_1 = 3u;
+      if (false) {
+      } else {
+        continue;
+      }
+    }
+    var_1 = 4u;
+
+    continuing {
+      var_1 = 5u;
+    }
+  }
+  var_1 = 6u;
+  return;
+}
+
+[[stage(fragment)]]
+fn main() {
+  main_1();
+}
+
+error: loop does not exit
diff --git a/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_Continue_IfBreak_OnTrue.spvasm.expected.wgsl b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_Continue_IfBreak_OnTrue.spvasm.expected.wgsl
new file mode 100644
index 0000000..b80786e
--- /dev/null
+++ b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_Continue_IfBreak_OnTrue.spvasm.expected.wgsl
@@ -0,0 +1,33 @@
+SKIP: FAILED
+
+
+var<private> var_1 : u32;
+
+fn main_1() {
+  var_1 = 0u;
+  loop {
+    var_1 = 1u;
+    var_1 = 2u;
+    if (true) {
+      var_1 = 3u;
+      if (false) {
+      } else {
+        continue;
+      }
+    }
+    var_1 = 4u;
+
+    continuing {
+      var_1 = 5u;
+    }
+  }
+  var_1 = 6u;
+  return;
+}
+
+[[stage(fragment)]]
+fn main() {
+  main_1();
+}
+
+error: loop does not exit
diff --git a/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_LoopBreak_Continue_OnFalse.spvasm.expected.hlsl b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_LoopBreak_Continue_OnFalse.spvasm.expected.hlsl
index a367fa7..0aaad00 100644
--- a/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_LoopBreak_Continue_OnFalse.spvasm.expected.hlsl
+++ b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_LoopBreak_Continue_OnFalse.spvasm.expected.hlsl
@@ -4,7 +4,7 @@
 
 void main_1() {
   var_1 = 0u;
-  while (true) {
+  [loop] while (true) {
     var_1 = 1u;
     if (true) {
       var_1 = 2u;
@@ -33,7 +33,7 @@
 warning: DXIL.dll not found.  Resulting DXIL will not be signed for use in release environments.
 
 error: validation errors
-tint_ZSOcKK:27: error: Loop must have break.
+/tmp/tint_Rz6lq4:27: error: Loop must have break.
 Validation failed.
 
 
diff --git a/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_LoopBreak_Forward_OnFalse.spvasm.expected.hlsl b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_LoopBreak_Forward_OnFalse.spvasm.expected.hlsl
index 43d7046..bcca862 100644
--- a/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_LoopBreak_Forward_OnFalse.spvasm.expected.hlsl
+++ b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_LoopBreak_Forward_OnFalse.spvasm.expected.hlsl
@@ -4,7 +4,7 @@
 
 void main_1() {
   var_1 = 0u;
-  while (true) {
+  [loop] while (true) {
     var_1 = 1u;
     var_1 = 2u;
     if (false) {
@@ -26,7 +26,7 @@
 warning: DXIL.dll not found.  Resulting DXIL will not be signed for use in release environments.
 
 error: validation errors
-tint_QwTln4:20: error: Loop must have break.
+/tmp/tint_T39Xh2:20: error: Loop must have break.
 Validation failed.
 
 
diff --git a/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_LoopContinue_FromSwitch.spvasm.expected.hlsl b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_LoopContinue_FromSwitch.spvasm.expected.hlsl
index 8dbdd97..7b5bc4f 100644
--- a/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_LoopContinue_FromSwitch.spvasm.expected.hlsl
+++ b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_LoopContinue_FromSwitch.spvasm.expected.hlsl
@@ -1,27 +1,24 @@
 SKIP: FAILED
 
-static uint var_1 = 0u;
 
-void main_1() {
+var<private> var_1 : u32;
+
+fn main_1() {
   var_1 = 1u;
-  while (true) {
+  loop {
     var_1 = 2u;
     var_1 = 3u;
     switch(42u) {
       case 40u: {
         var_1 = 4u;
-        {
-          var_1 = 6u;
-        }
         continue;
-        break;
       }
       default: {
-        break;
       }
     }
     var_1 = 5u;
-    {
+
+    continuing {
       var_1 = 6u;
     }
   }
@@ -29,15 +26,9 @@
   return;
 }
 
-void main() {
+[[stage(fragment)]]
+fn main() {
   main_1();
-  return;
 }
-warning: DXIL.dll not found.  Resulting DXIL will not be signed for use in release environments.
 
-error: validation errors
-tint_jbcKmW:30: error: Loop must have break.
-Validation failed.
-
-
-
+error: loop does not exit
diff --git a/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_LoopContinue_FromSwitch.spvasm.expected.msl b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_LoopContinue_FromSwitch.spvasm.expected.msl
new file mode 100644
index 0000000..7b5bc4f
--- /dev/null
+++ b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_LoopContinue_FromSwitch.spvasm.expected.msl
@@ -0,0 +1,34 @@
+SKIP: FAILED
+
+
+var<private> var_1 : u32;
+
+fn main_1() {
+  var_1 = 1u;
+  loop {
+    var_1 = 2u;
+    var_1 = 3u;
+    switch(42u) {
+      case 40u: {
+        var_1 = 4u;
+        continue;
+      }
+      default: {
+      }
+    }
+    var_1 = 5u;
+
+    continuing {
+      var_1 = 6u;
+    }
+  }
+  var_1 = 7u;
+  return;
+}
+
+[[stage(fragment)]]
+fn main() {
+  main_1();
+}
+
+error: loop does not exit
diff --git a/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_LoopContinue_FromSwitch.spvasm.expected.spvasm b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_LoopContinue_FromSwitch.spvasm.expected.spvasm
new file mode 100644
index 0000000..7b5bc4f
--- /dev/null
+++ b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_LoopContinue_FromSwitch.spvasm.expected.spvasm
@@ -0,0 +1,34 @@
+SKIP: FAILED
+
+
+var<private> var_1 : u32;
+
+fn main_1() {
+  var_1 = 1u;
+  loop {
+    var_1 = 2u;
+    var_1 = 3u;
+    switch(42u) {
+      case 40u: {
+        var_1 = 4u;
+        continue;
+      }
+      default: {
+      }
+    }
+    var_1 = 5u;
+
+    continuing {
+      var_1 = 6u;
+    }
+  }
+  var_1 = 7u;
+  return;
+}
+
+[[stage(fragment)]]
+fn main() {
+  main_1();
+}
+
+error: loop does not exit
diff --git a/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_LoopContinue_FromSwitch.spvasm.expected.wgsl b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_LoopContinue_FromSwitch.spvasm.expected.wgsl
new file mode 100644
index 0000000..7b5bc4f
--- /dev/null
+++ b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_LoopContinue_FromSwitch.spvasm.expected.wgsl
@@ -0,0 +1,34 @@
+SKIP: FAILED
+
+
+var<private> var_1 : u32;
+
+fn main_1() {
+  var_1 = 1u;
+  loop {
+    var_1 = 2u;
+    var_1 = 3u;
+    switch(42u) {
+      case 40u: {
+        var_1 = 4u;
+        continue;
+      }
+      default: {
+      }
+    }
+    var_1 = 5u;
+
+    continuing {
+      var_1 = 6u;
+    }
+  }
+  var_1 = 7u;
+  return;
+}
+
+[[stage(fragment)]]
+fn main() {
+  main_1();
+}
+
+error: loop does not exit
diff --git a/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_SwitchBreak_Continue_OnFalse.spvasm.expected.hlsl b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_SwitchBreak_Continue_OnFalse.spvasm.expected.hlsl
index 2f22ba2..90f16be 100644
--- a/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_SwitchBreak_Continue_OnFalse.spvasm.expected.hlsl
+++ b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_SwitchBreak_Continue_OnFalse.spvasm.expected.hlsl
@@ -1,10 +1,11 @@
 SKIP: FAILED
 
-static uint var_1 = 0u;
 
-void main_1() {
+var<private> var_1 : u32;
+
+fn main_1() {
   var_1 = 1u;
-  while (true) {
+  loop {
     var_1 = 2u;
     var_1 = 3u;
     switch(42u) {
@@ -12,19 +13,15 @@
         var_1 = 40u;
         if (false) {
         } else {
-          {
-            var_1 = 7u;
-          }
           continue;
         }
-        break;
       }
       default: {
-        break;
       }
     }
     var_1 = 6u;
-    {
+
+    continuing {
       var_1 = 7u;
     }
   }
@@ -32,15 +29,9 @@
   return;
 }
 
-void main() {
+[[stage(fragment)]]
+fn main() {
   main_1();
-  return;
 }
-warning: DXIL.dll not found.  Resulting DXIL will not be signed for use in release environments.
 
-error: validation errors
-tint_7vcoV0:33: error: Loop must have break.
-Validation failed.
-
-
-
+error: loop does not exit
diff --git a/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_SwitchBreak_Continue_OnFalse.spvasm.expected.msl b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_SwitchBreak_Continue_OnFalse.spvasm.expected.msl
new file mode 100644
index 0000000..90f16be
--- /dev/null
+++ b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_SwitchBreak_Continue_OnFalse.spvasm.expected.msl
@@ -0,0 +1,37 @@
+SKIP: FAILED
+
+
+var<private> var_1 : u32;
+
+fn main_1() {
+  var_1 = 1u;
+  loop {
+    var_1 = 2u;
+    var_1 = 3u;
+    switch(42u) {
+      case 40u: {
+        var_1 = 40u;
+        if (false) {
+        } else {
+          continue;
+        }
+      }
+      default: {
+      }
+    }
+    var_1 = 6u;
+
+    continuing {
+      var_1 = 7u;
+    }
+  }
+  var_1 = 8u;
+  return;
+}
+
+[[stage(fragment)]]
+fn main() {
+  main_1();
+}
+
+error: loop does not exit
diff --git a/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_SwitchBreak_Continue_OnFalse.spvasm.expected.spvasm b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_SwitchBreak_Continue_OnFalse.spvasm.expected.spvasm
new file mode 100644
index 0000000..90f16be
--- /dev/null
+++ b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_SwitchBreak_Continue_OnFalse.spvasm.expected.spvasm
@@ -0,0 +1,37 @@
+SKIP: FAILED
+
+
+var<private> var_1 : u32;
+
+fn main_1() {
+  var_1 = 1u;
+  loop {
+    var_1 = 2u;
+    var_1 = 3u;
+    switch(42u) {
+      case 40u: {
+        var_1 = 40u;
+        if (false) {
+        } else {
+          continue;
+        }
+      }
+      default: {
+      }
+    }
+    var_1 = 6u;
+
+    continuing {
+      var_1 = 7u;
+    }
+  }
+  var_1 = 8u;
+  return;
+}
+
+[[stage(fragment)]]
+fn main() {
+  main_1();
+}
+
+error: loop does not exit
diff --git a/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_SwitchBreak_Continue_OnFalse.spvasm.expected.wgsl b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_SwitchBreak_Continue_OnFalse.spvasm.expected.wgsl
new file mode 100644
index 0000000..90f16be
--- /dev/null
+++ b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_SwitchBreak_Continue_OnFalse.spvasm.expected.wgsl
@@ -0,0 +1,37 @@
+SKIP: FAILED
+
+
+var<private> var_1 : u32;
+
+fn main_1() {
+  var_1 = 1u;
+  loop {
+    var_1 = 2u;
+    var_1 = 3u;
+    switch(42u) {
+      case 40u: {
+        var_1 = 40u;
+        if (false) {
+        } else {
+          continue;
+        }
+      }
+      default: {
+      }
+    }
+    var_1 = 6u;
+
+    continuing {
+      var_1 = 7u;
+    }
+  }
+  var_1 = 8u;
+  return;
+}
+
+[[stage(fragment)]]
+fn main() {
+  main_1();
+}
+
+error: loop does not exit
diff --git a/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_SwitchBreak_Continue_OnTrue.spvasm.expected.hlsl b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_SwitchBreak_Continue_OnTrue.spvasm.expected.hlsl
index 8094caa..79d355b 100644
--- a/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_SwitchBreak_Continue_OnTrue.spvasm.expected.hlsl
+++ b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_SwitchBreak_Continue_OnTrue.spvasm.expected.hlsl
@@ -1,29 +1,26 @@
 SKIP: FAILED
 
-static uint var_1 = 0u;
 
-void main_1() {
+var<private> var_1 : u32;
+
+fn main_1() {
   var_1 = 1u;
-  while (true) {
+  loop {
     var_1 = 2u;
     var_1 = 3u;
     switch(42u) {
       case 40u: {
         var_1 = 40u;
         if (false) {
-          {
-            var_1 = 7u;
-          }
           continue;
         }
-        break;
       }
       default: {
-        break;
       }
     }
     var_1 = 6u;
-    {
+
+    continuing {
       var_1 = 7u;
     }
   }
@@ -31,15 +28,9 @@
   return;
 }
 
-void main() {
+[[stage(fragment)]]
+fn main() {
   main_1();
-  return;
 }
-warning: DXIL.dll not found.  Resulting DXIL will not be signed for use in release environments.
 
-error: validation errors
-tint_GolFDb:32: error: Loop must have break.
-Validation failed.
-
-
-
+error: loop does not exit
diff --git a/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_SwitchBreak_Continue_OnTrue.spvasm.expected.msl b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_SwitchBreak_Continue_OnTrue.spvasm.expected.msl
new file mode 100644
index 0000000..79d355b
--- /dev/null
+++ b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_SwitchBreak_Continue_OnTrue.spvasm.expected.msl
@@ -0,0 +1,36 @@
+SKIP: FAILED
+
+
+var<private> var_1 : u32;
+
+fn main_1() {
+  var_1 = 1u;
+  loop {
+    var_1 = 2u;
+    var_1 = 3u;
+    switch(42u) {
+      case 40u: {
+        var_1 = 40u;
+        if (false) {
+          continue;
+        }
+      }
+      default: {
+      }
+    }
+    var_1 = 6u;
+
+    continuing {
+      var_1 = 7u;
+    }
+  }
+  var_1 = 8u;
+  return;
+}
+
+[[stage(fragment)]]
+fn main() {
+  main_1();
+}
+
+error: loop does not exit
diff --git a/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_SwitchBreak_Continue_OnTrue.spvasm.expected.spvasm b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_SwitchBreak_Continue_OnTrue.spvasm.expected.spvasm
new file mode 100644
index 0000000..79d355b
--- /dev/null
+++ b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_SwitchBreak_Continue_OnTrue.spvasm.expected.spvasm
@@ -0,0 +1,36 @@
+SKIP: FAILED
+
+
+var<private> var_1 : u32;
+
+fn main_1() {
+  var_1 = 1u;
+  loop {
+    var_1 = 2u;
+    var_1 = 3u;
+    switch(42u) {
+      case 40u: {
+        var_1 = 40u;
+        if (false) {
+          continue;
+        }
+      }
+      default: {
+      }
+    }
+    var_1 = 6u;
+
+    continuing {
+      var_1 = 7u;
+    }
+  }
+  var_1 = 8u;
+  return;
+}
+
+[[stage(fragment)]]
+fn main() {
+  main_1();
+}
+
+error: loop does not exit
diff --git a/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_SwitchBreak_Continue_OnTrue.spvasm.expected.wgsl b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_SwitchBreak_Continue_OnTrue.spvasm.expected.wgsl
new file mode 100644
index 0000000..79d355b
--- /dev/null
+++ b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_BranchConditional_SwitchBreak_Continue_OnTrue.spvasm.expected.wgsl
@@ -0,0 +1,36 @@
+SKIP: FAILED
+
+
+var<private> var_1 : u32;
+
+fn main_1() {
+  var_1 = 1u;
+  loop {
+    var_1 = 2u;
+    var_1 = 3u;
+    switch(42u) {
+      case 40u: {
+        var_1 = 40u;
+        if (false) {
+          continue;
+        }
+      }
+      default: {
+      }
+    }
+    var_1 = 6u;
+
+    continuing {
+      var_1 = 7u;
+    }
+  }
+  var_1 = 8u;
+  return;
+}
+
+[[stage(fragment)]]
+fn main() {
+  main_1();
+}
+
+error: loop does not exit
diff --git a/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_Branch_BackEdge_MultiBlockLoop.spvasm.expected.hlsl b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_Branch_BackEdge_MultiBlockLoop.spvasm.expected.hlsl
index ad85b1a..54db413 100644
--- a/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_Branch_BackEdge_MultiBlockLoop.spvasm.expected.hlsl
+++ b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_Branch_BackEdge_MultiBlockLoop.spvasm.expected.hlsl
@@ -1,25 +1,21 @@
 SKIP: FAILED
 
-static uint var_1 = 0u;
 
-void main_1() {
-  while (true) {
-    {
+var<private> var_1 : u32;
+
+fn main_1() {
+  loop {
+
+    continuing {
       var_1 = 1u;
     }
   }
   return;
 }
 
-void main() {
+[[stage(fragment)]]
+fn main() {
   main_1();
-  return;
 }
-warning: DXIL.dll not found.  Resulting DXIL will not be signed for use in release environments.
 
-error: validation errors
-tint_rsqlpD:12: error: Loop must have break.
-Validation failed.
-
-
-
+error: loop does not exit
diff --git a/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_Branch_BackEdge_MultiBlockLoop.spvasm.expected.msl b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_Branch_BackEdge_MultiBlockLoop.spvasm.expected.msl
new file mode 100644
index 0000000..54db413
--- /dev/null
+++ b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_Branch_BackEdge_MultiBlockLoop.spvasm.expected.msl
@@ -0,0 +1,21 @@
+SKIP: FAILED
+
+
+var<private> var_1 : u32;
+
+fn main_1() {
+  loop {
+
+    continuing {
+      var_1 = 1u;
+    }
+  }
+  return;
+}
+
+[[stage(fragment)]]
+fn main() {
+  main_1();
+}
+
+error: loop does not exit
diff --git a/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_Branch_BackEdge_MultiBlockLoop.spvasm.expected.spvasm b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_Branch_BackEdge_MultiBlockLoop.spvasm.expected.spvasm
new file mode 100644
index 0000000..54db413
--- /dev/null
+++ b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_Branch_BackEdge_MultiBlockLoop.spvasm.expected.spvasm
@@ -0,0 +1,21 @@
+SKIP: FAILED
+
+
+var<private> var_1 : u32;
+
+fn main_1() {
+  loop {
+
+    continuing {
+      var_1 = 1u;
+    }
+  }
+  return;
+}
+
+[[stage(fragment)]]
+fn main() {
+  main_1();
+}
+
+error: loop does not exit
diff --git a/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_Branch_BackEdge_MultiBlockLoop.spvasm.expected.wgsl b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_Branch_BackEdge_MultiBlockLoop.spvasm.expected.wgsl
new file mode 100644
index 0000000..54db413
--- /dev/null
+++ b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_Branch_BackEdge_MultiBlockLoop.spvasm.expected.wgsl
@@ -0,0 +1,21 @@
+SKIP: FAILED
+
+
+var<private> var_1 : u32;
+
+fn main_1() {
+  loop {
+
+    continuing {
+      var_1 = 1u;
+    }
+  }
+  return;
+}
+
+[[stage(fragment)]]
+fn main() {
+  main_1();
+}
+
+error: loop does not exit
diff --git a/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_Branch_BackEdge_SingleBlockLoop.spvasm.expected.hlsl b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_Branch_BackEdge_SingleBlockLoop.spvasm.expected.hlsl
index 33ea4ab..8c9f743 100644
--- a/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_Branch_BackEdge_SingleBlockLoop.spvasm.expected.hlsl
+++ b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_Branch_BackEdge_SingleBlockLoop.spvasm.expected.hlsl
@@ -1,23 +1,18 @@
 SKIP: FAILED
 
-static uint var_1 = 0u;
 
-void main_1() {
-  while (true) {
+var<private> var_1 : u32;
+
+fn main_1() {
+  loop {
     var_1 = 1u;
   }
   return;
 }
 
-void main() {
+[[stage(fragment)]]
+fn main() {
   main_1();
-  return;
 }
-warning: DXIL.dll not found.  Resulting DXIL will not be signed for use in release environments.
 
-error: validation errors
-tint_M8paEY:10: error: Loop must have break.
-Validation failed.
-
-
-
+error: loop does not exit
diff --git a/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_Branch_BackEdge_SingleBlockLoop.spvasm.expected.msl b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_Branch_BackEdge_SingleBlockLoop.spvasm.expected.msl
new file mode 100644
index 0000000..8c9f743
--- /dev/null
+++ b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_Branch_BackEdge_SingleBlockLoop.spvasm.expected.msl
@@ -0,0 +1,18 @@
+SKIP: FAILED
+
+
+var<private> var_1 : u32;
+
+fn main_1() {
+  loop {
+    var_1 = 1u;
+  }
+  return;
+}
+
+[[stage(fragment)]]
+fn main() {
+  main_1();
+}
+
+error: loop does not exit
diff --git a/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_Branch_BackEdge_SingleBlockLoop.spvasm.expected.spvasm b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_Branch_BackEdge_SingleBlockLoop.spvasm.expected.spvasm
new file mode 100644
index 0000000..8c9f743
--- /dev/null
+++ b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_Branch_BackEdge_SingleBlockLoop.spvasm.expected.spvasm
@@ -0,0 +1,18 @@
+SKIP: FAILED
+
+
+var<private> var_1 : u32;
+
+fn main_1() {
+  loop {
+    var_1 = 1u;
+  }
+  return;
+}
+
+[[stage(fragment)]]
+fn main() {
+  main_1();
+}
+
+error: loop does not exit
diff --git a/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_Branch_BackEdge_SingleBlockLoop.spvasm.expected.wgsl b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_Branch_BackEdge_SingleBlockLoop.spvasm.expected.wgsl
new file mode 100644
index 0000000..8c9f743
--- /dev/null
+++ b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_Branch_BackEdge_SingleBlockLoop.spvasm.expected.wgsl
@@ -0,0 +1,18 @@
+SKIP: FAILED
+
+
+var<private> var_1 : u32;
+
+fn main_1() {
+  loop {
+    var_1 = 1u;
+  }
+  return;
+}
+
+[[stage(fragment)]]
+fn main() {
+  main_1();
+}
+
+error: loop does not exit
diff --git a/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_Branch_LoopContinue_BeforeLast.spvasm.expected.hlsl b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_Branch_LoopContinue_BeforeLast.spvasm.expected.hlsl
index cda0e35..084d93f 100644
--- a/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_Branch_LoopContinue_BeforeLast.spvasm.expected.hlsl
+++ b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_Branch_LoopContinue_BeforeLast.spvasm.expected.hlsl
@@ -1,33 +1,26 @@
 SKIP: FAILED
 
-static uint var_1 = 0u;
 
-void main_1() {
-  while (true) {
+var<private> var_1 : u32;
+
+fn main_1() {
+  loop {
     if (false) {
       var_1 = 1u;
-      {
-        var_1 = 3u;
-      }
       continue;
     }
     var_1 = 2u;
-    {
+
+    continuing {
       var_1 = 3u;
     }
   }
   return;
 }
 
-void main() {
+[[stage(fragment)]]
+fn main() {
   main_1();
-  return;
 }
-warning: DXIL.dll not found.  Resulting DXIL will not be signed for use in release environments.
 
-error: validation errors
-tint_Bo3oTm:20: error: Loop must have break.
-Validation failed.
-
-
-
+error: loop does not exit
diff --git a/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_Branch_LoopContinue_BeforeLast.spvasm.expected.msl b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_Branch_LoopContinue_BeforeLast.spvasm.expected.msl
new file mode 100644
index 0000000..084d93f
--- /dev/null
+++ b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_Branch_LoopContinue_BeforeLast.spvasm.expected.msl
@@ -0,0 +1,26 @@
+SKIP: FAILED
+
+
+var<private> var_1 : u32;
+
+fn main_1() {
+  loop {
+    if (false) {
+      var_1 = 1u;
+      continue;
+    }
+    var_1 = 2u;
+
+    continuing {
+      var_1 = 3u;
+    }
+  }
+  return;
+}
+
+[[stage(fragment)]]
+fn main() {
+  main_1();
+}
+
+error: loop does not exit
diff --git a/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_Branch_LoopContinue_BeforeLast.spvasm.expected.spvasm b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_Branch_LoopContinue_BeforeLast.spvasm.expected.spvasm
new file mode 100644
index 0000000..084d93f
--- /dev/null
+++ b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_Branch_LoopContinue_BeforeLast.spvasm.expected.spvasm
@@ -0,0 +1,26 @@
+SKIP: FAILED
+
+
+var<private> var_1 : u32;
+
+fn main_1() {
+  loop {
+    if (false) {
+      var_1 = 1u;
+      continue;
+    }
+    var_1 = 2u;
+
+    continuing {
+      var_1 = 3u;
+    }
+  }
+  return;
+}
+
+[[stage(fragment)]]
+fn main() {
+  main_1();
+}
+
+error: loop does not exit
diff --git a/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_Branch_LoopContinue_BeforeLast.spvasm.expected.wgsl b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_Branch_LoopContinue_BeforeLast.spvasm.expected.wgsl
new file mode 100644
index 0000000..084d93f
--- /dev/null
+++ b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_Branch_LoopContinue_BeforeLast.spvasm.expected.wgsl
@@ -0,0 +1,26 @@
+SKIP: FAILED
+
+
+var<private> var_1 : u32;
+
+fn main_1() {
+  loop {
+    if (false) {
+      var_1 = 1u;
+      continue;
+    }
+    var_1 = 2u;
+
+    continuing {
+      var_1 = 3u;
+    }
+  }
+  return;
+}
+
+[[stage(fragment)]]
+fn main() {
+  main_1();
+}
+
+error: loop does not exit
diff --git a/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_Branch_LoopContinue_FromSwitch.spvasm.expected.hlsl b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_Branch_LoopContinue_FromSwitch.spvasm.expected.hlsl
index f85a613..7b5bc4f 100644
--- a/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_Branch_LoopContinue_FromSwitch.spvasm.expected.hlsl
+++ b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_Branch_LoopContinue_FromSwitch.spvasm.expected.hlsl
@@ -1,27 +1,24 @@
 SKIP: FAILED
 
-static uint var_1 = 0u;
 
-void main_1() {
+var<private> var_1 : u32;
+
+fn main_1() {
   var_1 = 1u;
-  while (true) {
+  loop {
     var_1 = 2u;
     var_1 = 3u;
     switch(42u) {
       case 40u: {
         var_1 = 4u;
-        {
-          var_1 = 6u;
-        }
         continue;
-        break;
       }
       default: {
-        break;
       }
     }
     var_1 = 5u;
-    {
+
+    continuing {
       var_1 = 6u;
     }
   }
@@ -29,15 +26,9 @@
   return;
 }
 
-void main() {
+[[stage(fragment)]]
+fn main() {
   main_1();
-  return;
 }
-warning: DXIL.dll not found.  Resulting DXIL will not be signed for use in release environments.
 
-error: validation errors
-tint_ZKuQdB:30: error: Loop must have break.
-Validation failed.
-
-
-
+error: loop does not exit
diff --git a/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_Branch_LoopContinue_FromSwitch.spvasm.expected.msl b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_Branch_LoopContinue_FromSwitch.spvasm.expected.msl
new file mode 100644
index 0000000..7b5bc4f
--- /dev/null
+++ b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_Branch_LoopContinue_FromSwitch.spvasm.expected.msl
@@ -0,0 +1,34 @@
+SKIP: FAILED
+
+
+var<private> var_1 : u32;
+
+fn main_1() {
+  var_1 = 1u;
+  loop {
+    var_1 = 2u;
+    var_1 = 3u;
+    switch(42u) {
+      case 40u: {
+        var_1 = 4u;
+        continue;
+      }
+      default: {
+      }
+    }
+    var_1 = 5u;
+
+    continuing {
+      var_1 = 6u;
+    }
+  }
+  var_1 = 7u;
+  return;
+}
+
+[[stage(fragment)]]
+fn main() {
+  main_1();
+}
+
+error: loop does not exit
diff --git a/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_Branch_LoopContinue_FromSwitch.spvasm.expected.spvasm b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_Branch_LoopContinue_FromSwitch.spvasm.expected.spvasm
new file mode 100644
index 0000000..7b5bc4f
--- /dev/null
+++ b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_Branch_LoopContinue_FromSwitch.spvasm.expected.spvasm
@@ -0,0 +1,34 @@
+SKIP: FAILED
+
+
+var<private> var_1 : u32;
+
+fn main_1() {
+  var_1 = 1u;
+  loop {
+    var_1 = 2u;
+    var_1 = 3u;
+    switch(42u) {
+      case 40u: {
+        var_1 = 4u;
+        continue;
+      }
+      default: {
+      }
+    }
+    var_1 = 5u;
+
+    continuing {
+      var_1 = 6u;
+    }
+  }
+  var_1 = 7u;
+  return;
+}
+
+[[stage(fragment)]]
+fn main() {
+  main_1();
+}
+
+error: loop does not exit
diff --git a/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_Branch_LoopContinue_FromSwitch.spvasm.expected.wgsl b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_Branch_LoopContinue_FromSwitch.spvasm.expected.wgsl
new file mode 100644
index 0000000..7b5bc4f
--- /dev/null
+++ b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_Branch_LoopContinue_FromSwitch.spvasm.expected.wgsl
@@ -0,0 +1,34 @@
+SKIP: FAILED
+
+
+var<private> var_1 : u32;
+
+fn main_1() {
+  var_1 = 1u;
+  loop {
+    var_1 = 2u;
+    var_1 = 3u;
+    switch(42u) {
+      case 40u: {
+        var_1 = 4u;
+        continue;
+      }
+      default: {
+      }
+    }
+    var_1 = 5u;
+
+    continuing {
+      var_1 = 6u;
+    }
+  }
+  var_1 = 7u;
+  return;
+}
+
+[[stage(fragment)]]
+fn main() {
+  main_1();
+}
+
+error: loop does not exit
diff --git a/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_Branch_LoopContinue_LastInLoopConstruct.spvasm.expected.hlsl b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_Branch_LoopContinue_LastInLoopConstruct.spvasm.expected.hlsl
index 4b18289..d43665e 100644
--- a/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_Branch_LoopContinue_LastInLoopConstruct.spvasm.expected.hlsl
+++ b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_Branch_LoopContinue_LastInLoopConstruct.spvasm.expected.hlsl
@@ -1,26 +1,22 @@
 SKIP: FAILED
 
-static uint var_1 = 0u;
 
-void main_1() {
-  while (true) {
+var<private> var_1 : u32;
+
+fn main_1() {
+  loop {
     var_1 = 1u;
-    {
+
+    continuing {
       var_1 = 2u;
     }
   }
   return;
 }
 
-void main() {
+[[stage(fragment)]]
+fn main() {
   main_1();
-  return;
 }
-warning: DXIL.dll not found.  Resulting DXIL will not be signed for use in release environments.
 
-error: validation errors
-tint_7xiEOQ:13: error: Loop must have break.
-Validation failed.
-
-
-
+error: loop does not exit
diff --git a/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_Branch_LoopContinue_LastInLoopConstruct.spvasm.expected.msl b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_Branch_LoopContinue_LastInLoopConstruct.spvasm.expected.msl
new file mode 100644
index 0000000..d43665e
--- /dev/null
+++ b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_Branch_LoopContinue_LastInLoopConstruct.spvasm.expected.msl
@@ -0,0 +1,22 @@
+SKIP: FAILED
+
+
+var<private> var_1 : u32;
+
+fn main_1() {
+  loop {
+    var_1 = 1u;
+
+    continuing {
+      var_1 = 2u;
+    }
+  }
+  return;
+}
+
+[[stage(fragment)]]
+fn main() {
+  main_1();
+}
+
+error: loop does not exit
diff --git a/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_Branch_LoopContinue_LastInLoopConstruct.spvasm.expected.spvasm b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_Branch_LoopContinue_LastInLoopConstruct.spvasm.expected.spvasm
new file mode 100644
index 0000000..d43665e
--- /dev/null
+++ b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_Branch_LoopContinue_LastInLoopConstruct.spvasm.expected.spvasm
@@ -0,0 +1,22 @@
+SKIP: FAILED
+
+
+var<private> var_1 : u32;
+
+fn main_1() {
+  loop {
+    var_1 = 1u;
+
+    continuing {
+      var_1 = 2u;
+    }
+  }
+  return;
+}
+
+[[stage(fragment)]]
+fn main() {
+  main_1();
+}
+
+error: loop does not exit
diff --git a/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_Branch_LoopContinue_LastInLoopConstruct.spvasm.expected.wgsl b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_Branch_LoopContinue_LastInLoopConstruct.spvasm.expected.wgsl
new file mode 100644
index 0000000..d43665e
--- /dev/null
+++ b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_Branch_LoopContinue_LastInLoopConstruct.spvasm.expected.wgsl
@@ -0,0 +1,22 @@
+SKIP: FAILED
+
+
+var<private> var_1 : u32;
+
+fn main_1() {
+  loop {
+    var_1 = 1u;
+
+    continuing {
+      var_1 = 2u;
+    }
+  }
+  return;
+}
+
+[[stage(fragment)]]
+fn main() {
+  main_1();
+}
+
+error: loop does not exit
diff --git a/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_FalseBranch_LoopContinue.spvasm.expected.hlsl b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_FalseBranch_LoopContinue.spvasm.expected.hlsl
index 346c039..b7ad7d3 100644
--- a/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_FalseBranch_LoopContinue.spvasm.expected.hlsl
+++ b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_FalseBranch_LoopContinue.spvasm.expected.hlsl
@@ -1,9 +1,10 @@
 SKIP: FAILED
 
-static uint var_1 = 0u;
 
-void main_1() {
-  while (true) {
+var<private> var_1 : u32;
+
+fn main_1() {
+  loop {
     if (false) {
     } else {
       continue;
@@ -12,15 +13,9 @@
   return;
 }
 
-void main() {
+[[stage(fragment)]]
+fn main() {
   main_1();
-  return;
 }
-warning: DXIL.dll not found.  Resulting DXIL will not be signed for use in release environments.
 
-error: validation errors
-tint_dFrzYz:13: error: Loop must have break.
-Validation failed.
-
-
-
+error: loop does not exit
diff --git a/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_FalseBranch_LoopContinue.spvasm.expected.msl b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_FalseBranch_LoopContinue.spvasm.expected.msl
new file mode 100644
index 0000000..b7ad7d3
--- /dev/null
+++ b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_FalseBranch_LoopContinue.spvasm.expected.msl
@@ -0,0 +1,21 @@
+SKIP: FAILED
+
+
+var<private> var_1 : u32;
+
+fn main_1() {
+  loop {
+    if (false) {
+    } else {
+      continue;
+    }
+  }
+  return;
+}
+
+[[stage(fragment)]]
+fn main() {
+  main_1();
+}
+
+error: loop does not exit
diff --git a/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_FalseBranch_LoopContinue.spvasm.expected.spvasm b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_FalseBranch_LoopContinue.spvasm.expected.spvasm
new file mode 100644
index 0000000..b7ad7d3
--- /dev/null
+++ b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_FalseBranch_LoopContinue.spvasm.expected.spvasm
@@ -0,0 +1,21 @@
+SKIP: FAILED
+
+
+var<private> var_1 : u32;
+
+fn main_1() {
+  loop {
+    if (false) {
+    } else {
+      continue;
+    }
+  }
+  return;
+}
+
+[[stage(fragment)]]
+fn main() {
+  main_1();
+}
+
+error: loop does not exit
diff --git a/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_FalseBranch_LoopContinue.spvasm.expected.wgsl b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_FalseBranch_LoopContinue.spvasm.expected.wgsl
new file mode 100644
index 0000000..b7ad7d3
--- /dev/null
+++ b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_FalseBranch_LoopContinue.spvasm.expected.wgsl
@@ -0,0 +1,21 @@
+SKIP: FAILED
+
+
+var<private> var_1 : u32;
+
+fn main_1() {
+  loop {
+    if (false) {
+    } else {
+      continue;
+    }
+  }
+  return;
+}
+
+[[stage(fragment)]]
+fn main() {
+  main_1();
+}
+
+error: loop does not exit
diff --git a/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_IfSelection_TrueBranch_LoopBreak.spvasm.expected.hlsl b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_IfSelection_TrueBranch_LoopBreak.spvasm.expected.hlsl
index 8ccdfef..cb1311b 100644
--- a/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_IfSelection_TrueBranch_LoopBreak.spvasm.expected.hlsl
+++ b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_IfSelection_TrueBranch_LoopBreak.spvasm.expected.hlsl
@@ -3,7 +3,7 @@
 static uint var_1 = 0u;
 
 void main_1() {
-  while (true) {
+  [loop] while (true) {
     if (false) {
       break;
     }
@@ -18,7 +18,7 @@
 warning: DXIL.dll not found.  Resulting DXIL will not be signed for use in release environments.
 
 error: validation errors
-tint_FvyNcC:12: error: Loop must have break.
+/tmp/tint_lRzVSG:12: error: Loop must have break.
 Validation failed.
 
 
diff --git a/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_Kill_InsideLoop.spvasm.expected.hlsl b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_Kill_InsideLoop.spvasm.expected.hlsl
index 9e2cfec..cc96aff 100644
--- a/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_Kill_InsideLoop.spvasm.expected.hlsl
+++ b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_Kill_InsideLoop.spvasm.expected.hlsl
@@ -1,9 +1,10 @@
 SKIP: FAILED
 
+warning: code is unreachable
 static uint var_1 = 0u;
 
 void main_1() {
-  while (true) {
+  [loop] while (true) {
     discard;
   }
   discard;
diff --git a/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_LoopInternallyDiverge_Simple.spvasm.expected.hlsl b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_LoopInternallyDiverge_Simple.spvasm.expected.hlsl
index 31646eb..c9b1ed7 100644
--- a/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_LoopInternallyDiverge_Simple.spvasm.expected.hlsl
+++ b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_LoopInternallyDiverge_Simple.spvasm.expected.hlsl
@@ -1,21 +1,20 @@
 SKIP: FAILED
 
-static uint var_1 = 0u;
 
-void main_1() {
+var<private> var_1 : u32;
+
+fn main_1() {
   var_1 = 10u;
-  while (true) {
+  loop {
     var_1 = 20u;
     if (false) {
       var_1 = 30u;
-      {
-        var_1 = 90u;
-      }
       continue;
     } else {
       var_1 = 40u;
     }
-    {
+
+    continuing {
       var_1 = 90u;
     }
   }
@@ -23,15 +22,9 @@
   return;
 }
 
-void main() {
+[[stage(fragment)]]
+fn main() {
   main_1();
-  return;
 }
-warning: DXIL.dll not found.  Resulting DXIL will not be signed for use in release environments.
 
-error: validation errors
-tint_zB6KUk:24: error: Loop must have break.
-Validation failed.
-
-
-
+error: loop does not exit
diff --git a/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_LoopInternallyDiverge_Simple.spvasm.expected.msl b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_LoopInternallyDiverge_Simple.spvasm.expected.msl
new file mode 100644
index 0000000..c9b1ed7
--- /dev/null
+++ b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_LoopInternallyDiverge_Simple.spvasm.expected.msl
@@ -0,0 +1,30 @@
+SKIP: FAILED
+
+
+var<private> var_1 : u32;
+
+fn main_1() {
+  var_1 = 10u;
+  loop {
+    var_1 = 20u;
+    if (false) {
+      var_1 = 30u;
+      continue;
+    } else {
+      var_1 = 40u;
+    }
+
+    continuing {
+      var_1 = 90u;
+    }
+  }
+  var_1 = 99u;
+  return;
+}
+
+[[stage(fragment)]]
+fn main() {
+  main_1();
+}
+
+error: loop does not exit
diff --git a/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_LoopInternallyDiverge_Simple.spvasm.expected.spvasm b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_LoopInternallyDiverge_Simple.spvasm.expected.spvasm
new file mode 100644
index 0000000..c9b1ed7
--- /dev/null
+++ b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_LoopInternallyDiverge_Simple.spvasm.expected.spvasm
@@ -0,0 +1,30 @@
+SKIP: FAILED
+
+
+var<private> var_1 : u32;
+
+fn main_1() {
+  var_1 = 10u;
+  loop {
+    var_1 = 20u;
+    if (false) {
+      var_1 = 30u;
+      continue;
+    } else {
+      var_1 = 40u;
+    }
+
+    continuing {
+      var_1 = 90u;
+    }
+  }
+  var_1 = 99u;
+  return;
+}
+
+[[stage(fragment)]]
+fn main() {
+  main_1();
+}
+
+error: loop does not exit
diff --git a/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_LoopInternallyDiverge_Simple.spvasm.expected.wgsl b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_LoopInternallyDiverge_Simple.spvasm.expected.wgsl
new file mode 100644
index 0000000..c9b1ed7
--- /dev/null
+++ b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_LoopInternallyDiverge_Simple.spvasm.expected.wgsl
@@ -0,0 +1,30 @@
+SKIP: FAILED
+
+
+var<private> var_1 : u32;
+
+fn main_1() {
+  var_1 = 10u;
+  loop {
+    var_1 = 20u;
+    if (false) {
+      var_1 = 30u;
+      continue;
+    } else {
+      var_1 = 40u;
+    }
+
+    continuing {
+      var_1 = 90u;
+    }
+  }
+  var_1 = 99u;
+  return;
+}
+
+[[stage(fragment)]]
+fn main() {
+  main_1();
+}
+
+error: loop does not exit
diff --git a/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_Loop_BodyConditionallyBreaks_FromTrue.spvasm.expected.hlsl b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_Loop_BodyConditionallyBreaks_FromTrue.spvasm.expected.hlsl
index 1456916..73f066c 100644
--- a/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_Loop_BodyConditionallyBreaks_FromTrue.spvasm.expected.hlsl
+++ b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_Loop_BodyConditionallyBreaks_FromTrue.spvasm.expected.hlsl
@@ -3,7 +3,7 @@
 static uint var_1 = 0u;
 
 void main_1() {
-  while (true) {
+  [loop] while (true) {
     var_1 = 1u;
     if (false) {
       break;
@@ -22,7 +22,7 @@
 warning: DXIL.dll not found.  Resulting DXIL will not be signed for use in release environments.
 
 error: validation errors
-tint_LKWCSU:16: error: Loop must have break.
+/tmp/tint_KRVOs8:16: error: Loop must have break.
 Validation failed.
 
 
diff --git a/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_Loop_BodyConditionallyBreaks_FromTrue_Early.spvasm.expected.hlsl b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_Loop_BodyConditionallyBreaks_FromTrue_Early.spvasm.expected.hlsl
index 9853837..a919464 100644
--- a/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_Loop_BodyConditionallyBreaks_FromTrue_Early.spvasm.expected.hlsl
+++ b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_Loop_BodyConditionallyBreaks_FromTrue_Early.spvasm.expected.hlsl
@@ -3,7 +3,7 @@
 static uint var_1 = 0u;
 
 void main_1() {
-  while (true) {
+  [loop] while (true) {
     var_1 = 1u;
     if (false) {
       break;
@@ -23,7 +23,7 @@
 warning: DXIL.dll not found.  Resulting DXIL will not be signed for use in release environments.
 
 error: validation errors
-tint_ilDeI2:17: error: Loop must have break.
+/tmp/tint_tGC31y:17: error: Loop must have break.
 Validation failed.
 
 
diff --git a/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_Loop_MultiBlockContinueIsEntireLoop.spvasm.expected.hlsl b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_Loop_MultiBlockContinueIsEntireLoop.spvasm.expected.hlsl
index 6701d81..4ffe39d 100644
--- a/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_Loop_MultiBlockContinueIsEntireLoop.spvasm.expected.hlsl
+++ b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_Loop_MultiBlockContinueIsEntireLoop.spvasm.expected.hlsl
@@ -4,7 +4,7 @@
 
 void main_1() {
   var_1 = 0u;
-  while (true) {
+  [loop] while (true) {
     var_1 = 1u;
     var_1 = 2u;
     if (false) {
@@ -22,7 +22,7 @@
 warning: DXIL.dll not found.  Resulting DXIL will not be signed for use in release environments.
 
 error: validation errors
-tint_ol4Bod:16: error: Loop must have break.
+/tmp/tint_cS4x46:16: error: Loop must have break.
 Validation failed.
 
 
diff --git a/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_Loop_NestedIfContinue.spvasm.expected.hlsl b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_Loop_NestedIfContinue.spvasm.expected.hlsl
index 56b3000..084d93f 100644
--- a/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_Loop_NestedIfContinue.spvasm.expected.hlsl
+++ b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_Loop_NestedIfContinue.spvasm.expected.hlsl
@@ -1,33 +1,26 @@
 SKIP: FAILED
 
-static uint var_1 = 0u;
 
-void main_1() {
-  while (true) {
+var<private> var_1 : u32;
+
+fn main_1() {
+  loop {
     if (false) {
       var_1 = 1u;
-      {
-        var_1 = 3u;
-      }
       continue;
     }
     var_1 = 2u;
-    {
+
+    continuing {
       var_1 = 3u;
     }
   }
   return;
 }
 
-void main() {
+[[stage(fragment)]]
+fn main() {
   main_1();
-  return;
 }
-warning: DXIL.dll not found.  Resulting DXIL will not be signed for use in release environments.
 
-error: validation errors
-tint_MlbMXj:20: error: Loop must have break.
-Validation failed.
-
-
-
+error: loop does not exit
diff --git a/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_Loop_NestedIfContinue.spvasm.expected.msl b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_Loop_NestedIfContinue.spvasm.expected.msl
new file mode 100644
index 0000000..084d93f
--- /dev/null
+++ b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_Loop_NestedIfContinue.spvasm.expected.msl
@@ -0,0 +1,26 @@
+SKIP: FAILED
+
+
+var<private> var_1 : u32;
+
+fn main_1() {
+  loop {
+    if (false) {
+      var_1 = 1u;
+      continue;
+    }
+    var_1 = 2u;
+
+    continuing {
+      var_1 = 3u;
+    }
+  }
+  return;
+}
+
+[[stage(fragment)]]
+fn main() {
+  main_1();
+}
+
+error: loop does not exit
diff --git a/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_Loop_NestedIfContinue.spvasm.expected.spvasm b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_Loop_NestedIfContinue.spvasm.expected.spvasm
new file mode 100644
index 0000000..084d93f
--- /dev/null
+++ b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_Loop_NestedIfContinue.spvasm.expected.spvasm
@@ -0,0 +1,26 @@
+SKIP: FAILED
+
+
+var<private> var_1 : u32;
+
+fn main_1() {
+  loop {
+    if (false) {
+      var_1 = 1u;
+      continue;
+    }
+    var_1 = 2u;
+
+    continuing {
+      var_1 = 3u;
+    }
+  }
+  return;
+}
+
+[[stage(fragment)]]
+fn main() {
+  main_1();
+}
+
+error: loop does not exit
diff --git a/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_Loop_NestedIfContinue.spvasm.expected.wgsl b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_Loop_NestedIfContinue.spvasm.expected.wgsl
new file mode 100644
index 0000000..084d93f
--- /dev/null
+++ b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_Loop_NestedIfContinue.spvasm.expected.wgsl
@@ -0,0 +1,26 @@
+SKIP: FAILED
+
+
+var<private> var_1 : u32;
+
+fn main_1() {
+  loop {
+    if (false) {
+      var_1 = 1u;
+      continue;
+    }
+    var_1 = 2u;
+
+    continuing {
+      var_1 = 3u;
+    }
+  }
+  return;
+}
+
+[[stage(fragment)]]
+fn main() {
+  main_1();
+}
+
+error: loop does not exit
diff --git a/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_Loop_SingleBlock_BothBackedge.spvasm.expected.hlsl b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_Loop_SingleBlock_BothBackedge.spvasm.expected.hlsl
index 9e25b63..0fcda02 100644
--- a/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_Loop_SingleBlock_BothBackedge.spvasm.expected.hlsl
+++ b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_Loop_SingleBlock_BothBackedge.spvasm.expected.hlsl
@@ -1,25 +1,20 @@
 SKIP: FAILED
 
-static uint var_1 = 0u;
 
-void main_1() {
+var<private> var_1 : u32;
+
+fn main_1() {
   var_1 = 0u;
-  while (true) {
+  loop {
     var_1 = 1u;
   }
   var_1 = 999u;
   return;
 }
 
-void main() {
+[[stage(fragment)]]
+fn main() {
   main_1();
-  return;
 }
-warning: DXIL.dll not found.  Resulting DXIL will not be signed for use in release environments.
 
-error: validation errors
-tint_4MTE0x:12: error: Loop must have break.
-Validation failed.
-
-
-
+error: loop does not exit
diff --git a/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_Loop_SingleBlock_BothBackedge.spvasm.expected.msl b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_Loop_SingleBlock_BothBackedge.spvasm.expected.msl
new file mode 100644
index 0000000..0fcda02
--- /dev/null
+++ b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_Loop_SingleBlock_BothBackedge.spvasm.expected.msl
@@ -0,0 +1,20 @@
+SKIP: FAILED
+
+
+var<private> var_1 : u32;
+
+fn main_1() {
+  var_1 = 0u;
+  loop {
+    var_1 = 1u;
+  }
+  var_1 = 999u;
+  return;
+}
+
+[[stage(fragment)]]
+fn main() {
+  main_1();
+}
+
+error: loop does not exit
diff --git a/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_Loop_SingleBlock_BothBackedge.spvasm.expected.spvasm b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_Loop_SingleBlock_BothBackedge.spvasm.expected.spvasm
new file mode 100644
index 0000000..0fcda02
--- /dev/null
+++ b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_Loop_SingleBlock_BothBackedge.spvasm.expected.spvasm
@@ -0,0 +1,20 @@
+SKIP: FAILED
+
+
+var<private> var_1 : u32;
+
+fn main_1() {
+  var_1 = 0u;
+  loop {
+    var_1 = 1u;
+  }
+  var_1 = 999u;
+  return;
+}
+
+[[stage(fragment)]]
+fn main() {
+  main_1();
+}
+
+error: loop does not exit
diff --git a/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_Loop_SingleBlock_BothBackedge.spvasm.expected.wgsl b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_Loop_SingleBlock_BothBackedge.spvasm.expected.wgsl
new file mode 100644
index 0000000..0fcda02
--- /dev/null
+++ b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_Loop_SingleBlock_BothBackedge.spvasm.expected.wgsl
@@ -0,0 +1,20 @@
+SKIP: FAILED
+
+
+var<private> var_1 : u32;
+
+fn main_1() {
+  var_1 = 0u;
+  loop {
+    var_1 = 1u;
+  }
+  var_1 = 999u;
+  return;
+}
+
+[[stage(fragment)]]
+fn main() {
+  main_1();
+}
+
+error: loop does not exit
diff --git a/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_Loop_SingleBlock_FalseBackedge.spvasm.expected.hlsl b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_Loop_SingleBlock_FalseBackedge.spvasm.expected.hlsl
index 7ace5c3..ba462d6 100644
--- a/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_Loop_SingleBlock_FalseBackedge.spvasm.expected.hlsl
+++ b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_Loop_SingleBlock_FalseBackedge.spvasm.expected.hlsl
@@ -4,7 +4,7 @@
 
 void main_1() {
   var_1 = 0u;
-  while (true) {
+  [loop] while (true) {
     var_1 = 1u;
     if (false) {
       break;
@@ -21,7 +21,7 @@
 warning: DXIL.dll not found.  Resulting DXIL will not be signed for use in release environments.
 
 error: validation errors
-tint_zYChsb:15: error: Loop must have break.
+/tmp/tint_Iz92Ch:15: error: Loop must have break.
 Validation failed.
 
 
diff --git a/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_Loop_SingleBlock_UnconditionalBackege.spvasm.expected.hlsl b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_Loop_SingleBlock_UnconditionalBackege.spvasm.expected.hlsl
index c382cf9..0fcda02 100644
--- a/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_Loop_SingleBlock_UnconditionalBackege.spvasm.expected.hlsl
+++ b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_Loop_SingleBlock_UnconditionalBackege.spvasm.expected.hlsl
@@ -1,25 +1,20 @@
 SKIP: FAILED
 
-static uint var_1 = 0u;
 
-void main_1() {
+var<private> var_1 : u32;
+
+fn main_1() {
   var_1 = 0u;
-  while (true) {
+  loop {
     var_1 = 1u;
   }
   var_1 = 999u;
   return;
 }
 
-void main() {
+[[stage(fragment)]]
+fn main() {
   main_1();
-  return;
 }
-warning: DXIL.dll not found.  Resulting DXIL will not be signed for use in release environments.
 
-error: validation errors
-tint_chIw8M:12: error: Loop must have break.
-Validation failed.
-
-
-
+error: loop does not exit
diff --git a/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_Loop_SingleBlock_UnconditionalBackege.spvasm.expected.msl b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_Loop_SingleBlock_UnconditionalBackege.spvasm.expected.msl
new file mode 100644
index 0000000..0fcda02
--- /dev/null
+++ b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_Loop_SingleBlock_UnconditionalBackege.spvasm.expected.msl
@@ -0,0 +1,20 @@
+SKIP: FAILED
+
+
+var<private> var_1 : u32;
+
+fn main_1() {
+  var_1 = 0u;
+  loop {
+    var_1 = 1u;
+  }
+  var_1 = 999u;
+  return;
+}
+
+[[stage(fragment)]]
+fn main() {
+  main_1();
+}
+
+error: loop does not exit
diff --git a/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_Loop_SingleBlock_UnconditionalBackege.spvasm.expected.spvasm b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_Loop_SingleBlock_UnconditionalBackege.spvasm.expected.spvasm
new file mode 100644
index 0000000..0fcda02
--- /dev/null
+++ b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_Loop_SingleBlock_UnconditionalBackege.spvasm.expected.spvasm
@@ -0,0 +1,20 @@
+SKIP: FAILED
+
+
+var<private> var_1 : u32;
+
+fn main_1() {
+  var_1 = 0u;
+  loop {
+    var_1 = 1u;
+  }
+  var_1 = 999u;
+  return;
+}
+
+[[stage(fragment)]]
+fn main() {
+  main_1();
+}
+
+error: loop does not exit
diff --git a/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_Loop_SingleBlock_UnconditionalBackege.spvasm.expected.wgsl b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_Loop_SingleBlock_UnconditionalBackege.spvasm.expected.wgsl
new file mode 100644
index 0000000..0fcda02
--- /dev/null
+++ b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_Loop_SingleBlock_UnconditionalBackege.spvasm.expected.wgsl
@@ -0,0 +1,20 @@
+SKIP: FAILED
+
+
+var<private> var_1 : u32;
+
+fn main_1() {
+  var_1 = 0u;
+  loop {
+    var_1 = 1u;
+  }
+  var_1 = 999u;
+  return;
+}
+
+[[stage(fragment)]]
+fn main() {
+  main_1();
+}
+
+error: loop does not exit
diff --git a/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_Loop_Unconditional_Body_ContinueNestIf.spvasm.expected.hlsl b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_Loop_Unconditional_Body_ContinueNestIf.spvasm.expected.hlsl
index 29dbf21..ae96510 100644
--- a/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_Loop_Unconditional_Body_ContinueNestIf.spvasm.expected.hlsl
+++ b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_Loop_Unconditional_Body_ContinueNestIf.spvasm.expected.hlsl
@@ -1,13 +1,15 @@
 SKIP: FAILED
 
-static uint var_1 = 0u;
 
-void main_1() {
+var<private> var_1 : u32;
+
+fn main_1() {
   var_1 = 0u;
-  while (true) {
+  loop {
     var_1 = 1u;
     var_1 = 2u;
-    {
+
+    continuing {
       var_1 = 3u;
       if (true) {
         var_1 = 4u;
@@ -19,15 +21,9 @@
   return;
 }
 
-void main() {
+[[stage(fragment)]]
+fn main() {
   main_1();
-  return;
 }
-warning: DXIL.dll not found.  Resulting DXIL will not be signed for use in release environments.
 
-error: validation errors
-tint_lyH14u:20: error: Loop must have break.
-Validation failed.
-
-
-
+error: loop does not exit
diff --git a/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_Loop_Unconditional_Body_ContinueNestIf.spvasm.expected.msl b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_Loop_Unconditional_Body_ContinueNestIf.spvasm.expected.msl
new file mode 100644
index 0000000..ae96510
--- /dev/null
+++ b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_Loop_Unconditional_Body_ContinueNestIf.spvasm.expected.msl
@@ -0,0 +1,29 @@
+SKIP: FAILED
+
+
+var<private> var_1 : u32;
+
+fn main_1() {
+  var_1 = 0u;
+  loop {
+    var_1 = 1u;
+    var_1 = 2u;
+
+    continuing {
+      var_1 = 3u;
+      if (true) {
+        var_1 = 4u;
+      }
+      var_1 = 5u;
+    }
+  }
+  var_1 = 999u;
+  return;
+}
+
+[[stage(fragment)]]
+fn main() {
+  main_1();
+}
+
+error: loop does not exit
diff --git a/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_Loop_Unconditional_Body_ContinueNestIf.spvasm.expected.spvasm b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_Loop_Unconditional_Body_ContinueNestIf.spvasm.expected.spvasm
new file mode 100644
index 0000000..ae96510
--- /dev/null
+++ b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_Loop_Unconditional_Body_ContinueNestIf.spvasm.expected.spvasm
@@ -0,0 +1,29 @@
+SKIP: FAILED
+
+
+var<private> var_1 : u32;
+
+fn main_1() {
+  var_1 = 0u;
+  loop {
+    var_1 = 1u;
+    var_1 = 2u;
+
+    continuing {
+      var_1 = 3u;
+      if (true) {
+        var_1 = 4u;
+      }
+      var_1 = 5u;
+    }
+  }
+  var_1 = 999u;
+  return;
+}
+
+[[stage(fragment)]]
+fn main() {
+  main_1();
+}
+
+error: loop does not exit
diff --git a/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_Loop_Unconditional_Body_ContinueNestIf.spvasm.expected.wgsl b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_Loop_Unconditional_Body_ContinueNestIf.spvasm.expected.wgsl
new file mode 100644
index 0000000..ae96510
--- /dev/null
+++ b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_Loop_Unconditional_Body_ContinueNestIf.spvasm.expected.wgsl
@@ -0,0 +1,29 @@
+SKIP: FAILED
+
+
+var<private> var_1 : u32;
+
+fn main_1() {
+  var_1 = 0u;
+  loop {
+    var_1 = 1u;
+    var_1 = 2u;
+
+    continuing {
+      var_1 = 3u;
+      if (true) {
+        var_1 = 4u;
+      }
+      var_1 = 5u;
+    }
+  }
+  var_1 = 999u;
+  return;
+}
+
+[[stage(fragment)]]
+fn main() {
+  main_1();
+}
+
+error: loop does not exit
diff --git a/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_Loop_Unconditional_Body_MultiBlockContinue.spvasm.expected.hlsl b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_Loop_Unconditional_Body_MultiBlockContinue.spvasm.expected.hlsl
index ea62bd5..9e69952 100644
--- a/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_Loop_Unconditional_Body_MultiBlockContinue.spvasm.expected.hlsl
+++ b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_Loop_Unconditional_Body_MultiBlockContinue.spvasm.expected.hlsl
@@ -1,13 +1,15 @@
 SKIP: FAILED
 
-static uint var_1 = 0u;
 
-void main_1() {
+var<private> var_1 : u32;
+
+fn main_1() {
   var_1 = 0u;
-  while (true) {
+  loop {
     var_1 = 1u;
     var_1 = 2u;
-    {
+
+    continuing {
       var_1 = 3u;
       var_1 = 4u;
     }
@@ -16,15 +18,9 @@
   return;
 }
 
-void main() {
+[[stage(fragment)]]
+fn main() {
   main_1();
-  return;
 }
-warning: DXIL.dll not found.  Resulting DXIL will not be signed for use in release environments.
 
-error: validation errors
-tint_WSJX53:17: error: Loop must have break.
-Validation failed.
-
-
-
+error: loop does not exit
diff --git a/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_Loop_Unconditional_Body_MultiBlockContinue.spvasm.expected.msl b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_Loop_Unconditional_Body_MultiBlockContinue.spvasm.expected.msl
new file mode 100644
index 0000000..9e69952
--- /dev/null
+++ b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_Loop_Unconditional_Body_MultiBlockContinue.spvasm.expected.msl
@@ -0,0 +1,26 @@
+SKIP: FAILED
+
+
+var<private> var_1 : u32;
+
+fn main_1() {
+  var_1 = 0u;
+  loop {
+    var_1 = 1u;
+    var_1 = 2u;
+
+    continuing {
+      var_1 = 3u;
+      var_1 = 4u;
+    }
+  }
+  var_1 = 999u;
+  return;
+}
+
+[[stage(fragment)]]
+fn main() {
+  main_1();
+}
+
+error: loop does not exit
diff --git a/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_Loop_Unconditional_Body_MultiBlockContinue.spvasm.expected.spvasm b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_Loop_Unconditional_Body_MultiBlockContinue.spvasm.expected.spvasm
new file mode 100644
index 0000000..9e69952
--- /dev/null
+++ b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_Loop_Unconditional_Body_MultiBlockContinue.spvasm.expected.spvasm
@@ -0,0 +1,26 @@
+SKIP: FAILED
+
+
+var<private> var_1 : u32;
+
+fn main_1() {
+  var_1 = 0u;
+  loop {
+    var_1 = 1u;
+    var_1 = 2u;
+
+    continuing {
+      var_1 = 3u;
+      var_1 = 4u;
+    }
+  }
+  var_1 = 999u;
+  return;
+}
+
+[[stage(fragment)]]
+fn main() {
+  main_1();
+}
+
+error: loop does not exit
diff --git a/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_Loop_Unconditional_Body_MultiBlockContinue.spvasm.expected.wgsl b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_Loop_Unconditional_Body_MultiBlockContinue.spvasm.expected.wgsl
new file mode 100644
index 0000000..9e69952
--- /dev/null
+++ b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_Loop_Unconditional_Body_MultiBlockContinue.spvasm.expected.wgsl
@@ -0,0 +1,26 @@
+SKIP: FAILED
+
+
+var<private> var_1 : u32;
+
+fn main_1() {
+  var_1 = 0u;
+  loop {
+    var_1 = 1u;
+    var_1 = 2u;
+
+    continuing {
+      var_1 = 3u;
+      var_1 = 4u;
+    }
+  }
+  var_1 = 999u;
+  return;
+}
+
+[[stage(fragment)]]
+fn main() {
+  main_1();
+}
+
+error: loop does not exit
diff --git a/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_Loop_Unconditional_Body_SingleBlockContinue.spvasm.expected.hlsl b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_Loop_Unconditional_Body_SingleBlockContinue.spvasm.expected.hlsl
index d42179c..e32d9bd 100644
--- a/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_Loop_Unconditional_Body_SingleBlockContinue.spvasm.expected.hlsl
+++ b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_Loop_Unconditional_Body_SingleBlockContinue.spvasm.expected.hlsl
@@ -1,13 +1,15 @@
 SKIP: FAILED
 
-static uint var_1 = 0u;
 
-void main_1() {
+var<private> var_1 : u32;
+
+fn main_1() {
   var_1 = 0u;
-  while (true) {
+  loop {
     var_1 = 1u;
     var_1 = 2u;
-    {
+
+    continuing {
       var_1 = 3u;
     }
   }
@@ -15,15 +17,9 @@
   return;
 }
 
-void main() {
+[[stage(fragment)]]
+fn main() {
   main_1();
-  return;
 }
-warning: DXIL.dll not found.  Resulting DXIL will not be signed for use in release environments.
 
-error: validation errors
-tint_vD8PSg:16: error: Loop must have break.
-Validation failed.
-
-
-
+error: loop does not exit
diff --git a/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_Loop_Unconditional_Body_SingleBlockContinue.spvasm.expected.msl b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_Loop_Unconditional_Body_SingleBlockContinue.spvasm.expected.msl
new file mode 100644
index 0000000..e32d9bd
--- /dev/null
+++ b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_Loop_Unconditional_Body_SingleBlockContinue.spvasm.expected.msl
@@ -0,0 +1,25 @@
+SKIP: FAILED
+
+
+var<private> var_1 : u32;
+
+fn main_1() {
+  var_1 = 0u;
+  loop {
+    var_1 = 1u;
+    var_1 = 2u;
+
+    continuing {
+      var_1 = 3u;
+    }
+  }
+  var_1 = 999u;
+  return;
+}
+
+[[stage(fragment)]]
+fn main() {
+  main_1();
+}
+
+error: loop does not exit
diff --git a/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_Loop_Unconditional_Body_SingleBlockContinue.spvasm.expected.spvasm b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_Loop_Unconditional_Body_SingleBlockContinue.spvasm.expected.spvasm
new file mode 100644
index 0000000..e32d9bd
--- /dev/null
+++ b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_Loop_Unconditional_Body_SingleBlockContinue.spvasm.expected.spvasm
@@ -0,0 +1,25 @@
+SKIP: FAILED
+
+
+var<private> var_1 : u32;
+
+fn main_1() {
+  var_1 = 0u;
+  loop {
+    var_1 = 1u;
+    var_1 = 2u;
+
+    continuing {
+      var_1 = 3u;
+    }
+  }
+  var_1 = 999u;
+  return;
+}
+
+[[stage(fragment)]]
+fn main() {
+  main_1();
+}
+
+error: loop does not exit
diff --git a/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_Loop_Unconditional_Body_SingleBlockContinue.spvasm.expected.wgsl b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_Loop_Unconditional_Body_SingleBlockContinue.spvasm.expected.wgsl
new file mode 100644
index 0000000..e32d9bd
--- /dev/null
+++ b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_Loop_Unconditional_Body_SingleBlockContinue.spvasm.expected.wgsl
@@ -0,0 +1,25 @@
+SKIP: FAILED
+
+
+var<private> var_1 : u32;
+
+fn main_1() {
+  var_1 = 0u;
+  loop {
+    var_1 = 1u;
+    var_1 = 2u;
+
+    continuing {
+      var_1 = 3u;
+    }
+  }
+  var_1 = 999u;
+  return;
+}
+
+[[stage(fragment)]]
+fn main() {
+  main_1();
+}
+
+error: loop does not exit
diff --git a/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_TrueBranch_LoopContinue.spvasm.expected.hlsl b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_TrueBranch_LoopContinue.spvasm.expected.hlsl
index 19ad3d0..32e75fb 100644
--- a/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_TrueBranch_LoopContinue.spvasm.expected.hlsl
+++ b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_TrueBranch_LoopContinue.spvasm.expected.hlsl
@@ -1,9 +1,10 @@
 SKIP: FAILED
 
-static uint var_1 = 0u;
 
-void main_1() {
-  while (true) {
+var<private> var_1 : u32;
+
+fn main_1() {
+  loop {
     if (false) {
       continue;
     }
@@ -11,15 +12,9 @@
   return;
 }
 
-void main() {
+[[stage(fragment)]]
+fn main() {
   main_1();
-  return;
 }
-warning: DXIL.dll not found.  Resulting DXIL will not be signed for use in release environments.
 
-error: validation errors
-tint_EyIpkA:12: error: Loop must have break.
-Validation failed.
-
-
-
+error: loop does not exit
diff --git a/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_TrueBranch_LoopContinue.spvasm.expected.msl b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_TrueBranch_LoopContinue.spvasm.expected.msl
new file mode 100644
index 0000000..32e75fb
--- /dev/null
+++ b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_TrueBranch_LoopContinue.spvasm.expected.msl
@@ -0,0 +1,20 @@
+SKIP: FAILED
+
+
+var<private> var_1 : u32;
+
+fn main_1() {
+  loop {
+    if (false) {
+      continue;
+    }
+  }
+  return;
+}
+
+[[stage(fragment)]]
+fn main() {
+  main_1();
+}
+
+error: loop does not exit
diff --git a/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_TrueBranch_LoopContinue.spvasm.expected.spvasm b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_TrueBranch_LoopContinue.spvasm.expected.spvasm
new file mode 100644
index 0000000..32e75fb
--- /dev/null
+++ b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_TrueBranch_LoopContinue.spvasm.expected.spvasm
@@ -0,0 +1,20 @@
+SKIP: FAILED
+
+
+var<private> var_1 : u32;
+
+fn main_1() {
+  loop {
+    if (false) {
+      continue;
+    }
+  }
+  return;
+}
+
+[[stage(fragment)]]
+fn main() {
+  main_1();
+}
+
+error: loop does not exit
diff --git a/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_TrueBranch_LoopContinue.spvasm.expected.wgsl b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_TrueBranch_LoopContinue.spvasm.expected.wgsl
new file mode 100644
index 0000000..32e75fb
--- /dev/null
+++ b/test/unittest/reader/spirv/SpvParserCFGTest_EmitBody_TrueBranch_LoopContinue.spvasm.expected.wgsl
@@ -0,0 +1,20 @@
+SKIP: FAILED
+
+
+var<private> var_1 : u32;
+
+fn main_1() {
+  loop {
+    if (false) {
+      continue;
+    }
+  }
+  return;
+}
+
+[[stage(fragment)]]
+fn main() {
+  main_1();
+}
+
+error: loop does not exit
diff --git a/test/unittest/reader/spirv/SpvParserCFGTest_FindIfSelectionInternalHeaders_FalseBranch_LoopContinue_Ok.spvasm.expected.hlsl b/test/unittest/reader/spirv/SpvParserCFGTest_FindIfSelectionInternalHeaders_FalseBranch_LoopContinue_Ok.spvasm.expected.hlsl
index a43ffcd..b7ad7d3 100644
--- a/test/unittest/reader/spirv/SpvParserCFGTest_FindIfSelectionInternalHeaders_FalseBranch_LoopContinue_Ok.spvasm.expected.hlsl
+++ b/test/unittest/reader/spirv/SpvParserCFGTest_FindIfSelectionInternalHeaders_FalseBranch_LoopContinue_Ok.spvasm.expected.hlsl
@@ -1,9 +1,10 @@
 SKIP: FAILED
 
-static uint var_1 = 0u;
 
-void main_1() {
-  while (true) {
+var<private> var_1 : u32;
+
+fn main_1() {
+  loop {
     if (false) {
     } else {
       continue;
@@ -12,15 +13,9 @@
   return;
 }
 
-void main() {
+[[stage(fragment)]]
+fn main() {
   main_1();
-  return;
 }
-warning: DXIL.dll not found.  Resulting DXIL will not be signed for use in release environments.
 
-error: validation errors
-tint_HrNFse:13: error: Loop must have break.
-Validation failed.
-
-
-
+error: loop does not exit
diff --git a/test/unittest/reader/spirv/SpvParserCFGTest_FindIfSelectionInternalHeaders_FalseBranch_LoopContinue_Ok.spvasm.expected.msl b/test/unittest/reader/spirv/SpvParserCFGTest_FindIfSelectionInternalHeaders_FalseBranch_LoopContinue_Ok.spvasm.expected.msl
new file mode 100644
index 0000000..b7ad7d3
--- /dev/null
+++ b/test/unittest/reader/spirv/SpvParserCFGTest_FindIfSelectionInternalHeaders_FalseBranch_LoopContinue_Ok.spvasm.expected.msl
@@ -0,0 +1,21 @@
+SKIP: FAILED
+
+
+var<private> var_1 : u32;
+
+fn main_1() {
+  loop {
+    if (false) {
+    } else {
+      continue;
+    }
+  }
+  return;
+}
+
+[[stage(fragment)]]
+fn main() {
+  main_1();
+}
+
+error: loop does not exit
diff --git a/test/unittest/reader/spirv/SpvParserCFGTest_FindIfSelectionInternalHeaders_FalseBranch_LoopContinue_Ok.spvasm.expected.spvasm b/test/unittest/reader/spirv/SpvParserCFGTest_FindIfSelectionInternalHeaders_FalseBranch_LoopContinue_Ok.spvasm.expected.spvasm
new file mode 100644
index 0000000..b7ad7d3
--- /dev/null
+++ b/test/unittest/reader/spirv/SpvParserCFGTest_FindIfSelectionInternalHeaders_FalseBranch_LoopContinue_Ok.spvasm.expected.spvasm
@@ -0,0 +1,21 @@
+SKIP: FAILED
+
+
+var<private> var_1 : u32;
+
+fn main_1() {
+  loop {
+    if (false) {
+    } else {
+      continue;
+    }
+  }
+  return;
+}
+
+[[stage(fragment)]]
+fn main() {
+  main_1();
+}
+
+error: loop does not exit
diff --git a/test/unittest/reader/spirv/SpvParserCFGTest_FindIfSelectionInternalHeaders_FalseBranch_LoopContinue_Ok.spvasm.expected.wgsl b/test/unittest/reader/spirv/SpvParserCFGTest_FindIfSelectionInternalHeaders_FalseBranch_LoopContinue_Ok.spvasm.expected.wgsl
new file mode 100644
index 0000000..b7ad7d3
--- /dev/null
+++ b/test/unittest/reader/spirv/SpvParserCFGTest_FindIfSelectionInternalHeaders_FalseBranch_LoopContinue_Ok.spvasm.expected.wgsl
@@ -0,0 +1,21 @@
+SKIP: FAILED
+
+
+var<private> var_1 : u32;
+
+fn main_1() {
+  loop {
+    if (false) {
+    } else {
+      continue;
+    }
+  }
+  return;
+}
+
+[[stage(fragment)]]
+fn main() {
+  main_1();
+}
+
+error: loop does not exit
diff --git a/test/unittest/reader/spirv/SpvParserCFGTest_FindIfSelectionInternalHeaders_TrueBranch_LoopBreak_Ok.spvasm.expected.hlsl b/test/unittest/reader/spirv/SpvParserCFGTest_FindIfSelectionInternalHeaders_TrueBranch_LoopBreak_Ok.spvasm.expected.hlsl
index a699918..b132482 100644
--- a/test/unittest/reader/spirv/SpvParserCFGTest_FindIfSelectionInternalHeaders_TrueBranch_LoopBreak_Ok.spvasm.expected.hlsl
+++ b/test/unittest/reader/spirv/SpvParserCFGTest_FindIfSelectionInternalHeaders_TrueBranch_LoopBreak_Ok.spvasm.expected.hlsl
@@ -3,7 +3,7 @@
 static uint var_1 = 0u;
 
 void main_1() {
-  while (true) {
+  [loop] while (true) {
     if (false) {
       break;
     }
@@ -18,7 +18,7 @@
 warning: DXIL.dll not found.  Resulting DXIL will not be signed for use in release environments.
 
 error: validation errors
-tint_dK0Vw9:12: error: Loop must have break.
+/tmp/tint_ABIRu4:12: error: Loop must have break.
 Validation failed.
 
 
diff --git a/test/unittest/reader/spirv/SpvParserCFGTest_FindIfSelectionInternalHeaders_TrueBranch_LoopContinue_Ok.spvasm.expected.hlsl b/test/unittest/reader/spirv/SpvParserCFGTest_FindIfSelectionInternalHeaders_TrueBranch_LoopContinue_Ok.spvasm.expected.hlsl
index a771aad..32e75fb 100644
--- a/test/unittest/reader/spirv/SpvParserCFGTest_FindIfSelectionInternalHeaders_TrueBranch_LoopContinue_Ok.spvasm.expected.hlsl
+++ b/test/unittest/reader/spirv/SpvParserCFGTest_FindIfSelectionInternalHeaders_TrueBranch_LoopContinue_Ok.spvasm.expected.hlsl
@@ -1,9 +1,10 @@
 SKIP: FAILED
 
-static uint var_1 = 0u;
 
-void main_1() {
-  while (true) {
+var<private> var_1 : u32;
+
+fn main_1() {
+  loop {
     if (false) {
       continue;
     }
@@ -11,15 +12,9 @@
   return;
 }
 
-void main() {
+[[stage(fragment)]]
+fn main() {
   main_1();
-  return;
 }
-warning: DXIL.dll not found.  Resulting DXIL will not be signed for use in release environments.
 
-error: validation errors
-tint_fz0Wqg:12: error: Loop must have break.
-Validation failed.
-
-
-
+error: loop does not exit
diff --git a/test/unittest/reader/spirv/SpvParserCFGTest_FindIfSelectionInternalHeaders_TrueBranch_LoopContinue_Ok.spvasm.expected.msl b/test/unittest/reader/spirv/SpvParserCFGTest_FindIfSelectionInternalHeaders_TrueBranch_LoopContinue_Ok.spvasm.expected.msl
new file mode 100644
index 0000000..32e75fb
--- /dev/null
+++ b/test/unittest/reader/spirv/SpvParserCFGTest_FindIfSelectionInternalHeaders_TrueBranch_LoopContinue_Ok.spvasm.expected.msl
@@ -0,0 +1,20 @@
+SKIP: FAILED
+
+
+var<private> var_1 : u32;
+
+fn main_1() {
+  loop {
+    if (false) {
+      continue;
+    }
+  }
+  return;
+}
+
+[[stage(fragment)]]
+fn main() {
+  main_1();
+}
+
+error: loop does not exit
diff --git a/test/unittest/reader/spirv/SpvParserCFGTest_FindIfSelectionInternalHeaders_TrueBranch_LoopContinue_Ok.spvasm.expected.spvasm b/test/unittest/reader/spirv/SpvParserCFGTest_FindIfSelectionInternalHeaders_TrueBranch_LoopContinue_Ok.spvasm.expected.spvasm
new file mode 100644
index 0000000..32e75fb
--- /dev/null
+++ b/test/unittest/reader/spirv/SpvParserCFGTest_FindIfSelectionInternalHeaders_TrueBranch_LoopContinue_Ok.spvasm.expected.spvasm
@@ -0,0 +1,20 @@
+SKIP: FAILED
+
+
+var<private> var_1 : u32;
+
+fn main_1() {
+  loop {
+    if (false) {
+      continue;
+    }
+  }
+  return;
+}
+
+[[stage(fragment)]]
+fn main() {
+  main_1();
+}
+
+error: loop does not exit
diff --git a/test/unittest/reader/spirv/SpvParserCFGTest_FindIfSelectionInternalHeaders_TrueBranch_LoopContinue_Ok.spvasm.expected.wgsl b/test/unittest/reader/spirv/SpvParserCFGTest_FindIfSelectionInternalHeaders_TrueBranch_LoopContinue_Ok.spvasm.expected.wgsl
new file mode 100644
index 0000000..32e75fb
--- /dev/null
+++ b/test/unittest/reader/spirv/SpvParserCFGTest_FindIfSelectionInternalHeaders_TrueBranch_LoopContinue_Ok.spvasm.expected.wgsl
@@ -0,0 +1,20 @@
+SKIP: FAILED
+
+
+var<private> var_1 : u32;
+
+fn main_1() {
+  loop {
+    if (false) {
+      continue;
+    }
+  }
+  return;
+}
+
+[[stage(fragment)]]
+fn main() {
+  main_1();
+}
+
+error: loop does not exit
diff --git a/test/unittest/reader/spirv/SpvParserCFGTest_LabelControlFlowConstructs_LoopInterallyDiverge.spvasm.expected.hlsl b/test/unittest/reader/spirv/SpvParserCFGTest_LabelControlFlowConstructs_LoopInterallyDiverge.spvasm.expected.hlsl
index c69a44d..32e75fb 100644
--- a/test/unittest/reader/spirv/SpvParserCFGTest_LabelControlFlowConstructs_LoopInterallyDiverge.spvasm.expected.hlsl
+++ b/test/unittest/reader/spirv/SpvParserCFGTest_LabelControlFlowConstructs_LoopInterallyDiverge.spvasm.expected.hlsl
@@ -1,9 +1,10 @@
 SKIP: FAILED
 
-static uint var_1 = 0u;
 
-void main_1() {
-  while (true) {
+var<private> var_1 : u32;
+
+fn main_1() {
+  loop {
     if (false) {
       continue;
     }
@@ -11,15 +12,9 @@
   return;
 }
 
-void main() {
+[[stage(fragment)]]
+fn main() {
   main_1();
-  return;
 }
-warning: DXIL.dll not found.  Resulting DXIL will not be signed for use in release environments.
 
-error: validation errors
-tint_B7oTsM:12: error: Loop must have break.
-Validation failed.
-
-
-
+error: loop does not exit
diff --git a/test/unittest/reader/spirv/SpvParserCFGTest_LabelControlFlowConstructs_LoopInterallyDiverge.spvasm.expected.msl b/test/unittest/reader/spirv/SpvParserCFGTest_LabelControlFlowConstructs_LoopInterallyDiverge.spvasm.expected.msl
new file mode 100644
index 0000000..32e75fb
--- /dev/null
+++ b/test/unittest/reader/spirv/SpvParserCFGTest_LabelControlFlowConstructs_LoopInterallyDiverge.spvasm.expected.msl
@@ -0,0 +1,20 @@
+SKIP: FAILED
+
+
+var<private> var_1 : u32;
+
+fn main_1() {
+  loop {
+    if (false) {
+      continue;
+    }
+  }
+  return;
+}
+
+[[stage(fragment)]]
+fn main() {
+  main_1();
+}
+
+error: loop does not exit
diff --git a/test/unittest/reader/spirv/SpvParserCFGTest_LabelControlFlowConstructs_LoopInterallyDiverge.spvasm.expected.spvasm b/test/unittest/reader/spirv/SpvParserCFGTest_LabelControlFlowConstructs_LoopInterallyDiverge.spvasm.expected.spvasm
new file mode 100644
index 0000000..32e75fb
--- /dev/null
+++ b/test/unittest/reader/spirv/SpvParserCFGTest_LabelControlFlowConstructs_LoopInterallyDiverge.spvasm.expected.spvasm
@@ -0,0 +1,20 @@
+SKIP: FAILED
+
+
+var<private> var_1 : u32;
+
+fn main_1() {
+  loop {
+    if (false) {
+      continue;
+    }
+  }
+  return;
+}
+
+[[stage(fragment)]]
+fn main() {
+  main_1();
+}
+
+error: loop does not exit
diff --git a/test/unittest/reader/spirv/SpvParserCFGTest_LabelControlFlowConstructs_LoopInterallyDiverge.spvasm.expected.wgsl b/test/unittest/reader/spirv/SpvParserCFGTest_LabelControlFlowConstructs_LoopInterallyDiverge.spvasm.expected.wgsl
new file mode 100644
index 0000000..32e75fb
--- /dev/null
+++ b/test/unittest/reader/spirv/SpvParserCFGTest_LabelControlFlowConstructs_LoopInterallyDiverge.spvasm.expected.wgsl
@@ -0,0 +1,20 @@
+SKIP: FAILED
+
+
+var<private> var_1 : u32;
+
+fn main_1() {
+  loop {
+    if (false) {
+      continue;
+    }
+  }
+  return;
+}
+
+[[stage(fragment)]]
+fn main() {
+  main_1();
+}
+
+error: loop does not exit
diff --git a/test/unittest/reader/spirv/SpvParserCFGTest_RegisterMerges_GoodLoopMerge_MultiBlockLoop_ContinueIsHeader.spvasm.expected.hlsl b/test/unittest/reader/spirv/SpvParserCFGTest_RegisterMerges_GoodLoopMerge_MultiBlockLoop_ContinueIsHeader.spvasm.expected.hlsl
index 1abf4b0..2d78e5b 100644
--- a/test/unittest/reader/spirv/SpvParserCFGTest_RegisterMerges_GoodLoopMerge_MultiBlockLoop_ContinueIsHeader.spvasm.expected.hlsl
+++ b/test/unittest/reader/spirv/SpvParserCFGTest_RegisterMerges_GoodLoopMerge_MultiBlockLoop_ContinueIsHeader.spvasm.expected.hlsl
@@ -1,22 +1,17 @@
 SKIP: FAILED
 
-static uint var_1 = 0u;
 
-void main_1() {
-  while (true) {
+var<private> var_1 : u32;
+
+fn main_1() {
+  loop {
   }
   return;
 }
 
-void main() {
+[[stage(fragment)]]
+fn main() {
   main_1();
-  return;
 }
-warning: DXIL.dll not found.  Resulting DXIL will not be signed for use in release environments.
 
-error: validation errors
-tint_8uV2qf:9: error: Loop must have break.
-Validation failed.
-
-
-
+error: loop does not exit
diff --git a/test/unittest/reader/spirv/SpvParserCFGTest_RegisterMerges_GoodLoopMerge_MultiBlockLoop_ContinueIsHeader.spvasm.expected.msl b/test/unittest/reader/spirv/SpvParserCFGTest_RegisterMerges_GoodLoopMerge_MultiBlockLoop_ContinueIsHeader.spvasm.expected.msl
new file mode 100644
index 0000000..2d78e5b
--- /dev/null
+++ b/test/unittest/reader/spirv/SpvParserCFGTest_RegisterMerges_GoodLoopMerge_MultiBlockLoop_ContinueIsHeader.spvasm.expected.msl
@@ -0,0 +1,17 @@
+SKIP: FAILED
+
+
+var<private> var_1 : u32;
+
+fn main_1() {
+  loop {
+  }
+  return;
+}
+
+[[stage(fragment)]]
+fn main() {
+  main_1();
+}
+
+error: loop does not exit
diff --git a/test/unittest/reader/spirv/SpvParserCFGTest_RegisterMerges_GoodLoopMerge_MultiBlockLoop_ContinueIsHeader.spvasm.expected.spvasm b/test/unittest/reader/spirv/SpvParserCFGTest_RegisterMerges_GoodLoopMerge_MultiBlockLoop_ContinueIsHeader.spvasm.expected.spvasm
new file mode 100644
index 0000000..2d78e5b
--- /dev/null
+++ b/test/unittest/reader/spirv/SpvParserCFGTest_RegisterMerges_GoodLoopMerge_MultiBlockLoop_ContinueIsHeader.spvasm.expected.spvasm
@@ -0,0 +1,17 @@
+SKIP: FAILED
+
+
+var<private> var_1 : u32;
+
+fn main_1() {
+  loop {
+  }
+  return;
+}
+
+[[stage(fragment)]]
+fn main() {
+  main_1();
+}
+
+error: loop does not exit
diff --git a/test/unittest/reader/spirv/SpvParserCFGTest_RegisterMerges_GoodLoopMerge_MultiBlockLoop_ContinueIsHeader.spvasm.expected.wgsl b/test/unittest/reader/spirv/SpvParserCFGTest_RegisterMerges_GoodLoopMerge_MultiBlockLoop_ContinueIsHeader.spvasm.expected.wgsl
new file mode 100644
index 0000000..2d78e5b
--- /dev/null
+++ b/test/unittest/reader/spirv/SpvParserCFGTest_RegisterMerges_GoodLoopMerge_MultiBlockLoop_ContinueIsHeader.spvasm.expected.wgsl
@@ -0,0 +1,17 @@
+SKIP: FAILED
+
+
+var<private> var_1 : u32;
+
+fn main_1() {
+  loop {
+  }
+  return;
+}
+
+[[stage(fragment)]]
+fn main() {
+  main_1();
+}
+
+error: loop does not exit
diff --git a/test/unittest/reader/spirv/SpvParserFunctionVarTest_EmitStatement_CombinatorialNonPointer_DefConstruct_DoesNotEncloseAllUses.spvasm.expected.hlsl b/test/unittest/reader/spirv/SpvParserFunctionVarTest_EmitStatement_CombinatorialNonPointer_DefConstruct_DoesNotEncloseAllUses.spvasm.expected.hlsl
index bb84b44..4818f55 100644
--- a/test/unittest/reader/spirv/SpvParserFunctionVarTest_EmitStatement_CombinatorialNonPointer_DefConstruct_DoesNotEncloseAllUses.spvasm.expected.hlsl
+++ b/test/unittest/reader/spirv/SpvParserFunctionVarTest_EmitStatement_CombinatorialNonPointer_DefConstruct_DoesNotEncloseAllUses.spvasm.expected.hlsl
@@ -4,7 +4,7 @@
 
 void main_1() {
   x_1 = 0u;
-  while (true) {
+  [loop] while (true) {
     uint x_2 = 0u;
     x_1 = 1u;
     if (false) {
@@ -35,7 +35,7 @@
 warning: DXIL.dll not found.  Resulting DXIL will not be signed for use in release environments.
 
 error: validation errors
-tint_9DZjPt:29: error: Loop must have break.
+/tmp/tint_LpDCMy:29: error: Loop must have break.
 Validation failed.
 
 
diff --git a/test/unittest/reader/spirv/SpvParserFunctionVarTest_EmitStatement_CombinatorialValue_Immediate_UsedOnceDifferentConstruct.spvasm.expected.hlsl b/test/unittest/reader/spirv/SpvParserFunctionVarTest_EmitStatement_CombinatorialValue_Immediate_UsedOnceDifferentConstruct.spvasm.expected.hlsl
index ee868d4..016ae84 100644
--- a/test/unittest/reader/spirv/SpvParserFunctionVarTest_EmitStatement_CombinatorialValue_Immediate_UsedOnceDifferentConstruct.spvasm.expected.hlsl
+++ b/test/unittest/reader/spirv/SpvParserFunctionVarTest_EmitStatement_CombinatorialValue_Immediate_UsedOnceDifferentConstruct.spvasm.expected.hlsl
@@ -1,11 +1,19 @@
 SKIP: FAILED
 
-void main_1() {
-  uint x_25 = 0u;
-  const uint x_2 = (1u + 1u);
+
+struct S {
+  field0 : u32;
+  field1 : f32;
+  field2 : array<u32, 2u>;
+};
+
+fn main_1() {
+  var x_25 : u32;
+  let x_2 : u32 = (1u + 1u);
   x_25 = 1u;
-  while (true) {
-    {
+  loop {
+
+    continuing {
       x_25 = x_2;
     }
   }
@@ -13,15 +21,9 @@
   return;
 }
 
-void main() {
+[[stage(fragment)]]
+fn main() {
   main_1();
-  return;
 }
-warning: DXIL.dll not found.  Resulting DXIL will not be signed for use in release environments.
 
-error: validation errors
-tint_yj82Xu:14: error: Loop must have break.
-Validation failed.
-
-
-
+error: loop does not exit
diff --git a/test/unittest/reader/spirv/SpvParserFunctionVarTest_EmitStatement_CombinatorialValue_Immediate_UsedOnceDifferentConstruct.spvasm.expected.msl b/test/unittest/reader/spirv/SpvParserFunctionVarTest_EmitStatement_CombinatorialValue_Immediate_UsedOnceDifferentConstruct.spvasm.expected.msl
new file mode 100644
index 0000000..016ae84
--- /dev/null
+++ b/test/unittest/reader/spirv/SpvParserFunctionVarTest_EmitStatement_CombinatorialValue_Immediate_UsedOnceDifferentConstruct.spvasm.expected.msl
@@ -0,0 +1,29 @@
+SKIP: FAILED
+
+
+struct S {
+  field0 : u32;
+  field1 : f32;
+  field2 : array<u32, 2u>;
+};
+
+fn main_1() {
+  var x_25 : u32;
+  let x_2 : u32 = (1u + 1u);
+  x_25 = 1u;
+  loop {
+
+    continuing {
+      x_25 = x_2;
+    }
+  }
+  x_25 = 2u;
+  return;
+}
+
+[[stage(fragment)]]
+fn main() {
+  main_1();
+}
+
+error: loop does not exit
diff --git a/test/unittest/reader/spirv/SpvParserFunctionVarTest_EmitStatement_CombinatorialValue_Immediate_UsedOnceDifferentConstruct.spvasm.expected.spvasm b/test/unittest/reader/spirv/SpvParserFunctionVarTest_EmitStatement_CombinatorialValue_Immediate_UsedOnceDifferentConstruct.spvasm.expected.spvasm
new file mode 100644
index 0000000..016ae84
--- /dev/null
+++ b/test/unittest/reader/spirv/SpvParserFunctionVarTest_EmitStatement_CombinatorialValue_Immediate_UsedOnceDifferentConstruct.spvasm.expected.spvasm
@@ -0,0 +1,29 @@
+SKIP: FAILED
+
+
+struct S {
+  field0 : u32;
+  field1 : f32;
+  field2 : array<u32, 2u>;
+};
+
+fn main_1() {
+  var x_25 : u32;
+  let x_2 : u32 = (1u + 1u);
+  x_25 = 1u;
+  loop {
+
+    continuing {
+      x_25 = x_2;
+    }
+  }
+  x_25 = 2u;
+  return;
+}
+
+[[stage(fragment)]]
+fn main() {
+  main_1();
+}
+
+error: loop does not exit
diff --git a/test/unittest/reader/spirv/SpvParserFunctionVarTest_EmitStatement_CombinatorialValue_Immediate_UsedOnceDifferentConstruct.spvasm.expected.wgsl b/test/unittest/reader/spirv/SpvParserFunctionVarTest_EmitStatement_CombinatorialValue_Immediate_UsedOnceDifferentConstruct.spvasm.expected.wgsl
new file mode 100644
index 0000000..016ae84
--- /dev/null
+++ b/test/unittest/reader/spirv/SpvParserFunctionVarTest_EmitStatement_CombinatorialValue_Immediate_UsedOnceDifferentConstruct.spvasm.expected.wgsl
@@ -0,0 +1,29 @@
+SKIP: FAILED
+
+
+struct S {
+  field0 : u32;
+  field1 : f32;
+  field2 : array<u32, 2u>;
+};
+
+fn main_1() {
+  var x_25 : u32;
+  let x_2 : u32 = (1u + 1u);
+  x_25 = 1u;
+  loop {
+
+    continuing {
+      x_25 = x_2;
+    }
+  }
+  x_25 = 2u;
+  return;
+}
+
+[[stage(fragment)]]
+fn main() {
+  main_1();
+}
+
+error: loop does not exit
diff --git a/test/unittest/reader/spirv/SpvParserFunctionVarTest_EmitStatement_Phi_FromElseAndThen.spvasm.expected.hlsl b/test/unittest/reader/spirv/SpvParserFunctionVarTest_EmitStatement_Phi_FromElseAndThen.spvasm.expected.hlsl
index 95210b7..ef00dd5 100644
--- a/test/unittest/reader/spirv/SpvParserFunctionVarTest_EmitStatement_Phi_FromElseAndThen.spvasm.expected.hlsl
+++ b/test/unittest/reader/spirv/SpvParserFunctionVarTest_EmitStatement_Phi_FromElseAndThen.spvasm.expected.hlsl
@@ -1,5 +1,6 @@
 SKIP: FAILED
 
+warning: code is unreachable
 static uint x_1 = 0u;
 static bool x_7 = false;
 static bool x_8 = false;
@@ -7,7 +8,7 @@
 void main_1() {
   const bool x_101 = x_7;
   const bool x_102 = x_8;
-  while (true) {
+  [loop] while (true) {
     uint x_2_phi = 0u;
     if (x_101) {
       break;
@@ -40,7 +41,7 @@
 warning: DXIL.dll not found.  Resulting DXIL will not be signed for use in release environments.
 
 error: validation errors
-tint_GXPsdi:34: error: Loop must have break.
+/tmp/tint_l2mEof:34: error: Loop must have break.
 Validation failed.
 
 
diff --git a/test/unittest/reader/spirv/SpvParserFunctionVarTest_EmitStatement_Phi_FromHeaderAndThen.spvasm.expected.hlsl b/test/unittest/reader/spirv/SpvParserFunctionVarTest_EmitStatement_Phi_FromHeaderAndThen.spvasm.expected.hlsl
index 2116f83..671644c 100644
--- a/test/unittest/reader/spirv/SpvParserFunctionVarTest_EmitStatement_Phi_FromHeaderAndThen.spvasm.expected.hlsl
+++ b/test/unittest/reader/spirv/SpvParserFunctionVarTest_EmitStatement_Phi_FromHeaderAndThen.spvasm.expected.hlsl
@@ -1,5 +1,6 @@
 SKIP: FAILED
 
+warning: code is unreachable
 static uint x_1 = 0u;
 static bool x_7 = false;
 static bool x_8 = false;
@@ -7,7 +8,7 @@
 void main_1() {
   const bool x_101 = x_7;
   const bool x_102 = x_8;
-  while (true) {
+  [loop] while (true) {
     uint x_2_phi = 0u;
     if (x_101) {
       break;
@@ -40,7 +41,7 @@
 warning: DXIL.dll not found.  Resulting DXIL will not be signed for use in release environments.
 
 error: validation errors
-tint_N12ZXm:34: error: Loop must have break.
+/tmp/tint_nu4hkX:34: error: Loop must have break.
 Validation failed.
 
 
diff --git a/test/unittest/reader/spirv/SpvParserFunctionVarTest_EmitStatement_Phi_MultiBlockLoopIndex.spvasm.expected.hlsl b/test/unittest/reader/spirv/SpvParserFunctionVarTest_EmitStatement_Phi_MultiBlockLoopIndex.spvasm.expected.hlsl
index aa3d19b..e80132c 100644
--- a/test/unittest/reader/spirv/SpvParserFunctionVarTest_EmitStatement_Phi_MultiBlockLoopIndex.spvasm.expected.hlsl
+++ b/test/unittest/reader/spirv/SpvParserFunctionVarTest_EmitStatement_Phi_MultiBlockLoopIndex.spvasm.expected.hlsl
@@ -5,7 +5,7 @@
 static bool x_8 = false;
 
 void main_1() {
-  while (true) {
+  [loop] while (true) {
     uint x_2_phi = 0u;
     uint x_3_phi = 0u;
     const bool x_101 = x_7;
@@ -15,7 +15,7 @@
     if (x_101) {
       break;
     }
-    while (true) {
+    [loop] while (true) {
       uint x_4 = 0u;
       const uint x_2 = x_2_phi;
       const uint x_3 = x_3_phi;
@@ -39,7 +39,7 @@
 warning: DXIL.dll not found.  Resulting DXIL will not be signed for use in release environments.
 
 error: validation errors
-tint_eXjRIC:33: error: Loop must have break.
+/tmp/tint_zJdet0:33: error: Loop must have break.
 Validation failed.
 
 
diff --git a/test/unittest/reader/spirv/SpvParserFunctionVarTest_EmitStatement_Phi_SingleBlockLoopIndex.spvasm.expected.hlsl b/test/unittest/reader/spirv/SpvParserFunctionVarTest_EmitStatement_Phi_SingleBlockLoopIndex.spvasm.expected.hlsl
index 179199a..277b39f 100644
--- a/test/unittest/reader/spirv/SpvParserFunctionVarTest_EmitStatement_Phi_SingleBlockLoopIndex.spvasm.expected.hlsl
+++ b/test/unittest/reader/spirv/SpvParserFunctionVarTest_EmitStatement_Phi_SingleBlockLoopIndex.spvasm.expected.hlsl
@@ -5,7 +5,7 @@
 static bool x_8 = false;
 
 void main_1() {
-  while (true) {
+  [loop] while (true) {
     uint x_2_phi = 0u;
     uint x_3_phi = 0u;
     const bool x_101 = x_7;
@@ -15,7 +15,7 @@
     if (x_101) {
       break;
     }
-    while (true) {
+    [loop] while (true) {
       const uint x_3 = x_3_phi;
       x_2_phi = (x_2_phi + 1u);
       x_3_phi = x_3;
@@ -34,7 +34,7 @@
 warning: DXIL.dll not found.  Resulting DXIL will not be signed for use in release environments.
 
 error: validation errors
-tint_26i6xo:28: error: Loop must have break.
+/tmp/tint_XDVFVA:28: error: Loop must have break.
 Validation failed.
 
 
diff --git a/test/unittest/reader/spirv/SpvParserFunctionVarTest_EmitStatement_Phi_ValueFromLoopBodyAndContinuing.spvasm.expected.hlsl b/test/unittest/reader/spirv/SpvParserFunctionVarTest_EmitStatement_Phi_ValueFromLoopBodyAndContinuing.spvasm.expected.hlsl
index 1caa2f1..f9ae993 100644
--- a/test/unittest/reader/spirv/SpvParserFunctionVarTest_EmitStatement_Phi_ValueFromLoopBodyAndContinuing.spvasm.expected.hlsl
+++ b/test/unittest/reader/spirv/SpvParserFunctionVarTest_EmitStatement_Phi_ValueFromLoopBodyAndContinuing.spvasm.expected.hlsl
@@ -1,24 +1,34 @@
 SKIP: FAILED
 
-static uint x_1 = 0u;
-static bool x_17 = false;
 
-void main_1() {
-  const bool x_101 = x_17;
-  while (true) {
-    uint x_2_phi = 0u;
-    uint x_5_phi = 0u;
+struct S {
+  field0 : u32;
+  field1 : f32;
+  field2 : array<u32, 2u>;
+};
+
+var<private> x_1 : u32;
+
+var<private> x_17 : bool;
+
+fn main_1() {
+  let x_101 : bool = x_17;
+  loop {
+    var x_2_phi : u32;
+    var x_5_phi : u32;
     x_2_phi = 0u;
     x_5_phi = 1u;
-    while (true) {
-      uint x_7 = 0u;
-      const uint x_5 = x_5_phi;
-      const uint x_4 = (x_2_phi + 1u);
-      const uint x_6 = (x_4 + 1u);
+    loop {
+      var x_7 : u32;
+      let x_2 : u32 = x_2_phi;
+      let x_5 : u32 = x_5_phi;
+      let x_4 : u32 = (x_2 + 1u);
+      let x_6 : u32 = (x_4 + 1u);
       if (x_101) {
         break;
       }
-      {
+
+      continuing {
         x_7 = (x_4 + x_6);
         x_2_phi = x_4;
         x_5_phi = x_7;
@@ -28,15 +38,9 @@
   return;
 }
 
-void main() {
+[[stage(fragment)]]
+fn main() {
   main_1();
-  return;
 }
-warning: DXIL.dll not found.  Resulting DXIL will not be signed for use in release environments.
 
-error: validation errors
-tint_AU073z:29: error: Loop must have break.
-Validation failed.
-
-
-
+error: loop does not exit
diff --git a/test/unittest/reader/spirv/SpvParserFunctionVarTest_EmitStatement_Phi_ValueFromLoopBodyAndContinuing.spvasm.expected.msl b/test/unittest/reader/spirv/SpvParserFunctionVarTest_EmitStatement_Phi_ValueFromLoopBodyAndContinuing.spvasm.expected.msl
new file mode 100644
index 0000000..f9ae993
--- /dev/null
+++ b/test/unittest/reader/spirv/SpvParserFunctionVarTest_EmitStatement_Phi_ValueFromLoopBodyAndContinuing.spvasm.expected.msl
@@ -0,0 +1,46 @@
+SKIP: FAILED
+
+
+struct S {
+  field0 : u32;
+  field1 : f32;
+  field2 : array<u32, 2u>;
+};
+
+var<private> x_1 : u32;
+
+var<private> x_17 : bool;
+
+fn main_1() {
+  let x_101 : bool = x_17;
+  loop {
+    var x_2_phi : u32;
+    var x_5_phi : u32;
+    x_2_phi = 0u;
+    x_5_phi = 1u;
+    loop {
+      var x_7 : u32;
+      let x_2 : u32 = x_2_phi;
+      let x_5 : u32 = x_5_phi;
+      let x_4 : u32 = (x_2 + 1u);
+      let x_6 : u32 = (x_4 + 1u);
+      if (x_101) {
+        break;
+      }
+
+      continuing {
+        x_7 = (x_4 + x_6);
+        x_2_phi = x_4;
+        x_5_phi = x_7;
+      }
+    }
+  }
+  return;
+}
+
+[[stage(fragment)]]
+fn main() {
+  main_1();
+}
+
+error: loop does not exit
diff --git a/test/unittest/reader/spirv/SpvParserFunctionVarTest_EmitStatement_Phi_ValueFromLoopBodyAndContinuing.spvasm.expected.spvasm b/test/unittest/reader/spirv/SpvParserFunctionVarTest_EmitStatement_Phi_ValueFromLoopBodyAndContinuing.spvasm.expected.spvasm
new file mode 100644
index 0000000..f9ae993
--- /dev/null
+++ b/test/unittest/reader/spirv/SpvParserFunctionVarTest_EmitStatement_Phi_ValueFromLoopBodyAndContinuing.spvasm.expected.spvasm
@@ -0,0 +1,46 @@
+SKIP: FAILED
+
+
+struct S {
+  field0 : u32;
+  field1 : f32;
+  field2 : array<u32, 2u>;
+};
+
+var<private> x_1 : u32;
+
+var<private> x_17 : bool;
+
+fn main_1() {
+  let x_101 : bool = x_17;
+  loop {
+    var x_2_phi : u32;
+    var x_5_phi : u32;
+    x_2_phi = 0u;
+    x_5_phi = 1u;
+    loop {
+      var x_7 : u32;
+      let x_2 : u32 = x_2_phi;
+      let x_5 : u32 = x_5_phi;
+      let x_4 : u32 = (x_2 + 1u);
+      let x_6 : u32 = (x_4 + 1u);
+      if (x_101) {
+        break;
+      }
+
+      continuing {
+        x_7 = (x_4 + x_6);
+        x_2_phi = x_4;
+        x_5_phi = x_7;
+      }
+    }
+  }
+  return;
+}
+
+[[stage(fragment)]]
+fn main() {
+  main_1();
+}
+
+error: loop does not exit
diff --git a/test/unittest/reader/spirv/SpvParserFunctionVarTest_EmitStatement_Phi_ValueFromLoopBodyAndContinuing.spvasm.expected.wgsl b/test/unittest/reader/spirv/SpvParserFunctionVarTest_EmitStatement_Phi_ValueFromLoopBodyAndContinuing.spvasm.expected.wgsl
new file mode 100644
index 0000000..f9ae993
--- /dev/null
+++ b/test/unittest/reader/spirv/SpvParserFunctionVarTest_EmitStatement_Phi_ValueFromLoopBodyAndContinuing.spvasm.expected.wgsl
@@ -0,0 +1,46 @@
+SKIP: FAILED
+
+
+struct S {
+  field0 : u32;
+  field1 : f32;
+  field2 : array<u32, 2u>;
+};
+
+var<private> x_1 : u32;
+
+var<private> x_17 : bool;
+
+fn main_1() {
+  let x_101 : bool = x_17;
+  loop {
+    var x_2_phi : u32;
+    var x_5_phi : u32;
+    x_2_phi = 0u;
+    x_5_phi = 1u;
+    loop {
+      var x_7 : u32;
+      let x_2 : u32 = x_2_phi;
+      let x_5 : u32 = x_5_phi;
+      let x_4 : u32 = (x_2 + 1u);
+      let x_6 : u32 = (x_4 + 1u);
+      if (x_101) {
+        break;
+      }
+
+      continuing {
+        x_7 = (x_4 + x_6);
+        x_2_phi = x_4;
+        x_5_phi = x_7;
+      }
+    }
+  }
+  return;
+}
+
+[[stage(fragment)]]
+fn main() {
+  main_1();
+}
+
+error: loop does not exit
diff --git a/test/unittest/reader/spirv/SpvParserTest_VectorExtractDynamic_UnsignedIndex.spvasm.expected.hlsl b/test/unittest/reader/spirv/SpvParserTest_VectorExtractDynamic_UnsignedIndex.spvasm.expected.hlsl
index 3f12005..e6de520 100644
--- a/test/unittest/reader/spirv/SpvParserTest_VectorExtractDynamic_UnsignedIndex.spvasm.expected.hlsl
+++ b/test/unittest/reader/spirv/SpvParserTest_VectorExtractDynamic_UnsignedIndex.spvasm.expected.hlsl
@@ -2,7 +2,7 @@
 
 void main_1() {
   const uint2 x_1 = uint2(3u, 4u);
-  const uint x_10 = x_1[3u];
+  const uint x_10 = x_1[1u];
   return;
 }
 
@@ -11,8 +11,3 @@
   main_1();
   return;
 }
-tint_kzPJNg:3:25: error: vector element index '3' is out of bounds
-  const uint x_10 = x_1[3u];
-                        ^
-
-
diff --git a/test/unittest/reader/spirv/SpvUnaryConversionTest_ConvertFToU_HoistedValue.spvasm.expected.hlsl b/test/unittest/reader/spirv/SpvUnaryConversionTest_ConvertFToU_HoistedValue.spvasm.expected.hlsl
index e0c029f..e327721 100644
--- a/test/unittest/reader/spirv/SpvUnaryConversionTest_ConvertFToU_HoistedValue.spvasm.expected.hlsl
+++ b/test/unittest/reader/spirv/SpvUnaryConversionTest_ConvertFToU_HoistedValue.spvasm.expected.hlsl
@@ -1,7 +1,7 @@
 SKIP: FAILED
 
 void main_1() {
-  while (true) {
+  [loop] while (true) {
     float x_600 = 0.0f;
     if (true) {
       break;
diff --git a/test/vk-gl-cts/graphicsfuzz/color-set-in-for-loop/0-opt.spvasm b/test/vk-gl-cts/graphicsfuzz/color-set-in-for-loop/0-opt.spvasm
deleted file mode 100644
index 79f78a2..0000000
--- a/test/vk-gl-cts/graphicsfuzz/color-set-in-for-loop/0-opt.spvasm
+++ /dev/null
@@ -1,62 +0,0 @@
-               OpCapability Shader
-          %1 = OpExtInstImport "GLSL.std.450"
-               OpMemoryModel Logical GLSL450
-               OpEntryPoint Fragment %main "main" %_GLF_color
-               OpExecutionMode %main OriginUpperLeft
-               OpSource ESSL 310
-               OpName %main "main"
-               OpName %buf0 "buf0"
-               OpMemberName %buf0 0 "injectionSwitch"
-               OpName %_ ""
-               OpName %_GLF_color "_GLF_color"
-               OpMemberDecorate %buf0 0 Offset 0
-               OpDecorate %buf0 Block
-               OpDecorate %_ DescriptorSet 0
-               OpDecorate %_ Binding 0
-               OpDecorate %_GLF_color Location 0
-       %void = OpTypeVoid
-          %7 = OpTypeFunction %void
-      %float = OpTypeFloat 32
-    %v2float = OpTypeVector %float 2
-       %buf0 = OpTypeStruct %v2float
-%_ptr_Uniform_buf0 = OpTypePointer Uniform %buf0
-          %_ = OpVariable %_ptr_Uniform_buf0 Uniform
-        %int = OpTypeInt 32 1
-      %int_0 = OpConstant %int 0
-       %uint = OpTypeInt 32 0
-     %uint_0 = OpConstant %uint 0
-%_ptr_Uniform_float = OpTypePointer Uniform %float
-    %float_1 = OpConstant %float 1
-       %bool = OpTypeBool
-       %true = OpConstantTrue %bool
-    %v4float = OpTypeVector %float 4
-%_ptr_Output_v4float = OpTypePointer Output %v4float
- %_GLF_color = OpVariable %_ptr_Output_v4float Output
-    %float_0 = OpConstant %float 0
-         %22 = OpConstantComposite %v4float %float_0 %float_0 %float_0 %float_1
-         %23 = OpConstantComposite %v4float %float_1 %float_0 %float_0 %float_1
-       %main = OpFunction %void None %7
-         %24 = OpLabel
-         %25 = OpAccessChain %_ptr_Uniform_float %_ %int_0 %uint_0
-         %26 = OpLoad %float %25
-         %27 = OpFOrdGreaterThan %bool %26 %float_1
-               OpSelectionMerge %28 None
-               OpBranchConditional %27 %29 %28
-         %29 = OpLabel
-               OpBranch %30
-         %30 = OpLabel
-               OpLoopMerge %31 %32 None
-               OpBranch %33
-         %33 = OpLabel
-               OpBranch %34
-         %34 = OpLabel
-               OpStore %_GLF_color %22
-               OpBranch %32
-         %32 = OpLabel
-               OpBranch %30
-         %31 = OpLabel
-               OpUnreachable
-         %28 = OpLabel
-               OpStore %_GLF_color %23
-               OpReturn
-               OpFunctionEnd
diff --git a/test/vk-gl-cts/graphicsfuzz/color-set-in-for-loop/0-opt.spvasm.expected.hlsl b/test/vk-gl-cts/graphicsfuzz/color-set-in-for-loop/0-opt.spvasm.expected.hlsl
deleted file mode 100755
index 9de3ba3..0000000
--- a/test/vk-gl-cts/graphicsfuzz/color-set-in-for-loop/0-opt.spvasm.expected.hlsl
+++ /dev/null
Binary files differ
diff --git a/test/vk-gl-cts/graphicsfuzz/color-set-in-for-loop/0-opt.wgsl b/test/vk-gl-cts/graphicsfuzz/color-set-in-for-loop/0-opt.wgsl
index 72afddb..520dccb 100644
--- a/test/vk-gl-cts/graphicsfuzz/color-set-in-for-loop/0-opt.wgsl
+++ b/test/vk-gl-cts/graphicsfuzz/color-set-in-for-loop/0-opt.wgsl
@@ -11,6 +11,7 @@
   if ((x_26 > 1.0)) {
     loop {
       x_GLF_color = vec4<f32>(0.0, 0.0, 0.0, 1.0);
+      break;
     }
     return;
   }
diff --git a/test/vk-gl-cts/graphicsfuzz/struct-and-unreachable-infinite-loop/0.spvasm b/test/vk-gl-cts/graphicsfuzz/struct-and-unreachable-infinite-loop/0.spvasm
deleted file mode 100644
index cca8b7a..0000000
--- a/test/vk-gl-cts/graphicsfuzz/struct-and-unreachable-infinite-loop/0.spvasm
+++ /dev/null
@@ -1,89 +0,0 @@
-               OpCapability Shader
-          %1 = OpExtInstImport "GLSL.std.450"
-               OpMemoryModel Logical GLSL450
-               OpEntryPoint Fragment %main "main" %_GLF_color
-               OpExecutionMode %main OriginUpperLeft
-               OpSource ESSL 310
-               OpName %main "main"
-               OpName %BST "BST"
-               OpMemberName %BST 0 "data"
-               OpMemberName %BST 1 "leftIndex"
-               OpMemberName %BST 2 "rightIndex"
-               OpName %makeTreeNode_struct_BST_i1_i1_i11_ "makeTreeNode(struct-BST-i1-i1-i11;"
-               OpName %tree "tree"
-               OpName %tree_0 "tree"
-               OpName %param "param"
-               OpName %_GLF_color "_GLF_color"
-               OpMemberDecorate %BST 0 RelaxedPrecision
-               OpMemberDecorate %BST 1 RelaxedPrecision
-               OpMemberDecorate %BST 2 RelaxedPrecision
-               OpDecorate %9 RelaxedPrecision
-               OpDecorate %_GLF_color Location 0
-               OpDecorate %10 RelaxedPrecision
-               OpDecorate %11 RelaxedPrecision
-               OpDecorate %12 RelaxedPrecision
-       %void = OpTypeVoid
-         %14 = OpTypeFunction %void
-        %int = OpTypeInt 32 1
-        %BST = OpTypeStruct %int %int %int
-%_ptr_Function_BST = OpTypePointer Function %BST
-         %17 = OpTypeFunction %void %_ptr_Function_BST
-      %int_2 = OpConstant %int 2
-      %int_1 = OpConstant %int 1
-%_ptr_Function_int = OpTypePointer Function %int
-       %uint = OpTypeInt 32 0
-    %uint_10 = OpConstant %uint 10
-%_arr_BST_uint_10 = OpTypeArray %BST %uint_10
-%_ptr_Private__arr_BST_uint_10 = OpTypePointer Private %_arr_BST_uint_10
-      %int_0 = OpConstant %int 0
-%_ptr_Private_BST = OpTypePointer Private %BST
-%_ptr_Private_int = OpTypePointer Private %int
-       %bool = OpTypeBool
-       %true = OpConstantTrue %bool
-      %float = OpTypeFloat 32
-    %v4float = OpTypeVector %float 4
-%_ptr_Output_v4float = OpTypePointer Output %v4float
- %_GLF_color = OpVariable %_ptr_Output_v4float Output
-    %float_0 = OpConstant %float 0
-    %float_1 = OpConstant %float 1
-%_ptr_Function__arr_BST_uint_10 = OpTypePointer Function %_arr_BST_uint_10
-       %main = OpFunction %void None %14
-         %36 = OpLabel
-     %tree_0 = OpVariable %_ptr_Function__arr_BST_uint_10 Function
-      %param = OpVariable %_ptr_Function_BST Function
-         %37 = OpLoad %_arr_BST_uint_10 %tree_0
-         %38 = OpCompositeExtract %BST %37 0
-               OpStore %param %38
-         %39 = OpFunctionCall %void %makeTreeNode_struct_BST_i1_i1_i11_ %param
-         %40 = OpLoad %BST %param
-         %41 = OpLoad %_arr_BST_uint_10 %tree_0
-         %42 = OpCompositeInsert %_arr_BST_uint_10 %40 %41 0
-               OpStore %tree_0 %42
-         %43 = OpAccessChain %_ptr_Function_int %tree_0 %int_0 %int_2
-         %11 = OpLoad %_arr_BST_uint_10 %tree_0
-          %9 = OpCompositeExtract %int %11 0 2
-         %44 = OpIEqual %bool %9 %int_0
-               OpSelectionMerge %45 None
-               OpBranchConditional %44 %46 %45
-         %46 = OpLabel
-               OpBranch %47
-         %47 = OpLabel
-               OpLoopMerge %48 %47 None
-               OpBranch %47
-         %48 = OpLabel
-               OpUnreachable
-         %45 = OpLabel
-         %12 = OpLoad %_arr_BST_uint_10 %tree_0
-         %10 = OpCompositeExtract %int %12 0 2
-         %49 = OpConvertSToF %float %10
-         %50 = OpCompositeConstruct %v4float %49 %float_0 %float_0 %float_1
-               OpStore %_GLF_color %50
-               OpReturn
-               OpFunctionEnd
-%makeTreeNode_struct_BST_i1_i1_i11_ = OpFunction %void None %17
-       %tree = OpFunctionParameter %_ptr_Function_BST
-         %51 = OpLabel
-         %52 = OpAccessChain %_ptr_Function_int %tree %int_2
-               OpStore %52 %int_1
-               OpReturn
-               OpFunctionEnd
diff --git a/test/vk-gl-cts/graphicsfuzz/struct-and-unreachable-infinite-loop/0.wgsl b/test/vk-gl-cts/graphicsfuzz/struct-and-unreachable-infinite-loop/0.wgsl
deleted file mode 100644
index 974581d..0000000
--- a/test/vk-gl-cts/graphicsfuzz/struct-and-unreachable-infinite-loop/0.wgsl
+++ /dev/null
@@ -1,47 +0,0 @@
-struct BST {
-  data : i32;
-  leftIndex : i32;
-  rightIndex : i32;
-};
-
-var<private> x_GLF_color : vec4<f32>;
-
-fn makeTreeNode_struct_BST_i1_i1_i11_(tree : ptr<function, BST>) {
-  (*(tree)).rightIndex = 1;
-  return;
-}
-
-fn main_1() {
-  var tree_1 : array<BST, 10>;
-  var param : BST;
-  let x_37 : array<BST, 10> = tree_1;
-  param = x_37[0u];
-  makeTreeNode_struct_BST_i1_i1_i11_(&(param));
-  let x_40 : BST = param;
-  let x_41 : array<BST, 10> = tree_1;
-  var x_42_1 : array<BST, 10> = x_41;
-  x_42_1[0u] = x_40;
-  let x_42 : array<BST, 10> = x_42_1;
-  tree_1 = x_42;
-  let x_43 : ptr<function, i32> = &(tree_1[0].rightIndex);
-  let x_11 : array<BST, 10> = tree_1;
-  if ((x_11[0u].rightIndex == 0)) {
-    loop {
-    }
-    return;
-  }
-  let x_12 : array<BST, 10> = tree_1;
-  x_GLF_color = vec4<f32>(f32(x_12[0u].rightIndex), 0.0, 0.0, 1.0);
-  return;
-}
-
-struct main_out {
-  [[location(0)]]
-  x_GLF_color_1 : vec4<f32>;
-};
-
-[[stage(fragment)]]
-fn main() -> main_out {
-  main_1();
-  return main_out(x_GLF_color);
-}
diff --git a/test/vk-gl-cts/graphicsfuzz/unreachable-loops-in-switch/0.spvasm b/test/vk-gl-cts/graphicsfuzz/unreachable-loops-in-switch/0.spvasm
deleted file mode 100644
index 5791da8..0000000
--- a/test/vk-gl-cts/graphicsfuzz/unreachable-loops-in-switch/0.spvasm
+++ /dev/null
@@ -1,116 +0,0 @@
-               OpCapability Shader
-          %1 = OpExtInstImport "GLSL.std.450"
-               OpMemoryModel Logical GLSL450
-               OpEntryPoint Fragment %main "main" %_GLF_color
-               OpExecutionMode %main OriginUpperLeft
-               OpSource ESSL 310
-               OpName %main "main"
-               OpName %_GLF_color "_GLF_color"
-               OpName %i "i"
-               OpName %data "data"
-               OpDecorate %_GLF_color Location 0
-               OpDecorate %i RelaxedPrecision
-               OpDecorate %6 RelaxedPrecision
-               OpDecorate %7 RelaxedPrecision
-               OpDecorate %8 RelaxedPrecision
-               OpDecorate %9 RelaxedPrecision
-               OpDecorate %10 RelaxedPrecision
-       %void = OpTypeVoid
-         %12 = OpTypeFunction %void
-      %float = OpTypeFloat 32
-    %v4float = OpTypeVector %float 4
-%_ptr_Output_v4float = OpTypePointer Output %v4float
- %_GLF_color = OpVariable %_ptr_Output_v4float Output
-    %float_1 = OpConstant %float 1
-    %float_0 = OpConstant %float 0
-         %18 = OpConstantComposite %v4float %float_1 %float_0 %float_0 %float_1
-        %int = OpTypeInt 32 1
-%_ptr_Function_int = OpTypePointer Function %int
-      %int_0 = OpConstant %int 0
-      %int_1 = OpConstant %int 1
-       %bool = OpTypeBool
-       %uint = OpTypeInt 32 0
-     %uint_1 = OpConstant %uint 1
-%_arr_float_uint_1 = OpTypeArray %float %uint_1
-%_ptr_Function__arr_float_uint_1 = OpTypePointer Function %_arr_float_uint_1
-%_ptr_Function_float = OpTypePointer Function %float
-      %false = OpConstantFalse %bool
-       %true = OpConstantTrue %bool
-    %float_2 = OpConstant %float 2
-       %main = OpFunction %void None %12
-         %32 = OpLabel
-          %i = OpVariable %_ptr_Function_int Function
-       %data = OpVariable %_ptr_Function__arr_float_uint_1 Function
-               OpStore %_GLF_color %18
-               OpStore %i %int_0
-               OpBranch %33
-         %33 = OpLabel
-               OpLoopMerge %34 %35 None
-               OpBranch %36
-         %36 = OpLabel
-          %6 = OpLoad %int %i
-         %37 = OpSLessThan %bool %6 %int_1
-               OpBranchConditional %37 %38 %34
-         %38 = OpLabel
-          %7 = OpLoad %int %i
-         %39 = OpAccessChain %_ptr_Function_float %data %7
-         %40 = OpLoad %float %39
-         %41 = OpAccessChain %_ptr_Function_float %data %int_0
-         %42 = OpLoad %float %41
-         %43 = OpFOrdLessThan %bool %40 %42
-               OpSelectionMerge %44 None
-               OpBranchConditional %43 %45 %44
-         %45 = OpLabel
-               OpSelectionMerge %46 None
-               OpBranchConditional %false %47 %46
-         %47 = OpLabel
-          %8 = OpLoad %int %i
-         %48 = OpConvertSToF %float %8
-         %49 = OpFOrdGreaterThanEqual %bool %48 %float_1
-               OpSelectionMerge %50 None
-               OpBranchConditional %49 %51 %50
-         %51 = OpLabel
-               OpBranch %50
-         %50 = OpLabel
-               OpBranch %46
-         %46 = OpLabel
-               OpSelectionMerge %52 None
-               OpSwitch %int_0 %52 1 %53 0 %54
-         %53 = OpLabel
-               OpBranch %55
-         %55 = OpLabel
-               OpLoopMerge %56 %57 None
-               OpBranch %58
-         %58 = OpLabel
-               OpBranchConditional %true %59 %56
-         %59 = OpLabel
-               OpBranch %57
-         %57 = OpLabel
-               OpBranch %55
-         %56 = OpLabel
-               OpBranch %60
-         %60 = OpLabel
-               OpLoopMerge %61 %62 None
-               OpBranch %63
-         %63 = OpLabel
-               OpBranch %62
-         %62 = OpLabel
-               OpBranch %60
-         %61 = OpLabel
-               OpBranch %54
-         %54 = OpLabel
-         %64 = OpAccessChain %_ptr_Function_float %data %int_0
-               OpStore %64 %float_2
-               OpBranch %52
-         %52 = OpLabel
-               OpBranch %44
-         %44 = OpLabel
-               OpBranch %35
-         %35 = OpLabel
-          %9 = OpLoad %int %i
-         %10 = OpIAdd %int %9 %int_1
-               OpStore %i %10
-               OpBranch %33
-         %34 = OpLabel
-               OpReturn
-               OpFunctionEnd
diff --git a/test/vk-gl-cts/graphicsfuzz/unreachable-loops-in-switch/0.wgsl b/test/vk-gl-cts/graphicsfuzz/unreachable-loops-in-switch/0.wgsl
index 27a00c6..473428a 100644
--- a/test/vk-gl-cts/graphicsfuzz/unreachable-loops-in-switch/0.wgsl
+++ b/test/vk-gl-cts/graphicsfuzz/unreachable-loops-in-switch/0.wgsl
@@ -29,6 +29,7 @@
             }
           }
           loop {
+            break;
           }
           fallthrough;
         }
@@ -38,6 +39,8 @@
         default: {
         }
       }
+
+      break;
     }
 
     continuing {