[ir] Move AllowDuplicateBindings to a property

The BindingRemapper and GLSL TexturePolyfill transforms both add the
property.

The MultiplanarExternalTexture fuzzer now checks for potential binding
conflicts.

Bug: 512904070
Change-Id: Ifd659dc747827aafba29c56ef1bf589ed7cdd574
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/311670
Reviewed-by: dan sinclair <dsinclair@chromium.org>
Commit-Queue: James Price <jrprice@google.com>
diff --git a/src/tint/lang/core/ir/module.h b/src/tint/lang/core/ir/module.h
index 933a23d..6630691 100644
--- a/src/tint/lang/core/ir/module.h
+++ b/src/tint/lang/core/ir/module.h
@@ -56,6 +56,8 @@
 /// The IR validator will reject use of any non-core IR functionality when the module does not
 /// contain the corresponding property.
 enum class Property : uint8_t {
+    /// Allows binding points to be non-unique.
+    kAllowDuplicateBindings,
     /// Allows multiple entry points in the module.
     kAllowMultipleEntryPoints,
     /// Allow overrides
@@ -79,6 +81,7 @@
     case Property::k##p: \
         return out << #p
     switch (p) {  //
+        CASE(AllowDuplicateBindings);
         CASE(AllowMultipleEntryPoints);
         CASE(AllowOverrides);
         CASE(DisallowVectorMinMaxClamp);
diff --git a/src/tint/lang/core/ir/transform/array_length_from.h b/src/tint/lang/core/ir/transform/array_length_from.h
index 8dcd175..039f2f1 100644
--- a/src/tint/lang/core/ir/transform/array_length_from.h
+++ b/src/tint/lang/core/ir/transform/array_length_from.h
@@ -44,8 +44,9 @@
 
 /// The capabilities that the transform can support.
 const Capabilities kArrayLengthCapabilities{
-    Capability::kAllow8BitIntegers,      Capability::kAllow16BitIntegers,
-    Capability::kAllowDuplicateBindings, Capability::kMslAllowEntryPointInterface,
+    Capability::kAllow8BitIntegers,
+    Capability::kAllow16BitIntegers,
+    Capability::kMslAllowEntryPointInterface,
     Capability::kAllowNonCoreTypes,
 };
 
diff --git a/src/tint/lang/core/ir/transform/bgra8unorm_polyfill.h b/src/tint/lang/core/ir/transform/bgra8unorm_polyfill.h
index de945ee..4ddf2d3 100644
--- a/src/tint/lang/core/ir/transform/bgra8unorm_polyfill.h
+++ b/src/tint/lang/core/ir/transform/bgra8unorm_polyfill.h
@@ -40,7 +40,6 @@
 
 /// The capabilities that the transform can support.
 const Capabilities kBgra8UnormPolyfillCapabilities{
-    Capability::kAllowDuplicateBindings,
     Capability::kAllowNonCoreTypes,
     Capability::kAllow8BitIntegers,
 };
diff --git a/src/tint/lang/core/ir/transform/binary_polyfill.h b/src/tint/lang/core/ir/transform/binary_polyfill.h
index 6d6302d..8010c82 100644
--- a/src/tint/lang/core/ir/transform/binary_polyfill.h
+++ b/src/tint/lang/core/ir/transform/binary_polyfill.h
@@ -41,7 +41,6 @@
 
 /// The capabilities that the transform can support.
 const Capabilities kBinaryPolyfillCapabilities{
-    Capability::kAllowDuplicateBindings,
     Capability::kAllowNonCoreTypes,
     Capability::kAllow8BitIntegers,
     Capability::kAllow16BitIntegers,
diff --git a/src/tint/lang/core/ir/transform/binding_remapper.cc b/src/tint/lang/core/ir/transform/binding_remapper.cc
index 1ae2ca3..f580e0d 100644
--- a/src/tint/lang/core/ir/transform/binding_remapper.cc
+++ b/src/tint/lang/core/ir/transform/binding_remapper.cc
@@ -76,6 +76,8 @@
 
     Run(ir, binding_points);
 
+    ir.properties.Add(Property::kAllowDuplicateBindings);
+
     return Success;
 }
 
diff --git a/src/tint/lang/core/ir/transform/binding_remapper_fuzz.cc b/src/tint/lang/core/ir/transform/binding_remapper_fuzz.cc
index a4fe4b8..4379c9a 100644
--- a/src/tint/lang/core/ir/transform/binding_remapper_fuzz.cc
+++ b/src/tint/lang/core/ir/transform/binding_remapper_fuzz.cc
@@ -44,5 +44,7 @@
 
 TINT_IR_MODULE_FUZZER(tint::core::ir::transform::BindingRemapperFuzzer,
                       tint::core::ir::transform::kBindingRemapperCapabilities,
-                      tint::core::ir::transform::kBindingRemapperCapabilities +
-                          tint::core::ir::Capability::kAllowDuplicateBindings);
+                      tint::core::ir::transform::kBindingRemapperCapabilities,
+                      tint::core::ir::Properties{
+                          tint::core::ir::Property::kAllowDuplicateBindings,
+                      });
diff --git a/src/tint/lang/core/ir/transform/binding_remapper_test.cc b/src/tint/lang/core/ir/transform/binding_remapper_test.cc
index b70a3de..9e9d886 100644
--- a/src/tint/lang/core/ir/transform/binding_remapper_test.cc
+++ b/src/tint/lang/core/ir/transform/binding_remapper_test.cc
@@ -200,8 +200,6 @@
 }
 
 TEST_F(IR_BindingRemapperTest, BindingPointCollisionSameEntryPoint) {
-    capabilities.Add(Capability::kAllowDuplicateBindings);
-
     auto* buffer_a = b.Var("buffer_a", ty.ptr<uniform, i32>());
     buffer_a->SetBindingPoint(1, 2);
     mod.root_block->Append(buffer_a);
diff --git a/src/tint/lang/core/ir/transform/block_decorated_structs.h b/src/tint/lang/core/ir/transform/block_decorated_structs.h
index 33b7428..5c4f920 100644
--- a/src/tint/lang/core/ir/transform/block_decorated_structs.h
+++ b/src/tint/lang/core/ir/transform/block_decorated_structs.h
@@ -40,7 +40,6 @@
 
 /// The capabilities that the transform can support.
 const Capabilities kBlockDecoratedStructsCapabilities{
-    Capability::kAllowDuplicateBindings,
     Capability::kAllowNonCoreTypes,
     Capability::kAllow8BitIntegers,
     Capability::kAllow16BitIntegers,
diff --git a/src/tint/lang/core/ir/transform/builtin_polyfill.h b/src/tint/lang/core/ir/transform/builtin_polyfill.h
index 712ad1c..f90541a 100644
--- a/src/tint/lang/core/ir/transform/builtin_polyfill.h
+++ b/src/tint/lang/core/ir/transform/builtin_polyfill.h
@@ -41,7 +41,6 @@
 
 /// The capabilities that the transform can support.
 const Capabilities kBuiltinPolyfillCapabilities{
-    Capability::kAllowDuplicateBindings,
     Capability::kAllowNonCoreTypes,
     Capability::kAllow8BitIntegers,
     Capability::kAllow16BitIntegers,
diff --git a/src/tint/lang/core/ir/transform/builtin_scalarize.h b/src/tint/lang/core/ir/transform/builtin_scalarize.h
index 410bfc5..d32f01d2 100644
--- a/src/tint/lang/core/ir/transform/builtin_scalarize.h
+++ b/src/tint/lang/core/ir/transform/builtin_scalarize.h
@@ -41,7 +41,6 @@
 
 /// The capabilities that the transform can support.
 const Capabilities kBuiltinScalarizeCapabilities{
-    core::ir::Capability::kAllowDuplicateBindings,
     core::ir::Capability::kAllow8BitIntegers,
     core::ir::Capability::kAllow16BitIntegers,
     core::ir::Capability::kAllow64BitIntegers,
diff --git a/src/tint/lang/core/ir/transform/change_immediate_to_uniform.cc b/src/tint/lang/core/ir/transform/change_immediate_to_uniform.cc
index 5e48982..152e69e 100644
--- a/src/tint/lang/core/ir/transform/change_immediate_to_uniform.cc
+++ b/src/tint/lang/core/ir/transform/change_immediate_to_uniform.cc
@@ -153,7 +153,6 @@
                               core::ir::Capability::kAllow16BitIntegers,
                               core::ir::Capability::kAllowPointSizeBuiltin,
                               core::ir::Capability::kAllowClipDistancesOnF32ScalarAndVector,
-                              core::ir::Capability::kAllowDuplicateBindings,
                               core::ir::Capability::kAllowNonCoreTypes,
                               core::ir::Capability::kMslAllowEntryPointInterface,
                           },
diff --git a/src/tint/lang/core/ir/transform/combine_access_instructions.cc b/src/tint/lang/core/ir/transform/combine_access_instructions.cc
index d9bbf07..f8deb2f 100644
--- a/src/tint/lang/core/ir/transform/combine_access_instructions.cc
+++ b/src/tint/lang/core/ir/transform/combine_access_instructions.cc
@@ -82,7 +82,6 @@
 Result<SuccessType> CombineAccessInstructions(Module& ir) {
     core::ir::AssertValid(ir,
                           core::ir::Capabilities{
-                              core::ir::Capability::kAllowDuplicateBindings,
                               core::ir::Capability::kAllowNonCoreTypes,
                               core::ir::Capability::kAllow8BitIntegers,
                           },
diff --git a/src/tint/lang/core/ir/transform/conversion_polyfill.h b/src/tint/lang/core/ir/transform/conversion_polyfill.h
index 7e08848..56397b1 100644
--- a/src/tint/lang/core/ir/transform/conversion_polyfill.h
+++ b/src/tint/lang/core/ir/transform/conversion_polyfill.h
@@ -41,7 +41,6 @@
 
 /// The capabilities that the transform can support.
 const Capabilities kConversionPolyfillCapabilities{
-    Capability::kAllowDuplicateBindings,
     Capability::kAllowNonCoreTypes,
     Capability::kAllow8BitIntegers,
     Capability::kAllow16BitIntegers,
diff --git a/src/tint/lang/core/ir/transform/decompose_access.cc b/src/tint/lang/core/ir/transform/decompose_access.cc
index 8518d8d..42d73bd 100644
--- a/src/tint/lang/core/ir/transform/decompose_access.cc
+++ b/src/tint/lang/core/ir/transform/decompose_access.cc
@@ -1538,7 +1538,6 @@
                               core::ir::Capability::kAllow16BitIntegers,
                               core::ir::Capability::kAllowHandleVarsWithoutBindings,
                               core::ir::Capability::kAllowClipDistancesOnF32ScalarAndVector,
-                              core::ir::Capability::kAllowDuplicateBindings,
                               core::ir::Capability::kAllowNonCoreTypes,
                               core::ir::Capability::kLoosenValidationForShaderIO,
                           },
diff --git a/src/tint/lang/core/ir/transform/demote_to_helper.h b/src/tint/lang/core/ir/transform/demote_to_helper.h
index 6d392f6..e9b29a6 100644
--- a/src/tint/lang/core/ir/transform/demote_to_helper.h
+++ b/src/tint/lang/core/ir/transform/demote_to_helper.h
@@ -42,7 +42,6 @@
 const core::ir::Capabilities kDemoteToHelperCapabilities{
     core::ir::Capability::kAllowVectorElementPointer,
     core::ir::Capability::kAllowClipDistancesOnF32ScalarAndVector,
-    core::ir::Capability::kAllowDuplicateBindings,
     core::ir::Capability::kAllowNonCoreTypes,
     core::ir::Capability::kAllow8BitIntegers,
     core::ir::Capability::kAllow16BitIntegers,
diff --git a/src/tint/lang/core/ir/transform/direct_variable_access.h b/src/tint/lang/core/ir/transform/direct_variable_access.h
index dde363b..c19c261 100644
--- a/src/tint/lang/core/ir/transform/direct_variable_access.h
+++ b/src/tint/lang/core/ir/transform/direct_variable_access.h
@@ -42,7 +42,6 @@
 /// The capabilities that the transform can support.
 const core::ir::Capabilities kDirectVariableAccessCapabilities{
     core::ir::Capability::kAllowClipDistancesOnF32ScalarAndVector,
-    core::ir::Capability::kAllowDuplicateBindings,
     core::ir::Capability::kAllowNonCoreTypes,
     core::ir::Capability::kAllow8BitIntegers,
     core::ir::Capability::kAllow16BitIntegers,
diff --git a/src/tint/lang/core/ir/transform/multiplanar_external_texture.h b/src/tint/lang/core/ir/transform/multiplanar_external_texture.h
index 863a649..db78708 100644
--- a/src/tint/lang/core/ir/transform/multiplanar_external_texture.h
+++ b/src/tint/lang/core/ir/transform/multiplanar_external_texture.h
@@ -41,7 +41,6 @@
 
 /// The capabilities that the transform can support.
 const Capabilities kMultiplanarExternalTextureCapabilities{
-    Capability::kAllowDuplicateBindings,
     Capability::kAllowNonCoreTypes,
     Capability::kAllow8BitIntegers,
     Capability::kAllow16BitIntegers,
diff --git a/src/tint/lang/core/ir/transform/multiplanar_external_texture_fuzz.cc b/src/tint/lang/core/ir/transform/multiplanar_external_texture_fuzz.cc
index 501d6d8..b5d492c 100644
--- a/src/tint/lang/core/ir/transform/multiplanar_external_texture_fuzz.cc
+++ b/src/tint/lang/core/ir/transform/multiplanar_external_texture_fuzz.cc
@@ -28,6 +28,7 @@
 #include "src/tint/cmd/fuzz/common/ir_fuzzer.h"
 #include "src/tint/lang/core/ir/transform/multiplanar_external_texture.h"
 #include "src/tint/lang/core/ir/validator.h"
+#include "src/tint/lang/core/ir/var.h"
 
 namespace tint::core::ir::transform {
 namespace {
@@ -38,10 +39,25 @@
 Result<SuccessType> MultiplanarExternalTextureFuzzer(Module& ir,
                                                      const fuzz::ir::Context&,
                                                      const BindingsMap& input_map) {
+    Hashset<BindingPoint, 16> existing_bindings;
+    for (auto* inst : *ir.root_block) {
+        if (auto* var = inst->As<core::ir::Var>()) {
+            if (auto bp = var->BindingPoint()) {
+                existing_bindings.Add(*bp);
+            }
+        }
+    }
+
     tint::transform::multiplanar::BindingsMap multiplanar_map;
     for (const auto& iter : input_map) {
+        if (existing_bindings.Contains(iter.second.params) ||
+            existing_bindings.Contains(iter.second.plane_1)) {
+            return Failure{"new bindings conflict with existing bindings"};
+        }
+
         multiplanar_map.emplace(iter.first, iter.second);
     }
+
     return MultiplanarExternalTexture(ir, multiplanar_map);
 }
 
diff --git a/src/tint/lang/core/ir/transform/prepare_immediate_data.cc b/src/tint/lang/core/ir/transform/prepare_immediate_data.cc
index ee67b25..0f47667 100644
--- a/src/tint/lang/core/ir/transform/prepare_immediate_data.cc
+++ b/src/tint/lang/core/ir/transform/prepare_immediate_data.cc
@@ -156,7 +156,6 @@
                                                  const PrepareImmediateDataConfig& config) {
     core::ir::AssertValid(ir,
                           core::ir::Capabilities{
-                              core::ir::Capability::kAllowDuplicateBindings,
                               core::ir::Capability::kAllow8BitIntegers,
                               core::ir::Capability::kAllow16BitIntegers,
                               core::ir::Capability::kAllowNonCoreTypes,
diff --git a/src/tint/lang/core/ir/transform/preserve_padding.h b/src/tint/lang/core/ir/transform/preserve_padding.h
index cc08dea..9c9b581 100644
--- a/src/tint/lang/core/ir/transform/preserve_padding.h
+++ b/src/tint/lang/core/ir/transform/preserve_padding.h
@@ -41,7 +41,6 @@
 /// The capabilities that the transform can support.
 const core::ir::Capabilities kPreservePaddingCapabilities{
     core::ir::Capability::kAllowHandleVarsWithoutBindings,
-    core::ir::Capability::kAllowDuplicateBindings,
     core::ir::Capability::kAllowNonCoreTypes,
     core::ir::Capability::kAllow8BitIntegers,
 };
diff --git a/src/tint/lang/core/ir/transform/prevent_infinite_loops.h b/src/tint/lang/core/ir/transform/prevent_infinite_loops.h
index d569b5f..435cd20 100644
--- a/src/tint/lang/core/ir/transform/prevent_infinite_loops.h
+++ b/src/tint/lang/core/ir/transform/prevent_infinite_loops.h
@@ -40,7 +40,6 @@
 
 /// The capabilities that the transform can support.
 const Capabilities kPreventInfiniteLoopsCapabilities{
-    Capability::kAllowDuplicateBindings,
     Capability::kAllow8BitIntegers,
     Capability::kAllow16BitIntegers,
 };
diff --git a/src/tint/lang/core/ir/transform/propagate_buffer_sizes.h b/src/tint/lang/core/ir/transform/propagate_buffer_sizes.h
index 51ca161..6e65a7c 100644
--- a/src/tint/lang/core/ir/transform/propagate_buffer_sizes.h
+++ b/src/tint/lang/core/ir/transform/propagate_buffer_sizes.h
@@ -40,7 +40,6 @@
 
 /// The capabilities that the transform can support.
 const Capabilities kPropagateBufferSizesCapabilities{
-    Capability::kAllowDuplicateBindings,
     Capability::kAllow8BitIntegers,
     Capability::kAllow16BitIntegers,
 };
diff --git a/src/tint/lang/core/ir/transform/remove_continue_in_switch.cc b/src/tint/lang/core/ir/transform/remove_continue_in_switch.cc
index 66561f5..8456121 100644
--- a/src/tint/lang/core/ir/transform/remove_continue_in_switch.cc
+++ b/src/tint/lang/core/ir/transform/remove_continue_in_switch.cc
@@ -127,7 +127,6 @@
                               core::ir::Capability::kAllowVectorElementPointer,
                               core::ir::Capability::kAllowHandleVarsWithoutBindings,
                               core::ir::Capability::kAllowClipDistancesOnF32ScalarAndVector,
-                              core::ir::Capability::kAllowDuplicateBindings,
                               core::ir::Capability::kAllowNonCoreTypes,
                           },
                           "before core.RemoveContinueInSwitch");
diff --git a/src/tint/lang/core/ir/transform/remove_terminator_args.h b/src/tint/lang/core/ir/transform/remove_terminator_args.h
index 0970248..36ea888 100644
--- a/src/tint/lang/core/ir/transform/remove_terminator_args.h
+++ b/src/tint/lang/core/ir/transform/remove_terminator_args.h
@@ -50,7 +50,6 @@
     core::ir::Capability::kAllowAnyLetType,
     core::ir::Capability::kAllowModuleScopeLets,
     core::ir::Capability::kMslAllowEntryPointInterface,
-    core::ir::Capability::kAllowDuplicateBindings,
     core::ir::Capability::kAllowNonCoreTypes,
     core::ir::Capability::kLoosenValidationForShaderIO,
 };
diff --git a/src/tint/lang/core/ir/transform/remove_uniform_vector_component_loads.cc b/src/tint/lang/core/ir/transform/remove_uniform_vector_component_loads.cc
index ad1c654..e66b6f0 100644
--- a/src/tint/lang/core/ir/transform/remove_uniform_vector_component_loads.cc
+++ b/src/tint/lang/core/ir/transform/remove_uniform_vector_component_loads.cc
@@ -80,7 +80,6 @@
 Result<SuccessType> RemoveUniformVectorComponentLoads(core::ir::Module& ir) {
     core::ir::AssertValid(ir,
                           core::ir::Capabilities{
-                              core::ir::Capability::kAllowDuplicateBindings,
                               core::ir::Capability::kAllowNonCoreTypes,
                               core::ir::Capability::kAllow8BitIntegers,
                               core::ir::Capability::kAllow16BitIntegers,
diff --git a/src/tint/lang/core/ir/transform/rename_conflicts.h b/src/tint/lang/core/ir/transform/rename_conflicts.h
index df8101e..4debd7e 100644
--- a/src/tint/lang/core/ir/transform/rename_conflicts.h
+++ b/src/tint/lang/core/ir/transform/rename_conflicts.h
@@ -50,7 +50,6 @@
     core::ir::Capability::kAllowAnyLetType,
     core::ir::Capability::kAllowModuleScopeLets,
     core::ir::Capability::kMslAllowEntryPointInterface,
-    core::ir::Capability::kAllowDuplicateBindings,
     core::ir::Capability::kAllowNonCoreTypes,
     core::ir::Capability::kLoosenValidationForShaderIO,
 };
diff --git a/src/tint/lang/core/ir/transform/resource_table.cc b/src/tint/lang/core/ir/transform/resource_table.cc
index 01e4175..c3d4fbe 100644
--- a/src/tint/lang/core/ir/transform/resource_table.cc
+++ b/src/tint/lang/core/ir/transform/resource_table.cc
@@ -632,7 +632,6 @@
                                   ResourceTableHelper* helper) {
     AssertValid(ir,
                 core::ir::Capabilities{
-                    core::ir::Capability::kAllowDuplicateBindings,
                     core::ir::Capability::kAllow8BitIntegers,
                     core::ir::Capability::kAllow16BitIntegers,
                 },
diff --git a/src/tint/lang/core/ir/transform/robustness.h b/src/tint/lang/core/ir/transform/robustness.h
index 49b8176..42fb787 100644
--- a/src/tint/lang/core/ir/transform/robustness.h
+++ b/src/tint/lang/core/ir/transform/robustness.h
@@ -44,7 +44,6 @@
 
 /// The capabilities that the transform can support.
 const Capabilities kRobustnessCapabilities{
-    Capability::kAllowDuplicateBindings,
     Capability::kAllow8BitIntegers,
     Capability::kAllow16BitIntegers,
 };
diff --git a/src/tint/lang/core/ir/transform/signed_integer_polyfill.cc b/src/tint/lang/core/ir/transform/signed_integer_polyfill.cc
index bfc9d74..dbb4e67 100644
--- a/src/tint/lang/core/ir/transform/signed_integer_polyfill.cc
+++ b/src/tint/lang/core/ir/transform/signed_integer_polyfill.cc
@@ -147,7 +147,6 @@
                                           const SignedIntegerPolyfillConfig& cfg) {
     AssertValid(ir,
                 core::ir::Capabilities{
-                    core::ir::Capability::kAllowDuplicateBindings,
                     core::ir::Capability::kAllow8BitIntegers,
                     core::ir::Capability::kAllow16BitIntegers,
                     core::ir::Capability::kAllow64BitIntegers,
diff --git a/src/tint/lang/core/ir/transform/std140.h b/src/tint/lang/core/ir/transform/std140.h
index 4063678..9d5d4d6 100644
--- a/src/tint/lang/core/ir/transform/std140.h
+++ b/src/tint/lang/core/ir/transform/std140.h
@@ -42,7 +42,6 @@
 const core::ir::Capabilities kStd140Capabilities{
     core::ir::Capability::kAllowHandleVarsWithoutBindings,
     core::ir::Capability::kAllowAnyInputAttachmentIndexType,
-    core::ir::Capability::kAllowDuplicateBindings,
     core::ir::Capability::kAllowNonCoreTypes,
     core::ir::Capability::kAllow8BitIntegers,
     core::ir::Capability::kLoosenValidationForShaderIO,
diff --git a/src/tint/lang/core/ir/transform/value_to_let.h b/src/tint/lang/core/ir/transform/value_to_let.h
index 6e017ef..09c76b5 100644
--- a/src/tint/lang/core/ir/transform/value_to_let.h
+++ b/src/tint/lang/core/ir/transform/value_to_let.h
@@ -52,7 +52,6 @@
     core::ir::Capability::kAllowAnyLetType,
     core::ir::Capability::kMslAllowEntryPointInterface,
     core::ir::Capability::kAllowModuleScopeLets,
-    core::ir::Capability::kAllowDuplicateBindings,
     core::ir::Capability::kAllowNonCoreTypes,
     core::ir::Capability::kLoosenValidationForShaderIO,
 };
diff --git a/src/tint/lang/core/ir/transform/vectorize_scalar_matrix_constructors.h b/src/tint/lang/core/ir/transform/vectorize_scalar_matrix_constructors.h
index ce2d5ec..ed73987 100644
--- a/src/tint/lang/core/ir/transform/vectorize_scalar_matrix_constructors.h
+++ b/src/tint/lang/core/ir/transform/vectorize_scalar_matrix_constructors.h
@@ -43,7 +43,6 @@
     core::ir::Capability::kAllowVectorElementPointer,
     core::ir::Capability::kAllowHandleVarsWithoutBindings,
     core::ir::Capability::kAllowClipDistancesOnF32ScalarAndVector,
-    core::ir::Capability::kAllowDuplicateBindings,
     core::ir::Capability::kAllowNonCoreTypes,
     core::ir::Capability::kAllow8BitIntegers,
     core::ir::Capability::kAllow16BitIntegers,
diff --git a/src/tint/lang/core/ir/transform/zero_init_workgroup_memory.h b/src/tint/lang/core/ir/transform/zero_init_workgroup_memory.h
index 33f2c0c..54fcc2a 100644
--- a/src/tint/lang/core/ir/transform/zero_init_workgroup_memory.h
+++ b/src/tint/lang/core/ir/transform/zero_init_workgroup_memory.h
@@ -40,8 +40,9 @@
 
 /// The capabilities that the transform can support.
 const Capabilities kZeroInitWorkgroupMemoryCapabilities{
-    Capability::kAllowDuplicateBindings,      Capability::kAllowNonCoreTypes,
-    Capability::kAllow8BitIntegers,           Capability::kAllow16BitIntegers,
+    Capability::kAllowNonCoreTypes,
+    Capability::kAllow8BitIntegers,
+    Capability::kAllow16BitIntegers,
     Capability::kMslAllowEntryPointInterface,
 };
 
diff --git a/src/tint/lang/core/ir/validator.cc b/src/tint/lang/core/ir/validator.cc
index 446d4a6..41f7b9a 100644
--- a/src/tint/lang/core/ir/validator.cc
+++ b/src/tint/lang/core/ir/validator.cc
@@ -2841,7 +2841,7 @@
         const Var* user_declared_immediate = nullptr;
 
         for (auto var : referenced_module_vars_.TransitiveReferences(func)) {
-            if (!capabilities_.Contains(Capability::kAllowDuplicateBindings) &&
+            if (!mod_.properties.Contains(Property::kAllowDuplicateBindings) &&
                 var->BindingPoint().has_value()) {
                 auto bp = var->BindingPoint().value();
                 if (!binding_points.Add(bp)) {
diff --git a/src/tint/lang/core/ir/validator.h b/src/tint/lang/core/ir/validator.h
index 794d29e..43eb5c5 100644
--- a/src/tint/lang/core/ir/validator.h
+++ b/src/tint/lang/core/ir/validator.h
@@ -60,9 +60,6 @@
     /// Allows input_attachment_index to be associated with any type, used by
     /// SPIRV backend for spirv.image.
     kAllowAnyInputAttachmentIndexType,
-    /// Allows binding points to be non-unique. Used after BindingRemapper is
-    /// invoked by MSL & GLSL backends.
-    kAllowDuplicateBindings,
     /// Allows module scope `var`s to exist without an IO annotation
     kAllowUnannotatedModuleIOVariables,
     /// Allows non-core types in the IR module
diff --git a/src/tint/lang/core/ir/validator_value_test.cc b/src/tint/lang/core/ir/validator_value_test.cc
index bb3f003..e32756e 100644
--- a/src/tint/lang/core/ir/validator_value_test.cc
+++ b/src/tint/lang/core/ir/validator_value_test.cc
@@ -743,7 +743,9 @@
 )")) << res.Failure();
 }
 
-TEST_F(IR_ValidatorTest, Var_DuplicateBindingPoints_CapabilityOverride) {
+TEST_F(IR_ValidatorTest, Var_DuplicateBindingPoints_WithProperty) {
+    mod.properties.Add(Property::kAllowDuplicateBindings);
+
     auto* var_a = b.Var<uniform, f32>();
     var_a->SetBindingPoint(1, 2);
     mod.root_block->Append(var_a);
@@ -759,7 +761,7 @@
         b.Return(f);
     });
 
-    auto res = ir::Validate(mod, Capabilities{Capability::kAllowDuplicateBindings});
+    auto res = ir::Validate(mod);
     ASSERT_EQ(res, Success);
 }
 
diff --git a/src/tint/lang/glsl/writer/printer/printer.h b/src/tint/lang/glsl/writer/printer/printer.h
index 90b617b..6b73ad3 100644
--- a/src/tint/lang/glsl/writer/printer/printer.h
+++ b/src/tint/lang/glsl/writer/printer/printer.h
@@ -45,7 +45,6 @@
 // The capabilities that might be needed due to raising.
 const core::ir::Capabilities kPrinterCapabilities{
     core::ir::Capability::kAllowHandleVarsWithoutBindings,
-    core::ir::Capability::kAllowDuplicateBindings,
     core::ir::Capability::kLoosenValidationForShaderIO,
     core::ir::Capability::kAllow16BitIntegers,
 };
diff --git a/src/tint/lang/glsl/writer/raise/binary_polyfill.cc b/src/tint/lang/glsl/writer/raise/binary_polyfill.cc
index ddd67af..1dbec60 100644
--- a/src/tint/lang/glsl/writer/raise/binary_polyfill.cc
+++ b/src/tint/lang/glsl/writer/raise/binary_polyfill.cc
@@ -216,9 +216,7 @@
 }  // namespace
 
 Result<SuccessType> BinaryPolyfill(core::ir::Module& ir) {
-    core::ir::AssertValid(ir,
-                          core::ir::Capabilities{core::ir::Capability::kAllowDuplicateBindings,
-                                                 core::ir::Capability::kAllow16BitIntegers},
+    core::ir::AssertValid(ir, core::ir::Capabilities{core::ir::Capability::kAllow16BitIntegers},
                           "before glsl.BinaryPolyfill");
 
     State{ir}.Process();
diff --git a/src/tint/lang/glsl/writer/raise/bitcast_polyfill.cc b/src/tint/lang/glsl/writer/raise/bitcast_polyfill.cc
index 0ad0d7d..db168ab 100644
--- a/src/tint/lang/glsl/writer/raise/bitcast_polyfill.cc
+++ b/src/tint/lang/glsl/writer/raise/bitcast_polyfill.cc
@@ -315,7 +315,6 @@
 Result<SuccessType> BitcastPolyfill(core::ir::Module& ir) {
     AssertValid(ir,
                 core::ir::Capabilities{core::ir::Capability::kAllowHandleVarsWithoutBindings,
-                                       core::ir::Capability::kAllowDuplicateBindings,
                                        core::ir::Capability::kLoosenValidationForShaderIO,
                                        core::ir::Capability::kAllow16BitIntegers},
                 "before glsl.BitcastPolyfill");
diff --git a/src/tint/lang/glsl/writer/raise/builtin_polyfill.cc b/src/tint/lang/glsl/writer/raise/builtin_polyfill.cc
index 7eccf41..85d54e2 100644
--- a/src/tint/lang/glsl/writer/raise/builtin_polyfill.cc
+++ b/src/tint/lang/glsl/writer/raise/builtin_polyfill.cc
@@ -518,9 +518,7 @@
 }  // namespace
 
 Result<SuccessType> BuiltinPolyfill(core::ir::Module& ir) {
-    AssertValid(ir,
-                core::ir::Capabilities{core::ir::Capability::kAllowDuplicateBindings,
-                                       core::ir::Capability::kAllow16BitIntegers},
+    AssertValid(ir, core::ir::Capabilities{core::ir::Capability::kAllow16BitIntegers},
                 "before glsl.BuiltinPolyfill");
 
     State{ir}.Process();
diff --git a/src/tint/lang/glsl/writer/raise/offset_first_index.cc b/src/tint/lang/glsl/writer/raise/offset_first_index.cc
index dde88c2..c019694 100644
--- a/src/tint/lang/glsl/writer/raise/offset_first_index.cc
+++ b/src/tint/lang/glsl/writer/raise/offset_first_index.cc
@@ -115,7 +115,6 @@
     AssertValid(ir,
                 core::ir::Capabilities{
                     core::ir::Capability::kAllowHandleVarsWithoutBindings,
-                    core::ir::Capability::kAllowDuplicateBindings,
                     core::ir::Capability::kLoosenValidationForShaderIO,
                     core::ir::Capability::kAllow16BitIntegers,
                 },
diff --git a/src/tint/lang/glsl/writer/raise/raise.cc b/src/tint/lang/glsl/writer/raise/raise.cc
index 405134e..b12e7c3 100644
--- a/src/tint/lang/glsl/writer/raise/raise.cc
+++ b/src/tint/lang/glsl/writer/raise/raise.cc
@@ -115,7 +115,7 @@
     RemapperData remapper_data{};
     PopulateBindingInfo(options, remapper_data, multiplanar_map);
     TINT_CHECK_RESULT(core::ir::transform::BindingRemapper(module, remapper_data));
-    // Capability::kAllowDuplicateBindings needed after BindingRemapper
+
     {
         core::ir::transform::BinaryPolyfillConfig binary_polyfills{};
         binary_polyfills.int_div_mod = !options.disable_polyfill_integer_div_mod;
diff --git a/src/tint/lang/glsl/writer/raise/shader_io.cc b/src/tint/lang/glsl/writer/raise/shader_io.cc
index 4950c9a..93eb5b8d 100644
--- a/src/tint/lang/glsl/writer/raise/shader_io.cc
+++ b/src/tint/lang/glsl/writer/raise/shader_io.cc
@@ -313,7 +313,6 @@
 Result<SuccessType> ShaderIO(core::ir::Module& ir, const ShaderIOConfig& config) {
     AssertValid(ir,
                 core::ir::Capabilities{core::ir::Capability::kAllowHandleVarsWithoutBindings,
-                                       core::ir::Capability::kAllowDuplicateBindings,
                                        core::ir::Capability::kAllow16BitIntegers},
                 "before glsl.ShaderIO");
 
diff --git a/src/tint/lang/glsl/writer/raise/texture_builtins_from_uniform.h b/src/tint/lang/glsl/writer/raise/texture_builtins_from_uniform.h
index ffdbfe58..8fcb887c 100644
--- a/src/tint/lang/glsl/writer/raise/texture_builtins_from_uniform.h
+++ b/src/tint/lang/glsl/writer/raise/texture_builtins_from_uniform.h
@@ -41,7 +41,7 @@
 
 /// The capabilities that the transform can support.
 const core::ir::Capabilities kTextureBuiltinFromUniformCapabilities{
-    core::ir::Capability::kAllowDuplicateBindings, core::ir::Capability::kAllow16BitIntegers};
+    core::ir::Capability::kAllow16BitIntegers};
 
 /// TextureBuiltinsFromUniform is a transform that replaces texture builtin function
 /// `textureNumLevels` and `textureNumSamples` which do not have GLSL equivalents with
diff --git a/src/tint/lang/glsl/writer/raise/texture_polyfill.cc b/src/tint/lang/glsl/writer/raise/texture_polyfill.cc
index b601257..eb1cf49 100644
--- a/src/tint/lang/glsl/writer/raise/texture_polyfill.cc
+++ b/src/tint/lang/glsl/writer/raise/texture_polyfill.cc
@@ -1264,13 +1264,13 @@
 }  // namespace
 
 Result<SuccessType> TexturePolyfill(core::ir::Module& ir, const TexturePolyfillConfig& cfg) {
-    AssertValid(ir,
-                core::ir::Capabilities{core::ir::Capability::kAllowDuplicateBindings,
-                                       core::ir::Capability::kAllow16BitIntegers},
+    AssertValid(ir, core::ir::Capabilities{core::ir::Capability::kAllow16BitIntegers},
                 "before glsl.TexturePolyfill");
 
     State{ir, cfg}.Process();
 
+    ir.properties.Add(core::ir::Property::kAllowDuplicateBindings);
+
     return Success;
 }
 
diff --git a/src/tint/lang/glsl/writer/raise/texture_polyfill_test.cc b/src/tint/lang/glsl/writer/raise/texture_polyfill_test.cc
index b357776..225efc4 100644
--- a/src/tint/lang/glsl/writer/raise/texture_polyfill_test.cc
+++ b/src/tint/lang/glsl/writer/raise/texture_polyfill_test.cc
@@ -6003,8 +6003,6 @@
 }
 )";
 
-    capabilities = core::ir::Capabilities{core::ir::Capability::kAllowDuplicateBindings};
-
     TexturePolyfillConfig cfg;
     cfg.placeholder_sampler_bind_point = {4, 0};
     Run(TexturePolyfill, cfg);
diff --git a/src/tint/lang/hlsl/writer/printer/printer.h b/src/tint/lang/hlsl/writer/printer/printer.h
index ded4e37..06873ee 100644
--- a/src/tint/lang/hlsl/writer/printer/printer.h
+++ b/src/tint/lang/hlsl/writer/printer/printer.h
@@ -47,7 +47,6 @@
     core::ir::Capability::kAllowModuleScopeLets,
     core::ir::Capability::kAllowVectorElementPointer,
     core::ir::Capability::kAllowClipDistancesOnF32ScalarAndVector,
-    core::ir::Capability::kAllowDuplicateBindings,
     core::ir::Capability::kAllowNonCoreTypes,
 };
 
diff --git a/src/tint/lang/hlsl/writer/raise/array_offset_from_immediate.h b/src/tint/lang/hlsl/writer/raise/array_offset_from_immediate.h
index 77a4044..44e8bdf 100644
--- a/src/tint/lang/hlsl/writer/raise/array_offset_from_immediate.h
+++ b/src/tint/lang/hlsl/writer/raise/array_offset_from_immediate.h
@@ -49,7 +49,6 @@
     core::ir::Capability::kAllow8BitIntegers,
     core::ir::Capability::kAllow16BitIntegers,
     core::ir::Capability::kAllowClipDistancesOnF32ScalarAndVector,
-    core::ir::Capability::kAllowDuplicateBindings,
     core::ir::Capability::kAllowNonCoreTypes,
 };
 
diff --git a/src/tint/lang/hlsl/writer/raise/array_offset_from_uniform.h b/src/tint/lang/hlsl/writer/raise/array_offset_from_uniform.h
index 9e8dd09..5f3d015 100644
--- a/src/tint/lang/hlsl/writer/raise/array_offset_from_uniform.h
+++ b/src/tint/lang/hlsl/writer/raise/array_offset_from_uniform.h
@@ -46,7 +46,6 @@
     core::ir::Capability::kAllow8BitIntegers,
     core::ir::Capability::kAllow16BitIntegers,
     core::ir::Capability::kAllowClipDistancesOnF32ScalarAndVector,
-    core::ir::Capability::kAllowDuplicateBindings,
     core::ir::Capability::kAllowNonCoreTypes,
 };
 
diff --git a/src/tint/lang/hlsl/writer/raise/binary_polyfill.cc b/src/tint/lang/hlsl/writer/raise/binary_polyfill.cc
index 713b97f..a2ebc43 100644
--- a/src/tint/lang/hlsl/writer/raise/binary_polyfill.cc
+++ b/src/tint/lang/hlsl/writer/raise/binary_polyfill.cc
@@ -142,7 +142,6 @@
                     core::ir::Capability::kAllow8BitIntegers,
                     core::ir::Capability::kAllow16BitIntegers,
                     core::ir::Capability::kAllowClipDistancesOnF32ScalarAndVector,
-                    core::ir::Capability::kAllowDuplicateBindings,
                     core::ir::Capability::kAllowNonCoreTypes,
                 },
                 "before hlsl.BinaryPolyfill");
diff --git a/src/tint/lang/hlsl/writer/raise/builtin_polyfill.cc b/src/tint/lang/hlsl/writer/raise/builtin_polyfill.cc
index e79158c..86139c4 100644
--- a/src/tint/lang/hlsl/writer/raise/builtin_polyfill.cc
+++ b/src/tint/lang/hlsl/writer/raise/builtin_polyfill.cc
@@ -2152,7 +2152,6 @@
                     core::ir::Capability::kAllow8BitIntegers,
                     core::ir::Capability::kAllow16BitIntegers,
                     core::ir::Capability::kAllowClipDistancesOnF32ScalarAndVector,
-                    core::ir::Capability::kAllowDuplicateBindings,
                     core::ir::Capability::kAllowNonCoreTypes,
                 },
                 "before hlsl.BuiltinPolyfill");
diff --git a/src/tint/lang/hlsl/writer/raise/decompose_storage_access.cc b/src/tint/lang/hlsl/writer/raise/decompose_storage_access.cc
index 7f4f298..db8130f 100644
--- a/src/tint/lang/hlsl/writer/raise/decompose_storage_access.cc
+++ b/src/tint/lang/hlsl/writer/raise/decompose_storage_access.cc
@@ -1039,7 +1039,6 @@
                               core::ir::Capability::kAllow8BitIntegers,
                               core::ir::Capability::kAllow16BitIntegers,
                               core::ir::Capability::kAllowClipDistancesOnF32ScalarAndVector,
-                              core::ir::Capability::kAllowDuplicateBindings,
                           },
                           "before hlsl.DecomposeStorageAccess");
 
diff --git a/src/tint/lang/hlsl/writer/raise/extract_ternary_values.h b/src/tint/lang/hlsl/writer/raise/extract_ternary_values.h
index 89e7a5e..1ea22fe 100644
--- a/src/tint/lang/hlsl/writer/raise/extract_ternary_values.h
+++ b/src/tint/lang/hlsl/writer/raise/extract_ternary_values.h
@@ -45,7 +45,6 @@
     core::ir::Capability::kAllowVectorElementPointer,
     core::ir::Capability::kAllowHandleVarsWithoutBindings,
     core::ir::Capability::kAllowClipDistancesOnF32ScalarAndVector,
-    core::ir::Capability::kAllowDuplicateBindings,
     core::ir::Capability::kAllowNonCoreTypes,
 };
 
diff --git a/src/tint/lang/hlsl/writer/raise/localize_struct_array_assignment.cc b/src/tint/lang/hlsl/writer/raise/localize_struct_array_assignment.cc
index 91e736e..ce6d30c 100644
--- a/src/tint/lang/hlsl/writer/raise/localize_struct_array_assignment.cc
+++ b/src/tint/lang/hlsl/writer/raise/localize_struct_array_assignment.cc
@@ -157,8 +157,7 @@
 }  // namespace
 
 Result<SuccessType> LocalizeStructArrayAssignment(core::ir::Module& ir) {
-    AssertValid(ir, core::ir::Capabilities{core::ir::Capability::kAllowDuplicateBindings},
-                "before hlsl.LocalizeStructArrayAssignment");
+    AssertValid(ir, "before hlsl.LocalizeStructArrayAssignment");
 
     State{ir}.Process();
 
diff --git a/src/tint/lang/hlsl/writer/raise/pixel_local.cc b/src/tint/lang/hlsl/writer/raise/pixel_local.cc
index 8527cbc..a269cd1 100644
--- a/src/tint/lang/hlsl/writer/raise/pixel_local.cc
+++ b/src/tint/lang/hlsl/writer/raise/pixel_local.cc
@@ -246,7 +246,6 @@
                           core::ir::Capabilities{
                               core::ir::Capability::kAllow16BitIntegers,
                               core::ir::Capability::kAllowClipDistancesOnF32ScalarAndVector,
-                              core::ir::Capability::kAllowDuplicateBindings,
                               core::ir::Capability::kAllowNonCoreTypes,
                           },
                           "before hlsl.PixelLocal");
diff --git a/src/tint/lang/hlsl/writer/raise/promote_initializers.h b/src/tint/lang/hlsl/writer/raise/promote_initializers.h
index 894798a..a3a99fa 100644
--- a/src/tint/lang/hlsl/writer/raise/promote_initializers.h
+++ b/src/tint/lang/hlsl/writer/raise/promote_initializers.h
@@ -44,7 +44,6 @@
     core::ir::Capability::kAllow16BitIntegers,
     core::ir::Capability::kAllowVectorElementPointer,
     core::ir::Capability::kAllowClipDistancesOnF32ScalarAndVector,
-    core::ir::Capability::kAllowDuplicateBindings,
     core::ir::Capability::kAllowNonCoreTypes,
 };
 
diff --git a/src/tint/lang/hlsl/writer/raise/replace_default_only_switch.cc b/src/tint/lang/hlsl/writer/raise/replace_default_only_switch.cc
index d598242..12c4245 100644
--- a/src/tint/lang/hlsl/writer/raise/replace_default_only_switch.cc
+++ b/src/tint/lang/hlsl/writer/raise/replace_default_only_switch.cc
@@ -97,8 +97,7 @@
 }  // namespace
 
 Result<SuccessType> ReplaceDefaultOnlySwitch(core::ir::Module& ir) {
-    AssertValid(ir, core::ir::Capabilities{core::ir::Capability::kAllowDuplicateBindings},
-                "before hlsl.ReplaceDefaultOnlySwitch");
+    AssertValid(ir, "before hlsl.ReplaceDefaultOnlySwitch");
 
     State{ir}.Process();
 
diff --git a/src/tint/lang/hlsl/writer/raise/replace_non_indexable_mat_vec_stores.cc b/src/tint/lang/hlsl/writer/raise/replace_non_indexable_mat_vec_stores.cc
index 4d8d16a..e524f47 100644
--- a/src/tint/lang/hlsl/writer/raise/replace_non_indexable_mat_vec_stores.cc
+++ b/src/tint/lang/hlsl/writer/raise/replace_non_indexable_mat_vec_stores.cc
@@ -295,8 +295,7 @@
 }  // namespace
 
 Result<SuccessType> ReplaceNonIndexableMatVecStores(core::ir::Module& ir) {
-    core::ir::AssertValid(ir, core::ir::Capabilities{core::ir::Capability::kAllowDuplicateBindings},
-                          "before hlsl.ReplaceNonIndexableMatVecStores");
+    core::ir::AssertValid(ir, "before hlsl.ReplaceNonIndexableMatVecStores");
 
     State{ir}.Process();
 
diff --git a/src/tint/lang/hlsl/writer/raise/replace_subgroup_matrix_init.cc b/src/tint/lang/hlsl/writer/raise/replace_subgroup_matrix_init.cc
index 283f9da..b46e896 100644
--- a/src/tint/lang/hlsl/writer/raise/replace_subgroup_matrix_init.cc
+++ b/src/tint/lang/hlsl/writer/raise/replace_subgroup_matrix_init.cc
@@ -179,7 +179,6 @@
                     core::ir::Capability::kAllowVectorElementPointer,
                     core::ir::Capability::kAllowHandleVarsWithoutBindings,
                     core::ir::Capability::kAllowClipDistancesOnF32ScalarAndVector,
-                    core::ir::Capability::kAllowDuplicateBindings,
                     core::ir::Capability::kAllowNonCoreTypes,
                 },
                 "before hlsl.ReplaceSubgroupMatrixInit");
diff --git a/src/tint/lang/hlsl/writer/raise/shader_io.cc b/src/tint/lang/hlsl/writer/raise/shader_io.cc
index 9ac49f8..74eeb67 100644
--- a/src/tint/lang/hlsl/writer/raise/shader_io.cc
+++ b/src/tint/lang/hlsl/writer/raise/shader_io.cc
@@ -763,8 +763,7 @@
 
 Result<SuccessType> ShaderIO(core::ir::Module& ir, const ShaderIOConfig& config) {
     core::ir::AssertValid(ir,
-                          core::ir::Capabilities{core::ir::Capability::kAllowDuplicateBindings,
-                                                 core::ir::Capability::kAllow8BitIntegers,
+                          core::ir::Capabilities{core::ir::Capability::kAllow8BitIntegers,
                                                  core::ir::Capability::kAllow16BitIntegers},
                           "before hlsl.ShaderIO");
 
diff --git a/src/tint/lang/msl/writer/raise/argument_buffers.cc b/src/tint/lang/msl/writer/raise/argument_buffers.cc
index 6393ef3..6da0b11 100644
--- a/src/tint/lang/msl/writer/raise/argument_buffers.cc
+++ b/src/tint/lang/msl/writer/raise/argument_buffers.cc
@@ -395,7 +395,6 @@
     AssertValid(ir,
                 tint::core::ir::Capabilities{
                     tint::core::ir::Capability::kAllowPointSizeBuiltin,
-                    tint::core::ir::Capability::kAllowDuplicateBindings,
                 },
                 "before msl.ArgumentBuffers");
 
diff --git a/src/tint/lang/msl/writer/raise/convert_print_to_log.cc b/src/tint/lang/msl/writer/raise/convert_print_to_log.cc
index b81d80f..a6515d7 100644
--- a/src/tint/lang/msl/writer/raise/convert_print_to_log.cc
+++ b/src/tint/lang/msl/writer/raise/convert_print_to_log.cc
@@ -252,7 +252,6 @@
 Result<SuccessType> ConvertPrintToLog(core::ir::Module& ir) {
     AssertValid(ir,
                 core::ir::Capabilities{
-                    core::ir::Capability::kAllowDuplicateBindings,
                     core::ir::Capability::kAllow8BitIntegers,
                 },
                 "before msl.ConvertPrintToLog");
diff --git a/src/tint/lang/msl/writer/raise/decompose_buffer.cc b/src/tint/lang/msl/writer/raise/decompose_buffer.cc
index 1c36a3f..08c9770 100644
--- a/src/tint/lang/msl/writer/raise/decompose_buffer.cc
+++ b/src/tint/lang/msl/writer/raise/decompose_buffer.cc
@@ -228,7 +228,6 @@
     AssertValid(ir,
                 tint::core::ir::Capabilities{
                     tint::core::ir::Capability::kAllowPointSizeBuiltin,
-                    tint::core::ir::Capability::kAllowDuplicateBindings,
                 },
                 "before msl.DecomposeBuffer");
 
diff --git a/src/tint/lang/msl/writer/raise/fix_type_layout.cc b/src/tint/lang/msl/writer/raise/fix_type_layout.cc
index 5f17aaf..53418e2 100644
--- a/src/tint/lang/msl/writer/raise/fix_type_layout.cc
+++ b/src/tint/lang/msl/writer/raise/fix_type_layout.cc
@@ -762,7 +762,6 @@
                 tint::core::ir::Capabilities{
                     core::ir::Capability::kAllow8BitIntegers,
                     tint::core::ir::Capability::kAllowPointSizeBuiltin,
-                    tint::core::ir::Capability::kAllowDuplicateBindings,
                     core::ir::Capability::kAllowNonCoreTypes,
                 },
                 "before msl.FixTypeLayout");
diff --git a/src/tint/lang/msl/writer/raise/module_scope_vars.cc b/src/tint/lang/msl/writer/raise/module_scope_vars.cc
index 238d7d0..4f2fac2 100644
--- a/src/tint/lang/msl/writer/raise/module_scope_vars.cc
+++ b/src/tint/lang/msl/writer/raise/module_scope_vars.cc
@@ -346,7 +346,6 @@
                     core::ir::Capability::kAllow8BitIntegers,
                     core::ir::Capability::kAllowPointSizeBuiltin,
                     core::ir::Capability::kMslAllowEntryPointInterface,
-                    core::ir::Capability::kAllowDuplicateBindings,
                     core::ir::Capability::kAllowNonCoreTypes,
                 },
                 "before msl.ModuleScopeVars");
diff --git a/src/tint/lang/msl/writer/raise/shader_io.cc b/src/tint/lang/msl/writer/raise/shader_io.cc
index fbca6fd..c40e807 100644
--- a/src/tint/lang/msl/writer/raise/shader_io.cc
+++ b/src/tint/lang/msl/writer/raise/shader_io.cc
@@ -344,7 +344,6 @@
     AssertValid(ir,
                 tint::core::ir::Capabilities{
                     core::ir::Capability::kAllow8BitIntegers,
-                    core::ir::Capability::kAllowDuplicateBindings,
                     core::ir::Capability::kAllowNonCoreTypes,
                 },
                 "before msl.ShaderIO");
diff --git a/src/tint/lang/msl/writer/raise/simd_ballot.cc b/src/tint/lang/msl/writer/raise/simd_ballot.cc
index 88f3ffb..cd321a1 100644
--- a/src/tint/lang/msl/writer/raise/simd_ballot.cc
+++ b/src/tint/lang/msl/writer/raise/simd_ballot.cc
@@ -160,7 +160,6 @@
                 tint::core::ir::Capabilities{
                     core::ir::Capability::kAllow8BitIntegers,
                     core::ir::Capability::kAllowPointSizeBuiltin,
-                    core::ir::Capability::kAllowDuplicateBindings,
                     core::ir::Capability::kAllowNonCoreTypes,
                 },
                 "before msl.SimdBallot");
diff --git a/src/tint/lang/spirv/writer/printer/printer.h b/src/tint/lang/spirv/writer/printer/printer.h
index 0922e3e..6c39d66 100644
--- a/src/tint/lang/spirv/writer/printer/printer.h
+++ b/src/tint/lang/spirv/writer/printer/printer.h
@@ -42,7 +42,6 @@
 
 // The capabilities that might be needed due to raising.
 const core::ir::Capabilities kPrinterCapabilities{
-    core::ir::Capability::kAllowDuplicateBindings,
     core::ir::Capability::kAllowAnyInputAttachmentIndexType,
     core::ir::Capability::kAllowNonCoreTypes,
     core::ir::Capability::kAllow8BitIntegers,
diff --git a/src/tint/lang/spirv/writer/raise/builtin_polyfill.cc b/src/tint/lang/spirv/writer/raise/builtin_polyfill.cc
index e5110b9..6bcf294 100644
--- a/src/tint/lang/spirv/writer/raise/builtin_polyfill.cc
+++ b/src/tint/lang/spirv/writer/raise/builtin_polyfill.cc
@@ -1497,7 +1497,6 @@
     AssertValid(ir,
                 core::ir::Capabilities{
                     core::ir::Capability::kAllow8BitIntegers,
-                    core::ir::Capability::kAllowDuplicateBindings,
                     core::ir::Capability::kAllowNonCoreTypes,
                 },
                 "before spirv.BuiltinPolyfill");
diff --git a/src/tint/lang/spirv/writer/raise/case_switch_to_if_else.cc b/src/tint/lang/spirv/writer/raise/case_switch_to_if_else.cc
index 9017693..37e6f8b 100644
--- a/src/tint/lang/spirv/writer/raise/case_switch_to_if_else.cc
+++ b/src/tint/lang/spirv/writer/raise/case_switch_to_if_else.cc
@@ -47,7 +47,6 @@
 namespace {
 
 const core::ir::Capabilities kCaseSwitchToIfElseCapabilities{
-    core::ir::Capability::kAllowDuplicateBindings,
     core::ir::Capability::kAllowAnyInputAttachmentIndexType,
     core::ir::Capability::kAllowNonCoreTypes,
 };
diff --git a/src/tint/lang/spirv/writer/raise/expand_implicit_splats.h b/src/tint/lang/spirv/writer/raise/expand_implicit_splats.h
index 6cafd5e..4093fc6 100644
--- a/src/tint/lang/spirv/writer/raise/expand_implicit_splats.h
+++ b/src/tint/lang/spirv/writer/raise/expand_implicit_splats.h
@@ -41,7 +41,6 @@
 
 /// The capabilities that the transform can support.
 const core::ir::Capabilities kExpandImplicitSplatsCapabilities{
-    core::ir::Capability::kAllowDuplicateBindings,
     core::ir::Capability::kAllowAnyInputAttachmentIndexType,
     core::ir::Capability::kAllowNonCoreTypes,
     core::ir::Capability::kAllow8BitIntegers,
diff --git a/src/tint/lang/spirv/writer/raise/fork_explicit_layout_types.h b/src/tint/lang/spirv/writer/raise/fork_explicit_layout_types.h
index 0b2ff8a..0350399 100644
--- a/src/tint/lang/spirv/writer/raise/fork_explicit_layout_types.h
+++ b/src/tint/lang/spirv/writer/raise/fork_explicit_layout_types.h
@@ -43,7 +43,6 @@
 
 /// The capabilities that the transform can support.
 const core::ir::Capabilities kForkExplicitLayoutTypesCapabilities{
-    core::ir::Capability::kAllowDuplicateBindings,
     core::ir::Capability::kAllowAnyInputAttachmentIndexType,
     core::ir::Capability::kAllowNonCoreTypes,
     core::ir::Capability::kAllow8BitIntegers,
diff --git a/src/tint/lang/spirv/writer/raise/handle_matrix_arithmetic.h b/src/tint/lang/spirv/writer/raise/handle_matrix_arithmetic.h
index 5ac41d8..c1bf5fb 100644
--- a/src/tint/lang/spirv/writer/raise/handle_matrix_arithmetic.h
+++ b/src/tint/lang/spirv/writer/raise/handle_matrix_arithmetic.h
@@ -40,7 +40,6 @@
 
 // The capabilities that the transform can support.
 const core::ir::Capabilities kHandleMatrixArithmeticCapabilities{
-    core::ir::Capability::kAllowDuplicateBindings,
     core::ir::Capability::kAllowAnyInputAttachmentIndexType,
     core::ir::Capability::kAllowNonCoreTypes,
     core::ir::Capability::kAllow8BitIntegers,
diff --git a/src/tint/lang/spirv/writer/raise/keep_binding_array_as_pointer.h b/src/tint/lang/spirv/writer/raise/keep_binding_array_as_pointer.h
index 03c6b8a..efc1b76 100644
--- a/src/tint/lang/spirv/writer/raise/keep_binding_array_as_pointer.h
+++ b/src/tint/lang/spirv/writer/raise/keep_binding_array_as_pointer.h
@@ -40,7 +40,6 @@
 
 // The capabilities that the transform can support.
 const core::ir::Capabilities kKeepBindingArrayAsPointerCapabilities{
-    core::ir::Capability::kAllowDuplicateBindings,
     core::ir::Capability::kAllowNonCoreTypes,
 };
 
diff --git a/src/tint/lang/spirv/writer/raise/merge_return.cc b/src/tint/lang/spirv/writer/raise/merge_return.cc
index 233d984..b1ed78b 100644
--- a/src/tint/lang/spirv/writer/raise/merge_return.cc
+++ b/src/tint/lang/spirv/writer/raise/merge_return.cc
@@ -42,7 +42,6 @@
 
 // The capabilities that the transform can support.
 const core::ir::Capabilities kMergeReturnCapabilities{
-    core::ir::Capability::kAllowDuplicateBindings,
     core::ir::Capability::kAllowAnyInputAttachmentIndexType,
     core::ir::Capability::kAllowNonCoreTypes,
     core::ir::Capability::kAllow8BitIntegers,
diff --git a/src/tint/lang/spirv/writer/raise/pass_matrix_by_pointer.cc b/src/tint/lang/spirv/writer/raise/pass_matrix_by_pointer.cc
index 96c9ace..301ce67 100644
--- a/src/tint/lang/spirv/writer/raise/pass_matrix_by_pointer.cc
+++ b/src/tint/lang/spirv/writer/raise/pass_matrix_by_pointer.cc
@@ -130,7 +130,6 @@
 Result<SuccessType> PassMatrixByPointer(core::ir::Module& ir) {
     core::ir::AssertValid(ir,
                           core::ir::Capabilities{
-                              core::ir::Capability::kAllowDuplicateBindings,
                               core::ir::Capability::kAllowNonCoreTypes,
                           },
                           "before spirv.PassMatrixByPointer");
diff --git a/src/tint/lang/spirv/writer/raise/remove_unreachable_in_loop_continuing.h b/src/tint/lang/spirv/writer/raise/remove_unreachable_in_loop_continuing.h
index 9728cac..951a0b0 100644
--- a/src/tint/lang/spirv/writer/raise/remove_unreachable_in_loop_continuing.h
+++ b/src/tint/lang/spirv/writer/raise/remove_unreachable_in_loop_continuing.h
@@ -40,7 +40,6 @@
 
 // The capabilities that the transform can support.
 const core::ir::Capabilities kRemoveUnreachableInLoopContinuingCapabilities{
-    core::ir::Capability::kAllowDuplicateBindings,
     core::ir::Capability::kAllowAnyInputAttachmentIndexType,
     core::ir::Capability::kAllowNonCoreTypes,
     core::ir::Capability::kAllow8BitIntegers,
diff --git a/src/tint/lang/spirv/writer/raise/shader_io.h b/src/tint/lang/spirv/writer/raise/shader_io.h
index 80f8758..37b9d41 100644
--- a/src/tint/lang/spirv/writer/raise/shader_io.h
+++ b/src/tint/lang/spirv/writer/raise/shader_io.h
@@ -44,7 +44,6 @@
 
 /// The capabilities that the transform can support.
 const core::ir::Capabilities kShaderIOCapabilities{
-    core::ir::Capability::kAllowDuplicateBindings,
     core::ir::Capability::kAllowAnyInputAttachmentIndexType,
     core::ir::Capability::kAllowNonCoreTypes,
     core::ir::Capability::kAllow8BitIntegers,
diff --git a/src/tint/lang/spirv/writer/raise/unary_polyfill.h b/src/tint/lang/spirv/writer/raise/unary_polyfill.h
index 9380c51..5400200 100644
--- a/src/tint/lang/spirv/writer/raise/unary_polyfill.h
+++ b/src/tint/lang/spirv/writer/raise/unary_polyfill.h
@@ -40,7 +40,6 @@
 
 // The capabilities that the transform can support.
 const core::ir::Capabilities kPolyfillUnaryCapabilities{
-    core::ir::Capability::kAllowDuplicateBindings,
     core::ir::Capability::kAllowAnyInputAttachmentIndexType,
     core::ir::Capability::kAllowNonCoreTypes,
     core::ir::Capability::kAllow8BitIntegers,
diff --git a/src/tint/lang/spirv/writer/raise/var_for_dynamic_index.h b/src/tint/lang/spirv/writer/raise/var_for_dynamic_index.h
index f7452f0..4ae5ce8 100644
--- a/src/tint/lang/spirv/writer/raise/var_for_dynamic_index.h
+++ b/src/tint/lang/spirv/writer/raise/var_for_dynamic_index.h
@@ -40,7 +40,6 @@
 
 /// The capabilities that the transform can support.
 const core::ir::Capabilities kVarForDynamicIndexCapabilities{
-    core::ir::Capability::kAllowDuplicateBindings,
     core::ir::Capability::kAllowAnyInputAttachmentIndexType,
     core::ir::Capability::kAllowNonCoreTypes,
     core::ir::Capability::kAllow8BitIntegers,