[tint][ir] Validate no calls to entry points

Bug: tint:1952
Change-Id: I7676ef0345f3df0310ed457933101d93037bd6bc
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/169221
Reviewed-by: Ben Clayton <bclayton@google.com>
Kokoro: Kokoro <noreply+kokoro@google.com>
Commit-Queue: James Price <jrprice@google.com>
diff --git a/src/tint/lang/core/ir/validator.cc b/src/tint/lang/core/ir/validator.cc
index 5546f2c..2aa16f8 100644
--- a/src/tint/lang/core/ir/validator.cc
+++ b/src/tint/lang/core/ir/validator.cc
@@ -598,6 +598,12 @@
         AddError(call, UserCall::kFunctionOperandOffset,
                  InstError(call, "call target is not part of the module"));
     }
+
+    if (call->Target()->Stage() != Function::PipelineStage::kUndefined) {
+        AddError(call, UserCall::kFunctionOperandOffset,
+                 InstError(call, "call target must not have a pipeline stage"));
+    }
+
     auto args = call->Args();
     auto params = call->Target()->Params();
     if (args.Length() != params.Length()) {
diff --git a/src/tint/lang/core/ir/validator_test.cc b/src/tint/lang/core/ir/validator_test.cc
index d81f679..3c2733a 100644
--- a/src/tint/lang/core/ir/validator_test.cc
+++ b/src/tint/lang/core/ir/validator_test.cc
@@ -179,6 +179,42 @@
 )");
 }
 
+TEST_F(IR_ValidatorTest, CallToEntryPointFunction) {
+    auto* f = b.Function("f", ty.void_());
+    auto* g = b.Function("g", ty.void_(), Function::PipelineStage::kCompute);
+
+    b.Append(f->Block(), [&] {
+        b.Call(g);
+        b.Return(f);
+    });
+    b.Append(g->Block(), [&] { b.Return(g); });
+
+    auto res = ir::Validate(mod);
+    ASSERT_NE(res, Success);
+    EXPECT_EQ(res.Failure().reason.str(),
+              R"(:3:20 error: call: call target must not have a pipeline stage
+    %2:void = call %g
+                   ^^
+
+:2:3 note: In block
+  %b1 = block {
+  ^^^^^^^^^^^
+
+note: # Disassembly
+%f = func():void -> %b1 {
+  %b1 = block {
+    %2:void = call %g
+    ret
+  }
+}
+%g = @compute func():void -> %b2 {
+  %b2 = block {
+    ret
+  }
+}
+)");
+}
+
 TEST_F(IR_ValidatorTest, CallToFunctionTooFewArguments) {
     auto* g = b.Function("g", ty.void_());
     g->SetParams({b.FunctionParam<i32>(), b.FunctionParam<i32>()});