[ir] Drop nullptr initializer from Override

This makes it match WGSL, where no operand means "must be initialized
by API".

Change-Id: I6e3b31348c7a01104b495a5ac0f099089ed00da6
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/351136
Reviewed-by: dan sinclair <dsinclair@chromium.org>
Commit-Queue: James Price <jrprice@google.com>
diff --git a/src/tint/lang/core/ir/override.cc b/src/tint/lang/core/ir/override.cc
index 719203e..da623db 100644
--- a/src/tint/lang/core/ir/override.cc
+++ b/src/tint/lang/core/ir/override.cc
@@ -41,14 +41,17 @@
 
 Override::Override(Id id, InstructionResult* result) : Base(id) {
     // Default to no initializer.
-    AddOperand(Override::kInitializerOperandOffset, nullptr);
     AddResult(result);
 }
 
 Override::~Override() = default;
 
 void Override::SetInitializer(Value* initializer) {
-    SetOperand(Override::kInitializerOperandOffset, initializer);
+    if (Operands().Length() > Override::kInitializerOperandOffset) {
+        SetOperand(Override::kInitializerOperandOffset, initializer);
+    } else {
+        AddOperand(Override::kInitializerOperandOffset, initializer);
+    }
 }
 
 Override* Override::Clone(CloneContext& ctx) {
diff --git a/src/tint/lang/core/ir/override.h b/src/tint/lang/core/ir/override.h
index 235b41c..2da41b5 100644
--- a/src/tint/lang/core/ir/override.h
+++ b/src/tint/lang/core/ir/override.h
@@ -45,8 +45,11 @@
     /// The fixed number of results returned by this instruction
     static constexpr size_t kNumResults = 1;
 
-    /// The fixed number of operands expected by this instruction
-    static constexpr size_t kNumOperands = 1;
+    /// The minimum number of operands accepted by override instructions.
+    static constexpr size_t kMinOperands = 0;
+
+    /// The maximum number of operands accepted by override instructions.
+    static constexpr size_t kMaxOperands = 1;
 
     /// Constructor (no results, no operands)
     /// @param id the instruction id
diff --git a/src/tint/lang/core/ir/referenced_module_decls_test.cc b/src/tint/lang/core/ir/referenced_module_decls_test.cc
index 3262624..f2ad4d2 100644
--- a/src/tint/lang/core/ir/referenced_module_decls_test.cc
+++ b/src/tint/lang/core/ir/referenced_module_decls_test.cc
@@ -91,7 +91,7 @@
   %o:i32 = override 1i @id(1)
   %4:i32 = add %o, 2i
   %c:ptr<workgroup, u32, read_write> = var
-  %p:i32 = override undef
+  %p:i32 = override
   %7:i32 = mul %p, 4i
 }
 
@@ -133,8 +133,8 @@
   %a:ptr<workgroup, u32, read_write> = var
   %b:ptr<workgroup, u32, read_write> = var
   %c:ptr<workgroup, u32, read_write> = var
-  %d:i32 = override undef
-  %e:i32 = override undef @id(1)
+  %d:i32 = override
+  %e:i32 = override @id(1)
 }
 
 %foo = func():void {
@@ -186,7 +186,7 @@
   %a:ptr<workgroup, u32, read_write> = var
   %b:ptr<workgroup, u32, read_write> = var
   %c:ptr<workgroup, u32, read_write> = var
-  %d:i32 = override undef
+  %d:i32 = override
 }
 
 %foo = func():void {
@@ -256,7 +256,7 @@
   %a:ptr<workgroup, u32, read_write> = var
   %b:ptr<workgroup, u32, read_write> = var
   %c:ptr<workgroup, u32, read_write> = var
-  %c_1:i32 = override undef  # %c_1: 'c'
+  %c_1:i32 = override  # %c_1: 'c'
 }
 
 %foo = func():void {
@@ -324,7 +324,7 @@
     auto* src = R"(
 $B1: {  # root
   %a:ptr<workgroup, u32, read_write> = var
-  %b:i32 = override undef
+  %b:i32 = override
   %c:ptr<workgroup, u32, read_write> = var
 }
 
@@ -419,7 +419,7 @@
 
     auto* src = R"(
 $B1: {  # root
-  %o:u32 = override undef @id(1)
+  %o:u32 = override @id(1)
 }
 
 %foo = @compute @workgroup_size(%o, 1u, 1u) func():void {
@@ -451,7 +451,7 @@
 
     auto* src = R"(
 $B1: {  # root
-  %o:u32 = override undef @id(1)
+  %o:u32 = override @id(1)
   %a:ptr<workgroup, array<i32, %o>, read_write> = var
 }
 
diff --git a/src/tint/lang/core/ir/transform/single_entry_point_test.cc b/src/tint/lang/core/ir/transform/single_entry_point_test.cc
index e771a49..b07e5ea 100644
--- a/src/tint/lang/core/ir/transform/single_entry_point_test.cc
+++ b/src/tint/lang/core/ir/transform/single_entry_point_test.cc
@@ -294,9 +294,9 @@
 
     auto* src = R"(
 $B1: {  # root
-  %o1:i32 = override undef @id(1)
-  %o2:i32 = override undef @id(2)
-  %o3:i32 = override undef @id(3)
+  %o1:i32 = override @id(1)
+  %o2:i32 = override @id(2)
+  %o3:i32 = override @id(3)
 }
 
 %foo = @fragment func():void {
@@ -316,8 +316,8 @@
 
     auto* expect = R"(
 $B1: {  # root
-  %o1:i32 = override undef @id(1)
-  %o2:i32 = override undef @id(2)
+  %o1:i32 = override @id(1)
+  %o2:i32 = override @id(2)
 }
 
 %foo = @fragment func():void {
@@ -520,10 +520,10 @@
 
     auto* src = R"(
 $B1: {  # root
-  %unused_override:i32 = override undef @id(5)
-  %o1:i32 = override undef @id(1)
-  %o2:i32 = override undef @id(2)
-  %o3:i32 = override undef @id(3)
+  %unused_override:i32 = override @id(5)
+  %o1:i32 = override @id(1)
+  %o2:i32 = override @id(2)
+  %o3:i32 = override @id(3)
 }
 
 %unused_func = func():void {
@@ -561,9 +561,9 @@
 
     auto* expect = R"(
 $B1: {  # root
-  %o1:i32 = override undef @id(1)
-  %o2:i32 = override undef @id(2)
-  %o3:i32 = override undef @id(3)
+  %o1:i32 = override @id(1)
+  %o2:i32 = override @id(2)
+  %o3:i32 = override @id(3)
 }
 
 %f1 = func():void {
@@ -775,13 +775,13 @@
 
     auto* src = R"(
 $B1: {  # root
-  %o1:i32 = override undef @id(1)
-  %o2:i32 = override undef @id(2)
-  %o3:i32 = override undef @id(3)
-  %o4:i32 = override undef @id(4)
-  %o5:i32 = override undef @id(5)
-  %o6:i32 = override undef @id(6)
-  %o7:i32 = override undef @id(7)
+  %o1:i32 = override @id(1)
+  %o2:i32 = override @id(2)
+  %o3:i32 = override @id(3)
+  %o4:i32 = override @id(4)
+  %o5:i32 = override @id(5)
+  %o6:i32 = override @id(6)
+  %o7:i32 = override @id(7)
 }
 
 %foo = @fragment func():void {
@@ -807,8 +807,8 @@
 
     auto* expect = R"(
 $B1: {  # root
-  %o1:i32 = override undef @id(1)
-  %o5:i32 = override undef @id(5)
+  %o1:i32 = override @id(1)
+  %o5:i32 = override @id(5)
 }
 
 %foo = @fragment func():void {
@@ -840,9 +840,9 @@
 
     auto* src = R"(
 $B1: {  # root
-  %o1:i32 = override undef @id(1)
-  %o2:i32 = override undef @id(2)
-  %o3:i32 = override undef @id(3)
+  %o1:i32 = override @id(1)
+  %o2:i32 = override @id(2)
+  %o3:i32 = override @id(3)
 }
 
 %foo = @compute @workgroup_size(%o1, %o2, %o1) func():void {
@@ -859,8 +859,8 @@
 
     auto* expect = R"(
 $B1: {  # root
-  %o1:i32 = override undef @id(1)
-  %o2:i32 = override undef @id(2)
+  %o1:i32 = override @id(1)
+  %o2:i32 = override @id(2)
 }
 
 %foo = @compute @workgroup_size(%o1, %o2, %o1) func():void {
@@ -908,8 +908,8 @@
 
     auto* src = R"(
 $B1: {  # root
-  %o1:i32 = override undef @id(1)
-  %o2:i32 = override undef @id(2)
+  %o1:i32 = override @id(1)
+  %o2:i32 = override @id(2)
   %a:ptr<workgroup, array<i32, %o1>, read_write> = var
   %b:ptr<workgroup, array<i32, %o2>, read_write> = var
 }
@@ -930,7 +930,7 @@
 
     auto* expect = R"(
 $B1: {  # root
-  %o1:i32 = override undef @id(1)
+  %o1:i32 = override @id(1)
   %a:ptr<workgroup, array<i32, %o1>, read_write> = var
 }
 
@@ -965,7 +965,7 @@
     EntryPoint("foo", {func});
     auto* src = R"(
 $B1: {  # root
-  %x:u32 = override undef @id(2)
+  %x:u32 = override @id(2)
   %2:u32 = add %x, 4u
   %a:u32 = override %2 @id(1)
 }
@@ -985,7 +985,7 @@
 
     auto* expect = R"(
 $B1: {  # root
-  %x:u32 = override undef @id(2)
+  %x:u32 = override @id(2)
   %2:u32 = add %x, 4u
   %a:u32 = override %2 @id(1)
 }
@@ -1026,7 +1026,7 @@
     EntryPoint("foo", {v1});
     auto* src = R"(
 $B1: {  # root
-  %x:u32 = override undef @id(2)
+  %x:u32 = override @id(2)
   %2:u32 = add %x, 3u
   %a:ptr<private, u32, read_write> = var %2
 }
@@ -1041,7 +1041,7 @@
 
     auto* expect = R"(
 $B1: {  # root
-  %x:u32 = override undef @id(2)
+  %x:u32 = override @id(2)
   %2:u32 = add %x, 3u
   %a:ptr<private, u32, read_write> = var %2
 }
@@ -1081,7 +1081,7 @@
     EntryPoint("foo", {v1});
     auto* src = R"(
 $B1: {  # root
-  %x:u32 = override undef @id(2)
+  %x:u32 = override @id(2)
   %2:u32 = add %x, 3u
   %3:u32 = add %x, 3u
   %a:ptr<private, u32, read_write> = var %2
@@ -1098,7 +1098,7 @@
 
     auto* expect = R"(
 $B1: {  # root
-  %x:u32 = override undef @id(2)
+  %x:u32 = override @id(2)
   %2:u32 = add %x, 3u
   %a:ptr<private, u32, read_write> = var %2
 }
@@ -1134,7 +1134,7 @@
     EntryPoint("foo", {});
     auto* src = R"(
 $B1: {  # root
-  %x:u32 = override undef @id(2)
+  %x:u32 = override @id(2)
   %2:u32 = add %x, 3u
   %a:ptr<private, u32, read_write> = var %2
 }
@@ -1187,7 +1187,7 @@
 
     auto* src = R"(
 $B1: {  # root
-  %cond:bool = override undef @id(0)
+  %cond:bool = override @id(0)
   %one_f32:f32 = override 1.0f @id(2)
   %3:bool = constexpr_if %cond [t: $B2, f: $B3] {  # constexpr_if_1
     $B2: {  # true
@@ -1217,7 +1217,7 @@
 
     auto* expect = R"(
 $B1: {  # root
-  %cond:bool = override undef @id(0)
+  %cond:bool = override @id(0)
   %one_f32:f32 = override 1.0f @id(2)
   %3:bool = constexpr_if %cond [t: $B2, f: $B3] {  # constexpr_if_1
     $B2: {  # true
@@ -1275,7 +1275,7 @@
     });
     auto* src = R"(
 $B1: {  # root
-  %x:i32 = override undef @id(0)
+  %x:i32 = override @id(0)
   %2:i32 = add %x, 2i
   %v:ptr<workgroup, buffer<%2>, read_write> = var
 }
diff --git a/src/tint/lang/core/ir/transform/substitute_overrides_test.cc b/src/tint/lang/core/ir/transform/substitute_overrides_test.cc
index 2c6b7a2..efd089b 100644
--- a/src/tint/lang/core/ir/transform/substitute_overrides_test.cc
+++ b/src/tint/lang/core/ir/transform/substitute_overrides_test.cc
@@ -88,7 +88,7 @@
 
     auto* src = R"(
 $B1: {  # root
-  %a:i32 = override undef @id(1)
+  %a:i32 = override @id(1)
 }
 
 )";
@@ -219,7 +219,7 @@
 
     auto* src = R"(
 $B1: {  # root
-  %a:u32 = override undef @id(1)
+  %a:u32 = override @id(1)
 }
 
 %foo = func():u32 {
@@ -351,7 +351,7 @@
 
     auto* src = R"(
 $B1: {  # root
-  %x:u32 = override undef @id(2)
+  %x:u32 = override @id(2)
   %2:u32 = add %x, 4u
   %a:u32 = override %2 @id(1)
 }
@@ -399,7 +399,7 @@
 
     auto* src = R"(
 $B1: {  # root
-  %x:u32 = override undef @id(2)
+  %x:u32 = override @id(2)
   %2:u32 = add %x, 4u
   %a:u32 = override %2 @id(1)
 }
@@ -443,7 +443,7 @@
 
     auto* src = R"(
 $B1: {  # root
-  %x:f32 = override undef @id(2)
+  %x:f32 = override @id(2)
   %2:f32 = add %x, 4.0f
   %a:f32 = override %2 @id(1)
 }
@@ -480,7 +480,7 @@
 
     auto* src = R"(
 $B1: {  # root
-  %rhs:u32 = override undef @id(1)
+  %rhs:u32 = override @id(1)
 }
 
 %foo = func():u32 {
@@ -516,7 +516,7 @@
 
     auto* src = R"(
 $B1: {  # root
-  %rhs:u32 = override undef @id(1)
+  %rhs:u32 = override @id(1)
 }
 
 %foo = func():u32 {
@@ -553,7 +553,7 @@
 
     auto* src = R"(
 $B1: {  # root
-  %rhs:u32 = override undef @id(1)
+  %rhs:u32 = override @id(1)
 }
 
 %foo = func():u32 {
@@ -590,7 +590,7 @@
 
     auto* src = R"(
 $B1: {  # root
-  %rhs:u32 = override undef @id(1)
+  %rhs:u32 = override @id(1)
 }
 
 %foo = func():u32 {
@@ -631,7 +631,7 @@
 
     auto* src = R"(
 $B1: {  # root
-  %x:f32 = override undef @id(2)
+  %x:f32 = override @id(2)
   %2:f32 = add %x, 340282346638528859811704183484516925440.0f
   %a:f32 = override %2 @id(1)
 }
@@ -672,7 +672,7 @@
 
     auto* src = R"(
 $B1: {  # root
-  %x:u32 = override undef @id(2)
+  %x:u32 = override @id(2)
   %2:u32 = add %x, 4u
   %a:u32 = override %2 @id(1)
 }
@@ -762,7 +762,7 @@
 
     auto* src = R"(
 $B1: {  # root
-  %x:u32 = override undef @id(2)
+  %x:u32 = override @id(2)
   %2:u32 = add %x, 4u
   %a:u32 = override %2 @id(1)
 }
@@ -812,7 +812,7 @@
 
     auto* src = R"(
 $B1: {  # root
-  %x:f32 = override undef @id(2)
+  %x:f32 = override @id(2)
 }
 
 %foo = @fragment func():void {
@@ -868,7 +868,7 @@
 
     auto* src = R"(
 $B1: {  # root
-  %x:u32 = override undef @id(2)
+  %x:u32 = override @id(2)
   %2:u32 = add %x, 4u
   %a:u32 = override %2 @id(1)
 }
@@ -929,7 +929,7 @@
 
     auto* src = R"(
 $B1: {  # root
-  %x:u32 = override undef @id(2)
+  %x:u32 = override @id(2)
   %2:u32 = add %x, 4u
   %a:u32 = override %2 @id(1)
 }
@@ -990,7 +990,7 @@
 
     auto* src = R"(
 $B1: {  # root
-  %x:f32 = override undef @id(2)
+  %x:f32 = override @id(2)
   %2:f32 = add %x, 4.0f
   %a:f32 = override %2 @id(1)
 }
@@ -1052,7 +1052,7 @@
 
     auto* src = R"(
 $B1: {  # root
-  %x:f32 = override undef @id(2)
+  %x:f32 = override @id(2)
   %2:f32 = add %x, 4.0f
   %a:f32 = override %2 @id(1)
 }
@@ -1107,7 +1107,7 @@
 
     auto* src = R"(
 $B1: {  # root
-  %x:u32 = override undef @id(2)
+  %x:u32 = override @id(2)
   %v:ptr<workgroup, array<i32, %x>, read_write> = var
 }
 
@@ -1162,8 +1162,8 @@
 
     auto* src = R"(
 $B1: {  # root
-  %x:u32 = override undef @id(2)
-  %y:u32 = override undef @id(3)
+  %x:u32 = override @id(2)
+  %y:u32 = override @id(3)
   %v:ptr<workgroup, array<u32, %x>, read_write> = var
 }
 
@@ -1206,7 +1206,7 @@
 
     auto* src = R"(
 $B1: {  # root
-  %x:u32 = override undef @id(2)
+  %x:u32 = override @id(2)
   %v:ptr<workgroup, array<u32, %x>, read_write> = var
 }
 
@@ -1248,7 +1248,7 @@
 
     auto* src = R"(
 $B1: {  # root
-  %x:u32 = override undef @id(2)
+  %x:u32 = override @id(2)
   %v:ptr<workgroup, array<u32, %x>, read_write> = var
 }
 
@@ -1285,7 +1285,7 @@
 
     auto* src = R"(
 $B1: {  # root
-  %x:u32 = override undef @id(2)
+  %x:u32 = override @id(2)
   %2:u32 = mul %x, 2u
   %v:ptr<workgroup, array<i32, %2>, read_write> = var
 }
@@ -1338,7 +1338,7 @@
 
     auto* src = R"(
 $B1: {  # root
-  %x:u32 = override undef @id(2)
+  %x:u32 = override @id(2)
   %v:ptr<workgroup, array<i32, %x>, read_write> = var
 }
 
@@ -1399,7 +1399,7 @@
 
     auto* src = R"(
 $B1: {  # root
-  %cond:bool = override undef @id(0)
+  %cond:bool = override @id(0)
   %one_f32:f32 = override 1.0f @id(2)
   %3:bool = constexpr_if %cond [t: $B2, f: $B3] {  # constexpr_if_1
     $B2: {  # true
@@ -1463,7 +1463,7 @@
 
     auto* src = R"(
 $B1: {  # root
-  %cond:bool = override undef @id(0)
+  %cond:bool = override @id(0)
   %one_f32:f32 = override 1.0f @id(2)
   %3:bool = constexpr_if %cond [t: $B2, f: $B3] {  # constexpr_if_1
     $B2: {  # true
@@ -1521,7 +1521,7 @@
 
     auto* src = R"(
 $B1: {  # root
-  %cond:bool = override undef @id(0)
+  %cond:bool = override @id(0)
   %one_f32:f32 = override 1.0f @id(2)
   %3:bool = constexpr_if %cond [t: $B2, f: $B3] {  # constexpr_if_1
     $B2: {  # true
@@ -1597,7 +1597,7 @@
 
     auto* src = R"(
 $B1: {  # root
-  %cond:bool = override undef @id(0)
+  %cond:bool = override @id(0)
   %zero_f32:f32 = override 0.0f @id(2)
   %3:bool = constexpr_if %cond [t: $B2, f: $B3] {  # constexpr_if_1
     $B2: {  # true
@@ -1674,8 +1674,8 @@
 
     auto* src = R"(
 $B1: {  # root
-  %x:u32 = override undef @id(1)
-  %y:bool = override undef @id(2)
+  %x:u32 = override @id(1)
+  %y:bool = override @id(2)
 }
 
 %foo = @compute @workgroup_size(1u, 1u, 1u) func():void {
@@ -1740,7 +1740,7 @@
 
     auto* src = R"(
 $B1: {  # root
-  %y:bool = override undef @id(1)
+  %y:bool = override @id(1)
 }
 
 %foo = @compute @workgroup_size(1u, 1u, 1u) func():void {
@@ -1803,7 +1803,7 @@
 
     auto* src = R"(
 $B1: {  # root
-  %x:u32 = override undef @id(0)
+  %x:u32 = override @id(0)
 }
 
 %foo2 = func():u32 {
@@ -1844,7 +1844,7 @@
 
     auto* src = R"(
 $B1: {  # root
-  %x:i32 = override undef @id(0)
+  %x:i32 = override @id(0)
   %arr:ptr<storage, array<u32>, read_write> = var @binding_point(0, 0)
 }
 
@@ -1894,10 +1894,10 @@
 
     auto* src = R"(
 $B1: {  # root
-  %o0:f16 = override undef @id(0)
-  %o1:f16 = override undef @id(1)
-  %o2:f16 = override undef @id(2)
-  %o3:f16 = override undef @id(3)
+  %o0:f16 = override @id(0)
+  %o1:f16 = override @id(1)
+  %o2:f16 = override @id(2)
+  %o3:f16 = override @id(3)
   %5:vec4<f16> = construct %o0, %o1, %o2, %o3
   %6:vec4<f16> = ceil %5
   %global:ptr<private, vec4<f16>, read_write> = var %6
@@ -1945,7 +1945,7 @@
     });
     auto* src = R"(
 $B1: {  # root
-  %x:u32 = override undef @id(2)
+  %x:u32 = override @id(2)
 }
 
 )";
@@ -1967,7 +1967,7 @@
     });
     auto* src = R"(
 $B1: {  # root
-  %x:i32 = override undef @id(2)
+  %x:i32 = override @id(2)
 }
 
 )";
@@ -1989,7 +1989,7 @@
     });
     auto* src = R"(
 $B1: {  # root
-  %x:f32 = override undef @id(2)
+  %x:f32 = override @id(2)
 }
 
 )";
@@ -2011,7 +2011,7 @@
     });
     auto* src = R"(
 $B1: {  # root
-  %x:f16 = override undef @id(2)
+  %x:f16 = override @id(2)
 }
 
 )";
@@ -2048,7 +2048,7 @@
 
     auto* src = R"(
 $B1: {  # root
-  %x:u32 = override undef @id(2)
+  %x:u32 = override @id(2)
   %v:ptr<workgroup, array<u32, %x>, read_write> = var
 }
 
@@ -2091,7 +2091,7 @@
 
     auto* src = R"(
 $B1: {  # root
-  %x:i32 = override undef @id(2)
+  %x:i32 = override @id(2)
   %v:ptr<workgroup, array<u32, %x>, read_write> = var
 }
 
@@ -2136,7 +2136,7 @@
 
     auto* src = R"(
 $B1: {  # root
-  %x:i32 = override undef @id(0)
+  %x:i32 = override @id(0)
   %v:ptr<workgroup, array<u32, %x>, read_write> = var
 }
 
@@ -2182,7 +2182,7 @@
     });
     auto* src = R"(
 $B1: {  # root
-  %x:i32 = override undef @id(0)
+  %x:i32 = override @id(0)
   %2:i32 = add %x, 2i
   %v:ptr<workgroup, array<u32, %2>, read_write> = var
 }
@@ -2253,7 +2253,7 @@
     });
     auto* src = R"(
 $B1: {  # root
-  %x:i32 = override undef @id(0)
+  %x:i32 = override @id(0)
   %2:i32 = add %x, 2i
   %v:ptr<workgroup, buffer<%2>, read_write> = var
 }
@@ -2321,7 +2321,7 @@
 
     auto* src = R"(
 $B1: {  # root
-  %x:i32 = override undef @id(1)
+  %x:i32 = override @id(1)
   %v:ptr<workgroup, buffer<%x>, read_write> = var
 }
 
@@ -2366,7 +2366,7 @@
 
     auto* src = R"(
 $B1: {  # root
-  %x:i32 = override undef @id(1)
+  %x:i32 = override @id(1)
   %v:ptr<workgroup, buffer<%x>, read_write> = var
 }
 
@@ -2411,7 +2411,7 @@
 
     auto* src = R"(
 $B1: {  # root
-  %x:i32 = override undef @id(1)
+  %x:i32 = override @id(1)
   %v:ptr<workgroup, buffer<%x>, read_write> = var
 }
 
@@ -2456,7 +2456,7 @@
 
     auto* src = R"(
 $B1: {  # root
-  %x:i32 = override undef @id(1)
+  %x:i32 = override @id(1)
   %v:ptr<workgroup, buffer<%x>, read_write> = var
 }
 
@@ -2511,7 +2511,7 @@
 }
 
 $B1: {  # root
-  %x:i32 = override undef @id(1)
+  %x:i32 = override @id(1)
   %v:ptr<workgroup, buffer<%x>, read_write> = var
 }
 
@@ -2566,7 +2566,7 @@
 }
 
 $B1: {  # root
-  %x:i32 = override undef @id(1)
+  %x:i32 = override @id(1)
   %v:ptr<workgroup, buffer<%x>, read_write> = var
 }
 
@@ -2608,7 +2608,7 @@
 
     auto* src = R"(
 $B1: {  # root
-  %x:u32 = override undef @id(1)
+  %x:u32 = override @id(1)
   %v:ptr<workgroup, buffer<128>, read_write> = var
 }
 
@@ -2667,9 +2667,9 @@
 }
 
 $B1: {  # root
-  %b:u32 = override undef @id(1)
-  %o:u32 = override undef @id(2)
-  %s:u32 = override undef @id(3)
+  %b:u32 = override @id(1)
+  %o:u32 = override @id(2)
+  %s:u32 = override @id(3)
   %v:ptr<workgroup, buffer<%b>, read_write> = var
 }
 
@@ -2730,9 +2730,9 @@
 }
 
 $B1: {  # root
-  %b:u32 = override undef @id(1)
-  %o:u32 = override undef @id(2)
-  %s:u32 = override undef @id(3)
+  %b:u32 = override @id(1)
+  %o:u32 = override @id(2)
+  %s:u32 = override @id(3)
   %v:ptr<workgroup, buffer<%b>, read_write> = var
 }
 
@@ -2793,9 +2793,9 @@
 }
 
 $B1: {  # root
-  %b:u32 = override undef @id(1)
-  %o:u32 = override undef @id(2)
-  %s:u32 = override undef @id(3)
+  %b:u32 = override @id(1)
+  %o:u32 = override @id(2)
+  %s:u32 = override @id(3)
   %v:ptr<workgroup, buffer<%b>, read_write> = var
 }
 
@@ -2848,7 +2848,7 @@
 
     auto* src = R"(
 $B1: {  # root
-  %x:u32 = override undef @id(1)
+  %x:u32 = override @id(1)
   %v:ptr<workgroup, buffer<%x>, read_write> = var
 }
 
@@ -2904,7 +2904,7 @@
 
     auto* src = R"(
 $B1: {  # root
-  %x:u32 = override undef @id(1)
+  %x:u32 = override @id(1)
   %v:ptr<workgroup, buffer<128>, read_write> = var
 }
 
diff --git a/src/tint/lang/core/ir/validator/validator.cc b/src/tint/lang/core/ir/validator/validator.cc
index 0acf998..cb19f9d 100644
--- a/src/tint/lang/core/ir/validator/validator.cc
+++ b/src/tint/lang/core/ir/validator/validator.cc
@@ -425,9 +425,9 @@
     auto* operand = inst->Operand(idx);
 
     if (DAWN_UNLIKELY(operand == nullptr)) {
-        // var and override instructions are allowed to have a nullptr initializers.
+        // var instructions are allowed to have a nullptr initializers.
         // terminator instructions use nullptr operands to signal 'undef'.
-        if (inst->IsAnyOf<Terminator, Var, Override>()) {
+        if (inst->IsAnyOf<Terminator, Var>()) {
             return true;
         }
 
diff --git a/src/tint/lang/core/ir/validator/validator_instructions.cc b/src/tint/lang/core/ir/validator/validator_instructions.cc
index 0af7753..2ca3f23 100644
--- a/src/tint/lang/core/ir/validator/validator_instructions.cc
+++ b/src/tint/lang/core/ir/validator/validator_instructions.cc
@@ -271,7 +271,8 @@
 }
 
 void Validator::CheckOverride(const Override* o) {
-    if (!CheckResultsAndOperands(o, Override::kNumResults, Override::kNumOperands)) {
+    if (!CheckResultsAndOperandRange(o, Override::kNumResults, Override::kMinOperands,
+                                     Override::kMaxOperands)) {
         return;
     }
 
diff --git a/src/tint/lang/core/ir/validator/validator_test.cc b/src/tint/lang/core/ir/validator/validator_test.cc
index 22472e5..81282fe 100644
--- a/src/tint/lang/core/ir/validator/validator_test.cc
+++ b/src/tint/lang/core/ir/validator/validator_test.cc
@@ -1970,7 +1970,7 @@
     EXPECT_THAT(
         res.Failure().reason,
         testing::HasSubstr(R"(:2:18 error: override: override type 'vec3<u32>' is not a scalar
-  %1:vec3<u32> = override undef
+  %1:vec3<u32> = override
                  ^^^^^^^^
 )")) << res.Failure();
 }
@@ -2010,7 +2010,7 @@
     ASSERT_NE(res, Success);
     EXPECT_THAT(res.Failure().reason,
                 testing::HasSubstr(R"(:3:12 error: override: duplicate override id encountered: 2
-  %2:i32 = override undef @id(2)
+  %2:i32 = override @id(2)
            ^^^^^^^^
 )")) << res.Failure();
 }
@@ -2187,7 +2187,7 @@
     ASSERT_NE(res, Success);
     EXPECT_THAT(res.Failure().reason,
                 testing::HasSubstr(R"(:2:12 error: override: must have an id or an initializer
-  %1:u32 = override undef
+  %1:u32 = override
            ^^^^^^^^
 )")) << res.Failure();
 }
diff --git a/src/tint/lang/core/ir/validator/validator_value_test.cc b/src/tint/lang/core/ir/validator/validator_value_test.cc
index f8498fe..752f4df 100644
--- a/src/tint/lang/core/ir/validator/validator_value_test.cc
+++ b/src/tint/lang/core/ir/validator/validator_value_test.cc
@@ -1679,19 +1679,6 @@
                 testing::HasSubstr("error: let: subgroup_matrix values cannot be constant"));
 }
 
-TEST_F(IR_ValidatorTest, Override_RequiresInitOperand) {
-    mod.properties.Add(core::ir::Property::kAllowOverrides);
-    auto* o = mod.CreateInstruction<Override>();
-    o->AddResult(b.InstructionResult<core::type::U32>());
-    o->SetOverrideId(OverrideId{1});
-    mod.root_block->Append(o);
-
-    auto res = ir::Validate(mod);
-    ASSERT_NE(res, Success);
-    EXPECT_THAT(res.Failure().reason,
-                testing::HasSubstr("error: override: expected exactly 1 operands, got 0"));
-}
-
 TEST_F(IR_ValidatorTest, Override_TooManyOperands) {
     mod.properties.Add(core::ir::Property::kAllowOverrides);
     auto* o = mod.CreateInstruction<Override>();
@@ -1703,19 +1690,7 @@
     auto res = ir::Validate(mod);
     ASSERT_NE(res, Success);
     EXPECT_THAT(res.Failure().reason,
-                testing::HasSubstr("error: override: expected exactly 1 operands, got 2"));
-}
-
-TEST_F(IR_ValidatorTest, Override_NullInitializer) {
-    mod.properties.Add(core::ir::Property::kAllowOverrides);
-    auto* o = mod.CreateInstruction<Override>();
-    o->AddResult(b.InstructionResult<core::type::U32>());
-    o->SetOperands(Vector<ir::Value*, 1>{nullptr});
-    o->SetOverrideId(OverrideId{1});
-    mod.root_block->Append(o);
-
-    auto res = ir::Validate(mod);
-    ASSERT_EQ(res, Success) << res.Failure();
+                testing::HasSubstr("error: override: expected between 0 and 1 operands, got 2"));
 }
 
 TEST_F(IR_ValidatorTest, Alignment_InvalidInstruction) {
diff --git a/src/tint/lang/wgsl/reader/program_to_ir/program_to_ir_test.cc b/src/tint/lang/wgsl/reader/program_to_ir/program_to_ir_test.cc
index 4d5bd73..f38c3ab 100644
--- a/src/tint/lang/wgsl/reader/program_to_ir/program_to_ir_test.cc
+++ b/src/tint/lang/wgsl/reader/program_to_ir/program_to_ir_test.cc
@@ -1200,7 +1200,7 @@
     EXPECT_EQ(m.SourceOf(override).range.begin, loc);
 
     EXPECT_EQ(Dis(m), R"($B1: {  # root
-  %a:i32 = override undef @id(0)
+  %a:i32 = override @id(0)
 }
 
 )");
@@ -1265,7 +1265,7 @@
     auto m = res.Move();
 
     EXPECT_EQ(Dis(m), R"($B1: {  # root
-  %b:u32 = override undef @id(0)
+  %b:u32 = override @id(0)
   %2:bool = constexpr_if false [t: $B2, f: $B3] {  # constexpr_if_1
     $B2: {  # true
       exit_if true  # constexpr_if_1
@@ -1293,8 +1293,8 @@
     auto m = res.Move();
 
     EXPECT_EQ(Dis(m), R"($B1: {  # root
-  %a:u32 = override undef @id(0)
-  %b:bool = override undef @id(1)
+  %a:u32 = override @id(0)
+  %b:bool = override @id(1)
   %3:bool = constexpr_if %b [t: $B2, f: $B3] {  # constexpr_if_1
     $B2: {  # true
       %4:u32 = div 1u, %a
@@ -1325,8 +1325,8 @@
     ASSERT_EQ(1u, m.functions.Length());
 
     EXPECT_EQ(Dis(m), R"($B1: {  # root
-  %a:u32 = override undef @id(0)
-  %b:bool = override undef @id(1)
+  %a:u32 = override @id(0)
+  %b:bool = override @id(1)
 }
 
 %test_function = @compute @workgroup_size(1u, 1u, 1u) func():void {
@@ -1362,7 +1362,7 @@
     ASSERT_EQ(1u, m.functions.Length());
 
     EXPECT_EQ(Dis(m), R"($B1: {  # root
-  %a:u32 = override undef @id(0)
+  %a:u32 = override @id(0)
 }
 
 %test_function = @compute @workgroup_size(1u, 1u, 1u) func():void {
@@ -1394,7 +1394,7 @@
 
     auto m = res.Move();
     EXPECT_EQ(Dis(m), R"($B1: {  # root
-  %z:u32 = override undef @id(0)
+  %z:u32 = override @id(0)
   %2:u32 = add %z, 2u
   %a:u32 = override %2 @id(1)
 }
@@ -1448,7 +1448,7 @@
 
     auto m = res.Move();
     EXPECT_EQ(Dis(m), R"($B1: {  # root
-  %cond:bool = override undef @id(0)
+  %cond:bool = override @id(0)
   %zero_i32:i32 = override 0i @id(1)
   %one_f32:f32 = override 1.0f @id(2)
   %thirty_one:u32 = override 31u @id(3)
@@ -1491,7 +1491,7 @@
 
     auto m = res.Move();
     EXPECT_EQ(Dis(m), R"($B1: {  # root
-  %x:u32 = override undef @id(0)
+  %x:u32 = override @id(0)
   %2:u32 = mul %x, 2u
   %arr:ptr<workgroup, array<u32, %2>, read_write> = var
 }
@@ -1519,7 +1519,7 @@
 
     auto m = res.Move();
     EXPECT_EQ(Dis(m), R"($B1: {  # root
-  %x:u32 = override undef @id(0)
+  %x:u32 = override @id(0)
   %2:u32 = mul %x, 2u
 }