spirv-reader (AST): split combined image samplers
Add end-to-end reader tests using input SPIR-V from unit tests for the two
spirv-opt transforms. These are all expected to be readable now.
Update the dawn unit tests:
- a combined-image-sampler test now passes
- add an array-of-combined-image-sampler test that fails
Bug: 398231475
Change-Id: I3c906fb75b7eb66ecaa76d33d1d1e3b8246bf803
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/231534
Commit-Queue: dan sinclair <dsinclair@chromium.org>
Auto-Submit: David Neto <dneto@google.com>
Reviewed-by: dan sinclair <dsinclair@chromium.org>
diff --git a/src/dawn/tests/unittests/validation/ShaderModuleValidationTests.cpp b/src/dawn/tests/unittests/validation/ShaderModuleValidationTests.cpp
index 37bc486..8f8658b 100644
--- a/src/dawn/tests/unittests/validation/ShaderModuleValidationTests.cpp
+++ b/src/dawn/tests/unittests/validation/ShaderModuleValidationTests.cpp
@@ -73,7 +73,11 @@
utils::CreateShaderModuleFromASM(device, shader);
}
-// Test that it is not allowed to use combined texture and sampler.
+// Tint's SPIR-V reader transforms a combined image sampler into two
+// variables: an image part and a sampler part. The sampler part's binding
+// number is incremented. This may produce a conflict, which is solved
+// by iterating further binding increments. It's easy to use in simple cases:
+// a sampled image variable effectively takes up two binding slots.
TEST_F(ShaderModuleValidationTest, CombinedTextureAndSampler) {
// SPIR-V ASM produced by glslang for the following fragment shader:
//
@@ -111,6 +115,44 @@
OpFunctionEnd
)";
+ utils::CreateShaderModuleFromASM(device, shader);
+}
+
+TEST_F(ShaderModuleValidationTest, ArrayOfCombinedTextureAndSampler) {
+ // SPIR-V ASM produced by glslang for the following fragment shader:
+ //
+ // #version 450
+ // layout(set = 0, binding = 0) uniform sampler2D tex[2];
+ // void main () {}
+ //
+ // Dawn/WebGPU does not yet support arrays of sampled images.
+ const char* shader = R"(
+ OpCapability Shader
+ %1 = OpExtInstImport "GLSL.std.450"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %main "main"
+ OpExecutionMode %main OriginUpperLeft
+ OpSource GLSL 450
+ OpName %main "main"
+ OpName %tex "tex"
+ OpDecorate %tex Binding 0
+ OpDecorate %tex DescriptorSet 0
+ %void = OpTypeVoid
+ %3 = OpTypeFunction %void
+ %float = OpTypeFloat 32
+ %7 = OpTypeImage %float 2D 0 0 0 1 Unknown
+ %8 = OpTypeSampledImage %7
+ %uint = OpTypeInt 32 0
+ %uint_2 = OpConstant %uint 2
+%_arr_8_uint_2 = OpTypeArray %8 %uint_2
+%_ptr_UniformConstant__arr_8_uint_2 = OpTypePointer UniformConstant %_arr_8_uint_2
+ %tex = OpVariable %_ptr_UniformConstant__arr_8_uint_2 UniformConstant
+ %main = OpFunction %void None %3
+ %5 = OpLabel
+ OpReturn
+ OpFunctionEnd
+ )";
+
ASSERT_DEVICE_ERROR(utils::CreateShaderModuleFromASM(device, shader));
}
diff --git a/src/tint/lang/spirv/reader/ast_parser/BUILD.bazel b/src/tint/lang/spirv/reader/ast_parser/BUILD.bazel
index 35e1a22..c67f190 100644
--- a/src/tint/lang/spirv/reader/ast_parser/BUILD.bazel
+++ b/src/tint/lang/spirv/reader/ast_parser/BUILD.bazel
@@ -96,6 +96,7 @@
":tint_build_spv_reader_or_tint_build_spv_writer": [
"@spirv_headers//:spirv_cpp11_headers", "@spirv_headers//:spirv_c_headers",
"@spirv_tools//:spirv_tools_opt",
+ "@spirv_tools",
],
"//conditions:default": [],
}),
diff --git a/src/tint/lang/spirv/reader/ast_parser/BUILD.cmake b/src/tint/lang/spirv/reader/ast_parser/BUILD.cmake
index 61a79da..8bc80db 100644
--- a/src/tint/lang/spirv/reader/ast_parser/BUILD.cmake
+++ b/src/tint/lang/spirv/reader/ast_parser/BUILD.cmake
@@ -103,6 +103,7 @@
tint_target_add_external_dependencies(tint_lang_spirv_reader_ast_parser lib
"spirv-headers"
"spirv-opt-internal"
+ "spirv-tools"
)
endif(TINT_BUILD_SPV_READER OR TINT_BUILD_SPV_WRITER)
diff --git a/src/tint/lang/spirv/reader/ast_parser/BUILD.gn b/src/tint/lang/spirv/reader/ast_parser/BUILD.gn
index 359f2b6..fe367ef 100644
--- a/src/tint/lang/spirv/reader/ast_parser/BUILD.gn
+++ b/src/tint/lang/spirv/reader/ast_parser/BUILD.gn
@@ -103,8 +103,10 @@
deps += [
"${tint_spirv_headers_dir}:spv_headers",
"${tint_spirv_tools_dir}:spvtools",
+ "${tint_spirv_tools_dir}:spvtools_headers",
"${tint_spirv_tools_dir}:spvtools_opt",
"${tint_spirv_tools_dir}:spvtools_val",
+ "${tint_spirv_tools_dir}:spvtools_val",
]
}
public_configs = [ "${tint_spirv_tools_dir}/:spvtools_internal_config" ]
diff --git a/src/tint/lang/spirv/reader/ast_parser/ast_parser.cc b/src/tint/lang/spirv/reader/ast_parser/ast_parser.cc
index 930a6c7..509a914 100644
--- a/src/tint/lang/spirv/reader/ast_parser/ast_parser.cc
+++ b/src/tint/lang/spirv/reader/ast_parser/ast_parser.cc
@@ -33,6 +33,7 @@
#include <utility>
#include "source/opt/build_module.h"
+#include "spirv-tools/optimizer.hpp"
#include "src/tint/lang/core/fluent_types.h"
#include "src/tint/lang/core/type/depth_texture.h"
#include "src/tint/lang/core/type/multisampled_texture.h"
@@ -337,6 +338,22 @@
success_ = false;
return false;
}
+
+ // Split combined-image-samplers into separate image and sampler parts.
+ // Sampler bindings numbers get incremented. The increments are propagated
+ // among resource variaables until settling occurs.
+ {
+ spvtools::Optimizer optimizer(kInputEnv);
+ optimizer.SetMessageConsumer(message_consumer_);
+ optimizer.RegisterPass(spvtools::CreateSplitCombinedImageSamplerPass());
+ optimizer.RegisterPass(spvtools::CreateResolveBindingConflictsPass());
+ std::vector<uint32_t> new_binary;
+ if (!optimizer.Run(spv_binary_.data(), spv_binary_.size(), &new_binary)) {
+ return false;
+ }
+ spv_binary_ = std::move(new_binary);
+ }
+
if (!BuildInternalModule()) {
return false;
}
diff --git a/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_DeletesCopyObjectOfPtr_0.spvasm b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_DeletesCopyObjectOfPtr_0.spvasm
new file mode 100644
index 0000000..efd0f8a
--- /dev/null
+++ b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_DeletesCopyObjectOfPtr_0.spvasm
@@ -0,0 +1,71 @@
+ OpCapability Shader
+ OpCapability RuntimeDescriptorArray
+ OpExtension "SPV_EXT_descriptor_indexing"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ OpName %main "main"
+ OpName %main_0 "main_0"
+ OpName %voidfn "voidfn"
+
+ OpDecorate %100 DescriptorSet 0
+ OpDecorate %100 Binding 0
+
+ ; CHECK: OpName
+ ; CHECK-NOT: OpDecorate %100
+ ; CHECK: OpDecorate %[[image_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[sampler_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[image_var]] Binding 0
+ ; CHECK: OpDecorate %[[sampler_var]] Binding 0
+
+ ; CHECK: %10 = OpTypeImage %
+ ; CHECK: %[[image_ptr_ty:\w+]] = OpTypePointer UniformConstant %10
+ ; CHECK: %[[sampler_ty:\d+]] = OpTypeSampler
+ ; CHECK: %[[sampler_ptr_ty:\w+]] = OpTypePointer UniformConstant %[[sampler_ty]]
+
+ ; The combined image variable is replaced by an image variable and a sampler variable.
+
+ ; CHECK-NOT: %100 = OpVariable
+ ; CHECK-DAG: %[[sampler_var]] = OpVariable %[[sampler_ptr_ty]] UniformConstant
+ ; CHECK-DAG: %[[image_var]] = OpVariable %[[image_ptr_ty]] UniformConstant
+ ; CHECK: = OpFunction
+
+
+ %float = OpTypeFloat 32
+ %uint = OpTypeInt 32 0
+ %int = OpTypeInt 32 1
+ %uint_0 = OpConstant %uint 0
+ %uint_1 = OpConstant %uint 1
+ %uint_3 = OpConstant %uint 3
+ %float_0 = OpConstant %float 0
+ %v2float = OpTypeVector %float 2
+ %v3float = OpTypeVector %float 3
+ %v4float = OpTypeVector %float 4
+ %13 = OpConstantNull %v2float
+ %14 = OpConstantNull %v3float
+ %15 = OpConstantNull %v4float
+ %void = OpTypeVoid
+ %voidfn = OpTypeFunction %void
+ %10 = OpTypeImage %float 2D 0 0 0 1 Unknown
+ %11 = OpTypeSampledImage %10
+%_ptr_UniformConstant_11 = OpTypePointer UniformConstant %11
+
+ %100 = OpVariable %_ptr_UniformConstant_11 UniformConstant
+ %main = OpFunction %void None %voidfn
+ %main_0 = OpLabel
+ %101 = OpCopyObject %_ptr_UniformConstant_11 %100
+ %102 = OpLoad %11 %101
+ %103 = OpCopyObject %_ptr_UniformConstant_11 %101
+ %104 = OpCopyObject %11 %102 ;; this copy survives
+ OpReturn
+ OpFunctionEnd
+
+ ; The OpCopyObject instructions are removed.
+ ; The load of the combined image+sampler is replaced by a two loads, then
+ ; a combination operation. The only OpCopyObject that remains is the copy
+ ; of the copy of the sampled image value.
+ ; CHECK: %[[im:\d+]] = OpLoad %10 %[[image_var]]
+ ; CHECK: %[[s:\d+]] = OpLoad %[[sampler_ty]] %[[sampler_var]]
+ ; CHECK: %[[si:\d+]] = OpSampledImage %11 %[[im]] %[[s]]
+ ; CHECK-NEXT: OpCopyObject %11 %[[si]]
+ ; CHECK-NEXT: OpReturn
diff --git a/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_DeletesCopyObjectOfPtr_1.spvasm b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_DeletesCopyObjectOfPtr_1.spvasm
new file mode 100644
index 0000000..127492f
--- /dev/null
+++ b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_DeletesCopyObjectOfPtr_1.spvasm
@@ -0,0 +1,71 @@
+ OpCapability Shader
+ OpCapability RuntimeDescriptorArray
+ OpExtension "SPV_EXT_descriptor_indexing"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ OpName %main "main"
+ OpName %main_0 "main_0"
+ OpName %voidfn "voidfn"
+
+ OpDecorate %100 DescriptorSet 0
+ OpDecorate %100 Binding 0
+
+ ; CHECK: OpName
+ ; CHECK-NOT: OpDecorate %100
+ ; CHECK: OpDecorate %[[image_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[sampler_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[image_var]] Binding 0
+ ; CHECK: OpDecorate %[[sampler_var]] Binding 0
+
+ ; CHECK: %10 = OpTypeImage %
+ ; CHECK: %[[image_ptr_ty:\w+]] = OpTypePointer UniformConstant %10
+ ; CHECK: %[[sampler_ty:\d+]] = OpTypeSampler
+ ; CHECK: %[[sampler_ptr_ty:\w+]] = OpTypePointer UniformConstant %[[sampler_ty]]
+
+ ; The combined image variable is replaced by an image variable and a sampler variable.
+
+ ; CHECK-NOT: %100 = OpVariable
+ ; CHECK-DAG: %[[sampler_var]] = OpVariable %[[sampler_ptr_ty]] UniformConstant
+ ; CHECK-DAG: %[[image_var]] = OpVariable %[[image_ptr_ty]] UniformConstant
+ ; CHECK: = OpFunction
+
+
+ %float = OpTypeFloat 32
+ %uint = OpTypeInt 32 0
+ %int = OpTypeInt 32 1
+ %uint_0 = OpConstant %uint 0
+ %uint_1 = OpConstant %uint 1
+ %uint_3 = OpConstant %uint 3
+ %float_0 = OpConstant %float 0
+ %v2float = OpTypeVector %float 2
+ %v3float = OpTypeVector %float 3
+ %v4float = OpTypeVector %float 4
+ %13 = OpConstantNull %v2float
+ %14 = OpConstantNull %v3float
+ %15 = OpConstantNull %v4float
+ %void = OpTypeVoid
+ %voidfn = OpTypeFunction %void
+ %10 = OpTypeImage %float 2D 1 0 0 1 Unknown
+ %11 = OpTypeSampledImage %10
+%_ptr_UniformConstant_11 = OpTypePointer UniformConstant %11
+
+ %100 = OpVariable %_ptr_UniformConstant_11 UniformConstant
+ %main = OpFunction %void None %voidfn
+ %main_0 = OpLabel
+ %101 = OpCopyObject %_ptr_UniformConstant_11 %100
+ %102 = OpLoad %11 %101
+ %103 = OpCopyObject %_ptr_UniformConstant_11 %101
+ %104 = OpCopyObject %11 %102 ;; this copy survives
+ OpReturn
+ OpFunctionEnd
+
+ ; The OpCopyObject instructions are removed.
+ ; The load of the combined image+sampler is replaced by a two loads, then
+ ; a combination operation. The only OpCopyObject that remains is the copy
+ ; of the copy of the sampled image value.
+ ; CHECK: %[[im:\d+]] = OpLoad %10 %[[image_var]]
+ ; CHECK: %[[s:\d+]] = OpLoad %[[sampler_ty]] %[[sampler_var]]
+ ; CHECK: %[[si:\d+]] = OpSampledImage %11 %[[im]] %[[s]]
+ ; CHECK-NEXT: OpCopyObject %11 %[[si]]
+ ; CHECK-NEXT: OpReturn
diff --git a/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_DeletesCopyObjectOfPtr_10.spvasm b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_DeletesCopyObjectOfPtr_10.spvasm
new file mode 100644
index 0000000..194624e
--- /dev/null
+++ b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_DeletesCopyObjectOfPtr_10.spvasm
@@ -0,0 +1,71 @@
+ OpCapability Shader
+ OpCapability RuntimeDescriptorArray
+ OpExtension "SPV_EXT_descriptor_indexing"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ OpName %main "main"
+ OpName %main_0 "main_0"
+ OpName %voidfn "voidfn"
+
+ OpDecorate %100 DescriptorSet 0
+ OpDecorate %100 Binding 0
+
+ ; CHECK: OpName
+ ; CHECK-NOT: OpDecorate %100
+ ; CHECK: OpDecorate %[[image_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[sampler_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[image_var]] Binding 0
+ ; CHECK: OpDecorate %[[sampler_var]] Binding 0
+
+ ; CHECK: %10 = OpTypeImage %
+ ; CHECK: %[[image_ptr_ty:\w+]] = OpTypePointer UniformConstant %10
+ ; CHECK: %[[sampler_ty:\d+]] = OpTypeSampler
+ ; CHECK: %[[sampler_ptr_ty:\w+]] = OpTypePointer UniformConstant %[[sampler_ty]]
+
+ ; The combined image variable is replaced by an image variable and a sampler variable.
+
+ ; CHECK-NOT: %100 = OpVariable
+ ; CHECK-DAG: %[[sampler_var]] = OpVariable %[[sampler_ptr_ty]] UniformConstant
+ ; CHECK-DAG: %[[image_var]] = OpVariable %[[image_ptr_ty]] UniformConstant
+ ; CHECK: = OpFunction
+
+
+ %float = OpTypeFloat 32
+ %uint = OpTypeInt 32 0
+ %int = OpTypeInt 32 1
+ %uint_0 = OpConstant %uint 0
+ %uint_1 = OpConstant %uint 1
+ %uint_3 = OpConstant %uint 3
+ %float_0 = OpConstant %float 0
+ %v2float = OpTypeVector %float 2
+ %v3float = OpTypeVector %float 3
+ %v4float = OpTypeVector %float 4
+ %13 = OpConstantNull %v2float
+ %14 = OpConstantNull %v3float
+ %15 = OpConstantNull %v4float
+ %void = OpTypeVoid
+ %voidfn = OpTypeFunction %void
+ %10 = OpTypeImage %float Cube 1 1 0 1 Unknown
+ %11 = OpTypeSampledImage %10
+%_ptr_UniformConstant_11 = OpTypePointer UniformConstant %11
+
+ %100 = OpVariable %_ptr_UniformConstant_11 UniformConstant
+ %main = OpFunction %void None %voidfn
+ %main_0 = OpLabel
+ %101 = OpCopyObject %_ptr_UniformConstant_11 %100
+ %102 = OpLoad %11 %101
+ %103 = OpCopyObject %_ptr_UniformConstant_11 %101
+ %104 = OpCopyObject %11 %102 ;; this copy survives
+ OpReturn
+ OpFunctionEnd
+
+ ; The OpCopyObject instructions are removed.
+ ; The load of the combined image+sampler is replaced by a two loads, then
+ ; a combination operation. The only OpCopyObject that remains is the copy
+ ; of the copy of the sampled image value.
+ ; CHECK: %[[im:\d+]] = OpLoad %10 %[[image_var]]
+ ; CHECK: %[[s:\d+]] = OpLoad %[[sampler_ty]] %[[sampler_var]]
+ ; CHECK: %[[si:\d+]] = OpSampledImage %11 %[[im]] %[[s]]
+ ; CHECK-NEXT: OpCopyObject %11 %[[si]]
+ ; CHECK-NEXT: OpReturn
diff --git a/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_DeletesCopyObjectOfPtr_11.spvasm b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_DeletesCopyObjectOfPtr_11.spvasm
new file mode 100644
index 0000000..09d5763
--- /dev/null
+++ b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_DeletesCopyObjectOfPtr_11.spvasm
@@ -0,0 +1,71 @@
+ OpCapability Shader
+ OpCapability RuntimeDescriptorArray
+ OpExtension "SPV_EXT_descriptor_indexing"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ OpName %main "main"
+ OpName %main_0 "main_0"
+ OpName %voidfn "voidfn"
+
+ OpDecorate %100 DescriptorSet 0
+ OpDecorate %100 Binding 0
+
+ ; CHECK: OpName
+ ; CHECK-NOT: OpDecorate %100
+ ; CHECK: OpDecorate %[[image_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[sampler_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[image_var]] Binding 0
+ ; CHECK: OpDecorate %[[sampler_var]] Binding 0
+
+ ; CHECK: %10 = OpTypeImage %
+ ; CHECK: %[[image_ptr_ty:\w+]] = OpTypePointer UniformConstant %10
+ ; CHECK: %[[sampler_ty:\d+]] = OpTypeSampler
+ ; CHECK: %[[sampler_ptr_ty:\w+]] = OpTypePointer UniformConstant %[[sampler_ty]]
+
+ ; The combined image variable is replaced by an image variable and a sampler variable.
+
+ ; CHECK-NOT: %100 = OpVariable
+ ; CHECK-DAG: %[[sampler_var]] = OpVariable %[[sampler_ptr_ty]] UniformConstant
+ ; CHECK-DAG: %[[image_var]] = OpVariable %[[image_ptr_ty]] UniformConstant
+ ; CHECK: = OpFunction
+
+
+ %float = OpTypeFloat 32
+ %uint = OpTypeInt 32 0
+ %int = OpTypeInt 32 1
+ %uint_0 = OpConstant %uint 0
+ %uint_1 = OpConstant %uint 1
+ %uint_3 = OpConstant %uint 3
+ %float_0 = OpConstant %float 0
+ %v2float = OpTypeVector %float 2
+ %v3float = OpTypeVector %float 3
+ %v4float = OpTypeVector %float 4
+ %13 = OpConstantNull %v2float
+ %14 = OpConstantNull %v3float
+ %15 = OpConstantNull %v4float
+ %void = OpTypeVoid
+ %voidfn = OpTypeFunction %void
+ %10 = OpTypeImage %int 2D 0 0 0 1 Unknown
+ %11 = OpTypeSampledImage %10
+%_ptr_UniformConstant_11 = OpTypePointer UniformConstant %11
+
+ %100 = OpVariable %_ptr_UniformConstant_11 UniformConstant
+ %main = OpFunction %void None %voidfn
+ %main_0 = OpLabel
+ %101 = OpCopyObject %_ptr_UniformConstant_11 %100
+ %102 = OpLoad %11 %101
+ %103 = OpCopyObject %_ptr_UniformConstant_11 %101
+ %104 = OpCopyObject %11 %102 ;; this copy survives
+ OpReturn
+ OpFunctionEnd
+
+ ; The OpCopyObject instructions are removed.
+ ; The load of the combined image+sampler is replaced by a two loads, then
+ ; a combination operation. The only OpCopyObject that remains is the copy
+ ; of the copy of the sampled image value.
+ ; CHECK: %[[im:\d+]] = OpLoad %10 %[[image_var]]
+ ; CHECK: %[[s:\d+]] = OpLoad %[[sampler_ty]] %[[sampler_var]]
+ ; CHECK: %[[si:\d+]] = OpSampledImage %11 %[[im]] %[[s]]
+ ; CHECK-NEXT: OpCopyObject %11 %[[si]]
+ ; CHECK-NEXT: OpReturn
diff --git a/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_DeletesCopyObjectOfPtr_12.spvasm b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_DeletesCopyObjectOfPtr_12.spvasm
new file mode 100644
index 0000000..017a327
--- /dev/null
+++ b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_DeletesCopyObjectOfPtr_12.spvasm
@@ -0,0 +1,71 @@
+ OpCapability Shader
+ OpCapability RuntimeDescriptorArray
+ OpExtension "SPV_EXT_descriptor_indexing"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ OpName %main "main"
+ OpName %main_0 "main_0"
+ OpName %voidfn "voidfn"
+
+ OpDecorate %100 DescriptorSet 0
+ OpDecorate %100 Binding 0
+
+ ; CHECK: OpName
+ ; CHECK-NOT: OpDecorate %100
+ ; CHECK: OpDecorate %[[image_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[sampler_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[image_var]] Binding 0
+ ; CHECK: OpDecorate %[[sampler_var]] Binding 0
+
+ ; CHECK: %10 = OpTypeImage %
+ ; CHECK: %[[image_ptr_ty:\w+]] = OpTypePointer UniformConstant %10
+ ; CHECK: %[[sampler_ty:\d+]] = OpTypeSampler
+ ; CHECK: %[[sampler_ptr_ty:\w+]] = OpTypePointer UniformConstant %[[sampler_ty]]
+
+ ; The combined image variable is replaced by an image variable and a sampler variable.
+
+ ; CHECK-NOT: %100 = OpVariable
+ ; CHECK-DAG: %[[sampler_var]] = OpVariable %[[sampler_ptr_ty]] UniformConstant
+ ; CHECK-DAG: %[[image_var]] = OpVariable %[[image_ptr_ty]] UniformConstant
+ ; CHECK: = OpFunction
+
+
+ %float = OpTypeFloat 32
+ %uint = OpTypeInt 32 0
+ %int = OpTypeInt 32 1
+ %uint_0 = OpConstant %uint 0
+ %uint_1 = OpConstant %uint 1
+ %uint_3 = OpConstant %uint 3
+ %float_0 = OpConstant %float 0
+ %v2float = OpTypeVector %float 2
+ %v3float = OpTypeVector %float 3
+ %v4float = OpTypeVector %float 4
+ %13 = OpConstantNull %v2float
+ %14 = OpConstantNull %v3float
+ %15 = OpConstantNull %v4float
+ %void = OpTypeVoid
+ %voidfn = OpTypeFunction %void
+ %10 = OpTypeImage %int 2D 1 0 0 1 Unknown
+ %11 = OpTypeSampledImage %10
+%_ptr_UniformConstant_11 = OpTypePointer UniformConstant %11
+
+ %100 = OpVariable %_ptr_UniformConstant_11 UniformConstant
+ %main = OpFunction %void None %voidfn
+ %main_0 = OpLabel
+ %101 = OpCopyObject %_ptr_UniformConstant_11 %100
+ %102 = OpLoad %11 %101
+ %103 = OpCopyObject %_ptr_UniformConstant_11 %101
+ %104 = OpCopyObject %11 %102 ;; this copy survives
+ OpReturn
+ OpFunctionEnd
+
+ ; The OpCopyObject instructions are removed.
+ ; The load of the combined image+sampler is replaced by a two loads, then
+ ; a combination operation. The only OpCopyObject that remains is the copy
+ ; of the copy of the sampled image value.
+ ; CHECK: %[[im:\d+]] = OpLoad %10 %[[image_var]]
+ ; CHECK: %[[s:\d+]] = OpLoad %[[sampler_ty]] %[[sampler_var]]
+ ; CHECK: %[[si:\d+]] = OpSampledImage %11 %[[im]] %[[s]]
+ ; CHECK-NEXT: OpCopyObject %11 %[[si]]
+ ; CHECK-NEXT: OpReturn
diff --git a/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_DeletesCopyObjectOfPtr_13.spvasm b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_DeletesCopyObjectOfPtr_13.spvasm
new file mode 100644
index 0000000..2f287de
--- /dev/null
+++ b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_DeletesCopyObjectOfPtr_13.spvasm
@@ -0,0 +1,71 @@
+ OpCapability Shader
+ OpCapability RuntimeDescriptorArray
+ OpExtension "SPV_EXT_descriptor_indexing"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ OpName %main "main"
+ OpName %main_0 "main_0"
+ OpName %voidfn "voidfn"
+
+ OpDecorate %100 DescriptorSet 0
+ OpDecorate %100 Binding 0
+
+ ; CHECK: OpName
+ ; CHECK-NOT: OpDecorate %100
+ ; CHECK: OpDecorate %[[image_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[sampler_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[image_var]] Binding 0
+ ; CHECK: OpDecorate %[[sampler_var]] Binding 0
+
+ ; CHECK: %10 = OpTypeImage %
+ ; CHECK: %[[image_ptr_ty:\w+]] = OpTypePointer UniformConstant %10
+ ; CHECK: %[[sampler_ty:\d+]] = OpTypeSampler
+ ; CHECK: %[[sampler_ptr_ty:\w+]] = OpTypePointer UniformConstant %[[sampler_ty]]
+
+ ; The combined image variable is replaced by an image variable and a sampler variable.
+
+ ; CHECK-NOT: %100 = OpVariable
+ ; CHECK-DAG: %[[sampler_var]] = OpVariable %[[sampler_ptr_ty]] UniformConstant
+ ; CHECK-DAG: %[[image_var]] = OpVariable %[[image_ptr_ty]] UniformConstant
+ ; CHECK: = OpFunction
+
+
+ %float = OpTypeFloat 32
+ %uint = OpTypeInt 32 0
+ %int = OpTypeInt 32 1
+ %uint_0 = OpConstant %uint 0
+ %uint_1 = OpConstant %uint 1
+ %uint_3 = OpConstant %uint 3
+ %float_0 = OpConstant %float 0
+ %v2float = OpTypeVector %float 2
+ %v3float = OpTypeVector %float 3
+ %v4float = OpTypeVector %float 4
+ %13 = OpConstantNull %v2float
+ %14 = OpConstantNull %v3float
+ %15 = OpConstantNull %v4float
+ %void = OpTypeVoid
+ %voidfn = OpTypeFunction %void
+ %10 = OpTypeImage %int 2D 0 1 0 1 Unknown
+ %11 = OpTypeSampledImage %10
+%_ptr_UniformConstant_11 = OpTypePointer UniformConstant %11
+
+ %100 = OpVariable %_ptr_UniformConstant_11 UniformConstant
+ %main = OpFunction %void None %voidfn
+ %main_0 = OpLabel
+ %101 = OpCopyObject %_ptr_UniformConstant_11 %100
+ %102 = OpLoad %11 %101
+ %103 = OpCopyObject %_ptr_UniformConstant_11 %101
+ %104 = OpCopyObject %11 %102 ;; this copy survives
+ OpReturn
+ OpFunctionEnd
+
+ ; The OpCopyObject instructions are removed.
+ ; The load of the combined image+sampler is replaced by a two loads, then
+ ; a combination operation. The only OpCopyObject that remains is the copy
+ ; of the copy of the sampled image value.
+ ; CHECK: %[[im:\d+]] = OpLoad %10 %[[image_var]]
+ ; CHECK: %[[s:\d+]] = OpLoad %[[sampler_ty]] %[[sampler_var]]
+ ; CHECK: %[[si:\d+]] = OpSampledImage %11 %[[im]] %[[s]]
+ ; CHECK-NEXT: OpCopyObject %11 %[[si]]
+ ; CHECK-NEXT: OpReturn
diff --git a/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_DeletesCopyObjectOfPtr_14.spvasm b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_DeletesCopyObjectOfPtr_14.spvasm
new file mode 100644
index 0000000..9af8b50
--- /dev/null
+++ b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_DeletesCopyObjectOfPtr_14.spvasm
@@ -0,0 +1,71 @@
+ OpCapability Shader
+ OpCapability RuntimeDescriptorArray
+ OpExtension "SPV_EXT_descriptor_indexing"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ OpName %main "main"
+ OpName %main_0 "main_0"
+ OpName %voidfn "voidfn"
+
+ OpDecorate %100 DescriptorSet 0
+ OpDecorate %100 Binding 0
+
+ ; CHECK: OpName
+ ; CHECK-NOT: OpDecorate %100
+ ; CHECK: OpDecorate %[[image_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[sampler_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[image_var]] Binding 0
+ ; CHECK: OpDecorate %[[sampler_var]] Binding 0
+
+ ; CHECK: %10 = OpTypeImage %
+ ; CHECK: %[[image_ptr_ty:\w+]] = OpTypePointer UniformConstant %10
+ ; CHECK: %[[sampler_ty:\d+]] = OpTypeSampler
+ ; CHECK: %[[sampler_ptr_ty:\w+]] = OpTypePointer UniformConstant %[[sampler_ty]]
+
+ ; The combined image variable is replaced by an image variable and a sampler variable.
+
+ ; CHECK-NOT: %100 = OpVariable
+ ; CHECK-DAG: %[[sampler_var]] = OpVariable %[[sampler_ptr_ty]] UniformConstant
+ ; CHECK-DAG: %[[image_var]] = OpVariable %[[image_ptr_ty]] UniformConstant
+ ; CHECK: = OpFunction
+
+
+ %float = OpTypeFloat 32
+ %uint = OpTypeInt 32 0
+ %int = OpTypeInt 32 1
+ %uint_0 = OpConstant %uint 0
+ %uint_1 = OpConstant %uint 1
+ %uint_3 = OpConstant %uint 3
+ %float_0 = OpConstant %float 0
+ %v2float = OpTypeVector %float 2
+ %v3float = OpTypeVector %float 3
+ %v4float = OpTypeVector %float 4
+ %13 = OpConstantNull %v2float
+ %14 = OpConstantNull %v3float
+ %15 = OpConstantNull %v4float
+ %void = OpTypeVoid
+ %voidfn = OpTypeFunction %void
+ %10 = OpTypeImage %int 2D 1 1 0 1 Unknown
+ %11 = OpTypeSampledImage %10
+%_ptr_UniformConstant_11 = OpTypePointer UniformConstant %11
+
+ %100 = OpVariable %_ptr_UniformConstant_11 UniformConstant
+ %main = OpFunction %void None %voidfn
+ %main_0 = OpLabel
+ %101 = OpCopyObject %_ptr_UniformConstant_11 %100
+ %102 = OpLoad %11 %101
+ %103 = OpCopyObject %_ptr_UniformConstant_11 %101
+ %104 = OpCopyObject %11 %102 ;; this copy survives
+ OpReturn
+ OpFunctionEnd
+
+ ; The OpCopyObject instructions are removed.
+ ; The load of the combined image+sampler is replaced by a two loads, then
+ ; a combination operation. The only OpCopyObject that remains is the copy
+ ; of the copy of the sampled image value.
+ ; CHECK: %[[im:\d+]] = OpLoad %10 %[[image_var]]
+ ; CHECK: %[[s:\d+]] = OpLoad %[[sampler_ty]] %[[sampler_var]]
+ ; CHECK: %[[si:\d+]] = OpSampledImage %11 %[[im]] %[[s]]
+ ; CHECK-NEXT: OpCopyObject %11 %[[si]]
+ ; CHECK-NEXT: OpReturn
diff --git a/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_DeletesCopyObjectOfPtr_15.spvasm b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_DeletesCopyObjectOfPtr_15.spvasm
new file mode 100644
index 0000000..21af6b7
--- /dev/null
+++ b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_DeletesCopyObjectOfPtr_15.spvasm
@@ -0,0 +1,71 @@
+ OpCapability Shader
+ OpCapability RuntimeDescriptorArray
+ OpExtension "SPV_EXT_descriptor_indexing"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ OpName %main "main"
+ OpName %main_0 "main_0"
+ OpName %voidfn "voidfn"
+
+ OpDecorate %100 DescriptorSet 0
+ OpDecorate %100 Binding 0
+
+ ; CHECK: OpName
+ ; CHECK-NOT: OpDecorate %100
+ ; CHECK: OpDecorate %[[image_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[sampler_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[image_var]] Binding 0
+ ; CHECK: OpDecorate %[[sampler_var]] Binding 0
+
+ ; CHECK: %10 = OpTypeImage %
+ ; CHECK: %[[image_ptr_ty:\w+]] = OpTypePointer UniformConstant %10
+ ; CHECK: %[[sampler_ty:\d+]] = OpTypeSampler
+ ; CHECK: %[[sampler_ptr_ty:\w+]] = OpTypePointer UniformConstant %[[sampler_ty]]
+
+ ; The combined image variable is replaced by an image variable and a sampler variable.
+
+ ; CHECK-NOT: %100 = OpVariable
+ ; CHECK-DAG: %[[sampler_var]] = OpVariable %[[sampler_ptr_ty]] UniformConstant
+ ; CHECK-DAG: %[[image_var]] = OpVariable %[[image_ptr_ty]] UniformConstant
+ ; CHECK: = OpFunction
+
+
+ %float = OpTypeFloat 32
+ %uint = OpTypeInt 32 0
+ %int = OpTypeInt 32 1
+ %uint_0 = OpConstant %uint 0
+ %uint_1 = OpConstant %uint 1
+ %uint_3 = OpConstant %uint 3
+ %float_0 = OpConstant %float 0
+ %v2float = OpTypeVector %float 2
+ %v3float = OpTypeVector %float 3
+ %v4float = OpTypeVector %float 4
+ %13 = OpConstantNull %v2float
+ %14 = OpConstantNull %v3float
+ %15 = OpConstantNull %v4float
+ %void = OpTypeVoid
+ %voidfn = OpTypeFunction %void
+ %10 = OpTypeImage %int 2D 0 0 1 1 Unknown
+ %11 = OpTypeSampledImage %10
+%_ptr_UniformConstant_11 = OpTypePointer UniformConstant %11
+
+ %100 = OpVariable %_ptr_UniformConstant_11 UniformConstant
+ %main = OpFunction %void None %voidfn
+ %main_0 = OpLabel
+ %101 = OpCopyObject %_ptr_UniformConstant_11 %100
+ %102 = OpLoad %11 %101
+ %103 = OpCopyObject %_ptr_UniformConstant_11 %101
+ %104 = OpCopyObject %11 %102 ;; this copy survives
+ OpReturn
+ OpFunctionEnd
+
+ ; The OpCopyObject instructions are removed.
+ ; The load of the combined image+sampler is replaced by a two loads, then
+ ; a combination operation. The only OpCopyObject that remains is the copy
+ ; of the copy of the sampled image value.
+ ; CHECK: %[[im:\d+]] = OpLoad %10 %[[image_var]]
+ ; CHECK: %[[s:\d+]] = OpLoad %[[sampler_ty]] %[[sampler_var]]
+ ; CHECK: %[[si:\d+]] = OpSampledImage %11 %[[im]] %[[s]]
+ ; CHECK-NEXT: OpCopyObject %11 %[[si]]
+ ; CHECK-NEXT: OpReturn
diff --git a/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_DeletesCopyObjectOfPtr_17.spvasm b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_DeletesCopyObjectOfPtr_17.spvasm
new file mode 100644
index 0000000..86ff9ad
--- /dev/null
+++ b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_DeletesCopyObjectOfPtr_17.spvasm
@@ -0,0 +1,71 @@
+ OpCapability Shader
+ OpCapability RuntimeDescriptorArray
+ OpExtension "SPV_EXT_descriptor_indexing"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ OpName %main "main"
+ OpName %main_0 "main_0"
+ OpName %voidfn "voidfn"
+
+ OpDecorate %100 DescriptorSet 0
+ OpDecorate %100 Binding 0
+
+ ; CHECK: OpName
+ ; CHECK-NOT: OpDecorate %100
+ ; CHECK: OpDecorate %[[image_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[sampler_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[image_var]] Binding 0
+ ; CHECK: OpDecorate %[[sampler_var]] Binding 0
+
+ ; CHECK: %10 = OpTypeImage %
+ ; CHECK: %[[image_ptr_ty:\w+]] = OpTypePointer UniformConstant %10
+ ; CHECK: %[[sampler_ty:\d+]] = OpTypeSampler
+ ; CHECK: %[[sampler_ptr_ty:\w+]] = OpTypePointer UniformConstant %[[sampler_ty]]
+
+ ; The combined image variable is replaced by an image variable and a sampler variable.
+
+ ; CHECK-NOT: %100 = OpVariable
+ ; CHECK-DAG: %[[sampler_var]] = OpVariable %[[sampler_ptr_ty]] UniformConstant
+ ; CHECK-DAG: %[[image_var]] = OpVariable %[[image_ptr_ty]] UniformConstant
+ ; CHECK: = OpFunction
+
+
+ %float = OpTypeFloat 32
+ %uint = OpTypeInt 32 0
+ %int = OpTypeInt 32 1
+ %uint_0 = OpConstant %uint 0
+ %uint_1 = OpConstant %uint 1
+ %uint_3 = OpConstant %uint 3
+ %float_0 = OpConstant %float 0
+ %v2float = OpTypeVector %float 2
+ %v3float = OpTypeVector %float 3
+ %v4float = OpTypeVector %float 4
+ %13 = OpConstantNull %v2float
+ %14 = OpConstantNull %v3float
+ %15 = OpConstantNull %v4float
+ %void = OpTypeVoid
+ %voidfn = OpTypeFunction %void
+ %10 = OpTypeImage %int 3D 0 0 0 1 Unknown
+ %11 = OpTypeSampledImage %10
+%_ptr_UniformConstant_11 = OpTypePointer UniformConstant %11
+
+ %100 = OpVariable %_ptr_UniformConstant_11 UniformConstant
+ %main = OpFunction %void None %voidfn
+ %main_0 = OpLabel
+ %101 = OpCopyObject %_ptr_UniformConstant_11 %100
+ %102 = OpLoad %11 %101
+ %103 = OpCopyObject %_ptr_UniformConstant_11 %101
+ %104 = OpCopyObject %11 %102 ;; this copy survives
+ OpReturn
+ OpFunctionEnd
+
+ ; The OpCopyObject instructions are removed.
+ ; The load of the combined image+sampler is replaced by a two loads, then
+ ; a combination operation. The only OpCopyObject that remains is the copy
+ ; of the copy of the sampled image value.
+ ; CHECK: %[[im:\d+]] = OpLoad %10 %[[image_var]]
+ ; CHECK: %[[s:\d+]] = OpLoad %[[sampler_ty]] %[[sampler_var]]
+ ; CHECK: %[[si:\d+]] = OpSampledImage %11 %[[im]] %[[s]]
+ ; CHECK-NEXT: OpCopyObject %11 %[[si]]
+ ; CHECK-NEXT: OpReturn
diff --git a/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_DeletesCopyObjectOfPtr_18.spvasm b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_DeletesCopyObjectOfPtr_18.spvasm
new file mode 100644
index 0000000..d7b67d7
--- /dev/null
+++ b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_DeletesCopyObjectOfPtr_18.spvasm
@@ -0,0 +1,71 @@
+ OpCapability Shader
+ OpCapability RuntimeDescriptorArray
+ OpExtension "SPV_EXT_descriptor_indexing"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ OpName %main "main"
+ OpName %main_0 "main_0"
+ OpName %voidfn "voidfn"
+
+ OpDecorate %100 DescriptorSet 0
+ OpDecorate %100 Binding 0
+
+ ; CHECK: OpName
+ ; CHECK-NOT: OpDecorate %100
+ ; CHECK: OpDecorate %[[image_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[sampler_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[image_var]] Binding 0
+ ; CHECK: OpDecorate %[[sampler_var]] Binding 0
+
+ ; CHECK: %10 = OpTypeImage %
+ ; CHECK: %[[image_ptr_ty:\w+]] = OpTypePointer UniformConstant %10
+ ; CHECK: %[[sampler_ty:\d+]] = OpTypeSampler
+ ; CHECK: %[[sampler_ptr_ty:\w+]] = OpTypePointer UniformConstant %[[sampler_ty]]
+
+ ; The combined image variable is replaced by an image variable and a sampler variable.
+
+ ; CHECK-NOT: %100 = OpVariable
+ ; CHECK-DAG: %[[sampler_var]] = OpVariable %[[sampler_ptr_ty]] UniformConstant
+ ; CHECK-DAG: %[[image_var]] = OpVariable %[[image_ptr_ty]] UniformConstant
+ ; CHECK: = OpFunction
+
+
+ %float = OpTypeFloat 32
+ %uint = OpTypeInt 32 0
+ %int = OpTypeInt 32 1
+ %uint_0 = OpConstant %uint 0
+ %uint_1 = OpConstant %uint 1
+ %uint_3 = OpConstant %uint 3
+ %float_0 = OpConstant %float 0
+ %v2float = OpTypeVector %float 2
+ %v3float = OpTypeVector %float 3
+ %v4float = OpTypeVector %float 4
+ %13 = OpConstantNull %v2float
+ %14 = OpConstantNull %v3float
+ %15 = OpConstantNull %v4float
+ %void = OpTypeVoid
+ %voidfn = OpTypeFunction %void
+ %10 = OpTypeImage %int Cube 0 0 0 1 Unknown
+ %11 = OpTypeSampledImage %10
+%_ptr_UniformConstant_11 = OpTypePointer UniformConstant %11
+
+ %100 = OpVariable %_ptr_UniformConstant_11 UniformConstant
+ %main = OpFunction %void None %voidfn
+ %main_0 = OpLabel
+ %101 = OpCopyObject %_ptr_UniformConstant_11 %100
+ %102 = OpLoad %11 %101
+ %103 = OpCopyObject %_ptr_UniformConstant_11 %101
+ %104 = OpCopyObject %11 %102 ;; this copy survives
+ OpReturn
+ OpFunctionEnd
+
+ ; The OpCopyObject instructions are removed.
+ ; The load of the combined image+sampler is replaced by a two loads, then
+ ; a combination operation. The only OpCopyObject that remains is the copy
+ ; of the copy of the sampled image value.
+ ; CHECK: %[[im:\d+]] = OpLoad %10 %[[image_var]]
+ ; CHECK: %[[s:\d+]] = OpLoad %[[sampler_ty]] %[[sampler_var]]
+ ; CHECK: %[[si:\d+]] = OpSampledImage %11 %[[im]] %[[s]]
+ ; CHECK-NEXT: OpCopyObject %11 %[[si]]
+ ; CHECK-NEXT: OpReturn
diff --git a/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_DeletesCopyObjectOfPtr_19.spvasm b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_DeletesCopyObjectOfPtr_19.spvasm
new file mode 100644
index 0000000..685eb9c
--- /dev/null
+++ b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_DeletesCopyObjectOfPtr_19.spvasm
@@ -0,0 +1,71 @@
+ OpCapability Shader
+ OpCapability RuntimeDescriptorArray
+ OpExtension "SPV_EXT_descriptor_indexing"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ OpName %main "main"
+ OpName %main_0 "main_0"
+ OpName %voidfn "voidfn"
+
+ OpDecorate %100 DescriptorSet 0
+ OpDecorate %100 Binding 0
+
+ ; CHECK: OpName
+ ; CHECK-NOT: OpDecorate %100
+ ; CHECK: OpDecorate %[[image_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[sampler_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[image_var]] Binding 0
+ ; CHECK: OpDecorate %[[sampler_var]] Binding 0
+
+ ; CHECK: %10 = OpTypeImage %
+ ; CHECK: %[[image_ptr_ty:\w+]] = OpTypePointer UniformConstant %10
+ ; CHECK: %[[sampler_ty:\d+]] = OpTypeSampler
+ ; CHECK: %[[sampler_ptr_ty:\w+]] = OpTypePointer UniformConstant %[[sampler_ty]]
+
+ ; The combined image variable is replaced by an image variable and a sampler variable.
+
+ ; CHECK-NOT: %100 = OpVariable
+ ; CHECK-DAG: %[[sampler_var]] = OpVariable %[[sampler_ptr_ty]] UniformConstant
+ ; CHECK-DAG: %[[image_var]] = OpVariable %[[image_ptr_ty]] UniformConstant
+ ; CHECK: = OpFunction
+
+
+ %float = OpTypeFloat 32
+ %uint = OpTypeInt 32 0
+ %int = OpTypeInt 32 1
+ %uint_0 = OpConstant %uint 0
+ %uint_1 = OpConstant %uint 1
+ %uint_3 = OpConstant %uint 3
+ %float_0 = OpConstant %float 0
+ %v2float = OpTypeVector %float 2
+ %v3float = OpTypeVector %float 3
+ %v4float = OpTypeVector %float 4
+ %13 = OpConstantNull %v2float
+ %14 = OpConstantNull %v3float
+ %15 = OpConstantNull %v4float
+ %void = OpTypeVoid
+ %voidfn = OpTypeFunction %void
+ %10 = OpTypeImage %int Cube 1 0 0 1 Unknown
+ %11 = OpTypeSampledImage %10
+%_ptr_UniformConstant_11 = OpTypePointer UniformConstant %11
+
+ %100 = OpVariable %_ptr_UniformConstant_11 UniformConstant
+ %main = OpFunction %void None %voidfn
+ %main_0 = OpLabel
+ %101 = OpCopyObject %_ptr_UniformConstant_11 %100
+ %102 = OpLoad %11 %101
+ %103 = OpCopyObject %_ptr_UniformConstant_11 %101
+ %104 = OpCopyObject %11 %102 ;; this copy survives
+ OpReturn
+ OpFunctionEnd
+
+ ; The OpCopyObject instructions are removed.
+ ; The load of the combined image+sampler is replaced by a two loads, then
+ ; a combination operation. The only OpCopyObject that remains is the copy
+ ; of the copy of the sampled image value.
+ ; CHECK: %[[im:\d+]] = OpLoad %10 %[[image_var]]
+ ; CHECK: %[[s:\d+]] = OpLoad %[[sampler_ty]] %[[sampler_var]]
+ ; CHECK: %[[si:\d+]] = OpSampledImage %11 %[[im]] %[[s]]
+ ; CHECK-NEXT: OpCopyObject %11 %[[si]]
+ ; CHECK-NEXT: OpReturn
diff --git a/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_DeletesCopyObjectOfPtr_2.spvasm b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_DeletesCopyObjectOfPtr_2.spvasm
new file mode 100644
index 0000000..efeac2c
--- /dev/null
+++ b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_DeletesCopyObjectOfPtr_2.spvasm
@@ -0,0 +1,71 @@
+ OpCapability Shader
+ OpCapability RuntimeDescriptorArray
+ OpExtension "SPV_EXT_descriptor_indexing"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ OpName %main "main"
+ OpName %main_0 "main_0"
+ OpName %voidfn "voidfn"
+
+ OpDecorate %100 DescriptorSet 0
+ OpDecorate %100 Binding 0
+
+ ; CHECK: OpName
+ ; CHECK-NOT: OpDecorate %100
+ ; CHECK: OpDecorate %[[image_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[sampler_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[image_var]] Binding 0
+ ; CHECK: OpDecorate %[[sampler_var]] Binding 0
+
+ ; CHECK: %10 = OpTypeImage %
+ ; CHECK: %[[image_ptr_ty:\w+]] = OpTypePointer UniformConstant %10
+ ; CHECK: %[[sampler_ty:\d+]] = OpTypeSampler
+ ; CHECK: %[[sampler_ptr_ty:\w+]] = OpTypePointer UniformConstant %[[sampler_ty]]
+
+ ; The combined image variable is replaced by an image variable and a sampler variable.
+
+ ; CHECK-NOT: %100 = OpVariable
+ ; CHECK-DAG: %[[sampler_var]] = OpVariable %[[sampler_ptr_ty]] UniformConstant
+ ; CHECK-DAG: %[[image_var]] = OpVariable %[[image_ptr_ty]] UniformConstant
+ ; CHECK: = OpFunction
+
+
+ %float = OpTypeFloat 32
+ %uint = OpTypeInt 32 0
+ %int = OpTypeInt 32 1
+ %uint_0 = OpConstant %uint 0
+ %uint_1 = OpConstant %uint 1
+ %uint_3 = OpConstant %uint 3
+ %float_0 = OpConstant %float 0
+ %v2float = OpTypeVector %float 2
+ %v3float = OpTypeVector %float 3
+ %v4float = OpTypeVector %float 4
+ %13 = OpConstantNull %v2float
+ %14 = OpConstantNull %v3float
+ %15 = OpConstantNull %v4float
+ %void = OpTypeVoid
+ %voidfn = OpTypeFunction %void
+ %10 = OpTypeImage %float 2D 0 1 0 1 Unknown
+ %11 = OpTypeSampledImage %10
+%_ptr_UniformConstant_11 = OpTypePointer UniformConstant %11
+
+ %100 = OpVariable %_ptr_UniformConstant_11 UniformConstant
+ %main = OpFunction %void None %voidfn
+ %main_0 = OpLabel
+ %101 = OpCopyObject %_ptr_UniformConstant_11 %100
+ %102 = OpLoad %11 %101
+ %103 = OpCopyObject %_ptr_UniformConstant_11 %101
+ %104 = OpCopyObject %11 %102 ;; this copy survives
+ OpReturn
+ OpFunctionEnd
+
+ ; The OpCopyObject instructions are removed.
+ ; The load of the combined image+sampler is replaced by a two loads, then
+ ; a combination operation. The only OpCopyObject that remains is the copy
+ ; of the copy of the sampled image value.
+ ; CHECK: %[[im:\d+]] = OpLoad %10 %[[image_var]]
+ ; CHECK: %[[s:\d+]] = OpLoad %[[sampler_ty]] %[[sampler_var]]
+ ; CHECK: %[[si:\d+]] = OpSampledImage %11 %[[im]] %[[s]]
+ ; CHECK-NEXT: OpCopyObject %11 %[[si]]
+ ; CHECK-NEXT: OpReturn
diff --git a/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_DeletesCopyObjectOfPtr_20.spvasm b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_DeletesCopyObjectOfPtr_20.spvasm
new file mode 100644
index 0000000..d8f9e99
--- /dev/null
+++ b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_DeletesCopyObjectOfPtr_20.spvasm
@@ -0,0 +1,71 @@
+ OpCapability Shader
+ OpCapability RuntimeDescriptorArray
+ OpExtension "SPV_EXT_descriptor_indexing"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ OpName %main "main"
+ OpName %main_0 "main_0"
+ OpName %voidfn "voidfn"
+
+ OpDecorate %100 DescriptorSet 0
+ OpDecorate %100 Binding 0
+
+ ; CHECK: OpName
+ ; CHECK-NOT: OpDecorate %100
+ ; CHECK: OpDecorate %[[image_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[sampler_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[image_var]] Binding 0
+ ; CHECK: OpDecorate %[[sampler_var]] Binding 0
+
+ ; CHECK: %10 = OpTypeImage %
+ ; CHECK: %[[image_ptr_ty:\w+]] = OpTypePointer UniformConstant %10
+ ; CHECK: %[[sampler_ty:\d+]] = OpTypeSampler
+ ; CHECK: %[[sampler_ptr_ty:\w+]] = OpTypePointer UniformConstant %[[sampler_ty]]
+
+ ; The combined image variable is replaced by an image variable and a sampler variable.
+
+ ; CHECK-NOT: %100 = OpVariable
+ ; CHECK-DAG: %[[sampler_var]] = OpVariable %[[sampler_ptr_ty]] UniformConstant
+ ; CHECK-DAG: %[[image_var]] = OpVariable %[[image_ptr_ty]] UniformConstant
+ ; CHECK: = OpFunction
+
+
+ %float = OpTypeFloat 32
+ %uint = OpTypeInt 32 0
+ %int = OpTypeInt 32 1
+ %uint_0 = OpConstant %uint 0
+ %uint_1 = OpConstant %uint 1
+ %uint_3 = OpConstant %uint 3
+ %float_0 = OpConstant %float 0
+ %v2float = OpTypeVector %float 2
+ %v3float = OpTypeVector %float 3
+ %v4float = OpTypeVector %float 4
+ %13 = OpConstantNull %v2float
+ %14 = OpConstantNull %v3float
+ %15 = OpConstantNull %v4float
+ %void = OpTypeVoid
+ %voidfn = OpTypeFunction %void
+ %10 = OpTypeImage %int Cube 0 1 0 1 Unknown
+ %11 = OpTypeSampledImage %10
+%_ptr_UniformConstant_11 = OpTypePointer UniformConstant %11
+
+ %100 = OpVariable %_ptr_UniformConstant_11 UniformConstant
+ %main = OpFunction %void None %voidfn
+ %main_0 = OpLabel
+ %101 = OpCopyObject %_ptr_UniformConstant_11 %100
+ %102 = OpLoad %11 %101
+ %103 = OpCopyObject %_ptr_UniformConstant_11 %101
+ %104 = OpCopyObject %11 %102 ;; this copy survives
+ OpReturn
+ OpFunctionEnd
+
+ ; The OpCopyObject instructions are removed.
+ ; The load of the combined image+sampler is replaced by a two loads, then
+ ; a combination operation. The only OpCopyObject that remains is the copy
+ ; of the copy of the sampled image value.
+ ; CHECK: %[[im:\d+]] = OpLoad %10 %[[image_var]]
+ ; CHECK: %[[s:\d+]] = OpLoad %[[sampler_ty]] %[[sampler_var]]
+ ; CHECK: %[[si:\d+]] = OpSampledImage %11 %[[im]] %[[s]]
+ ; CHECK-NEXT: OpCopyObject %11 %[[si]]
+ ; CHECK-NEXT: OpReturn
diff --git a/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_DeletesCopyObjectOfPtr_21.spvasm b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_DeletesCopyObjectOfPtr_21.spvasm
new file mode 100644
index 0000000..a6696cb
--- /dev/null
+++ b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_DeletesCopyObjectOfPtr_21.spvasm
@@ -0,0 +1,71 @@
+ OpCapability Shader
+ OpCapability RuntimeDescriptorArray
+ OpExtension "SPV_EXT_descriptor_indexing"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ OpName %main "main"
+ OpName %main_0 "main_0"
+ OpName %voidfn "voidfn"
+
+ OpDecorate %100 DescriptorSet 0
+ OpDecorate %100 Binding 0
+
+ ; CHECK: OpName
+ ; CHECK-NOT: OpDecorate %100
+ ; CHECK: OpDecorate %[[image_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[sampler_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[image_var]] Binding 0
+ ; CHECK: OpDecorate %[[sampler_var]] Binding 0
+
+ ; CHECK: %10 = OpTypeImage %
+ ; CHECK: %[[image_ptr_ty:\w+]] = OpTypePointer UniformConstant %10
+ ; CHECK: %[[sampler_ty:\d+]] = OpTypeSampler
+ ; CHECK: %[[sampler_ptr_ty:\w+]] = OpTypePointer UniformConstant %[[sampler_ty]]
+
+ ; The combined image variable is replaced by an image variable and a sampler variable.
+
+ ; CHECK-NOT: %100 = OpVariable
+ ; CHECK-DAG: %[[sampler_var]] = OpVariable %[[sampler_ptr_ty]] UniformConstant
+ ; CHECK-DAG: %[[image_var]] = OpVariable %[[image_ptr_ty]] UniformConstant
+ ; CHECK: = OpFunction
+
+
+ %float = OpTypeFloat 32
+ %uint = OpTypeInt 32 0
+ %int = OpTypeInt 32 1
+ %uint_0 = OpConstant %uint 0
+ %uint_1 = OpConstant %uint 1
+ %uint_3 = OpConstant %uint 3
+ %float_0 = OpConstant %float 0
+ %v2float = OpTypeVector %float 2
+ %v3float = OpTypeVector %float 3
+ %v4float = OpTypeVector %float 4
+ %13 = OpConstantNull %v2float
+ %14 = OpConstantNull %v3float
+ %15 = OpConstantNull %v4float
+ %void = OpTypeVoid
+ %voidfn = OpTypeFunction %void
+ %10 = OpTypeImage %int Cube 1 1 0 1 Unknown
+ %11 = OpTypeSampledImage %10
+%_ptr_UniformConstant_11 = OpTypePointer UniformConstant %11
+
+ %100 = OpVariable %_ptr_UniformConstant_11 UniformConstant
+ %main = OpFunction %void None %voidfn
+ %main_0 = OpLabel
+ %101 = OpCopyObject %_ptr_UniformConstant_11 %100
+ %102 = OpLoad %11 %101
+ %103 = OpCopyObject %_ptr_UniformConstant_11 %101
+ %104 = OpCopyObject %11 %102 ;; this copy survives
+ OpReturn
+ OpFunctionEnd
+
+ ; The OpCopyObject instructions are removed.
+ ; The load of the combined image+sampler is replaced by a two loads, then
+ ; a combination operation. The only OpCopyObject that remains is the copy
+ ; of the copy of the sampled image value.
+ ; CHECK: %[[im:\d+]] = OpLoad %10 %[[image_var]]
+ ; CHECK: %[[s:\d+]] = OpLoad %[[sampler_ty]] %[[sampler_var]]
+ ; CHECK: %[[si:\d+]] = OpSampledImage %11 %[[im]] %[[s]]
+ ; CHECK-NEXT: OpCopyObject %11 %[[si]]
+ ; CHECK-NEXT: OpReturn
diff --git a/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_DeletesCopyObjectOfPtr_22.spvasm b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_DeletesCopyObjectOfPtr_22.spvasm
new file mode 100644
index 0000000..0ac0b6e
--- /dev/null
+++ b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_DeletesCopyObjectOfPtr_22.spvasm
@@ -0,0 +1,71 @@
+ OpCapability Shader
+ OpCapability RuntimeDescriptorArray
+ OpExtension "SPV_EXT_descriptor_indexing"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ OpName %main "main"
+ OpName %main_0 "main_0"
+ OpName %voidfn "voidfn"
+
+ OpDecorate %100 DescriptorSet 0
+ OpDecorate %100 Binding 0
+
+ ; CHECK: OpName
+ ; CHECK-NOT: OpDecorate %100
+ ; CHECK: OpDecorate %[[image_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[sampler_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[image_var]] Binding 0
+ ; CHECK: OpDecorate %[[sampler_var]] Binding 0
+
+ ; CHECK: %10 = OpTypeImage %
+ ; CHECK: %[[image_ptr_ty:\w+]] = OpTypePointer UniformConstant %10
+ ; CHECK: %[[sampler_ty:\d+]] = OpTypeSampler
+ ; CHECK: %[[sampler_ptr_ty:\w+]] = OpTypePointer UniformConstant %[[sampler_ty]]
+
+ ; The combined image variable is replaced by an image variable and a sampler variable.
+
+ ; CHECK-NOT: %100 = OpVariable
+ ; CHECK-DAG: %[[sampler_var]] = OpVariable %[[sampler_ptr_ty]] UniformConstant
+ ; CHECK-DAG: %[[image_var]] = OpVariable %[[image_ptr_ty]] UniformConstant
+ ; CHECK: = OpFunction
+
+
+ %float = OpTypeFloat 32
+ %uint = OpTypeInt 32 0
+ %int = OpTypeInt 32 1
+ %uint_0 = OpConstant %uint 0
+ %uint_1 = OpConstant %uint 1
+ %uint_3 = OpConstant %uint 3
+ %float_0 = OpConstant %float 0
+ %v2float = OpTypeVector %float 2
+ %v3float = OpTypeVector %float 3
+ %v4float = OpTypeVector %float 4
+ %13 = OpConstantNull %v2float
+ %14 = OpConstantNull %v3float
+ %15 = OpConstantNull %v4float
+ %void = OpTypeVoid
+ %voidfn = OpTypeFunction %void
+ %10 = OpTypeImage %uint 2D 0 0 0 1 Unknown
+ %11 = OpTypeSampledImage %10
+%_ptr_UniformConstant_11 = OpTypePointer UniformConstant %11
+
+ %100 = OpVariable %_ptr_UniformConstant_11 UniformConstant
+ %main = OpFunction %void None %voidfn
+ %main_0 = OpLabel
+ %101 = OpCopyObject %_ptr_UniformConstant_11 %100
+ %102 = OpLoad %11 %101
+ %103 = OpCopyObject %_ptr_UniformConstant_11 %101
+ %104 = OpCopyObject %11 %102 ;; this copy survives
+ OpReturn
+ OpFunctionEnd
+
+ ; The OpCopyObject instructions are removed.
+ ; The load of the combined image+sampler is replaced by a two loads, then
+ ; a combination operation. The only OpCopyObject that remains is the copy
+ ; of the copy of the sampled image value.
+ ; CHECK: %[[im:\d+]] = OpLoad %10 %[[image_var]]
+ ; CHECK: %[[s:\d+]] = OpLoad %[[sampler_ty]] %[[sampler_var]]
+ ; CHECK: %[[si:\d+]] = OpSampledImage %11 %[[im]] %[[s]]
+ ; CHECK-NEXT: OpCopyObject %11 %[[si]]
+ ; CHECK-NEXT: OpReturn
diff --git a/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_DeletesCopyObjectOfPtr_23.spvasm b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_DeletesCopyObjectOfPtr_23.spvasm
new file mode 100644
index 0000000..18ef056
--- /dev/null
+++ b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_DeletesCopyObjectOfPtr_23.spvasm
@@ -0,0 +1,71 @@
+ OpCapability Shader
+ OpCapability RuntimeDescriptorArray
+ OpExtension "SPV_EXT_descriptor_indexing"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ OpName %main "main"
+ OpName %main_0 "main_0"
+ OpName %voidfn "voidfn"
+
+ OpDecorate %100 DescriptorSet 0
+ OpDecorate %100 Binding 0
+
+ ; CHECK: OpName
+ ; CHECK-NOT: OpDecorate %100
+ ; CHECK: OpDecorate %[[image_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[sampler_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[image_var]] Binding 0
+ ; CHECK: OpDecorate %[[sampler_var]] Binding 0
+
+ ; CHECK: %10 = OpTypeImage %
+ ; CHECK: %[[image_ptr_ty:\w+]] = OpTypePointer UniformConstant %10
+ ; CHECK: %[[sampler_ty:\d+]] = OpTypeSampler
+ ; CHECK: %[[sampler_ptr_ty:\w+]] = OpTypePointer UniformConstant %[[sampler_ty]]
+
+ ; The combined image variable is replaced by an image variable and a sampler variable.
+
+ ; CHECK-NOT: %100 = OpVariable
+ ; CHECK-DAG: %[[sampler_var]] = OpVariable %[[sampler_ptr_ty]] UniformConstant
+ ; CHECK-DAG: %[[image_var]] = OpVariable %[[image_ptr_ty]] UniformConstant
+ ; CHECK: = OpFunction
+
+
+ %float = OpTypeFloat 32
+ %uint = OpTypeInt 32 0
+ %int = OpTypeInt 32 1
+ %uint_0 = OpConstant %uint 0
+ %uint_1 = OpConstant %uint 1
+ %uint_3 = OpConstant %uint 3
+ %float_0 = OpConstant %float 0
+ %v2float = OpTypeVector %float 2
+ %v3float = OpTypeVector %float 3
+ %v4float = OpTypeVector %float 4
+ %13 = OpConstantNull %v2float
+ %14 = OpConstantNull %v3float
+ %15 = OpConstantNull %v4float
+ %void = OpTypeVoid
+ %voidfn = OpTypeFunction %void
+ %10 = OpTypeImage %uint 2D 1 0 0 1 Unknown
+ %11 = OpTypeSampledImage %10
+%_ptr_UniformConstant_11 = OpTypePointer UniformConstant %11
+
+ %100 = OpVariable %_ptr_UniformConstant_11 UniformConstant
+ %main = OpFunction %void None %voidfn
+ %main_0 = OpLabel
+ %101 = OpCopyObject %_ptr_UniformConstant_11 %100
+ %102 = OpLoad %11 %101
+ %103 = OpCopyObject %_ptr_UniformConstant_11 %101
+ %104 = OpCopyObject %11 %102 ;; this copy survives
+ OpReturn
+ OpFunctionEnd
+
+ ; The OpCopyObject instructions are removed.
+ ; The load of the combined image+sampler is replaced by a two loads, then
+ ; a combination operation. The only OpCopyObject that remains is the copy
+ ; of the copy of the sampled image value.
+ ; CHECK: %[[im:\d+]] = OpLoad %10 %[[image_var]]
+ ; CHECK: %[[s:\d+]] = OpLoad %[[sampler_ty]] %[[sampler_var]]
+ ; CHECK: %[[si:\d+]] = OpSampledImage %11 %[[im]] %[[s]]
+ ; CHECK-NEXT: OpCopyObject %11 %[[si]]
+ ; CHECK-NEXT: OpReturn
diff --git a/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_DeletesCopyObjectOfPtr_24.spvasm b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_DeletesCopyObjectOfPtr_24.spvasm
new file mode 100644
index 0000000..4e9ec69
--- /dev/null
+++ b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_DeletesCopyObjectOfPtr_24.spvasm
@@ -0,0 +1,71 @@
+ OpCapability Shader
+ OpCapability RuntimeDescriptorArray
+ OpExtension "SPV_EXT_descriptor_indexing"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ OpName %main "main"
+ OpName %main_0 "main_0"
+ OpName %voidfn "voidfn"
+
+ OpDecorate %100 DescriptorSet 0
+ OpDecorate %100 Binding 0
+
+ ; CHECK: OpName
+ ; CHECK-NOT: OpDecorate %100
+ ; CHECK: OpDecorate %[[image_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[sampler_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[image_var]] Binding 0
+ ; CHECK: OpDecorate %[[sampler_var]] Binding 0
+
+ ; CHECK: %10 = OpTypeImage %
+ ; CHECK: %[[image_ptr_ty:\w+]] = OpTypePointer UniformConstant %10
+ ; CHECK: %[[sampler_ty:\d+]] = OpTypeSampler
+ ; CHECK: %[[sampler_ptr_ty:\w+]] = OpTypePointer UniformConstant %[[sampler_ty]]
+
+ ; The combined image variable is replaced by an image variable and a sampler variable.
+
+ ; CHECK-NOT: %100 = OpVariable
+ ; CHECK-DAG: %[[sampler_var]] = OpVariable %[[sampler_ptr_ty]] UniformConstant
+ ; CHECK-DAG: %[[image_var]] = OpVariable %[[image_ptr_ty]] UniformConstant
+ ; CHECK: = OpFunction
+
+
+ %float = OpTypeFloat 32
+ %uint = OpTypeInt 32 0
+ %int = OpTypeInt 32 1
+ %uint_0 = OpConstant %uint 0
+ %uint_1 = OpConstant %uint 1
+ %uint_3 = OpConstant %uint 3
+ %float_0 = OpConstant %float 0
+ %v2float = OpTypeVector %float 2
+ %v3float = OpTypeVector %float 3
+ %v4float = OpTypeVector %float 4
+ %13 = OpConstantNull %v2float
+ %14 = OpConstantNull %v3float
+ %15 = OpConstantNull %v4float
+ %void = OpTypeVoid
+ %voidfn = OpTypeFunction %void
+ %10 = OpTypeImage %uint 2D 0 1 0 1 Unknown
+ %11 = OpTypeSampledImage %10
+%_ptr_UniformConstant_11 = OpTypePointer UniformConstant %11
+
+ %100 = OpVariable %_ptr_UniformConstant_11 UniformConstant
+ %main = OpFunction %void None %voidfn
+ %main_0 = OpLabel
+ %101 = OpCopyObject %_ptr_UniformConstant_11 %100
+ %102 = OpLoad %11 %101
+ %103 = OpCopyObject %_ptr_UniformConstant_11 %101
+ %104 = OpCopyObject %11 %102 ;; this copy survives
+ OpReturn
+ OpFunctionEnd
+
+ ; The OpCopyObject instructions are removed.
+ ; The load of the combined image+sampler is replaced by a two loads, then
+ ; a combination operation. The only OpCopyObject that remains is the copy
+ ; of the copy of the sampled image value.
+ ; CHECK: %[[im:\d+]] = OpLoad %10 %[[image_var]]
+ ; CHECK: %[[s:\d+]] = OpLoad %[[sampler_ty]] %[[sampler_var]]
+ ; CHECK: %[[si:\d+]] = OpSampledImage %11 %[[im]] %[[s]]
+ ; CHECK-NEXT: OpCopyObject %11 %[[si]]
+ ; CHECK-NEXT: OpReturn
diff --git a/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_DeletesCopyObjectOfPtr_25.spvasm b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_DeletesCopyObjectOfPtr_25.spvasm
new file mode 100644
index 0000000..a512ce3
--- /dev/null
+++ b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_DeletesCopyObjectOfPtr_25.spvasm
@@ -0,0 +1,71 @@
+ OpCapability Shader
+ OpCapability RuntimeDescriptorArray
+ OpExtension "SPV_EXT_descriptor_indexing"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ OpName %main "main"
+ OpName %main_0 "main_0"
+ OpName %voidfn "voidfn"
+
+ OpDecorate %100 DescriptorSet 0
+ OpDecorate %100 Binding 0
+
+ ; CHECK: OpName
+ ; CHECK-NOT: OpDecorate %100
+ ; CHECK: OpDecorate %[[image_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[sampler_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[image_var]] Binding 0
+ ; CHECK: OpDecorate %[[sampler_var]] Binding 0
+
+ ; CHECK: %10 = OpTypeImage %
+ ; CHECK: %[[image_ptr_ty:\w+]] = OpTypePointer UniformConstant %10
+ ; CHECK: %[[sampler_ty:\d+]] = OpTypeSampler
+ ; CHECK: %[[sampler_ptr_ty:\w+]] = OpTypePointer UniformConstant %[[sampler_ty]]
+
+ ; The combined image variable is replaced by an image variable and a sampler variable.
+
+ ; CHECK-NOT: %100 = OpVariable
+ ; CHECK-DAG: %[[sampler_var]] = OpVariable %[[sampler_ptr_ty]] UniformConstant
+ ; CHECK-DAG: %[[image_var]] = OpVariable %[[image_ptr_ty]] UniformConstant
+ ; CHECK: = OpFunction
+
+
+ %float = OpTypeFloat 32
+ %uint = OpTypeInt 32 0
+ %int = OpTypeInt 32 1
+ %uint_0 = OpConstant %uint 0
+ %uint_1 = OpConstant %uint 1
+ %uint_3 = OpConstant %uint 3
+ %float_0 = OpConstant %float 0
+ %v2float = OpTypeVector %float 2
+ %v3float = OpTypeVector %float 3
+ %v4float = OpTypeVector %float 4
+ %13 = OpConstantNull %v2float
+ %14 = OpConstantNull %v3float
+ %15 = OpConstantNull %v4float
+ %void = OpTypeVoid
+ %voidfn = OpTypeFunction %void
+ %10 = OpTypeImage %uint 2D 1 1 0 1 Unknown
+ %11 = OpTypeSampledImage %10
+%_ptr_UniformConstant_11 = OpTypePointer UniformConstant %11
+
+ %100 = OpVariable %_ptr_UniformConstant_11 UniformConstant
+ %main = OpFunction %void None %voidfn
+ %main_0 = OpLabel
+ %101 = OpCopyObject %_ptr_UniformConstant_11 %100
+ %102 = OpLoad %11 %101
+ %103 = OpCopyObject %_ptr_UniformConstant_11 %101
+ %104 = OpCopyObject %11 %102 ;; this copy survives
+ OpReturn
+ OpFunctionEnd
+
+ ; The OpCopyObject instructions are removed.
+ ; The load of the combined image+sampler is replaced by a two loads, then
+ ; a combination operation. The only OpCopyObject that remains is the copy
+ ; of the copy of the sampled image value.
+ ; CHECK: %[[im:\d+]] = OpLoad %10 %[[image_var]]
+ ; CHECK: %[[s:\d+]] = OpLoad %[[sampler_ty]] %[[sampler_var]]
+ ; CHECK: %[[si:\d+]] = OpSampledImage %11 %[[im]] %[[s]]
+ ; CHECK-NEXT: OpCopyObject %11 %[[si]]
+ ; CHECK-NEXT: OpReturn
diff --git a/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_DeletesCopyObjectOfPtr_26.spvasm b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_DeletesCopyObjectOfPtr_26.spvasm
new file mode 100644
index 0000000..c0e2750
--- /dev/null
+++ b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_DeletesCopyObjectOfPtr_26.spvasm
@@ -0,0 +1,71 @@
+ OpCapability Shader
+ OpCapability RuntimeDescriptorArray
+ OpExtension "SPV_EXT_descriptor_indexing"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ OpName %main "main"
+ OpName %main_0 "main_0"
+ OpName %voidfn "voidfn"
+
+ OpDecorate %100 DescriptorSet 0
+ OpDecorate %100 Binding 0
+
+ ; CHECK: OpName
+ ; CHECK-NOT: OpDecorate %100
+ ; CHECK: OpDecorate %[[image_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[sampler_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[image_var]] Binding 0
+ ; CHECK: OpDecorate %[[sampler_var]] Binding 0
+
+ ; CHECK: %10 = OpTypeImage %
+ ; CHECK: %[[image_ptr_ty:\w+]] = OpTypePointer UniformConstant %10
+ ; CHECK: %[[sampler_ty:\d+]] = OpTypeSampler
+ ; CHECK: %[[sampler_ptr_ty:\w+]] = OpTypePointer UniformConstant %[[sampler_ty]]
+
+ ; The combined image variable is replaced by an image variable and a sampler variable.
+
+ ; CHECK-NOT: %100 = OpVariable
+ ; CHECK-DAG: %[[sampler_var]] = OpVariable %[[sampler_ptr_ty]] UniformConstant
+ ; CHECK-DAG: %[[image_var]] = OpVariable %[[image_ptr_ty]] UniformConstant
+ ; CHECK: = OpFunction
+
+
+ %float = OpTypeFloat 32
+ %uint = OpTypeInt 32 0
+ %int = OpTypeInt 32 1
+ %uint_0 = OpConstant %uint 0
+ %uint_1 = OpConstant %uint 1
+ %uint_3 = OpConstant %uint 3
+ %float_0 = OpConstant %float 0
+ %v2float = OpTypeVector %float 2
+ %v3float = OpTypeVector %float 3
+ %v4float = OpTypeVector %float 4
+ %13 = OpConstantNull %v2float
+ %14 = OpConstantNull %v3float
+ %15 = OpConstantNull %v4float
+ %void = OpTypeVoid
+ %voidfn = OpTypeFunction %void
+ %10 = OpTypeImage %uint 2D 0 0 1 1 Unknown
+ %11 = OpTypeSampledImage %10
+%_ptr_UniformConstant_11 = OpTypePointer UniformConstant %11
+
+ %100 = OpVariable %_ptr_UniformConstant_11 UniformConstant
+ %main = OpFunction %void None %voidfn
+ %main_0 = OpLabel
+ %101 = OpCopyObject %_ptr_UniformConstant_11 %100
+ %102 = OpLoad %11 %101
+ %103 = OpCopyObject %_ptr_UniformConstant_11 %101
+ %104 = OpCopyObject %11 %102 ;; this copy survives
+ OpReturn
+ OpFunctionEnd
+
+ ; The OpCopyObject instructions are removed.
+ ; The load of the combined image+sampler is replaced by a two loads, then
+ ; a combination operation. The only OpCopyObject that remains is the copy
+ ; of the copy of the sampled image value.
+ ; CHECK: %[[im:\d+]] = OpLoad %10 %[[image_var]]
+ ; CHECK: %[[s:\d+]] = OpLoad %[[sampler_ty]] %[[sampler_var]]
+ ; CHECK: %[[si:\d+]] = OpSampledImage %11 %[[im]] %[[s]]
+ ; CHECK-NEXT: OpCopyObject %11 %[[si]]
+ ; CHECK-NEXT: OpReturn
diff --git a/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_DeletesCopyObjectOfPtr_28.spvasm b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_DeletesCopyObjectOfPtr_28.spvasm
new file mode 100644
index 0000000..f708b27
--- /dev/null
+++ b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_DeletesCopyObjectOfPtr_28.spvasm
@@ -0,0 +1,71 @@
+ OpCapability Shader
+ OpCapability RuntimeDescriptorArray
+ OpExtension "SPV_EXT_descriptor_indexing"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ OpName %main "main"
+ OpName %main_0 "main_0"
+ OpName %voidfn "voidfn"
+
+ OpDecorate %100 DescriptorSet 0
+ OpDecorate %100 Binding 0
+
+ ; CHECK: OpName
+ ; CHECK-NOT: OpDecorate %100
+ ; CHECK: OpDecorate %[[image_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[sampler_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[image_var]] Binding 0
+ ; CHECK: OpDecorate %[[sampler_var]] Binding 0
+
+ ; CHECK: %10 = OpTypeImage %
+ ; CHECK: %[[image_ptr_ty:\w+]] = OpTypePointer UniformConstant %10
+ ; CHECK: %[[sampler_ty:\d+]] = OpTypeSampler
+ ; CHECK: %[[sampler_ptr_ty:\w+]] = OpTypePointer UniformConstant %[[sampler_ty]]
+
+ ; The combined image variable is replaced by an image variable and a sampler variable.
+
+ ; CHECK-NOT: %100 = OpVariable
+ ; CHECK-DAG: %[[sampler_var]] = OpVariable %[[sampler_ptr_ty]] UniformConstant
+ ; CHECK-DAG: %[[image_var]] = OpVariable %[[image_ptr_ty]] UniformConstant
+ ; CHECK: = OpFunction
+
+
+ %float = OpTypeFloat 32
+ %uint = OpTypeInt 32 0
+ %int = OpTypeInt 32 1
+ %uint_0 = OpConstant %uint 0
+ %uint_1 = OpConstant %uint 1
+ %uint_3 = OpConstant %uint 3
+ %float_0 = OpConstant %float 0
+ %v2float = OpTypeVector %float 2
+ %v3float = OpTypeVector %float 3
+ %v4float = OpTypeVector %float 4
+ %13 = OpConstantNull %v2float
+ %14 = OpConstantNull %v3float
+ %15 = OpConstantNull %v4float
+ %void = OpTypeVoid
+ %voidfn = OpTypeFunction %void
+ %10 = OpTypeImage %uint 3D 0 0 0 1 Unknown
+ %11 = OpTypeSampledImage %10
+%_ptr_UniformConstant_11 = OpTypePointer UniformConstant %11
+
+ %100 = OpVariable %_ptr_UniformConstant_11 UniformConstant
+ %main = OpFunction %void None %voidfn
+ %main_0 = OpLabel
+ %101 = OpCopyObject %_ptr_UniformConstant_11 %100
+ %102 = OpLoad %11 %101
+ %103 = OpCopyObject %_ptr_UniformConstant_11 %101
+ %104 = OpCopyObject %11 %102 ;; this copy survives
+ OpReturn
+ OpFunctionEnd
+
+ ; The OpCopyObject instructions are removed.
+ ; The load of the combined image+sampler is replaced by a two loads, then
+ ; a combination operation. The only OpCopyObject that remains is the copy
+ ; of the copy of the sampled image value.
+ ; CHECK: %[[im:\d+]] = OpLoad %10 %[[image_var]]
+ ; CHECK: %[[s:\d+]] = OpLoad %[[sampler_ty]] %[[sampler_var]]
+ ; CHECK: %[[si:\d+]] = OpSampledImage %11 %[[im]] %[[s]]
+ ; CHECK-NEXT: OpCopyObject %11 %[[si]]
+ ; CHECK-NEXT: OpReturn
diff --git a/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_DeletesCopyObjectOfPtr_29.spvasm b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_DeletesCopyObjectOfPtr_29.spvasm
new file mode 100644
index 0000000..c08fc68
--- /dev/null
+++ b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_DeletesCopyObjectOfPtr_29.spvasm
@@ -0,0 +1,71 @@
+ OpCapability Shader
+ OpCapability RuntimeDescriptorArray
+ OpExtension "SPV_EXT_descriptor_indexing"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ OpName %main "main"
+ OpName %main_0 "main_0"
+ OpName %voidfn "voidfn"
+
+ OpDecorate %100 DescriptorSet 0
+ OpDecorate %100 Binding 0
+
+ ; CHECK: OpName
+ ; CHECK-NOT: OpDecorate %100
+ ; CHECK: OpDecorate %[[image_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[sampler_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[image_var]] Binding 0
+ ; CHECK: OpDecorate %[[sampler_var]] Binding 0
+
+ ; CHECK: %10 = OpTypeImage %
+ ; CHECK: %[[image_ptr_ty:\w+]] = OpTypePointer UniformConstant %10
+ ; CHECK: %[[sampler_ty:\d+]] = OpTypeSampler
+ ; CHECK: %[[sampler_ptr_ty:\w+]] = OpTypePointer UniformConstant %[[sampler_ty]]
+
+ ; The combined image variable is replaced by an image variable and a sampler variable.
+
+ ; CHECK-NOT: %100 = OpVariable
+ ; CHECK-DAG: %[[sampler_var]] = OpVariable %[[sampler_ptr_ty]] UniformConstant
+ ; CHECK-DAG: %[[image_var]] = OpVariable %[[image_ptr_ty]] UniformConstant
+ ; CHECK: = OpFunction
+
+
+ %float = OpTypeFloat 32
+ %uint = OpTypeInt 32 0
+ %int = OpTypeInt 32 1
+ %uint_0 = OpConstant %uint 0
+ %uint_1 = OpConstant %uint 1
+ %uint_3 = OpConstant %uint 3
+ %float_0 = OpConstant %float 0
+ %v2float = OpTypeVector %float 2
+ %v3float = OpTypeVector %float 3
+ %v4float = OpTypeVector %float 4
+ %13 = OpConstantNull %v2float
+ %14 = OpConstantNull %v3float
+ %15 = OpConstantNull %v4float
+ %void = OpTypeVoid
+ %voidfn = OpTypeFunction %void
+ %10 = OpTypeImage %uint Cube 0 0 0 1 Unknown
+ %11 = OpTypeSampledImage %10
+%_ptr_UniformConstant_11 = OpTypePointer UniformConstant %11
+
+ %100 = OpVariable %_ptr_UniformConstant_11 UniformConstant
+ %main = OpFunction %void None %voidfn
+ %main_0 = OpLabel
+ %101 = OpCopyObject %_ptr_UniformConstant_11 %100
+ %102 = OpLoad %11 %101
+ %103 = OpCopyObject %_ptr_UniformConstant_11 %101
+ %104 = OpCopyObject %11 %102 ;; this copy survives
+ OpReturn
+ OpFunctionEnd
+
+ ; The OpCopyObject instructions are removed.
+ ; The load of the combined image+sampler is replaced by a two loads, then
+ ; a combination operation. The only OpCopyObject that remains is the copy
+ ; of the copy of the sampled image value.
+ ; CHECK: %[[im:\d+]] = OpLoad %10 %[[image_var]]
+ ; CHECK: %[[s:\d+]] = OpLoad %[[sampler_ty]] %[[sampler_var]]
+ ; CHECK: %[[si:\d+]] = OpSampledImage %11 %[[im]] %[[s]]
+ ; CHECK-NEXT: OpCopyObject %11 %[[si]]
+ ; CHECK-NEXT: OpReturn
diff --git a/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_DeletesCopyObjectOfPtr_3.spvasm b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_DeletesCopyObjectOfPtr_3.spvasm
new file mode 100644
index 0000000..afc9e44
--- /dev/null
+++ b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_DeletesCopyObjectOfPtr_3.spvasm
@@ -0,0 +1,71 @@
+ OpCapability Shader
+ OpCapability RuntimeDescriptorArray
+ OpExtension "SPV_EXT_descriptor_indexing"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ OpName %main "main"
+ OpName %main_0 "main_0"
+ OpName %voidfn "voidfn"
+
+ OpDecorate %100 DescriptorSet 0
+ OpDecorate %100 Binding 0
+
+ ; CHECK: OpName
+ ; CHECK-NOT: OpDecorate %100
+ ; CHECK: OpDecorate %[[image_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[sampler_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[image_var]] Binding 0
+ ; CHECK: OpDecorate %[[sampler_var]] Binding 0
+
+ ; CHECK: %10 = OpTypeImage %
+ ; CHECK: %[[image_ptr_ty:\w+]] = OpTypePointer UniformConstant %10
+ ; CHECK: %[[sampler_ty:\d+]] = OpTypeSampler
+ ; CHECK: %[[sampler_ptr_ty:\w+]] = OpTypePointer UniformConstant %[[sampler_ty]]
+
+ ; The combined image variable is replaced by an image variable and a sampler variable.
+
+ ; CHECK-NOT: %100 = OpVariable
+ ; CHECK-DAG: %[[sampler_var]] = OpVariable %[[sampler_ptr_ty]] UniformConstant
+ ; CHECK-DAG: %[[image_var]] = OpVariable %[[image_ptr_ty]] UniformConstant
+ ; CHECK: = OpFunction
+
+
+ %float = OpTypeFloat 32
+ %uint = OpTypeInt 32 0
+ %int = OpTypeInt 32 1
+ %uint_0 = OpConstant %uint 0
+ %uint_1 = OpConstant %uint 1
+ %uint_3 = OpConstant %uint 3
+ %float_0 = OpConstant %float 0
+ %v2float = OpTypeVector %float 2
+ %v3float = OpTypeVector %float 3
+ %v4float = OpTypeVector %float 4
+ %13 = OpConstantNull %v2float
+ %14 = OpConstantNull %v3float
+ %15 = OpConstantNull %v4float
+ %void = OpTypeVoid
+ %voidfn = OpTypeFunction %void
+ %10 = OpTypeImage %float 2D 1 1 0 1 Unknown
+ %11 = OpTypeSampledImage %10
+%_ptr_UniformConstant_11 = OpTypePointer UniformConstant %11
+
+ %100 = OpVariable %_ptr_UniformConstant_11 UniformConstant
+ %main = OpFunction %void None %voidfn
+ %main_0 = OpLabel
+ %101 = OpCopyObject %_ptr_UniformConstant_11 %100
+ %102 = OpLoad %11 %101
+ %103 = OpCopyObject %_ptr_UniformConstant_11 %101
+ %104 = OpCopyObject %11 %102 ;; this copy survives
+ OpReturn
+ OpFunctionEnd
+
+ ; The OpCopyObject instructions are removed.
+ ; The load of the combined image+sampler is replaced by a two loads, then
+ ; a combination operation. The only OpCopyObject that remains is the copy
+ ; of the copy of the sampled image value.
+ ; CHECK: %[[im:\d+]] = OpLoad %10 %[[image_var]]
+ ; CHECK: %[[s:\d+]] = OpLoad %[[sampler_ty]] %[[sampler_var]]
+ ; CHECK: %[[si:\d+]] = OpSampledImage %11 %[[im]] %[[s]]
+ ; CHECK-NEXT: OpCopyObject %11 %[[si]]
+ ; CHECK-NEXT: OpReturn
diff --git a/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_DeletesCopyObjectOfPtr_30.spvasm b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_DeletesCopyObjectOfPtr_30.spvasm
new file mode 100644
index 0000000..a118c89
--- /dev/null
+++ b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_DeletesCopyObjectOfPtr_30.spvasm
@@ -0,0 +1,71 @@
+ OpCapability Shader
+ OpCapability RuntimeDescriptorArray
+ OpExtension "SPV_EXT_descriptor_indexing"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ OpName %main "main"
+ OpName %main_0 "main_0"
+ OpName %voidfn "voidfn"
+
+ OpDecorate %100 DescriptorSet 0
+ OpDecorate %100 Binding 0
+
+ ; CHECK: OpName
+ ; CHECK-NOT: OpDecorate %100
+ ; CHECK: OpDecorate %[[image_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[sampler_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[image_var]] Binding 0
+ ; CHECK: OpDecorate %[[sampler_var]] Binding 0
+
+ ; CHECK: %10 = OpTypeImage %
+ ; CHECK: %[[image_ptr_ty:\w+]] = OpTypePointer UniformConstant %10
+ ; CHECK: %[[sampler_ty:\d+]] = OpTypeSampler
+ ; CHECK: %[[sampler_ptr_ty:\w+]] = OpTypePointer UniformConstant %[[sampler_ty]]
+
+ ; The combined image variable is replaced by an image variable and a sampler variable.
+
+ ; CHECK-NOT: %100 = OpVariable
+ ; CHECK-DAG: %[[sampler_var]] = OpVariable %[[sampler_ptr_ty]] UniformConstant
+ ; CHECK-DAG: %[[image_var]] = OpVariable %[[image_ptr_ty]] UniformConstant
+ ; CHECK: = OpFunction
+
+
+ %float = OpTypeFloat 32
+ %uint = OpTypeInt 32 0
+ %int = OpTypeInt 32 1
+ %uint_0 = OpConstant %uint 0
+ %uint_1 = OpConstant %uint 1
+ %uint_3 = OpConstant %uint 3
+ %float_0 = OpConstant %float 0
+ %v2float = OpTypeVector %float 2
+ %v3float = OpTypeVector %float 3
+ %v4float = OpTypeVector %float 4
+ %13 = OpConstantNull %v2float
+ %14 = OpConstantNull %v3float
+ %15 = OpConstantNull %v4float
+ %void = OpTypeVoid
+ %voidfn = OpTypeFunction %void
+ %10 = OpTypeImage %uint Cube 1 0 0 1 Unknown
+ %11 = OpTypeSampledImage %10
+%_ptr_UniformConstant_11 = OpTypePointer UniformConstant %11
+
+ %100 = OpVariable %_ptr_UniformConstant_11 UniformConstant
+ %main = OpFunction %void None %voidfn
+ %main_0 = OpLabel
+ %101 = OpCopyObject %_ptr_UniformConstant_11 %100
+ %102 = OpLoad %11 %101
+ %103 = OpCopyObject %_ptr_UniformConstant_11 %101
+ %104 = OpCopyObject %11 %102 ;; this copy survives
+ OpReturn
+ OpFunctionEnd
+
+ ; The OpCopyObject instructions are removed.
+ ; The load of the combined image+sampler is replaced by a two loads, then
+ ; a combination operation. The only OpCopyObject that remains is the copy
+ ; of the copy of the sampled image value.
+ ; CHECK: %[[im:\d+]] = OpLoad %10 %[[image_var]]
+ ; CHECK: %[[s:\d+]] = OpLoad %[[sampler_ty]] %[[sampler_var]]
+ ; CHECK: %[[si:\d+]] = OpSampledImage %11 %[[im]] %[[s]]
+ ; CHECK-NEXT: OpCopyObject %11 %[[si]]
+ ; CHECK-NEXT: OpReturn
diff --git a/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_DeletesCopyObjectOfPtr_31.spvasm b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_DeletesCopyObjectOfPtr_31.spvasm
new file mode 100644
index 0000000..1139852
--- /dev/null
+++ b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_DeletesCopyObjectOfPtr_31.spvasm
@@ -0,0 +1,71 @@
+ OpCapability Shader
+ OpCapability RuntimeDescriptorArray
+ OpExtension "SPV_EXT_descriptor_indexing"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ OpName %main "main"
+ OpName %main_0 "main_0"
+ OpName %voidfn "voidfn"
+
+ OpDecorate %100 DescriptorSet 0
+ OpDecorate %100 Binding 0
+
+ ; CHECK: OpName
+ ; CHECK-NOT: OpDecorate %100
+ ; CHECK: OpDecorate %[[image_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[sampler_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[image_var]] Binding 0
+ ; CHECK: OpDecorate %[[sampler_var]] Binding 0
+
+ ; CHECK: %10 = OpTypeImage %
+ ; CHECK: %[[image_ptr_ty:\w+]] = OpTypePointer UniformConstant %10
+ ; CHECK: %[[sampler_ty:\d+]] = OpTypeSampler
+ ; CHECK: %[[sampler_ptr_ty:\w+]] = OpTypePointer UniformConstant %[[sampler_ty]]
+
+ ; The combined image variable is replaced by an image variable and a sampler variable.
+
+ ; CHECK-NOT: %100 = OpVariable
+ ; CHECK-DAG: %[[sampler_var]] = OpVariable %[[sampler_ptr_ty]] UniformConstant
+ ; CHECK-DAG: %[[image_var]] = OpVariable %[[image_ptr_ty]] UniformConstant
+ ; CHECK: = OpFunction
+
+
+ %float = OpTypeFloat 32
+ %uint = OpTypeInt 32 0
+ %int = OpTypeInt 32 1
+ %uint_0 = OpConstant %uint 0
+ %uint_1 = OpConstant %uint 1
+ %uint_3 = OpConstant %uint 3
+ %float_0 = OpConstant %float 0
+ %v2float = OpTypeVector %float 2
+ %v3float = OpTypeVector %float 3
+ %v4float = OpTypeVector %float 4
+ %13 = OpConstantNull %v2float
+ %14 = OpConstantNull %v3float
+ %15 = OpConstantNull %v4float
+ %void = OpTypeVoid
+ %voidfn = OpTypeFunction %void
+ %10 = OpTypeImage %uint Cube 0 1 0 1 Unknown
+ %11 = OpTypeSampledImage %10
+%_ptr_UniformConstant_11 = OpTypePointer UniformConstant %11
+
+ %100 = OpVariable %_ptr_UniformConstant_11 UniformConstant
+ %main = OpFunction %void None %voidfn
+ %main_0 = OpLabel
+ %101 = OpCopyObject %_ptr_UniformConstant_11 %100
+ %102 = OpLoad %11 %101
+ %103 = OpCopyObject %_ptr_UniformConstant_11 %101
+ %104 = OpCopyObject %11 %102 ;; this copy survives
+ OpReturn
+ OpFunctionEnd
+
+ ; The OpCopyObject instructions are removed.
+ ; The load of the combined image+sampler is replaced by a two loads, then
+ ; a combination operation. The only OpCopyObject that remains is the copy
+ ; of the copy of the sampled image value.
+ ; CHECK: %[[im:\d+]] = OpLoad %10 %[[image_var]]
+ ; CHECK: %[[s:\d+]] = OpLoad %[[sampler_ty]] %[[sampler_var]]
+ ; CHECK: %[[si:\d+]] = OpSampledImage %11 %[[im]] %[[s]]
+ ; CHECK-NEXT: OpCopyObject %11 %[[si]]
+ ; CHECK-NEXT: OpReturn
diff --git a/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_DeletesCopyObjectOfPtr_32.spvasm b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_DeletesCopyObjectOfPtr_32.spvasm
new file mode 100644
index 0000000..5c7de73
--- /dev/null
+++ b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_DeletesCopyObjectOfPtr_32.spvasm
@@ -0,0 +1,71 @@
+ OpCapability Shader
+ OpCapability RuntimeDescriptorArray
+ OpExtension "SPV_EXT_descriptor_indexing"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ OpName %main "main"
+ OpName %main_0 "main_0"
+ OpName %voidfn "voidfn"
+
+ OpDecorate %100 DescriptorSet 0
+ OpDecorate %100 Binding 0
+
+ ; CHECK: OpName
+ ; CHECK-NOT: OpDecorate %100
+ ; CHECK: OpDecorate %[[image_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[sampler_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[image_var]] Binding 0
+ ; CHECK: OpDecorate %[[sampler_var]] Binding 0
+
+ ; CHECK: %10 = OpTypeImage %
+ ; CHECK: %[[image_ptr_ty:\w+]] = OpTypePointer UniformConstant %10
+ ; CHECK: %[[sampler_ty:\d+]] = OpTypeSampler
+ ; CHECK: %[[sampler_ptr_ty:\w+]] = OpTypePointer UniformConstant %[[sampler_ty]]
+
+ ; The combined image variable is replaced by an image variable and a sampler variable.
+
+ ; CHECK-NOT: %100 = OpVariable
+ ; CHECK-DAG: %[[sampler_var]] = OpVariable %[[sampler_ptr_ty]] UniformConstant
+ ; CHECK-DAG: %[[image_var]] = OpVariable %[[image_ptr_ty]] UniformConstant
+ ; CHECK: = OpFunction
+
+
+ %float = OpTypeFloat 32
+ %uint = OpTypeInt 32 0
+ %int = OpTypeInt 32 1
+ %uint_0 = OpConstant %uint 0
+ %uint_1 = OpConstant %uint 1
+ %uint_3 = OpConstant %uint 3
+ %float_0 = OpConstant %float 0
+ %v2float = OpTypeVector %float 2
+ %v3float = OpTypeVector %float 3
+ %v4float = OpTypeVector %float 4
+ %13 = OpConstantNull %v2float
+ %14 = OpConstantNull %v3float
+ %15 = OpConstantNull %v4float
+ %void = OpTypeVoid
+ %voidfn = OpTypeFunction %void
+ %10 = OpTypeImage %uint Cube 1 1 0 1 Unknown
+ %11 = OpTypeSampledImage %10
+%_ptr_UniformConstant_11 = OpTypePointer UniformConstant %11
+
+ %100 = OpVariable %_ptr_UniformConstant_11 UniformConstant
+ %main = OpFunction %void None %voidfn
+ %main_0 = OpLabel
+ %101 = OpCopyObject %_ptr_UniformConstant_11 %100
+ %102 = OpLoad %11 %101
+ %103 = OpCopyObject %_ptr_UniformConstant_11 %101
+ %104 = OpCopyObject %11 %102 ;; this copy survives
+ OpReturn
+ OpFunctionEnd
+
+ ; The OpCopyObject instructions are removed.
+ ; The load of the combined image+sampler is replaced by a two loads, then
+ ; a combination operation. The only OpCopyObject that remains is the copy
+ ; of the copy of the sampled image value.
+ ; CHECK: %[[im:\d+]] = OpLoad %10 %[[image_var]]
+ ; CHECK: %[[s:\d+]] = OpLoad %[[sampler_ty]] %[[sampler_var]]
+ ; CHECK: %[[si:\d+]] = OpSampledImage %11 %[[im]] %[[s]]
+ ; CHECK-NEXT: OpCopyObject %11 %[[si]]
+ ; CHECK-NEXT: OpReturn
diff --git a/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_DeletesCopyObjectOfPtr_4.spvasm b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_DeletesCopyObjectOfPtr_4.spvasm
new file mode 100644
index 0000000..413808b
--- /dev/null
+++ b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_DeletesCopyObjectOfPtr_4.spvasm
@@ -0,0 +1,71 @@
+ OpCapability Shader
+ OpCapability RuntimeDescriptorArray
+ OpExtension "SPV_EXT_descriptor_indexing"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ OpName %main "main"
+ OpName %main_0 "main_0"
+ OpName %voidfn "voidfn"
+
+ OpDecorate %100 DescriptorSet 0
+ OpDecorate %100 Binding 0
+
+ ; CHECK: OpName
+ ; CHECK-NOT: OpDecorate %100
+ ; CHECK: OpDecorate %[[image_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[sampler_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[image_var]] Binding 0
+ ; CHECK: OpDecorate %[[sampler_var]] Binding 0
+
+ ; CHECK: %10 = OpTypeImage %
+ ; CHECK: %[[image_ptr_ty:\w+]] = OpTypePointer UniformConstant %10
+ ; CHECK: %[[sampler_ty:\d+]] = OpTypeSampler
+ ; CHECK: %[[sampler_ptr_ty:\w+]] = OpTypePointer UniformConstant %[[sampler_ty]]
+
+ ; The combined image variable is replaced by an image variable and a sampler variable.
+
+ ; CHECK-NOT: %100 = OpVariable
+ ; CHECK-DAG: %[[sampler_var]] = OpVariable %[[sampler_ptr_ty]] UniformConstant
+ ; CHECK-DAG: %[[image_var]] = OpVariable %[[image_ptr_ty]] UniformConstant
+ ; CHECK: = OpFunction
+
+
+ %float = OpTypeFloat 32
+ %uint = OpTypeInt 32 0
+ %int = OpTypeInt 32 1
+ %uint_0 = OpConstant %uint 0
+ %uint_1 = OpConstant %uint 1
+ %uint_3 = OpConstant %uint 3
+ %float_0 = OpConstant %float 0
+ %v2float = OpTypeVector %float 2
+ %v3float = OpTypeVector %float 3
+ %v4float = OpTypeVector %float 4
+ %13 = OpConstantNull %v2float
+ %14 = OpConstantNull %v3float
+ %15 = OpConstantNull %v4float
+ %void = OpTypeVoid
+ %voidfn = OpTypeFunction %void
+ %10 = OpTypeImage %float 2D 0 0 1 1 Unknown
+ %11 = OpTypeSampledImage %10
+%_ptr_UniformConstant_11 = OpTypePointer UniformConstant %11
+
+ %100 = OpVariable %_ptr_UniformConstant_11 UniformConstant
+ %main = OpFunction %void None %voidfn
+ %main_0 = OpLabel
+ %101 = OpCopyObject %_ptr_UniformConstant_11 %100
+ %102 = OpLoad %11 %101
+ %103 = OpCopyObject %_ptr_UniformConstant_11 %101
+ %104 = OpCopyObject %11 %102 ;; this copy survives
+ OpReturn
+ OpFunctionEnd
+
+ ; The OpCopyObject instructions are removed.
+ ; The load of the combined image+sampler is replaced by a two loads, then
+ ; a combination operation. The only OpCopyObject that remains is the copy
+ ; of the copy of the sampled image value.
+ ; CHECK: %[[im:\d+]] = OpLoad %10 %[[image_var]]
+ ; CHECK: %[[s:\d+]] = OpLoad %[[sampler_ty]] %[[sampler_var]]
+ ; CHECK: %[[si:\d+]] = OpSampledImage %11 %[[im]] %[[s]]
+ ; CHECK-NEXT: OpCopyObject %11 %[[si]]
+ ; CHECK-NEXT: OpReturn
diff --git a/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_DeletesCopyObjectOfPtr_6.spvasm b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_DeletesCopyObjectOfPtr_6.spvasm
new file mode 100644
index 0000000..0c61fb5
--- /dev/null
+++ b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_DeletesCopyObjectOfPtr_6.spvasm
@@ -0,0 +1,71 @@
+ OpCapability Shader
+ OpCapability RuntimeDescriptorArray
+ OpExtension "SPV_EXT_descriptor_indexing"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ OpName %main "main"
+ OpName %main_0 "main_0"
+ OpName %voidfn "voidfn"
+
+ OpDecorate %100 DescriptorSet 0
+ OpDecorate %100 Binding 0
+
+ ; CHECK: OpName
+ ; CHECK-NOT: OpDecorate %100
+ ; CHECK: OpDecorate %[[image_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[sampler_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[image_var]] Binding 0
+ ; CHECK: OpDecorate %[[sampler_var]] Binding 0
+
+ ; CHECK: %10 = OpTypeImage %
+ ; CHECK: %[[image_ptr_ty:\w+]] = OpTypePointer UniformConstant %10
+ ; CHECK: %[[sampler_ty:\d+]] = OpTypeSampler
+ ; CHECK: %[[sampler_ptr_ty:\w+]] = OpTypePointer UniformConstant %[[sampler_ty]]
+
+ ; The combined image variable is replaced by an image variable and a sampler variable.
+
+ ; CHECK-NOT: %100 = OpVariable
+ ; CHECK-DAG: %[[sampler_var]] = OpVariable %[[sampler_ptr_ty]] UniformConstant
+ ; CHECK-DAG: %[[image_var]] = OpVariable %[[image_ptr_ty]] UniformConstant
+ ; CHECK: = OpFunction
+
+
+ %float = OpTypeFloat 32
+ %uint = OpTypeInt 32 0
+ %int = OpTypeInt 32 1
+ %uint_0 = OpConstant %uint 0
+ %uint_1 = OpConstant %uint 1
+ %uint_3 = OpConstant %uint 3
+ %float_0 = OpConstant %float 0
+ %v2float = OpTypeVector %float 2
+ %v3float = OpTypeVector %float 3
+ %v4float = OpTypeVector %float 4
+ %13 = OpConstantNull %v2float
+ %14 = OpConstantNull %v3float
+ %15 = OpConstantNull %v4float
+ %void = OpTypeVoid
+ %voidfn = OpTypeFunction %void
+ %10 = OpTypeImage %float 3D 0 0 0 1 Unknown
+ %11 = OpTypeSampledImage %10
+%_ptr_UniformConstant_11 = OpTypePointer UniformConstant %11
+
+ %100 = OpVariable %_ptr_UniformConstant_11 UniformConstant
+ %main = OpFunction %void None %voidfn
+ %main_0 = OpLabel
+ %101 = OpCopyObject %_ptr_UniformConstant_11 %100
+ %102 = OpLoad %11 %101
+ %103 = OpCopyObject %_ptr_UniformConstant_11 %101
+ %104 = OpCopyObject %11 %102 ;; this copy survives
+ OpReturn
+ OpFunctionEnd
+
+ ; The OpCopyObject instructions are removed.
+ ; The load of the combined image+sampler is replaced by a two loads, then
+ ; a combination operation. The only OpCopyObject that remains is the copy
+ ; of the copy of the sampled image value.
+ ; CHECK: %[[im:\d+]] = OpLoad %10 %[[image_var]]
+ ; CHECK: %[[s:\d+]] = OpLoad %[[sampler_ty]] %[[sampler_var]]
+ ; CHECK: %[[si:\d+]] = OpSampledImage %11 %[[im]] %[[s]]
+ ; CHECK-NEXT: OpCopyObject %11 %[[si]]
+ ; CHECK-NEXT: OpReturn
diff --git a/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_DeletesCopyObjectOfPtr_7.spvasm b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_DeletesCopyObjectOfPtr_7.spvasm
new file mode 100644
index 0000000..a1c53d4
--- /dev/null
+++ b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_DeletesCopyObjectOfPtr_7.spvasm
@@ -0,0 +1,71 @@
+ OpCapability Shader
+ OpCapability RuntimeDescriptorArray
+ OpExtension "SPV_EXT_descriptor_indexing"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ OpName %main "main"
+ OpName %main_0 "main_0"
+ OpName %voidfn "voidfn"
+
+ OpDecorate %100 DescriptorSet 0
+ OpDecorate %100 Binding 0
+
+ ; CHECK: OpName
+ ; CHECK-NOT: OpDecorate %100
+ ; CHECK: OpDecorate %[[image_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[sampler_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[image_var]] Binding 0
+ ; CHECK: OpDecorate %[[sampler_var]] Binding 0
+
+ ; CHECK: %10 = OpTypeImage %
+ ; CHECK: %[[image_ptr_ty:\w+]] = OpTypePointer UniformConstant %10
+ ; CHECK: %[[sampler_ty:\d+]] = OpTypeSampler
+ ; CHECK: %[[sampler_ptr_ty:\w+]] = OpTypePointer UniformConstant %[[sampler_ty]]
+
+ ; The combined image variable is replaced by an image variable and a sampler variable.
+
+ ; CHECK-NOT: %100 = OpVariable
+ ; CHECK-DAG: %[[sampler_var]] = OpVariable %[[sampler_ptr_ty]] UniformConstant
+ ; CHECK-DAG: %[[image_var]] = OpVariable %[[image_ptr_ty]] UniformConstant
+ ; CHECK: = OpFunction
+
+
+ %float = OpTypeFloat 32
+ %uint = OpTypeInt 32 0
+ %int = OpTypeInt 32 1
+ %uint_0 = OpConstant %uint 0
+ %uint_1 = OpConstant %uint 1
+ %uint_3 = OpConstant %uint 3
+ %float_0 = OpConstant %float 0
+ %v2float = OpTypeVector %float 2
+ %v3float = OpTypeVector %float 3
+ %v4float = OpTypeVector %float 4
+ %13 = OpConstantNull %v2float
+ %14 = OpConstantNull %v3float
+ %15 = OpConstantNull %v4float
+ %void = OpTypeVoid
+ %voidfn = OpTypeFunction %void
+ %10 = OpTypeImage %float Cube 0 0 0 1 Unknown
+ %11 = OpTypeSampledImage %10
+%_ptr_UniformConstant_11 = OpTypePointer UniformConstant %11
+
+ %100 = OpVariable %_ptr_UniformConstant_11 UniformConstant
+ %main = OpFunction %void None %voidfn
+ %main_0 = OpLabel
+ %101 = OpCopyObject %_ptr_UniformConstant_11 %100
+ %102 = OpLoad %11 %101
+ %103 = OpCopyObject %_ptr_UniformConstant_11 %101
+ %104 = OpCopyObject %11 %102 ;; this copy survives
+ OpReturn
+ OpFunctionEnd
+
+ ; The OpCopyObject instructions are removed.
+ ; The load of the combined image+sampler is replaced by a two loads, then
+ ; a combination operation. The only OpCopyObject that remains is the copy
+ ; of the copy of the sampled image value.
+ ; CHECK: %[[im:\d+]] = OpLoad %10 %[[image_var]]
+ ; CHECK: %[[s:\d+]] = OpLoad %[[sampler_ty]] %[[sampler_var]]
+ ; CHECK: %[[si:\d+]] = OpSampledImage %11 %[[im]] %[[s]]
+ ; CHECK-NEXT: OpCopyObject %11 %[[si]]
+ ; CHECK-NEXT: OpReturn
diff --git a/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_DeletesCopyObjectOfPtr_8.spvasm b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_DeletesCopyObjectOfPtr_8.spvasm
new file mode 100644
index 0000000..e561acb
--- /dev/null
+++ b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_DeletesCopyObjectOfPtr_8.spvasm
@@ -0,0 +1,71 @@
+ OpCapability Shader
+ OpCapability RuntimeDescriptorArray
+ OpExtension "SPV_EXT_descriptor_indexing"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ OpName %main "main"
+ OpName %main_0 "main_0"
+ OpName %voidfn "voidfn"
+
+ OpDecorate %100 DescriptorSet 0
+ OpDecorate %100 Binding 0
+
+ ; CHECK: OpName
+ ; CHECK-NOT: OpDecorate %100
+ ; CHECK: OpDecorate %[[image_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[sampler_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[image_var]] Binding 0
+ ; CHECK: OpDecorate %[[sampler_var]] Binding 0
+
+ ; CHECK: %10 = OpTypeImage %
+ ; CHECK: %[[image_ptr_ty:\w+]] = OpTypePointer UniformConstant %10
+ ; CHECK: %[[sampler_ty:\d+]] = OpTypeSampler
+ ; CHECK: %[[sampler_ptr_ty:\w+]] = OpTypePointer UniformConstant %[[sampler_ty]]
+
+ ; The combined image variable is replaced by an image variable and a sampler variable.
+
+ ; CHECK-NOT: %100 = OpVariable
+ ; CHECK-DAG: %[[sampler_var]] = OpVariable %[[sampler_ptr_ty]] UniformConstant
+ ; CHECK-DAG: %[[image_var]] = OpVariable %[[image_ptr_ty]] UniformConstant
+ ; CHECK: = OpFunction
+
+
+ %float = OpTypeFloat 32
+ %uint = OpTypeInt 32 0
+ %int = OpTypeInt 32 1
+ %uint_0 = OpConstant %uint 0
+ %uint_1 = OpConstant %uint 1
+ %uint_3 = OpConstant %uint 3
+ %float_0 = OpConstant %float 0
+ %v2float = OpTypeVector %float 2
+ %v3float = OpTypeVector %float 3
+ %v4float = OpTypeVector %float 4
+ %13 = OpConstantNull %v2float
+ %14 = OpConstantNull %v3float
+ %15 = OpConstantNull %v4float
+ %void = OpTypeVoid
+ %voidfn = OpTypeFunction %void
+ %10 = OpTypeImage %float Cube 1 0 0 1 Unknown
+ %11 = OpTypeSampledImage %10
+%_ptr_UniformConstant_11 = OpTypePointer UniformConstant %11
+
+ %100 = OpVariable %_ptr_UniformConstant_11 UniformConstant
+ %main = OpFunction %void None %voidfn
+ %main_0 = OpLabel
+ %101 = OpCopyObject %_ptr_UniformConstant_11 %100
+ %102 = OpLoad %11 %101
+ %103 = OpCopyObject %_ptr_UniformConstant_11 %101
+ %104 = OpCopyObject %11 %102 ;; this copy survives
+ OpReturn
+ OpFunctionEnd
+
+ ; The OpCopyObject instructions are removed.
+ ; The load of the combined image+sampler is replaced by a two loads, then
+ ; a combination operation. The only OpCopyObject that remains is the copy
+ ; of the copy of the sampled image value.
+ ; CHECK: %[[im:\d+]] = OpLoad %10 %[[image_var]]
+ ; CHECK: %[[s:\d+]] = OpLoad %[[sampler_ty]] %[[sampler_var]]
+ ; CHECK: %[[si:\d+]] = OpSampledImage %11 %[[im]] %[[s]]
+ ; CHECK-NEXT: OpCopyObject %11 %[[si]]
+ ; CHECK-NEXT: OpReturn
diff --git a/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_DeletesCopyObjectOfPtr_9.spvasm b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_DeletesCopyObjectOfPtr_9.spvasm
new file mode 100644
index 0000000..d4cb4b0
--- /dev/null
+++ b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_DeletesCopyObjectOfPtr_9.spvasm
@@ -0,0 +1,71 @@
+ OpCapability Shader
+ OpCapability RuntimeDescriptorArray
+ OpExtension "SPV_EXT_descriptor_indexing"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ OpName %main "main"
+ OpName %main_0 "main_0"
+ OpName %voidfn "voidfn"
+
+ OpDecorate %100 DescriptorSet 0
+ OpDecorate %100 Binding 0
+
+ ; CHECK: OpName
+ ; CHECK-NOT: OpDecorate %100
+ ; CHECK: OpDecorate %[[image_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[sampler_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[image_var]] Binding 0
+ ; CHECK: OpDecorate %[[sampler_var]] Binding 0
+
+ ; CHECK: %10 = OpTypeImage %
+ ; CHECK: %[[image_ptr_ty:\w+]] = OpTypePointer UniformConstant %10
+ ; CHECK: %[[sampler_ty:\d+]] = OpTypeSampler
+ ; CHECK: %[[sampler_ptr_ty:\w+]] = OpTypePointer UniformConstant %[[sampler_ty]]
+
+ ; The combined image variable is replaced by an image variable and a sampler variable.
+
+ ; CHECK-NOT: %100 = OpVariable
+ ; CHECK-DAG: %[[sampler_var]] = OpVariable %[[sampler_ptr_ty]] UniformConstant
+ ; CHECK-DAG: %[[image_var]] = OpVariable %[[image_ptr_ty]] UniformConstant
+ ; CHECK: = OpFunction
+
+
+ %float = OpTypeFloat 32
+ %uint = OpTypeInt 32 0
+ %int = OpTypeInt 32 1
+ %uint_0 = OpConstant %uint 0
+ %uint_1 = OpConstant %uint 1
+ %uint_3 = OpConstant %uint 3
+ %float_0 = OpConstant %float 0
+ %v2float = OpTypeVector %float 2
+ %v3float = OpTypeVector %float 3
+ %v4float = OpTypeVector %float 4
+ %13 = OpConstantNull %v2float
+ %14 = OpConstantNull %v3float
+ %15 = OpConstantNull %v4float
+ %void = OpTypeVoid
+ %voidfn = OpTypeFunction %void
+ %10 = OpTypeImage %float Cube 0 1 0 1 Unknown
+ %11 = OpTypeSampledImage %10
+%_ptr_UniformConstant_11 = OpTypePointer UniformConstant %11
+
+ %100 = OpVariable %_ptr_UniformConstant_11 UniformConstant
+ %main = OpFunction %void None %voidfn
+ %main_0 = OpLabel
+ %101 = OpCopyObject %_ptr_UniformConstant_11 %100
+ %102 = OpLoad %11 %101
+ %103 = OpCopyObject %_ptr_UniformConstant_11 %101
+ %104 = OpCopyObject %11 %102 ;; this copy survives
+ OpReturn
+ OpFunctionEnd
+
+ ; The OpCopyObject instructions are removed.
+ ; The load of the combined image+sampler is replaced by a two loads, then
+ ; a combination operation. The only OpCopyObject that remains is the copy
+ ; of the copy of the sampled image value.
+ ; CHECK: %[[im:\d+]] = OpLoad %10 %[[image_var]]
+ ; CHECK: %[[s:\d+]] = OpLoad %[[sampler_ty]] %[[sampler_var]]
+ ; CHECK: %[[si:\d+]] = OpSampledImage %11 %[[im]] %[[s]]
+ ; CHECK-NEXT: OpCopyObject %11 %[[si]]
+ ; CHECK-NEXT: OpReturn
diff --git a/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_0.spvasm b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_0.spvasm
new file mode 100644
index 0000000..0b2fff1
--- /dev/null
+++ b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_0.spvasm
@@ -0,0 +1,69 @@
+ OpCapability Shader
+ OpCapability RuntimeDescriptorArray
+ OpExtension "SPV_EXT_descriptor_indexing"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ OpName %main "main"
+ OpName %main_0 "main_0"
+ OpName %voidfn "voidfn"
+
+ OpName %combined "combined"
+ OpDecorate %100 DescriptorSet 0
+ OpDecorate %100 Binding 0
+
+ ; CHECK: OpName
+ ; CHECK-NOT: OpDecorate %100
+ ; CHECK: OpDecorate %[[image_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[sampler_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[image_var]] Binding 0
+ ; CHECK: OpDecorate %[[sampler_var]] Binding 0
+
+ ; CHECK: %10 = OpTypeImage %
+ ; CHECK: %[[image_ptr_ty:\w+]] = OpTypePointer UniformConstant %10
+ ; CHECK: %[[sampler_ty:\d+]] = OpTypeSampler
+ ; CHECK: %[[sampler_ptr_ty:\w+]] = OpTypePointer UniformConstant %[[sampler_ty]]
+
+ ; The combined image variable is replaced by an image variable and a sampler variable.
+
+ ; CHECK-NOT: %100 = OpVariable
+ ; CHECK-DAG: %[[sampler_var]] = OpVariable %[[sampler_ptr_ty]] UniformConstant
+ ; CHECK-DAG: %[[image_var]] = OpVariable %[[image_ptr_ty]] UniformConstant
+ ; CHECK: = OpFunction
+
+ ; The load of the combined image+sampler is replaced by a two loads, then
+ ; a combination operation.
+ ; CHECK: %[[im:\d+]] = OpLoad %10 %[[image_var]]
+ ; CHECK: %[[s:\d+]] = OpLoad %[[sampler_ty]] %[[sampler_var]]
+ ; CHECK: %combined = OpSampledImage %11 %[[im]] %[[s]]
+
+ %float = OpTypeFloat 32
+ %uint = OpTypeInt 32 0
+ %int = OpTypeInt 32 1
+ %uint_0 = OpConstant %uint 0
+ %uint_1 = OpConstant %uint 1
+ %uint_3 = OpConstant %uint 3
+ %float_0 = OpConstant %float 0
+ %v2float = OpTypeVector %float 2
+ %v3float = OpTypeVector %float 3
+ %v4float = OpTypeVector %float 4
+ %13 = OpConstantNull %v2float
+ %14 = OpConstantNull %v3float
+ %15 = OpConstantNull %v4float
+ %void = OpTypeVoid
+ %voidfn = OpTypeFunction %void
+ %10 = OpTypeImage %float 2D 0 0 0 1 Unknown
+ %11 = OpTypeSampledImage %10
+%_ptr_UniformConstant_11 = OpTypePointer UniformConstant %11
+
+ %100 = OpVariable %_ptr_UniformConstant_11 UniformConstant
+ %main = OpFunction %void None %voidfn
+ %main_0 = OpLabel
+ %combined = OpLoad %11 %100
+
+ ; Uses of the combined image sampler are preserved.
+ ; CHECK: OpCopyObject %11 %combined
+
+ %7 = OpCopyObject %11 %combined
+ OpReturn
+ OpFunctionEnd
diff --git a/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_1.spvasm b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_1.spvasm
new file mode 100644
index 0000000..fba2fe9
--- /dev/null
+++ b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_1.spvasm
@@ -0,0 +1,69 @@
+ OpCapability Shader
+ OpCapability RuntimeDescriptorArray
+ OpExtension "SPV_EXT_descriptor_indexing"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ OpName %main "main"
+ OpName %main_0 "main_0"
+ OpName %voidfn "voidfn"
+
+ OpName %combined "combined"
+ OpDecorate %100 DescriptorSet 0
+ OpDecorate %100 Binding 0
+
+ ; CHECK: OpName
+ ; CHECK-NOT: OpDecorate %100
+ ; CHECK: OpDecorate %[[image_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[sampler_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[image_var]] Binding 0
+ ; CHECK: OpDecorate %[[sampler_var]] Binding 0
+
+ ; CHECK: %10 = OpTypeImage %
+ ; CHECK: %[[image_ptr_ty:\w+]] = OpTypePointer UniformConstant %10
+ ; CHECK: %[[sampler_ty:\d+]] = OpTypeSampler
+ ; CHECK: %[[sampler_ptr_ty:\w+]] = OpTypePointer UniformConstant %[[sampler_ty]]
+
+ ; The combined image variable is replaced by an image variable and a sampler variable.
+
+ ; CHECK-NOT: %100 = OpVariable
+ ; CHECK-DAG: %[[sampler_var]] = OpVariable %[[sampler_ptr_ty]] UniformConstant
+ ; CHECK-DAG: %[[image_var]] = OpVariable %[[image_ptr_ty]] UniformConstant
+ ; CHECK: = OpFunction
+
+ ; The load of the combined image+sampler is replaced by a two loads, then
+ ; a combination operation.
+ ; CHECK: %[[im:\d+]] = OpLoad %10 %[[image_var]]
+ ; CHECK: %[[s:\d+]] = OpLoad %[[sampler_ty]] %[[sampler_var]]
+ ; CHECK: %combined = OpSampledImage %11 %[[im]] %[[s]]
+
+ %float = OpTypeFloat 32
+ %uint = OpTypeInt 32 0
+ %int = OpTypeInt 32 1
+ %uint_0 = OpConstant %uint 0
+ %uint_1 = OpConstant %uint 1
+ %uint_3 = OpConstant %uint 3
+ %float_0 = OpConstant %float 0
+ %v2float = OpTypeVector %float 2
+ %v3float = OpTypeVector %float 3
+ %v4float = OpTypeVector %float 4
+ %13 = OpConstantNull %v2float
+ %14 = OpConstantNull %v3float
+ %15 = OpConstantNull %v4float
+ %void = OpTypeVoid
+ %voidfn = OpTypeFunction %void
+ %10 = OpTypeImage %float 2D 1 0 0 1 Unknown
+ %11 = OpTypeSampledImage %10
+%_ptr_UniformConstant_11 = OpTypePointer UniformConstant %11
+
+ %100 = OpVariable %_ptr_UniformConstant_11 UniformConstant
+ %main = OpFunction %void None %voidfn
+ %main_0 = OpLabel
+ %combined = OpLoad %11 %100
+
+ ; Uses of the combined image sampler are preserved.
+ ; CHECK: OpCopyObject %11 %combined
+
+ %7 = OpCopyObject %11 %combined
+ OpReturn
+ OpFunctionEnd
diff --git a/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_10.spvasm b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_10.spvasm
new file mode 100644
index 0000000..f76c01f
--- /dev/null
+++ b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_10.spvasm
@@ -0,0 +1,69 @@
+ OpCapability Shader
+ OpCapability RuntimeDescriptorArray
+ OpExtension "SPV_EXT_descriptor_indexing"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ OpName %main "main"
+ OpName %main_0 "main_0"
+ OpName %voidfn "voidfn"
+
+ OpName %combined "combined"
+ OpDecorate %100 DescriptorSet 0
+ OpDecorate %100 Binding 0
+
+ ; CHECK: OpName
+ ; CHECK-NOT: OpDecorate %100
+ ; CHECK: OpDecorate %[[image_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[sampler_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[image_var]] Binding 0
+ ; CHECK: OpDecorate %[[sampler_var]] Binding 0
+
+ ; CHECK: %10 = OpTypeImage %
+ ; CHECK: %[[image_ptr_ty:\w+]] = OpTypePointer UniformConstant %10
+ ; CHECK: %[[sampler_ty:\d+]] = OpTypeSampler
+ ; CHECK: %[[sampler_ptr_ty:\w+]] = OpTypePointer UniformConstant %[[sampler_ty]]
+
+ ; The combined image variable is replaced by an image variable and a sampler variable.
+
+ ; CHECK-NOT: %100 = OpVariable
+ ; CHECK-DAG: %[[sampler_var]] = OpVariable %[[sampler_ptr_ty]] UniformConstant
+ ; CHECK-DAG: %[[image_var]] = OpVariable %[[image_ptr_ty]] UniformConstant
+ ; CHECK: = OpFunction
+
+ ; The load of the combined image+sampler is replaced by a two loads, then
+ ; a combination operation.
+ ; CHECK: %[[im:\d+]] = OpLoad %10 %[[image_var]]
+ ; CHECK: %[[s:\d+]] = OpLoad %[[sampler_ty]] %[[sampler_var]]
+ ; CHECK: %combined = OpSampledImage %11 %[[im]] %[[s]]
+
+ %float = OpTypeFloat 32
+ %uint = OpTypeInt 32 0
+ %int = OpTypeInt 32 1
+ %uint_0 = OpConstant %uint 0
+ %uint_1 = OpConstant %uint 1
+ %uint_3 = OpConstant %uint 3
+ %float_0 = OpConstant %float 0
+ %v2float = OpTypeVector %float 2
+ %v3float = OpTypeVector %float 3
+ %v4float = OpTypeVector %float 4
+ %13 = OpConstantNull %v2float
+ %14 = OpConstantNull %v3float
+ %15 = OpConstantNull %v4float
+ %void = OpTypeVoid
+ %voidfn = OpTypeFunction %void
+ %10 = OpTypeImage %float Cube 1 1 0 1 Unknown
+ %11 = OpTypeSampledImage %10
+%_ptr_UniformConstant_11 = OpTypePointer UniformConstant %11
+
+ %100 = OpVariable %_ptr_UniformConstant_11 UniformConstant
+ %main = OpFunction %void None %voidfn
+ %main_0 = OpLabel
+ %combined = OpLoad %11 %100
+
+ ; Uses of the combined image sampler are preserved.
+ ; CHECK: OpCopyObject %11 %combined
+
+ %7 = OpCopyObject %11 %combined
+ OpReturn
+ OpFunctionEnd
diff --git a/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_11.spvasm b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_11.spvasm
new file mode 100644
index 0000000..c323a55
--- /dev/null
+++ b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_11.spvasm
@@ -0,0 +1,69 @@
+ OpCapability Shader
+ OpCapability RuntimeDescriptorArray
+ OpExtension "SPV_EXT_descriptor_indexing"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ OpName %main "main"
+ OpName %main_0 "main_0"
+ OpName %voidfn "voidfn"
+
+ OpName %combined "combined"
+ OpDecorate %100 DescriptorSet 0
+ OpDecorate %100 Binding 0
+
+ ; CHECK: OpName
+ ; CHECK-NOT: OpDecorate %100
+ ; CHECK: OpDecorate %[[image_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[sampler_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[image_var]] Binding 0
+ ; CHECK: OpDecorate %[[sampler_var]] Binding 0
+
+ ; CHECK: %10 = OpTypeImage %
+ ; CHECK: %[[image_ptr_ty:\w+]] = OpTypePointer UniformConstant %10
+ ; CHECK: %[[sampler_ty:\d+]] = OpTypeSampler
+ ; CHECK: %[[sampler_ptr_ty:\w+]] = OpTypePointer UniformConstant %[[sampler_ty]]
+
+ ; The combined image variable is replaced by an image variable and a sampler variable.
+
+ ; CHECK-NOT: %100 = OpVariable
+ ; CHECK-DAG: %[[sampler_var]] = OpVariable %[[sampler_ptr_ty]] UniformConstant
+ ; CHECK-DAG: %[[image_var]] = OpVariable %[[image_ptr_ty]] UniformConstant
+ ; CHECK: = OpFunction
+
+ ; The load of the combined image+sampler is replaced by a two loads, then
+ ; a combination operation.
+ ; CHECK: %[[im:\d+]] = OpLoad %10 %[[image_var]]
+ ; CHECK: %[[s:\d+]] = OpLoad %[[sampler_ty]] %[[sampler_var]]
+ ; CHECK: %combined = OpSampledImage %11 %[[im]] %[[s]]
+
+ %float = OpTypeFloat 32
+ %uint = OpTypeInt 32 0
+ %int = OpTypeInt 32 1
+ %uint_0 = OpConstant %uint 0
+ %uint_1 = OpConstant %uint 1
+ %uint_3 = OpConstant %uint 3
+ %float_0 = OpConstant %float 0
+ %v2float = OpTypeVector %float 2
+ %v3float = OpTypeVector %float 3
+ %v4float = OpTypeVector %float 4
+ %13 = OpConstantNull %v2float
+ %14 = OpConstantNull %v3float
+ %15 = OpConstantNull %v4float
+ %void = OpTypeVoid
+ %voidfn = OpTypeFunction %void
+ %10 = OpTypeImage %int 2D 0 0 0 1 Unknown
+ %11 = OpTypeSampledImage %10
+%_ptr_UniformConstant_11 = OpTypePointer UniformConstant %11
+
+ %100 = OpVariable %_ptr_UniformConstant_11 UniformConstant
+ %main = OpFunction %void None %voidfn
+ %main_0 = OpLabel
+ %combined = OpLoad %11 %100
+
+ ; Uses of the combined image sampler are preserved.
+ ; CHECK: OpCopyObject %11 %combined
+
+ %7 = OpCopyObject %11 %combined
+ OpReturn
+ OpFunctionEnd
diff --git a/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_12.spvasm b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_12.spvasm
new file mode 100644
index 0000000..05de526
--- /dev/null
+++ b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_12.spvasm
@@ -0,0 +1,69 @@
+ OpCapability Shader
+ OpCapability RuntimeDescriptorArray
+ OpExtension "SPV_EXT_descriptor_indexing"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ OpName %main "main"
+ OpName %main_0 "main_0"
+ OpName %voidfn "voidfn"
+
+ OpName %combined "combined"
+ OpDecorate %100 DescriptorSet 0
+ OpDecorate %100 Binding 0
+
+ ; CHECK: OpName
+ ; CHECK-NOT: OpDecorate %100
+ ; CHECK: OpDecorate %[[image_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[sampler_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[image_var]] Binding 0
+ ; CHECK: OpDecorate %[[sampler_var]] Binding 0
+
+ ; CHECK: %10 = OpTypeImage %
+ ; CHECK: %[[image_ptr_ty:\w+]] = OpTypePointer UniformConstant %10
+ ; CHECK: %[[sampler_ty:\d+]] = OpTypeSampler
+ ; CHECK: %[[sampler_ptr_ty:\w+]] = OpTypePointer UniformConstant %[[sampler_ty]]
+
+ ; The combined image variable is replaced by an image variable and a sampler variable.
+
+ ; CHECK-NOT: %100 = OpVariable
+ ; CHECK-DAG: %[[sampler_var]] = OpVariable %[[sampler_ptr_ty]] UniformConstant
+ ; CHECK-DAG: %[[image_var]] = OpVariable %[[image_ptr_ty]] UniformConstant
+ ; CHECK: = OpFunction
+
+ ; The load of the combined image+sampler is replaced by a two loads, then
+ ; a combination operation.
+ ; CHECK: %[[im:\d+]] = OpLoad %10 %[[image_var]]
+ ; CHECK: %[[s:\d+]] = OpLoad %[[sampler_ty]] %[[sampler_var]]
+ ; CHECK: %combined = OpSampledImage %11 %[[im]] %[[s]]
+
+ %float = OpTypeFloat 32
+ %uint = OpTypeInt 32 0
+ %int = OpTypeInt 32 1
+ %uint_0 = OpConstant %uint 0
+ %uint_1 = OpConstant %uint 1
+ %uint_3 = OpConstant %uint 3
+ %float_0 = OpConstant %float 0
+ %v2float = OpTypeVector %float 2
+ %v3float = OpTypeVector %float 3
+ %v4float = OpTypeVector %float 4
+ %13 = OpConstantNull %v2float
+ %14 = OpConstantNull %v3float
+ %15 = OpConstantNull %v4float
+ %void = OpTypeVoid
+ %voidfn = OpTypeFunction %void
+ %10 = OpTypeImage %int 2D 1 0 0 1 Unknown
+ %11 = OpTypeSampledImage %10
+%_ptr_UniformConstant_11 = OpTypePointer UniformConstant %11
+
+ %100 = OpVariable %_ptr_UniformConstant_11 UniformConstant
+ %main = OpFunction %void None %voidfn
+ %main_0 = OpLabel
+ %combined = OpLoad %11 %100
+
+ ; Uses of the combined image sampler are preserved.
+ ; CHECK: OpCopyObject %11 %combined
+
+ %7 = OpCopyObject %11 %combined
+ OpReturn
+ OpFunctionEnd
diff --git a/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_13.spvasm b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_13.spvasm
new file mode 100644
index 0000000..000be8b
--- /dev/null
+++ b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_13.spvasm
@@ -0,0 +1,69 @@
+ OpCapability Shader
+ OpCapability RuntimeDescriptorArray
+ OpExtension "SPV_EXT_descriptor_indexing"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ OpName %main "main"
+ OpName %main_0 "main_0"
+ OpName %voidfn "voidfn"
+
+ OpName %combined "combined"
+ OpDecorate %100 DescriptorSet 0
+ OpDecorate %100 Binding 0
+
+ ; CHECK: OpName
+ ; CHECK-NOT: OpDecorate %100
+ ; CHECK: OpDecorate %[[image_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[sampler_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[image_var]] Binding 0
+ ; CHECK: OpDecorate %[[sampler_var]] Binding 0
+
+ ; CHECK: %10 = OpTypeImage %
+ ; CHECK: %[[image_ptr_ty:\w+]] = OpTypePointer UniformConstant %10
+ ; CHECK: %[[sampler_ty:\d+]] = OpTypeSampler
+ ; CHECK: %[[sampler_ptr_ty:\w+]] = OpTypePointer UniformConstant %[[sampler_ty]]
+
+ ; The combined image variable is replaced by an image variable and a sampler variable.
+
+ ; CHECK-NOT: %100 = OpVariable
+ ; CHECK-DAG: %[[sampler_var]] = OpVariable %[[sampler_ptr_ty]] UniformConstant
+ ; CHECK-DAG: %[[image_var]] = OpVariable %[[image_ptr_ty]] UniformConstant
+ ; CHECK: = OpFunction
+
+ ; The load of the combined image+sampler is replaced by a two loads, then
+ ; a combination operation.
+ ; CHECK: %[[im:\d+]] = OpLoad %10 %[[image_var]]
+ ; CHECK: %[[s:\d+]] = OpLoad %[[sampler_ty]] %[[sampler_var]]
+ ; CHECK: %combined = OpSampledImage %11 %[[im]] %[[s]]
+
+ %float = OpTypeFloat 32
+ %uint = OpTypeInt 32 0
+ %int = OpTypeInt 32 1
+ %uint_0 = OpConstant %uint 0
+ %uint_1 = OpConstant %uint 1
+ %uint_3 = OpConstant %uint 3
+ %float_0 = OpConstant %float 0
+ %v2float = OpTypeVector %float 2
+ %v3float = OpTypeVector %float 3
+ %v4float = OpTypeVector %float 4
+ %13 = OpConstantNull %v2float
+ %14 = OpConstantNull %v3float
+ %15 = OpConstantNull %v4float
+ %void = OpTypeVoid
+ %voidfn = OpTypeFunction %void
+ %10 = OpTypeImage %int 2D 0 1 0 1 Unknown
+ %11 = OpTypeSampledImage %10
+%_ptr_UniformConstant_11 = OpTypePointer UniformConstant %11
+
+ %100 = OpVariable %_ptr_UniformConstant_11 UniformConstant
+ %main = OpFunction %void None %voidfn
+ %main_0 = OpLabel
+ %combined = OpLoad %11 %100
+
+ ; Uses of the combined image sampler are preserved.
+ ; CHECK: OpCopyObject %11 %combined
+
+ %7 = OpCopyObject %11 %combined
+ OpReturn
+ OpFunctionEnd
diff --git a/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_14.spvasm b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_14.spvasm
new file mode 100644
index 0000000..57456c1
--- /dev/null
+++ b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_14.spvasm
@@ -0,0 +1,69 @@
+ OpCapability Shader
+ OpCapability RuntimeDescriptorArray
+ OpExtension "SPV_EXT_descriptor_indexing"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ OpName %main "main"
+ OpName %main_0 "main_0"
+ OpName %voidfn "voidfn"
+
+ OpName %combined "combined"
+ OpDecorate %100 DescriptorSet 0
+ OpDecorate %100 Binding 0
+
+ ; CHECK: OpName
+ ; CHECK-NOT: OpDecorate %100
+ ; CHECK: OpDecorate %[[image_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[sampler_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[image_var]] Binding 0
+ ; CHECK: OpDecorate %[[sampler_var]] Binding 0
+
+ ; CHECK: %10 = OpTypeImage %
+ ; CHECK: %[[image_ptr_ty:\w+]] = OpTypePointer UniformConstant %10
+ ; CHECK: %[[sampler_ty:\d+]] = OpTypeSampler
+ ; CHECK: %[[sampler_ptr_ty:\w+]] = OpTypePointer UniformConstant %[[sampler_ty]]
+
+ ; The combined image variable is replaced by an image variable and a sampler variable.
+
+ ; CHECK-NOT: %100 = OpVariable
+ ; CHECK-DAG: %[[sampler_var]] = OpVariable %[[sampler_ptr_ty]] UniformConstant
+ ; CHECK-DAG: %[[image_var]] = OpVariable %[[image_ptr_ty]] UniformConstant
+ ; CHECK: = OpFunction
+
+ ; The load of the combined image+sampler is replaced by a two loads, then
+ ; a combination operation.
+ ; CHECK: %[[im:\d+]] = OpLoad %10 %[[image_var]]
+ ; CHECK: %[[s:\d+]] = OpLoad %[[sampler_ty]] %[[sampler_var]]
+ ; CHECK: %combined = OpSampledImage %11 %[[im]] %[[s]]
+
+ %float = OpTypeFloat 32
+ %uint = OpTypeInt 32 0
+ %int = OpTypeInt 32 1
+ %uint_0 = OpConstant %uint 0
+ %uint_1 = OpConstant %uint 1
+ %uint_3 = OpConstant %uint 3
+ %float_0 = OpConstant %float 0
+ %v2float = OpTypeVector %float 2
+ %v3float = OpTypeVector %float 3
+ %v4float = OpTypeVector %float 4
+ %13 = OpConstantNull %v2float
+ %14 = OpConstantNull %v3float
+ %15 = OpConstantNull %v4float
+ %void = OpTypeVoid
+ %voidfn = OpTypeFunction %void
+ %10 = OpTypeImage %int 2D 1 1 0 1 Unknown
+ %11 = OpTypeSampledImage %10
+%_ptr_UniformConstant_11 = OpTypePointer UniformConstant %11
+
+ %100 = OpVariable %_ptr_UniformConstant_11 UniformConstant
+ %main = OpFunction %void None %voidfn
+ %main_0 = OpLabel
+ %combined = OpLoad %11 %100
+
+ ; Uses of the combined image sampler are preserved.
+ ; CHECK: OpCopyObject %11 %combined
+
+ %7 = OpCopyObject %11 %combined
+ OpReturn
+ OpFunctionEnd
diff --git a/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_15.spvasm b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_15.spvasm
new file mode 100644
index 0000000..45cd46b
--- /dev/null
+++ b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_15.spvasm
@@ -0,0 +1,69 @@
+ OpCapability Shader
+ OpCapability RuntimeDescriptorArray
+ OpExtension "SPV_EXT_descriptor_indexing"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ OpName %main "main"
+ OpName %main_0 "main_0"
+ OpName %voidfn "voidfn"
+
+ OpName %combined "combined"
+ OpDecorate %100 DescriptorSet 0
+ OpDecorate %100 Binding 0
+
+ ; CHECK: OpName
+ ; CHECK-NOT: OpDecorate %100
+ ; CHECK: OpDecorate %[[image_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[sampler_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[image_var]] Binding 0
+ ; CHECK: OpDecorate %[[sampler_var]] Binding 0
+
+ ; CHECK: %10 = OpTypeImage %
+ ; CHECK: %[[image_ptr_ty:\w+]] = OpTypePointer UniformConstant %10
+ ; CHECK: %[[sampler_ty:\d+]] = OpTypeSampler
+ ; CHECK: %[[sampler_ptr_ty:\w+]] = OpTypePointer UniformConstant %[[sampler_ty]]
+
+ ; The combined image variable is replaced by an image variable and a sampler variable.
+
+ ; CHECK-NOT: %100 = OpVariable
+ ; CHECK-DAG: %[[sampler_var]] = OpVariable %[[sampler_ptr_ty]] UniformConstant
+ ; CHECK-DAG: %[[image_var]] = OpVariable %[[image_ptr_ty]] UniformConstant
+ ; CHECK: = OpFunction
+
+ ; The load of the combined image+sampler is replaced by a two loads, then
+ ; a combination operation.
+ ; CHECK: %[[im:\d+]] = OpLoad %10 %[[image_var]]
+ ; CHECK: %[[s:\d+]] = OpLoad %[[sampler_ty]] %[[sampler_var]]
+ ; CHECK: %combined = OpSampledImage %11 %[[im]] %[[s]]
+
+ %float = OpTypeFloat 32
+ %uint = OpTypeInt 32 0
+ %int = OpTypeInt 32 1
+ %uint_0 = OpConstant %uint 0
+ %uint_1 = OpConstant %uint 1
+ %uint_3 = OpConstant %uint 3
+ %float_0 = OpConstant %float 0
+ %v2float = OpTypeVector %float 2
+ %v3float = OpTypeVector %float 3
+ %v4float = OpTypeVector %float 4
+ %13 = OpConstantNull %v2float
+ %14 = OpConstantNull %v3float
+ %15 = OpConstantNull %v4float
+ %void = OpTypeVoid
+ %voidfn = OpTypeFunction %void
+ %10 = OpTypeImage %int 2D 0 0 1 1 Unknown
+ %11 = OpTypeSampledImage %10
+%_ptr_UniformConstant_11 = OpTypePointer UniformConstant %11
+
+ %100 = OpVariable %_ptr_UniformConstant_11 UniformConstant
+ %main = OpFunction %void None %voidfn
+ %main_0 = OpLabel
+ %combined = OpLoad %11 %100
+
+ ; Uses of the combined image sampler are preserved.
+ ; CHECK: OpCopyObject %11 %combined
+
+ %7 = OpCopyObject %11 %combined
+ OpReturn
+ OpFunctionEnd
diff --git a/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_17.spvasm b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_17.spvasm
new file mode 100644
index 0000000..a303192
--- /dev/null
+++ b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_17.spvasm
@@ -0,0 +1,69 @@
+ OpCapability Shader
+ OpCapability RuntimeDescriptorArray
+ OpExtension "SPV_EXT_descriptor_indexing"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ OpName %main "main"
+ OpName %main_0 "main_0"
+ OpName %voidfn "voidfn"
+
+ OpName %combined "combined"
+ OpDecorate %100 DescriptorSet 0
+ OpDecorate %100 Binding 0
+
+ ; CHECK: OpName
+ ; CHECK-NOT: OpDecorate %100
+ ; CHECK: OpDecorate %[[image_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[sampler_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[image_var]] Binding 0
+ ; CHECK: OpDecorate %[[sampler_var]] Binding 0
+
+ ; CHECK: %10 = OpTypeImage %
+ ; CHECK: %[[image_ptr_ty:\w+]] = OpTypePointer UniformConstant %10
+ ; CHECK: %[[sampler_ty:\d+]] = OpTypeSampler
+ ; CHECK: %[[sampler_ptr_ty:\w+]] = OpTypePointer UniformConstant %[[sampler_ty]]
+
+ ; The combined image variable is replaced by an image variable and a sampler variable.
+
+ ; CHECK-NOT: %100 = OpVariable
+ ; CHECK-DAG: %[[sampler_var]] = OpVariable %[[sampler_ptr_ty]] UniformConstant
+ ; CHECK-DAG: %[[image_var]] = OpVariable %[[image_ptr_ty]] UniformConstant
+ ; CHECK: = OpFunction
+
+ ; The load of the combined image+sampler is replaced by a two loads, then
+ ; a combination operation.
+ ; CHECK: %[[im:\d+]] = OpLoad %10 %[[image_var]]
+ ; CHECK: %[[s:\d+]] = OpLoad %[[sampler_ty]] %[[sampler_var]]
+ ; CHECK: %combined = OpSampledImage %11 %[[im]] %[[s]]
+
+ %float = OpTypeFloat 32
+ %uint = OpTypeInt 32 0
+ %int = OpTypeInt 32 1
+ %uint_0 = OpConstant %uint 0
+ %uint_1 = OpConstant %uint 1
+ %uint_3 = OpConstant %uint 3
+ %float_0 = OpConstant %float 0
+ %v2float = OpTypeVector %float 2
+ %v3float = OpTypeVector %float 3
+ %v4float = OpTypeVector %float 4
+ %13 = OpConstantNull %v2float
+ %14 = OpConstantNull %v3float
+ %15 = OpConstantNull %v4float
+ %void = OpTypeVoid
+ %voidfn = OpTypeFunction %void
+ %10 = OpTypeImage %int 3D 0 0 0 1 Unknown
+ %11 = OpTypeSampledImage %10
+%_ptr_UniformConstant_11 = OpTypePointer UniformConstant %11
+
+ %100 = OpVariable %_ptr_UniformConstant_11 UniformConstant
+ %main = OpFunction %void None %voidfn
+ %main_0 = OpLabel
+ %combined = OpLoad %11 %100
+
+ ; Uses of the combined image sampler are preserved.
+ ; CHECK: OpCopyObject %11 %combined
+
+ %7 = OpCopyObject %11 %combined
+ OpReturn
+ OpFunctionEnd
diff --git a/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_18.spvasm b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_18.spvasm
new file mode 100644
index 0000000..a024a20
--- /dev/null
+++ b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_18.spvasm
@@ -0,0 +1,69 @@
+ OpCapability Shader
+ OpCapability RuntimeDescriptorArray
+ OpExtension "SPV_EXT_descriptor_indexing"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ OpName %main "main"
+ OpName %main_0 "main_0"
+ OpName %voidfn "voidfn"
+
+ OpName %combined "combined"
+ OpDecorate %100 DescriptorSet 0
+ OpDecorate %100 Binding 0
+
+ ; CHECK: OpName
+ ; CHECK-NOT: OpDecorate %100
+ ; CHECK: OpDecorate %[[image_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[sampler_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[image_var]] Binding 0
+ ; CHECK: OpDecorate %[[sampler_var]] Binding 0
+
+ ; CHECK: %10 = OpTypeImage %
+ ; CHECK: %[[image_ptr_ty:\w+]] = OpTypePointer UniformConstant %10
+ ; CHECK: %[[sampler_ty:\d+]] = OpTypeSampler
+ ; CHECK: %[[sampler_ptr_ty:\w+]] = OpTypePointer UniformConstant %[[sampler_ty]]
+
+ ; The combined image variable is replaced by an image variable and a sampler variable.
+
+ ; CHECK-NOT: %100 = OpVariable
+ ; CHECK-DAG: %[[sampler_var]] = OpVariable %[[sampler_ptr_ty]] UniformConstant
+ ; CHECK-DAG: %[[image_var]] = OpVariable %[[image_ptr_ty]] UniformConstant
+ ; CHECK: = OpFunction
+
+ ; The load of the combined image+sampler is replaced by a two loads, then
+ ; a combination operation.
+ ; CHECK: %[[im:\d+]] = OpLoad %10 %[[image_var]]
+ ; CHECK: %[[s:\d+]] = OpLoad %[[sampler_ty]] %[[sampler_var]]
+ ; CHECK: %combined = OpSampledImage %11 %[[im]] %[[s]]
+
+ %float = OpTypeFloat 32
+ %uint = OpTypeInt 32 0
+ %int = OpTypeInt 32 1
+ %uint_0 = OpConstant %uint 0
+ %uint_1 = OpConstant %uint 1
+ %uint_3 = OpConstant %uint 3
+ %float_0 = OpConstant %float 0
+ %v2float = OpTypeVector %float 2
+ %v3float = OpTypeVector %float 3
+ %v4float = OpTypeVector %float 4
+ %13 = OpConstantNull %v2float
+ %14 = OpConstantNull %v3float
+ %15 = OpConstantNull %v4float
+ %void = OpTypeVoid
+ %voidfn = OpTypeFunction %void
+ %10 = OpTypeImage %int Cube 0 0 0 1 Unknown
+ %11 = OpTypeSampledImage %10
+%_ptr_UniformConstant_11 = OpTypePointer UniformConstant %11
+
+ %100 = OpVariable %_ptr_UniformConstant_11 UniformConstant
+ %main = OpFunction %void None %voidfn
+ %main_0 = OpLabel
+ %combined = OpLoad %11 %100
+
+ ; Uses of the combined image sampler are preserved.
+ ; CHECK: OpCopyObject %11 %combined
+
+ %7 = OpCopyObject %11 %combined
+ OpReturn
+ OpFunctionEnd
diff --git a/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_19.spvasm b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_19.spvasm
new file mode 100644
index 0000000..e5fb4ba
--- /dev/null
+++ b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_19.spvasm
@@ -0,0 +1,69 @@
+ OpCapability Shader
+ OpCapability RuntimeDescriptorArray
+ OpExtension "SPV_EXT_descriptor_indexing"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ OpName %main "main"
+ OpName %main_0 "main_0"
+ OpName %voidfn "voidfn"
+
+ OpName %combined "combined"
+ OpDecorate %100 DescriptorSet 0
+ OpDecorate %100 Binding 0
+
+ ; CHECK: OpName
+ ; CHECK-NOT: OpDecorate %100
+ ; CHECK: OpDecorate %[[image_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[sampler_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[image_var]] Binding 0
+ ; CHECK: OpDecorate %[[sampler_var]] Binding 0
+
+ ; CHECK: %10 = OpTypeImage %
+ ; CHECK: %[[image_ptr_ty:\w+]] = OpTypePointer UniformConstant %10
+ ; CHECK: %[[sampler_ty:\d+]] = OpTypeSampler
+ ; CHECK: %[[sampler_ptr_ty:\w+]] = OpTypePointer UniformConstant %[[sampler_ty]]
+
+ ; The combined image variable is replaced by an image variable and a sampler variable.
+
+ ; CHECK-NOT: %100 = OpVariable
+ ; CHECK-DAG: %[[sampler_var]] = OpVariable %[[sampler_ptr_ty]] UniformConstant
+ ; CHECK-DAG: %[[image_var]] = OpVariable %[[image_ptr_ty]] UniformConstant
+ ; CHECK: = OpFunction
+
+ ; The load of the combined image+sampler is replaced by a two loads, then
+ ; a combination operation.
+ ; CHECK: %[[im:\d+]] = OpLoad %10 %[[image_var]]
+ ; CHECK: %[[s:\d+]] = OpLoad %[[sampler_ty]] %[[sampler_var]]
+ ; CHECK: %combined = OpSampledImage %11 %[[im]] %[[s]]
+
+ %float = OpTypeFloat 32
+ %uint = OpTypeInt 32 0
+ %int = OpTypeInt 32 1
+ %uint_0 = OpConstant %uint 0
+ %uint_1 = OpConstant %uint 1
+ %uint_3 = OpConstant %uint 3
+ %float_0 = OpConstant %float 0
+ %v2float = OpTypeVector %float 2
+ %v3float = OpTypeVector %float 3
+ %v4float = OpTypeVector %float 4
+ %13 = OpConstantNull %v2float
+ %14 = OpConstantNull %v3float
+ %15 = OpConstantNull %v4float
+ %void = OpTypeVoid
+ %voidfn = OpTypeFunction %void
+ %10 = OpTypeImage %int Cube 1 0 0 1 Unknown
+ %11 = OpTypeSampledImage %10
+%_ptr_UniformConstant_11 = OpTypePointer UniformConstant %11
+
+ %100 = OpVariable %_ptr_UniformConstant_11 UniformConstant
+ %main = OpFunction %void None %voidfn
+ %main_0 = OpLabel
+ %combined = OpLoad %11 %100
+
+ ; Uses of the combined image sampler are preserved.
+ ; CHECK: OpCopyObject %11 %combined
+
+ %7 = OpCopyObject %11 %combined
+ OpReturn
+ OpFunctionEnd
diff --git a/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_2.spvasm b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_2.spvasm
new file mode 100644
index 0000000..1f4f760
--- /dev/null
+++ b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_2.spvasm
@@ -0,0 +1,69 @@
+ OpCapability Shader
+ OpCapability RuntimeDescriptorArray
+ OpExtension "SPV_EXT_descriptor_indexing"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ OpName %main "main"
+ OpName %main_0 "main_0"
+ OpName %voidfn "voidfn"
+
+ OpName %combined "combined"
+ OpDecorate %100 DescriptorSet 0
+ OpDecorate %100 Binding 0
+
+ ; CHECK: OpName
+ ; CHECK-NOT: OpDecorate %100
+ ; CHECK: OpDecorate %[[image_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[sampler_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[image_var]] Binding 0
+ ; CHECK: OpDecorate %[[sampler_var]] Binding 0
+
+ ; CHECK: %10 = OpTypeImage %
+ ; CHECK: %[[image_ptr_ty:\w+]] = OpTypePointer UniformConstant %10
+ ; CHECK: %[[sampler_ty:\d+]] = OpTypeSampler
+ ; CHECK: %[[sampler_ptr_ty:\w+]] = OpTypePointer UniformConstant %[[sampler_ty]]
+
+ ; The combined image variable is replaced by an image variable and a sampler variable.
+
+ ; CHECK-NOT: %100 = OpVariable
+ ; CHECK-DAG: %[[sampler_var]] = OpVariable %[[sampler_ptr_ty]] UniformConstant
+ ; CHECK-DAG: %[[image_var]] = OpVariable %[[image_ptr_ty]] UniformConstant
+ ; CHECK: = OpFunction
+
+ ; The load of the combined image+sampler is replaced by a two loads, then
+ ; a combination operation.
+ ; CHECK: %[[im:\d+]] = OpLoad %10 %[[image_var]]
+ ; CHECK: %[[s:\d+]] = OpLoad %[[sampler_ty]] %[[sampler_var]]
+ ; CHECK: %combined = OpSampledImage %11 %[[im]] %[[s]]
+
+ %float = OpTypeFloat 32
+ %uint = OpTypeInt 32 0
+ %int = OpTypeInt 32 1
+ %uint_0 = OpConstant %uint 0
+ %uint_1 = OpConstant %uint 1
+ %uint_3 = OpConstant %uint 3
+ %float_0 = OpConstant %float 0
+ %v2float = OpTypeVector %float 2
+ %v3float = OpTypeVector %float 3
+ %v4float = OpTypeVector %float 4
+ %13 = OpConstantNull %v2float
+ %14 = OpConstantNull %v3float
+ %15 = OpConstantNull %v4float
+ %void = OpTypeVoid
+ %voidfn = OpTypeFunction %void
+ %10 = OpTypeImage %float 2D 0 1 0 1 Unknown
+ %11 = OpTypeSampledImage %10
+%_ptr_UniformConstant_11 = OpTypePointer UniformConstant %11
+
+ %100 = OpVariable %_ptr_UniformConstant_11 UniformConstant
+ %main = OpFunction %void None %voidfn
+ %main_0 = OpLabel
+ %combined = OpLoad %11 %100
+
+ ; Uses of the combined image sampler are preserved.
+ ; CHECK: OpCopyObject %11 %combined
+
+ %7 = OpCopyObject %11 %combined
+ OpReturn
+ OpFunctionEnd
diff --git a/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_20.spvasm b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_20.spvasm
new file mode 100644
index 0000000..a65b985
--- /dev/null
+++ b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_20.spvasm
@@ -0,0 +1,69 @@
+ OpCapability Shader
+ OpCapability RuntimeDescriptorArray
+ OpExtension "SPV_EXT_descriptor_indexing"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ OpName %main "main"
+ OpName %main_0 "main_0"
+ OpName %voidfn "voidfn"
+
+ OpName %combined "combined"
+ OpDecorate %100 DescriptorSet 0
+ OpDecorate %100 Binding 0
+
+ ; CHECK: OpName
+ ; CHECK-NOT: OpDecorate %100
+ ; CHECK: OpDecorate %[[image_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[sampler_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[image_var]] Binding 0
+ ; CHECK: OpDecorate %[[sampler_var]] Binding 0
+
+ ; CHECK: %10 = OpTypeImage %
+ ; CHECK: %[[image_ptr_ty:\w+]] = OpTypePointer UniformConstant %10
+ ; CHECK: %[[sampler_ty:\d+]] = OpTypeSampler
+ ; CHECK: %[[sampler_ptr_ty:\w+]] = OpTypePointer UniformConstant %[[sampler_ty]]
+
+ ; The combined image variable is replaced by an image variable and a sampler variable.
+
+ ; CHECK-NOT: %100 = OpVariable
+ ; CHECK-DAG: %[[sampler_var]] = OpVariable %[[sampler_ptr_ty]] UniformConstant
+ ; CHECK-DAG: %[[image_var]] = OpVariable %[[image_ptr_ty]] UniformConstant
+ ; CHECK: = OpFunction
+
+ ; The load of the combined image+sampler is replaced by a two loads, then
+ ; a combination operation.
+ ; CHECK: %[[im:\d+]] = OpLoad %10 %[[image_var]]
+ ; CHECK: %[[s:\d+]] = OpLoad %[[sampler_ty]] %[[sampler_var]]
+ ; CHECK: %combined = OpSampledImage %11 %[[im]] %[[s]]
+
+ %float = OpTypeFloat 32
+ %uint = OpTypeInt 32 0
+ %int = OpTypeInt 32 1
+ %uint_0 = OpConstant %uint 0
+ %uint_1 = OpConstant %uint 1
+ %uint_3 = OpConstant %uint 3
+ %float_0 = OpConstant %float 0
+ %v2float = OpTypeVector %float 2
+ %v3float = OpTypeVector %float 3
+ %v4float = OpTypeVector %float 4
+ %13 = OpConstantNull %v2float
+ %14 = OpConstantNull %v3float
+ %15 = OpConstantNull %v4float
+ %void = OpTypeVoid
+ %voidfn = OpTypeFunction %void
+ %10 = OpTypeImage %int Cube 0 1 0 1 Unknown
+ %11 = OpTypeSampledImage %10
+%_ptr_UniformConstant_11 = OpTypePointer UniformConstant %11
+
+ %100 = OpVariable %_ptr_UniformConstant_11 UniformConstant
+ %main = OpFunction %void None %voidfn
+ %main_0 = OpLabel
+ %combined = OpLoad %11 %100
+
+ ; Uses of the combined image sampler are preserved.
+ ; CHECK: OpCopyObject %11 %combined
+
+ %7 = OpCopyObject %11 %combined
+ OpReturn
+ OpFunctionEnd
diff --git a/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_21.spvasm b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_21.spvasm
new file mode 100644
index 0000000..8f458fb
--- /dev/null
+++ b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_21.spvasm
@@ -0,0 +1,69 @@
+ OpCapability Shader
+ OpCapability RuntimeDescriptorArray
+ OpExtension "SPV_EXT_descriptor_indexing"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ OpName %main "main"
+ OpName %main_0 "main_0"
+ OpName %voidfn "voidfn"
+
+ OpName %combined "combined"
+ OpDecorate %100 DescriptorSet 0
+ OpDecorate %100 Binding 0
+
+ ; CHECK: OpName
+ ; CHECK-NOT: OpDecorate %100
+ ; CHECK: OpDecorate %[[image_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[sampler_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[image_var]] Binding 0
+ ; CHECK: OpDecorate %[[sampler_var]] Binding 0
+
+ ; CHECK: %10 = OpTypeImage %
+ ; CHECK: %[[image_ptr_ty:\w+]] = OpTypePointer UniformConstant %10
+ ; CHECK: %[[sampler_ty:\d+]] = OpTypeSampler
+ ; CHECK: %[[sampler_ptr_ty:\w+]] = OpTypePointer UniformConstant %[[sampler_ty]]
+
+ ; The combined image variable is replaced by an image variable and a sampler variable.
+
+ ; CHECK-NOT: %100 = OpVariable
+ ; CHECK-DAG: %[[sampler_var]] = OpVariable %[[sampler_ptr_ty]] UniformConstant
+ ; CHECK-DAG: %[[image_var]] = OpVariable %[[image_ptr_ty]] UniformConstant
+ ; CHECK: = OpFunction
+
+ ; The load of the combined image+sampler is replaced by a two loads, then
+ ; a combination operation.
+ ; CHECK: %[[im:\d+]] = OpLoad %10 %[[image_var]]
+ ; CHECK: %[[s:\d+]] = OpLoad %[[sampler_ty]] %[[sampler_var]]
+ ; CHECK: %combined = OpSampledImage %11 %[[im]] %[[s]]
+
+ %float = OpTypeFloat 32
+ %uint = OpTypeInt 32 0
+ %int = OpTypeInt 32 1
+ %uint_0 = OpConstant %uint 0
+ %uint_1 = OpConstant %uint 1
+ %uint_3 = OpConstant %uint 3
+ %float_0 = OpConstant %float 0
+ %v2float = OpTypeVector %float 2
+ %v3float = OpTypeVector %float 3
+ %v4float = OpTypeVector %float 4
+ %13 = OpConstantNull %v2float
+ %14 = OpConstantNull %v3float
+ %15 = OpConstantNull %v4float
+ %void = OpTypeVoid
+ %voidfn = OpTypeFunction %void
+ %10 = OpTypeImage %int Cube 1 1 0 1 Unknown
+ %11 = OpTypeSampledImage %10
+%_ptr_UniformConstant_11 = OpTypePointer UniformConstant %11
+
+ %100 = OpVariable %_ptr_UniformConstant_11 UniformConstant
+ %main = OpFunction %void None %voidfn
+ %main_0 = OpLabel
+ %combined = OpLoad %11 %100
+
+ ; Uses of the combined image sampler are preserved.
+ ; CHECK: OpCopyObject %11 %combined
+
+ %7 = OpCopyObject %11 %combined
+ OpReturn
+ OpFunctionEnd
diff --git a/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_22.spvasm b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_22.spvasm
new file mode 100644
index 0000000..866f472
--- /dev/null
+++ b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_22.spvasm
@@ -0,0 +1,69 @@
+ OpCapability Shader
+ OpCapability RuntimeDescriptorArray
+ OpExtension "SPV_EXT_descriptor_indexing"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ OpName %main "main"
+ OpName %main_0 "main_0"
+ OpName %voidfn "voidfn"
+
+ OpName %combined "combined"
+ OpDecorate %100 DescriptorSet 0
+ OpDecorate %100 Binding 0
+
+ ; CHECK: OpName
+ ; CHECK-NOT: OpDecorate %100
+ ; CHECK: OpDecorate %[[image_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[sampler_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[image_var]] Binding 0
+ ; CHECK: OpDecorate %[[sampler_var]] Binding 0
+
+ ; CHECK: %10 = OpTypeImage %
+ ; CHECK: %[[image_ptr_ty:\w+]] = OpTypePointer UniformConstant %10
+ ; CHECK: %[[sampler_ty:\d+]] = OpTypeSampler
+ ; CHECK: %[[sampler_ptr_ty:\w+]] = OpTypePointer UniformConstant %[[sampler_ty]]
+
+ ; The combined image variable is replaced by an image variable and a sampler variable.
+
+ ; CHECK-NOT: %100 = OpVariable
+ ; CHECK-DAG: %[[sampler_var]] = OpVariable %[[sampler_ptr_ty]] UniformConstant
+ ; CHECK-DAG: %[[image_var]] = OpVariable %[[image_ptr_ty]] UniformConstant
+ ; CHECK: = OpFunction
+
+ ; The load of the combined image+sampler is replaced by a two loads, then
+ ; a combination operation.
+ ; CHECK: %[[im:\d+]] = OpLoad %10 %[[image_var]]
+ ; CHECK: %[[s:\d+]] = OpLoad %[[sampler_ty]] %[[sampler_var]]
+ ; CHECK: %combined = OpSampledImage %11 %[[im]] %[[s]]
+
+ %float = OpTypeFloat 32
+ %uint = OpTypeInt 32 0
+ %int = OpTypeInt 32 1
+ %uint_0 = OpConstant %uint 0
+ %uint_1 = OpConstant %uint 1
+ %uint_3 = OpConstant %uint 3
+ %float_0 = OpConstant %float 0
+ %v2float = OpTypeVector %float 2
+ %v3float = OpTypeVector %float 3
+ %v4float = OpTypeVector %float 4
+ %13 = OpConstantNull %v2float
+ %14 = OpConstantNull %v3float
+ %15 = OpConstantNull %v4float
+ %void = OpTypeVoid
+ %voidfn = OpTypeFunction %void
+ %10 = OpTypeImage %uint 2D 0 0 0 1 Unknown
+ %11 = OpTypeSampledImage %10
+%_ptr_UniformConstant_11 = OpTypePointer UniformConstant %11
+
+ %100 = OpVariable %_ptr_UniformConstant_11 UniformConstant
+ %main = OpFunction %void None %voidfn
+ %main_0 = OpLabel
+ %combined = OpLoad %11 %100
+
+ ; Uses of the combined image sampler are preserved.
+ ; CHECK: OpCopyObject %11 %combined
+
+ %7 = OpCopyObject %11 %combined
+ OpReturn
+ OpFunctionEnd
diff --git a/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_23.spvasm b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_23.spvasm
new file mode 100644
index 0000000..f61f40c
--- /dev/null
+++ b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_23.spvasm
@@ -0,0 +1,69 @@
+ OpCapability Shader
+ OpCapability RuntimeDescriptorArray
+ OpExtension "SPV_EXT_descriptor_indexing"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ OpName %main "main"
+ OpName %main_0 "main_0"
+ OpName %voidfn "voidfn"
+
+ OpName %combined "combined"
+ OpDecorate %100 DescriptorSet 0
+ OpDecorate %100 Binding 0
+
+ ; CHECK: OpName
+ ; CHECK-NOT: OpDecorate %100
+ ; CHECK: OpDecorate %[[image_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[sampler_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[image_var]] Binding 0
+ ; CHECK: OpDecorate %[[sampler_var]] Binding 0
+
+ ; CHECK: %10 = OpTypeImage %
+ ; CHECK: %[[image_ptr_ty:\w+]] = OpTypePointer UniformConstant %10
+ ; CHECK: %[[sampler_ty:\d+]] = OpTypeSampler
+ ; CHECK: %[[sampler_ptr_ty:\w+]] = OpTypePointer UniformConstant %[[sampler_ty]]
+
+ ; The combined image variable is replaced by an image variable and a sampler variable.
+
+ ; CHECK-NOT: %100 = OpVariable
+ ; CHECK-DAG: %[[sampler_var]] = OpVariable %[[sampler_ptr_ty]] UniformConstant
+ ; CHECK-DAG: %[[image_var]] = OpVariable %[[image_ptr_ty]] UniformConstant
+ ; CHECK: = OpFunction
+
+ ; The load of the combined image+sampler is replaced by a two loads, then
+ ; a combination operation.
+ ; CHECK: %[[im:\d+]] = OpLoad %10 %[[image_var]]
+ ; CHECK: %[[s:\d+]] = OpLoad %[[sampler_ty]] %[[sampler_var]]
+ ; CHECK: %combined = OpSampledImage %11 %[[im]] %[[s]]
+
+ %float = OpTypeFloat 32
+ %uint = OpTypeInt 32 0
+ %int = OpTypeInt 32 1
+ %uint_0 = OpConstant %uint 0
+ %uint_1 = OpConstant %uint 1
+ %uint_3 = OpConstant %uint 3
+ %float_0 = OpConstant %float 0
+ %v2float = OpTypeVector %float 2
+ %v3float = OpTypeVector %float 3
+ %v4float = OpTypeVector %float 4
+ %13 = OpConstantNull %v2float
+ %14 = OpConstantNull %v3float
+ %15 = OpConstantNull %v4float
+ %void = OpTypeVoid
+ %voidfn = OpTypeFunction %void
+ %10 = OpTypeImage %uint 2D 1 0 0 1 Unknown
+ %11 = OpTypeSampledImage %10
+%_ptr_UniformConstant_11 = OpTypePointer UniformConstant %11
+
+ %100 = OpVariable %_ptr_UniformConstant_11 UniformConstant
+ %main = OpFunction %void None %voidfn
+ %main_0 = OpLabel
+ %combined = OpLoad %11 %100
+
+ ; Uses of the combined image sampler are preserved.
+ ; CHECK: OpCopyObject %11 %combined
+
+ %7 = OpCopyObject %11 %combined
+ OpReturn
+ OpFunctionEnd
diff --git a/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_24.spvasm b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_24.spvasm
new file mode 100644
index 0000000..5222d1d
--- /dev/null
+++ b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_24.spvasm
@@ -0,0 +1,69 @@
+ OpCapability Shader
+ OpCapability RuntimeDescriptorArray
+ OpExtension "SPV_EXT_descriptor_indexing"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ OpName %main "main"
+ OpName %main_0 "main_0"
+ OpName %voidfn "voidfn"
+
+ OpName %combined "combined"
+ OpDecorate %100 DescriptorSet 0
+ OpDecorate %100 Binding 0
+
+ ; CHECK: OpName
+ ; CHECK-NOT: OpDecorate %100
+ ; CHECK: OpDecorate %[[image_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[sampler_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[image_var]] Binding 0
+ ; CHECK: OpDecorate %[[sampler_var]] Binding 0
+
+ ; CHECK: %10 = OpTypeImage %
+ ; CHECK: %[[image_ptr_ty:\w+]] = OpTypePointer UniformConstant %10
+ ; CHECK: %[[sampler_ty:\d+]] = OpTypeSampler
+ ; CHECK: %[[sampler_ptr_ty:\w+]] = OpTypePointer UniformConstant %[[sampler_ty]]
+
+ ; The combined image variable is replaced by an image variable and a sampler variable.
+
+ ; CHECK-NOT: %100 = OpVariable
+ ; CHECK-DAG: %[[sampler_var]] = OpVariable %[[sampler_ptr_ty]] UniformConstant
+ ; CHECK-DAG: %[[image_var]] = OpVariable %[[image_ptr_ty]] UniformConstant
+ ; CHECK: = OpFunction
+
+ ; The load of the combined image+sampler is replaced by a two loads, then
+ ; a combination operation.
+ ; CHECK: %[[im:\d+]] = OpLoad %10 %[[image_var]]
+ ; CHECK: %[[s:\d+]] = OpLoad %[[sampler_ty]] %[[sampler_var]]
+ ; CHECK: %combined = OpSampledImage %11 %[[im]] %[[s]]
+
+ %float = OpTypeFloat 32
+ %uint = OpTypeInt 32 0
+ %int = OpTypeInt 32 1
+ %uint_0 = OpConstant %uint 0
+ %uint_1 = OpConstant %uint 1
+ %uint_3 = OpConstant %uint 3
+ %float_0 = OpConstant %float 0
+ %v2float = OpTypeVector %float 2
+ %v3float = OpTypeVector %float 3
+ %v4float = OpTypeVector %float 4
+ %13 = OpConstantNull %v2float
+ %14 = OpConstantNull %v3float
+ %15 = OpConstantNull %v4float
+ %void = OpTypeVoid
+ %voidfn = OpTypeFunction %void
+ %10 = OpTypeImage %uint 2D 0 1 0 1 Unknown
+ %11 = OpTypeSampledImage %10
+%_ptr_UniformConstant_11 = OpTypePointer UniformConstant %11
+
+ %100 = OpVariable %_ptr_UniformConstant_11 UniformConstant
+ %main = OpFunction %void None %voidfn
+ %main_0 = OpLabel
+ %combined = OpLoad %11 %100
+
+ ; Uses of the combined image sampler are preserved.
+ ; CHECK: OpCopyObject %11 %combined
+
+ %7 = OpCopyObject %11 %combined
+ OpReturn
+ OpFunctionEnd
diff --git a/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_25.spvasm b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_25.spvasm
new file mode 100644
index 0000000..100209f
--- /dev/null
+++ b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_25.spvasm
@@ -0,0 +1,69 @@
+ OpCapability Shader
+ OpCapability RuntimeDescriptorArray
+ OpExtension "SPV_EXT_descriptor_indexing"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ OpName %main "main"
+ OpName %main_0 "main_0"
+ OpName %voidfn "voidfn"
+
+ OpName %combined "combined"
+ OpDecorate %100 DescriptorSet 0
+ OpDecorate %100 Binding 0
+
+ ; CHECK: OpName
+ ; CHECK-NOT: OpDecorate %100
+ ; CHECK: OpDecorate %[[image_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[sampler_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[image_var]] Binding 0
+ ; CHECK: OpDecorate %[[sampler_var]] Binding 0
+
+ ; CHECK: %10 = OpTypeImage %
+ ; CHECK: %[[image_ptr_ty:\w+]] = OpTypePointer UniformConstant %10
+ ; CHECK: %[[sampler_ty:\d+]] = OpTypeSampler
+ ; CHECK: %[[sampler_ptr_ty:\w+]] = OpTypePointer UniformConstant %[[sampler_ty]]
+
+ ; The combined image variable is replaced by an image variable and a sampler variable.
+
+ ; CHECK-NOT: %100 = OpVariable
+ ; CHECK-DAG: %[[sampler_var]] = OpVariable %[[sampler_ptr_ty]] UniformConstant
+ ; CHECK-DAG: %[[image_var]] = OpVariable %[[image_ptr_ty]] UniformConstant
+ ; CHECK: = OpFunction
+
+ ; The load of the combined image+sampler is replaced by a two loads, then
+ ; a combination operation.
+ ; CHECK: %[[im:\d+]] = OpLoad %10 %[[image_var]]
+ ; CHECK: %[[s:\d+]] = OpLoad %[[sampler_ty]] %[[sampler_var]]
+ ; CHECK: %combined = OpSampledImage %11 %[[im]] %[[s]]
+
+ %float = OpTypeFloat 32
+ %uint = OpTypeInt 32 0
+ %int = OpTypeInt 32 1
+ %uint_0 = OpConstant %uint 0
+ %uint_1 = OpConstant %uint 1
+ %uint_3 = OpConstant %uint 3
+ %float_0 = OpConstant %float 0
+ %v2float = OpTypeVector %float 2
+ %v3float = OpTypeVector %float 3
+ %v4float = OpTypeVector %float 4
+ %13 = OpConstantNull %v2float
+ %14 = OpConstantNull %v3float
+ %15 = OpConstantNull %v4float
+ %void = OpTypeVoid
+ %voidfn = OpTypeFunction %void
+ %10 = OpTypeImage %uint 2D 1 1 0 1 Unknown
+ %11 = OpTypeSampledImage %10
+%_ptr_UniformConstant_11 = OpTypePointer UniformConstant %11
+
+ %100 = OpVariable %_ptr_UniformConstant_11 UniformConstant
+ %main = OpFunction %void None %voidfn
+ %main_0 = OpLabel
+ %combined = OpLoad %11 %100
+
+ ; Uses of the combined image sampler are preserved.
+ ; CHECK: OpCopyObject %11 %combined
+
+ %7 = OpCopyObject %11 %combined
+ OpReturn
+ OpFunctionEnd
diff --git a/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_26.spvasm b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_26.spvasm
new file mode 100644
index 0000000..f37bf91
--- /dev/null
+++ b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_26.spvasm
@@ -0,0 +1,69 @@
+ OpCapability Shader
+ OpCapability RuntimeDescriptorArray
+ OpExtension "SPV_EXT_descriptor_indexing"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ OpName %main "main"
+ OpName %main_0 "main_0"
+ OpName %voidfn "voidfn"
+
+ OpName %combined "combined"
+ OpDecorate %100 DescriptorSet 0
+ OpDecorate %100 Binding 0
+
+ ; CHECK: OpName
+ ; CHECK-NOT: OpDecorate %100
+ ; CHECK: OpDecorate %[[image_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[sampler_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[image_var]] Binding 0
+ ; CHECK: OpDecorate %[[sampler_var]] Binding 0
+
+ ; CHECK: %10 = OpTypeImage %
+ ; CHECK: %[[image_ptr_ty:\w+]] = OpTypePointer UniformConstant %10
+ ; CHECK: %[[sampler_ty:\d+]] = OpTypeSampler
+ ; CHECK: %[[sampler_ptr_ty:\w+]] = OpTypePointer UniformConstant %[[sampler_ty]]
+
+ ; The combined image variable is replaced by an image variable and a sampler variable.
+
+ ; CHECK-NOT: %100 = OpVariable
+ ; CHECK-DAG: %[[sampler_var]] = OpVariable %[[sampler_ptr_ty]] UniformConstant
+ ; CHECK-DAG: %[[image_var]] = OpVariable %[[image_ptr_ty]] UniformConstant
+ ; CHECK: = OpFunction
+
+ ; The load of the combined image+sampler is replaced by a two loads, then
+ ; a combination operation.
+ ; CHECK: %[[im:\d+]] = OpLoad %10 %[[image_var]]
+ ; CHECK: %[[s:\d+]] = OpLoad %[[sampler_ty]] %[[sampler_var]]
+ ; CHECK: %combined = OpSampledImage %11 %[[im]] %[[s]]
+
+ %float = OpTypeFloat 32
+ %uint = OpTypeInt 32 0
+ %int = OpTypeInt 32 1
+ %uint_0 = OpConstant %uint 0
+ %uint_1 = OpConstant %uint 1
+ %uint_3 = OpConstant %uint 3
+ %float_0 = OpConstant %float 0
+ %v2float = OpTypeVector %float 2
+ %v3float = OpTypeVector %float 3
+ %v4float = OpTypeVector %float 4
+ %13 = OpConstantNull %v2float
+ %14 = OpConstantNull %v3float
+ %15 = OpConstantNull %v4float
+ %void = OpTypeVoid
+ %voidfn = OpTypeFunction %void
+ %10 = OpTypeImage %uint 2D 0 0 1 1 Unknown
+ %11 = OpTypeSampledImage %10
+%_ptr_UniformConstant_11 = OpTypePointer UniformConstant %11
+
+ %100 = OpVariable %_ptr_UniformConstant_11 UniformConstant
+ %main = OpFunction %void None %voidfn
+ %main_0 = OpLabel
+ %combined = OpLoad %11 %100
+
+ ; Uses of the combined image sampler are preserved.
+ ; CHECK: OpCopyObject %11 %combined
+
+ %7 = OpCopyObject %11 %combined
+ OpReturn
+ OpFunctionEnd
diff --git a/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_28.spvasm b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_28.spvasm
new file mode 100644
index 0000000..e38060c
--- /dev/null
+++ b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_28.spvasm
@@ -0,0 +1,69 @@
+ OpCapability Shader
+ OpCapability RuntimeDescriptorArray
+ OpExtension "SPV_EXT_descriptor_indexing"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ OpName %main "main"
+ OpName %main_0 "main_0"
+ OpName %voidfn "voidfn"
+
+ OpName %combined "combined"
+ OpDecorate %100 DescriptorSet 0
+ OpDecorate %100 Binding 0
+
+ ; CHECK: OpName
+ ; CHECK-NOT: OpDecorate %100
+ ; CHECK: OpDecorate %[[image_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[sampler_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[image_var]] Binding 0
+ ; CHECK: OpDecorate %[[sampler_var]] Binding 0
+
+ ; CHECK: %10 = OpTypeImage %
+ ; CHECK: %[[image_ptr_ty:\w+]] = OpTypePointer UniformConstant %10
+ ; CHECK: %[[sampler_ty:\d+]] = OpTypeSampler
+ ; CHECK: %[[sampler_ptr_ty:\w+]] = OpTypePointer UniformConstant %[[sampler_ty]]
+
+ ; The combined image variable is replaced by an image variable and a sampler variable.
+
+ ; CHECK-NOT: %100 = OpVariable
+ ; CHECK-DAG: %[[sampler_var]] = OpVariable %[[sampler_ptr_ty]] UniformConstant
+ ; CHECK-DAG: %[[image_var]] = OpVariable %[[image_ptr_ty]] UniformConstant
+ ; CHECK: = OpFunction
+
+ ; The load of the combined image+sampler is replaced by a two loads, then
+ ; a combination operation.
+ ; CHECK: %[[im:\d+]] = OpLoad %10 %[[image_var]]
+ ; CHECK: %[[s:\d+]] = OpLoad %[[sampler_ty]] %[[sampler_var]]
+ ; CHECK: %combined = OpSampledImage %11 %[[im]] %[[s]]
+
+ %float = OpTypeFloat 32
+ %uint = OpTypeInt 32 0
+ %int = OpTypeInt 32 1
+ %uint_0 = OpConstant %uint 0
+ %uint_1 = OpConstant %uint 1
+ %uint_3 = OpConstant %uint 3
+ %float_0 = OpConstant %float 0
+ %v2float = OpTypeVector %float 2
+ %v3float = OpTypeVector %float 3
+ %v4float = OpTypeVector %float 4
+ %13 = OpConstantNull %v2float
+ %14 = OpConstantNull %v3float
+ %15 = OpConstantNull %v4float
+ %void = OpTypeVoid
+ %voidfn = OpTypeFunction %void
+ %10 = OpTypeImage %uint 3D 0 0 0 1 Unknown
+ %11 = OpTypeSampledImage %10
+%_ptr_UniformConstant_11 = OpTypePointer UniformConstant %11
+
+ %100 = OpVariable %_ptr_UniformConstant_11 UniformConstant
+ %main = OpFunction %void None %voidfn
+ %main_0 = OpLabel
+ %combined = OpLoad %11 %100
+
+ ; Uses of the combined image sampler are preserved.
+ ; CHECK: OpCopyObject %11 %combined
+
+ %7 = OpCopyObject %11 %combined
+ OpReturn
+ OpFunctionEnd
diff --git a/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_29.spvasm b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_29.spvasm
new file mode 100644
index 0000000..0165403
--- /dev/null
+++ b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_29.spvasm
@@ -0,0 +1,69 @@
+ OpCapability Shader
+ OpCapability RuntimeDescriptorArray
+ OpExtension "SPV_EXT_descriptor_indexing"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ OpName %main "main"
+ OpName %main_0 "main_0"
+ OpName %voidfn "voidfn"
+
+ OpName %combined "combined"
+ OpDecorate %100 DescriptorSet 0
+ OpDecorate %100 Binding 0
+
+ ; CHECK: OpName
+ ; CHECK-NOT: OpDecorate %100
+ ; CHECK: OpDecorate %[[image_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[sampler_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[image_var]] Binding 0
+ ; CHECK: OpDecorate %[[sampler_var]] Binding 0
+
+ ; CHECK: %10 = OpTypeImage %
+ ; CHECK: %[[image_ptr_ty:\w+]] = OpTypePointer UniformConstant %10
+ ; CHECK: %[[sampler_ty:\d+]] = OpTypeSampler
+ ; CHECK: %[[sampler_ptr_ty:\w+]] = OpTypePointer UniformConstant %[[sampler_ty]]
+
+ ; The combined image variable is replaced by an image variable and a sampler variable.
+
+ ; CHECK-NOT: %100 = OpVariable
+ ; CHECK-DAG: %[[sampler_var]] = OpVariable %[[sampler_ptr_ty]] UniformConstant
+ ; CHECK-DAG: %[[image_var]] = OpVariable %[[image_ptr_ty]] UniformConstant
+ ; CHECK: = OpFunction
+
+ ; The load of the combined image+sampler is replaced by a two loads, then
+ ; a combination operation.
+ ; CHECK: %[[im:\d+]] = OpLoad %10 %[[image_var]]
+ ; CHECK: %[[s:\d+]] = OpLoad %[[sampler_ty]] %[[sampler_var]]
+ ; CHECK: %combined = OpSampledImage %11 %[[im]] %[[s]]
+
+ %float = OpTypeFloat 32
+ %uint = OpTypeInt 32 0
+ %int = OpTypeInt 32 1
+ %uint_0 = OpConstant %uint 0
+ %uint_1 = OpConstant %uint 1
+ %uint_3 = OpConstant %uint 3
+ %float_0 = OpConstant %float 0
+ %v2float = OpTypeVector %float 2
+ %v3float = OpTypeVector %float 3
+ %v4float = OpTypeVector %float 4
+ %13 = OpConstantNull %v2float
+ %14 = OpConstantNull %v3float
+ %15 = OpConstantNull %v4float
+ %void = OpTypeVoid
+ %voidfn = OpTypeFunction %void
+ %10 = OpTypeImage %uint Cube 0 0 0 1 Unknown
+ %11 = OpTypeSampledImage %10
+%_ptr_UniformConstant_11 = OpTypePointer UniformConstant %11
+
+ %100 = OpVariable %_ptr_UniformConstant_11 UniformConstant
+ %main = OpFunction %void None %voidfn
+ %main_0 = OpLabel
+ %combined = OpLoad %11 %100
+
+ ; Uses of the combined image sampler are preserved.
+ ; CHECK: OpCopyObject %11 %combined
+
+ %7 = OpCopyObject %11 %combined
+ OpReturn
+ OpFunctionEnd
diff --git a/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_3.spvasm b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_3.spvasm
new file mode 100644
index 0000000..450b798
--- /dev/null
+++ b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_3.spvasm
@@ -0,0 +1,69 @@
+ OpCapability Shader
+ OpCapability RuntimeDescriptorArray
+ OpExtension "SPV_EXT_descriptor_indexing"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ OpName %main "main"
+ OpName %main_0 "main_0"
+ OpName %voidfn "voidfn"
+
+ OpName %combined "combined"
+ OpDecorate %100 DescriptorSet 0
+ OpDecorate %100 Binding 0
+
+ ; CHECK: OpName
+ ; CHECK-NOT: OpDecorate %100
+ ; CHECK: OpDecorate %[[image_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[sampler_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[image_var]] Binding 0
+ ; CHECK: OpDecorate %[[sampler_var]] Binding 0
+
+ ; CHECK: %10 = OpTypeImage %
+ ; CHECK: %[[image_ptr_ty:\w+]] = OpTypePointer UniformConstant %10
+ ; CHECK: %[[sampler_ty:\d+]] = OpTypeSampler
+ ; CHECK: %[[sampler_ptr_ty:\w+]] = OpTypePointer UniformConstant %[[sampler_ty]]
+
+ ; The combined image variable is replaced by an image variable and a sampler variable.
+
+ ; CHECK-NOT: %100 = OpVariable
+ ; CHECK-DAG: %[[sampler_var]] = OpVariable %[[sampler_ptr_ty]] UniformConstant
+ ; CHECK-DAG: %[[image_var]] = OpVariable %[[image_ptr_ty]] UniformConstant
+ ; CHECK: = OpFunction
+
+ ; The load of the combined image+sampler is replaced by a two loads, then
+ ; a combination operation.
+ ; CHECK: %[[im:\d+]] = OpLoad %10 %[[image_var]]
+ ; CHECK: %[[s:\d+]] = OpLoad %[[sampler_ty]] %[[sampler_var]]
+ ; CHECK: %combined = OpSampledImage %11 %[[im]] %[[s]]
+
+ %float = OpTypeFloat 32
+ %uint = OpTypeInt 32 0
+ %int = OpTypeInt 32 1
+ %uint_0 = OpConstant %uint 0
+ %uint_1 = OpConstant %uint 1
+ %uint_3 = OpConstant %uint 3
+ %float_0 = OpConstant %float 0
+ %v2float = OpTypeVector %float 2
+ %v3float = OpTypeVector %float 3
+ %v4float = OpTypeVector %float 4
+ %13 = OpConstantNull %v2float
+ %14 = OpConstantNull %v3float
+ %15 = OpConstantNull %v4float
+ %void = OpTypeVoid
+ %voidfn = OpTypeFunction %void
+ %10 = OpTypeImage %float 2D 1 1 0 1 Unknown
+ %11 = OpTypeSampledImage %10
+%_ptr_UniformConstant_11 = OpTypePointer UniformConstant %11
+
+ %100 = OpVariable %_ptr_UniformConstant_11 UniformConstant
+ %main = OpFunction %void None %voidfn
+ %main_0 = OpLabel
+ %combined = OpLoad %11 %100
+
+ ; Uses of the combined image sampler are preserved.
+ ; CHECK: OpCopyObject %11 %combined
+
+ %7 = OpCopyObject %11 %combined
+ OpReturn
+ OpFunctionEnd
diff --git a/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_30.spvasm b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_30.spvasm
new file mode 100644
index 0000000..e8d5e03
--- /dev/null
+++ b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_30.spvasm
@@ -0,0 +1,69 @@
+ OpCapability Shader
+ OpCapability RuntimeDescriptorArray
+ OpExtension "SPV_EXT_descriptor_indexing"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ OpName %main "main"
+ OpName %main_0 "main_0"
+ OpName %voidfn "voidfn"
+
+ OpName %combined "combined"
+ OpDecorate %100 DescriptorSet 0
+ OpDecorate %100 Binding 0
+
+ ; CHECK: OpName
+ ; CHECK-NOT: OpDecorate %100
+ ; CHECK: OpDecorate %[[image_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[sampler_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[image_var]] Binding 0
+ ; CHECK: OpDecorate %[[sampler_var]] Binding 0
+
+ ; CHECK: %10 = OpTypeImage %
+ ; CHECK: %[[image_ptr_ty:\w+]] = OpTypePointer UniformConstant %10
+ ; CHECK: %[[sampler_ty:\d+]] = OpTypeSampler
+ ; CHECK: %[[sampler_ptr_ty:\w+]] = OpTypePointer UniformConstant %[[sampler_ty]]
+
+ ; The combined image variable is replaced by an image variable and a sampler variable.
+
+ ; CHECK-NOT: %100 = OpVariable
+ ; CHECK-DAG: %[[sampler_var]] = OpVariable %[[sampler_ptr_ty]] UniformConstant
+ ; CHECK-DAG: %[[image_var]] = OpVariable %[[image_ptr_ty]] UniformConstant
+ ; CHECK: = OpFunction
+
+ ; The load of the combined image+sampler is replaced by a two loads, then
+ ; a combination operation.
+ ; CHECK: %[[im:\d+]] = OpLoad %10 %[[image_var]]
+ ; CHECK: %[[s:\d+]] = OpLoad %[[sampler_ty]] %[[sampler_var]]
+ ; CHECK: %combined = OpSampledImage %11 %[[im]] %[[s]]
+
+ %float = OpTypeFloat 32
+ %uint = OpTypeInt 32 0
+ %int = OpTypeInt 32 1
+ %uint_0 = OpConstant %uint 0
+ %uint_1 = OpConstant %uint 1
+ %uint_3 = OpConstant %uint 3
+ %float_0 = OpConstant %float 0
+ %v2float = OpTypeVector %float 2
+ %v3float = OpTypeVector %float 3
+ %v4float = OpTypeVector %float 4
+ %13 = OpConstantNull %v2float
+ %14 = OpConstantNull %v3float
+ %15 = OpConstantNull %v4float
+ %void = OpTypeVoid
+ %voidfn = OpTypeFunction %void
+ %10 = OpTypeImage %uint Cube 1 0 0 1 Unknown
+ %11 = OpTypeSampledImage %10
+%_ptr_UniformConstant_11 = OpTypePointer UniformConstant %11
+
+ %100 = OpVariable %_ptr_UniformConstant_11 UniformConstant
+ %main = OpFunction %void None %voidfn
+ %main_0 = OpLabel
+ %combined = OpLoad %11 %100
+
+ ; Uses of the combined image sampler are preserved.
+ ; CHECK: OpCopyObject %11 %combined
+
+ %7 = OpCopyObject %11 %combined
+ OpReturn
+ OpFunctionEnd
diff --git a/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_31.spvasm b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_31.spvasm
new file mode 100644
index 0000000..6977850
--- /dev/null
+++ b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_31.spvasm
@@ -0,0 +1,69 @@
+ OpCapability Shader
+ OpCapability RuntimeDescriptorArray
+ OpExtension "SPV_EXT_descriptor_indexing"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ OpName %main "main"
+ OpName %main_0 "main_0"
+ OpName %voidfn "voidfn"
+
+ OpName %combined "combined"
+ OpDecorate %100 DescriptorSet 0
+ OpDecorate %100 Binding 0
+
+ ; CHECK: OpName
+ ; CHECK-NOT: OpDecorate %100
+ ; CHECK: OpDecorate %[[image_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[sampler_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[image_var]] Binding 0
+ ; CHECK: OpDecorate %[[sampler_var]] Binding 0
+
+ ; CHECK: %10 = OpTypeImage %
+ ; CHECK: %[[image_ptr_ty:\w+]] = OpTypePointer UniformConstant %10
+ ; CHECK: %[[sampler_ty:\d+]] = OpTypeSampler
+ ; CHECK: %[[sampler_ptr_ty:\w+]] = OpTypePointer UniformConstant %[[sampler_ty]]
+
+ ; The combined image variable is replaced by an image variable and a sampler variable.
+
+ ; CHECK-NOT: %100 = OpVariable
+ ; CHECK-DAG: %[[sampler_var]] = OpVariable %[[sampler_ptr_ty]] UniformConstant
+ ; CHECK-DAG: %[[image_var]] = OpVariable %[[image_ptr_ty]] UniformConstant
+ ; CHECK: = OpFunction
+
+ ; The load of the combined image+sampler is replaced by a two loads, then
+ ; a combination operation.
+ ; CHECK: %[[im:\d+]] = OpLoad %10 %[[image_var]]
+ ; CHECK: %[[s:\d+]] = OpLoad %[[sampler_ty]] %[[sampler_var]]
+ ; CHECK: %combined = OpSampledImage %11 %[[im]] %[[s]]
+
+ %float = OpTypeFloat 32
+ %uint = OpTypeInt 32 0
+ %int = OpTypeInt 32 1
+ %uint_0 = OpConstant %uint 0
+ %uint_1 = OpConstant %uint 1
+ %uint_3 = OpConstant %uint 3
+ %float_0 = OpConstant %float 0
+ %v2float = OpTypeVector %float 2
+ %v3float = OpTypeVector %float 3
+ %v4float = OpTypeVector %float 4
+ %13 = OpConstantNull %v2float
+ %14 = OpConstantNull %v3float
+ %15 = OpConstantNull %v4float
+ %void = OpTypeVoid
+ %voidfn = OpTypeFunction %void
+ %10 = OpTypeImage %uint Cube 0 1 0 1 Unknown
+ %11 = OpTypeSampledImage %10
+%_ptr_UniformConstant_11 = OpTypePointer UniformConstant %11
+
+ %100 = OpVariable %_ptr_UniformConstant_11 UniformConstant
+ %main = OpFunction %void None %voidfn
+ %main_0 = OpLabel
+ %combined = OpLoad %11 %100
+
+ ; Uses of the combined image sampler are preserved.
+ ; CHECK: OpCopyObject %11 %combined
+
+ %7 = OpCopyObject %11 %combined
+ OpReturn
+ OpFunctionEnd
diff --git a/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_32.spvasm b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_32.spvasm
new file mode 100644
index 0000000..4829c26
--- /dev/null
+++ b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_32.spvasm
@@ -0,0 +1,69 @@
+ OpCapability Shader
+ OpCapability RuntimeDescriptorArray
+ OpExtension "SPV_EXT_descriptor_indexing"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ OpName %main "main"
+ OpName %main_0 "main_0"
+ OpName %voidfn "voidfn"
+
+ OpName %combined "combined"
+ OpDecorate %100 DescriptorSet 0
+ OpDecorate %100 Binding 0
+
+ ; CHECK: OpName
+ ; CHECK-NOT: OpDecorate %100
+ ; CHECK: OpDecorate %[[image_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[sampler_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[image_var]] Binding 0
+ ; CHECK: OpDecorate %[[sampler_var]] Binding 0
+
+ ; CHECK: %10 = OpTypeImage %
+ ; CHECK: %[[image_ptr_ty:\w+]] = OpTypePointer UniformConstant %10
+ ; CHECK: %[[sampler_ty:\d+]] = OpTypeSampler
+ ; CHECK: %[[sampler_ptr_ty:\w+]] = OpTypePointer UniformConstant %[[sampler_ty]]
+
+ ; The combined image variable is replaced by an image variable and a sampler variable.
+
+ ; CHECK-NOT: %100 = OpVariable
+ ; CHECK-DAG: %[[sampler_var]] = OpVariable %[[sampler_ptr_ty]] UniformConstant
+ ; CHECK-DAG: %[[image_var]] = OpVariable %[[image_ptr_ty]] UniformConstant
+ ; CHECK: = OpFunction
+
+ ; The load of the combined image+sampler is replaced by a two loads, then
+ ; a combination operation.
+ ; CHECK: %[[im:\d+]] = OpLoad %10 %[[image_var]]
+ ; CHECK: %[[s:\d+]] = OpLoad %[[sampler_ty]] %[[sampler_var]]
+ ; CHECK: %combined = OpSampledImage %11 %[[im]] %[[s]]
+
+ %float = OpTypeFloat 32
+ %uint = OpTypeInt 32 0
+ %int = OpTypeInt 32 1
+ %uint_0 = OpConstant %uint 0
+ %uint_1 = OpConstant %uint 1
+ %uint_3 = OpConstant %uint 3
+ %float_0 = OpConstant %float 0
+ %v2float = OpTypeVector %float 2
+ %v3float = OpTypeVector %float 3
+ %v4float = OpTypeVector %float 4
+ %13 = OpConstantNull %v2float
+ %14 = OpConstantNull %v3float
+ %15 = OpConstantNull %v4float
+ %void = OpTypeVoid
+ %voidfn = OpTypeFunction %void
+ %10 = OpTypeImage %uint Cube 1 1 0 1 Unknown
+ %11 = OpTypeSampledImage %10
+%_ptr_UniformConstant_11 = OpTypePointer UniformConstant %11
+
+ %100 = OpVariable %_ptr_UniformConstant_11 UniformConstant
+ %main = OpFunction %void None %voidfn
+ %main_0 = OpLabel
+ %combined = OpLoad %11 %100
+
+ ; Uses of the combined image sampler are preserved.
+ ; CHECK: OpCopyObject %11 %combined
+
+ %7 = OpCopyObject %11 %combined
+ OpReturn
+ OpFunctionEnd
diff --git a/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_4.spvasm b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_4.spvasm
new file mode 100644
index 0000000..a25e547
--- /dev/null
+++ b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_4.spvasm
@@ -0,0 +1,69 @@
+ OpCapability Shader
+ OpCapability RuntimeDescriptorArray
+ OpExtension "SPV_EXT_descriptor_indexing"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ OpName %main "main"
+ OpName %main_0 "main_0"
+ OpName %voidfn "voidfn"
+
+ OpName %combined "combined"
+ OpDecorate %100 DescriptorSet 0
+ OpDecorate %100 Binding 0
+
+ ; CHECK: OpName
+ ; CHECK-NOT: OpDecorate %100
+ ; CHECK: OpDecorate %[[image_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[sampler_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[image_var]] Binding 0
+ ; CHECK: OpDecorate %[[sampler_var]] Binding 0
+
+ ; CHECK: %10 = OpTypeImage %
+ ; CHECK: %[[image_ptr_ty:\w+]] = OpTypePointer UniformConstant %10
+ ; CHECK: %[[sampler_ty:\d+]] = OpTypeSampler
+ ; CHECK: %[[sampler_ptr_ty:\w+]] = OpTypePointer UniformConstant %[[sampler_ty]]
+
+ ; The combined image variable is replaced by an image variable and a sampler variable.
+
+ ; CHECK-NOT: %100 = OpVariable
+ ; CHECK-DAG: %[[sampler_var]] = OpVariable %[[sampler_ptr_ty]] UniformConstant
+ ; CHECK-DAG: %[[image_var]] = OpVariable %[[image_ptr_ty]] UniformConstant
+ ; CHECK: = OpFunction
+
+ ; The load of the combined image+sampler is replaced by a two loads, then
+ ; a combination operation.
+ ; CHECK: %[[im:\d+]] = OpLoad %10 %[[image_var]]
+ ; CHECK: %[[s:\d+]] = OpLoad %[[sampler_ty]] %[[sampler_var]]
+ ; CHECK: %combined = OpSampledImage %11 %[[im]] %[[s]]
+
+ %float = OpTypeFloat 32
+ %uint = OpTypeInt 32 0
+ %int = OpTypeInt 32 1
+ %uint_0 = OpConstant %uint 0
+ %uint_1 = OpConstant %uint 1
+ %uint_3 = OpConstant %uint 3
+ %float_0 = OpConstant %float 0
+ %v2float = OpTypeVector %float 2
+ %v3float = OpTypeVector %float 3
+ %v4float = OpTypeVector %float 4
+ %13 = OpConstantNull %v2float
+ %14 = OpConstantNull %v3float
+ %15 = OpConstantNull %v4float
+ %void = OpTypeVoid
+ %voidfn = OpTypeFunction %void
+ %10 = OpTypeImage %float 2D 0 0 1 1 Unknown
+ %11 = OpTypeSampledImage %10
+%_ptr_UniformConstant_11 = OpTypePointer UniformConstant %11
+
+ %100 = OpVariable %_ptr_UniformConstant_11 UniformConstant
+ %main = OpFunction %void None %voidfn
+ %main_0 = OpLabel
+ %combined = OpLoad %11 %100
+
+ ; Uses of the combined image sampler are preserved.
+ ; CHECK: OpCopyObject %11 %combined
+
+ %7 = OpCopyObject %11 %combined
+ OpReturn
+ OpFunctionEnd
diff --git a/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_6.spvasm b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_6.spvasm
new file mode 100644
index 0000000..c4ee6b6
--- /dev/null
+++ b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_6.spvasm
@@ -0,0 +1,69 @@
+ OpCapability Shader
+ OpCapability RuntimeDescriptorArray
+ OpExtension "SPV_EXT_descriptor_indexing"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ OpName %main "main"
+ OpName %main_0 "main_0"
+ OpName %voidfn "voidfn"
+
+ OpName %combined "combined"
+ OpDecorate %100 DescriptorSet 0
+ OpDecorate %100 Binding 0
+
+ ; CHECK: OpName
+ ; CHECK-NOT: OpDecorate %100
+ ; CHECK: OpDecorate %[[image_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[sampler_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[image_var]] Binding 0
+ ; CHECK: OpDecorate %[[sampler_var]] Binding 0
+
+ ; CHECK: %10 = OpTypeImage %
+ ; CHECK: %[[image_ptr_ty:\w+]] = OpTypePointer UniformConstant %10
+ ; CHECK: %[[sampler_ty:\d+]] = OpTypeSampler
+ ; CHECK: %[[sampler_ptr_ty:\w+]] = OpTypePointer UniformConstant %[[sampler_ty]]
+
+ ; The combined image variable is replaced by an image variable and a sampler variable.
+
+ ; CHECK-NOT: %100 = OpVariable
+ ; CHECK-DAG: %[[sampler_var]] = OpVariable %[[sampler_ptr_ty]] UniformConstant
+ ; CHECK-DAG: %[[image_var]] = OpVariable %[[image_ptr_ty]] UniformConstant
+ ; CHECK: = OpFunction
+
+ ; The load of the combined image+sampler is replaced by a two loads, then
+ ; a combination operation.
+ ; CHECK: %[[im:\d+]] = OpLoad %10 %[[image_var]]
+ ; CHECK: %[[s:\d+]] = OpLoad %[[sampler_ty]] %[[sampler_var]]
+ ; CHECK: %combined = OpSampledImage %11 %[[im]] %[[s]]
+
+ %float = OpTypeFloat 32
+ %uint = OpTypeInt 32 0
+ %int = OpTypeInt 32 1
+ %uint_0 = OpConstant %uint 0
+ %uint_1 = OpConstant %uint 1
+ %uint_3 = OpConstant %uint 3
+ %float_0 = OpConstant %float 0
+ %v2float = OpTypeVector %float 2
+ %v3float = OpTypeVector %float 3
+ %v4float = OpTypeVector %float 4
+ %13 = OpConstantNull %v2float
+ %14 = OpConstantNull %v3float
+ %15 = OpConstantNull %v4float
+ %void = OpTypeVoid
+ %voidfn = OpTypeFunction %void
+ %10 = OpTypeImage %float 3D 0 0 0 1 Unknown
+ %11 = OpTypeSampledImage %10
+%_ptr_UniformConstant_11 = OpTypePointer UniformConstant %11
+
+ %100 = OpVariable %_ptr_UniformConstant_11 UniformConstant
+ %main = OpFunction %void None %voidfn
+ %main_0 = OpLabel
+ %combined = OpLoad %11 %100
+
+ ; Uses of the combined image sampler are preserved.
+ ; CHECK: OpCopyObject %11 %combined
+
+ %7 = OpCopyObject %11 %combined
+ OpReturn
+ OpFunctionEnd
diff --git a/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_7.spvasm b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_7.spvasm
new file mode 100644
index 0000000..41acfe1
--- /dev/null
+++ b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_7.spvasm
@@ -0,0 +1,69 @@
+ OpCapability Shader
+ OpCapability RuntimeDescriptorArray
+ OpExtension "SPV_EXT_descriptor_indexing"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ OpName %main "main"
+ OpName %main_0 "main_0"
+ OpName %voidfn "voidfn"
+
+ OpName %combined "combined"
+ OpDecorate %100 DescriptorSet 0
+ OpDecorate %100 Binding 0
+
+ ; CHECK: OpName
+ ; CHECK-NOT: OpDecorate %100
+ ; CHECK: OpDecorate %[[image_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[sampler_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[image_var]] Binding 0
+ ; CHECK: OpDecorate %[[sampler_var]] Binding 0
+
+ ; CHECK: %10 = OpTypeImage %
+ ; CHECK: %[[image_ptr_ty:\w+]] = OpTypePointer UniformConstant %10
+ ; CHECK: %[[sampler_ty:\d+]] = OpTypeSampler
+ ; CHECK: %[[sampler_ptr_ty:\w+]] = OpTypePointer UniformConstant %[[sampler_ty]]
+
+ ; The combined image variable is replaced by an image variable and a sampler variable.
+
+ ; CHECK-NOT: %100 = OpVariable
+ ; CHECK-DAG: %[[sampler_var]] = OpVariable %[[sampler_ptr_ty]] UniformConstant
+ ; CHECK-DAG: %[[image_var]] = OpVariable %[[image_ptr_ty]] UniformConstant
+ ; CHECK: = OpFunction
+
+ ; The load of the combined image+sampler is replaced by a two loads, then
+ ; a combination operation.
+ ; CHECK: %[[im:\d+]] = OpLoad %10 %[[image_var]]
+ ; CHECK: %[[s:\d+]] = OpLoad %[[sampler_ty]] %[[sampler_var]]
+ ; CHECK: %combined = OpSampledImage %11 %[[im]] %[[s]]
+
+ %float = OpTypeFloat 32
+ %uint = OpTypeInt 32 0
+ %int = OpTypeInt 32 1
+ %uint_0 = OpConstant %uint 0
+ %uint_1 = OpConstant %uint 1
+ %uint_3 = OpConstant %uint 3
+ %float_0 = OpConstant %float 0
+ %v2float = OpTypeVector %float 2
+ %v3float = OpTypeVector %float 3
+ %v4float = OpTypeVector %float 4
+ %13 = OpConstantNull %v2float
+ %14 = OpConstantNull %v3float
+ %15 = OpConstantNull %v4float
+ %void = OpTypeVoid
+ %voidfn = OpTypeFunction %void
+ %10 = OpTypeImage %float Cube 0 0 0 1 Unknown
+ %11 = OpTypeSampledImage %10
+%_ptr_UniformConstant_11 = OpTypePointer UniformConstant %11
+
+ %100 = OpVariable %_ptr_UniformConstant_11 UniformConstant
+ %main = OpFunction %void None %voidfn
+ %main_0 = OpLabel
+ %combined = OpLoad %11 %100
+
+ ; Uses of the combined image sampler are preserved.
+ ; CHECK: OpCopyObject %11 %combined
+
+ %7 = OpCopyObject %11 %combined
+ OpReturn
+ OpFunctionEnd
diff --git a/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_8.spvasm b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_8.spvasm
new file mode 100644
index 0000000..75bb43e
--- /dev/null
+++ b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_8.spvasm
@@ -0,0 +1,69 @@
+ OpCapability Shader
+ OpCapability RuntimeDescriptorArray
+ OpExtension "SPV_EXT_descriptor_indexing"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ OpName %main "main"
+ OpName %main_0 "main_0"
+ OpName %voidfn "voidfn"
+
+ OpName %combined "combined"
+ OpDecorate %100 DescriptorSet 0
+ OpDecorate %100 Binding 0
+
+ ; CHECK: OpName
+ ; CHECK-NOT: OpDecorate %100
+ ; CHECK: OpDecorate %[[image_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[sampler_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[image_var]] Binding 0
+ ; CHECK: OpDecorate %[[sampler_var]] Binding 0
+
+ ; CHECK: %10 = OpTypeImage %
+ ; CHECK: %[[image_ptr_ty:\w+]] = OpTypePointer UniformConstant %10
+ ; CHECK: %[[sampler_ty:\d+]] = OpTypeSampler
+ ; CHECK: %[[sampler_ptr_ty:\w+]] = OpTypePointer UniformConstant %[[sampler_ty]]
+
+ ; The combined image variable is replaced by an image variable and a sampler variable.
+
+ ; CHECK-NOT: %100 = OpVariable
+ ; CHECK-DAG: %[[sampler_var]] = OpVariable %[[sampler_ptr_ty]] UniformConstant
+ ; CHECK-DAG: %[[image_var]] = OpVariable %[[image_ptr_ty]] UniformConstant
+ ; CHECK: = OpFunction
+
+ ; The load of the combined image+sampler is replaced by a two loads, then
+ ; a combination operation.
+ ; CHECK: %[[im:\d+]] = OpLoad %10 %[[image_var]]
+ ; CHECK: %[[s:\d+]] = OpLoad %[[sampler_ty]] %[[sampler_var]]
+ ; CHECK: %combined = OpSampledImage %11 %[[im]] %[[s]]
+
+ %float = OpTypeFloat 32
+ %uint = OpTypeInt 32 0
+ %int = OpTypeInt 32 1
+ %uint_0 = OpConstant %uint 0
+ %uint_1 = OpConstant %uint 1
+ %uint_3 = OpConstant %uint 3
+ %float_0 = OpConstant %float 0
+ %v2float = OpTypeVector %float 2
+ %v3float = OpTypeVector %float 3
+ %v4float = OpTypeVector %float 4
+ %13 = OpConstantNull %v2float
+ %14 = OpConstantNull %v3float
+ %15 = OpConstantNull %v4float
+ %void = OpTypeVoid
+ %voidfn = OpTypeFunction %void
+ %10 = OpTypeImage %float Cube 1 0 0 1 Unknown
+ %11 = OpTypeSampledImage %10
+%_ptr_UniformConstant_11 = OpTypePointer UniformConstant %11
+
+ %100 = OpVariable %_ptr_UniformConstant_11 UniformConstant
+ %main = OpFunction %void None %voidfn
+ %main_0 = OpLabel
+ %combined = OpLoad %11 %100
+
+ ; Uses of the combined image sampler are preserved.
+ ; CHECK: OpCopyObject %11 %combined
+
+ %7 = OpCopyObject %11 %combined
+ OpReturn
+ OpFunctionEnd
diff --git a/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_9.spvasm b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_9.spvasm
new file mode 100644
index 0000000..f286020
--- /dev/null
+++ b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_9.spvasm
@@ -0,0 +1,69 @@
+ OpCapability Shader
+ OpCapability RuntimeDescriptorArray
+ OpExtension "SPV_EXT_descriptor_indexing"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ OpName %main "main"
+ OpName %main_0 "main_0"
+ OpName %voidfn "voidfn"
+
+ OpName %combined "combined"
+ OpDecorate %100 DescriptorSet 0
+ OpDecorate %100 Binding 0
+
+ ; CHECK: OpName
+ ; CHECK-NOT: OpDecorate %100
+ ; CHECK: OpDecorate %[[image_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[sampler_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[image_var]] Binding 0
+ ; CHECK: OpDecorate %[[sampler_var]] Binding 0
+
+ ; CHECK: %10 = OpTypeImage %
+ ; CHECK: %[[image_ptr_ty:\w+]] = OpTypePointer UniformConstant %10
+ ; CHECK: %[[sampler_ty:\d+]] = OpTypeSampler
+ ; CHECK: %[[sampler_ptr_ty:\w+]] = OpTypePointer UniformConstant %[[sampler_ty]]
+
+ ; The combined image variable is replaced by an image variable and a sampler variable.
+
+ ; CHECK-NOT: %100 = OpVariable
+ ; CHECK-DAG: %[[sampler_var]] = OpVariable %[[sampler_ptr_ty]] UniformConstant
+ ; CHECK-DAG: %[[image_var]] = OpVariable %[[image_ptr_ty]] UniformConstant
+ ; CHECK: = OpFunction
+
+ ; The load of the combined image+sampler is replaced by a two loads, then
+ ; a combination operation.
+ ; CHECK: %[[im:\d+]] = OpLoad %10 %[[image_var]]
+ ; CHECK: %[[s:\d+]] = OpLoad %[[sampler_ty]] %[[sampler_var]]
+ ; CHECK: %combined = OpSampledImage %11 %[[im]] %[[s]]
+
+ %float = OpTypeFloat 32
+ %uint = OpTypeInt 32 0
+ %int = OpTypeInt 32 1
+ %uint_0 = OpConstant %uint 0
+ %uint_1 = OpConstant %uint 1
+ %uint_3 = OpConstant %uint 3
+ %float_0 = OpConstant %float 0
+ %v2float = OpTypeVector %float 2
+ %v3float = OpTypeVector %float 3
+ %v4float = OpTypeVector %float 4
+ %13 = OpConstantNull %v2float
+ %14 = OpConstantNull %v3float
+ %15 = OpConstantNull %v4float
+ %void = OpTypeVoid
+ %voidfn = OpTypeFunction %void
+ %10 = OpTypeImage %float Cube 0 1 0 1 Unknown
+ %11 = OpTypeSampledImage %10
+%_ptr_UniformConstant_11 = OpTypePointer UniformConstant %11
+
+ %100 = OpVariable %_ptr_UniformConstant_11 UniformConstant
+ %main = OpFunction %void None %voidfn
+ %main_0 = OpLabel
+ %combined = OpLoad %11 %100
+
+ ; Uses of the combined image sampler are preserved.
+ ; CHECK: OpCopyObject %11 %combined
+
+ %7 = OpCopyObject %11 %combined
+ OpReturn
+ OpFunctionEnd
diff --git a/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_RelaxedPrecisionOnLoadCopied_0.spvasm b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_RelaxedPrecisionOnLoadCopied_0.spvasm
new file mode 100644
index 0000000..a0040e1
--- /dev/null
+++ b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_RelaxedPrecisionOnLoadCopied_0.spvasm
@@ -0,0 +1,77 @@
+ OpCapability Shader
+ OpCapability RuntimeDescriptorArray
+ OpExtension "SPV_EXT_descriptor_indexing"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ OpName %main "main"
+ OpName %main_0 "main_0"
+ OpName %voidfn "voidfn"
+
+ OpName %combined "combined"
+ OpDecorate %100 DescriptorSet 0
+ OpDecorate %100 Binding 0
+ OpDecorate %combined RelaxedPrecision
+
+ ; CHECK: OpName
+ ; CHECK-NOT: OpDecorate %100
+ ; CHECK: OpDecorate %[[image_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[sampler_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[image_var]] Binding 0
+ ; CHECK: OpDecorate %[[sampler_var]] Binding 0
+
+ ; This is what we are checking in this test.
+ ; CHECK: OpDecorate %[[im:\d+]] RelaxedPrecision
+ ; CHECK: OpDecorate %[[s:\d+]] RelaxedPrecision
+
+ ; CHECK: %10 = OpTypeImage %
+ ; CHECK: %[[image_ptr_ty:\w+]] = OpTypePointer UniformConstant %10
+ ; CHECK: %[[sampler_ty:\d+]] = OpTypeSampler
+ ; CHECK: %[[sampler_ptr_ty:\w+]] = OpTypePointer UniformConstant %[[sampler_ty]]
+
+ ; The combined image variable is replaced by an image variable and a sampler variable.
+
+ ; CHECK-NOT: %100 = OpVariable
+ ; CHECK-NOT: OpVariable _ptr_UniformConstant_11
+ ; CHECK-DAG: %[[sampler_var]] = OpVariable %[[sampler_ptr_ty]] UniformConstant
+ ; CHECK-DAG: %[[image_var]] = OpVariable %[[image_ptr_ty]] UniformConstant
+ ; CHECK: = OpFunction
+
+ ; The load of the combined image+sampler is replaced by a two loads, then
+ ; a combination operation. The new loads get the same decorations that the
+ ; original load had.
+ ; CHECK: %[[im]] = OpLoad %10 %[[image_var]]
+ ; CHECK: %[[s]] = OpLoad %[[sampler_ty]] %[[sampler_var]]
+ ; CHECK: %combined = OpSampledImage %11 %[[im]] %[[s]]
+
+ %bool = OpTypeBool ; location marker
+ %float = OpTypeFloat 32
+ %uint = OpTypeInt 32 0
+ %int = OpTypeInt 32 1
+ %uint_0 = OpConstant %uint 0
+ %uint_1 = OpConstant %uint 1
+ %uint_3 = OpConstant %uint 3
+ %float_0 = OpConstant %float 0
+ %v2float = OpTypeVector %float 2
+ %v3float = OpTypeVector %float 3
+ %v4float = OpTypeVector %float 4
+ %13 = OpConstantNull %v2float
+ %14 = OpConstantNull %v3float
+ %15 = OpConstantNull %v4float
+ %void = OpTypeVoid
+ %voidfn = OpTypeFunction %void
+ %10 = OpTypeImage %float 2D 0 0 0 1 Unknown
+ %11 = OpTypeSampledImage %10
+%_ptr_UniformConstant_11 = OpTypePointer UniformConstant %11
+
+ %100 = OpVariable %_ptr_UniformConstant_11 UniformConstant
+ %main = OpFunction %void None %voidfn
+ %main_0 = OpLabel
+ %combined = OpLoad %11 %100
+
+ ; Uses of the combined image sampler are preserved.
+ ; CHECK: OpCopyObject %11 %combined
+
+ %7 = OpCopyObject %11 %combined
+ OpReturn
+ OpFunctionEnd
diff --git a/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_RelaxedPrecisionOnLoadCopied_1.spvasm b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_RelaxedPrecisionOnLoadCopied_1.spvasm
new file mode 100644
index 0000000..44aa899
--- /dev/null
+++ b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_RelaxedPrecisionOnLoadCopied_1.spvasm
@@ -0,0 +1,77 @@
+ OpCapability Shader
+ OpCapability RuntimeDescriptorArray
+ OpExtension "SPV_EXT_descriptor_indexing"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ OpName %main "main"
+ OpName %main_0 "main_0"
+ OpName %voidfn "voidfn"
+
+ OpName %combined "combined"
+ OpDecorate %100 DescriptorSet 0
+ OpDecorate %100 Binding 0
+ OpDecorate %combined RelaxedPrecision
+
+ ; CHECK: OpName
+ ; CHECK-NOT: OpDecorate %100
+ ; CHECK: OpDecorate %[[image_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[sampler_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[image_var]] Binding 0
+ ; CHECK: OpDecorate %[[sampler_var]] Binding 0
+
+ ; This is what we are checking in this test.
+ ; CHECK: OpDecorate %[[im:\d+]] RelaxedPrecision
+ ; CHECK: OpDecorate %[[s:\d+]] RelaxedPrecision
+
+ ; CHECK: %10 = OpTypeImage %
+ ; CHECK: %[[image_ptr_ty:\w+]] = OpTypePointer UniformConstant %10
+ ; CHECK: %[[sampler_ty:\d+]] = OpTypeSampler
+ ; CHECK: %[[sampler_ptr_ty:\w+]] = OpTypePointer UniformConstant %[[sampler_ty]]
+
+ ; The combined image variable is replaced by an image variable and a sampler variable.
+
+ ; CHECK-NOT: %100 = OpVariable
+ ; CHECK-NOT: OpVariable _ptr_UniformConstant_11
+ ; CHECK-DAG: %[[sampler_var]] = OpVariable %[[sampler_ptr_ty]] UniformConstant
+ ; CHECK-DAG: %[[image_var]] = OpVariable %[[image_ptr_ty]] UniformConstant
+ ; CHECK: = OpFunction
+
+ ; The load of the combined image+sampler is replaced by a two loads, then
+ ; a combination operation. The new loads get the same decorations that the
+ ; original load had.
+ ; CHECK: %[[im]] = OpLoad %10 %[[image_var]]
+ ; CHECK: %[[s]] = OpLoad %[[sampler_ty]] %[[sampler_var]]
+ ; CHECK: %combined = OpSampledImage %11 %[[im]] %[[s]]
+
+ %bool = OpTypeBool ; location marker
+ %float = OpTypeFloat 32
+ %uint = OpTypeInt 32 0
+ %int = OpTypeInt 32 1
+ %uint_0 = OpConstant %uint 0
+ %uint_1 = OpConstant %uint 1
+ %uint_3 = OpConstant %uint 3
+ %float_0 = OpConstant %float 0
+ %v2float = OpTypeVector %float 2
+ %v3float = OpTypeVector %float 3
+ %v4float = OpTypeVector %float 4
+ %13 = OpConstantNull %v2float
+ %14 = OpConstantNull %v3float
+ %15 = OpConstantNull %v4float
+ %void = OpTypeVoid
+ %voidfn = OpTypeFunction %void
+ %10 = OpTypeImage %float 2D 1 0 0 1 Unknown
+ %11 = OpTypeSampledImage %10
+%_ptr_UniformConstant_11 = OpTypePointer UniformConstant %11
+
+ %100 = OpVariable %_ptr_UniformConstant_11 UniformConstant
+ %main = OpFunction %void None %voidfn
+ %main_0 = OpLabel
+ %combined = OpLoad %11 %100
+
+ ; Uses of the combined image sampler are preserved.
+ ; CHECK: OpCopyObject %11 %combined
+
+ %7 = OpCopyObject %11 %combined
+ OpReturn
+ OpFunctionEnd
diff --git a/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_RelaxedPrecisionOnLoadCopied_10.spvasm b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_RelaxedPrecisionOnLoadCopied_10.spvasm
new file mode 100644
index 0000000..d3206ee
--- /dev/null
+++ b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_RelaxedPrecisionOnLoadCopied_10.spvasm
@@ -0,0 +1,77 @@
+ OpCapability Shader
+ OpCapability RuntimeDescriptorArray
+ OpExtension "SPV_EXT_descriptor_indexing"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ OpName %main "main"
+ OpName %main_0 "main_0"
+ OpName %voidfn "voidfn"
+
+ OpName %combined "combined"
+ OpDecorate %100 DescriptorSet 0
+ OpDecorate %100 Binding 0
+ OpDecorate %combined RelaxedPrecision
+
+ ; CHECK: OpName
+ ; CHECK-NOT: OpDecorate %100
+ ; CHECK: OpDecorate %[[image_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[sampler_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[image_var]] Binding 0
+ ; CHECK: OpDecorate %[[sampler_var]] Binding 0
+
+ ; This is what we are checking in this test.
+ ; CHECK: OpDecorate %[[im:\d+]] RelaxedPrecision
+ ; CHECK: OpDecorate %[[s:\d+]] RelaxedPrecision
+
+ ; CHECK: %10 = OpTypeImage %
+ ; CHECK: %[[image_ptr_ty:\w+]] = OpTypePointer UniformConstant %10
+ ; CHECK: %[[sampler_ty:\d+]] = OpTypeSampler
+ ; CHECK: %[[sampler_ptr_ty:\w+]] = OpTypePointer UniformConstant %[[sampler_ty]]
+
+ ; The combined image variable is replaced by an image variable and a sampler variable.
+
+ ; CHECK-NOT: %100 = OpVariable
+ ; CHECK-NOT: OpVariable _ptr_UniformConstant_11
+ ; CHECK-DAG: %[[sampler_var]] = OpVariable %[[sampler_ptr_ty]] UniformConstant
+ ; CHECK-DAG: %[[image_var]] = OpVariable %[[image_ptr_ty]] UniformConstant
+ ; CHECK: = OpFunction
+
+ ; The load of the combined image+sampler is replaced by a two loads, then
+ ; a combination operation. The new loads get the same decorations that the
+ ; original load had.
+ ; CHECK: %[[im]] = OpLoad %10 %[[image_var]]
+ ; CHECK: %[[s]] = OpLoad %[[sampler_ty]] %[[sampler_var]]
+ ; CHECK: %combined = OpSampledImage %11 %[[im]] %[[s]]
+
+ %bool = OpTypeBool ; location marker
+ %float = OpTypeFloat 32
+ %uint = OpTypeInt 32 0
+ %int = OpTypeInt 32 1
+ %uint_0 = OpConstant %uint 0
+ %uint_1 = OpConstant %uint 1
+ %uint_3 = OpConstant %uint 3
+ %float_0 = OpConstant %float 0
+ %v2float = OpTypeVector %float 2
+ %v3float = OpTypeVector %float 3
+ %v4float = OpTypeVector %float 4
+ %13 = OpConstantNull %v2float
+ %14 = OpConstantNull %v3float
+ %15 = OpConstantNull %v4float
+ %void = OpTypeVoid
+ %voidfn = OpTypeFunction %void
+ %10 = OpTypeImage %float Cube 1 1 0 1 Unknown
+ %11 = OpTypeSampledImage %10
+%_ptr_UniformConstant_11 = OpTypePointer UniformConstant %11
+
+ %100 = OpVariable %_ptr_UniformConstant_11 UniformConstant
+ %main = OpFunction %void None %voidfn
+ %main_0 = OpLabel
+ %combined = OpLoad %11 %100
+
+ ; Uses of the combined image sampler are preserved.
+ ; CHECK: OpCopyObject %11 %combined
+
+ %7 = OpCopyObject %11 %combined
+ OpReturn
+ OpFunctionEnd
diff --git a/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_RelaxedPrecisionOnLoadCopied_11.spvasm b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_RelaxedPrecisionOnLoadCopied_11.spvasm
new file mode 100644
index 0000000..6921757
--- /dev/null
+++ b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_RelaxedPrecisionOnLoadCopied_11.spvasm
@@ -0,0 +1,77 @@
+ OpCapability Shader
+ OpCapability RuntimeDescriptorArray
+ OpExtension "SPV_EXT_descriptor_indexing"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ OpName %main "main"
+ OpName %main_0 "main_0"
+ OpName %voidfn "voidfn"
+
+ OpName %combined "combined"
+ OpDecorate %100 DescriptorSet 0
+ OpDecorate %100 Binding 0
+ OpDecorate %combined RelaxedPrecision
+
+ ; CHECK: OpName
+ ; CHECK-NOT: OpDecorate %100
+ ; CHECK: OpDecorate %[[image_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[sampler_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[image_var]] Binding 0
+ ; CHECK: OpDecorate %[[sampler_var]] Binding 0
+
+ ; This is what we are checking in this test.
+ ; CHECK: OpDecorate %[[im:\d+]] RelaxedPrecision
+ ; CHECK: OpDecorate %[[s:\d+]] RelaxedPrecision
+
+ ; CHECK: %10 = OpTypeImage %
+ ; CHECK: %[[image_ptr_ty:\w+]] = OpTypePointer UniformConstant %10
+ ; CHECK: %[[sampler_ty:\d+]] = OpTypeSampler
+ ; CHECK: %[[sampler_ptr_ty:\w+]] = OpTypePointer UniformConstant %[[sampler_ty]]
+
+ ; The combined image variable is replaced by an image variable and a sampler variable.
+
+ ; CHECK-NOT: %100 = OpVariable
+ ; CHECK-NOT: OpVariable _ptr_UniformConstant_11
+ ; CHECK-DAG: %[[sampler_var]] = OpVariable %[[sampler_ptr_ty]] UniformConstant
+ ; CHECK-DAG: %[[image_var]] = OpVariable %[[image_ptr_ty]] UniformConstant
+ ; CHECK: = OpFunction
+
+ ; The load of the combined image+sampler is replaced by a two loads, then
+ ; a combination operation. The new loads get the same decorations that the
+ ; original load had.
+ ; CHECK: %[[im]] = OpLoad %10 %[[image_var]]
+ ; CHECK: %[[s]] = OpLoad %[[sampler_ty]] %[[sampler_var]]
+ ; CHECK: %combined = OpSampledImage %11 %[[im]] %[[s]]
+
+ %bool = OpTypeBool ; location marker
+ %float = OpTypeFloat 32
+ %uint = OpTypeInt 32 0
+ %int = OpTypeInt 32 1
+ %uint_0 = OpConstant %uint 0
+ %uint_1 = OpConstant %uint 1
+ %uint_3 = OpConstant %uint 3
+ %float_0 = OpConstant %float 0
+ %v2float = OpTypeVector %float 2
+ %v3float = OpTypeVector %float 3
+ %v4float = OpTypeVector %float 4
+ %13 = OpConstantNull %v2float
+ %14 = OpConstantNull %v3float
+ %15 = OpConstantNull %v4float
+ %void = OpTypeVoid
+ %voidfn = OpTypeFunction %void
+ %10 = OpTypeImage %int 2D 0 0 0 1 Unknown
+ %11 = OpTypeSampledImage %10
+%_ptr_UniformConstant_11 = OpTypePointer UniformConstant %11
+
+ %100 = OpVariable %_ptr_UniformConstant_11 UniformConstant
+ %main = OpFunction %void None %voidfn
+ %main_0 = OpLabel
+ %combined = OpLoad %11 %100
+
+ ; Uses of the combined image sampler are preserved.
+ ; CHECK: OpCopyObject %11 %combined
+
+ %7 = OpCopyObject %11 %combined
+ OpReturn
+ OpFunctionEnd
diff --git a/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_RelaxedPrecisionOnLoadCopied_12.spvasm b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_RelaxedPrecisionOnLoadCopied_12.spvasm
new file mode 100644
index 0000000..919562b
--- /dev/null
+++ b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_RelaxedPrecisionOnLoadCopied_12.spvasm
@@ -0,0 +1,77 @@
+ OpCapability Shader
+ OpCapability RuntimeDescriptorArray
+ OpExtension "SPV_EXT_descriptor_indexing"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ OpName %main "main"
+ OpName %main_0 "main_0"
+ OpName %voidfn "voidfn"
+
+ OpName %combined "combined"
+ OpDecorate %100 DescriptorSet 0
+ OpDecorate %100 Binding 0
+ OpDecorate %combined RelaxedPrecision
+
+ ; CHECK: OpName
+ ; CHECK-NOT: OpDecorate %100
+ ; CHECK: OpDecorate %[[image_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[sampler_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[image_var]] Binding 0
+ ; CHECK: OpDecorate %[[sampler_var]] Binding 0
+
+ ; This is what we are checking in this test.
+ ; CHECK: OpDecorate %[[im:\d+]] RelaxedPrecision
+ ; CHECK: OpDecorate %[[s:\d+]] RelaxedPrecision
+
+ ; CHECK: %10 = OpTypeImage %
+ ; CHECK: %[[image_ptr_ty:\w+]] = OpTypePointer UniformConstant %10
+ ; CHECK: %[[sampler_ty:\d+]] = OpTypeSampler
+ ; CHECK: %[[sampler_ptr_ty:\w+]] = OpTypePointer UniformConstant %[[sampler_ty]]
+
+ ; The combined image variable is replaced by an image variable and a sampler variable.
+
+ ; CHECK-NOT: %100 = OpVariable
+ ; CHECK-NOT: OpVariable _ptr_UniformConstant_11
+ ; CHECK-DAG: %[[sampler_var]] = OpVariable %[[sampler_ptr_ty]] UniformConstant
+ ; CHECK-DAG: %[[image_var]] = OpVariable %[[image_ptr_ty]] UniformConstant
+ ; CHECK: = OpFunction
+
+ ; The load of the combined image+sampler is replaced by a two loads, then
+ ; a combination operation. The new loads get the same decorations that the
+ ; original load had.
+ ; CHECK: %[[im]] = OpLoad %10 %[[image_var]]
+ ; CHECK: %[[s]] = OpLoad %[[sampler_ty]] %[[sampler_var]]
+ ; CHECK: %combined = OpSampledImage %11 %[[im]] %[[s]]
+
+ %bool = OpTypeBool ; location marker
+ %float = OpTypeFloat 32
+ %uint = OpTypeInt 32 0
+ %int = OpTypeInt 32 1
+ %uint_0 = OpConstant %uint 0
+ %uint_1 = OpConstant %uint 1
+ %uint_3 = OpConstant %uint 3
+ %float_0 = OpConstant %float 0
+ %v2float = OpTypeVector %float 2
+ %v3float = OpTypeVector %float 3
+ %v4float = OpTypeVector %float 4
+ %13 = OpConstantNull %v2float
+ %14 = OpConstantNull %v3float
+ %15 = OpConstantNull %v4float
+ %void = OpTypeVoid
+ %voidfn = OpTypeFunction %void
+ %10 = OpTypeImage %int 2D 1 0 0 1 Unknown
+ %11 = OpTypeSampledImage %10
+%_ptr_UniformConstant_11 = OpTypePointer UniformConstant %11
+
+ %100 = OpVariable %_ptr_UniformConstant_11 UniformConstant
+ %main = OpFunction %void None %voidfn
+ %main_0 = OpLabel
+ %combined = OpLoad %11 %100
+
+ ; Uses of the combined image sampler are preserved.
+ ; CHECK: OpCopyObject %11 %combined
+
+ %7 = OpCopyObject %11 %combined
+ OpReturn
+ OpFunctionEnd
diff --git a/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_RelaxedPrecisionOnLoadCopied_13.spvasm b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_RelaxedPrecisionOnLoadCopied_13.spvasm
new file mode 100644
index 0000000..ca8336d
--- /dev/null
+++ b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_RelaxedPrecisionOnLoadCopied_13.spvasm
@@ -0,0 +1,77 @@
+ OpCapability Shader
+ OpCapability RuntimeDescriptorArray
+ OpExtension "SPV_EXT_descriptor_indexing"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ OpName %main "main"
+ OpName %main_0 "main_0"
+ OpName %voidfn "voidfn"
+
+ OpName %combined "combined"
+ OpDecorate %100 DescriptorSet 0
+ OpDecorate %100 Binding 0
+ OpDecorate %combined RelaxedPrecision
+
+ ; CHECK: OpName
+ ; CHECK-NOT: OpDecorate %100
+ ; CHECK: OpDecorate %[[image_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[sampler_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[image_var]] Binding 0
+ ; CHECK: OpDecorate %[[sampler_var]] Binding 0
+
+ ; This is what we are checking in this test.
+ ; CHECK: OpDecorate %[[im:\d+]] RelaxedPrecision
+ ; CHECK: OpDecorate %[[s:\d+]] RelaxedPrecision
+
+ ; CHECK: %10 = OpTypeImage %
+ ; CHECK: %[[image_ptr_ty:\w+]] = OpTypePointer UniformConstant %10
+ ; CHECK: %[[sampler_ty:\d+]] = OpTypeSampler
+ ; CHECK: %[[sampler_ptr_ty:\w+]] = OpTypePointer UniformConstant %[[sampler_ty]]
+
+ ; The combined image variable is replaced by an image variable and a sampler variable.
+
+ ; CHECK-NOT: %100 = OpVariable
+ ; CHECK-NOT: OpVariable _ptr_UniformConstant_11
+ ; CHECK-DAG: %[[sampler_var]] = OpVariable %[[sampler_ptr_ty]] UniformConstant
+ ; CHECK-DAG: %[[image_var]] = OpVariable %[[image_ptr_ty]] UniformConstant
+ ; CHECK: = OpFunction
+
+ ; The load of the combined image+sampler is replaced by a two loads, then
+ ; a combination operation. The new loads get the same decorations that the
+ ; original load had.
+ ; CHECK: %[[im]] = OpLoad %10 %[[image_var]]
+ ; CHECK: %[[s]] = OpLoad %[[sampler_ty]] %[[sampler_var]]
+ ; CHECK: %combined = OpSampledImage %11 %[[im]] %[[s]]
+
+ %bool = OpTypeBool ; location marker
+ %float = OpTypeFloat 32
+ %uint = OpTypeInt 32 0
+ %int = OpTypeInt 32 1
+ %uint_0 = OpConstant %uint 0
+ %uint_1 = OpConstant %uint 1
+ %uint_3 = OpConstant %uint 3
+ %float_0 = OpConstant %float 0
+ %v2float = OpTypeVector %float 2
+ %v3float = OpTypeVector %float 3
+ %v4float = OpTypeVector %float 4
+ %13 = OpConstantNull %v2float
+ %14 = OpConstantNull %v3float
+ %15 = OpConstantNull %v4float
+ %void = OpTypeVoid
+ %voidfn = OpTypeFunction %void
+ %10 = OpTypeImage %int 2D 0 1 0 1 Unknown
+ %11 = OpTypeSampledImage %10
+%_ptr_UniformConstant_11 = OpTypePointer UniformConstant %11
+
+ %100 = OpVariable %_ptr_UniformConstant_11 UniformConstant
+ %main = OpFunction %void None %voidfn
+ %main_0 = OpLabel
+ %combined = OpLoad %11 %100
+
+ ; Uses of the combined image sampler are preserved.
+ ; CHECK: OpCopyObject %11 %combined
+
+ %7 = OpCopyObject %11 %combined
+ OpReturn
+ OpFunctionEnd
diff --git a/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_RelaxedPrecisionOnLoadCopied_14.spvasm b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_RelaxedPrecisionOnLoadCopied_14.spvasm
new file mode 100644
index 0000000..a7230a8
--- /dev/null
+++ b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_RelaxedPrecisionOnLoadCopied_14.spvasm
@@ -0,0 +1,77 @@
+ OpCapability Shader
+ OpCapability RuntimeDescriptorArray
+ OpExtension "SPV_EXT_descriptor_indexing"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ OpName %main "main"
+ OpName %main_0 "main_0"
+ OpName %voidfn "voidfn"
+
+ OpName %combined "combined"
+ OpDecorate %100 DescriptorSet 0
+ OpDecorate %100 Binding 0
+ OpDecorate %combined RelaxedPrecision
+
+ ; CHECK: OpName
+ ; CHECK-NOT: OpDecorate %100
+ ; CHECK: OpDecorate %[[image_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[sampler_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[image_var]] Binding 0
+ ; CHECK: OpDecorate %[[sampler_var]] Binding 0
+
+ ; This is what we are checking in this test.
+ ; CHECK: OpDecorate %[[im:\d+]] RelaxedPrecision
+ ; CHECK: OpDecorate %[[s:\d+]] RelaxedPrecision
+
+ ; CHECK: %10 = OpTypeImage %
+ ; CHECK: %[[image_ptr_ty:\w+]] = OpTypePointer UniformConstant %10
+ ; CHECK: %[[sampler_ty:\d+]] = OpTypeSampler
+ ; CHECK: %[[sampler_ptr_ty:\w+]] = OpTypePointer UniformConstant %[[sampler_ty]]
+
+ ; The combined image variable is replaced by an image variable and a sampler variable.
+
+ ; CHECK-NOT: %100 = OpVariable
+ ; CHECK-NOT: OpVariable _ptr_UniformConstant_11
+ ; CHECK-DAG: %[[sampler_var]] = OpVariable %[[sampler_ptr_ty]] UniformConstant
+ ; CHECK-DAG: %[[image_var]] = OpVariable %[[image_ptr_ty]] UniformConstant
+ ; CHECK: = OpFunction
+
+ ; The load of the combined image+sampler is replaced by a two loads, then
+ ; a combination operation. The new loads get the same decorations that the
+ ; original load had.
+ ; CHECK: %[[im]] = OpLoad %10 %[[image_var]]
+ ; CHECK: %[[s]] = OpLoad %[[sampler_ty]] %[[sampler_var]]
+ ; CHECK: %combined = OpSampledImage %11 %[[im]] %[[s]]
+
+ %bool = OpTypeBool ; location marker
+ %float = OpTypeFloat 32
+ %uint = OpTypeInt 32 0
+ %int = OpTypeInt 32 1
+ %uint_0 = OpConstant %uint 0
+ %uint_1 = OpConstant %uint 1
+ %uint_3 = OpConstant %uint 3
+ %float_0 = OpConstant %float 0
+ %v2float = OpTypeVector %float 2
+ %v3float = OpTypeVector %float 3
+ %v4float = OpTypeVector %float 4
+ %13 = OpConstantNull %v2float
+ %14 = OpConstantNull %v3float
+ %15 = OpConstantNull %v4float
+ %void = OpTypeVoid
+ %voidfn = OpTypeFunction %void
+ %10 = OpTypeImage %int 2D 1 1 0 1 Unknown
+ %11 = OpTypeSampledImage %10
+%_ptr_UniformConstant_11 = OpTypePointer UniformConstant %11
+
+ %100 = OpVariable %_ptr_UniformConstant_11 UniformConstant
+ %main = OpFunction %void None %voidfn
+ %main_0 = OpLabel
+ %combined = OpLoad %11 %100
+
+ ; Uses of the combined image sampler are preserved.
+ ; CHECK: OpCopyObject %11 %combined
+
+ %7 = OpCopyObject %11 %combined
+ OpReturn
+ OpFunctionEnd
diff --git a/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_RelaxedPrecisionOnLoadCopied_15.spvasm b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_RelaxedPrecisionOnLoadCopied_15.spvasm
new file mode 100644
index 0000000..6901d5c
--- /dev/null
+++ b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_RelaxedPrecisionOnLoadCopied_15.spvasm
@@ -0,0 +1,77 @@
+ OpCapability Shader
+ OpCapability RuntimeDescriptorArray
+ OpExtension "SPV_EXT_descriptor_indexing"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ OpName %main "main"
+ OpName %main_0 "main_0"
+ OpName %voidfn "voidfn"
+
+ OpName %combined "combined"
+ OpDecorate %100 DescriptorSet 0
+ OpDecorate %100 Binding 0
+ OpDecorate %combined RelaxedPrecision
+
+ ; CHECK: OpName
+ ; CHECK-NOT: OpDecorate %100
+ ; CHECK: OpDecorate %[[image_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[sampler_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[image_var]] Binding 0
+ ; CHECK: OpDecorate %[[sampler_var]] Binding 0
+
+ ; This is what we are checking in this test.
+ ; CHECK: OpDecorate %[[im:\d+]] RelaxedPrecision
+ ; CHECK: OpDecorate %[[s:\d+]] RelaxedPrecision
+
+ ; CHECK: %10 = OpTypeImage %
+ ; CHECK: %[[image_ptr_ty:\w+]] = OpTypePointer UniformConstant %10
+ ; CHECK: %[[sampler_ty:\d+]] = OpTypeSampler
+ ; CHECK: %[[sampler_ptr_ty:\w+]] = OpTypePointer UniformConstant %[[sampler_ty]]
+
+ ; The combined image variable is replaced by an image variable and a sampler variable.
+
+ ; CHECK-NOT: %100 = OpVariable
+ ; CHECK-NOT: OpVariable _ptr_UniformConstant_11
+ ; CHECK-DAG: %[[sampler_var]] = OpVariable %[[sampler_ptr_ty]] UniformConstant
+ ; CHECK-DAG: %[[image_var]] = OpVariable %[[image_ptr_ty]] UniformConstant
+ ; CHECK: = OpFunction
+
+ ; The load of the combined image+sampler is replaced by a two loads, then
+ ; a combination operation. The new loads get the same decorations that the
+ ; original load had.
+ ; CHECK: %[[im]] = OpLoad %10 %[[image_var]]
+ ; CHECK: %[[s]] = OpLoad %[[sampler_ty]] %[[sampler_var]]
+ ; CHECK: %combined = OpSampledImage %11 %[[im]] %[[s]]
+
+ %bool = OpTypeBool ; location marker
+ %float = OpTypeFloat 32
+ %uint = OpTypeInt 32 0
+ %int = OpTypeInt 32 1
+ %uint_0 = OpConstant %uint 0
+ %uint_1 = OpConstant %uint 1
+ %uint_3 = OpConstant %uint 3
+ %float_0 = OpConstant %float 0
+ %v2float = OpTypeVector %float 2
+ %v3float = OpTypeVector %float 3
+ %v4float = OpTypeVector %float 4
+ %13 = OpConstantNull %v2float
+ %14 = OpConstantNull %v3float
+ %15 = OpConstantNull %v4float
+ %void = OpTypeVoid
+ %voidfn = OpTypeFunction %void
+ %10 = OpTypeImage %int 2D 0 0 1 1 Unknown
+ %11 = OpTypeSampledImage %10
+%_ptr_UniformConstant_11 = OpTypePointer UniformConstant %11
+
+ %100 = OpVariable %_ptr_UniformConstant_11 UniformConstant
+ %main = OpFunction %void None %voidfn
+ %main_0 = OpLabel
+ %combined = OpLoad %11 %100
+
+ ; Uses of the combined image sampler are preserved.
+ ; CHECK: OpCopyObject %11 %combined
+
+ %7 = OpCopyObject %11 %combined
+ OpReturn
+ OpFunctionEnd
diff --git a/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_RelaxedPrecisionOnLoadCopied_17.spvasm b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_RelaxedPrecisionOnLoadCopied_17.spvasm
new file mode 100644
index 0000000..691fd04
--- /dev/null
+++ b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_RelaxedPrecisionOnLoadCopied_17.spvasm
@@ -0,0 +1,77 @@
+ OpCapability Shader
+ OpCapability RuntimeDescriptorArray
+ OpExtension "SPV_EXT_descriptor_indexing"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ OpName %main "main"
+ OpName %main_0 "main_0"
+ OpName %voidfn "voidfn"
+
+ OpName %combined "combined"
+ OpDecorate %100 DescriptorSet 0
+ OpDecorate %100 Binding 0
+ OpDecorate %combined RelaxedPrecision
+
+ ; CHECK: OpName
+ ; CHECK-NOT: OpDecorate %100
+ ; CHECK: OpDecorate %[[image_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[sampler_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[image_var]] Binding 0
+ ; CHECK: OpDecorate %[[sampler_var]] Binding 0
+
+ ; This is what we are checking in this test.
+ ; CHECK: OpDecorate %[[im:\d+]] RelaxedPrecision
+ ; CHECK: OpDecorate %[[s:\d+]] RelaxedPrecision
+
+ ; CHECK: %10 = OpTypeImage %
+ ; CHECK: %[[image_ptr_ty:\w+]] = OpTypePointer UniformConstant %10
+ ; CHECK: %[[sampler_ty:\d+]] = OpTypeSampler
+ ; CHECK: %[[sampler_ptr_ty:\w+]] = OpTypePointer UniformConstant %[[sampler_ty]]
+
+ ; The combined image variable is replaced by an image variable and a sampler variable.
+
+ ; CHECK-NOT: %100 = OpVariable
+ ; CHECK-NOT: OpVariable _ptr_UniformConstant_11
+ ; CHECK-DAG: %[[sampler_var]] = OpVariable %[[sampler_ptr_ty]] UniformConstant
+ ; CHECK-DAG: %[[image_var]] = OpVariable %[[image_ptr_ty]] UniformConstant
+ ; CHECK: = OpFunction
+
+ ; The load of the combined image+sampler is replaced by a two loads, then
+ ; a combination operation. The new loads get the same decorations that the
+ ; original load had.
+ ; CHECK: %[[im]] = OpLoad %10 %[[image_var]]
+ ; CHECK: %[[s]] = OpLoad %[[sampler_ty]] %[[sampler_var]]
+ ; CHECK: %combined = OpSampledImage %11 %[[im]] %[[s]]
+
+ %bool = OpTypeBool ; location marker
+ %float = OpTypeFloat 32
+ %uint = OpTypeInt 32 0
+ %int = OpTypeInt 32 1
+ %uint_0 = OpConstant %uint 0
+ %uint_1 = OpConstant %uint 1
+ %uint_3 = OpConstant %uint 3
+ %float_0 = OpConstant %float 0
+ %v2float = OpTypeVector %float 2
+ %v3float = OpTypeVector %float 3
+ %v4float = OpTypeVector %float 4
+ %13 = OpConstantNull %v2float
+ %14 = OpConstantNull %v3float
+ %15 = OpConstantNull %v4float
+ %void = OpTypeVoid
+ %voidfn = OpTypeFunction %void
+ %10 = OpTypeImage %int 3D 0 0 0 1 Unknown
+ %11 = OpTypeSampledImage %10
+%_ptr_UniformConstant_11 = OpTypePointer UniformConstant %11
+
+ %100 = OpVariable %_ptr_UniformConstant_11 UniformConstant
+ %main = OpFunction %void None %voidfn
+ %main_0 = OpLabel
+ %combined = OpLoad %11 %100
+
+ ; Uses of the combined image sampler are preserved.
+ ; CHECK: OpCopyObject %11 %combined
+
+ %7 = OpCopyObject %11 %combined
+ OpReturn
+ OpFunctionEnd
diff --git a/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_RelaxedPrecisionOnLoadCopied_18.spvasm b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_RelaxedPrecisionOnLoadCopied_18.spvasm
new file mode 100644
index 0000000..2958ad8
--- /dev/null
+++ b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_RelaxedPrecisionOnLoadCopied_18.spvasm
@@ -0,0 +1,77 @@
+ OpCapability Shader
+ OpCapability RuntimeDescriptorArray
+ OpExtension "SPV_EXT_descriptor_indexing"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ OpName %main "main"
+ OpName %main_0 "main_0"
+ OpName %voidfn "voidfn"
+
+ OpName %combined "combined"
+ OpDecorate %100 DescriptorSet 0
+ OpDecorate %100 Binding 0
+ OpDecorate %combined RelaxedPrecision
+
+ ; CHECK: OpName
+ ; CHECK-NOT: OpDecorate %100
+ ; CHECK: OpDecorate %[[image_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[sampler_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[image_var]] Binding 0
+ ; CHECK: OpDecorate %[[sampler_var]] Binding 0
+
+ ; This is what we are checking in this test.
+ ; CHECK: OpDecorate %[[im:\d+]] RelaxedPrecision
+ ; CHECK: OpDecorate %[[s:\d+]] RelaxedPrecision
+
+ ; CHECK: %10 = OpTypeImage %
+ ; CHECK: %[[image_ptr_ty:\w+]] = OpTypePointer UniformConstant %10
+ ; CHECK: %[[sampler_ty:\d+]] = OpTypeSampler
+ ; CHECK: %[[sampler_ptr_ty:\w+]] = OpTypePointer UniformConstant %[[sampler_ty]]
+
+ ; The combined image variable is replaced by an image variable and a sampler variable.
+
+ ; CHECK-NOT: %100 = OpVariable
+ ; CHECK-NOT: OpVariable _ptr_UniformConstant_11
+ ; CHECK-DAG: %[[sampler_var]] = OpVariable %[[sampler_ptr_ty]] UniformConstant
+ ; CHECK-DAG: %[[image_var]] = OpVariable %[[image_ptr_ty]] UniformConstant
+ ; CHECK: = OpFunction
+
+ ; The load of the combined image+sampler is replaced by a two loads, then
+ ; a combination operation. The new loads get the same decorations that the
+ ; original load had.
+ ; CHECK: %[[im]] = OpLoad %10 %[[image_var]]
+ ; CHECK: %[[s]] = OpLoad %[[sampler_ty]] %[[sampler_var]]
+ ; CHECK: %combined = OpSampledImage %11 %[[im]] %[[s]]
+
+ %bool = OpTypeBool ; location marker
+ %float = OpTypeFloat 32
+ %uint = OpTypeInt 32 0
+ %int = OpTypeInt 32 1
+ %uint_0 = OpConstant %uint 0
+ %uint_1 = OpConstant %uint 1
+ %uint_3 = OpConstant %uint 3
+ %float_0 = OpConstant %float 0
+ %v2float = OpTypeVector %float 2
+ %v3float = OpTypeVector %float 3
+ %v4float = OpTypeVector %float 4
+ %13 = OpConstantNull %v2float
+ %14 = OpConstantNull %v3float
+ %15 = OpConstantNull %v4float
+ %void = OpTypeVoid
+ %voidfn = OpTypeFunction %void
+ %10 = OpTypeImage %int Cube 0 0 0 1 Unknown
+ %11 = OpTypeSampledImage %10
+%_ptr_UniformConstant_11 = OpTypePointer UniformConstant %11
+
+ %100 = OpVariable %_ptr_UniformConstant_11 UniformConstant
+ %main = OpFunction %void None %voidfn
+ %main_0 = OpLabel
+ %combined = OpLoad %11 %100
+
+ ; Uses of the combined image sampler are preserved.
+ ; CHECK: OpCopyObject %11 %combined
+
+ %7 = OpCopyObject %11 %combined
+ OpReturn
+ OpFunctionEnd
diff --git a/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_RelaxedPrecisionOnLoadCopied_19.spvasm b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_RelaxedPrecisionOnLoadCopied_19.spvasm
new file mode 100644
index 0000000..62982b4
--- /dev/null
+++ b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_RelaxedPrecisionOnLoadCopied_19.spvasm
@@ -0,0 +1,77 @@
+ OpCapability Shader
+ OpCapability RuntimeDescriptorArray
+ OpExtension "SPV_EXT_descriptor_indexing"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ OpName %main "main"
+ OpName %main_0 "main_0"
+ OpName %voidfn "voidfn"
+
+ OpName %combined "combined"
+ OpDecorate %100 DescriptorSet 0
+ OpDecorate %100 Binding 0
+ OpDecorate %combined RelaxedPrecision
+
+ ; CHECK: OpName
+ ; CHECK-NOT: OpDecorate %100
+ ; CHECK: OpDecorate %[[image_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[sampler_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[image_var]] Binding 0
+ ; CHECK: OpDecorate %[[sampler_var]] Binding 0
+
+ ; This is what we are checking in this test.
+ ; CHECK: OpDecorate %[[im:\d+]] RelaxedPrecision
+ ; CHECK: OpDecorate %[[s:\d+]] RelaxedPrecision
+
+ ; CHECK: %10 = OpTypeImage %
+ ; CHECK: %[[image_ptr_ty:\w+]] = OpTypePointer UniformConstant %10
+ ; CHECK: %[[sampler_ty:\d+]] = OpTypeSampler
+ ; CHECK: %[[sampler_ptr_ty:\w+]] = OpTypePointer UniformConstant %[[sampler_ty]]
+
+ ; The combined image variable is replaced by an image variable and a sampler variable.
+
+ ; CHECK-NOT: %100 = OpVariable
+ ; CHECK-NOT: OpVariable _ptr_UniformConstant_11
+ ; CHECK-DAG: %[[sampler_var]] = OpVariable %[[sampler_ptr_ty]] UniformConstant
+ ; CHECK-DAG: %[[image_var]] = OpVariable %[[image_ptr_ty]] UniformConstant
+ ; CHECK: = OpFunction
+
+ ; The load of the combined image+sampler is replaced by a two loads, then
+ ; a combination operation. The new loads get the same decorations that the
+ ; original load had.
+ ; CHECK: %[[im]] = OpLoad %10 %[[image_var]]
+ ; CHECK: %[[s]] = OpLoad %[[sampler_ty]] %[[sampler_var]]
+ ; CHECK: %combined = OpSampledImage %11 %[[im]] %[[s]]
+
+ %bool = OpTypeBool ; location marker
+ %float = OpTypeFloat 32
+ %uint = OpTypeInt 32 0
+ %int = OpTypeInt 32 1
+ %uint_0 = OpConstant %uint 0
+ %uint_1 = OpConstant %uint 1
+ %uint_3 = OpConstant %uint 3
+ %float_0 = OpConstant %float 0
+ %v2float = OpTypeVector %float 2
+ %v3float = OpTypeVector %float 3
+ %v4float = OpTypeVector %float 4
+ %13 = OpConstantNull %v2float
+ %14 = OpConstantNull %v3float
+ %15 = OpConstantNull %v4float
+ %void = OpTypeVoid
+ %voidfn = OpTypeFunction %void
+ %10 = OpTypeImage %int Cube 1 0 0 1 Unknown
+ %11 = OpTypeSampledImage %10
+%_ptr_UniformConstant_11 = OpTypePointer UniformConstant %11
+
+ %100 = OpVariable %_ptr_UniformConstant_11 UniformConstant
+ %main = OpFunction %void None %voidfn
+ %main_0 = OpLabel
+ %combined = OpLoad %11 %100
+
+ ; Uses of the combined image sampler are preserved.
+ ; CHECK: OpCopyObject %11 %combined
+
+ %7 = OpCopyObject %11 %combined
+ OpReturn
+ OpFunctionEnd
diff --git a/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_RelaxedPrecisionOnLoadCopied_2.spvasm b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_RelaxedPrecisionOnLoadCopied_2.spvasm
new file mode 100644
index 0000000..a53f5dc
--- /dev/null
+++ b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_RelaxedPrecisionOnLoadCopied_2.spvasm
@@ -0,0 +1,77 @@
+ OpCapability Shader
+ OpCapability RuntimeDescriptorArray
+ OpExtension "SPV_EXT_descriptor_indexing"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ OpName %main "main"
+ OpName %main_0 "main_0"
+ OpName %voidfn "voidfn"
+
+ OpName %combined "combined"
+ OpDecorate %100 DescriptorSet 0
+ OpDecorate %100 Binding 0
+ OpDecorate %combined RelaxedPrecision
+
+ ; CHECK: OpName
+ ; CHECK-NOT: OpDecorate %100
+ ; CHECK: OpDecorate %[[image_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[sampler_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[image_var]] Binding 0
+ ; CHECK: OpDecorate %[[sampler_var]] Binding 0
+
+ ; This is what we are checking in this test.
+ ; CHECK: OpDecorate %[[im:\d+]] RelaxedPrecision
+ ; CHECK: OpDecorate %[[s:\d+]] RelaxedPrecision
+
+ ; CHECK: %10 = OpTypeImage %
+ ; CHECK: %[[image_ptr_ty:\w+]] = OpTypePointer UniformConstant %10
+ ; CHECK: %[[sampler_ty:\d+]] = OpTypeSampler
+ ; CHECK: %[[sampler_ptr_ty:\w+]] = OpTypePointer UniformConstant %[[sampler_ty]]
+
+ ; The combined image variable is replaced by an image variable and a sampler variable.
+
+ ; CHECK-NOT: %100 = OpVariable
+ ; CHECK-NOT: OpVariable _ptr_UniformConstant_11
+ ; CHECK-DAG: %[[sampler_var]] = OpVariable %[[sampler_ptr_ty]] UniformConstant
+ ; CHECK-DAG: %[[image_var]] = OpVariable %[[image_ptr_ty]] UniformConstant
+ ; CHECK: = OpFunction
+
+ ; The load of the combined image+sampler is replaced by a two loads, then
+ ; a combination operation. The new loads get the same decorations that the
+ ; original load had.
+ ; CHECK: %[[im]] = OpLoad %10 %[[image_var]]
+ ; CHECK: %[[s]] = OpLoad %[[sampler_ty]] %[[sampler_var]]
+ ; CHECK: %combined = OpSampledImage %11 %[[im]] %[[s]]
+
+ %bool = OpTypeBool ; location marker
+ %float = OpTypeFloat 32
+ %uint = OpTypeInt 32 0
+ %int = OpTypeInt 32 1
+ %uint_0 = OpConstant %uint 0
+ %uint_1 = OpConstant %uint 1
+ %uint_3 = OpConstant %uint 3
+ %float_0 = OpConstant %float 0
+ %v2float = OpTypeVector %float 2
+ %v3float = OpTypeVector %float 3
+ %v4float = OpTypeVector %float 4
+ %13 = OpConstantNull %v2float
+ %14 = OpConstantNull %v3float
+ %15 = OpConstantNull %v4float
+ %void = OpTypeVoid
+ %voidfn = OpTypeFunction %void
+ %10 = OpTypeImage %float 2D 0 1 0 1 Unknown
+ %11 = OpTypeSampledImage %10
+%_ptr_UniformConstant_11 = OpTypePointer UniformConstant %11
+
+ %100 = OpVariable %_ptr_UniformConstant_11 UniformConstant
+ %main = OpFunction %void None %voidfn
+ %main_0 = OpLabel
+ %combined = OpLoad %11 %100
+
+ ; Uses of the combined image sampler are preserved.
+ ; CHECK: OpCopyObject %11 %combined
+
+ %7 = OpCopyObject %11 %combined
+ OpReturn
+ OpFunctionEnd
diff --git a/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_RelaxedPrecisionOnLoadCopied_20.spvasm b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_RelaxedPrecisionOnLoadCopied_20.spvasm
new file mode 100644
index 0000000..88b8c45
--- /dev/null
+++ b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_RelaxedPrecisionOnLoadCopied_20.spvasm
@@ -0,0 +1,77 @@
+ OpCapability Shader
+ OpCapability RuntimeDescriptorArray
+ OpExtension "SPV_EXT_descriptor_indexing"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ OpName %main "main"
+ OpName %main_0 "main_0"
+ OpName %voidfn "voidfn"
+
+ OpName %combined "combined"
+ OpDecorate %100 DescriptorSet 0
+ OpDecorate %100 Binding 0
+ OpDecorate %combined RelaxedPrecision
+
+ ; CHECK: OpName
+ ; CHECK-NOT: OpDecorate %100
+ ; CHECK: OpDecorate %[[image_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[sampler_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[image_var]] Binding 0
+ ; CHECK: OpDecorate %[[sampler_var]] Binding 0
+
+ ; This is what we are checking in this test.
+ ; CHECK: OpDecorate %[[im:\d+]] RelaxedPrecision
+ ; CHECK: OpDecorate %[[s:\d+]] RelaxedPrecision
+
+ ; CHECK: %10 = OpTypeImage %
+ ; CHECK: %[[image_ptr_ty:\w+]] = OpTypePointer UniformConstant %10
+ ; CHECK: %[[sampler_ty:\d+]] = OpTypeSampler
+ ; CHECK: %[[sampler_ptr_ty:\w+]] = OpTypePointer UniformConstant %[[sampler_ty]]
+
+ ; The combined image variable is replaced by an image variable and a sampler variable.
+
+ ; CHECK-NOT: %100 = OpVariable
+ ; CHECK-NOT: OpVariable _ptr_UniformConstant_11
+ ; CHECK-DAG: %[[sampler_var]] = OpVariable %[[sampler_ptr_ty]] UniformConstant
+ ; CHECK-DAG: %[[image_var]] = OpVariable %[[image_ptr_ty]] UniformConstant
+ ; CHECK: = OpFunction
+
+ ; The load of the combined image+sampler is replaced by a two loads, then
+ ; a combination operation. The new loads get the same decorations that the
+ ; original load had.
+ ; CHECK: %[[im]] = OpLoad %10 %[[image_var]]
+ ; CHECK: %[[s]] = OpLoad %[[sampler_ty]] %[[sampler_var]]
+ ; CHECK: %combined = OpSampledImage %11 %[[im]] %[[s]]
+
+ %bool = OpTypeBool ; location marker
+ %float = OpTypeFloat 32
+ %uint = OpTypeInt 32 0
+ %int = OpTypeInt 32 1
+ %uint_0 = OpConstant %uint 0
+ %uint_1 = OpConstant %uint 1
+ %uint_3 = OpConstant %uint 3
+ %float_0 = OpConstant %float 0
+ %v2float = OpTypeVector %float 2
+ %v3float = OpTypeVector %float 3
+ %v4float = OpTypeVector %float 4
+ %13 = OpConstantNull %v2float
+ %14 = OpConstantNull %v3float
+ %15 = OpConstantNull %v4float
+ %void = OpTypeVoid
+ %voidfn = OpTypeFunction %void
+ %10 = OpTypeImage %int Cube 0 1 0 1 Unknown
+ %11 = OpTypeSampledImage %10
+%_ptr_UniformConstant_11 = OpTypePointer UniformConstant %11
+
+ %100 = OpVariable %_ptr_UniformConstant_11 UniformConstant
+ %main = OpFunction %void None %voidfn
+ %main_0 = OpLabel
+ %combined = OpLoad %11 %100
+
+ ; Uses of the combined image sampler are preserved.
+ ; CHECK: OpCopyObject %11 %combined
+
+ %7 = OpCopyObject %11 %combined
+ OpReturn
+ OpFunctionEnd
diff --git a/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_RelaxedPrecisionOnLoadCopied_21.spvasm b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_RelaxedPrecisionOnLoadCopied_21.spvasm
new file mode 100644
index 0000000..22404db
--- /dev/null
+++ b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_RelaxedPrecisionOnLoadCopied_21.spvasm
@@ -0,0 +1,77 @@
+ OpCapability Shader
+ OpCapability RuntimeDescriptorArray
+ OpExtension "SPV_EXT_descriptor_indexing"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ OpName %main "main"
+ OpName %main_0 "main_0"
+ OpName %voidfn "voidfn"
+
+ OpName %combined "combined"
+ OpDecorate %100 DescriptorSet 0
+ OpDecorate %100 Binding 0
+ OpDecorate %combined RelaxedPrecision
+
+ ; CHECK: OpName
+ ; CHECK-NOT: OpDecorate %100
+ ; CHECK: OpDecorate %[[image_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[sampler_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[image_var]] Binding 0
+ ; CHECK: OpDecorate %[[sampler_var]] Binding 0
+
+ ; This is what we are checking in this test.
+ ; CHECK: OpDecorate %[[im:\d+]] RelaxedPrecision
+ ; CHECK: OpDecorate %[[s:\d+]] RelaxedPrecision
+
+ ; CHECK: %10 = OpTypeImage %
+ ; CHECK: %[[image_ptr_ty:\w+]] = OpTypePointer UniformConstant %10
+ ; CHECK: %[[sampler_ty:\d+]] = OpTypeSampler
+ ; CHECK: %[[sampler_ptr_ty:\w+]] = OpTypePointer UniformConstant %[[sampler_ty]]
+
+ ; The combined image variable is replaced by an image variable and a sampler variable.
+
+ ; CHECK-NOT: %100 = OpVariable
+ ; CHECK-NOT: OpVariable _ptr_UniformConstant_11
+ ; CHECK-DAG: %[[sampler_var]] = OpVariable %[[sampler_ptr_ty]] UniformConstant
+ ; CHECK-DAG: %[[image_var]] = OpVariable %[[image_ptr_ty]] UniformConstant
+ ; CHECK: = OpFunction
+
+ ; The load of the combined image+sampler is replaced by a two loads, then
+ ; a combination operation. The new loads get the same decorations that the
+ ; original load had.
+ ; CHECK: %[[im]] = OpLoad %10 %[[image_var]]
+ ; CHECK: %[[s]] = OpLoad %[[sampler_ty]] %[[sampler_var]]
+ ; CHECK: %combined = OpSampledImage %11 %[[im]] %[[s]]
+
+ %bool = OpTypeBool ; location marker
+ %float = OpTypeFloat 32
+ %uint = OpTypeInt 32 0
+ %int = OpTypeInt 32 1
+ %uint_0 = OpConstant %uint 0
+ %uint_1 = OpConstant %uint 1
+ %uint_3 = OpConstant %uint 3
+ %float_0 = OpConstant %float 0
+ %v2float = OpTypeVector %float 2
+ %v3float = OpTypeVector %float 3
+ %v4float = OpTypeVector %float 4
+ %13 = OpConstantNull %v2float
+ %14 = OpConstantNull %v3float
+ %15 = OpConstantNull %v4float
+ %void = OpTypeVoid
+ %voidfn = OpTypeFunction %void
+ %10 = OpTypeImage %int Cube 1 1 0 1 Unknown
+ %11 = OpTypeSampledImage %10
+%_ptr_UniformConstant_11 = OpTypePointer UniformConstant %11
+
+ %100 = OpVariable %_ptr_UniformConstant_11 UniformConstant
+ %main = OpFunction %void None %voidfn
+ %main_0 = OpLabel
+ %combined = OpLoad %11 %100
+
+ ; Uses of the combined image sampler are preserved.
+ ; CHECK: OpCopyObject %11 %combined
+
+ %7 = OpCopyObject %11 %combined
+ OpReturn
+ OpFunctionEnd
diff --git a/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_RelaxedPrecisionOnLoadCopied_22.spvasm b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_RelaxedPrecisionOnLoadCopied_22.spvasm
new file mode 100644
index 0000000..99acfef
--- /dev/null
+++ b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_RelaxedPrecisionOnLoadCopied_22.spvasm
@@ -0,0 +1,77 @@
+ OpCapability Shader
+ OpCapability RuntimeDescriptorArray
+ OpExtension "SPV_EXT_descriptor_indexing"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ OpName %main "main"
+ OpName %main_0 "main_0"
+ OpName %voidfn "voidfn"
+
+ OpName %combined "combined"
+ OpDecorate %100 DescriptorSet 0
+ OpDecorate %100 Binding 0
+ OpDecorate %combined RelaxedPrecision
+
+ ; CHECK: OpName
+ ; CHECK-NOT: OpDecorate %100
+ ; CHECK: OpDecorate %[[image_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[sampler_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[image_var]] Binding 0
+ ; CHECK: OpDecorate %[[sampler_var]] Binding 0
+
+ ; This is what we are checking in this test.
+ ; CHECK: OpDecorate %[[im:\d+]] RelaxedPrecision
+ ; CHECK: OpDecorate %[[s:\d+]] RelaxedPrecision
+
+ ; CHECK: %10 = OpTypeImage %
+ ; CHECK: %[[image_ptr_ty:\w+]] = OpTypePointer UniformConstant %10
+ ; CHECK: %[[sampler_ty:\d+]] = OpTypeSampler
+ ; CHECK: %[[sampler_ptr_ty:\w+]] = OpTypePointer UniformConstant %[[sampler_ty]]
+
+ ; The combined image variable is replaced by an image variable and a sampler variable.
+
+ ; CHECK-NOT: %100 = OpVariable
+ ; CHECK-NOT: OpVariable _ptr_UniformConstant_11
+ ; CHECK-DAG: %[[sampler_var]] = OpVariable %[[sampler_ptr_ty]] UniformConstant
+ ; CHECK-DAG: %[[image_var]] = OpVariable %[[image_ptr_ty]] UniformConstant
+ ; CHECK: = OpFunction
+
+ ; The load of the combined image+sampler is replaced by a two loads, then
+ ; a combination operation. The new loads get the same decorations that the
+ ; original load had.
+ ; CHECK: %[[im]] = OpLoad %10 %[[image_var]]
+ ; CHECK: %[[s]] = OpLoad %[[sampler_ty]] %[[sampler_var]]
+ ; CHECK: %combined = OpSampledImage %11 %[[im]] %[[s]]
+
+ %bool = OpTypeBool ; location marker
+ %float = OpTypeFloat 32
+ %uint = OpTypeInt 32 0
+ %int = OpTypeInt 32 1
+ %uint_0 = OpConstant %uint 0
+ %uint_1 = OpConstant %uint 1
+ %uint_3 = OpConstant %uint 3
+ %float_0 = OpConstant %float 0
+ %v2float = OpTypeVector %float 2
+ %v3float = OpTypeVector %float 3
+ %v4float = OpTypeVector %float 4
+ %13 = OpConstantNull %v2float
+ %14 = OpConstantNull %v3float
+ %15 = OpConstantNull %v4float
+ %void = OpTypeVoid
+ %voidfn = OpTypeFunction %void
+ %10 = OpTypeImage %uint 2D 0 0 0 1 Unknown
+ %11 = OpTypeSampledImage %10
+%_ptr_UniformConstant_11 = OpTypePointer UniformConstant %11
+
+ %100 = OpVariable %_ptr_UniformConstant_11 UniformConstant
+ %main = OpFunction %void None %voidfn
+ %main_0 = OpLabel
+ %combined = OpLoad %11 %100
+
+ ; Uses of the combined image sampler are preserved.
+ ; CHECK: OpCopyObject %11 %combined
+
+ %7 = OpCopyObject %11 %combined
+ OpReturn
+ OpFunctionEnd
diff --git a/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_RelaxedPrecisionOnLoadCopied_23.spvasm b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_RelaxedPrecisionOnLoadCopied_23.spvasm
new file mode 100644
index 0000000..6e23bed
--- /dev/null
+++ b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_RelaxedPrecisionOnLoadCopied_23.spvasm
@@ -0,0 +1,77 @@
+ OpCapability Shader
+ OpCapability RuntimeDescriptorArray
+ OpExtension "SPV_EXT_descriptor_indexing"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ OpName %main "main"
+ OpName %main_0 "main_0"
+ OpName %voidfn "voidfn"
+
+ OpName %combined "combined"
+ OpDecorate %100 DescriptorSet 0
+ OpDecorate %100 Binding 0
+ OpDecorate %combined RelaxedPrecision
+
+ ; CHECK: OpName
+ ; CHECK-NOT: OpDecorate %100
+ ; CHECK: OpDecorate %[[image_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[sampler_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[image_var]] Binding 0
+ ; CHECK: OpDecorate %[[sampler_var]] Binding 0
+
+ ; This is what we are checking in this test.
+ ; CHECK: OpDecorate %[[im:\d+]] RelaxedPrecision
+ ; CHECK: OpDecorate %[[s:\d+]] RelaxedPrecision
+
+ ; CHECK: %10 = OpTypeImage %
+ ; CHECK: %[[image_ptr_ty:\w+]] = OpTypePointer UniformConstant %10
+ ; CHECK: %[[sampler_ty:\d+]] = OpTypeSampler
+ ; CHECK: %[[sampler_ptr_ty:\w+]] = OpTypePointer UniformConstant %[[sampler_ty]]
+
+ ; The combined image variable is replaced by an image variable and a sampler variable.
+
+ ; CHECK-NOT: %100 = OpVariable
+ ; CHECK-NOT: OpVariable _ptr_UniformConstant_11
+ ; CHECK-DAG: %[[sampler_var]] = OpVariable %[[sampler_ptr_ty]] UniformConstant
+ ; CHECK-DAG: %[[image_var]] = OpVariable %[[image_ptr_ty]] UniformConstant
+ ; CHECK: = OpFunction
+
+ ; The load of the combined image+sampler is replaced by a two loads, then
+ ; a combination operation. The new loads get the same decorations that the
+ ; original load had.
+ ; CHECK: %[[im]] = OpLoad %10 %[[image_var]]
+ ; CHECK: %[[s]] = OpLoad %[[sampler_ty]] %[[sampler_var]]
+ ; CHECK: %combined = OpSampledImage %11 %[[im]] %[[s]]
+
+ %bool = OpTypeBool ; location marker
+ %float = OpTypeFloat 32
+ %uint = OpTypeInt 32 0
+ %int = OpTypeInt 32 1
+ %uint_0 = OpConstant %uint 0
+ %uint_1 = OpConstant %uint 1
+ %uint_3 = OpConstant %uint 3
+ %float_0 = OpConstant %float 0
+ %v2float = OpTypeVector %float 2
+ %v3float = OpTypeVector %float 3
+ %v4float = OpTypeVector %float 4
+ %13 = OpConstantNull %v2float
+ %14 = OpConstantNull %v3float
+ %15 = OpConstantNull %v4float
+ %void = OpTypeVoid
+ %voidfn = OpTypeFunction %void
+ %10 = OpTypeImage %uint 2D 1 0 0 1 Unknown
+ %11 = OpTypeSampledImage %10
+%_ptr_UniformConstant_11 = OpTypePointer UniformConstant %11
+
+ %100 = OpVariable %_ptr_UniformConstant_11 UniformConstant
+ %main = OpFunction %void None %voidfn
+ %main_0 = OpLabel
+ %combined = OpLoad %11 %100
+
+ ; Uses of the combined image sampler are preserved.
+ ; CHECK: OpCopyObject %11 %combined
+
+ %7 = OpCopyObject %11 %combined
+ OpReturn
+ OpFunctionEnd
diff --git a/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_RelaxedPrecisionOnLoadCopied_24.spvasm b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_RelaxedPrecisionOnLoadCopied_24.spvasm
new file mode 100644
index 0000000..4e9411e
--- /dev/null
+++ b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_RelaxedPrecisionOnLoadCopied_24.spvasm
@@ -0,0 +1,77 @@
+ OpCapability Shader
+ OpCapability RuntimeDescriptorArray
+ OpExtension "SPV_EXT_descriptor_indexing"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ OpName %main "main"
+ OpName %main_0 "main_0"
+ OpName %voidfn "voidfn"
+
+ OpName %combined "combined"
+ OpDecorate %100 DescriptorSet 0
+ OpDecorate %100 Binding 0
+ OpDecorate %combined RelaxedPrecision
+
+ ; CHECK: OpName
+ ; CHECK-NOT: OpDecorate %100
+ ; CHECK: OpDecorate %[[image_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[sampler_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[image_var]] Binding 0
+ ; CHECK: OpDecorate %[[sampler_var]] Binding 0
+
+ ; This is what we are checking in this test.
+ ; CHECK: OpDecorate %[[im:\d+]] RelaxedPrecision
+ ; CHECK: OpDecorate %[[s:\d+]] RelaxedPrecision
+
+ ; CHECK: %10 = OpTypeImage %
+ ; CHECK: %[[image_ptr_ty:\w+]] = OpTypePointer UniformConstant %10
+ ; CHECK: %[[sampler_ty:\d+]] = OpTypeSampler
+ ; CHECK: %[[sampler_ptr_ty:\w+]] = OpTypePointer UniformConstant %[[sampler_ty]]
+
+ ; The combined image variable is replaced by an image variable and a sampler variable.
+
+ ; CHECK-NOT: %100 = OpVariable
+ ; CHECK-NOT: OpVariable _ptr_UniformConstant_11
+ ; CHECK-DAG: %[[sampler_var]] = OpVariable %[[sampler_ptr_ty]] UniformConstant
+ ; CHECK-DAG: %[[image_var]] = OpVariable %[[image_ptr_ty]] UniformConstant
+ ; CHECK: = OpFunction
+
+ ; The load of the combined image+sampler is replaced by a two loads, then
+ ; a combination operation. The new loads get the same decorations that the
+ ; original load had.
+ ; CHECK: %[[im]] = OpLoad %10 %[[image_var]]
+ ; CHECK: %[[s]] = OpLoad %[[sampler_ty]] %[[sampler_var]]
+ ; CHECK: %combined = OpSampledImage %11 %[[im]] %[[s]]
+
+ %bool = OpTypeBool ; location marker
+ %float = OpTypeFloat 32
+ %uint = OpTypeInt 32 0
+ %int = OpTypeInt 32 1
+ %uint_0 = OpConstant %uint 0
+ %uint_1 = OpConstant %uint 1
+ %uint_3 = OpConstant %uint 3
+ %float_0 = OpConstant %float 0
+ %v2float = OpTypeVector %float 2
+ %v3float = OpTypeVector %float 3
+ %v4float = OpTypeVector %float 4
+ %13 = OpConstantNull %v2float
+ %14 = OpConstantNull %v3float
+ %15 = OpConstantNull %v4float
+ %void = OpTypeVoid
+ %voidfn = OpTypeFunction %void
+ %10 = OpTypeImage %uint 2D 0 1 0 1 Unknown
+ %11 = OpTypeSampledImage %10
+%_ptr_UniformConstant_11 = OpTypePointer UniformConstant %11
+
+ %100 = OpVariable %_ptr_UniformConstant_11 UniformConstant
+ %main = OpFunction %void None %voidfn
+ %main_0 = OpLabel
+ %combined = OpLoad %11 %100
+
+ ; Uses of the combined image sampler are preserved.
+ ; CHECK: OpCopyObject %11 %combined
+
+ %7 = OpCopyObject %11 %combined
+ OpReturn
+ OpFunctionEnd
diff --git a/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_RelaxedPrecisionOnLoadCopied_25.spvasm b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_RelaxedPrecisionOnLoadCopied_25.spvasm
new file mode 100644
index 0000000..81399ae
--- /dev/null
+++ b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_RelaxedPrecisionOnLoadCopied_25.spvasm
@@ -0,0 +1,77 @@
+ OpCapability Shader
+ OpCapability RuntimeDescriptorArray
+ OpExtension "SPV_EXT_descriptor_indexing"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ OpName %main "main"
+ OpName %main_0 "main_0"
+ OpName %voidfn "voidfn"
+
+ OpName %combined "combined"
+ OpDecorate %100 DescriptorSet 0
+ OpDecorate %100 Binding 0
+ OpDecorate %combined RelaxedPrecision
+
+ ; CHECK: OpName
+ ; CHECK-NOT: OpDecorate %100
+ ; CHECK: OpDecorate %[[image_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[sampler_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[image_var]] Binding 0
+ ; CHECK: OpDecorate %[[sampler_var]] Binding 0
+
+ ; This is what we are checking in this test.
+ ; CHECK: OpDecorate %[[im:\d+]] RelaxedPrecision
+ ; CHECK: OpDecorate %[[s:\d+]] RelaxedPrecision
+
+ ; CHECK: %10 = OpTypeImage %
+ ; CHECK: %[[image_ptr_ty:\w+]] = OpTypePointer UniformConstant %10
+ ; CHECK: %[[sampler_ty:\d+]] = OpTypeSampler
+ ; CHECK: %[[sampler_ptr_ty:\w+]] = OpTypePointer UniformConstant %[[sampler_ty]]
+
+ ; The combined image variable is replaced by an image variable and a sampler variable.
+
+ ; CHECK-NOT: %100 = OpVariable
+ ; CHECK-NOT: OpVariable _ptr_UniformConstant_11
+ ; CHECK-DAG: %[[sampler_var]] = OpVariable %[[sampler_ptr_ty]] UniformConstant
+ ; CHECK-DAG: %[[image_var]] = OpVariable %[[image_ptr_ty]] UniformConstant
+ ; CHECK: = OpFunction
+
+ ; The load of the combined image+sampler is replaced by a two loads, then
+ ; a combination operation. The new loads get the same decorations that the
+ ; original load had.
+ ; CHECK: %[[im]] = OpLoad %10 %[[image_var]]
+ ; CHECK: %[[s]] = OpLoad %[[sampler_ty]] %[[sampler_var]]
+ ; CHECK: %combined = OpSampledImage %11 %[[im]] %[[s]]
+
+ %bool = OpTypeBool ; location marker
+ %float = OpTypeFloat 32
+ %uint = OpTypeInt 32 0
+ %int = OpTypeInt 32 1
+ %uint_0 = OpConstant %uint 0
+ %uint_1 = OpConstant %uint 1
+ %uint_3 = OpConstant %uint 3
+ %float_0 = OpConstant %float 0
+ %v2float = OpTypeVector %float 2
+ %v3float = OpTypeVector %float 3
+ %v4float = OpTypeVector %float 4
+ %13 = OpConstantNull %v2float
+ %14 = OpConstantNull %v3float
+ %15 = OpConstantNull %v4float
+ %void = OpTypeVoid
+ %voidfn = OpTypeFunction %void
+ %10 = OpTypeImage %uint 2D 1 1 0 1 Unknown
+ %11 = OpTypeSampledImage %10
+%_ptr_UniformConstant_11 = OpTypePointer UniformConstant %11
+
+ %100 = OpVariable %_ptr_UniformConstant_11 UniformConstant
+ %main = OpFunction %void None %voidfn
+ %main_0 = OpLabel
+ %combined = OpLoad %11 %100
+
+ ; Uses of the combined image sampler are preserved.
+ ; CHECK: OpCopyObject %11 %combined
+
+ %7 = OpCopyObject %11 %combined
+ OpReturn
+ OpFunctionEnd
diff --git a/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_RelaxedPrecisionOnLoadCopied_26.spvasm b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_RelaxedPrecisionOnLoadCopied_26.spvasm
new file mode 100644
index 0000000..25c8168
--- /dev/null
+++ b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_RelaxedPrecisionOnLoadCopied_26.spvasm
@@ -0,0 +1,77 @@
+ OpCapability Shader
+ OpCapability RuntimeDescriptorArray
+ OpExtension "SPV_EXT_descriptor_indexing"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ OpName %main "main"
+ OpName %main_0 "main_0"
+ OpName %voidfn "voidfn"
+
+ OpName %combined "combined"
+ OpDecorate %100 DescriptorSet 0
+ OpDecorate %100 Binding 0
+ OpDecorate %combined RelaxedPrecision
+
+ ; CHECK: OpName
+ ; CHECK-NOT: OpDecorate %100
+ ; CHECK: OpDecorate %[[image_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[sampler_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[image_var]] Binding 0
+ ; CHECK: OpDecorate %[[sampler_var]] Binding 0
+
+ ; This is what we are checking in this test.
+ ; CHECK: OpDecorate %[[im:\d+]] RelaxedPrecision
+ ; CHECK: OpDecorate %[[s:\d+]] RelaxedPrecision
+
+ ; CHECK: %10 = OpTypeImage %
+ ; CHECK: %[[image_ptr_ty:\w+]] = OpTypePointer UniformConstant %10
+ ; CHECK: %[[sampler_ty:\d+]] = OpTypeSampler
+ ; CHECK: %[[sampler_ptr_ty:\w+]] = OpTypePointer UniformConstant %[[sampler_ty]]
+
+ ; The combined image variable is replaced by an image variable and a sampler variable.
+
+ ; CHECK-NOT: %100 = OpVariable
+ ; CHECK-NOT: OpVariable _ptr_UniformConstant_11
+ ; CHECK-DAG: %[[sampler_var]] = OpVariable %[[sampler_ptr_ty]] UniformConstant
+ ; CHECK-DAG: %[[image_var]] = OpVariable %[[image_ptr_ty]] UniformConstant
+ ; CHECK: = OpFunction
+
+ ; The load of the combined image+sampler is replaced by a two loads, then
+ ; a combination operation. The new loads get the same decorations that the
+ ; original load had.
+ ; CHECK: %[[im]] = OpLoad %10 %[[image_var]]
+ ; CHECK: %[[s]] = OpLoad %[[sampler_ty]] %[[sampler_var]]
+ ; CHECK: %combined = OpSampledImage %11 %[[im]] %[[s]]
+
+ %bool = OpTypeBool ; location marker
+ %float = OpTypeFloat 32
+ %uint = OpTypeInt 32 0
+ %int = OpTypeInt 32 1
+ %uint_0 = OpConstant %uint 0
+ %uint_1 = OpConstant %uint 1
+ %uint_3 = OpConstant %uint 3
+ %float_0 = OpConstant %float 0
+ %v2float = OpTypeVector %float 2
+ %v3float = OpTypeVector %float 3
+ %v4float = OpTypeVector %float 4
+ %13 = OpConstantNull %v2float
+ %14 = OpConstantNull %v3float
+ %15 = OpConstantNull %v4float
+ %void = OpTypeVoid
+ %voidfn = OpTypeFunction %void
+ %10 = OpTypeImage %uint 2D 0 0 1 1 Unknown
+ %11 = OpTypeSampledImage %10
+%_ptr_UniformConstant_11 = OpTypePointer UniformConstant %11
+
+ %100 = OpVariable %_ptr_UniformConstant_11 UniformConstant
+ %main = OpFunction %void None %voidfn
+ %main_0 = OpLabel
+ %combined = OpLoad %11 %100
+
+ ; Uses of the combined image sampler are preserved.
+ ; CHECK: OpCopyObject %11 %combined
+
+ %7 = OpCopyObject %11 %combined
+ OpReturn
+ OpFunctionEnd
diff --git a/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_RelaxedPrecisionOnLoadCopied_28.spvasm b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_RelaxedPrecisionOnLoadCopied_28.spvasm
new file mode 100644
index 0000000..6e5efc2
--- /dev/null
+++ b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_RelaxedPrecisionOnLoadCopied_28.spvasm
@@ -0,0 +1,77 @@
+ OpCapability Shader
+ OpCapability RuntimeDescriptorArray
+ OpExtension "SPV_EXT_descriptor_indexing"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ OpName %main "main"
+ OpName %main_0 "main_0"
+ OpName %voidfn "voidfn"
+
+ OpName %combined "combined"
+ OpDecorate %100 DescriptorSet 0
+ OpDecorate %100 Binding 0
+ OpDecorate %combined RelaxedPrecision
+
+ ; CHECK: OpName
+ ; CHECK-NOT: OpDecorate %100
+ ; CHECK: OpDecorate %[[image_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[sampler_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[image_var]] Binding 0
+ ; CHECK: OpDecorate %[[sampler_var]] Binding 0
+
+ ; This is what we are checking in this test.
+ ; CHECK: OpDecorate %[[im:\d+]] RelaxedPrecision
+ ; CHECK: OpDecorate %[[s:\d+]] RelaxedPrecision
+
+ ; CHECK: %10 = OpTypeImage %
+ ; CHECK: %[[image_ptr_ty:\w+]] = OpTypePointer UniformConstant %10
+ ; CHECK: %[[sampler_ty:\d+]] = OpTypeSampler
+ ; CHECK: %[[sampler_ptr_ty:\w+]] = OpTypePointer UniformConstant %[[sampler_ty]]
+
+ ; The combined image variable is replaced by an image variable and a sampler variable.
+
+ ; CHECK-NOT: %100 = OpVariable
+ ; CHECK-NOT: OpVariable _ptr_UniformConstant_11
+ ; CHECK-DAG: %[[sampler_var]] = OpVariable %[[sampler_ptr_ty]] UniformConstant
+ ; CHECK-DAG: %[[image_var]] = OpVariable %[[image_ptr_ty]] UniformConstant
+ ; CHECK: = OpFunction
+
+ ; The load of the combined image+sampler is replaced by a two loads, then
+ ; a combination operation. The new loads get the same decorations that the
+ ; original load had.
+ ; CHECK: %[[im]] = OpLoad %10 %[[image_var]]
+ ; CHECK: %[[s]] = OpLoad %[[sampler_ty]] %[[sampler_var]]
+ ; CHECK: %combined = OpSampledImage %11 %[[im]] %[[s]]
+
+ %bool = OpTypeBool ; location marker
+ %float = OpTypeFloat 32
+ %uint = OpTypeInt 32 0
+ %int = OpTypeInt 32 1
+ %uint_0 = OpConstant %uint 0
+ %uint_1 = OpConstant %uint 1
+ %uint_3 = OpConstant %uint 3
+ %float_0 = OpConstant %float 0
+ %v2float = OpTypeVector %float 2
+ %v3float = OpTypeVector %float 3
+ %v4float = OpTypeVector %float 4
+ %13 = OpConstantNull %v2float
+ %14 = OpConstantNull %v3float
+ %15 = OpConstantNull %v4float
+ %void = OpTypeVoid
+ %voidfn = OpTypeFunction %void
+ %10 = OpTypeImage %uint 3D 0 0 0 1 Unknown
+ %11 = OpTypeSampledImage %10
+%_ptr_UniformConstant_11 = OpTypePointer UniformConstant %11
+
+ %100 = OpVariable %_ptr_UniformConstant_11 UniformConstant
+ %main = OpFunction %void None %voidfn
+ %main_0 = OpLabel
+ %combined = OpLoad %11 %100
+
+ ; Uses of the combined image sampler are preserved.
+ ; CHECK: OpCopyObject %11 %combined
+
+ %7 = OpCopyObject %11 %combined
+ OpReturn
+ OpFunctionEnd
diff --git a/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_RelaxedPrecisionOnLoadCopied_29.spvasm b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_RelaxedPrecisionOnLoadCopied_29.spvasm
new file mode 100644
index 0000000..bb67189
--- /dev/null
+++ b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_RelaxedPrecisionOnLoadCopied_29.spvasm
@@ -0,0 +1,77 @@
+ OpCapability Shader
+ OpCapability RuntimeDescriptorArray
+ OpExtension "SPV_EXT_descriptor_indexing"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ OpName %main "main"
+ OpName %main_0 "main_0"
+ OpName %voidfn "voidfn"
+
+ OpName %combined "combined"
+ OpDecorate %100 DescriptorSet 0
+ OpDecorate %100 Binding 0
+ OpDecorate %combined RelaxedPrecision
+
+ ; CHECK: OpName
+ ; CHECK-NOT: OpDecorate %100
+ ; CHECK: OpDecorate %[[image_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[sampler_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[image_var]] Binding 0
+ ; CHECK: OpDecorate %[[sampler_var]] Binding 0
+
+ ; This is what we are checking in this test.
+ ; CHECK: OpDecorate %[[im:\d+]] RelaxedPrecision
+ ; CHECK: OpDecorate %[[s:\d+]] RelaxedPrecision
+
+ ; CHECK: %10 = OpTypeImage %
+ ; CHECK: %[[image_ptr_ty:\w+]] = OpTypePointer UniformConstant %10
+ ; CHECK: %[[sampler_ty:\d+]] = OpTypeSampler
+ ; CHECK: %[[sampler_ptr_ty:\w+]] = OpTypePointer UniformConstant %[[sampler_ty]]
+
+ ; The combined image variable is replaced by an image variable and a sampler variable.
+
+ ; CHECK-NOT: %100 = OpVariable
+ ; CHECK-NOT: OpVariable _ptr_UniformConstant_11
+ ; CHECK-DAG: %[[sampler_var]] = OpVariable %[[sampler_ptr_ty]] UniformConstant
+ ; CHECK-DAG: %[[image_var]] = OpVariable %[[image_ptr_ty]] UniformConstant
+ ; CHECK: = OpFunction
+
+ ; The load of the combined image+sampler is replaced by a two loads, then
+ ; a combination operation. The new loads get the same decorations that the
+ ; original load had.
+ ; CHECK: %[[im]] = OpLoad %10 %[[image_var]]
+ ; CHECK: %[[s]] = OpLoad %[[sampler_ty]] %[[sampler_var]]
+ ; CHECK: %combined = OpSampledImage %11 %[[im]] %[[s]]
+
+ %bool = OpTypeBool ; location marker
+ %float = OpTypeFloat 32
+ %uint = OpTypeInt 32 0
+ %int = OpTypeInt 32 1
+ %uint_0 = OpConstant %uint 0
+ %uint_1 = OpConstant %uint 1
+ %uint_3 = OpConstant %uint 3
+ %float_0 = OpConstant %float 0
+ %v2float = OpTypeVector %float 2
+ %v3float = OpTypeVector %float 3
+ %v4float = OpTypeVector %float 4
+ %13 = OpConstantNull %v2float
+ %14 = OpConstantNull %v3float
+ %15 = OpConstantNull %v4float
+ %void = OpTypeVoid
+ %voidfn = OpTypeFunction %void
+ %10 = OpTypeImage %uint Cube 0 0 0 1 Unknown
+ %11 = OpTypeSampledImage %10
+%_ptr_UniformConstant_11 = OpTypePointer UniformConstant %11
+
+ %100 = OpVariable %_ptr_UniformConstant_11 UniformConstant
+ %main = OpFunction %void None %voidfn
+ %main_0 = OpLabel
+ %combined = OpLoad %11 %100
+
+ ; Uses of the combined image sampler are preserved.
+ ; CHECK: OpCopyObject %11 %combined
+
+ %7 = OpCopyObject %11 %combined
+ OpReturn
+ OpFunctionEnd
diff --git a/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_RelaxedPrecisionOnLoadCopied_3.spvasm b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_RelaxedPrecisionOnLoadCopied_3.spvasm
new file mode 100644
index 0000000..b23904c
--- /dev/null
+++ b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_RelaxedPrecisionOnLoadCopied_3.spvasm
@@ -0,0 +1,77 @@
+ OpCapability Shader
+ OpCapability RuntimeDescriptorArray
+ OpExtension "SPV_EXT_descriptor_indexing"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ OpName %main "main"
+ OpName %main_0 "main_0"
+ OpName %voidfn "voidfn"
+
+ OpName %combined "combined"
+ OpDecorate %100 DescriptorSet 0
+ OpDecorate %100 Binding 0
+ OpDecorate %combined RelaxedPrecision
+
+ ; CHECK: OpName
+ ; CHECK-NOT: OpDecorate %100
+ ; CHECK: OpDecorate %[[image_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[sampler_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[image_var]] Binding 0
+ ; CHECK: OpDecorate %[[sampler_var]] Binding 0
+
+ ; This is what we are checking in this test.
+ ; CHECK: OpDecorate %[[im:\d+]] RelaxedPrecision
+ ; CHECK: OpDecorate %[[s:\d+]] RelaxedPrecision
+
+ ; CHECK: %10 = OpTypeImage %
+ ; CHECK: %[[image_ptr_ty:\w+]] = OpTypePointer UniformConstant %10
+ ; CHECK: %[[sampler_ty:\d+]] = OpTypeSampler
+ ; CHECK: %[[sampler_ptr_ty:\w+]] = OpTypePointer UniformConstant %[[sampler_ty]]
+
+ ; The combined image variable is replaced by an image variable and a sampler variable.
+
+ ; CHECK-NOT: %100 = OpVariable
+ ; CHECK-NOT: OpVariable _ptr_UniformConstant_11
+ ; CHECK-DAG: %[[sampler_var]] = OpVariable %[[sampler_ptr_ty]] UniformConstant
+ ; CHECK-DAG: %[[image_var]] = OpVariable %[[image_ptr_ty]] UniformConstant
+ ; CHECK: = OpFunction
+
+ ; The load of the combined image+sampler is replaced by a two loads, then
+ ; a combination operation. The new loads get the same decorations that the
+ ; original load had.
+ ; CHECK: %[[im]] = OpLoad %10 %[[image_var]]
+ ; CHECK: %[[s]] = OpLoad %[[sampler_ty]] %[[sampler_var]]
+ ; CHECK: %combined = OpSampledImage %11 %[[im]] %[[s]]
+
+ %bool = OpTypeBool ; location marker
+ %float = OpTypeFloat 32
+ %uint = OpTypeInt 32 0
+ %int = OpTypeInt 32 1
+ %uint_0 = OpConstant %uint 0
+ %uint_1 = OpConstant %uint 1
+ %uint_3 = OpConstant %uint 3
+ %float_0 = OpConstant %float 0
+ %v2float = OpTypeVector %float 2
+ %v3float = OpTypeVector %float 3
+ %v4float = OpTypeVector %float 4
+ %13 = OpConstantNull %v2float
+ %14 = OpConstantNull %v3float
+ %15 = OpConstantNull %v4float
+ %void = OpTypeVoid
+ %voidfn = OpTypeFunction %void
+ %10 = OpTypeImage %float 2D 1 1 0 1 Unknown
+ %11 = OpTypeSampledImage %10
+%_ptr_UniformConstant_11 = OpTypePointer UniformConstant %11
+
+ %100 = OpVariable %_ptr_UniformConstant_11 UniformConstant
+ %main = OpFunction %void None %voidfn
+ %main_0 = OpLabel
+ %combined = OpLoad %11 %100
+
+ ; Uses of the combined image sampler are preserved.
+ ; CHECK: OpCopyObject %11 %combined
+
+ %7 = OpCopyObject %11 %combined
+ OpReturn
+ OpFunctionEnd
diff --git a/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_RelaxedPrecisionOnLoadCopied_30.spvasm b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_RelaxedPrecisionOnLoadCopied_30.spvasm
new file mode 100644
index 0000000..a054203
--- /dev/null
+++ b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_RelaxedPrecisionOnLoadCopied_30.spvasm
@@ -0,0 +1,77 @@
+ OpCapability Shader
+ OpCapability RuntimeDescriptorArray
+ OpExtension "SPV_EXT_descriptor_indexing"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ OpName %main "main"
+ OpName %main_0 "main_0"
+ OpName %voidfn "voidfn"
+
+ OpName %combined "combined"
+ OpDecorate %100 DescriptorSet 0
+ OpDecorate %100 Binding 0
+ OpDecorate %combined RelaxedPrecision
+
+ ; CHECK: OpName
+ ; CHECK-NOT: OpDecorate %100
+ ; CHECK: OpDecorate %[[image_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[sampler_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[image_var]] Binding 0
+ ; CHECK: OpDecorate %[[sampler_var]] Binding 0
+
+ ; This is what we are checking in this test.
+ ; CHECK: OpDecorate %[[im:\d+]] RelaxedPrecision
+ ; CHECK: OpDecorate %[[s:\d+]] RelaxedPrecision
+
+ ; CHECK: %10 = OpTypeImage %
+ ; CHECK: %[[image_ptr_ty:\w+]] = OpTypePointer UniformConstant %10
+ ; CHECK: %[[sampler_ty:\d+]] = OpTypeSampler
+ ; CHECK: %[[sampler_ptr_ty:\w+]] = OpTypePointer UniformConstant %[[sampler_ty]]
+
+ ; The combined image variable is replaced by an image variable and a sampler variable.
+
+ ; CHECK-NOT: %100 = OpVariable
+ ; CHECK-NOT: OpVariable _ptr_UniformConstant_11
+ ; CHECK-DAG: %[[sampler_var]] = OpVariable %[[sampler_ptr_ty]] UniformConstant
+ ; CHECK-DAG: %[[image_var]] = OpVariable %[[image_ptr_ty]] UniformConstant
+ ; CHECK: = OpFunction
+
+ ; The load of the combined image+sampler is replaced by a two loads, then
+ ; a combination operation. The new loads get the same decorations that the
+ ; original load had.
+ ; CHECK: %[[im]] = OpLoad %10 %[[image_var]]
+ ; CHECK: %[[s]] = OpLoad %[[sampler_ty]] %[[sampler_var]]
+ ; CHECK: %combined = OpSampledImage %11 %[[im]] %[[s]]
+
+ %bool = OpTypeBool ; location marker
+ %float = OpTypeFloat 32
+ %uint = OpTypeInt 32 0
+ %int = OpTypeInt 32 1
+ %uint_0 = OpConstant %uint 0
+ %uint_1 = OpConstant %uint 1
+ %uint_3 = OpConstant %uint 3
+ %float_0 = OpConstant %float 0
+ %v2float = OpTypeVector %float 2
+ %v3float = OpTypeVector %float 3
+ %v4float = OpTypeVector %float 4
+ %13 = OpConstantNull %v2float
+ %14 = OpConstantNull %v3float
+ %15 = OpConstantNull %v4float
+ %void = OpTypeVoid
+ %voidfn = OpTypeFunction %void
+ %10 = OpTypeImage %uint Cube 1 0 0 1 Unknown
+ %11 = OpTypeSampledImage %10
+%_ptr_UniformConstant_11 = OpTypePointer UniformConstant %11
+
+ %100 = OpVariable %_ptr_UniformConstant_11 UniformConstant
+ %main = OpFunction %void None %voidfn
+ %main_0 = OpLabel
+ %combined = OpLoad %11 %100
+
+ ; Uses of the combined image sampler are preserved.
+ ; CHECK: OpCopyObject %11 %combined
+
+ %7 = OpCopyObject %11 %combined
+ OpReturn
+ OpFunctionEnd
diff --git a/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_RelaxedPrecisionOnLoadCopied_31.spvasm b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_RelaxedPrecisionOnLoadCopied_31.spvasm
new file mode 100644
index 0000000..f5a53a5
--- /dev/null
+++ b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_RelaxedPrecisionOnLoadCopied_31.spvasm
@@ -0,0 +1,77 @@
+ OpCapability Shader
+ OpCapability RuntimeDescriptorArray
+ OpExtension "SPV_EXT_descriptor_indexing"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ OpName %main "main"
+ OpName %main_0 "main_0"
+ OpName %voidfn "voidfn"
+
+ OpName %combined "combined"
+ OpDecorate %100 DescriptorSet 0
+ OpDecorate %100 Binding 0
+ OpDecorate %combined RelaxedPrecision
+
+ ; CHECK: OpName
+ ; CHECK-NOT: OpDecorate %100
+ ; CHECK: OpDecorate %[[image_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[sampler_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[image_var]] Binding 0
+ ; CHECK: OpDecorate %[[sampler_var]] Binding 0
+
+ ; This is what we are checking in this test.
+ ; CHECK: OpDecorate %[[im:\d+]] RelaxedPrecision
+ ; CHECK: OpDecorate %[[s:\d+]] RelaxedPrecision
+
+ ; CHECK: %10 = OpTypeImage %
+ ; CHECK: %[[image_ptr_ty:\w+]] = OpTypePointer UniformConstant %10
+ ; CHECK: %[[sampler_ty:\d+]] = OpTypeSampler
+ ; CHECK: %[[sampler_ptr_ty:\w+]] = OpTypePointer UniformConstant %[[sampler_ty]]
+
+ ; The combined image variable is replaced by an image variable and a sampler variable.
+
+ ; CHECK-NOT: %100 = OpVariable
+ ; CHECK-NOT: OpVariable _ptr_UniformConstant_11
+ ; CHECK-DAG: %[[sampler_var]] = OpVariable %[[sampler_ptr_ty]] UniformConstant
+ ; CHECK-DAG: %[[image_var]] = OpVariable %[[image_ptr_ty]] UniformConstant
+ ; CHECK: = OpFunction
+
+ ; The load of the combined image+sampler is replaced by a two loads, then
+ ; a combination operation. The new loads get the same decorations that the
+ ; original load had.
+ ; CHECK: %[[im]] = OpLoad %10 %[[image_var]]
+ ; CHECK: %[[s]] = OpLoad %[[sampler_ty]] %[[sampler_var]]
+ ; CHECK: %combined = OpSampledImage %11 %[[im]] %[[s]]
+
+ %bool = OpTypeBool ; location marker
+ %float = OpTypeFloat 32
+ %uint = OpTypeInt 32 0
+ %int = OpTypeInt 32 1
+ %uint_0 = OpConstant %uint 0
+ %uint_1 = OpConstant %uint 1
+ %uint_3 = OpConstant %uint 3
+ %float_0 = OpConstant %float 0
+ %v2float = OpTypeVector %float 2
+ %v3float = OpTypeVector %float 3
+ %v4float = OpTypeVector %float 4
+ %13 = OpConstantNull %v2float
+ %14 = OpConstantNull %v3float
+ %15 = OpConstantNull %v4float
+ %void = OpTypeVoid
+ %voidfn = OpTypeFunction %void
+ %10 = OpTypeImage %uint Cube 0 1 0 1 Unknown
+ %11 = OpTypeSampledImage %10
+%_ptr_UniformConstant_11 = OpTypePointer UniformConstant %11
+
+ %100 = OpVariable %_ptr_UniformConstant_11 UniformConstant
+ %main = OpFunction %void None %voidfn
+ %main_0 = OpLabel
+ %combined = OpLoad %11 %100
+
+ ; Uses of the combined image sampler are preserved.
+ ; CHECK: OpCopyObject %11 %combined
+
+ %7 = OpCopyObject %11 %combined
+ OpReturn
+ OpFunctionEnd
diff --git a/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_RelaxedPrecisionOnLoadCopied_32.spvasm b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_RelaxedPrecisionOnLoadCopied_32.spvasm
new file mode 100644
index 0000000..f2d4a8e
--- /dev/null
+++ b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_RelaxedPrecisionOnLoadCopied_32.spvasm
@@ -0,0 +1,77 @@
+ OpCapability Shader
+ OpCapability RuntimeDescriptorArray
+ OpExtension "SPV_EXT_descriptor_indexing"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ OpName %main "main"
+ OpName %main_0 "main_0"
+ OpName %voidfn "voidfn"
+
+ OpName %combined "combined"
+ OpDecorate %100 DescriptorSet 0
+ OpDecorate %100 Binding 0
+ OpDecorate %combined RelaxedPrecision
+
+ ; CHECK: OpName
+ ; CHECK-NOT: OpDecorate %100
+ ; CHECK: OpDecorate %[[image_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[sampler_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[image_var]] Binding 0
+ ; CHECK: OpDecorate %[[sampler_var]] Binding 0
+
+ ; This is what we are checking in this test.
+ ; CHECK: OpDecorate %[[im:\d+]] RelaxedPrecision
+ ; CHECK: OpDecorate %[[s:\d+]] RelaxedPrecision
+
+ ; CHECK: %10 = OpTypeImage %
+ ; CHECK: %[[image_ptr_ty:\w+]] = OpTypePointer UniformConstant %10
+ ; CHECK: %[[sampler_ty:\d+]] = OpTypeSampler
+ ; CHECK: %[[sampler_ptr_ty:\w+]] = OpTypePointer UniformConstant %[[sampler_ty]]
+
+ ; The combined image variable is replaced by an image variable and a sampler variable.
+
+ ; CHECK-NOT: %100 = OpVariable
+ ; CHECK-NOT: OpVariable _ptr_UniformConstant_11
+ ; CHECK-DAG: %[[sampler_var]] = OpVariable %[[sampler_ptr_ty]] UniformConstant
+ ; CHECK-DAG: %[[image_var]] = OpVariable %[[image_ptr_ty]] UniformConstant
+ ; CHECK: = OpFunction
+
+ ; The load of the combined image+sampler is replaced by a two loads, then
+ ; a combination operation. The new loads get the same decorations that the
+ ; original load had.
+ ; CHECK: %[[im]] = OpLoad %10 %[[image_var]]
+ ; CHECK: %[[s]] = OpLoad %[[sampler_ty]] %[[sampler_var]]
+ ; CHECK: %combined = OpSampledImage %11 %[[im]] %[[s]]
+
+ %bool = OpTypeBool ; location marker
+ %float = OpTypeFloat 32
+ %uint = OpTypeInt 32 0
+ %int = OpTypeInt 32 1
+ %uint_0 = OpConstant %uint 0
+ %uint_1 = OpConstant %uint 1
+ %uint_3 = OpConstant %uint 3
+ %float_0 = OpConstant %float 0
+ %v2float = OpTypeVector %float 2
+ %v3float = OpTypeVector %float 3
+ %v4float = OpTypeVector %float 4
+ %13 = OpConstantNull %v2float
+ %14 = OpConstantNull %v3float
+ %15 = OpConstantNull %v4float
+ %void = OpTypeVoid
+ %voidfn = OpTypeFunction %void
+ %10 = OpTypeImage %uint Cube 1 1 0 1 Unknown
+ %11 = OpTypeSampledImage %10
+%_ptr_UniformConstant_11 = OpTypePointer UniformConstant %11
+
+ %100 = OpVariable %_ptr_UniformConstant_11 UniformConstant
+ %main = OpFunction %void None %voidfn
+ %main_0 = OpLabel
+ %combined = OpLoad %11 %100
+
+ ; Uses of the combined image sampler are preserved.
+ ; CHECK: OpCopyObject %11 %combined
+
+ %7 = OpCopyObject %11 %combined
+ OpReturn
+ OpFunctionEnd
diff --git a/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_RelaxedPrecisionOnLoadCopied_4.spvasm b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_RelaxedPrecisionOnLoadCopied_4.spvasm
new file mode 100644
index 0000000..f5ec33d
--- /dev/null
+++ b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_RelaxedPrecisionOnLoadCopied_4.spvasm
@@ -0,0 +1,77 @@
+ OpCapability Shader
+ OpCapability RuntimeDescriptorArray
+ OpExtension "SPV_EXT_descriptor_indexing"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ OpName %main "main"
+ OpName %main_0 "main_0"
+ OpName %voidfn "voidfn"
+
+ OpName %combined "combined"
+ OpDecorate %100 DescriptorSet 0
+ OpDecorate %100 Binding 0
+ OpDecorate %combined RelaxedPrecision
+
+ ; CHECK: OpName
+ ; CHECK-NOT: OpDecorate %100
+ ; CHECK: OpDecorate %[[image_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[sampler_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[image_var]] Binding 0
+ ; CHECK: OpDecorate %[[sampler_var]] Binding 0
+
+ ; This is what we are checking in this test.
+ ; CHECK: OpDecorate %[[im:\d+]] RelaxedPrecision
+ ; CHECK: OpDecorate %[[s:\d+]] RelaxedPrecision
+
+ ; CHECK: %10 = OpTypeImage %
+ ; CHECK: %[[image_ptr_ty:\w+]] = OpTypePointer UniformConstant %10
+ ; CHECK: %[[sampler_ty:\d+]] = OpTypeSampler
+ ; CHECK: %[[sampler_ptr_ty:\w+]] = OpTypePointer UniformConstant %[[sampler_ty]]
+
+ ; The combined image variable is replaced by an image variable and a sampler variable.
+
+ ; CHECK-NOT: %100 = OpVariable
+ ; CHECK-NOT: OpVariable _ptr_UniformConstant_11
+ ; CHECK-DAG: %[[sampler_var]] = OpVariable %[[sampler_ptr_ty]] UniformConstant
+ ; CHECK-DAG: %[[image_var]] = OpVariable %[[image_ptr_ty]] UniformConstant
+ ; CHECK: = OpFunction
+
+ ; The load of the combined image+sampler is replaced by a two loads, then
+ ; a combination operation. The new loads get the same decorations that the
+ ; original load had.
+ ; CHECK: %[[im]] = OpLoad %10 %[[image_var]]
+ ; CHECK: %[[s]] = OpLoad %[[sampler_ty]] %[[sampler_var]]
+ ; CHECK: %combined = OpSampledImage %11 %[[im]] %[[s]]
+
+ %bool = OpTypeBool ; location marker
+ %float = OpTypeFloat 32
+ %uint = OpTypeInt 32 0
+ %int = OpTypeInt 32 1
+ %uint_0 = OpConstant %uint 0
+ %uint_1 = OpConstant %uint 1
+ %uint_3 = OpConstant %uint 3
+ %float_0 = OpConstant %float 0
+ %v2float = OpTypeVector %float 2
+ %v3float = OpTypeVector %float 3
+ %v4float = OpTypeVector %float 4
+ %13 = OpConstantNull %v2float
+ %14 = OpConstantNull %v3float
+ %15 = OpConstantNull %v4float
+ %void = OpTypeVoid
+ %voidfn = OpTypeFunction %void
+ %10 = OpTypeImage %float 2D 0 0 1 1 Unknown
+ %11 = OpTypeSampledImage %10
+%_ptr_UniformConstant_11 = OpTypePointer UniformConstant %11
+
+ %100 = OpVariable %_ptr_UniformConstant_11 UniformConstant
+ %main = OpFunction %void None %voidfn
+ %main_0 = OpLabel
+ %combined = OpLoad %11 %100
+
+ ; Uses of the combined image sampler are preserved.
+ ; CHECK: OpCopyObject %11 %combined
+
+ %7 = OpCopyObject %11 %combined
+ OpReturn
+ OpFunctionEnd
diff --git a/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_RelaxedPrecisionOnLoadCopied_6.spvasm b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_RelaxedPrecisionOnLoadCopied_6.spvasm
new file mode 100644
index 0000000..4a355ed
--- /dev/null
+++ b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_RelaxedPrecisionOnLoadCopied_6.spvasm
@@ -0,0 +1,77 @@
+ OpCapability Shader
+ OpCapability RuntimeDescriptorArray
+ OpExtension "SPV_EXT_descriptor_indexing"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ OpName %main "main"
+ OpName %main_0 "main_0"
+ OpName %voidfn "voidfn"
+
+ OpName %combined "combined"
+ OpDecorate %100 DescriptorSet 0
+ OpDecorate %100 Binding 0
+ OpDecorate %combined RelaxedPrecision
+
+ ; CHECK: OpName
+ ; CHECK-NOT: OpDecorate %100
+ ; CHECK: OpDecorate %[[image_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[sampler_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[image_var]] Binding 0
+ ; CHECK: OpDecorate %[[sampler_var]] Binding 0
+
+ ; This is what we are checking in this test.
+ ; CHECK: OpDecorate %[[im:\d+]] RelaxedPrecision
+ ; CHECK: OpDecorate %[[s:\d+]] RelaxedPrecision
+
+ ; CHECK: %10 = OpTypeImage %
+ ; CHECK: %[[image_ptr_ty:\w+]] = OpTypePointer UniformConstant %10
+ ; CHECK: %[[sampler_ty:\d+]] = OpTypeSampler
+ ; CHECK: %[[sampler_ptr_ty:\w+]] = OpTypePointer UniformConstant %[[sampler_ty]]
+
+ ; The combined image variable is replaced by an image variable and a sampler variable.
+
+ ; CHECK-NOT: %100 = OpVariable
+ ; CHECK-NOT: OpVariable _ptr_UniformConstant_11
+ ; CHECK-DAG: %[[sampler_var]] = OpVariable %[[sampler_ptr_ty]] UniformConstant
+ ; CHECK-DAG: %[[image_var]] = OpVariable %[[image_ptr_ty]] UniformConstant
+ ; CHECK: = OpFunction
+
+ ; The load of the combined image+sampler is replaced by a two loads, then
+ ; a combination operation. The new loads get the same decorations that the
+ ; original load had.
+ ; CHECK: %[[im]] = OpLoad %10 %[[image_var]]
+ ; CHECK: %[[s]] = OpLoad %[[sampler_ty]] %[[sampler_var]]
+ ; CHECK: %combined = OpSampledImage %11 %[[im]] %[[s]]
+
+ %bool = OpTypeBool ; location marker
+ %float = OpTypeFloat 32
+ %uint = OpTypeInt 32 0
+ %int = OpTypeInt 32 1
+ %uint_0 = OpConstant %uint 0
+ %uint_1 = OpConstant %uint 1
+ %uint_3 = OpConstant %uint 3
+ %float_0 = OpConstant %float 0
+ %v2float = OpTypeVector %float 2
+ %v3float = OpTypeVector %float 3
+ %v4float = OpTypeVector %float 4
+ %13 = OpConstantNull %v2float
+ %14 = OpConstantNull %v3float
+ %15 = OpConstantNull %v4float
+ %void = OpTypeVoid
+ %voidfn = OpTypeFunction %void
+ %10 = OpTypeImage %float 3D 0 0 0 1 Unknown
+ %11 = OpTypeSampledImage %10
+%_ptr_UniformConstant_11 = OpTypePointer UniformConstant %11
+
+ %100 = OpVariable %_ptr_UniformConstant_11 UniformConstant
+ %main = OpFunction %void None %voidfn
+ %main_0 = OpLabel
+ %combined = OpLoad %11 %100
+
+ ; Uses of the combined image sampler are preserved.
+ ; CHECK: OpCopyObject %11 %combined
+
+ %7 = OpCopyObject %11 %combined
+ OpReturn
+ OpFunctionEnd
diff --git a/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_RelaxedPrecisionOnLoadCopied_7.spvasm b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_RelaxedPrecisionOnLoadCopied_7.spvasm
new file mode 100644
index 0000000..97c1346
--- /dev/null
+++ b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_RelaxedPrecisionOnLoadCopied_7.spvasm
@@ -0,0 +1,77 @@
+ OpCapability Shader
+ OpCapability RuntimeDescriptorArray
+ OpExtension "SPV_EXT_descriptor_indexing"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ OpName %main "main"
+ OpName %main_0 "main_0"
+ OpName %voidfn "voidfn"
+
+ OpName %combined "combined"
+ OpDecorate %100 DescriptorSet 0
+ OpDecorate %100 Binding 0
+ OpDecorate %combined RelaxedPrecision
+
+ ; CHECK: OpName
+ ; CHECK-NOT: OpDecorate %100
+ ; CHECK: OpDecorate %[[image_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[sampler_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[image_var]] Binding 0
+ ; CHECK: OpDecorate %[[sampler_var]] Binding 0
+
+ ; This is what we are checking in this test.
+ ; CHECK: OpDecorate %[[im:\d+]] RelaxedPrecision
+ ; CHECK: OpDecorate %[[s:\d+]] RelaxedPrecision
+
+ ; CHECK: %10 = OpTypeImage %
+ ; CHECK: %[[image_ptr_ty:\w+]] = OpTypePointer UniformConstant %10
+ ; CHECK: %[[sampler_ty:\d+]] = OpTypeSampler
+ ; CHECK: %[[sampler_ptr_ty:\w+]] = OpTypePointer UniformConstant %[[sampler_ty]]
+
+ ; The combined image variable is replaced by an image variable and a sampler variable.
+
+ ; CHECK-NOT: %100 = OpVariable
+ ; CHECK-NOT: OpVariable _ptr_UniformConstant_11
+ ; CHECK-DAG: %[[sampler_var]] = OpVariable %[[sampler_ptr_ty]] UniformConstant
+ ; CHECK-DAG: %[[image_var]] = OpVariable %[[image_ptr_ty]] UniformConstant
+ ; CHECK: = OpFunction
+
+ ; The load of the combined image+sampler is replaced by a two loads, then
+ ; a combination operation. The new loads get the same decorations that the
+ ; original load had.
+ ; CHECK: %[[im]] = OpLoad %10 %[[image_var]]
+ ; CHECK: %[[s]] = OpLoad %[[sampler_ty]] %[[sampler_var]]
+ ; CHECK: %combined = OpSampledImage %11 %[[im]] %[[s]]
+
+ %bool = OpTypeBool ; location marker
+ %float = OpTypeFloat 32
+ %uint = OpTypeInt 32 0
+ %int = OpTypeInt 32 1
+ %uint_0 = OpConstant %uint 0
+ %uint_1 = OpConstant %uint 1
+ %uint_3 = OpConstant %uint 3
+ %float_0 = OpConstant %float 0
+ %v2float = OpTypeVector %float 2
+ %v3float = OpTypeVector %float 3
+ %v4float = OpTypeVector %float 4
+ %13 = OpConstantNull %v2float
+ %14 = OpConstantNull %v3float
+ %15 = OpConstantNull %v4float
+ %void = OpTypeVoid
+ %voidfn = OpTypeFunction %void
+ %10 = OpTypeImage %float Cube 0 0 0 1 Unknown
+ %11 = OpTypeSampledImage %10
+%_ptr_UniformConstant_11 = OpTypePointer UniformConstant %11
+
+ %100 = OpVariable %_ptr_UniformConstant_11 UniformConstant
+ %main = OpFunction %void None %voidfn
+ %main_0 = OpLabel
+ %combined = OpLoad %11 %100
+
+ ; Uses of the combined image sampler are preserved.
+ ; CHECK: OpCopyObject %11 %combined
+
+ %7 = OpCopyObject %11 %combined
+ OpReturn
+ OpFunctionEnd
diff --git a/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_RelaxedPrecisionOnLoadCopied_8.spvasm b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_RelaxedPrecisionOnLoadCopied_8.spvasm
new file mode 100644
index 0000000..999dce1
--- /dev/null
+++ b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_RelaxedPrecisionOnLoadCopied_8.spvasm
@@ -0,0 +1,77 @@
+ OpCapability Shader
+ OpCapability RuntimeDescriptorArray
+ OpExtension "SPV_EXT_descriptor_indexing"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ OpName %main "main"
+ OpName %main_0 "main_0"
+ OpName %voidfn "voidfn"
+
+ OpName %combined "combined"
+ OpDecorate %100 DescriptorSet 0
+ OpDecorate %100 Binding 0
+ OpDecorate %combined RelaxedPrecision
+
+ ; CHECK: OpName
+ ; CHECK-NOT: OpDecorate %100
+ ; CHECK: OpDecorate %[[image_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[sampler_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[image_var]] Binding 0
+ ; CHECK: OpDecorate %[[sampler_var]] Binding 0
+
+ ; This is what we are checking in this test.
+ ; CHECK: OpDecorate %[[im:\d+]] RelaxedPrecision
+ ; CHECK: OpDecorate %[[s:\d+]] RelaxedPrecision
+
+ ; CHECK: %10 = OpTypeImage %
+ ; CHECK: %[[image_ptr_ty:\w+]] = OpTypePointer UniformConstant %10
+ ; CHECK: %[[sampler_ty:\d+]] = OpTypeSampler
+ ; CHECK: %[[sampler_ptr_ty:\w+]] = OpTypePointer UniformConstant %[[sampler_ty]]
+
+ ; The combined image variable is replaced by an image variable and a sampler variable.
+
+ ; CHECK-NOT: %100 = OpVariable
+ ; CHECK-NOT: OpVariable _ptr_UniformConstant_11
+ ; CHECK-DAG: %[[sampler_var]] = OpVariable %[[sampler_ptr_ty]] UniformConstant
+ ; CHECK-DAG: %[[image_var]] = OpVariable %[[image_ptr_ty]] UniformConstant
+ ; CHECK: = OpFunction
+
+ ; The load of the combined image+sampler is replaced by a two loads, then
+ ; a combination operation. The new loads get the same decorations that the
+ ; original load had.
+ ; CHECK: %[[im]] = OpLoad %10 %[[image_var]]
+ ; CHECK: %[[s]] = OpLoad %[[sampler_ty]] %[[sampler_var]]
+ ; CHECK: %combined = OpSampledImage %11 %[[im]] %[[s]]
+
+ %bool = OpTypeBool ; location marker
+ %float = OpTypeFloat 32
+ %uint = OpTypeInt 32 0
+ %int = OpTypeInt 32 1
+ %uint_0 = OpConstant %uint 0
+ %uint_1 = OpConstant %uint 1
+ %uint_3 = OpConstant %uint 3
+ %float_0 = OpConstant %float 0
+ %v2float = OpTypeVector %float 2
+ %v3float = OpTypeVector %float 3
+ %v4float = OpTypeVector %float 4
+ %13 = OpConstantNull %v2float
+ %14 = OpConstantNull %v3float
+ %15 = OpConstantNull %v4float
+ %void = OpTypeVoid
+ %voidfn = OpTypeFunction %void
+ %10 = OpTypeImage %float Cube 1 0 0 1 Unknown
+ %11 = OpTypeSampledImage %10
+%_ptr_UniformConstant_11 = OpTypePointer UniformConstant %11
+
+ %100 = OpVariable %_ptr_UniformConstant_11 UniformConstant
+ %main = OpFunction %void None %voidfn
+ %main_0 = OpLabel
+ %combined = OpLoad %11 %100
+
+ ; Uses of the combined image sampler are preserved.
+ ; CHECK: OpCopyObject %11 %combined
+
+ %7 = OpCopyObject %11 %combined
+ OpReturn
+ OpFunctionEnd
diff --git a/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_RelaxedPrecisionOnLoadCopied_9.spvasm b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_RelaxedPrecisionOnLoadCopied_9.spvasm
new file mode 100644
index 0000000..7e67eeb
--- /dev/null
+++ b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_RelaxedPrecisionOnLoadCopied_9.spvasm
@@ -0,0 +1,77 @@
+ OpCapability Shader
+ OpCapability RuntimeDescriptorArray
+ OpExtension "SPV_EXT_descriptor_indexing"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ OpName %main "main"
+ OpName %main_0 "main_0"
+ OpName %voidfn "voidfn"
+
+ OpName %combined "combined"
+ OpDecorate %100 DescriptorSet 0
+ OpDecorate %100 Binding 0
+ OpDecorate %combined RelaxedPrecision
+
+ ; CHECK: OpName
+ ; CHECK-NOT: OpDecorate %100
+ ; CHECK: OpDecorate %[[image_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[sampler_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[image_var]] Binding 0
+ ; CHECK: OpDecorate %[[sampler_var]] Binding 0
+
+ ; This is what we are checking in this test.
+ ; CHECK: OpDecorate %[[im:\d+]] RelaxedPrecision
+ ; CHECK: OpDecorate %[[s:\d+]] RelaxedPrecision
+
+ ; CHECK: %10 = OpTypeImage %
+ ; CHECK: %[[image_ptr_ty:\w+]] = OpTypePointer UniformConstant %10
+ ; CHECK: %[[sampler_ty:\d+]] = OpTypeSampler
+ ; CHECK: %[[sampler_ptr_ty:\w+]] = OpTypePointer UniformConstant %[[sampler_ty]]
+
+ ; The combined image variable is replaced by an image variable and a sampler variable.
+
+ ; CHECK-NOT: %100 = OpVariable
+ ; CHECK-NOT: OpVariable _ptr_UniformConstant_11
+ ; CHECK-DAG: %[[sampler_var]] = OpVariable %[[sampler_ptr_ty]] UniformConstant
+ ; CHECK-DAG: %[[image_var]] = OpVariable %[[image_ptr_ty]] UniformConstant
+ ; CHECK: = OpFunction
+
+ ; The load of the combined image+sampler is replaced by a two loads, then
+ ; a combination operation. The new loads get the same decorations that the
+ ; original load had.
+ ; CHECK: %[[im]] = OpLoad %10 %[[image_var]]
+ ; CHECK: %[[s]] = OpLoad %[[sampler_ty]] %[[sampler_var]]
+ ; CHECK: %combined = OpSampledImage %11 %[[im]] %[[s]]
+
+ %bool = OpTypeBool ; location marker
+ %float = OpTypeFloat 32
+ %uint = OpTypeInt 32 0
+ %int = OpTypeInt 32 1
+ %uint_0 = OpConstant %uint 0
+ %uint_1 = OpConstant %uint 1
+ %uint_3 = OpConstant %uint 3
+ %float_0 = OpConstant %float 0
+ %v2float = OpTypeVector %float 2
+ %v3float = OpTypeVector %float 3
+ %v4float = OpTypeVector %float 4
+ %13 = OpConstantNull %v2float
+ %14 = OpConstantNull %v3float
+ %15 = OpConstantNull %v4float
+ %void = OpTypeVoid
+ %voidfn = OpTypeFunction %void
+ %10 = OpTypeImage %float Cube 0 1 0 1 Unknown
+ %11 = OpTypeSampledImage %10
+%_ptr_UniformConstant_11 = OpTypePointer UniformConstant %11
+
+ %100 = OpVariable %_ptr_UniformConstant_11 UniformConstant
+ %main = OpFunction %void None %voidfn
+ %main_0 = OpLabel
+ %combined = OpLoad %11 %100
+
+ ; Uses of the combined image sampler are preserved.
+ ; CHECK: OpCopyObject %11 %combined
+
+ %7 = OpCopyObject %11 %combined
+ OpReturn
+ OpFunctionEnd
diff --git a/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_RelaxedPrecisionOnVarCopied_0.spvasm b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_RelaxedPrecisionOnVarCopied_0.spvasm
new file mode 100644
index 0000000..d5e61fa
--- /dev/null
+++ b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_RelaxedPrecisionOnVarCopied_0.spvasm
@@ -0,0 +1,74 @@
+ OpCapability Shader
+ OpCapability RuntimeDescriptorArray
+ OpExtension "SPV_EXT_descriptor_indexing"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ OpName %main "main"
+ OpName %main_0 "main_0"
+ OpName %voidfn "voidfn"
+
+ OpName %combined "combined"
+ OpDecorate %100 DescriptorSet 0
+ OpDecorate %100 Binding 0
+ OpDecorate %100 RelaxedPrecision
+
+ ; CHECK: OpName
+ ; CHECK-NOT: OpDecorate %100
+ ; CHECK: OpDecorate %[[image_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[sampler_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[image_var]] Binding 0
+ ; CHECK: OpDecorate %[[sampler_var]] Binding 0
+ ; CHECK: OpDecorate %[[image_var:\d+]] RelaxedPrecision
+ ; CHECK: OpDecorate %[[sampler_var:\d+]] RelaxedPrecision
+
+ ; CHECK: %10 = OpTypeImage %
+ ; CHECK: %[[image_ptr_ty:\w+]] = OpTypePointer UniformConstant %10
+ ; CHECK: %[[sampler_ty:\d+]] = OpTypeSampler
+ ; CHECK: %[[sampler_ptr_ty:\w+]] = OpTypePointer UniformConstant %[[sampler_ty]]
+
+ ; The combined image variable is replaced by an image variable and a sampler variable.
+
+ ; CHECK-NOT: %100 = OpVariable
+ ; CHECK-NOT: OpVariable _ptr_UniformConstant_11
+ ; CHECK-DAG: %[[sampler_var]] = OpVariable %[[sampler_ptr_ty]] UniformConstant
+ ; CHECK-DAG: %[[image_var]] = OpVariable %[[image_ptr_ty]] UniformConstant
+ ; CHECK: = OpFunction
+
+ ; The load of the combined image+sampler is replaced by a two loads, then
+ ; a combination operation.
+ ; CHECK: %[[im:\d+]] = OpLoad %10 %[[image_var]]
+ ; CHECK: %[[s:\d+]] = OpLoad %[[sampler_ty]] %[[sampler_var]]
+ ; CHECK: %combined = OpSampledImage %11 %[[im]] %[[s]]
+
+ %bool = OpTypeBool ; location marker
+ %float = OpTypeFloat 32
+ %uint = OpTypeInt 32 0
+ %int = OpTypeInt 32 1
+ %uint_0 = OpConstant %uint 0
+ %uint_1 = OpConstant %uint 1
+ %uint_3 = OpConstant %uint 3
+ %float_0 = OpConstant %float 0
+ %v2float = OpTypeVector %float 2
+ %v3float = OpTypeVector %float 3
+ %v4float = OpTypeVector %float 4
+ %13 = OpConstantNull %v2float
+ %14 = OpConstantNull %v3float
+ %15 = OpConstantNull %v4float
+ %void = OpTypeVoid
+ %voidfn = OpTypeFunction %void
+ %10 = OpTypeImage %float 2D 0 0 0 1 Unknown
+ %11 = OpTypeSampledImage %10
+%_ptr_UniformConstant_11 = OpTypePointer UniformConstant %11
+
+ %100 = OpVariable %_ptr_UniformConstant_11 UniformConstant
+ %main = OpFunction %void None %voidfn
+ %main_0 = OpLabel
+ %combined = OpLoad %11 %100
+
+ ; Uses of the combined image sampler are preserved.
+ ; CHECK: OpCopyObject %11 %combined
+
+ %7 = OpCopyObject %11 %combined
+ OpReturn
+ OpFunctionEnd
diff --git a/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_RelaxedPrecisionOnVarCopied_1.spvasm b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_RelaxedPrecisionOnVarCopied_1.spvasm
new file mode 100644
index 0000000..57fc15a
--- /dev/null
+++ b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_RelaxedPrecisionOnVarCopied_1.spvasm
@@ -0,0 +1,74 @@
+ OpCapability Shader
+ OpCapability RuntimeDescriptorArray
+ OpExtension "SPV_EXT_descriptor_indexing"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ OpName %main "main"
+ OpName %main_0 "main_0"
+ OpName %voidfn "voidfn"
+
+ OpName %combined "combined"
+ OpDecorate %100 DescriptorSet 0
+ OpDecorate %100 Binding 0
+ OpDecorate %100 RelaxedPrecision
+
+ ; CHECK: OpName
+ ; CHECK-NOT: OpDecorate %100
+ ; CHECK: OpDecorate %[[image_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[sampler_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[image_var]] Binding 0
+ ; CHECK: OpDecorate %[[sampler_var]] Binding 0
+ ; CHECK: OpDecorate %[[image_var:\d+]] RelaxedPrecision
+ ; CHECK: OpDecorate %[[sampler_var:\d+]] RelaxedPrecision
+
+ ; CHECK: %10 = OpTypeImage %
+ ; CHECK: %[[image_ptr_ty:\w+]] = OpTypePointer UniformConstant %10
+ ; CHECK: %[[sampler_ty:\d+]] = OpTypeSampler
+ ; CHECK: %[[sampler_ptr_ty:\w+]] = OpTypePointer UniformConstant %[[sampler_ty]]
+
+ ; The combined image variable is replaced by an image variable and a sampler variable.
+
+ ; CHECK-NOT: %100 = OpVariable
+ ; CHECK-NOT: OpVariable _ptr_UniformConstant_11
+ ; CHECK-DAG: %[[sampler_var]] = OpVariable %[[sampler_ptr_ty]] UniformConstant
+ ; CHECK-DAG: %[[image_var]] = OpVariable %[[image_ptr_ty]] UniformConstant
+ ; CHECK: = OpFunction
+
+ ; The load of the combined image+sampler is replaced by a two loads, then
+ ; a combination operation.
+ ; CHECK: %[[im:\d+]] = OpLoad %10 %[[image_var]]
+ ; CHECK: %[[s:\d+]] = OpLoad %[[sampler_ty]] %[[sampler_var]]
+ ; CHECK: %combined = OpSampledImage %11 %[[im]] %[[s]]
+
+ %bool = OpTypeBool ; location marker
+ %float = OpTypeFloat 32
+ %uint = OpTypeInt 32 0
+ %int = OpTypeInt 32 1
+ %uint_0 = OpConstant %uint 0
+ %uint_1 = OpConstant %uint 1
+ %uint_3 = OpConstant %uint 3
+ %float_0 = OpConstant %float 0
+ %v2float = OpTypeVector %float 2
+ %v3float = OpTypeVector %float 3
+ %v4float = OpTypeVector %float 4
+ %13 = OpConstantNull %v2float
+ %14 = OpConstantNull %v3float
+ %15 = OpConstantNull %v4float
+ %void = OpTypeVoid
+ %voidfn = OpTypeFunction %void
+ %10 = OpTypeImage %float 2D 1 0 0 1 Unknown
+ %11 = OpTypeSampledImage %10
+%_ptr_UniformConstant_11 = OpTypePointer UniformConstant %11
+
+ %100 = OpVariable %_ptr_UniformConstant_11 UniformConstant
+ %main = OpFunction %void None %voidfn
+ %main_0 = OpLabel
+ %combined = OpLoad %11 %100
+
+ ; Uses of the combined image sampler are preserved.
+ ; CHECK: OpCopyObject %11 %combined
+
+ %7 = OpCopyObject %11 %combined
+ OpReturn
+ OpFunctionEnd
diff --git a/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_RelaxedPrecisionOnVarCopied_10.spvasm b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_RelaxedPrecisionOnVarCopied_10.spvasm
new file mode 100644
index 0000000..6db7c5f
--- /dev/null
+++ b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_RelaxedPrecisionOnVarCopied_10.spvasm
@@ -0,0 +1,74 @@
+ OpCapability Shader
+ OpCapability RuntimeDescriptorArray
+ OpExtension "SPV_EXT_descriptor_indexing"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ OpName %main "main"
+ OpName %main_0 "main_0"
+ OpName %voidfn "voidfn"
+
+ OpName %combined "combined"
+ OpDecorate %100 DescriptorSet 0
+ OpDecorate %100 Binding 0
+ OpDecorate %100 RelaxedPrecision
+
+ ; CHECK: OpName
+ ; CHECK-NOT: OpDecorate %100
+ ; CHECK: OpDecorate %[[image_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[sampler_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[image_var]] Binding 0
+ ; CHECK: OpDecorate %[[sampler_var]] Binding 0
+ ; CHECK: OpDecorate %[[image_var:\d+]] RelaxedPrecision
+ ; CHECK: OpDecorate %[[sampler_var:\d+]] RelaxedPrecision
+
+ ; CHECK: %10 = OpTypeImage %
+ ; CHECK: %[[image_ptr_ty:\w+]] = OpTypePointer UniformConstant %10
+ ; CHECK: %[[sampler_ty:\d+]] = OpTypeSampler
+ ; CHECK: %[[sampler_ptr_ty:\w+]] = OpTypePointer UniformConstant %[[sampler_ty]]
+
+ ; The combined image variable is replaced by an image variable and a sampler variable.
+
+ ; CHECK-NOT: %100 = OpVariable
+ ; CHECK-NOT: OpVariable _ptr_UniformConstant_11
+ ; CHECK-DAG: %[[sampler_var]] = OpVariable %[[sampler_ptr_ty]] UniformConstant
+ ; CHECK-DAG: %[[image_var]] = OpVariable %[[image_ptr_ty]] UniformConstant
+ ; CHECK: = OpFunction
+
+ ; The load of the combined image+sampler is replaced by a two loads, then
+ ; a combination operation.
+ ; CHECK: %[[im:\d+]] = OpLoad %10 %[[image_var]]
+ ; CHECK: %[[s:\d+]] = OpLoad %[[sampler_ty]] %[[sampler_var]]
+ ; CHECK: %combined = OpSampledImage %11 %[[im]] %[[s]]
+
+ %bool = OpTypeBool ; location marker
+ %float = OpTypeFloat 32
+ %uint = OpTypeInt 32 0
+ %int = OpTypeInt 32 1
+ %uint_0 = OpConstant %uint 0
+ %uint_1 = OpConstant %uint 1
+ %uint_3 = OpConstant %uint 3
+ %float_0 = OpConstant %float 0
+ %v2float = OpTypeVector %float 2
+ %v3float = OpTypeVector %float 3
+ %v4float = OpTypeVector %float 4
+ %13 = OpConstantNull %v2float
+ %14 = OpConstantNull %v3float
+ %15 = OpConstantNull %v4float
+ %void = OpTypeVoid
+ %voidfn = OpTypeFunction %void
+ %10 = OpTypeImage %float Cube 1 1 0 1 Unknown
+ %11 = OpTypeSampledImage %10
+%_ptr_UniformConstant_11 = OpTypePointer UniformConstant %11
+
+ %100 = OpVariable %_ptr_UniformConstant_11 UniformConstant
+ %main = OpFunction %void None %voidfn
+ %main_0 = OpLabel
+ %combined = OpLoad %11 %100
+
+ ; Uses of the combined image sampler are preserved.
+ ; CHECK: OpCopyObject %11 %combined
+
+ %7 = OpCopyObject %11 %combined
+ OpReturn
+ OpFunctionEnd
diff --git a/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_RelaxedPrecisionOnVarCopied_11.spvasm b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_RelaxedPrecisionOnVarCopied_11.spvasm
new file mode 100644
index 0000000..4682a80
--- /dev/null
+++ b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_RelaxedPrecisionOnVarCopied_11.spvasm
@@ -0,0 +1,74 @@
+ OpCapability Shader
+ OpCapability RuntimeDescriptorArray
+ OpExtension "SPV_EXT_descriptor_indexing"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ OpName %main "main"
+ OpName %main_0 "main_0"
+ OpName %voidfn "voidfn"
+
+ OpName %combined "combined"
+ OpDecorate %100 DescriptorSet 0
+ OpDecorate %100 Binding 0
+ OpDecorate %100 RelaxedPrecision
+
+ ; CHECK: OpName
+ ; CHECK-NOT: OpDecorate %100
+ ; CHECK: OpDecorate %[[image_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[sampler_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[image_var]] Binding 0
+ ; CHECK: OpDecorate %[[sampler_var]] Binding 0
+ ; CHECK: OpDecorate %[[image_var:\d+]] RelaxedPrecision
+ ; CHECK: OpDecorate %[[sampler_var:\d+]] RelaxedPrecision
+
+ ; CHECK: %10 = OpTypeImage %
+ ; CHECK: %[[image_ptr_ty:\w+]] = OpTypePointer UniformConstant %10
+ ; CHECK: %[[sampler_ty:\d+]] = OpTypeSampler
+ ; CHECK: %[[sampler_ptr_ty:\w+]] = OpTypePointer UniformConstant %[[sampler_ty]]
+
+ ; The combined image variable is replaced by an image variable and a sampler variable.
+
+ ; CHECK-NOT: %100 = OpVariable
+ ; CHECK-NOT: OpVariable _ptr_UniformConstant_11
+ ; CHECK-DAG: %[[sampler_var]] = OpVariable %[[sampler_ptr_ty]] UniformConstant
+ ; CHECK-DAG: %[[image_var]] = OpVariable %[[image_ptr_ty]] UniformConstant
+ ; CHECK: = OpFunction
+
+ ; The load of the combined image+sampler is replaced by a two loads, then
+ ; a combination operation.
+ ; CHECK: %[[im:\d+]] = OpLoad %10 %[[image_var]]
+ ; CHECK: %[[s:\d+]] = OpLoad %[[sampler_ty]] %[[sampler_var]]
+ ; CHECK: %combined = OpSampledImage %11 %[[im]] %[[s]]
+
+ %bool = OpTypeBool ; location marker
+ %float = OpTypeFloat 32
+ %uint = OpTypeInt 32 0
+ %int = OpTypeInt 32 1
+ %uint_0 = OpConstant %uint 0
+ %uint_1 = OpConstant %uint 1
+ %uint_3 = OpConstant %uint 3
+ %float_0 = OpConstant %float 0
+ %v2float = OpTypeVector %float 2
+ %v3float = OpTypeVector %float 3
+ %v4float = OpTypeVector %float 4
+ %13 = OpConstantNull %v2float
+ %14 = OpConstantNull %v3float
+ %15 = OpConstantNull %v4float
+ %void = OpTypeVoid
+ %voidfn = OpTypeFunction %void
+ %10 = OpTypeImage %int 2D 0 0 0 1 Unknown
+ %11 = OpTypeSampledImage %10
+%_ptr_UniformConstant_11 = OpTypePointer UniformConstant %11
+
+ %100 = OpVariable %_ptr_UniformConstant_11 UniformConstant
+ %main = OpFunction %void None %voidfn
+ %main_0 = OpLabel
+ %combined = OpLoad %11 %100
+
+ ; Uses of the combined image sampler are preserved.
+ ; CHECK: OpCopyObject %11 %combined
+
+ %7 = OpCopyObject %11 %combined
+ OpReturn
+ OpFunctionEnd
diff --git a/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_RelaxedPrecisionOnVarCopied_12.spvasm b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_RelaxedPrecisionOnVarCopied_12.spvasm
new file mode 100644
index 0000000..40dd3e2
--- /dev/null
+++ b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_RelaxedPrecisionOnVarCopied_12.spvasm
@@ -0,0 +1,74 @@
+ OpCapability Shader
+ OpCapability RuntimeDescriptorArray
+ OpExtension "SPV_EXT_descriptor_indexing"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ OpName %main "main"
+ OpName %main_0 "main_0"
+ OpName %voidfn "voidfn"
+
+ OpName %combined "combined"
+ OpDecorate %100 DescriptorSet 0
+ OpDecorate %100 Binding 0
+ OpDecorate %100 RelaxedPrecision
+
+ ; CHECK: OpName
+ ; CHECK-NOT: OpDecorate %100
+ ; CHECK: OpDecorate %[[image_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[sampler_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[image_var]] Binding 0
+ ; CHECK: OpDecorate %[[sampler_var]] Binding 0
+ ; CHECK: OpDecorate %[[image_var:\d+]] RelaxedPrecision
+ ; CHECK: OpDecorate %[[sampler_var:\d+]] RelaxedPrecision
+
+ ; CHECK: %10 = OpTypeImage %
+ ; CHECK: %[[image_ptr_ty:\w+]] = OpTypePointer UniformConstant %10
+ ; CHECK: %[[sampler_ty:\d+]] = OpTypeSampler
+ ; CHECK: %[[sampler_ptr_ty:\w+]] = OpTypePointer UniformConstant %[[sampler_ty]]
+
+ ; The combined image variable is replaced by an image variable and a sampler variable.
+
+ ; CHECK-NOT: %100 = OpVariable
+ ; CHECK-NOT: OpVariable _ptr_UniformConstant_11
+ ; CHECK-DAG: %[[sampler_var]] = OpVariable %[[sampler_ptr_ty]] UniformConstant
+ ; CHECK-DAG: %[[image_var]] = OpVariable %[[image_ptr_ty]] UniformConstant
+ ; CHECK: = OpFunction
+
+ ; The load of the combined image+sampler is replaced by a two loads, then
+ ; a combination operation.
+ ; CHECK: %[[im:\d+]] = OpLoad %10 %[[image_var]]
+ ; CHECK: %[[s:\d+]] = OpLoad %[[sampler_ty]] %[[sampler_var]]
+ ; CHECK: %combined = OpSampledImage %11 %[[im]] %[[s]]
+
+ %bool = OpTypeBool ; location marker
+ %float = OpTypeFloat 32
+ %uint = OpTypeInt 32 0
+ %int = OpTypeInt 32 1
+ %uint_0 = OpConstant %uint 0
+ %uint_1 = OpConstant %uint 1
+ %uint_3 = OpConstant %uint 3
+ %float_0 = OpConstant %float 0
+ %v2float = OpTypeVector %float 2
+ %v3float = OpTypeVector %float 3
+ %v4float = OpTypeVector %float 4
+ %13 = OpConstantNull %v2float
+ %14 = OpConstantNull %v3float
+ %15 = OpConstantNull %v4float
+ %void = OpTypeVoid
+ %voidfn = OpTypeFunction %void
+ %10 = OpTypeImage %int 2D 1 0 0 1 Unknown
+ %11 = OpTypeSampledImage %10
+%_ptr_UniformConstant_11 = OpTypePointer UniformConstant %11
+
+ %100 = OpVariable %_ptr_UniformConstant_11 UniformConstant
+ %main = OpFunction %void None %voidfn
+ %main_0 = OpLabel
+ %combined = OpLoad %11 %100
+
+ ; Uses of the combined image sampler are preserved.
+ ; CHECK: OpCopyObject %11 %combined
+
+ %7 = OpCopyObject %11 %combined
+ OpReturn
+ OpFunctionEnd
diff --git a/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_RelaxedPrecisionOnVarCopied_13.spvasm b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_RelaxedPrecisionOnVarCopied_13.spvasm
new file mode 100644
index 0000000..ccc1880
--- /dev/null
+++ b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_RelaxedPrecisionOnVarCopied_13.spvasm
@@ -0,0 +1,74 @@
+ OpCapability Shader
+ OpCapability RuntimeDescriptorArray
+ OpExtension "SPV_EXT_descriptor_indexing"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ OpName %main "main"
+ OpName %main_0 "main_0"
+ OpName %voidfn "voidfn"
+
+ OpName %combined "combined"
+ OpDecorate %100 DescriptorSet 0
+ OpDecorate %100 Binding 0
+ OpDecorate %100 RelaxedPrecision
+
+ ; CHECK: OpName
+ ; CHECK-NOT: OpDecorate %100
+ ; CHECK: OpDecorate %[[image_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[sampler_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[image_var]] Binding 0
+ ; CHECK: OpDecorate %[[sampler_var]] Binding 0
+ ; CHECK: OpDecorate %[[image_var:\d+]] RelaxedPrecision
+ ; CHECK: OpDecorate %[[sampler_var:\d+]] RelaxedPrecision
+
+ ; CHECK: %10 = OpTypeImage %
+ ; CHECK: %[[image_ptr_ty:\w+]] = OpTypePointer UniformConstant %10
+ ; CHECK: %[[sampler_ty:\d+]] = OpTypeSampler
+ ; CHECK: %[[sampler_ptr_ty:\w+]] = OpTypePointer UniformConstant %[[sampler_ty]]
+
+ ; The combined image variable is replaced by an image variable and a sampler variable.
+
+ ; CHECK-NOT: %100 = OpVariable
+ ; CHECK-NOT: OpVariable _ptr_UniformConstant_11
+ ; CHECK-DAG: %[[sampler_var]] = OpVariable %[[sampler_ptr_ty]] UniformConstant
+ ; CHECK-DAG: %[[image_var]] = OpVariable %[[image_ptr_ty]] UniformConstant
+ ; CHECK: = OpFunction
+
+ ; The load of the combined image+sampler is replaced by a two loads, then
+ ; a combination operation.
+ ; CHECK: %[[im:\d+]] = OpLoad %10 %[[image_var]]
+ ; CHECK: %[[s:\d+]] = OpLoad %[[sampler_ty]] %[[sampler_var]]
+ ; CHECK: %combined = OpSampledImage %11 %[[im]] %[[s]]
+
+ %bool = OpTypeBool ; location marker
+ %float = OpTypeFloat 32
+ %uint = OpTypeInt 32 0
+ %int = OpTypeInt 32 1
+ %uint_0 = OpConstant %uint 0
+ %uint_1 = OpConstant %uint 1
+ %uint_3 = OpConstant %uint 3
+ %float_0 = OpConstant %float 0
+ %v2float = OpTypeVector %float 2
+ %v3float = OpTypeVector %float 3
+ %v4float = OpTypeVector %float 4
+ %13 = OpConstantNull %v2float
+ %14 = OpConstantNull %v3float
+ %15 = OpConstantNull %v4float
+ %void = OpTypeVoid
+ %voidfn = OpTypeFunction %void
+ %10 = OpTypeImage %int 2D 0 1 0 1 Unknown
+ %11 = OpTypeSampledImage %10
+%_ptr_UniformConstant_11 = OpTypePointer UniformConstant %11
+
+ %100 = OpVariable %_ptr_UniformConstant_11 UniformConstant
+ %main = OpFunction %void None %voidfn
+ %main_0 = OpLabel
+ %combined = OpLoad %11 %100
+
+ ; Uses of the combined image sampler are preserved.
+ ; CHECK: OpCopyObject %11 %combined
+
+ %7 = OpCopyObject %11 %combined
+ OpReturn
+ OpFunctionEnd
diff --git a/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_RelaxedPrecisionOnVarCopied_14.spvasm b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_RelaxedPrecisionOnVarCopied_14.spvasm
new file mode 100644
index 0000000..0de5938
--- /dev/null
+++ b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_RelaxedPrecisionOnVarCopied_14.spvasm
@@ -0,0 +1,74 @@
+ OpCapability Shader
+ OpCapability RuntimeDescriptorArray
+ OpExtension "SPV_EXT_descriptor_indexing"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ OpName %main "main"
+ OpName %main_0 "main_0"
+ OpName %voidfn "voidfn"
+
+ OpName %combined "combined"
+ OpDecorate %100 DescriptorSet 0
+ OpDecorate %100 Binding 0
+ OpDecorate %100 RelaxedPrecision
+
+ ; CHECK: OpName
+ ; CHECK-NOT: OpDecorate %100
+ ; CHECK: OpDecorate %[[image_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[sampler_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[image_var]] Binding 0
+ ; CHECK: OpDecorate %[[sampler_var]] Binding 0
+ ; CHECK: OpDecorate %[[image_var:\d+]] RelaxedPrecision
+ ; CHECK: OpDecorate %[[sampler_var:\d+]] RelaxedPrecision
+
+ ; CHECK: %10 = OpTypeImage %
+ ; CHECK: %[[image_ptr_ty:\w+]] = OpTypePointer UniformConstant %10
+ ; CHECK: %[[sampler_ty:\d+]] = OpTypeSampler
+ ; CHECK: %[[sampler_ptr_ty:\w+]] = OpTypePointer UniformConstant %[[sampler_ty]]
+
+ ; The combined image variable is replaced by an image variable and a sampler variable.
+
+ ; CHECK-NOT: %100 = OpVariable
+ ; CHECK-NOT: OpVariable _ptr_UniformConstant_11
+ ; CHECK-DAG: %[[sampler_var]] = OpVariable %[[sampler_ptr_ty]] UniformConstant
+ ; CHECK-DAG: %[[image_var]] = OpVariable %[[image_ptr_ty]] UniformConstant
+ ; CHECK: = OpFunction
+
+ ; The load of the combined image+sampler is replaced by a two loads, then
+ ; a combination operation.
+ ; CHECK: %[[im:\d+]] = OpLoad %10 %[[image_var]]
+ ; CHECK: %[[s:\d+]] = OpLoad %[[sampler_ty]] %[[sampler_var]]
+ ; CHECK: %combined = OpSampledImage %11 %[[im]] %[[s]]
+
+ %bool = OpTypeBool ; location marker
+ %float = OpTypeFloat 32
+ %uint = OpTypeInt 32 0
+ %int = OpTypeInt 32 1
+ %uint_0 = OpConstant %uint 0
+ %uint_1 = OpConstant %uint 1
+ %uint_3 = OpConstant %uint 3
+ %float_0 = OpConstant %float 0
+ %v2float = OpTypeVector %float 2
+ %v3float = OpTypeVector %float 3
+ %v4float = OpTypeVector %float 4
+ %13 = OpConstantNull %v2float
+ %14 = OpConstantNull %v3float
+ %15 = OpConstantNull %v4float
+ %void = OpTypeVoid
+ %voidfn = OpTypeFunction %void
+ %10 = OpTypeImage %int 2D 1 1 0 1 Unknown
+ %11 = OpTypeSampledImage %10
+%_ptr_UniformConstant_11 = OpTypePointer UniformConstant %11
+
+ %100 = OpVariable %_ptr_UniformConstant_11 UniformConstant
+ %main = OpFunction %void None %voidfn
+ %main_0 = OpLabel
+ %combined = OpLoad %11 %100
+
+ ; Uses of the combined image sampler are preserved.
+ ; CHECK: OpCopyObject %11 %combined
+
+ %7 = OpCopyObject %11 %combined
+ OpReturn
+ OpFunctionEnd
diff --git a/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_RelaxedPrecisionOnVarCopied_15.spvasm b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_RelaxedPrecisionOnVarCopied_15.spvasm
new file mode 100644
index 0000000..216d24e
--- /dev/null
+++ b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_RelaxedPrecisionOnVarCopied_15.spvasm
@@ -0,0 +1,74 @@
+ OpCapability Shader
+ OpCapability RuntimeDescriptorArray
+ OpExtension "SPV_EXT_descriptor_indexing"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ OpName %main "main"
+ OpName %main_0 "main_0"
+ OpName %voidfn "voidfn"
+
+ OpName %combined "combined"
+ OpDecorate %100 DescriptorSet 0
+ OpDecorate %100 Binding 0
+ OpDecorate %100 RelaxedPrecision
+
+ ; CHECK: OpName
+ ; CHECK-NOT: OpDecorate %100
+ ; CHECK: OpDecorate %[[image_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[sampler_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[image_var]] Binding 0
+ ; CHECK: OpDecorate %[[sampler_var]] Binding 0
+ ; CHECK: OpDecorate %[[image_var:\d+]] RelaxedPrecision
+ ; CHECK: OpDecorate %[[sampler_var:\d+]] RelaxedPrecision
+
+ ; CHECK: %10 = OpTypeImage %
+ ; CHECK: %[[image_ptr_ty:\w+]] = OpTypePointer UniformConstant %10
+ ; CHECK: %[[sampler_ty:\d+]] = OpTypeSampler
+ ; CHECK: %[[sampler_ptr_ty:\w+]] = OpTypePointer UniformConstant %[[sampler_ty]]
+
+ ; The combined image variable is replaced by an image variable and a sampler variable.
+
+ ; CHECK-NOT: %100 = OpVariable
+ ; CHECK-NOT: OpVariable _ptr_UniformConstant_11
+ ; CHECK-DAG: %[[sampler_var]] = OpVariable %[[sampler_ptr_ty]] UniformConstant
+ ; CHECK-DAG: %[[image_var]] = OpVariable %[[image_ptr_ty]] UniformConstant
+ ; CHECK: = OpFunction
+
+ ; The load of the combined image+sampler is replaced by a two loads, then
+ ; a combination operation.
+ ; CHECK: %[[im:\d+]] = OpLoad %10 %[[image_var]]
+ ; CHECK: %[[s:\d+]] = OpLoad %[[sampler_ty]] %[[sampler_var]]
+ ; CHECK: %combined = OpSampledImage %11 %[[im]] %[[s]]
+
+ %bool = OpTypeBool ; location marker
+ %float = OpTypeFloat 32
+ %uint = OpTypeInt 32 0
+ %int = OpTypeInt 32 1
+ %uint_0 = OpConstant %uint 0
+ %uint_1 = OpConstant %uint 1
+ %uint_3 = OpConstant %uint 3
+ %float_0 = OpConstant %float 0
+ %v2float = OpTypeVector %float 2
+ %v3float = OpTypeVector %float 3
+ %v4float = OpTypeVector %float 4
+ %13 = OpConstantNull %v2float
+ %14 = OpConstantNull %v3float
+ %15 = OpConstantNull %v4float
+ %void = OpTypeVoid
+ %voidfn = OpTypeFunction %void
+ %10 = OpTypeImage %int 2D 0 0 1 1 Unknown
+ %11 = OpTypeSampledImage %10
+%_ptr_UniformConstant_11 = OpTypePointer UniformConstant %11
+
+ %100 = OpVariable %_ptr_UniformConstant_11 UniformConstant
+ %main = OpFunction %void None %voidfn
+ %main_0 = OpLabel
+ %combined = OpLoad %11 %100
+
+ ; Uses of the combined image sampler are preserved.
+ ; CHECK: OpCopyObject %11 %combined
+
+ %7 = OpCopyObject %11 %combined
+ OpReturn
+ OpFunctionEnd
diff --git a/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_RelaxedPrecisionOnVarCopied_17.spvasm b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_RelaxedPrecisionOnVarCopied_17.spvasm
new file mode 100644
index 0000000..812b22f
--- /dev/null
+++ b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_RelaxedPrecisionOnVarCopied_17.spvasm
@@ -0,0 +1,74 @@
+ OpCapability Shader
+ OpCapability RuntimeDescriptorArray
+ OpExtension "SPV_EXT_descriptor_indexing"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ OpName %main "main"
+ OpName %main_0 "main_0"
+ OpName %voidfn "voidfn"
+
+ OpName %combined "combined"
+ OpDecorate %100 DescriptorSet 0
+ OpDecorate %100 Binding 0
+ OpDecorate %100 RelaxedPrecision
+
+ ; CHECK: OpName
+ ; CHECK-NOT: OpDecorate %100
+ ; CHECK: OpDecorate %[[image_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[sampler_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[image_var]] Binding 0
+ ; CHECK: OpDecorate %[[sampler_var]] Binding 0
+ ; CHECK: OpDecorate %[[image_var:\d+]] RelaxedPrecision
+ ; CHECK: OpDecorate %[[sampler_var:\d+]] RelaxedPrecision
+
+ ; CHECK: %10 = OpTypeImage %
+ ; CHECK: %[[image_ptr_ty:\w+]] = OpTypePointer UniformConstant %10
+ ; CHECK: %[[sampler_ty:\d+]] = OpTypeSampler
+ ; CHECK: %[[sampler_ptr_ty:\w+]] = OpTypePointer UniformConstant %[[sampler_ty]]
+
+ ; The combined image variable is replaced by an image variable and a sampler variable.
+
+ ; CHECK-NOT: %100 = OpVariable
+ ; CHECK-NOT: OpVariable _ptr_UniformConstant_11
+ ; CHECK-DAG: %[[sampler_var]] = OpVariable %[[sampler_ptr_ty]] UniformConstant
+ ; CHECK-DAG: %[[image_var]] = OpVariable %[[image_ptr_ty]] UniformConstant
+ ; CHECK: = OpFunction
+
+ ; The load of the combined image+sampler is replaced by a two loads, then
+ ; a combination operation.
+ ; CHECK: %[[im:\d+]] = OpLoad %10 %[[image_var]]
+ ; CHECK: %[[s:\d+]] = OpLoad %[[sampler_ty]] %[[sampler_var]]
+ ; CHECK: %combined = OpSampledImage %11 %[[im]] %[[s]]
+
+ %bool = OpTypeBool ; location marker
+ %float = OpTypeFloat 32
+ %uint = OpTypeInt 32 0
+ %int = OpTypeInt 32 1
+ %uint_0 = OpConstant %uint 0
+ %uint_1 = OpConstant %uint 1
+ %uint_3 = OpConstant %uint 3
+ %float_0 = OpConstant %float 0
+ %v2float = OpTypeVector %float 2
+ %v3float = OpTypeVector %float 3
+ %v4float = OpTypeVector %float 4
+ %13 = OpConstantNull %v2float
+ %14 = OpConstantNull %v3float
+ %15 = OpConstantNull %v4float
+ %void = OpTypeVoid
+ %voidfn = OpTypeFunction %void
+ %10 = OpTypeImage %int 3D 0 0 0 1 Unknown
+ %11 = OpTypeSampledImage %10
+%_ptr_UniformConstant_11 = OpTypePointer UniformConstant %11
+
+ %100 = OpVariable %_ptr_UniformConstant_11 UniformConstant
+ %main = OpFunction %void None %voidfn
+ %main_0 = OpLabel
+ %combined = OpLoad %11 %100
+
+ ; Uses of the combined image sampler are preserved.
+ ; CHECK: OpCopyObject %11 %combined
+
+ %7 = OpCopyObject %11 %combined
+ OpReturn
+ OpFunctionEnd
diff --git a/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_RelaxedPrecisionOnVarCopied_18.spvasm b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_RelaxedPrecisionOnVarCopied_18.spvasm
new file mode 100644
index 0000000..10a5a60
--- /dev/null
+++ b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_RelaxedPrecisionOnVarCopied_18.spvasm
@@ -0,0 +1,74 @@
+ OpCapability Shader
+ OpCapability RuntimeDescriptorArray
+ OpExtension "SPV_EXT_descriptor_indexing"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ OpName %main "main"
+ OpName %main_0 "main_0"
+ OpName %voidfn "voidfn"
+
+ OpName %combined "combined"
+ OpDecorate %100 DescriptorSet 0
+ OpDecorate %100 Binding 0
+ OpDecorate %100 RelaxedPrecision
+
+ ; CHECK: OpName
+ ; CHECK-NOT: OpDecorate %100
+ ; CHECK: OpDecorate %[[image_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[sampler_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[image_var]] Binding 0
+ ; CHECK: OpDecorate %[[sampler_var]] Binding 0
+ ; CHECK: OpDecorate %[[image_var:\d+]] RelaxedPrecision
+ ; CHECK: OpDecorate %[[sampler_var:\d+]] RelaxedPrecision
+
+ ; CHECK: %10 = OpTypeImage %
+ ; CHECK: %[[image_ptr_ty:\w+]] = OpTypePointer UniformConstant %10
+ ; CHECK: %[[sampler_ty:\d+]] = OpTypeSampler
+ ; CHECK: %[[sampler_ptr_ty:\w+]] = OpTypePointer UniformConstant %[[sampler_ty]]
+
+ ; The combined image variable is replaced by an image variable and a sampler variable.
+
+ ; CHECK-NOT: %100 = OpVariable
+ ; CHECK-NOT: OpVariable _ptr_UniformConstant_11
+ ; CHECK-DAG: %[[sampler_var]] = OpVariable %[[sampler_ptr_ty]] UniformConstant
+ ; CHECK-DAG: %[[image_var]] = OpVariable %[[image_ptr_ty]] UniformConstant
+ ; CHECK: = OpFunction
+
+ ; The load of the combined image+sampler is replaced by a two loads, then
+ ; a combination operation.
+ ; CHECK: %[[im:\d+]] = OpLoad %10 %[[image_var]]
+ ; CHECK: %[[s:\d+]] = OpLoad %[[sampler_ty]] %[[sampler_var]]
+ ; CHECK: %combined = OpSampledImage %11 %[[im]] %[[s]]
+
+ %bool = OpTypeBool ; location marker
+ %float = OpTypeFloat 32
+ %uint = OpTypeInt 32 0
+ %int = OpTypeInt 32 1
+ %uint_0 = OpConstant %uint 0
+ %uint_1 = OpConstant %uint 1
+ %uint_3 = OpConstant %uint 3
+ %float_0 = OpConstant %float 0
+ %v2float = OpTypeVector %float 2
+ %v3float = OpTypeVector %float 3
+ %v4float = OpTypeVector %float 4
+ %13 = OpConstantNull %v2float
+ %14 = OpConstantNull %v3float
+ %15 = OpConstantNull %v4float
+ %void = OpTypeVoid
+ %voidfn = OpTypeFunction %void
+ %10 = OpTypeImage %int Cube 0 0 0 1 Unknown
+ %11 = OpTypeSampledImage %10
+%_ptr_UniformConstant_11 = OpTypePointer UniformConstant %11
+
+ %100 = OpVariable %_ptr_UniformConstant_11 UniformConstant
+ %main = OpFunction %void None %voidfn
+ %main_0 = OpLabel
+ %combined = OpLoad %11 %100
+
+ ; Uses of the combined image sampler are preserved.
+ ; CHECK: OpCopyObject %11 %combined
+
+ %7 = OpCopyObject %11 %combined
+ OpReturn
+ OpFunctionEnd
diff --git a/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_RelaxedPrecisionOnVarCopied_19.spvasm b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_RelaxedPrecisionOnVarCopied_19.spvasm
new file mode 100644
index 0000000..a0ab820
--- /dev/null
+++ b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_RelaxedPrecisionOnVarCopied_19.spvasm
@@ -0,0 +1,74 @@
+ OpCapability Shader
+ OpCapability RuntimeDescriptorArray
+ OpExtension "SPV_EXT_descriptor_indexing"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ OpName %main "main"
+ OpName %main_0 "main_0"
+ OpName %voidfn "voidfn"
+
+ OpName %combined "combined"
+ OpDecorate %100 DescriptorSet 0
+ OpDecorate %100 Binding 0
+ OpDecorate %100 RelaxedPrecision
+
+ ; CHECK: OpName
+ ; CHECK-NOT: OpDecorate %100
+ ; CHECK: OpDecorate %[[image_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[sampler_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[image_var]] Binding 0
+ ; CHECK: OpDecorate %[[sampler_var]] Binding 0
+ ; CHECK: OpDecorate %[[image_var:\d+]] RelaxedPrecision
+ ; CHECK: OpDecorate %[[sampler_var:\d+]] RelaxedPrecision
+
+ ; CHECK: %10 = OpTypeImage %
+ ; CHECK: %[[image_ptr_ty:\w+]] = OpTypePointer UniformConstant %10
+ ; CHECK: %[[sampler_ty:\d+]] = OpTypeSampler
+ ; CHECK: %[[sampler_ptr_ty:\w+]] = OpTypePointer UniformConstant %[[sampler_ty]]
+
+ ; The combined image variable is replaced by an image variable and a sampler variable.
+
+ ; CHECK-NOT: %100 = OpVariable
+ ; CHECK-NOT: OpVariable _ptr_UniformConstant_11
+ ; CHECK-DAG: %[[sampler_var]] = OpVariable %[[sampler_ptr_ty]] UniformConstant
+ ; CHECK-DAG: %[[image_var]] = OpVariable %[[image_ptr_ty]] UniformConstant
+ ; CHECK: = OpFunction
+
+ ; The load of the combined image+sampler is replaced by a two loads, then
+ ; a combination operation.
+ ; CHECK: %[[im:\d+]] = OpLoad %10 %[[image_var]]
+ ; CHECK: %[[s:\d+]] = OpLoad %[[sampler_ty]] %[[sampler_var]]
+ ; CHECK: %combined = OpSampledImage %11 %[[im]] %[[s]]
+
+ %bool = OpTypeBool ; location marker
+ %float = OpTypeFloat 32
+ %uint = OpTypeInt 32 0
+ %int = OpTypeInt 32 1
+ %uint_0 = OpConstant %uint 0
+ %uint_1 = OpConstant %uint 1
+ %uint_3 = OpConstant %uint 3
+ %float_0 = OpConstant %float 0
+ %v2float = OpTypeVector %float 2
+ %v3float = OpTypeVector %float 3
+ %v4float = OpTypeVector %float 4
+ %13 = OpConstantNull %v2float
+ %14 = OpConstantNull %v3float
+ %15 = OpConstantNull %v4float
+ %void = OpTypeVoid
+ %voidfn = OpTypeFunction %void
+ %10 = OpTypeImage %int Cube 1 0 0 1 Unknown
+ %11 = OpTypeSampledImage %10
+%_ptr_UniformConstant_11 = OpTypePointer UniformConstant %11
+
+ %100 = OpVariable %_ptr_UniformConstant_11 UniformConstant
+ %main = OpFunction %void None %voidfn
+ %main_0 = OpLabel
+ %combined = OpLoad %11 %100
+
+ ; Uses of the combined image sampler are preserved.
+ ; CHECK: OpCopyObject %11 %combined
+
+ %7 = OpCopyObject %11 %combined
+ OpReturn
+ OpFunctionEnd
diff --git a/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_RelaxedPrecisionOnVarCopied_2.spvasm b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_RelaxedPrecisionOnVarCopied_2.spvasm
new file mode 100644
index 0000000..b5d1bfc
--- /dev/null
+++ b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_RelaxedPrecisionOnVarCopied_2.spvasm
@@ -0,0 +1,74 @@
+ OpCapability Shader
+ OpCapability RuntimeDescriptorArray
+ OpExtension "SPV_EXT_descriptor_indexing"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ OpName %main "main"
+ OpName %main_0 "main_0"
+ OpName %voidfn "voidfn"
+
+ OpName %combined "combined"
+ OpDecorate %100 DescriptorSet 0
+ OpDecorate %100 Binding 0
+ OpDecorate %100 RelaxedPrecision
+
+ ; CHECK: OpName
+ ; CHECK-NOT: OpDecorate %100
+ ; CHECK: OpDecorate %[[image_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[sampler_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[image_var]] Binding 0
+ ; CHECK: OpDecorate %[[sampler_var]] Binding 0
+ ; CHECK: OpDecorate %[[image_var:\d+]] RelaxedPrecision
+ ; CHECK: OpDecorate %[[sampler_var:\d+]] RelaxedPrecision
+
+ ; CHECK: %10 = OpTypeImage %
+ ; CHECK: %[[image_ptr_ty:\w+]] = OpTypePointer UniformConstant %10
+ ; CHECK: %[[sampler_ty:\d+]] = OpTypeSampler
+ ; CHECK: %[[sampler_ptr_ty:\w+]] = OpTypePointer UniformConstant %[[sampler_ty]]
+
+ ; The combined image variable is replaced by an image variable and a sampler variable.
+
+ ; CHECK-NOT: %100 = OpVariable
+ ; CHECK-NOT: OpVariable _ptr_UniformConstant_11
+ ; CHECK-DAG: %[[sampler_var]] = OpVariable %[[sampler_ptr_ty]] UniformConstant
+ ; CHECK-DAG: %[[image_var]] = OpVariable %[[image_ptr_ty]] UniformConstant
+ ; CHECK: = OpFunction
+
+ ; The load of the combined image+sampler is replaced by a two loads, then
+ ; a combination operation.
+ ; CHECK: %[[im:\d+]] = OpLoad %10 %[[image_var]]
+ ; CHECK: %[[s:\d+]] = OpLoad %[[sampler_ty]] %[[sampler_var]]
+ ; CHECK: %combined = OpSampledImage %11 %[[im]] %[[s]]
+
+ %bool = OpTypeBool ; location marker
+ %float = OpTypeFloat 32
+ %uint = OpTypeInt 32 0
+ %int = OpTypeInt 32 1
+ %uint_0 = OpConstant %uint 0
+ %uint_1 = OpConstant %uint 1
+ %uint_3 = OpConstant %uint 3
+ %float_0 = OpConstant %float 0
+ %v2float = OpTypeVector %float 2
+ %v3float = OpTypeVector %float 3
+ %v4float = OpTypeVector %float 4
+ %13 = OpConstantNull %v2float
+ %14 = OpConstantNull %v3float
+ %15 = OpConstantNull %v4float
+ %void = OpTypeVoid
+ %voidfn = OpTypeFunction %void
+ %10 = OpTypeImage %float 2D 0 1 0 1 Unknown
+ %11 = OpTypeSampledImage %10
+%_ptr_UniformConstant_11 = OpTypePointer UniformConstant %11
+
+ %100 = OpVariable %_ptr_UniformConstant_11 UniformConstant
+ %main = OpFunction %void None %voidfn
+ %main_0 = OpLabel
+ %combined = OpLoad %11 %100
+
+ ; Uses of the combined image sampler are preserved.
+ ; CHECK: OpCopyObject %11 %combined
+
+ %7 = OpCopyObject %11 %combined
+ OpReturn
+ OpFunctionEnd
diff --git a/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_RelaxedPrecisionOnVarCopied_20.spvasm b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_RelaxedPrecisionOnVarCopied_20.spvasm
new file mode 100644
index 0000000..c36fc49
--- /dev/null
+++ b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_RelaxedPrecisionOnVarCopied_20.spvasm
@@ -0,0 +1,74 @@
+ OpCapability Shader
+ OpCapability RuntimeDescriptorArray
+ OpExtension "SPV_EXT_descriptor_indexing"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ OpName %main "main"
+ OpName %main_0 "main_0"
+ OpName %voidfn "voidfn"
+
+ OpName %combined "combined"
+ OpDecorate %100 DescriptorSet 0
+ OpDecorate %100 Binding 0
+ OpDecorate %100 RelaxedPrecision
+
+ ; CHECK: OpName
+ ; CHECK-NOT: OpDecorate %100
+ ; CHECK: OpDecorate %[[image_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[sampler_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[image_var]] Binding 0
+ ; CHECK: OpDecorate %[[sampler_var]] Binding 0
+ ; CHECK: OpDecorate %[[image_var:\d+]] RelaxedPrecision
+ ; CHECK: OpDecorate %[[sampler_var:\d+]] RelaxedPrecision
+
+ ; CHECK: %10 = OpTypeImage %
+ ; CHECK: %[[image_ptr_ty:\w+]] = OpTypePointer UniformConstant %10
+ ; CHECK: %[[sampler_ty:\d+]] = OpTypeSampler
+ ; CHECK: %[[sampler_ptr_ty:\w+]] = OpTypePointer UniformConstant %[[sampler_ty]]
+
+ ; The combined image variable is replaced by an image variable and a sampler variable.
+
+ ; CHECK-NOT: %100 = OpVariable
+ ; CHECK-NOT: OpVariable _ptr_UniformConstant_11
+ ; CHECK-DAG: %[[sampler_var]] = OpVariable %[[sampler_ptr_ty]] UniformConstant
+ ; CHECK-DAG: %[[image_var]] = OpVariable %[[image_ptr_ty]] UniformConstant
+ ; CHECK: = OpFunction
+
+ ; The load of the combined image+sampler is replaced by a two loads, then
+ ; a combination operation.
+ ; CHECK: %[[im:\d+]] = OpLoad %10 %[[image_var]]
+ ; CHECK: %[[s:\d+]] = OpLoad %[[sampler_ty]] %[[sampler_var]]
+ ; CHECK: %combined = OpSampledImage %11 %[[im]] %[[s]]
+
+ %bool = OpTypeBool ; location marker
+ %float = OpTypeFloat 32
+ %uint = OpTypeInt 32 0
+ %int = OpTypeInt 32 1
+ %uint_0 = OpConstant %uint 0
+ %uint_1 = OpConstant %uint 1
+ %uint_3 = OpConstant %uint 3
+ %float_0 = OpConstant %float 0
+ %v2float = OpTypeVector %float 2
+ %v3float = OpTypeVector %float 3
+ %v4float = OpTypeVector %float 4
+ %13 = OpConstantNull %v2float
+ %14 = OpConstantNull %v3float
+ %15 = OpConstantNull %v4float
+ %void = OpTypeVoid
+ %voidfn = OpTypeFunction %void
+ %10 = OpTypeImage %int Cube 0 1 0 1 Unknown
+ %11 = OpTypeSampledImage %10
+%_ptr_UniformConstant_11 = OpTypePointer UniformConstant %11
+
+ %100 = OpVariable %_ptr_UniformConstant_11 UniformConstant
+ %main = OpFunction %void None %voidfn
+ %main_0 = OpLabel
+ %combined = OpLoad %11 %100
+
+ ; Uses of the combined image sampler are preserved.
+ ; CHECK: OpCopyObject %11 %combined
+
+ %7 = OpCopyObject %11 %combined
+ OpReturn
+ OpFunctionEnd
diff --git a/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_RelaxedPrecisionOnVarCopied_21.spvasm b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_RelaxedPrecisionOnVarCopied_21.spvasm
new file mode 100644
index 0000000..b019ffa
--- /dev/null
+++ b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_RelaxedPrecisionOnVarCopied_21.spvasm
@@ -0,0 +1,74 @@
+ OpCapability Shader
+ OpCapability RuntimeDescriptorArray
+ OpExtension "SPV_EXT_descriptor_indexing"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ OpName %main "main"
+ OpName %main_0 "main_0"
+ OpName %voidfn "voidfn"
+
+ OpName %combined "combined"
+ OpDecorate %100 DescriptorSet 0
+ OpDecorate %100 Binding 0
+ OpDecorate %100 RelaxedPrecision
+
+ ; CHECK: OpName
+ ; CHECK-NOT: OpDecorate %100
+ ; CHECK: OpDecorate %[[image_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[sampler_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[image_var]] Binding 0
+ ; CHECK: OpDecorate %[[sampler_var]] Binding 0
+ ; CHECK: OpDecorate %[[image_var:\d+]] RelaxedPrecision
+ ; CHECK: OpDecorate %[[sampler_var:\d+]] RelaxedPrecision
+
+ ; CHECK: %10 = OpTypeImage %
+ ; CHECK: %[[image_ptr_ty:\w+]] = OpTypePointer UniformConstant %10
+ ; CHECK: %[[sampler_ty:\d+]] = OpTypeSampler
+ ; CHECK: %[[sampler_ptr_ty:\w+]] = OpTypePointer UniformConstant %[[sampler_ty]]
+
+ ; The combined image variable is replaced by an image variable and a sampler variable.
+
+ ; CHECK-NOT: %100 = OpVariable
+ ; CHECK-NOT: OpVariable _ptr_UniformConstant_11
+ ; CHECK-DAG: %[[sampler_var]] = OpVariable %[[sampler_ptr_ty]] UniformConstant
+ ; CHECK-DAG: %[[image_var]] = OpVariable %[[image_ptr_ty]] UniformConstant
+ ; CHECK: = OpFunction
+
+ ; The load of the combined image+sampler is replaced by a two loads, then
+ ; a combination operation.
+ ; CHECK: %[[im:\d+]] = OpLoad %10 %[[image_var]]
+ ; CHECK: %[[s:\d+]] = OpLoad %[[sampler_ty]] %[[sampler_var]]
+ ; CHECK: %combined = OpSampledImage %11 %[[im]] %[[s]]
+
+ %bool = OpTypeBool ; location marker
+ %float = OpTypeFloat 32
+ %uint = OpTypeInt 32 0
+ %int = OpTypeInt 32 1
+ %uint_0 = OpConstant %uint 0
+ %uint_1 = OpConstant %uint 1
+ %uint_3 = OpConstant %uint 3
+ %float_0 = OpConstant %float 0
+ %v2float = OpTypeVector %float 2
+ %v3float = OpTypeVector %float 3
+ %v4float = OpTypeVector %float 4
+ %13 = OpConstantNull %v2float
+ %14 = OpConstantNull %v3float
+ %15 = OpConstantNull %v4float
+ %void = OpTypeVoid
+ %voidfn = OpTypeFunction %void
+ %10 = OpTypeImage %int Cube 1 1 0 1 Unknown
+ %11 = OpTypeSampledImage %10
+%_ptr_UniformConstant_11 = OpTypePointer UniformConstant %11
+
+ %100 = OpVariable %_ptr_UniformConstant_11 UniformConstant
+ %main = OpFunction %void None %voidfn
+ %main_0 = OpLabel
+ %combined = OpLoad %11 %100
+
+ ; Uses of the combined image sampler are preserved.
+ ; CHECK: OpCopyObject %11 %combined
+
+ %7 = OpCopyObject %11 %combined
+ OpReturn
+ OpFunctionEnd
diff --git a/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_RelaxedPrecisionOnVarCopied_22.spvasm b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_RelaxedPrecisionOnVarCopied_22.spvasm
new file mode 100644
index 0000000..5335535
--- /dev/null
+++ b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_RelaxedPrecisionOnVarCopied_22.spvasm
@@ -0,0 +1,74 @@
+ OpCapability Shader
+ OpCapability RuntimeDescriptorArray
+ OpExtension "SPV_EXT_descriptor_indexing"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ OpName %main "main"
+ OpName %main_0 "main_0"
+ OpName %voidfn "voidfn"
+
+ OpName %combined "combined"
+ OpDecorate %100 DescriptorSet 0
+ OpDecorate %100 Binding 0
+ OpDecorate %100 RelaxedPrecision
+
+ ; CHECK: OpName
+ ; CHECK-NOT: OpDecorate %100
+ ; CHECK: OpDecorate %[[image_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[sampler_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[image_var]] Binding 0
+ ; CHECK: OpDecorate %[[sampler_var]] Binding 0
+ ; CHECK: OpDecorate %[[image_var:\d+]] RelaxedPrecision
+ ; CHECK: OpDecorate %[[sampler_var:\d+]] RelaxedPrecision
+
+ ; CHECK: %10 = OpTypeImage %
+ ; CHECK: %[[image_ptr_ty:\w+]] = OpTypePointer UniformConstant %10
+ ; CHECK: %[[sampler_ty:\d+]] = OpTypeSampler
+ ; CHECK: %[[sampler_ptr_ty:\w+]] = OpTypePointer UniformConstant %[[sampler_ty]]
+
+ ; The combined image variable is replaced by an image variable and a sampler variable.
+
+ ; CHECK-NOT: %100 = OpVariable
+ ; CHECK-NOT: OpVariable _ptr_UniformConstant_11
+ ; CHECK-DAG: %[[sampler_var]] = OpVariable %[[sampler_ptr_ty]] UniformConstant
+ ; CHECK-DAG: %[[image_var]] = OpVariable %[[image_ptr_ty]] UniformConstant
+ ; CHECK: = OpFunction
+
+ ; The load of the combined image+sampler is replaced by a two loads, then
+ ; a combination operation.
+ ; CHECK: %[[im:\d+]] = OpLoad %10 %[[image_var]]
+ ; CHECK: %[[s:\d+]] = OpLoad %[[sampler_ty]] %[[sampler_var]]
+ ; CHECK: %combined = OpSampledImage %11 %[[im]] %[[s]]
+
+ %bool = OpTypeBool ; location marker
+ %float = OpTypeFloat 32
+ %uint = OpTypeInt 32 0
+ %int = OpTypeInt 32 1
+ %uint_0 = OpConstant %uint 0
+ %uint_1 = OpConstant %uint 1
+ %uint_3 = OpConstant %uint 3
+ %float_0 = OpConstant %float 0
+ %v2float = OpTypeVector %float 2
+ %v3float = OpTypeVector %float 3
+ %v4float = OpTypeVector %float 4
+ %13 = OpConstantNull %v2float
+ %14 = OpConstantNull %v3float
+ %15 = OpConstantNull %v4float
+ %void = OpTypeVoid
+ %voidfn = OpTypeFunction %void
+ %10 = OpTypeImage %uint 2D 0 0 0 1 Unknown
+ %11 = OpTypeSampledImage %10
+%_ptr_UniformConstant_11 = OpTypePointer UniformConstant %11
+
+ %100 = OpVariable %_ptr_UniformConstant_11 UniformConstant
+ %main = OpFunction %void None %voidfn
+ %main_0 = OpLabel
+ %combined = OpLoad %11 %100
+
+ ; Uses of the combined image sampler are preserved.
+ ; CHECK: OpCopyObject %11 %combined
+
+ %7 = OpCopyObject %11 %combined
+ OpReturn
+ OpFunctionEnd
diff --git a/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_RelaxedPrecisionOnVarCopied_23.spvasm b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_RelaxedPrecisionOnVarCopied_23.spvasm
new file mode 100644
index 0000000..7cae0da
--- /dev/null
+++ b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_RelaxedPrecisionOnVarCopied_23.spvasm
@@ -0,0 +1,74 @@
+ OpCapability Shader
+ OpCapability RuntimeDescriptorArray
+ OpExtension "SPV_EXT_descriptor_indexing"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ OpName %main "main"
+ OpName %main_0 "main_0"
+ OpName %voidfn "voidfn"
+
+ OpName %combined "combined"
+ OpDecorate %100 DescriptorSet 0
+ OpDecorate %100 Binding 0
+ OpDecorate %100 RelaxedPrecision
+
+ ; CHECK: OpName
+ ; CHECK-NOT: OpDecorate %100
+ ; CHECK: OpDecorate %[[image_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[sampler_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[image_var]] Binding 0
+ ; CHECK: OpDecorate %[[sampler_var]] Binding 0
+ ; CHECK: OpDecorate %[[image_var:\d+]] RelaxedPrecision
+ ; CHECK: OpDecorate %[[sampler_var:\d+]] RelaxedPrecision
+
+ ; CHECK: %10 = OpTypeImage %
+ ; CHECK: %[[image_ptr_ty:\w+]] = OpTypePointer UniformConstant %10
+ ; CHECK: %[[sampler_ty:\d+]] = OpTypeSampler
+ ; CHECK: %[[sampler_ptr_ty:\w+]] = OpTypePointer UniformConstant %[[sampler_ty]]
+
+ ; The combined image variable is replaced by an image variable and a sampler variable.
+
+ ; CHECK-NOT: %100 = OpVariable
+ ; CHECK-NOT: OpVariable _ptr_UniformConstant_11
+ ; CHECK-DAG: %[[sampler_var]] = OpVariable %[[sampler_ptr_ty]] UniformConstant
+ ; CHECK-DAG: %[[image_var]] = OpVariable %[[image_ptr_ty]] UniformConstant
+ ; CHECK: = OpFunction
+
+ ; The load of the combined image+sampler is replaced by a two loads, then
+ ; a combination operation.
+ ; CHECK: %[[im:\d+]] = OpLoad %10 %[[image_var]]
+ ; CHECK: %[[s:\d+]] = OpLoad %[[sampler_ty]] %[[sampler_var]]
+ ; CHECK: %combined = OpSampledImage %11 %[[im]] %[[s]]
+
+ %bool = OpTypeBool ; location marker
+ %float = OpTypeFloat 32
+ %uint = OpTypeInt 32 0
+ %int = OpTypeInt 32 1
+ %uint_0 = OpConstant %uint 0
+ %uint_1 = OpConstant %uint 1
+ %uint_3 = OpConstant %uint 3
+ %float_0 = OpConstant %float 0
+ %v2float = OpTypeVector %float 2
+ %v3float = OpTypeVector %float 3
+ %v4float = OpTypeVector %float 4
+ %13 = OpConstantNull %v2float
+ %14 = OpConstantNull %v3float
+ %15 = OpConstantNull %v4float
+ %void = OpTypeVoid
+ %voidfn = OpTypeFunction %void
+ %10 = OpTypeImage %uint 2D 1 0 0 1 Unknown
+ %11 = OpTypeSampledImage %10
+%_ptr_UniformConstant_11 = OpTypePointer UniformConstant %11
+
+ %100 = OpVariable %_ptr_UniformConstant_11 UniformConstant
+ %main = OpFunction %void None %voidfn
+ %main_0 = OpLabel
+ %combined = OpLoad %11 %100
+
+ ; Uses of the combined image sampler are preserved.
+ ; CHECK: OpCopyObject %11 %combined
+
+ %7 = OpCopyObject %11 %combined
+ OpReturn
+ OpFunctionEnd
diff --git a/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_RelaxedPrecisionOnVarCopied_24.spvasm b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_RelaxedPrecisionOnVarCopied_24.spvasm
new file mode 100644
index 0000000..f02a7b4
--- /dev/null
+++ b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_RelaxedPrecisionOnVarCopied_24.spvasm
@@ -0,0 +1,74 @@
+ OpCapability Shader
+ OpCapability RuntimeDescriptorArray
+ OpExtension "SPV_EXT_descriptor_indexing"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ OpName %main "main"
+ OpName %main_0 "main_0"
+ OpName %voidfn "voidfn"
+
+ OpName %combined "combined"
+ OpDecorate %100 DescriptorSet 0
+ OpDecorate %100 Binding 0
+ OpDecorate %100 RelaxedPrecision
+
+ ; CHECK: OpName
+ ; CHECK-NOT: OpDecorate %100
+ ; CHECK: OpDecorate %[[image_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[sampler_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[image_var]] Binding 0
+ ; CHECK: OpDecorate %[[sampler_var]] Binding 0
+ ; CHECK: OpDecorate %[[image_var:\d+]] RelaxedPrecision
+ ; CHECK: OpDecorate %[[sampler_var:\d+]] RelaxedPrecision
+
+ ; CHECK: %10 = OpTypeImage %
+ ; CHECK: %[[image_ptr_ty:\w+]] = OpTypePointer UniformConstant %10
+ ; CHECK: %[[sampler_ty:\d+]] = OpTypeSampler
+ ; CHECK: %[[sampler_ptr_ty:\w+]] = OpTypePointer UniformConstant %[[sampler_ty]]
+
+ ; The combined image variable is replaced by an image variable and a sampler variable.
+
+ ; CHECK-NOT: %100 = OpVariable
+ ; CHECK-NOT: OpVariable _ptr_UniformConstant_11
+ ; CHECK-DAG: %[[sampler_var]] = OpVariable %[[sampler_ptr_ty]] UniformConstant
+ ; CHECK-DAG: %[[image_var]] = OpVariable %[[image_ptr_ty]] UniformConstant
+ ; CHECK: = OpFunction
+
+ ; The load of the combined image+sampler is replaced by a two loads, then
+ ; a combination operation.
+ ; CHECK: %[[im:\d+]] = OpLoad %10 %[[image_var]]
+ ; CHECK: %[[s:\d+]] = OpLoad %[[sampler_ty]] %[[sampler_var]]
+ ; CHECK: %combined = OpSampledImage %11 %[[im]] %[[s]]
+
+ %bool = OpTypeBool ; location marker
+ %float = OpTypeFloat 32
+ %uint = OpTypeInt 32 0
+ %int = OpTypeInt 32 1
+ %uint_0 = OpConstant %uint 0
+ %uint_1 = OpConstant %uint 1
+ %uint_3 = OpConstant %uint 3
+ %float_0 = OpConstant %float 0
+ %v2float = OpTypeVector %float 2
+ %v3float = OpTypeVector %float 3
+ %v4float = OpTypeVector %float 4
+ %13 = OpConstantNull %v2float
+ %14 = OpConstantNull %v3float
+ %15 = OpConstantNull %v4float
+ %void = OpTypeVoid
+ %voidfn = OpTypeFunction %void
+ %10 = OpTypeImage %uint 2D 0 1 0 1 Unknown
+ %11 = OpTypeSampledImage %10
+%_ptr_UniformConstant_11 = OpTypePointer UniformConstant %11
+
+ %100 = OpVariable %_ptr_UniformConstant_11 UniformConstant
+ %main = OpFunction %void None %voidfn
+ %main_0 = OpLabel
+ %combined = OpLoad %11 %100
+
+ ; Uses of the combined image sampler are preserved.
+ ; CHECK: OpCopyObject %11 %combined
+
+ %7 = OpCopyObject %11 %combined
+ OpReturn
+ OpFunctionEnd
diff --git a/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_RelaxedPrecisionOnVarCopied_25.spvasm b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_RelaxedPrecisionOnVarCopied_25.spvasm
new file mode 100644
index 0000000..1ef65af
--- /dev/null
+++ b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_RelaxedPrecisionOnVarCopied_25.spvasm
@@ -0,0 +1,74 @@
+ OpCapability Shader
+ OpCapability RuntimeDescriptorArray
+ OpExtension "SPV_EXT_descriptor_indexing"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ OpName %main "main"
+ OpName %main_0 "main_0"
+ OpName %voidfn "voidfn"
+
+ OpName %combined "combined"
+ OpDecorate %100 DescriptorSet 0
+ OpDecorate %100 Binding 0
+ OpDecorate %100 RelaxedPrecision
+
+ ; CHECK: OpName
+ ; CHECK-NOT: OpDecorate %100
+ ; CHECK: OpDecorate %[[image_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[sampler_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[image_var]] Binding 0
+ ; CHECK: OpDecorate %[[sampler_var]] Binding 0
+ ; CHECK: OpDecorate %[[image_var:\d+]] RelaxedPrecision
+ ; CHECK: OpDecorate %[[sampler_var:\d+]] RelaxedPrecision
+
+ ; CHECK: %10 = OpTypeImage %
+ ; CHECK: %[[image_ptr_ty:\w+]] = OpTypePointer UniformConstant %10
+ ; CHECK: %[[sampler_ty:\d+]] = OpTypeSampler
+ ; CHECK: %[[sampler_ptr_ty:\w+]] = OpTypePointer UniformConstant %[[sampler_ty]]
+
+ ; The combined image variable is replaced by an image variable and a sampler variable.
+
+ ; CHECK-NOT: %100 = OpVariable
+ ; CHECK-NOT: OpVariable _ptr_UniformConstant_11
+ ; CHECK-DAG: %[[sampler_var]] = OpVariable %[[sampler_ptr_ty]] UniformConstant
+ ; CHECK-DAG: %[[image_var]] = OpVariable %[[image_ptr_ty]] UniformConstant
+ ; CHECK: = OpFunction
+
+ ; The load of the combined image+sampler is replaced by a two loads, then
+ ; a combination operation.
+ ; CHECK: %[[im:\d+]] = OpLoad %10 %[[image_var]]
+ ; CHECK: %[[s:\d+]] = OpLoad %[[sampler_ty]] %[[sampler_var]]
+ ; CHECK: %combined = OpSampledImage %11 %[[im]] %[[s]]
+
+ %bool = OpTypeBool ; location marker
+ %float = OpTypeFloat 32
+ %uint = OpTypeInt 32 0
+ %int = OpTypeInt 32 1
+ %uint_0 = OpConstant %uint 0
+ %uint_1 = OpConstant %uint 1
+ %uint_3 = OpConstant %uint 3
+ %float_0 = OpConstant %float 0
+ %v2float = OpTypeVector %float 2
+ %v3float = OpTypeVector %float 3
+ %v4float = OpTypeVector %float 4
+ %13 = OpConstantNull %v2float
+ %14 = OpConstantNull %v3float
+ %15 = OpConstantNull %v4float
+ %void = OpTypeVoid
+ %voidfn = OpTypeFunction %void
+ %10 = OpTypeImage %uint 2D 1 1 0 1 Unknown
+ %11 = OpTypeSampledImage %10
+%_ptr_UniformConstant_11 = OpTypePointer UniformConstant %11
+
+ %100 = OpVariable %_ptr_UniformConstant_11 UniformConstant
+ %main = OpFunction %void None %voidfn
+ %main_0 = OpLabel
+ %combined = OpLoad %11 %100
+
+ ; Uses of the combined image sampler are preserved.
+ ; CHECK: OpCopyObject %11 %combined
+
+ %7 = OpCopyObject %11 %combined
+ OpReturn
+ OpFunctionEnd
diff --git a/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_RelaxedPrecisionOnVarCopied_26.spvasm b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_RelaxedPrecisionOnVarCopied_26.spvasm
new file mode 100644
index 0000000..62eb1e2
--- /dev/null
+++ b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_RelaxedPrecisionOnVarCopied_26.spvasm
@@ -0,0 +1,74 @@
+ OpCapability Shader
+ OpCapability RuntimeDescriptorArray
+ OpExtension "SPV_EXT_descriptor_indexing"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ OpName %main "main"
+ OpName %main_0 "main_0"
+ OpName %voidfn "voidfn"
+
+ OpName %combined "combined"
+ OpDecorate %100 DescriptorSet 0
+ OpDecorate %100 Binding 0
+ OpDecorate %100 RelaxedPrecision
+
+ ; CHECK: OpName
+ ; CHECK-NOT: OpDecorate %100
+ ; CHECK: OpDecorate %[[image_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[sampler_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[image_var]] Binding 0
+ ; CHECK: OpDecorate %[[sampler_var]] Binding 0
+ ; CHECK: OpDecorate %[[image_var:\d+]] RelaxedPrecision
+ ; CHECK: OpDecorate %[[sampler_var:\d+]] RelaxedPrecision
+
+ ; CHECK: %10 = OpTypeImage %
+ ; CHECK: %[[image_ptr_ty:\w+]] = OpTypePointer UniformConstant %10
+ ; CHECK: %[[sampler_ty:\d+]] = OpTypeSampler
+ ; CHECK: %[[sampler_ptr_ty:\w+]] = OpTypePointer UniformConstant %[[sampler_ty]]
+
+ ; The combined image variable is replaced by an image variable and a sampler variable.
+
+ ; CHECK-NOT: %100 = OpVariable
+ ; CHECK-NOT: OpVariable _ptr_UniformConstant_11
+ ; CHECK-DAG: %[[sampler_var]] = OpVariable %[[sampler_ptr_ty]] UniformConstant
+ ; CHECK-DAG: %[[image_var]] = OpVariable %[[image_ptr_ty]] UniformConstant
+ ; CHECK: = OpFunction
+
+ ; The load of the combined image+sampler is replaced by a two loads, then
+ ; a combination operation.
+ ; CHECK: %[[im:\d+]] = OpLoad %10 %[[image_var]]
+ ; CHECK: %[[s:\d+]] = OpLoad %[[sampler_ty]] %[[sampler_var]]
+ ; CHECK: %combined = OpSampledImage %11 %[[im]] %[[s]]
+
+ %bool = OpTypeBool ; location marker
+ %float = OpTypeFloat 32
+ %uint = OpTypeInt 32 0
+ %int = OpTypeInt 32 1
+ %uint_0 = OpConstant %uint 0
+ %uint_1 = OpConstant %uint 1
+ %uint_3 = OpConstant %uint 3
+ %float_0 = OpConstant %float 0
+ %v2float = OpTypeVector %float 2
+ %v3float = OpTypeVector %float 3
+ %v4float = OpTypeVector %float 4
+ %13 = OpConstantNull %v2float
+ %14 = OpConstantNull %v3float
+ %15 = OpConstantNull %v4float
+ %void = OpTypeVoid
+ %voidfn = OpTypeFunction %void
+ %10 = OpTypeImage %uint 2D 0 0 1 1 Unknown
+ %11 = OpTypeSampledImage %10
+%_ptr_UniformConstant_11 = OpTypePointer UniformConstant %11
+
+ %100 = OpVariable %_ptr_UniformConstant_11 UniformConstant
+ %main = OpFunction %void None %voidfn
+ %main_0 = OpLabel
+ %combined = OpLoad %11 %100
+
+ ; Uses of the combined image sampler are preserved.
+ ; CHECK: OpCopyObject %11 %combined
+
+ %7 = OpCopyObject %11 %combined
+ OpReturn
+ OpFunctionEnd
diff --git a/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_RelaxedPrecisionOnVarCopied_28.spvasm b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_RelaxedPrecisionOnVarCopied_28.spvasm
new file mode 100644
index 0000000..13d560a
--- /dev/null
+++ b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_RelaxedPrecisionOnVarCopied_28.spvasm
@@ -0,0 +1,74 @@
+ OpCapability Shader
+ OpCapability RuntimeDescriptorArray
+ OpExtension "SPV_EXT_descriptor_indexing"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ OpName %main "main"
+ OpName %main_0 "main_0"
+ OpName %voidfn "voidfn"
+
+ OpName %combined "combined"
+ OpDecorate %100 DescriptorSet 0
+ OpDecorate %100 Binding 0
+ OpDecorate %100 RelaxedPrecision
+
+ ; CHECK: OpName
+ ; CHECK-NOT: OpDecorate %100
+ ; CHECK: OpDecorate %[[image_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[sampler_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[image_var]] Binding 0
+ ; CHECK: OpDecorate %[[sampler_var]] Binding 0
+ ; CHECK: OpDecorate %[[image_var:\d+]] RelaxedPrecision
+ ; CHECK: OpDecorate %[[sampler_var:\d+]] RelaxedPrecision
+
+ ; CHECK: %10 = OpTypeImage %
+ ; CHECK: %[[image_ptr_ty:\w+]] = OpTypePointer UniformConstant %10
+ ; CHECK: %[[sampler_ty:\d+]] = OpTypeSampler
+ ; CHECK: %[[sampler_ptr_ty:\w+]] = OpTypePointer UniformConstant %[[sampler_ty]]
+
+ ; The combined image variable is replaced by an image variable and a sampler variable.
+
+ ; CHECK-NOT: %100 = OpVariable
+ ; CHECK-NOT: OpVariable _ptr_UniformConstant_11
+ ; CHECK-DAG: %[[sampler_var]] = OpVariable %[[sampler_ptr_ty]] UniformConstant
+ ; CHECK-DAG: %[[image_var]] = OpVariable %[[image_ptr_ty]] UniformConstant
+ ; CHECK: = OpFunction
+
+ ; The load of the combined image+sampler is replaced by a two loads, then
+ ; a combination operation.
+ ; CHECK: %[[im:\d+]] = OpLoad %10 %[[image_var]]
+ ; CHECK: %[[s:\d+]] = OpLoad %[[sampler_ty]] %[[sampler_var]]
+ ; CHECK: %combined = OpSampledImage %11 %[[im]] %[[s]]
+
+ %bool = OpTypeBool ; location marker
+ %float = OpTypeFloat 32
+ %uint = OpTypeInt 32 0
+ %int = OpTypeInt 32 1
+ %uint_0 = OpConstant %uint 0
+ %uint_1 = OpConstant %uint 1
+ %uint_3 = OpConstant %uint 3
+ %float_0 = OpConstant %float 0
+ %v2float = OpTypeVector %float 2
+ %v3float = OpTypeVector %float 3
+ %v4float = OpTypeVector %float 4
+ %13 = OpConstantNull %v2float
+ %14 = OpConstantNull %v3float
+ %15 = OpConstantNull %v4float
+ %void = OpTypeVoid
+ %voidfn = OpTypeFunction %void
+ %10 = OpTypeImage %uint 3D 0 0 0 1 Unknown
+ %11 = OpTypeSampledImage %10
+%_ptr_UniformConstant_11 = OpTypePointer UniformConstant %11
+
+ %100 = OpVariable %_ptr_UniformConstant_11 UniformConstant
+ %main = OpFunction %void None %voidfn
+ %main_0 = OpLabel
+ %combined = OpLoad %11 %100
+
+ ; Uses of the combined image sampler are preserved.
+ ; CHECK: OpCopyObject %11 %combined
+
+ %7 = OpCopyObject %11 %combined
+ OpReturn
+ OpFunctionEnd
diff --git a/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_RelaxedPrecisionOnVarCopied_29.spvasm b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_RelaxedPrecisionOnVarCopied_29.spvasm
new file mode 100644
index 0000000..cec1784
--- /dev/null
+++ b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_RelaxedPrecisionOnVarCopied_29.spvasm
@@ -0,0 +1,74 @@
+ OpCapability Shader
+ OpCapability RuntimeDescriptorArray
+ OpExtension "SPV_EXT_descriptor_indexing"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ OpName %main "main"
+ OpName %main_0 "main_0"
+ OpName %voidfn "voidfn"
+
+ OpName %combined "combined"
+ OpDecorate %100 DescriptorSet 0
+ OpDecorate %100 Binding 0
+ OpDecorate %100 RelaxedPrecision
+
+ ; CHECK: OpName
+ ; CHECK-NOT: OpDecorate %100
+ ; CHECK: OpDecorate %[[image_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[sampler_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[image_var]] Binding 0
+ ; CHECK: OpDecorate %[[sampler_var]] Binding 0
+ ; CHECK: OpDecorate %[[image_var:\d+]] RelaxedPrecision
+ ; CHECK: OpDecorate %[[sampler_var:\d+]] RelaxedPrecision
+
+ ; CHECK: %10 = OpTypeImage %
+ ; CHECK: %[[image_ptr_ty:\w+]] = OpTypePointer UniformConstant %10
+ ; CHECK: %[[sampler_ty:\d+]] = OpTypeSampler
+ ; CHECK: %[[sampler_ptr_ty:\w+]] = OpTypePointer UniformConstant %[[sampler_ty]]
+
+ ; The combined image variable is replaced by an image variable and a sampler variable.
+
+ ; CHECK-NOT: %100 = OpVariable
+ ; CHECK-NOT: OpVariable _ptr_UniformConstant_11
+ ; CHECK-DAG: %[[sampler_var]] = OpVariable %[[sampler_ptr_ty]] UniformConstant
+ ; CHECK-DAG: %[[image_var]] = OpVariable %[[image_ptr_ty]] UniformConstant
+ ; CHECK: = OpFunction
+
+ ; The load of the combined image+sampler is replaced by a two loads, then
+ ; a combination operation.
+ ; CHECK: %[[im:\d+]] = OpLoad %10 %[[image_var]]
+ ; CHECK: %[[s:\d+]] = OpLoad %[[sampler_ty]] %[[sampler_var]]
+ ; CHECK: %combined = OpSampledImage %11 %[[im]] %[[s]]
+
+ %bool = OpTypeBool ; location marker
+ %float = OpTypeFloat 32
+ %uint = OpTypeInt 32 0
+ %int = OpTypeInt 32 1
+ %uint_0 = OpConstant %uint 0
+ %uint_1 = OpConstant %uint 1
+ %uint_3 = OpConstant %uint 3
+ %float_0 = OpConstant %float 0
+ %v2float = OpTypeVector %float 2
+ %v3float = OpTypeVector %float 3
+ %v4float = OpTypeVector %float 4
+ %13 = OpConstantNull %v2float
+ %14 = OpConstantNull %v3float
+ %15 = OpConstantNull %v4float
+ %void = OpTypeVoid
+ %voidfn = OpTypeFunction %void
+ %10 = OpTypeImage %uint Cube 0 0 0 1 Unknown
+ %11 = OpTypeSampledImage %10
+%_ptr_UniformConstant_11 = OpTypePointer UniformConstant %11
+
+ %100 = OpVariable %_ptr_UniformConstant_11 UniformConstant
+ %main = OpFunction %void None %voidfn
+ %main_0 = OpLabel
+ %combined = OpLoad %11 %100
+
+ ; Uses of the combined image sampler are preserved.
+ ; CHECK: OpCopyObject %11 %combined
+
+ %7 = OpCopyObject %11 %combined
+ OpReturn
+ OpFunctionEnd
diff --git a/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_RelaxedPrecisionOnVarCopied_3.spvasm b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_RelaxedPrecisionOnVarCopied_3.spvasm
new file mode 100644
index 0000000..f954c6d
--- /dev/null
+++ b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_RelaxedPrecisionOnVarCopied_3.spvasm
@@ -0,0 +1,74 @@
+ OpCapability Shader
+ OpCapability RuntimeDescriptorArray
+ OpExtension "SPV_EXT_descriptor_indexing"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ OpName %main "main"
+ OpName %main_0 "main_0"
+ OpName %voidfn "voidfn"
+
+ OpName %combined "combined"
+ OpDecorate %100 DescriptorSet 0
+ OpDecorate %100 Binding 0
+ OpDecorate %100 RelaxedPrecision
+
+ ; CHECK: OpName
+ ; CHECK-NOT: OpDecorate %100
+ ; CHECK: OpDecorate %[[image_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[sampler_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[image_var]] Binding 0
+ ; CHECK: OpDecorate %[[sampler_var]] Binding 0
+ ; CHECK: OpDecorate %[[image_var:\d+]] RelaxedPrecision
+ ; CHECK: OpDecorate %[[sampler_var:\d+]] RelaxedPrecision
+
+ ; CHECK: %10 = OpTypeImage %
+ ; CHECK: %[[image_ptr_ty:\w+]] = OpTypePointer UniformConstant %10
+ ; CHECK: %[[sampler_ty:\d+]] = OpTypeSampler
+ ; CHECK: %[[sampler_ptr_ty:\w+]] = OpTypePointer UniformConstant %[[sampler_ty]]
+
+ ; The combined image variable is replaced by an image variable and a sampler variable.
+
+ ; CHECK-NOT: %100 = OpVariable
+ ; CHECK-NOT: OpVariable _ptr_UniformConstant_11
+ ; CHECK-DAG: %[[sampler_var]] = OpVariable %[[sampler_ptr_ty]] UniformConstant
+ ; CHECK-DAG: %[[image_var]] = OpVariable %[[image_ptr_ty]] UniformConstant
+ ; CHECK: = OpFunction
+
+ ; The load of the combined image+sampler is replaced by a two loads, then
+ ; a combination operation.
+ ; CHECK: %[[im:\d+]] = OpLoad %10 %[[image_var]]
+ ; CHECK: %[[s:\d+]] = OpLoad %[[sampler_ty]] %[[sampler_var]]
+ ; CHECK: %combined = OpSampledImage %11 %[[im]] %[[s]]
+
+ %bool = OpTypeBool ; location marker
+ %float = OpTypeFloat 32
+ %uint = OpTypeInt 32 0
+ %int = OpTypeInt 32 1
+ %uint_0 = OpConstant %uint 0
+ %uint_1 = OpConstant %uint 1
+ %uint_3 = OpConstant %uint 3
+ %float_0 = OpConstant %float 0
+ %v2float = OpTypeVector %float 2
+ %v3float = OpTypeVector %float 3
+ %v4float = OpTypeVector %float 4
+ %13 = OpConstantNull %v2float
+ %14 = OpConstantNull %v3float
+ %15 = OpConstantNull %v4float
+ %void = OpTypeVoid
+ %voidfn = OpTypeFunction %void
+ %10 = OpTypeImage %float 2D 1 1 0 1 Unknown
+ %11 = OpTypeSampledImage %10
+%_ptr_UniformConstant_11 = OpTypePointer UniformConstant %11
+
+ %100 = OpVariable %_ptr_UniformConstant_11 UniformConstant
+ %main = OpFunction %void None %voidfn
+ %main_0 = OpLabel
+ %combined = OpLoad %11 %100
+
+ ; Uses of the combined image sampler are preserved.
+ ; CHECK: OpCopyObject %11 %combined
+
+ %7 = OpCopyObject %11 %combined
+ OpReturn
+ OpFunctionEnd
diff --git a/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_RelaxedPrecisionOnVarCopied_30.spvasm b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_RelaxedPrecisionOnVarCopied_30.spvasm
new file mode 100644
index 0000000..7fab592
--- /dev/null
+++ b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_RelaxedPrecisionOnVarCopied_30.spvasm
@@ -0,0 +1,74 @@
+ OpCapability Shader
+ OpCapability RuntimeDescriptorArray
+ OpExtension "SPV_EXT_descriptor_indexing"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ OpName %main "main"
+ OpName %main_0 "main_0"
+ OpName %voidfn "voidfn"
+
+ OpName %combined "combined"
+ OpDecorate %100 DescriptorSet 0
+ OpDecorate %100 Binding 0
+ OpDecorate %100 RelaxedPrecision
+
+ ; CHECK: OpName
+ ; CHECK-NOT: OpDecorate %100
+ ; CHECK: OpDecorate %[[image_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[sampler_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[image_var]] Binding 0
+ ; CHECK: OpDecorate %[[sampler_var]] Binding 0
+ ; CHECK: OpDecorate %[[image_var:\d+]] RelaxedPrecision
+ ; CHECK: OpDecorate %[[sampler_var:\d+]] RelaxedPrecision
+
+ ; CHECK: %10 = OpTypeImage %
+ ; CHECK: %[[image_ptr_ty:\w+]] = OpTypePointer UniformConstant %10
+ ; CHECK: %[[sampler_ty:\d+]] = OpTypeSampler
+ ; CHECK: %[[sampler_ptr_ty:\w+]] = OpTypePointer UniformConstant %[[sampler_ty]]
+
+ ; The combined image variable is replaced by an image variable and a sampler variable.
+
+ ; CHECK-NOT: %100 = OpVariable
+ ; CHECK-NOT: OpVariable _ptr_UniformConstant_11
+ ; CHECK-DAG: %[[sampler_var]] = OpVariable %[[sampler_ptr_ty]] UniformConstant
+ ; CHECK-DAG: %[[image_var]] = OpVariable %[[image_ptr_ty]] UniformConstant
+ ; CHECK: = OpFunction
+
+ ; The load of the combined image+sampler is replaced by a two loads, then
+ ; a combination operation.
+ ; CHECK: %[[im:\d+]] = OpLoad %10 %[[image_var]]
+ ; CHECK: %[[s:\d+]] = OpLoad %[[sampler_ty]] %[[sampler_var]]
+ ; CHECK: %combined = OpSampledImage %11 %[[im]] %[[s]]
+
+ %bool = OpTypeBool ; location marker
+ %float = OpTypeFloat 32
+ %uint = OpTypeInt 32 0
+ %int = OpTypeInt 32 1
+ %uint_0 = OpConstant %uint 0
+ %uint_1 = OpConstant %uint 1
+ %uint_3 = OpConstant %uint 3
+ %float_0 = OpConstant %float 0
+ %v2float = OpTypeVector %float 2
+ %v3float = OpTypeVector %float 3
+ %v4float = OpTypeVector %float 4
+ %13 = OpConstantNull %v2float
+ %14 = OpConstantNull %v3float
+ %15 = OpConstantNull %v4float
+ %void = OpTypeVoid
+ %voidfn = OpTypeFunction %void
+ %10 = OpTypeImage %uint Cube 1 0 0 1 Unknown
+ %11 = OpTypeSampledImage %10
+%_ptr_UniformConstant_11 = OpTypePointer UniformConstant %11
+
+ %100 = OpVariable %_ptr_UniformConstant_11 UniformConstant
+ %main = OpFunction %void None %voidfn
+ %main_0 = OpLabel
+ %combined = OpLoad %11 %100
+
+ ; Uses of the combined image sampler are preserved.
+ ; CHECK: OpCopyObject %11 %combined
+
+ %7 = OpCopyObject %11 %combined
+ OpReturn
+ OpFunctionEnd
diff --git a/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_RelaxedPrecisionOnVarCopied_31.spvasm b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_RelaxedPrecisionOnVarCopied_31.spvasm
new file mode 100644
index 0000000..cc881bc
--- /dev/null
+++ b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_RelaxedPrecisionOnVarCopied_31.spvasm
@@ -0,0 +1,74 @@
+ OpCapability Shader
+ OpCapability RuntimeDescriptorArray
+ OpExtension "SPV_EXT_descriptor_indexing"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ OpName %main "main"
+ OpName %main_0 "main_0"
+ OpName %voidfn "voidfn"
+
+ OpName %combined "combined"
+ OpDecorate %100 DescriptorSet 0
+ OpDecorate %100 Binding 0
+ OpDecorate %100 RelaxedPrecision
+
+ ; CHECK: OpName
+ ; CHECK-NOT: OpDecorate %100
+ ; CHECK: OpDecorate %[[image_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[sampler_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[image_var]] Binding 0
+ ; CHECK: OpDecorate %[[sampler_var]] Binding 0
+ ; CHECK: OpDecorate %[[image_var:\d+]] RelaxedPrecision
+ ; CHECK: OpDecorate %[[sampler_var:\d+]] RelaxedPrecision
+
+ ; CHECK: %10 = OpTypeImage %
+ ; CHECK: %[[image_ptr_ty:\w+]] = OpTypePointer UniformConstant %10
+ ; CHECK: %[[sampler_ty:\d+]] = OpTypeSampler
+ ; CHECK: %[[sampler_ptr_ty:\w+]] = OpTypePointer UniformConstant %[[sampler_ty]]
+
+ ; The combined image variable is replaced by an image variable and a sampler variable.
+
+ ; CHECK-NOT: %100 = OpVariable
+ ; CHECK-NOT: OpVariable _ptr_UniformConstant_11
+ ; CHECK-DAG: %[[sampler_var]] = OpVariable %[[sampler_ptr_ty]] UniformConstant
+ ; CHECK-DAG: %[[image_var]] = OpVariable %[[image_ptr_ty]] UniformConstant
+ ; CHECK: = OpFunction
+
+ ; The load of the combined image+sampler is replaced by a two loads, then
+ ; a combination operation.
+ ; CHECK: %[[im:\d+]] = OpLoad %10 %[[image_var]]
+ ; CHECK: %[[s:\d+]] = OpLoad %[[sampler_ty]] %[[sampler_var]]
+ ; CHECK: %combined = OpSampledImage %11 %[[im]] %[[s]]
+
+ %bool = OpTypeBool ; location marker
+ %float = OpTypeFloat 32
+ %uint = OpTypeInt 32 0
+ %int = OpTypeInt 32 1
+ %uint_0 = OpConstant %uint 0
+ %uint_1 = OpConstant %uint 1
+ %uint_3 = OpConstant %uint 3
+ %float_0 = OpConstant %float 0
+ %v2float = OpTypeVector %float 2
+ %v3float = OpTypeVector %float 3
+ %v4float = OpTypeVector %float 4
+ %13 = OpConstantNull %v2float
+ %14 = OpConstantNull %v3float
+ %15 = OpConstantNull %v4float
+ %void = OpTypeVoid
+ %voidfn = OpTypeFunction %void
+ %10 = OpTypeImage %uint Cube 0 1 0 1 Unknown
+ %11 = OpTypeSampledImage %10
+%_ptr_UniformConstant_11 = OpTypePointer UniformConstant %11
+
+ %100 = OpVariable %_ptr_UniformConstant_11 UniformConstant
+ %main = OpFunction %void None %voidfn
+ %main_0 = OpLabel
+ %combined = OpLoad %11 %100
+
+ ; Uses of the combined image sampler are preserved.
+ ; CHECK: OpCopyObject %11 %combined
+
+ %7 = OpCopyObject %11 %combined
+ OpReturn
+ OpFunctionEnd
diff --git a/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_RelaxedPrecisionOnVarCopied_32.spvasm b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_RelaxedPrecisionOnVarCopied_32.spvasm
new file mode 100644
index 0000000..269a768
--- /dev/null
+++ b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_RelaxedPrecisionOnVarCopied_32.spvasm
@@ -0,0 +1,74 @@
+ OpCapability Shader
+ OpCapability RuntimeDescriptorArray
+ OpExtension "SPV_EXT_descriptor_indexing"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ OpName %main "main"
+ OpName %main_0 "main_0"
+ OpName %voidfn "voidfn"
+
+ OpName %combined "combined"
+ OpDecorate %100 DescriptorSet 0
+ OpDecorate %100 Binding 0
+ OpDecorate %100 RelaxedPrecision
+
+ ; CHECK: OpName
+ ; CHECK-NOT: OpDecorate %100
+ ; CHECK: OpDecorate %[[image_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[sampler_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[image_var]] Binding 0
+ ; CHECK: OpDecorate %[[sampler_var]] Binding 0
+ ; CHECK: OpDecorate %[[image_var:\d+]] RelaxedPrecision
+ ; CHECK: OpDecorate %[[sampler_var:\d+]] RelaxedPrecision
+
+ ; CHECK: %10 = OpTypeImage %
+ ; CHECK: %[[image_ptr_ty:\w+]] = OpTypePointer UniformConstant %10
+ ; CHECK: %[[sampler_ty:\d+]] = OpTypeSampler
+ ; CHECK: %[[sampler_ptr_ty:\w+]] = OpTypePointer UniformConstant %[[sampler_ty]]
+
+ ; The combined image variable is replaced by an image variable and a sampler variable.
+
+ ; CHECK-NOT: %100 = OpVariable
+ ; CHECK-NOT: OpVariable _ptr_UniformConstant_11
+ ; CHECK-DAG: %[[sampler_var]] = OpVariable %[[sampler_ptr_ty]] UniformConstant
+ ; CHECK-DAG: %[[image_var]] = OpVariable %[[image_ptr_ty]] UniformConstant
+ ; CHECK: = OpFunction
+
+ ; The load of the combined image+sampler is replaced by a two loads, then
+ ; a combination operation.
+ ; CHECK: %[[im:\d+]] = OpLoad %10 %[[image_var]]
+ ; CHECK: %[[s:\d+]] = OpLoad %[[sampler_ty]] %[[sampler_var]]
+ ; CHECK: %combined = OpSampledImage %11 %[[im]] %[[s]]
+
+ %bool = OpTypeBool ; location marker
+ %float = OpTypeFloat 32
+ %uint = OpTypeInt 32 0
+ %int = OpTypeInt 32 1
+ %uint_0 = OpConstant %uint 0
+ %uint_1 = OpConstant %uint 1
+ %uint_3 = OpConstant %uint 3
+ %float_0 = OpConstant %float 0
+ %v2float = OpTypeVector %float 2
+ %v3float = OpTypeVector %float 3
+ %v4float = OpTypeVector %float 4
+ %13 = OpConstantNull %v2float
+ %14 = OpConstantNull %v3float
+ %15 = OpConstantNull %v4float
+ %void = OpTypeVoid
+ %voidfn = OpTypeFunction %void
+ %10 = OpTypeImage %uint Cube 1 1 0 1 Unknown
+ %11 = OpTypeSampledImage %10
+%_ptr_UniformConstant_11 = OpTypePointer UniformConstant %11
+
+ %100 = OpVariable %_ptr_UniformConstant_11 UniformConstant
+ %main = OpFunction %void None %voidfn
+ %main_0 = OpLabel
+ %combined = OpLoad %11 %100
+
+ ; Uses of the combined image sampler are preserved.
+ ; CHECK: OpCopyObject %11 %combined
+
+ %7 = OpCopyObject %11 %combined
+ OpReturn
+ OpFunctionEnd
diff --git a/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_RelaxedPrecisionOnVarCopied_4.spvasm b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_RelaxedPrecisionOnVarCopied_4.spvasm
new file mode 100644
index 0000000..7f242a3
--- /dev/null
+++ b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_RelaxedPrecisionOnVarCopied_4.spvasm
@@ -0,0 +1,74 @@
+ OpCapability Shader
+ OpCapability RuntimeDescriptorArray
+ OpExtension "SPV_EXT_descriptor_indexing"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ OpName %main "main"
+ OpName %main_0 "main_0"
+ OpName %voidfn "voidfn"
+
+ OpName %combined "combined"
+ OpDecorate %100 DescriptorSet 0
+ OpDecorate %100 Binding 0
+ OpDecorate %100 RelaxedPrecision
+
+ ; CHECK: OpName
+ ; CHECK-NOT: OpDecorate %100
+ ; CHECK: OpDecorate %[[image_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[sampler_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[image_var]] Binding 0
+ ; CHECK: OpDecorate %[[sampler_var]] Binding 0
+ ; CHECK: OpDecorate %[[image_var:\d+]] RelaxedPrecision
+ ; CHECK: OpDecorate %[[sampler_var:\d+]] RelaxedPrecision
+
+ ; CHECK: %10 = OpTypeImage %
+ ; CHECK: %[[image_ptr_ty:\w+]] = OpTypePointer UniformConstant %10
+ ; CHECK: %[[sampler_ty:\d+]] = OpTypeSampler
+ ; CHECK: %[[sampler_ptr_ty:\w+]] = OpTypePointer UniformConstant %[[sampler_ty]]
+
+ ; The combined image variable is replaced by an image variable and a sampler variable.
+
+ ; CHECK-NOT: %100 = OpVariable
+ ; CHECK-NOT: OpVariable _ptr_UniformConstant_11
+ ; CHECK-DAG: %[[sampler_var]] = OpVariable %[[sampler_ptr_ty]] UniformConstant
+ ; CHECK-DAG: %[[image_var]] = OpVariable %[[image_ptr_ty]] UniformConstant
+ ; CHECK: = OpFunction
+
+ ; The load of the combined image+sampler is replaced by a two loads, then
+ ; a combination operation.
+ ; CHECK: %[[im:\d+]] = OpLoad %10 %[[image_var]]
+ ; CHECK: %[[s:\d+]] = OpLoad %[[sampler_ty]] %[[sampler_var]]
+ ; CHECK: %combined = OpSampledImage %11 %[[im]] %[[s]]
+
+ %bool = OpTypeBool ; location marker
+ %float = OpTypeFloat 32
+ %uint = OpTypeInt 32 0
+ %int = OpTypeInt 32 1
+ %uint_0 = OpConstant %uint 0
+ %uint_1 = OpConstant %uint 1
+ %uint_3 = OpConstant %uint 3
+ %float_0 = OpConstant %float 0
+ %v2float = OpTypeVector %float 2
+ %v3float = OpTypeVector %float 3
+ %v4float = OpTypeVector %float 4
+ %13 = OpConstantNull %v2float
+ %14 = OpConstantNull %v3float
+ %15 = OpConstantNull %v4float
+ %void = OpTypeVoid
+ %voidfn = OpTypeFunction %void
+ %10 = OpTypeImage %float 2D 0 0 1 1 Unknown
+ %11 = OpTypeSampledImage %10
+%_ptr_UniformConstant_11 = OpTypePointer UniformConstant %11
+
+ %100 = OpVariable %_ptr_UniformConstant_11 UniformConstant
+ %main = OpFunction %void None %voidfn
+ %main_0 = OpLabel
+ %combined = OpLoad %11 %100
+
+ ; Uses of the combined image sampler are preserved.
+ ; CHECK: OpCopyObject %11 %combined
+
+ %7 = OpCopyObject %11 %combined
+ OpReturn
+ OpFunctionEnd
diff --git a/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_RelaxedPrecisionOnVarCopied_6.spvasm b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_RelaxedPrecisionOnVarCopied_6.spvasm
new file mode 100644
index 0000000..a5f2506
--- /dev/null
+++ b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_RelaxedPrecisionOnVarCopied_6.spvasm
@@ -0,0 +1,74 @@
+ OpCapability Shader
+ OpCapability RuntimeDescriptorArray
+ OpExtension "SPV_EXT_descriptor_indexing"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ OpName %main "main"
+ OpName %main_0 "main_0"
+ OpName %voidfn "voidfn"
+
+ OpName %combined "combined"
+ OpDecorate %100 DescriptorSet 0
+ OpDecorate %100 Binding 0
+ OpDecorate %100 RelaxedPrecision
+
+ ; CHECK: OpName
+ ; CHECK-NOT: OpDecorate %100
+ ; CHECK: OpDecorate %[[image_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[sampler_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[image_var]] Binding 0
+ ; CHECK: OpDecorate %[[sampler_var]] Binding 0
+ ; CHECK: OpDecorate %[[image_var:\d+]] RelaxedPrecision
+ ; CHECK: OpDecorate %[[sampler_var:\d+]] RelaxedPrecision
+
+ ; CHECK: %10 = OpTypeImage %
+ ; CHECK: %[[image_ptr_ty:\w+]] = OpTypePointer UniformConstant %10
+ ; CHECK: %[[sampler_ty:\d+]] = OpTypeSampler
+ ; CHECK: %[[sampler_ptr_ty:\w+]] = OpTypePointer UniformConstant %[[sampler_ty]]
+
+ ; The combined image variable is replaced by an image variable and a sampler variable.
+
+ ; CHECK-NOT: %100 = OpVariable
+ ; CHECK-NOT: OpVariable _ptr_UniformConstant_11
+ ; CHECK-DAG: %[[sampler_var]] = OpVariable %[[sampler_ptr_ty]] UniformConstant
+ ; CHECK-DAG: %[[image_var]] = OpVariable %[[image_ptr_ty]] UniformConstant
+ ; CHECK: = OpFunction
+
+ ; The load of the combined image+sampler is replaced by a two loads, then
+ ; a combination operation.
+ ; CHECK: %[[im:\d+]] = OpLoad %10 %[[image_var]]
+ ; CHECK: %[[s:\d+]] = OpLoad %[[sampler_ty]] %[[sampler_var]]
+ ; CHECK: %combined = OpSampledImage %11 %[[im]] %[[s]]
+
+ %bool = OpTypeBool ; location marker
+ %float = OpTypeFloat 32
+ %uint = OpTypeInt 32 0
+ %int = OpTypeInt 32 1
+ %uint_0 = OpConstant %uint 0
+ %uint_1 = OpConstant %uint 1
+ %uint_3 = OpConstant %uint 3
+ %float_0 = OpConstant %float 0
+ %v2float = OpTypeVector %float 2
+ %v3float = OpTypeVector %float 3
+ %v4float = OpTypeVector %float 4
+ %13 = OpConstantNull %v2float
+ %14 = OpConstantNull %v3float
+ %15 = OpConstantNull %v4float
+ %void = OpTypeVoid
+ %voidfn = OpTypeFunction %void
+ %10 = OpTypeImage %float 3D 0 0 0 1 Unknown
+ %11 = OpTypeSampledImage %10
+%_ptr_UniformConstant_11 = OpTypePointer UniformConstant %11
+
+ %100 = OpVariable %_ptr_UniformConstant_11 UniformConstant
+ %main = OpFunction %void None %voidfn
+ %main_0 = OpLabel
+ %combined = OpLoad %11 %100
+
+ ; Uses of the combined image sampler are preserved.
+ ; CHECK: OpCopyObject %11 %combined
+
+ %7 = OpCopyObject %11 %combined
+ OpReturn
+ OpFunctionEnd
diff --git a/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_RelaxedPrecisionOnVarCopied_7.spvasm b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_RelaxedPrecisionOnVarCopied_7.spvasm
new file mode 100644
index 0000000..55f39c9
--- /dev/null
+++ b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_RelaxedPrecisionOnVarCopied_7.spvasm
@@ -0,0 +1,74 @@
+ OpCapability Shader
+ OpCapability RuntimeDescriptorArray
+ OpExtension "SPV_EXT_descriptor_indexing"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ OpName %main "main"
+ OpName %main_0 "main_0"
+ OpName %voidfn "voidfn"
+
+ OpName %combined "combined"
+ OpDecorate %100 DescriptorSet 0
+ OpDecorate %100 Binding 0
+ OpDecorate %100 RelaxedPrecision
+
+ ; CHECK: OpName
+ ; CHECK-NOT: OpDecorate %100
+ ; CHECK: OpDecorate %[[image_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[sampler_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[image_var]] Binding 0
+ ; CHECK: OpDecorate %[[sampler_var]] Binding 0
+ ; CHECK: OpDecorate %[[image_var:\d+]] RelaxedPrecision
+ ; CHECK: OpDecorate %[[sampler_var:\d+]] RelaxedPrecision
+
+ ; CHECK: %10 = OpTypeImage %
+ ; CHECK: %[[image_ptr_ty:\w+]] = OpTypePointer UniformConstant %10
+ ; CHECK: %[[sampler_ty:\d+]] = OpTypeSampler
+ ; CHECK: %[[sampler_ptr_ty:\w+]] = OpTypePointer UniformConstant %[[sampler_ty]]
+
+ ; The combined image variable is replaced by an image variable and a sampler variable.
+
+ ; CHECK-NOT: %100 = OpVariable
+ ; CHECK-NOT: OpVariable _ptr_UniformConstant_11
+ ; CHECK-DAG: %[[sampler_var]] = OpVariable %[[sampler_ptr_ty]] UniformConstant
+ ; CHECK-DAG: %[[image_var]] = OpVariable %[[image_ptr_ty]] UniformConstant
+ ; CHECK: = OpFunction
+
+ ; The load of the combined image+sampler is replaced by a two loads, then
+ ; a combination operation.
+ ; CHECK: %[[im:\d+]] = OpLoad %10 %[[image_var]]
+ ; CHECK: %[[s:\d+]] = OpLoad %[[sampler_ty]] %[[sampler_var]]
+ ; CHECK: %combined = OpSampledImage %11 %[[im]] %[[s]]
+
+ %bool = OpTypeBool ; location marker
+ %float = OpTypeFloat 32
+ %uint = OpTypeInt 32 0
+ %int = OpTypeInt 32 1
+ %uint_0 = OpConstant %uint 0
+ %uint_1 = OpConstant %uint 1
+ %uint_3 = OpConstant %uint 3
+ %float_0 = OpConstant %float 0
+ %v2float = OpTypeVector %float 2
+ %v3float = OpTypeVector %float 3
+ %v4float = OpTypeVector %float 4
+ %13 = OpConstantNull %v2float
+ %14 = OpConstantNull %v3float
+ %15 = OpConstantNull %v4float
+ %void = OpTypeVoid
+ %voidfn = OpTypeFunction %void
+ %10 = OpTypeImage %float Cube 0 0 0 1 Unknown
+ %11 = OpTypeSampledImage %10
+%_ptr_UniformConstant_11 = OpTypePointer UniformConstant %11
+
+ %100 = OpVariable %_ptr_UniformConstant_11 UniformConstant
+ %main = OpFunction %void None %voidfn
+ %main_0 = OpLabel
+ %combined = OpLoad %11 %100
+
+ ; Uses of the combined image sampler are preserved.
+ ; CHECK: OpCopyObject %11 %combined
+
+ %7 = OpCopyObject %11 %combined
+ OpReturn
+ OpFunctionEnd
diff --git a/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_RelaxedPrecisionOnVarCopied_8.spvasm b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_RelaxedPrecisionOnVarCopied_8.spvasm
new file mode 100644
index 0000000..7d9ce92
--- /dev/null
+++ b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_RelaxedPrecisionOnVarCopied_8.spvasm
@@ -0,0 +1,74 @@
+ OpCapability Shader
+ OpCapability RuntimeDescriptorArray
+ OpExtension "SPV_EXT_descriptor_indexing"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ OpName %main "main"
+ OpName %main_0 "main_0"
+ OpName %voidfn "voidfn"
+
+ OpName %combined "combined"
+ OpDecorate %100 DescriptorSet 0
+ OpDecorate %100 Binding 0
+ OpDecorate %100 RelaxedPrecision
+
+ ; CHECK: OpName
+ ; CHECK-NOT: OpDecorate %100
+ ; CHECK: OpDecorate %[[image_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[sampler_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[image_var]] Binding 0
+ ; CHECK: OpDecorate %[[sampler_var]] Binding 0
+ ; CHECK: OpDecorate %[[image_var:\d+]] RelaxedPrecision
+ ; CHECK: OpDecorate %[[sampler_var:\d+]] RelaxedPrecision
+
+ ; CHECK: %10 = OpTypeImage %
+ ; CHECK: %[[image_ptr_ty:\w+]] = OpTypePointer UniformConstant %10
+ ; CHECK: %[[sampler_ty:\d+]] = OpTypeSampler
+ ; CHECK: %[[sampler_ptr_ty:\w+]] = OpTypePointer UniformConstant %[[sampler_ty]]
+
+ ; The combined image variable is replaced by an image variable and a sampler variable.
+
+ ; CHECK-NOT: %100 = OpVariable
+ ; CHECK-NOT: OpVariable _ptr_UniformConstant_11
+ ; CHECK-DAG: %[[sampler_var]] = OpVariable %[[sampler_ptr_ty]] UniformConstant
+ ; CHECK-DAG: %[[image_var]] = OpVariable %[[image_ptr_ty]] UniformConstant
+ ; CHECK: = OpFunction
+
+ ; The load of the combined image+sampler is replaced by a two loads, then
+ ; a combination operation.
+ ; CHECK: %[[im:\d+]] = OpLoad %10 %[[image_var]]
+ ; CHECK: %[[s:\d+]] = OpLoad %[[sampler_ty]] %[[sampler_var]]
+ ; CHECK: %combined = OpSampledImage %11 %[[im]] %[[s]]
+
+ %bool = OpTypeBool ; location marker
+ %float = OpTypeFloat 32
+ %uint = OpTypeInt 32 0
+ %int = OpTypeInt 32 1
+ %uint_0 = OpConstant %uint 0
+ %uint_1 = OpConstant %uint 1
+ %uint_3 = OpConstant %uint 3
+ %float_0 = OpConstant %float 0
+ %v2float = OpTypeVector %float 2
+ %v3float = OpTypeVector %float 3
+ %v4float = OpTypeVector %float 4
+ %13 = OpConstantNull %v2float
+ %14 = OpConstantNull %v3float
+ %15 = OpConstantNull %v4float
+ %void = OpTypeVoid
+ %voidfn = OpTypeFunction %void
+ %10 = OpTypeImage %float Cube 1 0 0 1 Unknown
+ %11 = OpTypeSampledImage %10
+%_ptr_UniformConstant_11 = OpTypePointer UniformConstant %11
+
+ %100 = OpVariable %_ptr_UniformConstant_11 UniformConstant
+ %main = OpFunction %void None %voidfn
+ %main_0 = OpLabel
+ %combined = OpLoad %11 %100
+
+ ; Uses of the combined image sampler are preserved.
+ ; CHECK: OpCopyObject %11 %combined
+
+ %7 = OpCopyObject %11 %combined
+ OpReturn
+ OpFunctionEnd
diff --git a/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_RelaxedPrecisionOnVarCopied_9.spvasm b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_RelaxedPrecisionOnVarCopied_9.spvasm
new file mode 100644
index 0000000..ee7be5b
--- /dev/null
+++ b/test/tint/unittest/reader/combined_texture_sampler/AllCombinedTypes_SplitCombinedImageSamplerPassTypeCaseTest_Combined_RemapLoad_RelaxedPrecisionOnVarCopied_9.spvasm
@@ -0,0 +1,74 @@
+ OpCapability Shader
+ OpCapability RuntimeDescriptorArray
+ OpExtension "SPV_EXT_descriptor_indexing"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ OpName %main "main"
+ OpName %main_0 "main_0"
+ OpName %voidfn "voidfn"
+
+ OpName %combined "combined"
+ OpDecorate %100 DescriptorSet 0
+ OpDecorate %100 Binding 0
+ OpDecorate %100 RelaxedPrecision
+
+ ; CHECK: OpName
+ ; CHECK-NOT: OpDecorate %100
+ ; CHECK: OpDecorate %[[image_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[sampler_var:\d+]] DescriptorSet 0
+ ; CHECK: OpDecorate %[[image_var]] Binding 0
+ ; CHECK: OpDecorate %[[sampler_var]] Binding 0
+ ; CHECK: OpDecorate %[[image_var:\d+]] RelaxedPrecision
+ ; CHECK: OpDecorate %[[sampler_var:\d+]] RelaxedPrecision
+
+ ; CHECK: %10 = OpTypeImage %
+ ; CHECK: %[[image_ptr_ty:\w+]] = OpTypePointer UniformConstant %10
+ ; CHECK: %[[sampler_ty:\d+]] = OpTypeSampler
+ ; CHECK: %[[sampler_ptr_ty:\w+]] = OpTypePointer UniformConstant %[[sampler_ty]]
+
+ ; The combined image variable is replaced by an image variable and a sampler variable.
+
+ ; CHECK-NOT: %100 = OpVariable
+ ; CHECK-NOT: OpVariable _ptr_UniformConstant_11
+ ; CHECK-DAG: %[[sampler_var]] = OpVariable %[[sampler_ptr_ty]] UniformConstant
+ ; CHECK-DAG: %[[image_var]] = OpVariable %[[image_ptr_ty]] UniformConstant
+ ; CHECK: = OpFunction
+
+ ; The load of the combined image+sampler is replaced by a two loads, then
+ ; a combination operation.
+ ; CHECK: %[[im:\d+]] = OpLoad %10 %[[image_var]]
+ ; CHECK: %[[s:\d+]] = OpLoad %[[sampler_ty]] %[[sampler_var]]
+ ; CHECK: %combined = OpSampledImage %11 %[[im]] %[[s]]
+
+ %bool = OpTypeBool ; location marker
+ %float = OpTypeFloat 32
+ %uint = OpTypeInt 32 0
+ %int = OpTypeInt 32 1
+ %uint_0 = OpConstant %uint 0
+ %uint_1 = OpConstant %uint 1
+ %uint_3 = OpConstant %uint 3
+ %float_0 = OpConstant %float 0
+ %v2float = OpTypeVector %float 2
+ %v3float = OpTypeVector %float 3
+ %v4float = OpTypeVector %float 4
+ %13 = OpConstantNull %v2float
+ %14 = OpConstantNull %v3float
+ %15 = OpConstantNull %v4float
+ %void = OpTypeVoid
+ %voidfn = OpTypeFunction %void
+ %10 = OpTypeImage %float Cube 0 1 0 1 Unknown
+ %11 = OpTypeSampledImage %10
+%_ptr_UniformConstant_11 = OpTypePointer UniformConstant %11
+
+ %100 = OpVariable %_ptr_UniformConstant_11 UniformConstant
+ %main = OpFunction %void None %voidfn
+ %main_0 = OpLabel
+ %combined = OpLoad %11 %100
+
+ ; Uses of the combined image sampler are preserved.
+ ; CHECK: OpCopyObject %11 %combined
+
+ %7 = OpCopyObject %11 %combined
+ OpReturn
+ OpFunctionEnd
diff --git a/test/tint/unittest/reader/combined_texture_sampler/EntryPointRemap_SplitCombinedImageSamplerPassEntryPointRemapTest_EntryPoint_Combined_Unused_0.spvasm b/test/tint/unittest/reader/combined_texture_sampler/EntryPointRemap_SplitCombinedImageSamplerPassEntryPointRemapTest_EntryPoint_Combined_Unused_0.spvasm
new file mode 100644
index 0000000..35ab348
--- /dev/null
+++ b/test/tint/unittest/reader/combined_texture_sampler/EntryPointRemap_SplitCombinedImageSamplerPassEntryPointRemapTest_EntryPoint_Combined_Unused_0.spvasm
@@ -0,0 +1,58 @@
+ OpCapability Shader
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %main "main" %in_var %out_var
+ OpExecutionMode %main OriginUpperLeft
+ OpName %main "main"
+ OpName %main_0 "main_0"
+ OpName %voidfn "voidfn"
+
+ ; CHECK: OpEntryPoint Fragment %main "main" %in_var %out_var
+ ; These clauses ensure the expected interface is the whole interface.
+ ; CHECK-NOT: %{{\d+}}
+ ; CHECK-NOT: %in_var
+ ; CHECK-NOT: %out_var
+ ; CHECK-NOT: %combined_var
+ ; CHECK: OpExecutionMode %main OriginUpperLeft
+
+ ; The variable disappears.
+ ; CHECK-NOT: %combined_var =
+ ; CHECK: OpFunctionEnd
+ OpName %combined_var "combined_var"
+ OpName %in_var "in_var"
+ OpName %out_var "out_var"
+ OpDecorate %combined_var DescriptorSet 0
+ OpDecorate %combined_var Binding 0
+ OpDecorate %in_var BuiltIn FragCoord
+ OpDecorate %out_var Location 0
+
+
+ %bool = OpTypeBool
+ %float = OpTypeFloat 32
+ %uint = OpTypeInt 32 0
+ %int = OpTypeInt 32 1
+ %uint_0 = OpConstant %uint 0
+ %uint_1 = OpConstant %uint 1
+ %uint_3 = OpConstant %uint 3
+ %float_0 = OpConstant %float 0
+ %v2float = OpTypeVector %float 2
+ %v3float = OpTypeVector %float 3
+ %v4float = OpTypeVector %float 4
+ %13 = OpConstantNull %v2float
+ %14 = OpConstantNull %v3float
+ %15 = OpConstantNull %v4float
+ %void = OpTypeVoid
+ %voidfn = OpTypeFunction %void
+ %10 = OpTypeImage %float 2D 0 0 0 1 Unknown
+ %11 = OpTypeSampledImage %10
+ %_ptr_UniformConstant_11 = OpTypePointer UniformConstant %11
+ %in_ptr_v4f = OpTypePointer Input %v4float
+ %in_var = OpVariable %in_ptr_v4f Input
+ %out_ptr_v4f = OpTypePointer Output %v4float
+ %out_var = OpVariable %out_ptr_v4f Output
+
+ ; %combined_var is not used!
+ %combined_var = OpVariable %_ptr_UniformConstant_11 UniformConstant
+ %main = OpFunction %void None %voidfn
+ %main_0 = OpLabel
+ OpReturn
+ OpFunctionEnd
diff --git a/test/tint/unittest/reader/combined_texture_sampler/EntryPointRemap_SplitCombinedImageSamplerPassEntryPointRemapTest_EntryPoint_Combined_UsedInShader_0.spvasm b/test/tint/unittest/reader/combined_texture_sampler/EntryPointRemap_SplitCombinedImageSamplerPassEntryPointRemapTest_EntryPoint_Combined_UsedInShader_0.spvasm
new file mode 100644
index 0000000..dd854f7
--- /dev/null
+++ b/test/tint/unittest/reader/combined_texture_sampler/EntryPointRemap_SplitCombinedImageSamplerPassEntryPointRemapTest_EntryPoint_Combined_UsedInShader_0.spvasm
@@ -0,0 +1,68 @@
+ OpCapability Shader
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint Fragment %main "main" %in_var %out_var
+ OpExecutionMode %main OriginUpperLeft
+ OpName %main "main"
+ OpName %main_0 "main_0"
+ OpName %voidfn "voidfn"
+
+ OpName %combined "combined"
+ OpName %combined_var "combined_var"
+ OpName %in_var "in_var"
+ OpName %out_var "out_var"
+ OpDecorate %combined_var DescriptorSet 0
+ OpDecorate %combined_var Binding 0
+ OpDecorate %in_var BuiltIn FragCoord
+ OpDecorate %out_var Location 0
+
+; CHECK: OpEntryPoint Fragment %main "main" %in_var %out_var
+; These clauses ensure the expected interface is the whole interface.
+; CHECK-NOT: %{{\d+}}
+; CHECK-NOT: %in_var
+; CHECK-NOT: %out_var
+; CHECK-NOT: %combined_var
+; CHECK: OpExecutionMode %main OriginUpperLeft
+
+ ; Check the var names, tracing up through the types.
+ ; CHECK: %10 = OpTypeImage %float 2D 0 0 0 1 Unknown
+ ; CHECK: %[[image_ptr_ty:\w+]] = OpTypePointer UniformConstant %10
+ ; CHECK: %[[sampler_ty:\d+]] = OpTypeSampler
+ ; CHECK: %[[sampler_ptr_ty:\w+]] = OpTypePointer UniformConstant %[[sampler_ty]]
+ ; The combined image variable is replaced by an image variable and a sampler variable.
+ ; CHECK-DAG: %combined_var_sampler = OpVariable %[[sampler_ptr_ty]] UniformConstant
+ ; CHECK-DAG: %combined_var_image = OpVariable %[[image_ptr_ty]] UniformConstant
+ ; CHECK: = OpFunction
+
+ %bool = OpTypeBool
+ %float = OpTypeFloat 32
+ %uint = OpTypeInt 32 0
+ %int = OpTypeInt 32 1
+ %uint_0 = OpConstant %uint 0
+ %uint_1 = OpConstant %uint 1
+ %uint_3 = OpConstant %uint 3
+ %float_0 = OpConstant %float 0
+ %v2float = OpTypeVector %float 2
+ %v3float = OpTypeVector %float 3
+ %v4float = OpTypeVector %float 4
+ %13 = OpConstantNull %v2float
+ %14 = OpConstantNull %v3float
+ %15 = OpConstantNull %v4float
+ %void = OpTypeVoid
+ %voidfn = OpTypeFunction %void
+ %10 = OpTypeImage %float 2D 0 0 0 1 Unknown
+ %11 = OpTypeSampledImage %10
+%_ptr_UniformConstant_11 = OpTypePointer UniformConstant %11
+ %in_ptr_v4f = OpTypePointer Input %v4float
+ %in_var = OpVariable %in_ptr_v4f Input
+ %out_ptr_v4f = OpTypePointer Output %v4float
+ %out_var = OpVariable %out_ptr_v4f Output
+
+%combined_var = OpVariable %_ptr_UniformConstant_11 UniformConstant
+ %main = OpFunction %void None %voidfn
+ ;CHECK: %main_0 = OpLabel
+ ;CHECK: OpLoad
+
+ %main_0 = OpLabel
+ %combined = OpLoad %11 %combined_var
+ OpReturn
+ OpFunctionEnd
diff --git a/test/tint/unittest/reader/combined_texture_sampler/FunctionTypeRemap_SplitCombinedImageSamplerPassFunctionTypeTest_AvoidDuplicateType_3.spvasm b/test/tint/unittest/reader/combined_texture_sampler/FunctionTypeRemap_SplitCombinedImageSamplerPassFunctionTypeTest_AvoidDuplicateType_3.spvasm
new file mode 100644
index 0000000..dacafa8
--- /dev/null
+++ b/test/tint/unittest/reader/combined_texture_sampler/FunctionTypeRemap_SplitCombinedImageSamplerPassFunctionTypeTest_AvoidDuplicateType_3.spvasm
@@ -0,0 +1,55 @@
+ OpCapability Shader
+ OpCapability RuntimeDescriptorArray
+ OpExtension "SPV_EXT_descriptor_indexing"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ OpName %main "main"
+ OpName %main_0 "main_0"
+ OpName %voidfn "voidfn"
+
+ OpName %sampler_ty "sampler_ty"
+ OpName %image_ty "image_ty"
+ OpName %sampled_image_ty "sampled_image_ty"
+ OpName %_ptr_UniformConstant_sampler_ty "_ptr_UniformConstant_sampler_ty"
+ OpName %_ptr_UniformConstant_image_ty "_ptr_UniformConstant_image_ty"
+ OpName %ptr_sampled_image_ty "sampled_image_ty"
+ OpName %dest_ty "dest_ty"
+
+ %float = OpTypeFloat 32
+ %uint = OpTypeInt 32 0
+ %int = OpTypeInt 32 1
+ %uint_0 = OpConstant %uint 0
+ %uint_1 = OpConstant %uint 1
+ %uint_3 = OpConstant %uint 3
+ %float_0 = OpConstant %float 0
+ %v2float = OpTypeVector %float 2
+ %v3float = OpTypeVector %float 3
+ %v4float = OpTypeVector %float 4
+ %13 = OpConstantNull %v2float
+ %14 = OpConstantNull %v3float
+ %15 = OpConstantNull %v4float
+ %void = OpTypeVoid
+ %voidfn = OpTypeFunction %void
+
+
+ %sampler_ty = OpTypeSampler
+ %image_ty = OpTypeImage %float 2D 0 0 0 1 Unknown
+ %sampled_image_ty = OpTypeSampledImage %image_ty
+ %ptr_sampled_image_ty = OpTypePointer UniformConstant %sampled_image_ty
+ %_ptr_UniformConstant_image_ty = OpTypePointer UniformConstant %image_ty
+ %_ptr_UniformConstant_sampler_ty = OpTypePointer UniformConstant %sampler_ty
+
+ %100 = OpTypeFunction %float %sampled_image_ty
+ %dest_ty = OpTypeFunction %float %image_ty %sampler_ty
+
+ ; CHECK: OpTypeSampler
+ ; CHECK-NOT: %100 =
+ ; CHECK: %dest_ty = OpTypeFunction %float %image_ty %sampler_ty
+ ; CHECK-NOT: %100 =
+ ; CHECK: %main = OpFunction
+
+ %main = OpFunction %void None %voidfn
+ %main_0 = OpLabel
+ OpReturn
+ OpFunctionEnd
diff --git a/test/tint/unittest/reader/combined_texture_sampler/FunctionTypeRemap_SplitCombinedImageSamplerPassFunctionTypeTest_AvoidDuplicateType_4.spvasm b/test/tint/unittest/reader/combined_texture_sampler/FunctionTypeRemap_SplitCombinedImageSamplerPassFunctionTypeTest_AvoidDuplicateType_4.spvasm
new file mode 100644
index 0000000..a0e0b21
--- /dev/null
+++ b/test/tint/unittest/reader/combined_texture_sampler/FunctionTypeRemap_SplitCombinedImageSamplerPassFunctionTypeTest_AvoidDuplicateType_4.spvasm
@@ -0,0 +1,55 @@
+ OpCapability Shader
+ OpCapability RuntimeDescriptorArray
+ OpExtension "SPV_EXT_descriptor_indexing"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ OpName %main "main"
+ OpName %main_0 "main_0"
+ OpName %voidfn "voidfn"
+
+ OpName %sampler_ty "sampler_ty"
+ OpName %image_ty "image_ty"
+ OpName %sampled_image_ty "sampled_image_ty"
+ OpName %_ptr_UniformConstant_sampler_ty "_ptr_UniformConstant_sampler_ty"
+ OpName %_ptr_UniformConstant_image_ty "_ptr_UniformConstant_image_ty"
+ OpName %ptr_sampled_image_ty "sampled_image_ty"
+ OpName %dest_ty "dest_ty"
+
+ %float = OpTypeFloat 32
+ %uint = OpTypeInt 32 0
+ %int = OpTypeInt 32 1
+ %uint_0 = OpConstant %uint 0
+ %uint_1 = OpConstant %uint 1
+ %uint_3 = OpConstant %uint 3
+ %float_0 = OpConstant %float 0
+ %v2float = OpTypeVector %float 2
+ %v3float = OpTypeVector %float 3
+ %v4float = OpTypeVector %float 4
+ %13 = OpConstantNull %v2float
+ %14 = OpConstantNull %v3float
+ %15 = OpConstantNull %v4float
+ %void = OpTypeVoid
+ %voidfn = OpTypeFunction %void
+
+
+ %sampler_ty = OpTypeSampler
+ %image_ty = OpTypeImage %float 2D 0 0 0 1 Unknown
+ %sampled_image_ty = OpTypeSampledImage %image_ty
+ %ptr_sampled_image_ty = OpTypePointer UniformConstant %sampled_image_ty
+ %_ptr_UniformConstant_image_ty = OpTypePointer UniformConstant %image_ty
+ %_ptr_UniformConstant_sampler_ty = OpTypePointer UniformConstant %sampler_ty
+
+ %100 = OpTypeFunction %float %uint %sampled_image_ty %float
+ %dest_ty = OpTypeFunction %float %uint %image_ty %sampler_ty %float
+
+ ; CHECK: OpTypeSampler
+ ; CHECK-NOT: %100 =
+ ; CHECK: %dest_ty = OpTypeFunction %float %uint %image_ty %sampler_ty %float
+ ; CHECK-NOT: %100 =
+ ; CHECK: %main = OpFunction
+
+ %main = OpFunction %void None %voidfn
+ %main_0 = OpLabel
+ OpReturn
+ OpFunctionEnd
diff --git a/test/tint/unittest/reader/combined_texture_sampler/FunctionTypeRemap_SplitCombinedImageSamplerPassFunctionTypeTest_AvoidDuplicateType_5.spvasm b/test/tint/unittest/reader/combined_texture_sampler/FunctionTypeRemap_SplitCombinedImageSamplerPassFunctionTypeTest_AvoidDuplicateType_5.spvasm
new file mode 100644
index 0000000..895177c
--- /dev/null
+++ b/test/tint/unittest/reader/combined_texture_sampler/FunctionTypeRemap_SplitCombinedImageSamplerPassFunctionTypeTest_AvoidDuplicateType_5.spvasm
@@ -0,0 +1,55 @@
+ OpCapability Shader
+ OpCapability RuntimeDescriptorArray
+ OpExtension "SPV_EXT_descriptor_indexing"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ OpName %main "main"
+ OpName %main_0 "main_0"
+ OpName %voidfn "voidfn"
+
+ OpName %sampler_ty "sampler_ty"
+ OpName %image_ty "image_ty"
+ OpName %sampled_image_ty "sampled_image_ty"
+ OpName %_ptr_UniformConstant_sampler_ty "_ptr_UniformConstant_sampler_ty"
+ OpName %_ptr_UniformConstant_image_ty "_ptr_UniformConstant_image_ty"
+ OpName %ptr_sampled_image_ty "sampled_image_ty"
+ OpName %dest_ty "dest_ty"
+
+ %float = OpTypeFloat 32
+ %uint = OpTypeInt 32 0
+ %int = OpTypeInt 32 1
+ %uint_0 = OpConstant %uint 0
+ %uint_1 = OpConstant %uint 1
+ %uint_3 = OpConstant %uint 3
+ %float_0 = OpConstant %float 0
+ %v2float = OpTypeVector %float 2
+ %v3float = OpTypeVector %float 3
+ %v4float = OpTypeVector %float 4
+ %13 = OpConstantNull %v2float
+ %14 = OpConstantNull %v3float
+ %15 = OpConstantNull %v4float
+ %void = OpTypeVoid
+ %voidfn = OpTypeFunction %void
+
+
+ %sampler_ty = OpTypeSampler
+ %image_ty = OpTypeImage %float 2D 0 0 0 1 Unknown
+ %sampled_image_ty = OpTypeSampledImage %image_ty
+ %ptr_sampled_image_ty = OpTypePointer UniformConstant %sampled_image_ty
+ %_ptr_UniformConstant_image_ty = OpTypePointer UniformConstant %image_ty
+ %_ptr_UniformConstant_sampler_ty = OpTypePointer UniformConstant %sampler_ty
+
+ %100 = OpTypeFunction %float %ptr_sampled_image_ty
+ %dest_ty = OpTypeFunction %float %_ptr_UniformConstant_image_ty %_ptr_UniformConstant_sampler_ty
+
+ ; CHECK: OpTypeSampler
+ ; CHECK-NOT: %100 =
+ ; CHECK: %dest_ty = OpTypeFunction %float %_ptr_UniformConstant_image_ty %_ptr_UniformConstant_sampler_ty
+ ; CHECK-NOT: %100 =
+ ; CHECK: %main = OpFunction
+
+ %main = OpFunction %void None %voidfn
+ %main_0 = OpLabel
+ OpReturn
+ OpFunctionEnd
diff --git a/test/tint/unittest/reader/combined_texture_sampler/FunctionTypeRemap_SplitCombinedImageSamplerPassFunctionTypeTest_AvoidDuplicateType_6.spvasm b/test/tint/unittest/reader/combined_texture_sampler/FunctionTypeRemap_SplitCombinedImageSamplerPassFunctionTypeTest_AvoidDuplicateType_6.spvasm
new file mode 100644
index 0000000..bdbbb3a
--- /dev/null
+++ b/test/tint/unittest/reader/combined_texture_sampler/FunctionTypeRemap_SplitCombinedImageSamplerPassFunctionTypeTest_AvoidDuplicateType_6.spvasm
@@ -0,0 +1,55 @@
+ OpCapability Shader
+ OpCapability RuntimeDescriptorArray
+ OpExtension "SPV_EXT_descriptor_indexing"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ OpName %main "main"
+ OpName %main_0 "main_0"
+ OpName %voidfn "voidfn"
+
+ OpName %sampler_ty "sampler_ty"
+ OpName %image_ty "image_ty"
+ OpName %sampled_image_ty "sampled_image_ty"
+ OpName %_ptr_UniformConstant_sampler_ty "_ptr_UniformConstant_sampler_ty"
+ OpName %_ptr_UniformConstant_image_ty "_ptr_UniformConstant_image_ty"
+ OpName %ptr_sampled_image_ty "sampled_image_ty"
+ OpName %dest_ty "dest_ty"
+
+ %float = OpTypeFloat 32
+ %uint = OpTypeInt 32 0
+ %int = OpTypeInt 32 1
+ %uint_0 = OpConstant %uint 0
+ %uint_1 = OpConstant %uint 1
+ %uint_3 = OpConstant %uint 3
+ %float_0 = OpConstant %float 0
+ %v2float = OpTypeVector %float 2
+ %v3float = OpTypeVector %float 3
+ %v4float = OpTypeVector %float 4
+ %13 = OpConstantNull %v2float
+ %14 = OpConstantNull %v3float
+ %15 = OpConstantNull %v4float
+ %void = OpTypeVoid
+ %voidfn = OpTypeFunction %void
+
+
+ %sampler_ty = OpTypeSampler
+ %image_ty = OpTypeImage %float 2D 0 0 0 1 Unknown
+ %sampled_image_ty = OpTypeSampledImage %image_ty
+ %ptr_sampled_image_ty = OpTypePointer UniformConstant %sampled_image_ty
+ %_ptr_UniformConstant_image_ty = OpTypePointer UniformConstant %image_ty
+ %_ptr_UniformConstant_sampler_ty = OpTypePointer UniformConstant %sampler_ty
+
+ %100 = OpTypeFunction %float %uint %ptr_sampled_image_ty %float
+ %dest_ty = OpTypeFunction %float %uint %_ptr_UniformConstant_image_ty %_ptr_UniformConstant_sampler_ty %float
+
+ ; CHECK: OpTypeSampler
+ ; CHECK-NOT: %100 =
+ ; CHECK: %dest_ty = OpTypeFunction %float %uint %_ptr_UniformConstant_image_ty %_ptr_UniformConstant_sampler_ty %float
+ ; CHECK-NOT: %100 =
+ ; CHECK: %main = OpFunction
+
+ %main = OpFunction %void None %voidfn
+ %main_0 = OpLabel
+ OpReturn
+ OpFunctionEnd
diff --git a/test/tint/unittest/reader/combined_texture_sampler/FunctionTypeRemap_SplitCombinedImageSamplerPassFunctionTypeTest_AvoidDuplicateType_7.spvasm b/test/tint/unittest/reader/combined_texture_sampler/FunctionTypeRemap_SplitCombinedImageSamplerPassFunctionTypeTest_AvoidDuplicateType_7.spvasm
new file mode 100644
index 0000000..72f9b37
--- /dev/null
+++ b/test/tint/unittest/reader/combined_texture_sampler/FunctionTypeRemap_SplitCombinedImageSamplerPassFunctionTypeTest_AvoidDuplicateType_7.spvasm
@@ -0,0 +1,55 @@
+ OpCapability Shader
+ OpCapability RuntimeDescriptorArray
+ OpExtension "SPV_EXT_descriptor_indexing"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ OpName %main "main"
+ OpName %main_0 "main_0"
+ OpName %voidfn "voidfn"
+
+ OpName %sampler_ty "sampler_ty"
+ OpName %image_ty "image_ty"
+ OpName %sampled_image_ty "sampled_image_ty"
+ OpName %_ptr_UniformConstant_sampler_ty "_ptr_UniformConstant_sampler_ty"
+ OpName %_ptr_UniformConstant_image_ty "_ptr_UniformConstant_image_ty"
+ OpName %ptr_sampled_image_ty "sampled_image_ty"
+ OpName %dest_ty "dest_ty"
+
+ %float = OpTypeFloat 32
+ %uint = OpTypeInt 32 0
+ %int = OpTypeInt 32 1
+ %uint_0 = OpConstant %uint 0
+ %uint_1 = OpConstant %uint 1
+ %uint_3 = OpConstant %uint 3
+ %float_0 = OpConstant %float 0
+ %v2float = OpTypeVector %float 2
+ %v3float = OpTypeVector %float 3
+ %v4float = OpTypeVector %float 4
+ %13 = OpConstantNull %v2float
+ %14 = OpConstantNull %v3float
+ %15 = OpConstantNull %v4float
+ %void = OpTypeVoid
+ %voidfn = OpTypeFunction %void
+
+
+ %sampler_ty = OpTypeSampler
+ %image_ty = OpTypeImage %float 2D 0 0 0 1 Unknown
+ %sampled_image_ty = OpTypeSampledImage %image_ty
+ %ptr_sampled_image_ty = OpTypePointer UniformConstant %sampled_image_ty
+ %_ptr_UniformConstant_image_ty = OpTypePointer UniformConstant %image_ty
+ %_ptr_UniformConstant_sampler_ty = OpTypePointer UniformConstant %sampler_ty
+
+ %100 = OpTypeFunction %float %uint %ptr_sampled_image_ty %ptr_sampled_image_ty %float
+ %dest_ty = OpTypeFunction %float %uint %_ptr_UniformConstant_image_ty %_ptr_UniformConstant_sampler_ty %_ptr_UniformConstant_image_ty %_ptr_UniformConstant_sampler_ty %float
+
+ ; CHECK: OpTypeSampler
+ ; CHECK-NOT: %100 =
+ ; CHECK: %dest_ty = OpTypeFunction %float %uint %_ptr_UniformConstant_image_ty %_ptr_UniformConstant_sampler_ty %_ptr_UniformConstant_image_ty %_ptr_UniformConstant_sampler_ty %float
+ ; CHECK-NOT: %100 =
+ ; CHECK: %main = OpFunction
+
+ %main = OpFunction %void None %voidfn
+ %main_0 = OpLabel
+ OpReturn
+ OpFunctionEnd
diff --git a/test/tint/unittest/reader/combined_texture_sampler/FunctionTypeRemap_SplitCombinedImageSamplerPassFunctionTypeTest_ReplaceCombinedImageSamplersOnly_0.spvasm b/test/tint/unittest/reader/combined_texture_sampler/FunctionTypeRemap_SplitCombinedImageSamplerPassFunctionTypeTest_ReplaceCombinedImageSamplersOnly_0.spvasm
new file mode 100644
index 0000000..4b92259
--- /dev/null
+++ b/test/tint/unittest/reader/combined_texture_sampler/FunctionTypeRemap_SplitCombinedImageSamplerPassFunctionTypeTest_ReplaceCombinedImageSamplersOnly_0.spvasm
@@ -0,0 +1,46 @@
+ OpCapability Shader
+ OpCapability RuntimeDescriptorArray
+ OpExtension "SPV_EXT_descriptor_indexing"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ OpName %main "main"
+ OpName %main_0 "main_0"
+ OpName %voidfn "voidfn"
+
+ OpName %f_ty "f_ty"
+ OpName %sampler_ty "sampler_ty"
+ OpName %image_ty "image_ty"
+ OpName %sampled_image_ty "sampled_image_ty"
+ OpName %ptr_sampled_image_ty "sampled_image_ty"
+
+ %float = OpTypeFloat 32
+ %uint = OpTypeInt 32 0
+ %int = OpTypeInt 32 1
+ %uint_0 = OpConstant %uint 0
+ %uint_1 = OpConstant %uint 1
+ %uint_3 = OpConstant %uint 3
+ %float_0 = OpConstant %float 0
+ %v2float = OpTypeVector %float 2
+ %v3float = OpTypeVector %float 3
+ %v4float = OpTypeVector %float 4
+ %13 = OpConstantNull %v2float
+ %14 = OpConstantNull %v3float
+ %15 = OpConstantNull %v4float
+ %void = OpTypeVoid
+ %voidfn = OpTypeFunction %void
+
+
+ %sampler_ty = OpTypeSampler
+ %image_ty = OpTypeImage %float 2D 0 0 0 1 Unknown
+ %sampled_image_ty = OpTypeSampledImage %image_ty
+ %ptr_sampled_image_ty = OpTypePointer UniformConstant %sampled_image_ty
+
+ %f_ty = OpTypeFunction %float
+
+ ; CHECK: %f_ty = OpTypeFunction %float
+
+ %main = OpFunction %void None %voidfn
+ %main_0 = OpLabel
+ OpReturn
+ OpFunctionEnd
diff --git a/test/tint/unittest/reader/combined_texture_sampler/FunctionTypeRemap_SplitCombinedImageSamplerPassFunctionTypeTest_ReplaceCombinedImageSamplersOnly_1.spvasm b/test/tint/unittest/reader/combined_texture_sampler/FunctionTypeRemap_SplitCombinedImageSamplerPassFunctionTypeTest_ReplaceCombinedImageSamplersOnly_1.spvasm
new file mode 100644
index 0000000..01d8883
--- /dev/null
+++ b/test/tint/unittest/reader/combined_texture_sampler/FunctionTypeRemap_SplitCombinedImageSamplerPassFunctionTypeTest_ReplaceCombinedImageSamplersOnly_1.spvasm
@@ -0,0 +1,46 @@
+ OpCapability Shader
+ OpCapability RuntimeDescriptorArray
+ OpExtension "SPV_EXT_descriptor_indexing"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ OpName %main "main"
+ OpName %main_0 "main_0"
+ OpName %voidfn "voidfn"
+
+ OpName %f_ty "f_ty"
+ OpName %sampler_ty "sampler_ty"
+ OpName %image_ty "image_ty"
+ OpName %sampled_image_ty "sampled_image_ty"
+ OpName %ptr_sampled_image_ty "sampled_image_ty"
+
+ %float = OpTypeFloat 32
+ %uint = OpTypeInt 32 0
+ %int = OpTypeInt 32 1
+ %uint_0 = OpConstant %uint 0
+ %uint_1 = OpConstant %uint 1
+ %uint_3 = OpConstant %uint 3
+ %float_0 = OpConstant %float 0
+ %v2float = OpTypeVector %float 2
+ %v3float = OpTypeVector %float 3
+ %v4float = OpTypeVector %float 4
+ %13 = OpConstantNull %v2float
+ %14 = OpConstantNull %v3float
+ %15 = OpConstantNull %v4float
+ %void = OpTypeVoid
+ %voidfn = OpTypeFunction %void
+
+
+ %sampler_ty = OpTypeSampler
+ %image_ty = OpTypeImage %float 2D 0 0 0 1 Unknown
+ %sampled_image_ty = OpTypeSampledImage %image_ty
+ %ptr_sampled_image_ty = OpTypePointer UniformConstant %sampled_image_ty
+
+ %f_ty = OpTypeFunction %float %image_ty
+
+ ; CHECK: %f_ty = OpTypeFunction %float %image_ty
+
+ %main = OpFunction %void None %voidfn
+ %main_0 = OpLabel
+ OpReturn
+ OpFunctionEnd
diff --git a/test/tint/unittest/reader/combined_texture_sampler/FunctionTypeRemap_SplitCombinedImageSamplerPassFunctionTypeTest_ReplaceCombinedImageSamplersOnly_2.spvasm b/test/tint/unittest/reader/combined_texture_sampler/FunctionTypeRemap_SplitCombinedImageSamplerPassFunctionTypeTest_ReplaceCombinedImageSamplersOnly_2.spvasm
new file mode 100644
index 0000000..f07bf49
--- /dev/null
+++ b/test/tint/unittest/reader/combined_texture_sampler/FunctionTypeRemap_SplitCombinedImageSamplerPassFunctionTypeTest_ReplaceCombinedImageSamplersOnly_2.spvasm
@@ -0,0 +1,46 @@
+ OpCapability Shader
+ OpCapability RuntimeDescriptorArray
+ OpExtension "SPV_EXT_descriptor_indexing"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ OpName %main "main"
+ OpName %main_0 "main_0"
+ OpName %voidfn "voidfn"
+
+ OpName %f_ty "f_ty"
+ OpName %sampler_ty "sampler_ty"
+ OpName %image_ty "image_ty"
+ OpName %sampled_image_ty "sampled_image_ty"
+ OpName %ptr_sampled_image_ty "sampled_image_ty"
+
+ %float = OpTypeFloat 32
+ %uint = OpTypeInt 32 0
+ %int = OpTypeInt 32 1
+ %uint_0 = OpConstant %uint 0
+ %uint_1 = OpConstant %uint 1
+ %uint_3 = OpConstant %uint 3
+ %float_0 = OpConstant %float 0
+ %v2float = OpTypeVector %float 2
+ %v3float = OpTypeVector %float 3
+ %v4float = OpTypeVector %float 4
+ %13 = OpConstantNull %v2float
+ %14 = OpConstantNull %v3float
+ %15 = OpConstantNull %v4float
+ %void = OpTypeVoid
+ %voidfn = OpTypeFunction %void
+
+
+ %sampler_ty = OpTypeSampler
+ %image_ty = OpTypeImage %float 2D 0 0 0 1 Unknown
+ %sampled_image_ty = OpTypeSampledImage %image_ty
+ %ptr_sampled_image_ty = OpTypePointer UniformConstant %sampled_image_ty
+
+ %f_ty = OpTypeFunction %float %sampler_ty
+
+ ; CHECK: %f_ty = OpTypeFunction %float %sampler_ty
+
+ %main = OpFunction %void None %voidfn
+ %main_0 = OpLabel
+ OpReturn
+ OpFunctionEnd
diff --git a/test/tint/unittest/reader/combined_texture_sampler/FunctionTypeRemap_SplitCombinedImageSamplerPassFunctionTypeTest_ReplaceCombinedImageSamplersOnly_3.spvasm b/test/tint/unittest/reader/combined_texture_sampler/FunctionTypeRemap_SplitCombinedImageSamplerPassFunctionTypeTest_ReplaceCombinedImageSamplersOnly_3.spvasm
new file mode 100644
index 0000000..0a5997e
--- /dev/null
+++ b/test/tint/unittest/reader/combined_texture_sampler/FunctionTypeRemap_SplitCombinedImageSamplerPassFunctionTypeTest_ReplaceCombinedImageSamplersOnly_3.spvasm
@@ -0,0 +1,46 @@
+ OpCapability Shader
+ OpCapability RuntimeDescriptorArray
+ OpExtension "SPV_EXT_descriptor_indexing"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ OpName %main "main"
+ OpName %main_0 "main_0"
+ OpName %voidfn "voidfn"
+
+ OpName %f_ty "f_ty"
+ OpName %sampler_ty "sampler_ty"
+ OpName %image_ty "image_ty"
+ OpName %sampled_image_ty "sampled_image_ty"
+ OpName %ptr_sampled_image_ty "sampled_image_ty"
+
+ %float = OpTypeFloat 32
+ %uint = OpTypeInt 32 0
+ %int = OpTypeInt 32 1
+ %uint_0 = OpConstant %uint 0
+ %uint_1 = OpConstant %uint 1
+ %uint_3 = OpConstant %uint 3
+ %float_0 = OpConstant %float 0
+ %v2float = OpTypeVector %float 2
+ %v3float = OpTypeVector %float 3
+ %v4float = OpTypeVector %float 4
+ %13 = OpConstantNull %v2float
+ %14 = OpConstantNull %v3float
+ %15 = OpConstantNull %v4float
+ %void = OpTypeVoid
+ %voidfn = OpTypeFunction %void
+
+
+ %sampler_ty = OpTypeSampler
+ %image_ty = OpTypeImage %float 2D 0 0 0 1 Unknown
+ %sampled_image_ty = OpTypeSampledImage %image_ty
+ %ptr_sampled_image_ty = OpTypePointer UniformConstant %sampled_image_ty
+
+ %f_ty = OpTypeFunction %float %sampled_image_ty
+
+ ; CHECK: %f_ty = OpTypeFunction %float %image_ty %sampler_ty
+
+ %main = OpFunction %void None %voidfn
+ %main_0 = OpLabel
+ OpReturn
+ OpFunctionEnd
diff --git a/test/tint/unittest/reader/combined_texture_sampler/FunctionTypeRemap_SplitCombinedImageSamplerPassFunctionTypeTest_ReplaceCombinedImageSamplersOnly_4.spvasm b/test/tint/unittest/reader/combined_texture_sampler/FunctionTypeRemap_SplitCombinedImageSamplerPassFunctionTypeTest_ReplaceCombinedImageSamplersOnly_4.spvasm
new file mode 100644
index 0000000..adf93d6
--- /dev/null
+++ b/test/tint/unittest/reader/combined_texture_sampler/FunctionTypeRemap_SplitCombinedImageSamplerPassFunctionTypeTest_ReplaceCombinedImageSamplersOnly_4.spvasm
@@ -0,0 +1,46 @@
+ OpCapability Shader
+ OpCapability RuntimeDescriptorArray
+ OpExtension "SPV_EXT_descriptor_indexing"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ OpName %main "main"
+ OpName %main_0 "main_0"
+ OpName %voidfn "voidfn"
+
+ OpName %f_ty "f_ty"
+ OpName %sampler_ty "sampler_ty"
+ OpName %image_ty "image_ty"
+ OpName %sampled_image_ty "sampled_image_ty"
+ OpName %ptr_sampled_image_ty "sampled_image_ty"
+
+ %float = OpTypeFloat 32
+ %uint = OpTypeInt 32 0
+ %int = OpTypeInt 32 1
+ %uint_0 = OpConstant %uint 0
+ %uint_1 = OpConstant %uint 1
+ %uint_3 = OpConstant %uint 3
+ %float_0 = OpConstant %float 0
+ %v2float = OpTypeVector %float 2
+ %v3float = OpTypeVector %float 3
+ %v4float = OpTypeVector %float 4
+ %13 = OpConstantNull %v2float
+ %14 = OpConstantNull %v3float
+ %15 = OpConstantNull %v4float
+ %void = OpTypeVoid
+ %voidfn = OpTypeFunction %void
+
+
+ %sampler_ty = OpTypeSampler
+ %image_ty = OpTypeImage %float 2D 0 0 0 1 Unknown
+ %sampled_image_ty = OpTypeSampledImage %image_ty
+ %ptr_sampled_image_ty = OpTypePointer UniformConstant %sampled_image_ty
+
+ %f_ty = OpTypeFunction %float %uint %sampled_image_ty %float
+
+ ; CHECK: %f_ty = OpTypeFunction %float %uint %image_ty %sampler_ty %float
+
+ %main = OpFunction %void None %voidfn
+ %main_0 = OpLabel
+ OpReturn
+ OpFunctionEnd
diff --git a/test/tint/unittest/reader/combined_texture_sampler/FunctionTypeRemap_SplitCombinedImageSamplerPassFunctionTypeTest_ReplaceCombinedImageSamplersOnly_5.spvasm b/test/tint/unittest/reader/combined_texture_sampler/FunctionTypeRemap_SplitCombinedImageSamplerPassFunctionTypeTest_ReplaceCombinedImageSamplersOnly_5.spvasm
new file mode 100644
index 0000000..766ccc1
--- /dev/null
+++ b/test/tint/unittest/reader/combined_texture_sampler/FunctionTypeRemap_SplitCombinedImageSamplerPassFunctionTypeTest_ReplaceCombinedImageSamplersOnly_5.spvasm
@@ -0,0 +1,46 @@
+ OpCapability Shader
+ OpCapability RuntimeDescriptorArray
+ OpExtension "SPV_EXT_descriptor_indexing"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ OpName %main "main"
+ OpName %main_0 "main_0"
+ OpName %voidfn "voidfn"
+
+ OpName %f_ty "f_ty"
+ OpName %sampler_ty "sampler_ty"
+ OpName %image_ty "image_ty"
+ OpName %sampled_image_ty "sampled_image_ty"
+ OpName %ptr_sampled_image_ty "sampled_image_ty"
+
+ %float = OpTypeFloat 32
+ %uint = OpTypeInt 32 0
+ %int = OpTypeInt 32 1
+ %uint_0 = OpConstant %uint 0
+ %uint_1 = OpConstant %uint 1
+ %uint_3 = OpConstant %uint 3
+ %float_0 = OpConstant %float 0
+ %v2float = OpTypeVector %float 2
+ %v3float = OpTypeVector %float 3
+ %v4float = OpTypeVector %float 4
+ %13 = OpConstantNull %v2float
+ %14 = OpConstantNull %v3float
+ %15 = OpConstantNull %v4float
+ %void = OpTypeVoid
+ %voidfn = OpTypeFunction %void
+
+
+ %sampler_ty = OpTypeSampler
+ %image_ty = OpTypeImage %float 2D 0 0 0 1 Unknown
+ %sampled_image_ty = OpTypeSampledImage %image_ty
+ %ptr_sampled_image_ty = OpTypePointer UniformConstant %sampled_image_ty
+
+ %f_ty = OpTypeFunction %float %ptr_sampled_image_ty
+
+ ; CHECK: %f_ty = OpTypeFunction %float %_ptr_UniformConstant_image_ty %_ptr_UniformConstant_sampler_ty
+
+ %main = OpFunction %void None %voidfn
+ %main_0 = OpLabel
+ OpReturn
+ OpFunctionEnd
diff --git a/test/tint/unittest/reader/combined_texture_sampler/FunctionTypeRemap_SplitCombinedImageSamplerPassFunctionTypeTest_ReplaceCombinedImageSamplersOnly_6.spvasm b/test/tint/unittest/reader/combined_texture_sampler/FunctionTypeRemap_SplitCombinedImageSamplerPassFunctionTypeTest_ReplaceCombinedImageSamplersOnly_6.spvasm
new file mode 100644
index 0000000..91744cd
--- /dev/null
+++ b/test/tint/unittest/reader/combined_texture_sampler/FunctionTypeRemap_SplitCombinedImageSamplerPassFunctionTypeTest_ReplaceCombinedImageSamplersOnly_6.spvasm
@@ -0,0 +1,46 @@
+ OpCapability Shader
+ OpCapability RuntimeDescriptorArray
+ OpExtension "SPV_EXT_descriptor_indexing"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ OpName %main "main"
+ OpName %main_0 "main_0"
+ OpName %voidfn "voidfn"
+
+ OpName %f_ty "f_ty"
+ OpName %sampler_ty "sampler_ty"
+ OpName %image_ty "image_ty"
+ OpName %sampled_image_ty "sampled_image_ty"
+ OpName %ptr_sampled_image_ty "sampled_image_ty"
+
+ %float = OpTypeFloat 32
+ %uint = OpTypeInt 32 0
+ %int = OpTypeInt 32 1
+ %uint_0 = OpConstant %uint 0
+ %uint_1 = OpConstant %uint 1
+ %uint_3 = OpConstant %uint 3
+ %float_0 = OpConstant %float 0
+ %v2float = OpTypeVector %float 2
+ %v3float = OpTypeVector %float 3
+ %v4float = OpTypeVector %float 4
+ %13 = OpConstantNull %v2float
+ %14 = OpConstantNull %v3float
+ %15 = OpConstantNull %v4float
+ %void = OpTypeVoid
+ %voidfn = OpTypeFunction %void
+
+
+ %sampler_ty = OpTypeSampler
+ %image_ty = OpTypeImage %float 2D 0 0 0 1 Unknown
+ %sampled_image_ty = OpTypeSampledImage %image_ty
+ %ptr_sampled_image_ty = OpTypePointer UniformConstant %sampled_image_ty
+
+ %f_ty = OpTypeFunction %float %uint %ptr_sampled_image_ty %float
+
+ ; CHECK: %f_ty = OpTypeFunction %float %uint %_ptr_UniformConstant_image_ty %_ptr_UniformConstant_sampler_ty %float
+
+ %main = OpFunction %void None %voidfn
+ %main_0 = OpLabel
+ OpReturn
+ OpFunctionEnd
diff --git a/test/tint/unittest/reader/combined_texture_sampler/FunctionTypeRemap_SplitCombinedImageSamplerPassFunctionTypeTest_ReplaceCombinedImageSamplersOnly_7.spvasm b/test/tint/unittest/reader/combined_texture_sampler/FunctionTypeRemap_SplitCombinedImageSamplerPassFunctionTypeTest_ReplaceCombinedImageSamplersOnly_7.spvasm
new file mode 100644
index 0000000..32f5443
--- /dev/null
+++ b/test/tint/unittest/reader/combined_texture_sampler/FunctionTypeRemap_SplitCombinedImageSamplerPassFunctionTypeTest_ReplaceCombinedImageSamplersOnly_7.spvasm
@@ -0,0 +1,46 @@
+ OpCapability Shader
+ OpCapability RuntimeDescriptorArray
+ OpExtension "SPV_EXT_descriptor_indexing"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ OpName %main "main"
+ OpName %main_0 "main_0"
+ OpName %voidfn "voidfn"
+
+ OpName %f_ty "f_ty"
+ OpName %sampler_ty "sampler_ty"
+ OpName %image_ty "image_ty"
+ OpName %sampled_image_ty "sampled_image_ty"
+ OpName %ptr_sampled_image_ty "sampled_image_ty"
+
+ %float = OpTypeFloat 32
+ %uint = OpTypeInt 32 0
+ %int = OpTypeInt 32 1
+ %uint_0 = OpConstant %uint 0
+ %uint_1 = OpConstant %uint 1
+ %uint_3 = OpConstant %uint 3
+ %float_0 = OpConstant %float 0
+ %v2float = OpTypeVector %float 2
+ %v3float = OpTypeVector %float 3
+ %v4float = OpTypeVector %float 4
+ %13 = OpConstantNull %v2float
+ %14 = OpConstantNull %v3float
+ %15 = OpConstantNull %v4float
+ %void = OpTypeVoid
+ %voidfn = OpTypeFunction %void
+
+
+ %sampler_ty = OpTypeSampler
+ %image_ty = OpTypeImage %float 2D 0 0 0 1 Unknown
+ %sampled_image_ty = OpTypeSampledImage %image_ty
+ %ptr_sampled_image_ty = OpTypePointer UniformConstant %sampled_image_ty
+
+ %f_ty = OpTypeFunction %float %uint %ptr_sampled_image_ty %ptr_sampled_image_ty %float
+
+ ; CHECK: %f_ty = OpTypeFunction %float %uint %_ptr_UniformConstant_image_ty %_ptr_UniformConstant_sampler_ty %_ptr_UniformConstant_image_ty %_ptr_UniformConstant_sampler_ty %float
+
+ %main = OpFunction %void None %voidfn
+ %main_0 = OpLabel
+ OpReturn
+ OpFunctionEnd
diff --git a/test/tint/unittest/reader/combined_texture_sampler/ResolveBindingConflictsTest_MultiEntryPoint_ConflictCascade_Resolves.spvasm b/test/tint/unittest/reader/combined_texture_sampler/ResolveBindingConflictsTest_MultiEntryPoint_ConflictCascade_Resolves.spvasm
new file mode 100644
index 0000000..68a1f24
--- /dev/null
+++ b/test/tint/unittest/reader/combined_texture_sampler/ResolveBindingConflictsTest_MultiEntryPoint_ConflictCascade_Resolves.spvasm
@@ -0,0 +1,107 @@
+ OpCapability Shader
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %alpha "alpha"
+ OpEntryPoint GLCompute %beta "beta"
+ OpEntryPoint GLCompute %gamma "gamma"
+ OpEntryPoint GLCompute %delta "delta"
+ OpExecutionMode %alpha LocalSize 1 1 1
+ OpExecutionMode %beta LocalSize 1 1 1
+ OpExecutionMode %gamma LocalSize 1 1 1
+ OpExecutionMode %delta LocalSize 1 1 1
+ OpName %alpha "alpha"
+ OpName %beta "beta"
+ OpName %gamma "gamma"
+ OpName %delta "delta"
+ OpName %voidfn "voidfn"
+ OpName %s_ty "s_ty"
+ OpName %i_ty "i_ty"
+ OpName %si_ty "si_ty"
+ OpName %p_s_ty "p_s_ty"
+ OpName %p_i_ty "p_i_ty"
+ OpName %p_si_ty "p_si_ty"
+ OpName %st_ty "st_ty"
+ OpName %pu_st_ty "pu_st_ty"
+ OpName %pb_st_ty "pb_st_ty"
+
+ OpDecorate %100 DescriptorSet 0 ; The sampler
+ OpDecorate %100 Binding 0
+ OpDecorate %101 DescriptorSet 0
+ OpDecorate %101 Binding 0
+ OpDecorate %102 DescriptorSet 0
+ OpDecorate %102 Binding 1
+ OpDecorate %103 DescriptorSet 0
+ OpDecorate %103 Binding 2
+ OpDecorate %104 DescriptorSet 0
+ OpDecorate %104 Binding 3
+
+ ; %100 is bumped once:
+ ; CHECK: OpDecorate %100 DescriptorSet 0
+ ; CHECK: OpDecorate %100 Binding 1
+
+ ; CHECK: OpDecorate %101 DescriptorSet 0
+ ; CHECK: OpDecorate %101 Binding 0
+
+ ; pushed back from bump of %100
+ ; CHECK: OpDecorate %102 DescriptorSet 0
+ ; CHECK: OpDecorate %102 Binding 2
+
+ ; pushed back from bump of %102
+ ; CHECK: OpDecorate %103 DescriptorSet 0
+ ; CHECK: OpDecorate %103 Binding 3
+
+ ; pushed back from bump of %103
+ ; CHECK: OpDecorate %104 DescriptorSet 0
+ ; CHECK: OpDecorate %104 Binding 4
+
+ OpDecorate %st_ty Block
+ OpMemberDecorate %st_ty 0 Offset 0
+ %float = OpTypeFloat 32
+ %uint = OpTypeInt 32 0
+ %uint_0 = OpConstant %uint 0
+ %uint_3 = OpConstant %uint 3
+ %void = OpTypeVoid
+ %voidfn = OpTypeFunction %void
+ %s_ty = OpTypeSampler
+ %i_ty = OpTypeImage %float 2D 0 0 0 1 Unknown
+ %si_ty = OpTypeSampledImage %i_ty
+ %p_i_ty = OpTypePointer UniformConstant %i_ty
+ %p_s_ty = OpTypePointer UniformConstant %s_ty
+ %p_si_ty = OpTypePointer UniformConstant %si_ty
+ %st_ty = OpTypeStruct %uint
+ %pu_st_ty = OpTypePointer Uniform %st_ty
+ %pb_st_ty = OpTypePointer StorageBuffer %st_ty
+
+
+ %100 = OpVariable %p_s_ty UniformConstant ; used in alpha, beta
+ %101 = OpVariable %p_i_ty UniformConstant ; used in alpha
+ %102 = OpVariable %pu_st_ty Uniform ; used in beta, gamma
+ %103 = OpVariable %pb_st_ty StorageBuffer ; used in gamma, delta
+ %104 = OpVariable %p_si_ty UniformConstant ; used delta
+
+ %alpha = OpFunction %void None %voidfn
+ %1000 = OpLabel
+ %1001 = OpCopyObject %p_s_ty %100
+ %1002 = OpCopyObject %p_i_ty %101
+ OpReturn
+ OpFunctionEnd
+
+ %beta = OpFunction %void None %voidfn
+ %2000 = OpLabel
+ %2001 = OpCopyObject %p_s_ty %100
+ %2002 = OpCopyObject %pu_st_ty %102
+ OpReturn
+ OpFunctionEnd
+
+ %gamma = OpFunction %void None %voidfn
+ %3000 = OpLabel
+ %3001 = OpCopyObject %pu_st_ty %102
+ %3002 = OpCopyObject %pb_st_ty %103
+ OpReturn
+ OpFunctionEnd
+
+ %delta = OpFunction %void None %voidfn
+ %4000 = OpLabel
+ %4001 = OpCopyObject %pb_st_ty %103
+ %4002 = OpCopyObject %p_si_ty %104
+ OpReturn
+ OpFunctionEnd
diff --git a/test/tint/unittest/reader/combined_texture_sampler/ResolveBindingConflictsTest_MultiEntryPoint_ConflictCascade_RevisitEntryPoint.spvasm b/test/tint/unittest/reader/combined_texture_sampler/ResolveBindingConflictsTest_MultiEntryPoint_ConflictCascade_RevisitEntryPoint.spvasm
new file mode 100644
index 0000000..93c01d1
--- /dev/null
+++ b/test/tint/unittest/reader/combined_texture_sampler/ResolveBindingConflictsTest_MultiEntryPoint_ConflictCascade_RevisitEntryPoint.spvasm
@@ -0,0 +1,89 @@
+ OpCapability Shader
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %alpha "alpha"
+ OpEntryPoint GLCompute %beta "beta"
+ OpExecutionMode %alpha LocalSize 1 1 1
+ OpExecutionMode %beta LocalSize 1 1 1
+ OpName %alpha "alpha"
+ OpName %beta "beta"
+ OpName %voidfn "voidfn"
+ OpName %s_ty "s_ty"
+ OpName %i_ty "i_ty"
+ OpName %si_ty "si_ty"
+ OpName %p_s_ty "p_s_ty"
+ OpName %p_i_ty "p_i_ty"
+ OpName %p_si_ty "p_si_ty"
+ OpName %st_ty "st_ty"
+ OpName %pu_st_ty "pu_st_ty"
+ OpName %pb_st_ty "pb_st_ty"
+
+ OpDecorate %100 DescriptorSet 0
+ OpDecorate %100 Binding 0
+ OpDecorate %101 DescriptorSet 0 ; the sampler
+ OpDecorate %101 Binding 0
+ OpDecorate %102 DescriptorSet 0
+ OpDecorate %102 Binding 1
+ OpDecorate %103 DescriptorSet 0
+ OpDecorate %103 Binding 2
+ OpDecorate %104 DescriptorSet 0
+ OpDecorate %104 Binding 3
+ OpDecorate %105 DescriptorSet 0
+ OpDecorate %105 Binding 4
+
+ ; CHECK: OpDecorate %100 DescriptorSet 0
+ ; CHECK: OpDecorate %100 Binding 0
+ ; CHECK: OpDecorate %101 DescriptorSet 0
+ ; CHECK: OpDecorate %101 Binding 1
+ ; CHECK: OpDecorate %102 DescriptorSet 0
+ ; CHECK: OpDecorate %102 Binding 2
+ ; CHECK: OpDecorate %103 DescriptorSet 0
+ ; CHECK: OpDecorate %103 Binding 3
+ ; CHECK: OpDecorate %104 DescriptorSet 0
+ ; CHECK: OpDecorate %104 Binding 4
+ ; CHECK: OpDecorate %105 DescriptorSet 0
+ ; CHECK: OpDecorate %105 Binding 5
+
+ OpDecorate %st_ty Block
+ OpMemberDecorate %st_ty 0 Offset 0
+ %float = OpTypeFloat 32
+ %uint = OpTypeInt 32 0
+ %uint_0 = OpConstant %uint 0
+ %uint_3 = OpConstant %uint 3
+ %void = OpTypeVoid
+ %voidfn = OpTypeFunction %void
+ %s_ty = OpTypeSampler
+ %i_ty = OpTypeImage %float 2D 0 0 0 1 Unknown
+ %si_ty = OpTypeSampledImage %i_ty
+ %p_i_ty = OpTypePointer UniformConstant %i_ty
+ %p_s_ty = OpTypePointer UniformConstant %s_ty
+ %p_si_ty = OpTypePointer UniformConstant %si_ty
+ %st_ty = OpTypeStruct %uint
+ %pu_st_ty = OpTypePointer Uniform %st_ty
+ %pb_st_ty = OpTypePointer StorageBuffer %st_ty
+
+
+ %100 = OpVariable %p_i_ty UniformConstant
+ %101 = OpVariable %p_s_ty UniformConstant
+ %102 = OpVariable %pu_st_ty Uniform
+ %103 = OpVariable %pb_st_ty StorageBuffer
+ %104 = OpVariable %p_si_ty UniformConstant
+ %105 = OpVariable %p_s_ty UniformConstant
+
+ %alpha = OpFunction %void None %voidfn
+ %1000 = OpLabel
+ %1001 = OpCopyObject %p_i_ty %100
+ %1002 = OpCopyObject %p_s_ty %101
+ %1003 = OpCopyObject %pb_st_ty %103
+ %1004 = OpCopyObject %p_si_ty %104
+ %1005 = OpCopyObject %p_s_ty %105
+ OpReturn
+ OpFunctionEnd
+
+ %beta = OpFunction %void None %voidfn
+ %2000 = OpLabel
+ %2001 = OpCopyObject %p_s_ty %101
+ %2002 = OpCopyObject %pu_st_ty %102
+ %2003 = OpCopyObject %pb_st_ty %103
+ %2004 = OpCopyObject %p_s_ty %105
+ OpReturn
+ OpFunctionEnd
diff --git a/test/tint/unittest/reader/combined_texture_sampler/ResolveBindingConflictsTest_MultiEntryPoint_DuplicatConflicts_ResolvesOnlyOnce.spvasm b/test/tint/unittest/reader/combined_texture_sampler/ResolveBindingConflictsTest_MultiEntryPoint_DuplicatConflicts_ResolvesOnlyOnce.spvasm
new file mode 100644
index 0000000..8f38350
--- /dev/null
+++ b/test/tint/unittest/reader/combined_texture_sampler/ResolveBindingConflictsTest_MultiEntryPoint_DuplicatConflicts_ResolvesOnlyOnce.spvasm
@@ -0,0 +1,64 @@
+ OpCapability Shader
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %alpha "alpha"
+ OpEntryPoint GLCompute %beta "beta"
+ OpExecutionMode %alpha LocalSize 1 1 1
+ OpExecutionMode %beta LocalSize 1 1 1
+ OpName %alpha "alpha"
+ OpName %beta "beta"
+ OpName %voidfn "voidfn"
+ OpName %s_ty "s_ty"
+ OpName %i_ty "i_ty"
+ OpName %si_ty "si_ty"
+ OpName %p_s_ty "p_s_ty"
+ OpName %p_i_ty "p_i_ty"
+ OpName %p_si_ty "p_si_ty"
+ OpName %st_ty "st_ty"
+ OpName %pu_st_ty "pu_st_ty"
+ OpName %pb_st_ty "pb_st_ty"
+
+ OpDecorate %100 DescriptorSet 0
+ OpDecorate %100 Binding 0
+ OpDecorate %101 DescriptorSet 0
+ OpDecorate %101 Binding 0
+
+ ; CHECK: OpDecorate %100 DescriptorSet 0
+ ; CHECK: OpDecorate %100 Binding 1
+ ; CHECK: OpDecorate %101 DescriptorSet 0
+ ; CHECK: OpDecorate %101 Binding 0
+
+ OpDecorate %st_ty Block
+ OpMemberDecorate %st_ty 0 Offset 0
+ %float = OpTypeFloat 32
+ %uint = OpTypeInt 32 0
+ %uint_0 = OpConstant %uint 0
+ %uint_3 = OpConstant %uint 3
+ %void = OpTypeVoid
+ %voidfn = OpTypeFunction %void
+ %s_ty = OpTypeSampler
+ %i_ty = OpTypeImage %float 2D 0 0 0 1 Unknown
+ %si_ty = OpTypeSampledImage %i_ty
+ %p_i_ty = OpTypePointer UniformConstant %i_ty
+ %p_s_ty = OpTypePointer UniformConstant %s_ty
+ %p_si_ty = OpTypePointer UniformConstant %si_ty
+ %st_ty = OpTypeStruct %uint
+ %pu_st_ty = OpTypePointer Uniform %st_ty
+ %pb_st_ty = OpTypePointer StorageBuffer %st_ty
+
+
+ %100 = OpVariable %p_s_ty UniformConstant
+ %101 = OpVariable %p_i_ty UniformConstant
+
+ %alpha = OpFunction %void None %voidfn
+ %1000 = OpLabel
+ %1001 = OpCopyObject %p_s_ty %100
+ %1002 = OpCopyObject %p_i_ty %101
+ OpReturn
+ OpFunctionEnd
+
+ %beta = OpFunction %void None %voidfn
+ %2000 = OpLabel
+ %2001 = OpCopyObject %p_s_ty %100
+ %2002 = OpCopyObject %p_i_ty %101
+ OpReturn
+ OpFunctionEnd
diff --git a/test/tint/unittest/reader/combined_texture_sampler/ResolveBindingConflictsTest_MultiEntryPoint_IndependentConflicts_Resolves.spvasm b/test/tint/unittest/reader/combined_texture_sampler/ResolveBindingConflictsTest_MultiEntryPoint_IndependentConflicts_Resolves.spvasm
new file mode 100644
index 0000000..db74870
--- /dev/null
+++ b/test/tint/unittest/reader/combined_texture_sampler/ResolveBindingConflictsTest_MultiEntryPoint_IndependentConflicts_Resolves.spvasm
@@ -0,0 +1,74 @@
+ OpCapability Shader
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %alpha "alpha"
+ OpEntryPoint GLCompute %beta "beta"
+ OpExecutionMode %alpha LocalSize 1 1 1
+ OpExecutionMode %beta LocalSize 1 1 1
+ OpName %alpha "alpha"
+ OpName %beta "beta"
+ OpName %voidfn "voidfn"
+ OpName %s_ty "s_ty"
+ OpName %i_ty "i_ty"
+ OpName %si_ty "si_ty"
+ OpName %p_s_ty "p_s_ty"
+ OpName %p_i_ty "p_i_ty"
+ OpName %p_si_ty "p_si_ty"
+ OpName %st_ty "st_ty"
+ OpName %pu_st_ty "pu_st_ty"
+ OpName %pb_st_ty "pb_st_ty"
+
+ OpDecorate %100 DescriptorSet 0
+ OpDecorate %100 Binding 0
+ OpDecorate %101 DescriptorSet 0
+ OpDecorate %101 Binding 0
+ OpDecorate %102 DescriptorSet 0
+ OpDecorate %102 Binding 0
+ OpDecorate %103 DescriptorSet 0
+ OpDecorate %103 Binding 0
+
+ ; CHECK: OpDecorate %100 DescriptorSet 0
+ ; CHECK: OpDecorate %100 Binding 1
+ ; CHECK: OpDecorate %101 DescriptorSet 0
+ ; CHECK: OpDecorate %101 Binding 0
+ ; CHECK: OpDecorate %102 DescriptorSet 0
+ ; CHECK: OpDecorate %102 Binding 0
+ ; CHECK: OpDecorate %103 DescriptorSet 0
+ ; CHECK: OpDecorate %103 Binding 1
+
+ OpDecorate %st_ty Block
+ OpMemberDecorate %st_ty 0 Offset 0
+ %float = OpTypeFloat 32
+ %uint = OpTypeInt 32 0
+ %uint_0 = OpConstant %uint 0
+ %uint_3 = OpConstant %uint 3
+ %void = OpTypeVoid
+ %voidfn = OpTypeFunction %void
+ %s_ty = OpTypeSampler
+ %i_ty = OpTypeImage %float 2D 0 0 0 1 Unknown
+ %si_ty = OpTypeSampledImage %i_ty
+ %p_i_ty = OpTypePointer UniformConstant %i_ty
+ %p_s_ty = OpTypePointer UniformConstant %s_ty
+ %p_si_ty = OpTypePointer UniformConstant %si_ty
+ %st_ty = OpTypeStruct %uint
+ %pu_st_ty = OpTypePointer Uniform %st_ty
+ %pb_st_ty = OpTypePointer StorageBuffer %st_ty
+
+
+ %100 = OpVariable %p_s_ty UniformConstant
+ %101 = OpVariable %p_i_ty UniformConstant
+ %102 = OpVariable %p_i_ty UniformConstant
+ %103 = OpVariable %p_s_ty UniformConstant
+
+ %alpha = OpFunction %void None %voidfn
+ %1000 = OpLabel
+ %1001 = OpCopyObject %p_s_ty %100
+ %1002 = OpCopyObject %p_i_ty %101
+ OpReturn
+ OpFunctionEnd
+
+ %beta = OpFunction %void None %voidfn
+ %2000 = OpLabel
+ %2001 = OpCopyObject %p_i_ty %102
+ %2002 = OpCopyObject %p_s_ty %103
+ OpReturn
+ OpFunctionEnd
diff --git a/test/tint/unittest/reader/combined_texture_sampler/ResolveBindingConflictsTest_MultiEntryPoint_SameVarConflictsAcrossMultiEntryPoints_Resolves.spvasm b/test/tint/unittest/reader/combined_texture_sampler/ResolveBindingConflictsTest_MultiEntryPoint_SameVarConflictsAcrossMultiEntryPoints_Resolves.spvasm
new file mode 100644
index 0000000..8921ad4
--- /dev/null
+++ b/test/tint/unittest/reader/combined_texture_sampler/ResolveBindingConflictsTest_MultiEntryPoint_SameVarConflictsAcrossMultiEntryPoints_Resolves.spvasm
@@ -0,0 +1,90 @@
+ OpCapability Shader
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %alpha "alpha"
+ OpEntryPoint GLCompute %beta "beta"
+ OpEntryPoint GLCompute %gamma "gamma"
+ OpExecutionMode %alpha LocalSize 1 1 1
+ OpExecutionMode %beta LocalSize 1 1 1
+ OpExecutionMode %gamma LocalSize 1 1 1
+ OpName %alpha "alpha"
+ OpName %beta "beta"
+ OpName %gamma "gamma"
+ OpName %voidfn "voidfn"
+ OpName %s_ty "s_ty"
+ OpName %i_ty "i_ty"
+ OpName %si_ty "si_ty"
+ OpName %p_s_ty "p_s_ty"
+ OpName %p_i_ty "p_i_ty"
+ OpName %p_si_ty "p_si_ty"
+ OpName %st_ty "st_ty"
+ OpName %pu_st_ty "pu_st_ty"
+ OpName %pb_st_ty "pb_st_ty"
+
+ OpDecorate %100 DescriptorSet 0 ; The sampler
+ OpDecorate %100 Binding 0
+ OpDecorate %101 DescriptorSet 0
+ OpDecorate %101 Binding 0
+ OpDecorate %102 DescriptorSet 0
+ OpDecorate %102 Binding 1
+ OpDecorate %103 DescriptorSet 0
+ OpDecorate %103 Binding 2
+
+ ; bumped once
+ ; CHECK: OpDecorate %100 DescriptorSet 0
+ ; CHECK: OpDecorate %100 Binding 1
+
+ ; CHECK: OpDecorate %101 DescriptorSet 0
+ ; CHECK: OpDecorate %101 Binding 0
+
+ ; pushed back from bump of %100
+ ; CHECK: OpDecorate %102 DescriptorSet 0
+ ; CHECK: OpDecorate %102 Binding 2
+
+ ; does not need to be bumped
+ ; CHECK: OpDecorate %103 DescriptorSet 0
+ ; CHECK: OpDecorate %103 Binding 2
+
+ OpDecorate %st_ty Block
+ OpMemberDecorate %st_ty 0 Offset 0
+ %float = OpTypeFloat 32
+ %uint = OpTypeInt 32 0
+ %uint_0 = OpConstant %uint 0
+ %uint_3 = OpConstant %uint 3
+ %void = OpTypeVoid
+ %voidfn = OpTypeFunction %void
+ %s_ty = OpTypeSampler
+ %i_ty = OpTypeImage %float 2D 0 0 0 1 Unknown
+ %si_ty = OpTypeSampledImage %i_ty
+ %p_i_ty = OpTypePointer UniformConstant %i_ty
+ %p_s_ty = OpTypePointer UniformConstant %s_ty
+ %p_si_ty = OpTypePointer UniformConstant %si_ty
+ %st_ty = OpTypeStruct %uint
+ %pu_st_ty = OpTypePointer Uniform %st_ty
+ %pb_st_ty = OpTypePointer StorageBuffer %st_ty
+
+
+ %100 = OpVariable %p_s_ty UniformConstant ; used in alpha, beta, gamma
+ %101 = OpVariable %p_i_ty UniformConstant ; used in alpha
+ %102 = OpVariable %pu_st_ty Uniform ; used in beta
+ %103 = OpVariable %pb_st_ty StorageBuffer ; used in gamma
+
+ %alpha = OpFunction %void None %voidfn
+ %1000 = OpLabel
+ %1001 = OpCopyObject %p_s_ty %100
+ %1002 = OpCopyObject %p_i_ty %101
+ OpReturn
+ OpFunctionEnd
+
+ %beta = OpFunction %void None %voidfn
+ %2000 = OpLabel
+ %2001 = OpCopyObject %p_s_ty %100
+ %2002 = OpCopyObject %pu_st_ty %102
+ OpReturn
+ OpFunctionEnd
+
+ %gamma = OpFunction %void None %voidfn
+ %3000 = OpLabel
+ %3001 = OpCopyObject %p_s_ty %100
+ %3002 = OpCopyObject %pb_st_ty %103
+ OpReturn
+ OpFunctionEnd
diff --git a/test/tint/unittest/reader/combined_texture_sampler/ResolveBindingConflictsTest_NoBindings_NoChange.spvasm b/test/tint/unittest/reader/combined_texture_sampler/ResolveBindingConflictsTest_NoBindings_NoChange.spvasm
new file mode 100644
index 0000000..44f414e
--- /dev/null
+++ b/test/tint/unittest/reader/combined_texture_sampler/ResolveBindingConflictsTest_NoBindings_NoChange.spvasm
@@ -0,0 +1,36 @@
+ OpCapability Shader
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ OpName %main "main"
+ OpName %voidfn "voidfn"
+ OpName %s_ty "s_ty"
+ OpName %i_ty "i_ty"
+ OpName %si_ty "si_ty"
+ OpName %p_s_ty "p_s_ty"
+ OpName %p_i_ty "p_i_ty"
+ OpName %p_si_ty "p_si_ty"
+ OpName %st_ty "st_ty"
+ OpName %pu_st_ty "pu_st_ty"
+ OpName %pb_st_ty "pb_st_ty"
+ OpDecorate %st_ty Block
+ OpMemberDecorate %st_ty 0 Offset 0
+ %float = OpTypeFloat 32
+ %uint = OpTypeInt 32 0
+ %uint_0 = OpConstant %uint 0
+ %uint_3 = OpConstant %uint 3
+ %void = OpTypeVoid
+ %voidfn = OpTypeFunction %void
+ %s_ty = OpTypeSampler
+ %i_ty = OpTypeImage %float 2D 0 0 0 1 Unknown
+ %si_ty = OpTypeSampledImage %i_ty
+ %p_i_ty = OpTypePointer UniformConstant %i_ty
+ %p_s_ty = OpTypePointer UniformConstant %s_ty
+ %p_si_ty = OpTypePointer UniformConstant %si_ty
+ %st_ty = OpTypeStruct %uint
+ %pu_st_ty = OpTypePointer Uniform %st_ty
+ %pb_st_ty = OpTypePointer StorageBuffer %st_ty
+ %main = OpFunction %void None %voidfn
+ %100 = OpLabel
+ OpReturn
+ OpFunctionEnd
diff --git a/test/tint/unittest/reader/combined_texture_sampler/ResolveBindingConflictsTest_NoConflict_UnusedVars_NoChange.spvasm b/test/tint/unittest/reader/combined_texture_sampler/ResolveBindingConflictsTest_NoConflict_UnusedVars_NoChange.spvasm
new file mode 100644
index 0000000..8435009
--- /dev/null
+++ b/test/tint/unittest/reader/combined_texture_sampler/ResolveBindingConflictsTest_NoConflict_UnusedVars_NoChange.spvasm
@@ -0,0 +1,69 @@
+ OpCapability Shader
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ OpName %main "main"
+ OpName %voidfn "voidfn"
+ OpName %s_ty "s_ty"
+ OpName %i_ty "i_ty"
+ OpName %si_ty "si_ty"
+ OpName %p_s_ty "p_s_ty"
+ OpName %p_i_ty "p_i_ty"
+ OpName %p_si_ty "p_si_ty"
+ OpName %st_ty "st_ty"
+ OpName %pu_st_ty "pu_st_ty"
+ OpName %pb_st_ty "pb_st_ty"
+
+ OpDecorate %100 DescriptorSet 0
+ OpDecorate %100 Binding 0
+ OpDecorate %101 DescriptorSet 0
+ OpDecorate %101 Binding 0
+ OpDecorate %102 DescriptorSet 0
+ OpDecorate %102 Binding 0
+ OpDecorate %103 DescriptorSet 0
+ OpDecorate %103 Binding 0
+ OpDecorate %104 DescriptorSet 0
+ OpDecorate %104 Binding 0
+
+ ; CHECK: OpDecorate %100 DescriptorSet 0
+ ; CHECK: OpDecorate %100 Binding 0
+ ; CHECK: OpDecorate %101 DescriptorSet 0
+ ; CHECK: OpDecorate %101 Binding 0
+ ; CHECK: OpDecorate %102 DescriptorSet 0
+ ; CHECK: OpDecorate %102 Binding 0
+ ; CHECK: OpDecorate %103 DescriptorSet 0
+ ; CHECK: OpDecorate %103 Binding 0
+ ; CHECK: OpDecorate %104 DescriptorSet 0
+ ; CHECK: OpDecorate %104 Binding 0
+
+ OpDecorate %st_ty Block
+ OpMemberDecorate %st_ty 0 Offset 0
+ %float = OpTypeFloat 32
+ %uint = OpTypeInt 32 0
+ %uint_0 = OpConstant %uint 0
+ %uint_3 = OpConstant %uint 3
+ %void = OpTypeVoid
+ %voidfn = OpTypeFunction %void
+ %s_ty = OpTypeSampler
+ %i_ty = OpTypeImage %float 2D 0 0 0 1 Unknown
+ %si_ty = OpTypeSampledImage %i_ty
+ %p_i_ty = OpTypePointer UniformConstant %i_ty
+ %p_s_ty = OpTypePointer UniformConstant %s_ty
+ %p_si_ty = OpTypePointer UniformConstant %si_ty
+ %st_ty = OpTypeStruct %uint
+ %pu_st_ty = OpTypePointer Uniform %st_ty
+ %pb_st_ty = OpTypePointer StorageBuffer %st_ty
+
+
+ ; Unused variables
+
+ %100 = OpVariable %p_i_ty UniformConstant ; image
+ %101 = OpVariable %p_s_ty UniformConstant ; sampler
+ %102 = OpVariable %pu_st_ty Uniform ; UBO
+ %103 = OpVariable %pb_st_ty StorageBuffer ; SSBO
+ %104 = OpVariable %p_si_ty UniformConstant ; combined sampled image
+
+ %main = OpFunction %void None %voidfn
+ %10 = OpLabel
+ OpReturn
+ OpFunctionEnd
diff --git a/test/tint/unittest/reader/combined_texture_sampler/ResolveBindingConflictsTest_NoConflict_UsedVars_NoChange.spvasm b/test/tint/unittest/reader/combined_texture_sampler/ResolveBindingConflictsTest_NoConflict_UsedVars_NoChange.spvasm
new file mode 100644
index 0000000..210779a
--- /dev/null
+++ b/test/tint/unittest/reader/combined_texture_sampler/ResolveBindingConflictsTest_NoConflict_UsedVars_NoChange.spvasm
@@ -0,0 +1,72 @@
+ OpCapability Shader
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ OpName %main "main"
+ OpName %voidfn "voidfn"
+ OpName %s_ty "s_ty"
+ OpName %i_ty "i_ty"
+ OpName %si_ty "si_ty"
+ OpName %p_s_ty "p_s_ty"
+ OpName %p_i_ty "p_i_ty"
+ OpName %p_si_ty "p_si_ty"
+ OpName %st_ty "st_ty"
+ OpName %pu_st_ty "pu_st_ty"
+ OpName %pb_st_ty "pb_st_ty"
+
+ OpDecorate %100 DescriptorSet 0
+ OpDecorate %100 Binding 0
+ OpDecorate %101 DescriptorSet 0
+ OpDecorate %101 Binding 1
+ OpDecorate %102 DescriptorSet 0
+ OpDecorate %102 Binding 2
+ OpDecorate %103 DescriptorSet 0
+ OpDecorate %103 Binding 3
+ OpDecorate %110 DescriptorSet 1
+ OpDecorate %110 Binding 0
+
+ ; CHECK: OpDecorate %100 DescriptorSet 0
+ ; CHECK: OpDecorate %100 Binding 0
+ ; CHECK: OpDecorate %101 DescriptorSet 0
+ ; CHECK: OpDecorate %101 Binding 1
+ ; CHECK: OpDecorate %102 DescriptorSet 0
+ ; CHECK: OpDecorate %102 Binding 2
+ ; CHECK: OpDecorate %103 DescriptorSet 0
+ ; CHECK: OpDecorate %103 Binding 3
+ ; CHECK: OpDecorate %110 DescriptorSet 1
+ ; CHECK: OpDecorate %110 Binding 0
+
+ OpDecorate %st_ty Block
+ OpMemberDecorate %st_ty 0 Offset 0
+ %float = OpTypeFloat 32
+ %uint = OpTypeInt 32 0
+ %uint_0 = OpConstant %uint 0
+ %uint_3 = OpConstant %uint 3
+ %void = OpTypeVoid
+ %voidfn = OpTypeFunction %void
+ %s_ty = OpTypeSampler
+ %i_ty = OpTypeImage %float 2D 0 0 0 1 Unknown
+ %si_ty = OpTypeSampledImage %i_ty
+ %p_i_ty = OpTypePointer UniformConstant %i_ty
+ %p_s_ty = OpTypePointer UniformConstant %s_ty
+ %p_si_ty = OpTypePointer UniformConstant %si_ty
+ %st_ty = OpTypeStruct %uint
+ %pu_st_ty = OpTypePointer Uniform %st_ty
+ %pb_st_ty = OpTypePointer StorageBuffer %st_ty
+
+
+ %100 = OpVariable %p_i_ty UniformConstant ; image
+ %101 = OpVariable %p_s_ty UniformConstant ; sampler
+ %102 = OpVariable %pu_st_ty Uniform ; UBO
+ %103 = OpVariable %pb_st_ty StorageBuffer ; SSBO
+ %110 = OpVariable %p_si_ty UniformConstant ; combined sampled image
+
+ %main = OpFunction %void None %voidfn
+ %10 = OpLabel
+ %11 = OpCopyObject %p_i_ty %100
+ %12 = OpCopyObject %p_s_ty %101
+ %13 = OpCopyObject %pu_st_ty %102
+ %14 = OpCopyObject %pb_st_ty %103
+ %15 = OpCopyObject %p_si_ty %110
+ OpReturn
+ OpFunctionEnd
diff --git a/test/tint/unittest/reader/combined_texture_sampler/ResolveBindingConflictsTest_OneEntryPoint_Conflict_RippleStopsAtFirstHole.spvasm b/test/tint/unittest/reader/combined_texture_sampler/ResolveBindingConflictsTest_OneEntryPoint_Conflict_RippleStopsAtFirstHole.spvasm
new file mode 100644
index 0000000..a23e8a6
--- /dev/null
+++ b/test/tint/unittest/reader/combined_texture_sampler/ResolveBindingConflictsTest_OneEntryPoint_Conflict_RippleStopsAtFirstHole.spvasm
@@ -0,0 +1,74 @@
+ OpCapability Shader
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ OpName %main "main"
+ OpName %voidfn "voidfn"
+ OpName %s_ty "s_ty"
+ OpName %i_ty "i_ty"
+ OpName %si_ty "si_ty"
+ OpName %p_s_ty "p_s_ty"
+ OpName %p_i_ty "p_i_ty"
+ OpName %p_si_ty "p_si_ty"
+ OpName %st_ty "st_ty"
+ OpName %pu_st_ty "pu_st_ty"
+ OpName %pb_st_ty "pb_st_ty"
+
+ OpDecorate %100 DescriptorSet 0
+ OpDecorate %100 Binding 0
+ OpDecorate %101 DescriptorSet 0
+ OpDecorate %101 Binding 0
+ OpDecorate %102 DescriptorSet 0
+ OpDecorate %102 Binding 1
+ ; Leave a hole at (0, 2)
+ OpDecorate %103 DescriptorSet 0
+ OpDecorate %103 Binding 3
+ OpDecorate %104 DescriptorSet 0
+ OpDecorate %104 Binding 4
+
+ ; There was a hole at binding 2. The ripple stops there.
+ ; CHECK: OpDecorate %100 DescriptorSet 0
+ ; CHECK: OpDecorate %100 Binding 1
+ ; CHECK: OpDecorate %101 DescriptorSet 0
+ ; CHECK: OpDecorate %101 Binding 0
+ ; CHECK: OpDecorate %102 DescriptorSet 0
+ ; CHECK: OpDecorate %102 Binding 2
+ ; CHECK: OpDecorate %103 DescriptorSet 0
+ ; CHECK: OpDecorate %103 Binding 3
+ ; CHECK: OpDecorate %104 DescriptorSet 0
+ ; CHECK: OpDecorate %104 Binding 4
+
+ OpDecorate %st_ty Block
+ OpMemberDecorate %st_ty 0 Offset 0
+ %float = OpTypeFloat 32
+ %uint = OpTypeInt 32 0
+ %uint_0 = OpConstant %uint 0
+ %uint_3 = OpConstant %uint 3
+ %void = OpTypeVoid
+ %voidfn = OpTypeFunction %void
+ %s_ty = OpTypeSampler
+ %i_ty = OpTypeImage %float 2D 0 0 0 1 Unknown
+ %si_ty = OpTypeSampledImage %i_ty
+ %p_i_ty = OpTypePointer UniformConstant %i_ty
+ %p_s_ty = OpTypePointer UniformConstant %s_ty
+ %p_si_ty = OpTypePointer UniformConstant %si_ty
+ %st_ty = OpTypeStruct %uint
+ %pu_st_ty = OpTypePointer Uniform %st_ty
+ %pb_st_ty = OpTypePointer StorageBuffer %st_ty
+
+
+ %100 = OpVariable %p_s_ty UniformConstant ; sampler comes first
+ %101 = OpVariable %p_i_ty UniformConstant
+ %102 = OpVariable %pu_st_ty Uniform
+ %103 = OpVariable %pb_st_ty StorageBuffer
+ %104 = OpVariable %p_si_ty UniformConstant
+
+ %main = OpFunction %void None %voidfn
+ %10 = OpLabel
+ %11 = OpCopyObject %p_s_ty %100
+ %12 = OpCopyObject %p_i_ty %101
+ %13 = OpCopyObject %pu_st_ty %102
+ %14 = OpCopyObject %pb_st_ty %103
+ %15 = OpCopyObject %p_si_ty %104
+ OpReturn
+ OpFunctionEnd
diff --git a/test/tint/unittest/reader/combined_texture_sampler/ResolveBindingConflictsTest_OneEntryPoint_Conflict_Ripples.spvasm b/test/tint/unittest/reader/combined_texture_sampler/ResolveBindingConflictsTest_OneEntryPoint_Conflict_Ripples.spvasm
new file mode 100644
index 0000000..2079d3f
--- /dev/null
+++ b/test/tint/unittest/reader/combined_texture_sampler/ResolveBindingConflictsTest_OneEntryPoint_Conflict_Ripples.spvasm
@@ -0,0 +1,74 @@
+ OpCapability Shader
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ OpName %main "main"
+ OpName %voidfn "voidfn"
+ OpName %s_ty "s_ty"
+ OpName %i_ty "i_ty"
+ OpName %si_ty "si_ty"
+ OpName %p_s_ty "p_s_ty"
+ OpName %p_i_ty "p_i_ty"
+ OpName %p_si_ty "p_si_ty"
+ OpName %st_ty "st_ty"
+ OpName %pu_st_ty "pu_st_ty"
+ OpName %pb_st_ty "pb_st_ty"
+
+ OpDecorate %100 DescriptorSet 0
+ OpDecorate %100 Binding 0
+ OpDecorate %101 DescriptorSet 0
+ OpDecorate %101 Binding 0
+ OpDecorate %102 DescriptorSet 0
+ OpDecorate %102 Binding 1
+ OpDecorate %103 DescriptorSet 0
+ OpDecorate %103 Binding 2
+ OpDecorate %104 DescriptorSet 0
+ OpDecorate %104 Binding 3
+
+ ; The sampler's binding number is incremented, and later
+ ; bindings move out of the way.
+ ; CHECK: OpDecorate %100 DescriptorSet 0
+ ; CHECK: OpDecorate %100 Binding 1
+ ; CHECK: OpDecorate %101 DescriptorSet 0
+ ; CHECK: OpDecorate %101 Binding 0
+ ; CHECK: OpDecorate %102 DescriptorSet 0
+ ; CHECK: OpDecorate %102 Binding 2
+ ; CHECK: OpDecorate %103 DescriptorSet 0
+ ; CHECK: OpDecorate %103 Binding 3
+ ; CHECK: OpDecorate %104 DescriptorSet 0
+ ; CHECK: OpDecorate %104 Binding 4
+
+ OpDecorate %st_ty Block
+ OpMemberDecorate %st_ty 0 Offset 0
+ %float = OpTypeFloat 32
+ %uint = OpTypeInt 32 0
+ %uint_0 = OpConstant %uint 0
+ %uint_3 = OpConstant %uint 3
+ %void = OpTypeVoid
+ %voidfn = OpTypeFunction %void
+ %s_ty = OpTypeSampler
+ %i_ty = OpTypeImage %float 2D 0 0 0 1 Unknown
+ %si_ty = OpTypeSampledImage %i_ty
+ %p_i_ty = OpTypePointer UniformConstant %i_ty
+ %p_s_ty = OpTypePointer UniformConstant %s_ty
+ %p_si_ty = OpTypePointer UniformConstant %si_ty
+ %st_ty = OpTypeStruct %uint
+ %pu_st_ty = OpTypePointer Uniform %st_ty
+ %pb_st_ty = OpTypePointer StorageBuffer %st_ty
+
+
+ %100 = OpVariable %p_s_ty UniformConstant ; sampler comes first
+ %101 = OpVariable %p_i_ty UniformConstant
+ %102 = OpVariable %pu_st_ty Uniform
+ %103 = OpVariable %pb_st_ty StorageBuffer
+ %104 = OpVariable %p_si_ty UniformConstant
+
+ %main = OpFunction %void None %voidfn
+ %10 = OpLabel
+ %11 = OpCopyObject %p_s_ty %100
+ %12 = OpCopyObject %p_i_ty %101
+ %13 = OpCopyObject %pu_st_ty %102
+ %14 = OpCopyObject %pb_st_ty %103
+ %15 = OpCopyObject %p_si_ty %104
+ OpReturn
+ OpFunctionEnd
diff --git a/test/tint/unittest/reader/combined_texture_sampler/ResolveBindingConflictsTest_OneEntryPoint_MultiConflict_ComplexCallGraph_Resolves.spvasm b/test/tint/unittest/reader/combined_texture_sampler/ResolveBindingConflictsTest_OneEntryPoint_MultiConflict_ComplexCallGraph_Resolves.spvasm
new file mode 100644
index 0000000..00620f3
--- /dev/null
+++ b/test/tint/unittest/reader/combined_texture_sampler/ResolveBindingConflictsTest_OneEntryPoint_MultiConflict_ComplexCallGraph_Resolves.spvasm
@@ -0,0 +1,106 @@
+ OpCapability Shader
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ OpName %main "main"
+ OpName %voidfn "voidfn"
+ OpName %s_ty "s_ty"
+ OpName %i_ty "i_ty"
+ OpName %si_ty "si_ty"
+ OpName %p_s_ty "p_s_ty"
+ OpName %p_i_ty "p_i_ty"
+ OpName %p_si_ty "p_si_ty"
+ OpName %st_ty "st_ty"
+ OpName %pu_st_ty "pu_st_ty"
+ OpName %pb_st_ty "pb_st_ty"
+
+ OpDecorate %100 DescriptorSet 0
+ OpDecorate %100 Binding 0
+ OpDecorate %101 DescriptorSet 0
+ OpDecorate %101 Binding 0
+ OpDecorate %102 DescriptorSet 0
+ OpDecorate %102 Binding 1
+ OpDecorate %103 DescriptorSet 0
+ OpDecorate %103 Binding 1
+ OpDecorate %104 DescriptorSet 0
+ OpDecorate %104 Binding 2
+
+ ; CHECK: OpDecorate %100 DescriptorSet 0
+ ; CHECK: OpDecorate %100 Binding 1
+ ; CHECK: OpDecorate %101 DescriptorSet 0
+ ; CHECK: OpDecorate %101 Binding 0
+ ; CHECK: OpDecorate %102 DescriptorSet 0
+ ; CHECK: OpDecorate %102 Binding 2
+ ; CHECK: OpDecorate %103 DescriptorSet 0
+ ; CHECK: OpDecorate %103 Binding 3
+ ; CHECK: OpDecorate %104 DescriptorSet 0
+ ; CHECK: OpDecorate %104 Binding 4
+
+ OpDecorate %st_ty Block
+ OpMemberDecorate %st_ty 0 Offset 0
+ %float = OpTypeFloat 32
+ %uint = OpTypeInt 32 0
+ %uint_0 = OpConstant %uint 0
+ %uint_3 = OpConstant %uint 3
+ %void = OpTypeVoid
+ %voidfn = OpTypeFunction %void
+ %s_ty = OpTypeSampler
+ %i_ty = OpTypeImage %float 2D 0 0 0 1 Unknown
+ %si_ty = OpTypeSampledImage %i_ty
+ %p_i_ty = OpTypePointer UniformConstant %i_ty
+ %p_s_ty = OpTypePointer UniformConstant %s_ty
+ %p_si_ty = OpTypePointer UniformConstant %si_ty
+ %st_ty = OpTypeStruct %uint
+ %pu_st_ty = OpTypePointer Uniform %st_ty
+ %pb_st_ty = OpTypePointer StorageBuffer %st_ty
+
+
+ %100 = OpVariable %p_s_ty UniformConstant ; used in %200
+ %101 = OpVariable %p_i_ty UniformConstant ; used in %300, %400
+ %102 = OpVariable %p_i_ty UniformConstant ; used in %500
+ %103 = OpVariable %p_s_ty UniformConstant ; used in %400 twice
+ %104 = OpVariable %pu_st_ty Uniform ; used in %600
+
+ %200 = OpFunction %void None %voidfn
+ %201 = OpLabel
+ %202 = OpCopyObject %p_s_ty %100
+ OpReturn
+ OpFunctionEnd
+
+ %300 = OpFunction %void None %voidfn
+ %301 = OpLabel
+ %302 = OpCopyObject %p_i_ty %101
+ OpReturn
+ OpFunctionEnd
+
+ %400 = OpFunction %void None %voidfn
+ %401 = OpLabel
+ %402 = OpFunctionCall %void %200
+ %403 = OpCopyObject %p_s_ty %103
+ %404 = OpCopyObject %p_i_ty %101
+ %405 = OpCopyObject %p_s_ty %103
+ %406 = OpFunctionCall %void %300
+ OpReturn
+ OpFunctionEnd
+
+ %500 = OpFunction %void None %voidfn
+ %501 = OpLabel
+ %502 = OpFunctionCall %void %400
+ %503 = OpCopyObject %p_i_ty %102
+ %504 = OpFunctionCall %void %300
+ OpReturn
+ OpFunctionEnd
+
+ %600 = OpFunction %void None %voidfn
+ %601 = OpLabel
+ %602 = OpFunctionCall %void %300
+ %603 = OpFunctionCall %void %500
+ %604 = OpCopyObject %pu_st_ty %104
+ OpReturn
+ OpFunctionEnd
+
+ %main = OpFunction %void None %voidfn
+ %1000 = OpLabel
+ %1001 = OpFunctionCall %void %600
+ OpReturn
+ OpFunctionEnd
diff --git a/test/tint/unittest/reader/combined_texture_sampler/ResolveBindingConflictsTest_OneEntryPoint_MultiConflict_Resolves.spvasm b/test/tint/unittest/reader/combined_texture_sampler/ResolveBindingConflictsTest_OneEntryPoint_MultiConflict_Resolves.spvasm
new file mode 100644
index 0000000..fae0955
--- /dev/null
+++ b/test/tint/unittest/reader/combined_texture_sampler/ResolveBindingConflictsTest_OneEntryPoint_MultiConflict_Resolves.spvasm
@@ -0,0 +1,73 @@
+ OpCapability Shader
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ OpName %main "main"
+ OpName %voidfn "voidfn"
+ OpName %s_ty "s_ty"
+ OpName %i_ty "i_ty"
+ OpName %si_ty "si_ty"
+ OpName %p_s_ty "p_s_ty"
+ OpName %p_i_ty "p_i_ty"
+ OpName %p_si_ty "p_si_ty"
+ OpName %st_ty "st_ty"
+ OpName %pu_st_ty "pu_st_ty"
+ OpName %pb_st_ty "pb_st_ty"
+
+ ; Two conflicts: at Bindings 0, and 1
+ OpDecorate %100 DescriptorSet 0
+ OpDecorate %100 Binding 0
+ OpDecorate %101 DescriptorSet 0
+ OpDecorate %101 Binding 0
+ OpDecorate %102 DescriptorSet 0
+ OpDecorate %102 Binding 1
+ OpDecorate %103 DescriptorSet 0
+ OpDecorate %103 Binding 1
+ OpDecorate %104 DescriptorSet 0
+ OpDecorate %104 Binding 2
+
+ ; CHECK: OpDecorate %100 DescriptorSet 0
+ ; CHECK: OpDecorate %100 Binding 1
+ ; CHECK: OpDecorate %101 DescriptorSet 0
+ ; CHECK: OpDecorate %101 Binding 0
+ ; CHECK: OpDecorate %102 DescriptorSet 0
+ ; CHECK: OpDecorate %102 Binding 2
+ ; CHECK: OpDecorate %103 DescriptorSet 0
+ ; CHECK: OpDecorate %103 Binding 3
+ ; CHECK: OpDecorate %104 DescriptorSet 0
+ ; CHECK: OpDecorate %104 Binding 4
+
+ OpDecorate %st_ty Block
+ OpMemberDecorate %st_ty 0 Offset 0
+ %float = OpTypeFloat 32
+ %uint = OpTypeInt 32 0
+ %uint_0 = OpConstant %uint 0
+ %uint_3 = OpConstant %uint 3
+ %void = OpTypeVoid
+ %voidfn = OpTypeFunction %void
+ %s_ty = OpTypeSampler
+ %i_ty = OpTypeImage %float 2D 0 0 0 1 Unknown
+ %si_ty = OpTypeSampledImage %i_ty
+ %p_i_ty = OpTypePointer UniformConstant %i_ty
+ %p_s_ty = OpTypePointer UniformConstant %s_ty
+ %p_si_ty = OpTypePointer UniformConstant %si_ty
+ %st_ty = OpTypeStruct %uint
+ %pu_st_ty = OpTypePointer Uniform %st_ty
+ %pb_st_ty = OpTypePointer StorageBuffer %st_ty
+
+
+ %100 = OpVariable %p_s_ty UniformConstant ; sampler first
+ %101 = OpVariable %p_i_ty UniformConstant
+ %102 = OpVariable %p_i_ty UniformConstant
+ %103 = OpVariable %p_s_ty UniformConstant ; sampler second
+ %104 = OpVariable %pu_st_ty Uniform
+
+ %main = OpFunction %void None %voidfn
+ %10 = OpLabel
+ %11 = OpCopyObject %p_s_ty %100
+ %12 = OpCopyObject %p_i_ty %101
+ %13 = OpCopyObject %p_i_ty %102
+ %14 = OpCopyObject %p_s_ty %103
+ %15 = OpCopyObject %pu_st_ty %104
+ OpReturn
+ OpFunctionEnd
diff --git a/test/tint/unittest/reader/combined_texture_sampler/ResolveBindingConflictsTest_OneEntryPoint_SamplerFirstConflict_Resolves.spvasm b/test/tint/unittest/reader/combined_texture_sampler/ResolveBindingConflictsTest_OneEntryPoint_SamplerFirstConflict_Resolves.spvasm
new file mode 100644
index 0000000..f15866e
--- /dev/null
+++ b/test/tint/unittest/reader/combined_texture_sampler/ResolveBindingConflictsTest_OneEntryPoint_SamplerFirstConflict_Resolves.spvasm
@@ -0,0 +1,55 @@
+ OpCapability Shader
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ OpName %main "main"
+ OpName %voidfn "voidfn"
+ OpName %s_ty "s_ty"
+ OpName %i_ty "i_ty"
+ OpName %si_ty "si_ty"
+ OpName %p_s_ty "p_s_ty"
+ OpName %p_i_ty "p_i_ty"
+ OpName %p_si_ty "p_si_ty"
+ OpName %st_ty "st_ty"
+ OpName %pu_st_ty "pu_st_ty"
+ OpName %pb_st_ty "pb_st_ty"
+
+ OpDecorate %100 DescriptorSet 0
+ OpDecorate %100 Binding 0
+ OpDecorate %101 DescriptorSet 0
+ OpDecorate %101 Binding 0
+
+ ; The sampler's binding number is incremented, even when listed first.
+ ; CHECK: OpDecorate %100 DescriptorSet 0
+ ; CHECK: OpDecorate %100 Binding 1
+ ; CHECK: OpDecorate %101 DescriptorSet 0
+ ; CHECK: OpDecorate %101 Binding 0
+
+ OpDecorate %st_ty Block
+ OpMemberDecorate %st_ty 0 Offset 0
+ %float = OpTypeFloat 32
+ %uint = OpTypeInt 32 0
+ %uint_0 = OpConstant %uint 0
+ %uint_3 = OpConstant %uint 3
+ %void = OpTypeVoid
+ %voidfn = OpTypeFunction %void
+ %s_ty = OpTypeSampler
+ %i_ty = OpTypeImage %float 2D 0 0 0 1 Unknown
+ %si_ty = OpTypeSampledImage %i_ty
+ %p_i_ty = OpTypePointer UniformConstant %i_ty
+ %p_s_ty = OpTypePointer UniformConstant %s_ty
+ %p_si_ty = OpTypePointer UniformConstant %si_ty
+ %st_ty = OpTypeStruct %uint
+ %pu_st_ty = OpTypePointer Uniform %st_ty
+ %pb_st_ty = OpTypePointer StorageBuffer %st_ty
+
+
+ %100 = OpVariable %p_s_ty UniformConstant ; sampler listed first
+ %101 = OpVariable %p_i_ty UniformConstant
+
+ %main = OpFunction %void None %voidfn
+ %10 = OpLabel
+ %11 = OpCopyObject %p_s_ty %100
+ %12 = OpCopyObject %p_i_ty %101
+ OpReturn
+ OpFunctionEnd
diff --git a/test/tint/unittest/reader/combined_texture_sampler/ResolveBindingConflictsTest_OneEntryPoint_SamplerSecondConflict_Resolves.spvasm b/test/tint/unittest/reader/combined_texture_sampler/ResolveBindingConflictsTest_OneEntryPoint_SamplerSecondConflict_Resolves.spvasm
new file mode 100644
index 0000000..b4299aa
--- /dev/null
+++ b/test/tint/unittest/reader/combined_texture_sampler/ResolveBindingConflictsTest_OneEntryPoint_SamplerSecondConflict_Resolves.spvasm
@@ -0,0 +1,55 @@
+ OpCapability Shader
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ OpName %main "main"
+ OpName %voidfn "voidfn"
+ OpName %s_ty "s_ty"
+ OpName %i_ty "i_ty"
+ OpName %si_ty "si_ty"
+ OpName %p_s_ty "p_s_ty"
+ OpName %p_i_ty "p_i_ty"
+ OpName %p_si_ty "p_si_ty"
+ OpName %st_ty "st_ty"
+ OpName %pu_st_ty "pu_st_ty"
+ OpName %pb_st_ty "pb_st_ty"
+
+ OpDecorate %100 DescriptorSet 0
+ OpDecorate %100 Binding 0
+ OpDecorate %101 DescriptorSet 0
+ OpDecorate %101 Binding 0
+
+ ; The sampler's binding number is incremented, even when listed second.
+ ; CHECK: OpDecorate %100 DescriptorSet 0
+ ; CHECK: OpDecorate %100 Binding 0
+ ; CHECK: OpDecorate %101 DescriptorSet 0
+ ; CHECK: OpDecorate %101 Binding 1
+
+ OpDecorate %st_ty Block
+ OpMemberDecorate %st_ty 0 Offset 0
+ %float = OpTypeFloat 32
+ %uint = OpTypeInt 32 0
+ %uint_0 = OpConstant %uint 0
+ %uint_3 = OpConstant %uint 3
+ %void = OpTypeVoid
+ %voidfn = OpTypeFunction %void
+ %s_ty = OpTypeSampler
+ %i_ty = OpTypeImage %float 2D 0 0 0 1 Unknown
+ %si_ty = OpTypeSampledImage %i_ty
+ %p_i_ty = OpTypePointer UniformConstant %i_ty
+ %p_s_ty = OpTypePointer UniformConstant %s_ty
+ %p_si_ty = OpTypePointer UniformConstant %si_ty
+ %st_ty = OpTypeStruct %uint
+ %pu_st_ty = OpTypePointer Uniform %st_ty
+ %pb_st_ty = OpTypePointer StorageBuffer %st_ty
+
+
+ %100 = OpVariable %p_i_ty UniformConstant
+ %101 = OpVariable %p_s_ty UniformConstant ; sampler listed second
+
+ %main = OpFunction %void None %voidfn
+ %10 = OpLabel
+ %11 = OpCopyObject %p_i_ty %100
+ %12 = OpCopyObject %p_s_ty %101
+ OpReturn
+ OpFunctionEnd
diff --git a/test/tint/unittest/reader/combined_texture_sampler/SplitCombinedImageSamplerPassTest_Combined_NoSampler_CreatedBeforeSampledImage.spvasm b/test/tint/unittest/reader/combined_texture_sampler/SplitCombinedImageSamplerPassTest_Combined_NoSampler_CreatedBeforeSampledImage.spvasm
new file mode 100644
index 0000000..16a8f23
--- /dev/null
+++ b/test/tint/unittest/reader/combined_texture_sampler/SplitCombinedImageSamplerPassTest_Combined_NoSampler_CreatedBeforeSampledImage.spvasm
@@ -0,0 +1,44 @@
+ OpCapability Shader
+ OpCapability RuntimeDescriptorArray
+ OpExtension "SPV_EXT_descriptor_indexing"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ OpName %main "main"
+ OpName %main_0 "main_0"
+ OpName %voidfn "voidfn"
+ OpDecorate %100 DescriptorSet 0
+ OpDecorate %100 Binding 0
+
+ ; A sampler type is created and placed at the start of types.
+ ; CHECK: OpDecorate %{{\d+}} Binding 0
+ ; CHECK: OpDecorate %{{\d+}} Binding 0
+ ; CHECK-NOT: TypeSampledImage
+ ; CHECK: TypeSampler
+ ; CHECK: TypeSampledImage
+
+ %float = OpTypeFloat 32
+ %uint = OpTypeInt 32 0
+ %int = OpTypeInt 32 1
+ %uint_0 = OpConstant %uint 0
+ %uint_1 = OpConstant %uint 1
+ %uint_3 = OpConstant %uint 3
+ %float_0 = OpConstant %float 0
+ %v2float = OpTypeVector %float 2
+ %v3float = OpTypeVector %float 3
+ %v4float = OpTypeVector %float 4
+ %13 = OpConstantNull %v2float
+ %14 = OpConstantNull %v3float
+ %15 = OpConstantNull %v4float
+ %void = OpTypeVoid
+ %voidfn = OpTypeFunction %void
+ %10 = OpTypeImage %float 2D 0 0 0 1 Unknown
+ %11 = OpTypeSampledImage %10
+%_ptr_UniformConstant_11 = OpTypePointer UniformConstant %11
+
+ %100 = OpVariable %_ptr_UniformConstant_11 UniformConstant
+ %main = OpFunction %void None %voidfn
+ %main_0 = OpLabel
+ %6 = OpLoad %11 %100
+ OpReturn
+ OpFunctionEnd
diff --git a/test/tint/unittest/reader/combined_texture_sampler/SplitCombinedImageSamplerPassTest_Combined_SynthesizeVarNames.spvasm b/test/tint/unittest/reader/combined_texture_sampler/SplitCombinedImageSamplerPassTest_Combined_SynthesizeVarNames.spvasm
new file mode 100644
index 0000000..d393ae2
--- /dev/null
+++ b/test/tint/unittest/reader/combined_texture_sampler/SplitCombinedImageSamplerPassTest_Combined_SynthesizeVarNames.spvasm
@@ -0,0 +1,65 @@
+ OpCapability Shader
+ OpCapability RuntimeDescriptorArray
+ OpExtension "SPV_EXT_descriptor_indexing"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ OpName %main "main"
+ OpName %main_0 "main_0"
+ OpName %voidfn "voidfn"
+
+ OpName %orig_var "orig_var"
+ OpDecorate %orig_var DescriptorSet 0
+ OpDecorate %orig_var Binding 0
+
+ ; The combined image variable is replaced by an image variable and a sampler variable.
+
+ ; CHECK: OpCapability
+ ; The original name is deleted
+ ; CHECK-NOT: OpName %orig_var "
+ ; CHECK: OpName %orig_var_image "orig_var_image"
+ ; CHECK: OpName %orig_var_sampler "orig_var_sampler"
+ ; CHECK-NOT: OpName %orig_var "
+
+ ; CHECK: OpDecorate %orig_var_image DescriptorSet 0
+ ; CHECK: OpDecorate %orig_var_sampler DescriptorSet 0
+ ; CHECK: OpDecorate %orig_var_image Binding 0
+ ; CHECK: OpDecorate %orig_var_sampler Binding 0
+
+ ; CHECK: %10 = OpTypeImage %
+ ; CHECK: %[[image_ptr_ty:\w+]] = OpTypePointer UniformConstant %10
+ ; CHECK: %[[sampler_ty:\d+]] = OpTypeSampler
+ ; CHECK: %[[sampler_ptr_ty:\w+]] = OpTypePointer UniformConstant %[[sampler_ty]]
+
+
+ ; CHECK-NOT: %orig_var = OpVariable
+ ; CHECK-DAG: %orig_var_sampler = OpVariable %[[sampler_ptr_ty]] UniformConstant
+ ; CHECK-DAG: %orig_var_image = OpVariable %[[image_ptr_ty]] UniformConstant
+ ; CHECK: = OpFunction
+
+ %float = OpTypeFloat 32
+ %uint = OpTypeInt 32 0
+ %int = OpTypeInt 32 1
+ %uint_0 = OpConstant %uint 0
+ %uint_1 = OpConstant %uint 1
+ %uint_3 = OpConstant %uint 3
+ %float_0 = OpConstant %float 0
+ %v2float = OpTypeVector %float 2
+ %v3float = OpTypeVector %float 3
+ %v4float = OpTypeVector %float 4
+ %13 = OpConstantNull %v2float
+ %14 = OpConstantNull %v3float
+ %15 = OpConstantNull %v4float
+ %void = OpTypeVoid
+ %voidfn = OpTypeFunction %void
+
+ %10 = OpTypeImage %float 2D 0 0 0 1 Unknown
+ %11 = OpTypeSampledImage %10
+%_ptr_UniformConstant_11 = OpTypePointer UniformConstant %11
+
+ %orig_var = OpVariable %_ptr_UniformConstant_11 UniformConstant
+ %main = OpFunction %void None %voidfn
+ %main_0 = OpLabel
+ %101 = OpLoad %11 %orig_var
+ OpReturn
+ OpFunctionEnd
diff --git a/test/tint/unittest/reader/combined_texture_sampler/SplitCombinedImageSamplerPassTest_FunctionBody_PtrSampledImage.spvasm b/test/tint/unittest/reader/combined_texture_sampler/SplitCombinedImageSamplerPassTest_FunctionBody_PtrSampledImage.spvasm
new file mode 100644
index 0000000..ca17746
--- /dev/null
+++ b/test/tint/unittest/reader/combined_texture_sampler/SplitCombinedImageSamplerPassTest_FunctionBody_PtrSampledImage.spvasm
@@ -0,0 +1,81 @@
+ OpCapability Shader
+ OpCapability RuntimeDescriptorArray
+ OpExtension "SPV_EXT_descriptor_indexing"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ OpName %main "main"
+ OpName %main_0 "main_0"
+ OpName %voidfn "voidfn"
+
+ OpName %f "f"
+ OpName %f_ty "f_ty"
+ OpName %i_ty "i_ty"
+ OpName %s_ty "s_ty"
+ OpName %p_i_ty "p_i_ty"
+ OpName %p_s_ty "p_s_ty"
+
+ OpName %si_ty "si_ty"
+ OpName %p_si_ty "p_si_ty"
+ OpName %array_si_ty "array_si_ty"
+ OpName %rtarray_si_ty "rtarray_si_ty"
+ OpName %p_array_si_ty "p_array_si_ty"
+ OpName %p_rtarray_si_ty "p_rtarray_si_ty"
+ %float = OpTypeFloat 32
+ %uint = OpTypeInt 32 0
+ %int = OpTypeInt 32 1
+ %uint_0 = OpConstant %uint 0
+ %uint_1 = OpConstant %uint 1
+ %uint_3 = OpConstant %uint 3
+ %float_0 = OpConstant %float 0
+ %v2float = OpTypeVector %float 2
+ %v3float = OpTypeVector %float 3
+ %v4float = OpTypeVector %float 4
+ %13 = OpConstantNull %v2float
+ %14 = OpConstantNull %v3float
+ %15 = OpConstantNull %v4float
+ %void = OpTypeVoid
+ %voidfn = OpTypeFunction %void
+
+ %i_ty = OpTypeImage %float 2D 0 0 0 1 Unknown
+ %s_ty = OpTypeSampler
+ %p_i_ty = OpTypePointer UniformConstant %i_ty
+ %p_s_ty = OpTypePointer UniformConstant %s_ty
+
+ %si_ty = OpTypeSampledImage %i_ty
+ %p_si_ty = OpTypePointer UniformConstant %si_ty
+ %array_si_ty = OpTypeArray %si_ty %uint_3
+ %p_array_si_ty = OpTypePointer UniformConstant %array_si_ty
+ %rtarray_si_ty = OpTypeRuntimeArray %si_ty
+ %p_rtarray_si_ty = OpTypePointer UniformConstant %rtarray_si_ty
+
+
+ ; CHECK: %f_ty = OpTypeFunction %v4float %uint %p_i_ty %p_s_ty %float
+ %f_ty = OpTypeFunction %v4float %uint %p_si_ty %float
+
+ ; CHECK: %f = OpFunction %v4float None %f_ty
+ ; CHECK-NEXT: OpFunctionParameter %uint
+ ; CHECK-NEXT: %[[pi:\w+]] = OpFunctionParameter %p_i_ty
+ ; CHECK-NEXT: %[[ps:\w+]] = OpFunctionParameter %p_s_ty
+ ; CHECK-NEXT: OpFunctionParameter %float
+ ; CHECK-NEXT: OpLabel
+ ; CHECK-NEXT: %[[i:\w+]] = OpLoad %i_ty %[[pi]]
+ ; CHECK-NEXT: %[[s:\w+]] = OpLoad %s_ty %[[ps]]
+ ; CHECK-NEXT: %[[si:\w+]] = OpSampledImage %si_ty %[[i]] %[[s]]
+ ; CHECK-NEXT: %200 = OpImageSampleExplicitLod %v4float %[[si]] %13 Lod %float_0
+ ; CHECK-NEXT: OpReturnValue %200
+
+ %f = OpFunction %v4float None %f_ty
+ %100 = OpFunctionParameter %uint
+ %101 = OpFunctionParameter %p_si_ty ; replace this
+ %110 = OpFunctionParameter %float
+ %120 = OpLabel
+ %121 = OpLoad %si_ty %101
+ %200 = OpImageSampleExplicitLod %v4float %121 %13 Lod %float_0
+ OpReturnValue %200
+ OpFunctionEnd
+
+ %main = OpFunction %void None %voidfn
+ %main_0 = OpLabel
+ OpReturn
+ OpFunctionEnd
diff --git a/test/tint/unittest/reader/combined_texture_sampler/SplitCombinedImageSamplerPassTest_FunctionBody_SampledImage_OpImage.spvasm b/test/tint/unittest/reader/combined_texture_sampler/SplitCombinedImageSamplerPassTest_FunctionBody_SampledImage_OpImage.spvasm
new file mode 100644
index 0000000..d08ea72
--- /dev/null
+++ b/test/tint/unittest/reader/combined_texture_sampler/SplitCombinedImageSamplerPassTest_FunctionBody_SampledImage_OpImage.spvasm
@@ -0,0 +1,79 @@
+ OpCapability Shader
+ OpCapability RuntimeDescriptorArray
+ OpExtension "SPV_EXT_descriptor_indexing"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ OpName %main "main"
+ OpName %main_0 "main_0"
+ OpName %voidfn "voidfn"
+
+ OpName %f "f"
+ OpName %f_ty "f_ty"
+ OpName %i_ty "i_ty"
+ OpName %s_ty "s_ty"
+ OpName %p_i_ty "p_i_ty"
+ OpName %p_s_ty "p_s_ty"
+
+ OpName %si_ty "si_ty"
+ OpName %p_si_ty "p_si_ty"
+ OpName %array_si_ty "array_si_ty"
+ OpName %rtarray_si_ty "rtarray_si_ty"
+ OpName %p_array_si_ty "p_array_si_ty"
+ OpName %p_rtarray_si_ty "p_rtarray_si_ty"
+ %float = OpTypeFloat 32
+ %uint = OpTypeInt 32 0
+ %int = OpTypeInt 32 1
+ %uint_0 = OpConstant %uint 0
+ %uint_1 = OpConstant %uint 1
+ %uint_3 = OpConstant %uint 3
+ %float_0 = OpConstant %float 0
+ %v2float = OpTypeVector %float 2
+ %v3float = OpTypeVector %float 3
+ %v4float = OpTypeVector %float 4
+ %13 = OpConstantNull %v2float
+ %14 = OpConstantNull %v3float
+ %15 = OpConstantNull %v4float
+ %void = OpTypeVoid
+ %voidfn = OpTypeFunction %void
+
+ %i_ty = OpTypeImage %float 2D 0 0 0 1 Unknown
+ %s_ty = OpTypeSampler
+ %p_i_ty = OpTypePointer UniformConstant %i_ty
+ %p_s_ty = OpTypePointer UniformConstant %s_ty
+
+ %si_ty = OpTypeSampledImage %i_ty
+ %p_si_ty = OpTypePointer UniformConstant %si_ty
+ %array_si_ty = OpTypeArray %si_ty %uint_3
+ %p_array_si_ty = OpTypePointer UniformConstant %array_si_ty
+ %rtarray_si_ty = OpTypeRuntimeArray %si_ty
+ %p_rtarray_si_ty = OpTypePointer UniformConstant %rtarray_si_ty
+
+
+ ; CHECK: %f_ty = OpTypeFunction %void %uint %i_ty %s_ty %float
+ %f_ty = OpTypeFunction %void %uint %si_ty %float
+
+ ; CHECK: %f = OpFunction %void None %f_ty
+ ; CHECK: OpFunctionParameter %uint
+ ; CHECK-NEXT: %[[i:\w+]] = OpFunctionParameter %i_ty
+ ; CHECK-NEXT: %[[s:\w+]] = OpFunctionParameter %s_ty
+ ; CHECK-NEXT: OpFunctionParameter %float
+ ; CHECK-NEXT: OpLabel
+ ; CHECK-NEXT: %[[si:\w+]] = OpSampledImage %si_ty %[[i]] %[[s]]
+ ; CHECK-NEXT: %200 = OpImage %i_ty %[[si]]
+ ; CHECK-NEXT: OpReturn
+
+ %f = OpFunction %void None %f_ty
+ %100 = OpFunctionParameter %uint
+ %101 = OpFunctionParameter %si_ty ; replace this
+ %110 = OpFunctionParameter %float
+ %120 = OpLabel
+ %200 = OpImage %i_ty %101
+ OpReturn
+ OpFunctionEnd
+
+
+ %main = OpFunction %void None %voidfn
+ %main_0 = OpLabel
+ OpReturn
+ OpFunctionEnd
diff --git a/test/tint/unittest/reader/combined_texture_sampler/SplitCombinedImageSamplerPassTest_FunctionBody_SampledImage_OpImageSample.spvasm b/test/tint/unittest/reader/combined_texture_sampler/SplitCombinedImageSamplerPassTest_FunctionBody_SampledImage_OpImageSample.spvasm
new file mode 100644
index 0000000..9492368
--- /dev/null
+++ b/test/tint/unittest/reader/combined_texture_sampler/SplitCombinedImageSamplerPassTest_FunctionBody_SampledImage_OpImageSample.spvasm
@@ -0,0 +1,79 @@
+ OpCapability Shader
+ OpCapability RuntimeDescriptorArray
+ OpExtension "SPV_EXT_descriptor_indexing"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ OpName %main "main"
+ OpName %main_0 "main_0"
+ OpName %voidfn "voidfn"
+
+ OpName %f "f"
+ OpName %f_ty "f_ty"
+ OpName %i_ty "i_ty"
+ OpName %s_ty "s_ty"
+ OpName %p_i_ty "p_i_ty"
+ OpName %p_s_ty "p_s_ty"
+
+ OpName %si_ty "si_ty"
+ OpName %p_si_ty "p_si_ty"
+ OpName %array_si_ty "array_si_ty"
+ OpName %rtarray_si_ty "rtarray_si_ty"
+ OpName %p_array_si_ty "p_array_si_ty"
+ OpName %p_rtarray_si_ty "p_rtarray_si_ty"
+ %float = OpTypeFloat 32
+ %uint = OpTypeInt 32 0
+ %int = OpTypeInt 32 1
+ %uint_0 = OpConstant %uint 0
+ %uint_1 = OpConstant %uint 1
+ %uint_3 = OpConstant %uint 3
+ %float_0 = OpConstant %float 0
+ %v2float = OpTypeVector %float 2
+ %v3float = OpTypeVector %float 3
+ %v4float = OpTypeVector %float 4
+ %13 = OpConstantNull %v2float
+ %14 = OpConstantNull %v3float
+ %15 = OpConstantNull %v4float
+ %void = OpTypeVoid
+ %voidfn = OpTypeFunction %void
+
+ %i_ty = OpTypeImage %float 2D 0 0 0 1 Unknown
+ %s_ty = OpTypeSampler
+ %p_i_ty = OpTypePointer UniformConstant %i_ty
+ %p_s_ty = OpTypePointer UniformConstant %s_ty
+
+ %si_ty = OpTypeSampledImage %i_ty
+ %p_si_ty = OpTypePointer UniformConstant %si_ty
+ %array_si_ty = OpTypeArray %si_ty %uint_3
+ %p_array_si_ty = OpTypePointer UniformConstant %array_si_ty
+ %rtarray_si_ty = OpTypeRuntimeArray %si_ty
+ %p_rtarray_si_ty = OpTypePointer UniformConstant %rtarray_si_ty
+
+
+ ; CHECK: %f_ty = OpTypeFunction %v4float %uint %i_ty %s_ty %float
+ %f_ty = OpTypeFunction %v4float %uint %si_ty %float
+
+ ; CHECK: %f = OpFunction %v4float None %f_ty
+ ; CHECK: OpFunctionParameter %uint
+ ; CHECK-NEXT: %[[i:\w+]] = OpFunctionParameter %i_ty
+ ; CHECK-NEXT: %[[s:\w+]] = OpFunctionParameter %s_ty
+ ; CHECK-NEXT: OpFunctionParameter %float
+ ; CHECK-NEXT: OpLabel
+ ; CHECK-NEXT: %[[si:\w+]] = OpSampledImage %si_ty %[[i]] %[[s]]
+ ; CHECK-NEXT: %200 = OpImageSampleExplicitLod %v4float %[[si]] %13 Lod %float_0
+ ; CHECK-NEXT: OpReturnValue %200
+
+ %f = OpFunction %v4float None %f_ty
+ %100 = OpFunctionParameter %uint
+ %101 = OpFunctionParameter %si_ty ; replace this
+ %110 = OpFunctionParameter %float
+ %120 = OpLabel
+ %200 = OpImageSampleExplicitLod %v4float %101 %13 Lod %float_0
+ OpReturnValue %200
+ OpFunctionEnd
+
+
+ %main = OpFunction %void None %voidfn
+ %main_0 = OpLabel
+ OpReturn
+ OpFunctionEnd
diff --git a/test/tint/unittest/reader/combined_texture_sampler/SplitCombinedImageSamplerPassTest_FunctionBody_ScalarNoChange.spvasm b/test/tint/unittest/reader/combined_texture_sampler/SplitCombinedImageSamplerPassTest_FunctionBody_ScalarNoChange.spvasm
new file mode 100644
index 0000000..e7308c7
--- /dev/null
+++ b/test/tint/unittest/reader/combined_texture_sampler/SplitCombinedImageSamplerPassTest_FunctionBody_ScalarNoChange.spvasm
@@ -0,0 +1,74 @@
+ OpCapability Shader
+ OpCapability RuntimeDescriptorArray
+ OpExtension "SPV_EXT_descriptor_indexing"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ OpName %main "main"
+ OpName %main_0 "main_0"
+ OpName %voidfn "voidfn"
+
+ OpName %f "f"
+ OpName %f_ty "f_ty"
+ OpName %i_ty "i_ty"
+ OpName %s_ty "s_ty"
+ OpName %p_i_ty "p_i_ty"
+ OpName %p_s_ty "p_s_ty"
+
+ OpName %si_ty "si_ty"
+ OpName %p_si_ty "p_si_ty"
+ OpName %array_si_ty "array_si_ty"
+ OpName %rtarray_si_ty "rtarray_si_ty"
+ OpName %p_array_si_ty "p_array_si_ty"
+ OpName %p_rtarray_si_ty "p_rtarray_si_ty"
+ %float = OpTypeFloat 32
+ %uint = OpTypeInt 32 0
+ %int = OpTypeInt 32 1
+ %uint_0 = OpConstant %uint 0
+ %uint_1 = OpConstant %uint 1
+ %uint_3 = OpConstant %uint 3
+ %float_0 = OpConstant %float 0
+ %v2float = OpTypeVector %float 2
+ %v3float = OpTypeVector %float 3
+ %v4float = OpTypeVector %float 4
+ %13 = OpConstantNull %v2float
+ %14 = OpConstantNull %v3float
+ %15 = OpConstantNull %v4float
+ %void = OpTypeVoid
+ %voidfn = OpTypeFunction %void
+
+ %i_ty = OpTypeImage %float 2D 0 0 0 1 Unknown
+ %s_ty = OpTypeSampler
+ %p_i_ty = OpTypePointer UniformConstant %i_ty
+ %p_s_ty = OpTypePointer UniformConstant %s_ty
+
+ %si_ty = OpTypeSampledImage %i_ty
+ %p_si_ty = OpTypePointer UniformConstant %si_ty
+ %array_si_ty = OpTypeArray %si_ty %uint_3
+ %p_array_si_ty = OpTypePointer UniformConstant %array_si_ty
+ %rtarray_si_ty = OpTypeRuntimeArray %si_ty
+ %p_rtarray_si_ty = OpTypePointer UniformConstant %rtarray_si_ty
+
+
+ ; CHECK: %f_ty = OpTypeFunction %float %i_ty %s_ty %p_i_ty %p_s_ty
+ %f_ty = OpTypeFunction %float %i_ty %s_ty %p_i_ty %p_s_ty
+
+ ; CHECK: %f = OpFunction %float None %f_ty
+ ; CHECK-NEXT: OpFunctionParameter %i_ty
+ ; CHECK-NEXT: OpFunctionParameter %s_ty
+ ; CHECK-NEXT: OpFunctionParameter %p_i_ty
+ ; CHECK-NEXT: OpFunctionParameter %p_s_ty
+ ; CHECK-NEXT: OpLabel
+ %f = OpFunction %float None %f_ty
+ %100 = OpFunctionParameter %i_ty
+ %101 = OpFunctionParameter %s_ty
+ %102 = OpFunctionParameter %p_i_ty
+ %103 = OpFunctionParameter %p_s_ty
+ %110 = OpLabel
+ OpReturnValue %float_0
+ OpFunctionEnd
+
+ %main = OpFunction %void None %voidfn
+ %main_0 = OpLabel
+ OpReturn
+ OpFunctionEnd
diff --git a/test/tint/unittest/reader/combined_texture_sampler/SplitCombinedImageSamplerPassTest_FunctionCall_Image_NoChange.spvasm b/test/tint/unittest/reader/combined_texture_sampler/SplitCombinedImageSamplerPassTest_FunctionCall_Image_NoChange.spvasm
new file mode 100644
index 0000000..37f57e7
--- /dev/null
+++ b/test/tint/unittest/reader/combined_texture_sampler/SplitCombinedImageSamplerPassTest_FunctionCall_Image_NoChange.spvasm
@@ -0,0 +1,81 @@
+ OpCapability Shader
+ OpCapability RuntimeDescriptorArray
+ OpExtension "SPV_EXT_descriptor_indexing"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ OpName %main "main"
+ OpName %main_0 "main_0"
+ OpName %voidfn "voidfn"
+
+ OpName %f "f"
+ OpName %f_ty "f_ty"
+ OpName %i_ty "i_ty"
+ OpName %s_ty "s_ty"
+ OpName %p_i_ty "p_i_ty"
+ OpName %p_s_ty "p_s_ty"
+
+ OpName %caller_ty "caller_ty"
+ OpName %caller "caller"
+ OpName %caller_entry "caller_entry"
+ OpName %caller_call "caller_call"
+ OpName %caller_arg "caller_arg"
+ %float = OpTypeFloat 32
+ %uint = OpTypeInt 32 0
+ %int = OpTypeInt 32 1
+ %uint_0 = OpConstant %uint 0
+ %uint_1 = OpConstant %uint 1
+ %uint_3 = OpConstant %uint 3
+ %float_0 = OpConstant %float 0
+ %v2float = OpTypeVector %float 2
+ %v3float = OpTypeVector %float 3
+ %v4float = OpTypeVector %float 4
+ %13 = OpConstantNull %v2float
+ %14 = OpConstantNull %v3float
+ %15 = OpConstantNull %v4float
+ %void = OpTypeVoid
+ %voidfn = OpTypeFunction %void
+
+ %i_ty = OpTypeImage %float 2D 0 0 0 1 Unknown
+ %s_ty = OpTypeSampler
+ %p_i_ty = OpTypePointer UniformConstant %i_ty
+ %p_s_ty = OpTypePointer UniformConstant %s_ty
+
+
+ ; CHECK: %f_ty = OpTypeFunction %void %i_ty
+ %f_ty = OpTypeFunction %void %i_ty
+ %caller_ty = OpTypeFunction %float %i_ty
+
+ ; The called function does not change
+ ; CHECK: %f = OpFunction %void None %f_ty
+ ; CHECK-NEXT: = OpFunctionParameter %i_ty
+ ; CHECK-NEXT: = OpLabel
+ ; CHECK-NEXT: OpReturn
+ ; CHECK-NEXT: OpFunctionEnd
+
+ %f = OpFunction %void None %f_ty
+ %100 = OpFunctionParameter %i_ty
+ %110 = OpLabel
+ OpReturn
+ OpFunctionEnd
+
+ ; The caller does not change
+ ; CHECK: %caller = OpFunction %float None %caller_ty
+ ; CHECK-NEXT: %caller_arg = OpFunctionParameter %i_ty
+ ; CHECK-NEXT: %caller_entry = OpLabel
+ ; CHECK-NEXT: OpFunctionCall %void %f %caller_arg
+ ; CHECK-NEXT: OpReturnValue %float_0
+ ; CHECK-NEXT: OpFunctionEnd
+
+ %caller = OpFunction %float None %caller_ty
+ %caller_arg = OpFunctionParameter %i_ty
+%caller_entry = OpLabel
+ %caller_call = OpFunctionCall %void %f %caller_arg
+ OpReturnValue %float_0
+ OpFunctionEnd
+
+
+ %main = OpFunction %void None %voidfn
+ %main_0 = OpLabel
+ OpReturn
+ OpFunctionEnd
diff --git a/test/tint/unittest/reader/combined_texture_sampler/SplitCombinedImageSamplerPassTest_FunctionCall_NoImageOrSampler_NoChange.spvasm b/test/tint/unittest/reader/combined_texture_sampler/SplitCombinedImageSamplerPassTest_FunctionCall_NoImageOrSampler_NoChange.spvasm
new file mode 100644
index 0000000..3d67151
--- /dev/null
+++ b/test/tint/unittest/reader/combined_texture_sampler/SplitCombinedImageSamplerPassTest_FunctionCall_NoImageOrSampler_NoChange.spvasm
@@ -0,0 +1,90 @@
+ OpCapability Shader
+ OpCapability RuntimeDescriptorArray
+ OpExtension "SPV_EXT_descriptor_indexing"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ OpName %main "main"
+ OpName %main_0 "main_0"
+ OpName %voidfn "voidfn"
+
+ OpName %f "f"
+ OpName %f_ty "f_ty"
+ OpName %i_ty "i_ty"
+ OpName %s_ty "s_ty"
+ OpName %p_i_ty "p_i_ty"
+ OpName %p_s_ty "p_s_ty"
+
+ OpName %caller_ty "caller_ty"
+ OpName %caller "caller"
+ OpName %caller_entry "caller_entry"
+ OpName %caller_call "caller_call"
+ OpName %caller_arg "caller_arg"
+ %float = OpTypeFloat 32
+ %uint = OpTypeInt 32 0
+ %int = OpTypeInt 32 1
+ %uint_0 = OpConstant %uint 0
+ %uint_1 = OpConstant %uint 1
+ %uint_3 = OpConstant %uint 3
+ %float_0 = OpConstant %float 0
+ %v2float = OpTypeVector %float 2
+ %v3float = OpTypeVector %float 3
+ %v4float = OpTypeVector %float 4
+ %13 = OpConstantNull %v2float
+ %14 = OpConstantNull %v3float
+ %15 = OpConstantNull %v4float
+ %void = OpTypeVoid
+ %voidfn = OpTypeFunction %void
+
+ %i_ty = OpTypeImage %float 2D 0 0 0 1 Unknown
+ %s_ty = OpTypeSampler
+ %p_i_ty = OpTypePointer UniformConstant %i_ty
+ %p_s_ty = OpTypePointer UniformConstant %s_ty
+
+ %si_ty = OpTypeSampledImage %i_ty
+ %p_si_ty = OpTypePointer UniformConstant %si_ty
+ %array_si_ty = OpTypeArray %si_ty %uint_3
+ %p_array_si_ty = OpTypePointer UniformConstant %array_si_ty
+ %rtarray_si_ty = OpTypeRuntimeArray %si_ty
+ %p_rtarray_si_ty = OpTypePointer UniformConstant %rtarray_si_ty
+
+
+ ; CHECK: %f_ty = OpTypeFunction %void %uint %float
+ %f_ty = OpTypeFunction %void %uint %float
+ %caller_ty = OpTypeFunction %float ; make it return non-void otherwise it's just like main
+
+ ; The called function does not change
+ ; CHECK: %f = OpFunction %void None %f_ty
+ ; CHECK-NEXT: = OpFunctionParameter %uint
+ ; CHECK-NEXT: = OpFunctionParameter %float
+ ; CHECK-NEXT: = OpLabel
+ ; CHECK-NEXT: OpReturn
+ ; CHECK-NEXT: OpFunctionEnd
+
+ %f = OpFunction %void None %f_ty
+ %100 = OpFunctionParameter %uint
+ %101 = OpFunctionParameter %float
+ %110 = OpLabel
+ OpReturn
+ OpFunctionEnd
+
+ ; The caller does not change
+ ; CHECK: %caller = OpFunction %float None %caller_ty
+ ; CHECK-NEXT: %caller_entry = OpLabel
+ ; CHECK-NEXT: %caller_arg = OpCopyObject %uint %uint_0
+ ; CHECK-NEXT: OpFunctionCall %void %f %caller_arg %float_0
+ ; CHECK-NEXT: OpReturnValue %float_0
+ ; CHECK-NEXT: OpFunctionEnd
+
+ %caller = OpFunction %float None %caller_ty
+%caller_entry = OpLabel
+ %caller_arg = OpCopyObject %uint %uint_0
+ %caller_call = OpFunctionCall %void %f %caller_arg %float_0
+ OpReturnValue %float_0
+ OpFunctionEnd
+
+
+ %main = OpFunction %void None %voidfn
+ %main_0 = OpLabel
+ OpReturn
+ OpFunctionEnd
diff --git a/test/tint/unittest/reader/combined_texture_sampler/SplitCombinedImageSamplerPassTest_FunctionCall_PtrImage_NoChange.spvasm b/test/tint/unittest/reader/combined_texture_sampler/SplitCombinedImageSamplerPassTest_FunctionCall_PtrImage_NoChange.spvasm
new file mode 100644
index 0000000..6099b45
--- /dev/null
+++ b/test/tint/unittest/reader/combined_texture_sampler/SplitCombinedImageSamplerPassTest_FunctionCall_PtrImage_NoChange.spvasm
@@ -0,0 +1,81 @@
+ OpCapability Shader
+ OpCapability RuntimeDescriptorArray
+ OpExtension "SPV_EXT_descriptor_indexing"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ OpName %main "main"
+ OpName %main_0 "main_0"
+ OpName %voidfn "voidfn"
+
+ OpName %f "f"
+ OpName %f_ty "f_ty"
+ OpName %i_ty "i_ty"
+ OpName %s_ty "s_ty"
+ OpName %p_i_ty "p_i_ty"
+ OpName %p_s_ty "p_s_ty"
+
+ OpName %caller_ty "caller_ty"
+ OpName %caller "caller"
+ OpName %caller_entry "caller_entry"
+ OpName %caller_call "caller_call"
+ OpName %caller_arg "caller_arg"
+ %float = OpTypeFloat 32
+ %uint = OpTypeInt 32 0
+ %int = OpTypeInt 32 1
+ %uint_0 = OpConstant %uint 0
+ %uint_1 = OpConstant %uint 1
+ %uint_3 = OpConstant %uint 3
+ %float_0 = OpConstant %float 0
+ %v2float = OpTypeVector %float 2
+ %v3float = OpTypeVector %float 3
+ %v4float = OpTypeVector %float 4
+ %13 = OpConstantNull %v2float
+ %14 = OpConstantNull %v3float
+ %15 = OpConstantNull %v4float
+ %void = OpTypeVoid
+ %voidfn = OpTypeFunction %void
+
+ %i_ty = OpTypeImage %float 2D 0 0 0 1 Unknown
+ %s_ty = OpTypeSampler
+ %p_i_ty = OpTypePointer UniformConstant %i_ty
+ %p_s_ty = OpTypePointer UniformConstant %s_ty
+
+
+ ; CHECK: %f_ty = OpTypeFunction %void %p_i_ty
+ %f_ty = OpTypeFunction %void %p_i_ty
+ %caller_ty = OpTypeFunction %float %p_i_ty
+
+ ; The called function does not change
+ ; CHECK: %f = OpFunction %void None %f_ty
+ ; CHECK-NEXT: = OpFunctionParameter %p_i_ty
+ ; CHECK-NEXT: = OpLabel
+ ; CHECK-NEXT: OpReturn
+ ; CHECK-NEXT: OpFunctionEnd
+
+ %f = OpFunction %void None %f_ty
+ %100 = OpFunctionParameter %p_i_ty
+ %110 = OpLabel
+ OpReturn
+ OpFunctionEnd
+
+ ; The caller does not change
+ ; CHECK: %caller = OpFunction %float None %caller_ty
+ ; CHECK-NEXT: %caller_arg = OpFunctionParameter %p_i_ty
+ ; CHECK-NEXT: %caller_entry = OpLabel
+ ; CHECK-NEXT: OpFunctionCall %void %f %caller_arg
+ ; CHECK-NEXT: OpReturnValue %float_0
+ ; CHECK-NEXT: OpFunctionEnd
+
+ %caller = OpFunction %float None %caller_ty
+ %caller_arg = OpFunctionParameter %p_i_ty
+%caller_entry = OpLabel
+ %caller_call = OpFunctionCall %void %f %caller_arg
+ OpReturnValue %float_0
+ OpFunctionEnd
+
+
+ %main = OpFunction %void None %voidfn
+ %main_0 = OpLabel
+ OpReturn
+ OpFunctionEnd
diff --git a/test/tint/unittest/reader/combined_texture_sampler/SplitCombinedImageSamplerPassTest_FunctionCall_PtrSampledImage_Split.spvasm b/test/tint/unittest/reader/combined_texture_sampler/SplitCombinedImageSamplerPassTest_FunctionCall_PtrSampledImage_Split.spvasm
new file mode 100644
index 0000000..4dff8fd
--- /dev/null
+++ b/test/tint/unittest/reader/combined_texture_sampler/SplitCombinedImageSamplerPassTest_FunctionCall_PtrSampledImage_Split.spvasm
@@ -0,0 +1,96 @@
+ OpCapability Shader
+ OpCapability RuntimeDescriptorArray
+ OpExtension "SPV_EXT_descriptor_indexing"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ OpName %main "main"
+ OpName %main_0 "main_0"
+ OpName %voidfn "voidfn"
+
+ OpName %f "f"
+ OpName %f_ty "f_ty"
+ OpName %i_ty "i_ty"
+ OpName %s_ty "s_ty"
+ OpName %p_i_ty "p_i_ty"
+ OpName %p_s_ty "p_s_ty"
+
+ OpName %si_ty "si_ty"
+ OpName %p_si_ty "p_si_ty"
+ OpName %array_si_ty "array_si_ty"
+ OpName %rtarray_si_ty "rtarray_si_ty"
+ OpName %p_array_si_ty "p_array_si_ty"
+ OpName %p_rtarray_si_ty "p_rtarray_si_ty"
+
+ OpName %caller_ty "caller_ty"
+ OpName %caller "caller"
+ OpName %caller_entry "caller_entry"
+ OpName %caller_call "caller_call"
+ OpName %caller_arg "caller_arg"
+ %float = OpTypeFloat 32
+ %uint = OpTypeInt 32 0
+ %int = OpTypeInt 32 1
+ %uint_0 = OpConstant %uint 0
+ %uint_1 = OpConstant %uint 1
+ %uint_3 = OpConstant %uint 3
+ %float_0 = OpConstant %float 0
+ %v2float = OpTypeVector %float 2
+ %v3float = OpTypeVector %float 3
+ %v4float = OpTypeVector %float 4
+ %13 = OpConstantNull %v2float
+ %14 = OpConstantNull %v3float
+ %15 = OpConstantNull %v4float
+ %void = OpTypeVoid
+ %voidfn = OpTypeFunction %void
+
+ %i_ty = OpTypeImage %float 2D 0 0 0 1 Unknown
+ %s_ty = OpTypeSampler
+ %p_i_ty = OpTypePointer UniformConstant %i_ty
+ %p_s_ty = OpTypePointer UniformConstant %s_ty
+
+ %si_ty = OpTypeSampledImage %i_ty
+ %p_si_ty = OpTypePointer UniformConstant %si_ty
+ %array_si_ty = OpTypeArray %si_ty %uint_3
+ %p_array_si_ty = OpTypePointer UniformConstant %array_si_ty
+ %rtarray_si_ty = OpTypeRuntimeArray %si_ty
+ %p_rtarray_si_ty = OpTypePointer UniformConstant %rtarray_si_ty
+
+
+ ; CHECK: %f_ty = OpTypeFunction %void %p_i_ty %p_s_ty
+ %f_ty = OpTypeFunction %void %p_si_ty
+ %caller_ty = OpTypeFunction %float %p_si_ty
+
+ ; Call function arg is split. We've checked these details in other tests.
+ ; CHECK: %f = OpFunction %void None %f_ty
+ ; CHECK-NEXT: %[[callee_i:\w+]] = OpFunctionParameter %p_i_ty
+ ; CHECK-NEXT: %[[callee_s:\w+]] = OpFunctionParameter %p_s_ty
+ ; CHECK-NEXT: = OpLabel
+ ; CHECK-NEXT: OpReturn
+ ; CHECK-NEXT: OpFunctionEnd
+
+ %f = OpFunction %void None %f_ty
+ %100 = OpFunctionParameter %p_si_ty
+ %110 = OpLabel
+ OpReturn
+ OpFunctionEnd
+
+ ; CHECK: %caller = OpFunction %float None %caller_ty
+ ; CHECK-NEXT: %[[caller_i:\w+]] = OpFunctionParameter %p_i_ty
+ ; CHECK-NEXT: %[[caller_s:\w+]] = OpFunctionParameter %p_s_ty
+ ; CHECK-NEXT: %caller_entry = OpLabel
+ ; CHECK-NEXT: %caller_call = OpFunctionCall %void %f %[[caller_i]] %[[caller_s]]
+ ; CHECK-NEXT: OpReturnValue %float_0
+ ; CHECK-NEXT: OpFunctionEnd
+
+ %caller = OpFunction %float None %caller_ty
+ %caller_arg = OpFunctionParameter %p_si_ty
+%caller_entry = OpLabel
+ %caller_call = OpFunctionCall %void %f %caller_arg
+ OpReturnValue %float_0
+ OpFunctionEnd
+
+
+ %main = OpFunction %void None %voidfn
+ %main_0 = OpLabel
+ OpReturn
+ OpFunctionEnd
diff --git a/test/tint/unittest/reader/combined_texture_sampler/SplitCombinedImageSamplerPassTest_FunctionCall_PtrSampler_NoChange.spvasm b/test/tint/unittest/reader/combined_texture_sampler/SplitCombinedImageSamplerPassTest_FunctionCall_PtrSampler_NoChange.spvasm
new file mode 100644
index 0000000..89a9842
--- /dev/null
+++ b/test/tint/unittest/reader/combined_texture_sampler/SplitCombinedImageSamplerPassTest_FunctionCall_PtrSampler_NoChange.spvasm
@@ -0,0 +1,81 @@
+ OpCapability Shader
+ OpCapability RuntimeDescriptorArray
+ OpExtension "SPV_EXT_descriptor_indexing"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ OpName %main "main"
+ OpName %main_0 "main_0"
+ OpName %voidfn "voidfn"
+
+ OpName %f "f"
+ OpName %f_ty "f_ty"
+ OpName %i_ty "i_ty"
+ OpName %s_ty "s_ty"
+ OpName %p_i_ty "p_i_ty"
+ OpName %p_s_ty "p_s_ty"
+
+ OpName %caller_ty "caller_ty"
+ OpName %caller "caller"
+ OpName %caller_entry "caller_entry"
+ OpName %caller_call "caller_call"
+ OpName %caller_arg "caller_arg"
+ %float = OpTypeFloat 32
+ %uint = OpTypeInt 32 0
+ %int = OpTypeInt 32 1
+ %uint_0 = OpConstant %uint 0
+ %uint_1 = OpConstant %uint 1
+ %uint_3 = OpConstant %uint 3
+ %float_0 = OpConstant %float 0
+ %v2float = OpTypeVector %float 2
+ %v3float = OpTypeVector %float 3
+ %v4float = OpTypeVector %float 4
+ %13 = OpConstantNull %v2float
+ %14 = OpConstantNull %v3float
+ %15 = OpConstantNull %v4float
+ %void = OpTypeVoid
+ %voidfn = OpTypeFunction %void
+
+ %i_ty = OpTypeImage %float 2D 0 0 0 1 Unknown
+ %s_ty = OpTypeSampler
+ %p_i_ty = OpTypePointer UniformConstant %i_ty
+ %p_s_ty = OpTypePointer UniformConstant %s_ty
+
+
+ ; CHECK: %f_ty = OpTypeFunction %void %p_s_ty
+ %f_ty = OpTypeFunction %void %p_s_ty
+ %caller_ty = OpTypeFunction %float %p_s_ty
+
+ ; The called function does not change
+ ; CHECK: %f = OpFunction %void None %f_ty
+ ; CHECK-NEXT: = OpFunctionParameter %p_s_ty
+ ; CHECK-NEXT: = OpLabel
+ ; CHECK-NEXT: OpReturn
+ ; CHECK-NEXT: OpFunctionEnd
+
+ %f = OpFunction %void None %f_ty
+ %100 = OpFunctionParameter %p_s_ty
+ %110 = OpLabel
+ OpReturn
+ OpFunctionEnd
+
+ ; The caller does not change
+ ; CHECK: %caller = OpFunction %float None %caller_ty
+ ; CHECK-NEXT: %caller_arg = OpFunctionParameter %p_s_ty
+ ; CHECK-NEXT: %caller_entry = OpLabel
+ ; CHECK-NEXT: OpFunctionCall %void %f %caller_arg
+ ; CHECK-NEXT: OpReturnValue %float_0
+ ; CHECK-NEXT: OpFunctionEnd
+
+ %caller = OpFunction %float None %caller_ty
+ %caller_arg = OpFunctionParameter %p_s_ty
+%caller_entry = OpLabel
+ %caller_call = OpFunctionCall %void %f %caller_arg
+ OpReturnValue %float_0
+ OpFunctionEnd
+
+
+ %main = OpFunction %void None %voidfn
+ %main_0 = OpLabel
+ OpReturn
+ OpFunctionEnd
diff --git a/test/tint/unittest/reader/combined_texture_sampler/SplitCombinedImageSamplerPassTest_FunctionCall_SampledImageAndCopy_Split.spvasm b/test/tint/unittest/reader/combined_texture_sampler/SplitCombinedImageSamplerPassTest_FunctionCall_SampledImageAndCopy_Split.spvasm
new file mode 100644
index 0000000..0224f57
--- /dev/null
+++ b/test/tint/unittest/reader/combined_texture_sampler/SplitCombinedImageSamplerPassTest_FunctionCall_SampledImageAndCopy_Split.spvasm
@@ -0,0 +1,101 @@
+ OpCapability Shader
+ OpCapability RuntimeDescriptorArray
+ OpExtension "SPV_EXT_descriptor_indexing"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ OpName %main "main"
+ OpName %main_0 "main_0"
+ OpName %voidfn "voidfn"
+
+ OpName %f "f"
+ OpName %f_ty "f_ty"
+ OpName %i_ty "i_ty"
+ OpName %s_ty "s_ty"
+ OpName %p_i_ty "p_i_ty"
+ OpName %p_s_ty "p_s_ty"
+
+ OpName %si_ty "si_ty"
+ OpName %p_si_ty "p_si_ty"
+ OpName %array_si_ty "array_si_ty"
+ OpName %rtarray_si_ty "rtarray_si_ty"
+ OpName %p_array_si_ty "p_array_si_ty"
+ OpName %p_rtarray_si_ty "p_rtarray_si_ty"
+
+ OpName %caller_ty "caller_ty"
+ OpName %caller "caller"
+ OpName %caller_entry "caller_entry"
+ OpName %caller_call "caller_call"
+ OpName %caller_arg "caller_arg"
+ %float = OpTypeFloat 32
+ %uint = OpTypeInt 32 0
+ %int = OpTypeInt 32 1
+ %uint_0 = OpConstant %uint 0
+ %uint_1 = OpConstant %uint 1
+ %uint_3 = OpConstant %uint 3
+ %float_0 = OpConstant %float 0
+ %v2float = OpTypeVector %float 2
+ %v3float = OpTypeVector %float 3
+ %v4float = OpTypeVector %float 4
+ %13 = OpConstantNull %v2float
+ %14 = OpConstantNull %v3float
+ %15 = OpConstantNull %v4float
+ %void = OpTypeVoid
+ %voidfn = OpTypeFunction %void
+
+ %i_ty = OpTypeImage %float 2D 0 0 0 1 Unknown
+ %s_ty = OpTypeSampler
+ %p_i_ty = OpTypePointer UniformConstant %i_ty
+ %p_s_ty = OpTypePointer UniformConstant %s_ty
+
+ %si_ty = OpTypeSampledImage %i_ty
+ %p_si_ty = OpTypePointer UniformConstant %si_ty
+ %array_si_ty = OpTypeArray %si_ty %uint_3
+ %p_array_si_ty = OpTypePointer UniformConstant %array_si_ty
+ %rtarray_si_ty = OpTypeRuntimeArray %si_ty
+ %p_rtarray_si_ty = OpTypePointer UniformConstant %rtarray_si_ty
+
+
+ ; CHECK: %f_ty = OpTypeFunction %void %i_ty %s_ty %i_ty %s_ty
+ %f_ty = OpTypeFunction %void %si_ty %si_ty
+ ; CHECK: %caller_ty = OpTypeFunction %float %i_ty %s_ty
+ %caller_ty = OpTypeFunction %float %si_ty
+
+ ; Call function arg is split. We've checked these details in other tests.
+ ; CHECK: %f = OpFunction %void None %f_ty
+ ; CHECK-NEXT: %[[callee_i_0:\w+]] = OpFunctionParameter %i_ty
+ ; CHECK-NEXT: %[[callee_s_0:\w+]] = OpFunctionParameter %s_ty
+ ; CHECK-NEXT: %[[callee_i_1:\w+]] = OpFunctionParameter %i_ty
+ ; CHECK-NEXT: %[[callee_s_1:\w+]] = OpFunctionParameter %s_ty
+ ; CHECK-NEXT: = OpLabel
+ ; CHECK-NEXT: OpReturn
+ ; CHECK-NEXT: OpFunctionEnd
+
+ %f = OpFunction %void None %f_ty
+ %100 = OpFunctionParameter %si_ty
+ %101 = OpFunctionParameter %si_ty
+ %110 = OpLabel
+ OpReturn
+ OpFunctionEnd
+
+ ; CHECK: %caller = OpFunction %float None %caller_ty
+ ; CHECK-NEXT: %[[caller_i:\w+]] = OpFunctionParameter %i_ty
+ ; CHECK-NEXT: %[[caller_s:\w+]] = OpFunctionParameter %s_ty
+ ; CHECK-NEXT: %caller_entry = OpLabel
+ ; CHECK-NEXT: %caller_call = OpFunctionCall %void %f %[[caller_i]] %[[caller_s]] %[[caller_i]] %[[caller_s]]
+ ; CHECK-NEXT: OpReturnValue %float_0
+ ; CHECK-NEXT: OpFunctionEnd
+
+ %caller = OpFunction %float None %caller_ty
+ %caller_arg = OpFunctionParameter %si_ty
+%caller_entry = OpLabel
+ %copy = OpCopyObject %si_ty %caller_arg
+ %caller_call = OpFunctionCall %void %f %caller_arg %copy
+ OpReturnValue %float_0
+ OpFunctionEnd
+
+
+ %main = OpFunction %void None %voidfn
+ %main_0 = OpLabel
+ OpReturn
+ OpFunctionEnd
diff --git a/test/tint/unittest/reader/combined_texture_sampler/SplitCombinedImageSamplerPassTest_FunctionCall_SampledImageDuplicatedArg_Split.spvasm b/test/tint/unittest/reader/combined_texture_sampler/SplitCombinedImageSamplerPassTest_FunctionCall_SampledImageDuplicatedArg_Split.spvasm
new file mode 100644
index 0000000..affc5a1
--- /dev/null
+++ b/test/tint/unittest/reader/combined_texture_sampler/SplitCombinedImageSamplerPassTest_FunctionCall_SampledImageDuplicatedArg_Split.spvasm
@@ -0,0 +1,99 @@
+ OpCapability Shader
+ OpCapability RuntimeDescriptorArray
+ OpExtension "SPV_EXT_descriptor_indexing"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ OpName %main "main"
+ OpName %main_0 "main_0"
+ OpName %voidfn "voidfn"
+
+ OpName %f "f"
+ OpName %f_ty "f_ty"
+ OpName %i_ty "i_ty"
+ OpName %s_ty "s_ty"
+ OpName %p_i_ty "p_i_ty"
+ OpName %p_s_ty "p_s_ty"
+
+ OpName %si_ty "si_ty"
+ OpName %p_si_ty "p_si_ty"
+ OpName %array_si_ty "array_si_ty"
+ OpName %rtarray_si_ty "rtarray_si_ty"
+ OpName %p_array_si_ty "p_array_si_ty"
+ OpName %p_rtarray_si_ty "p_rtarray_si_ty"
+
+ OpName %caller_ty "caller_ty"
+ OpName %caller "caller"
+ OpName %caller_entry "caller_entry"
+ OpName %caller_call "caller_call"
+ OpName %caller_arg "caller_arg"
+ %float = OpTypeFloat 32
+ %uint = OpTypeInt 32 0
+ %int = OpTypeInt 32 1
+ %uint_0 = OpConstant %uint 0
+ %uint_1 = OpConstant %uint 1
+ %uint_3 = OpConstant %uint 3
+ %float_0 = OpConstant %float 0
+ %v2float = OpTypeVector %float 2
+ %v3float = OpTypeVector %float 3
+ %v4float = OpTypeVector %float 4
+ %13 = OpConstantNull %v2float
+ %14 = OpConstantNull %v3float
+ %15 = OpConstantNull %v4float
+ %void = OpTypeVoid
+ %voidfn = OpTypeFunction %void
+
+ %i_ty = OpTypeImage %float 2D 0 0 0 1 Unknown
+ %s_ty = OpTypeSampler
+ %p_i_ty = OpTypePointer UniformConstant %i_ty
+ %p_s_ty = OpTypePointer UniformConstant %s_ty
+
+ %si_ty = OpTypeSampledImage %i_ty
+ %p_si_ty = OpTypePointer UniformConstant %si_ty
+ %array_si_ty = OpTypeArray %si_ty %uint_3
+ %p_array_si_ty = OpTypePointer UniformConstant %array_si_ty
+ %rtarray_si_ty = OpTypeRuntimeArray %si_ty
+ %p_rtarray_si_ty = OpTypePointer UniformConstant %rtarray_si_ty
+
+
+ ; CHECK: %f_ty = OpTypeFunction %void %i_ty %s_ty %i_ty %s_ty
+ %f_ty = OpTypeFunction %void %si_ty %si_ty
+ %caller_ty = OpTypeFunction %float %si_ty
+
+ ; Call function arg is split. We've checked these details in other tests.
+ ; CHECK: %f = OpFunction %void None %f_ty
+ ; CHECK-NEXT: %[[callee_i_0:\w+]] = OpFunctionParameter %i_ty
+ ; CHECK-NEXT: %[[callee_s_0:\w+]] = OpFunctionParameter %s_ty
+ ; CHECK-NEXT: %[[callee_i_1:\w+]] = OpFunctionParameter %i_ty
+ ; CHECK-NEXT: %[[callee_s_1:\w+]] = OpFunctionParameter %s_ty
+ ; CHECK-NEXT: = OpLabel
+ ; CHECK-NEXT: OpReturn
+ ; CHECK-NEXT: OpFunctionEnd
+
+ %f = OpFunction %void None %f_ty
+ %100 = OpFunctionParameter %si_ty
+ %101 = OpFunctionParameter %si_ty
+ %110 = OpLabel
+ OpReturn
+ OpFunctionEnd
+
+ ; CHECK: %caller = OpFunction %float None %caller_ty
+ ; CHECK-NEXT: %[[caller_i:\w+]] = OpFunctionParameter %i_ty
+ ; CHECK-NEXT: %[[caller_s:\w+]] = OpFunctionParameter %s_ty
+ ; CHECK-NEXT: %caller_entry = OpLabel
+ ; CHECK-NEXT: %caller_call = OpFunctionCall %void %f %[[caller_i]] %[[caller_s]] %[[caller_i]] %[[caller_s]]
+ ; CHECK-NEXT: OpReturnValue %float_0
+ ; CHECK-NEXT: OpFunctionEnd
+
+ %caller = OpFunction %float None %caller_ty
+ %caller_arg = OpFunctionParameter %si_ty
+%caller_entry = OpLabel
+ %caller_call = OpFunctionCall %void %f %caller_arg %caller_arg
+ OpReturnValue %float_0
+ OpFunctionEnd
+
+
+ %main = OpFunction %void None %voidfn
+ %main_0 = OpLabel
+ OpReturn
+ OpFunctionEnd
diff --git a/test/tint/unittest/reader/combined_texture_sampler/SplitCombinedImageSamplerPassTest_FunctionCall_SampledImageSurrounded_Split.spvasm b/test/tint/unittest/reader/combined_texture_sampler/SplitCombinedImageSamplerPassTest_FunctionCall_SampledImageSurrounded_Split.spvasm
new file mode 100644
index 0000000..1cc136d
--- /dev/null
+++ b/test/tint/unittest/reader/combined_texture_sampler/SplitCombinedImageSamplerPassTest_FunctionCall_SampledImageSurrounded_Split.spvasm
@@ -0,0 +1,105 @@
+ OpCapability Shader
+ OpCapability RuntimeDescriptorArray
+ OpExtension "SPV_EXT_descriptor_indexing"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ OpName %main "main"
+ OpName %main_0 "main_0"
+ OpName %voidfn "voidfn"
+
+ OpName %f "f"
+ OpName %f_ty "f_ty"
+ OpName %i_ty "i_ty"
+ OpName %s_ty "s_ty"
+ OpName %p_i_ty "p_i_ty"
+ OpName %p_s_ty "p_s_ty"
+
+ OpName %si_ty "si_ty"
+ OpName %p_si_ty "p_si_ty"
+ OpName %array_si_ty "array_si_ty"
+ OpName %rtarray_si_ty "rtarray_si_ty"
+ OpName %p_array_si_ty "p_array_si_ty"
+ OpName %p_rtarray_si_ty "p_rtarray_si_ty"
+
+ OpName %caller_ty "caller_ty"
+ OpName %caller "caller"
+ OpName %caller_entry "caller_entry"
+ OpName %caller_call "caller_call"
+ OpName %caller_arg "caller_arg"
+ %float = OpTypeFloat 32
+ %uint = OpTypeInt 32 0
+ %int = OpTypeInt 32 1
+ %uint_0 = OpConstant %uint 0
+ %uint_1 = OpConstant %uint 1
+ %uint_3 = OpConstant %uint 3
+ %float_0 = OpConstant %float 0
+ %v2float = OpTypeVector %float 2
+ %v3float = OpTypeVector %float 3
+ %v4float = OpTypeVector %float 4
+ %13 = OpConstantNull %v2float
+ %14 = OpConstantNull %v3float
+ %15 = OpConstantNull %v4float
+ %void = OpTypeVoid
+ %voidfn = OpTypeFunction %void
+
+ %i_ty = OpTypeImage %float 2D 0 0 0 1 Unknown
+ %s_ty = OpTypeSampler
+ %p_i_ty = OpTypePointer UniformConstant %i_ty
+ %p_s_ty = OpTypePointer UniformConstant %s_ty
+
+ %si_ty = OpTypeSampledImage %i_ty
+ %p_si_ty = OpTypePointer UniformConstant %si_ty
+ %array_si_ty = OpTypeArray %si_ty %uint_3
+ %p_array_si_ty = OpTypePointer UniformConstant %array_si_ty
+ %rtarray_si_ty = OpTypeRuntimeArray %si_ty
+ %p_rtarray_si_ty = OpTypePointer UniformConstant %rtarray_si_ty
+
+
+ ; CHECK: %f_ty = OpTypeFunction %void %float %i_ty %s_ty %uint
+ %f_ty = OpTypeFunction %void %float %si_ty %uint
+ ; CHECK: %caller_ty = OpTypeFunction %float %uint %i_ty %s_ty %float
+ %caller_ty = OpTypeFunction %float %uint %si_ty %float
+
+ ; Call function arg is split. We've checked these details in other tests.
+ ; CHECK: %f = OpFunction %void None %f_ty
+ ; CHECK-NEXT: %[[callee_f:\w+]] = OpFunctionParameter %float
+ ; CHECK-NEXT: %[[callee_i:\w+]] = OpFunctionParameter %i_ty
+ ; CHECK-NEXT: %[[callee_s:\w+]] = OpFunctionParameter %s_ty
+ ; CHECK-NEXT: %[[callee_u:\w+]] = OpFunctionParameter %uint
+ ; CHECK-NEXT: = OpLabel
+ ; CHECK-NEXT: OpReturn
+ ; CHECK-NEXT: OpFunctionEnd
+
+ %f = OpFunction %void None %f_ty
+ %99 = OpFunctionParameter %float
+ %100 = OpFunctionParameter %si_ty
+ %101 = OpFunctionParameter %uint
+ %110 = OpLabel
+ OpReturn
+ OpFunctionEnd
+
+ ; CHECK: %caller = OpFunction %float None %caller_ty
+ ; CHECK-NEXT: %[[u_param:\w+]] = OpFunctionParameter %uint
+ ; CHECK-NEXT: %[[caller_i:\w+]] = OpFunctionParameter %i_ty
+ ; CHECK-NEXT: %[[caller_s:\w+]] = OpFunctionParameter %s_ty
+ ; CHECK-NEXT: %[[f_param:\w+]] = OpFunctionParameter %float
+ ; CHECK-NEXT: %caller_entry = OpLabel
+ ; CHECK-NEXT: %caller_call = OpFunctionCall %void %f %[[f_param]] %[[caller_i]] %[[caller_s]] %[[u_param]]
+ ; CHECK-NEXT: OpReturnValue %float_0
+ ; CHECK-NEXT: OpFunctionEnd
+
+ %caller = OpFunction %float None %caller_ty
+ %200 = OpFunctionParameter %uint
+ %caller_arg = OpFunctionParameter %si_ty
+ %201 = OpFunctionParameter %float
+%caller_entry = OpLabel
+ %caller_call = OpFunctionCall %void %f %201 %caller_arg %200
+ OpReturnValue %float_0
+ OpFunctionEnd
+
+
+ %main = OpFunction %void None %voidfn
+ %main_0 = OpLabel
+ OpReturn
+ OpFunctionEnd
diff --git a/test/tint/unittest/reader/combined_texture_sampler/SplitCombinedImageSamplerPassTest_FunctionCall_SampledImageTwoDistinct_Split.spvasm b/test/tint/unittest/reader/combined_texture_sampler/SplitCombinedImageSamplerPassTest_FunctionCall_SampledImageTwoDistinct_Split.spvasm
new file mode 100644
index 0000000..96116aa
--- /dev/null
+++ b/test/tint/unittest/reader/combined_texture_sampler/SplitCombinedImageSamplerPassTest_FunctionCall_SampledImageTwoDistinct_Split.spvasm
@@ -0,0 +1,102 @@
+ OpCapability Shader
+ OpCapability RuntimeDescriptorArray
+ OpExtension "SPV_EXT_descriptor_indexing"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ OpName %main "main"
+ OpName %main_0 "main_0"
+ OpName %voidfn "voidfn"
+
+ OpName %f "f"
+ OpName %f_ty "f_ty"
+ OpName %i_ty "i_ty"
+ OpName %s_ty "s_ty"
+ OpName %p_i_ty "p_i_ty"
+ OpName %p_s_ty "p_s_ty"
+
+ OpName %si_ty "si_ty"
+ OpName %p_si_ty "p_si_ty"
+ OpName %array_si_ty "array_si_ty"
+ OpName %rtarray_si_ty "rtarray_si_ty"
+ OpName %p_array_si_ty "p_array_si_ty"
+ OpName %p_rtarray_si_ty "p_rtarray_si_ty"
+
+ OpName %caller_ty "caller_ty"
+ OpName %caller "caller"
+ OpName %caller_entry "caller_entry"
+ OpName %caller_call "caller_call"
+ OpName %caller_arg "caller_arg"
+ %float = OpTypeFloat 32
+ %uint = OpTypeInt 32 0
+ %int = OpTypeInt 32 1
+ %uint_0 = OpConstant %uint 0
+ %uint_1 = OpConstant %uint 1
+ %uint_3 = OpConstant %uint 3
+ %float_0 = OpConstant %float 0
+ %v2float = OpTypeVector %float 2
+ %v3float = OpTypeVector %float 3
+ %v4float = OpTypeVector %float 4
+ %13 = OpConstantNull %v2float
+ %14 = OpConstantNull %v3float
+ %15 = OpConstantNull %v4float
+ %void = OpTypeVoid
+ %voidfn = OpTypeFunction %void
+
+ %i_ty = OpTypeImage %float 2D 0 0 0 1 Unknown
+ %s_ty = OpTypeSampler
+ %p_i_ty = OpTypePointer UniformConstant %i_ty
+ %p_s_ty = OpTypePointer UniformConstant %s_ty
+
+ %si_ty = OpTypeSampledImage %i_ty
+ %p_si_ty = OpTypePointer UniformConstant %si_ty
+ %array_si_ty = OpTypeArray %si_ty %uint_3
+ %p_array_si_ty = OpTypePointer UniformConstant %array_si_ty
+ %rtarray_si_ty = OpTypeRuntimeArray %si_ty
+ %p_rtarray_si_ty = OpTypePointer UniformConstant %rtarray_si_ty
+
+
+ ; CHECK: %f_ty = OpTypeFunction %void %i_ty %s_ty %i_ty %s_ty
+ %f_ty = OpTypeFunction %void %si_ty %si_ty
+ %caller_ty = OpTypeFunction %float %si_ty %si_ty
+
+ ; Call function arg is split. We've checked these details in other tests.
+ ; CHECK: %f = OpFunction %void None %f_ty
+ ; CHECK-NEXT: %[[callee_i_0:\w+]] = OpFunctionParameter %i_ty
+ ; CHECK-NEXT: %[[callee_s_0:\w+]] = OpFunctionParameter %s_ty
+ ; CHECK-NEXT: %[[callee_i_1:\w+]] = OpFunctionParameter %i_ty
+ ; CHECK-NEXT: %[[callee_s_1:\w+]] = OpFunctionParameter %s_ty
+ ; CHECK-NEXT: = OpLabel
+ ; CHECK-NEXT: OpReturn
+ ; CHECK-NEXT: OpFunctionEnd
+
+ %f = OpFunction %void None %f_ty
+ %100 = OpFunctionParameter %si_ty
+ %101 = OpFunctionParameter %si_ty
+ %110 = OpLabel
+ OpReturn
+ OpFunctionEnd
+
+ ; CHECK: %caller = OpFunction %float None %caller_ty
+ ; CHECK-NEXT: %[[caller_i_0:\w+]] = OpFunctionParameter %i_ty
+ ; CHECK-NEXT: %[[caller_s_0:\w+]] = OpFunctionParameter %s_ty
+ ; CHECK-NEXT: %[[caller_i_1:\w+]] = OpFunctionParameter %i_ty
+ ; CHECK-NEXT: %[[caller_s_1:\w+]] = OpFunctionParameter %s_ty
+ ; CHECK-NEXT: %caller_entry = OpLabel
+ ; CHECK-NEXT: %caller_call = OpFunctionCall %void %f %[[caller_i_0]] %[[caller_s_0]] %[[caller_i_1]] %[[caller_s_1]]
+ ; CHECK-NEXT: OpReturnValue %float_0
+ ; CHECK-NEXT: OpFunctionEnd
+
+ %caller = OpFunction %float None %caller_ty
+ %caller_arg = OpFunctionParameter %si_ty
+ %201 = OpFunctionParameter %si_ty
+%caller_entry = OpLabel
+ %caller_call = OpFunctionCall %void %f %caller_arg %201
+ OpReturnValue %float_0
+ OpFunctionEnd
+
+
+ %main = OpFunction %void None %voidfn
+ %main_0 = OpLabel
+ OpReturn
+ OpFunctionEnd
diff --git a/test/tint/unittest/reader/combined_texture_sampler/SplitCombinedImageSamplerPassTest_FunctionCall_SampledImage_Split.spvasm b/test/tint/unittest/reader/combined_texture_sampler/SplitCombinedImageSamplerPassTest_FunctionCall_SampledImage_Split.spvasm
new file mode 100644
index 0000000..fc04e96
--- /dev/null
+++ b/test/tint/unittest/reader/combined_texture_sampler/SplitCombinedImageSamplerPassTest_FunctionCall_SampledImage_Split.spvasm
@@ -0,0 +1,96 @@
+ OpCapability Shader
+ OpCapability RuntimeDescriptorArray
+ OpExtension "SPV_EXT_descriptor_indexing"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ OpName %main "main"
+ OpName %main_0 "main_0"
+ OpName %voidfn "voidfn"
+
+ OpName %f "f"
+ OpName %f_ty "f_ty"
+ OpName %i_ty "i_ty"
+ OpName %s_ty "s_ty"
+ OpName %p_i_ty "p_i_ty"
+ OpName %p_s_ty "p_s_ty"
+
+ OpName %si_ty "si_ty"
+ OpName %p_si_ty "p_si_ty"
+ OpName %array_si_ty "array_si_ty"
+ OpName %rtarray_si_ty "rtarray_si_ty"
+ OpName %p_array_si_ty "p_array_si_ty"
+ OpName %p_rtarray_si_ty "p_rtarray_si_ty"
+
+ OpName %caller_ty "caller_ty"
+ OpName %caller "caller"
+ OpName %caller_entry "caller_entry"
+ OpName %caller_call "caller_call"
+ OpName %caller_arg "caller_arg"
+ %float = OpTypeFloat 32
+ %uint = OpTypeInt 32 0
+ %int = OpTypeInt 32 1
+ %uint_0 = OpConstant %uint 0
+ %uint_1 = OpConstant %uint 1
+ %uint_3 = OpConstant %uint 3
+ %float_0 = OpConstant %float 0
+ %v2float = OpTypeVector %float 2
+ %v3float = OpTypeVector %float 3
+ %v4float = OpTypeVector %float 4
+ %13 = OpConstantNull %v2float
+ %14 = OpConstantNull %v3float
+ %15 = OpConstantNull %v4float
+ %void = OpTypeVoid
+ %voidfn = OpTypeFunction %void
+
+ %i_ty = OpTypeImage %float 2D 0 0 0 1 Unknown
+ %s_ty = OpTypeSampler
+ %p_i_ty = OpTypePointer UniformConstant %i_ty
+ %p_s_ty = OpTypePointer UniformConstant %s_ty
+
+ %si_ty = OpTypeSampledImage %i_ty
+ %p_si_ty = OpTypePointer UniformConstant %si_ty
+ %array_si_ty = OpTypeArray %si_ty %uint_3
+ %p_array_si_ty = OpTypePointer UniformConstant %array_si_ty
+ %rtarray_si_ty = OpTypeRuntimeArray %si_ty
+ %p_rtarray_si_ty = OpTypePointer UniformConstant %rtarray_si_ty
+
+
+ ; CHECK: %f_ty = OpTypeFunction %void %i_ty %s_ty
+ %f_ty = OpTypeFunction %void %si_ty
+ %caller_ty = OpTypeFunction %float %si_ty
+
+ ; Call function arg is split. We've checked these details in other tests.
+ ; CHECK: %f = OpFunction %void None %f_ty
+ ; CHECK-NEXT: %[[callee_i:\w+]] = OpFunctionParameter %i_ty
+ ; CHECK-NEXT: %[[callee_s:\w+]] = OpFunctionParameter %s_ty
+ ; CHECK-NEXT: = OpLabel
+ ; CHECK-NEXT: OpReturn
+ ; CHECK-NEXT: OpFunctionEnd
+
+ %f = OpFunction %void None %f_ty
+ %100 = OpFunctionParameter %si_ty
+ %110 = OpLabel
+ OpReturn
+ OpFunctionEnd
+
+ ; CHECK: %caller = OpFunction %float None %caller_ty
+ ; CHECK-NEXT: %[[caller_i:\w+]] = OpFunctionParameter %i_ty
+ ; CHECK-NEXT: %[[caller_s:\w+]] = OpFunctionParameter %s_ty
+ ; CHECK-NEXT: %caller_entry = OpLabel
+ ; CHECK-NEXT: %caller_call = OpFunctionCall %void %f %[[caller_i]] %[[caller_s]]
+ ; CHECK-NEXT: OpReturnValue %float_0
+ ; CHECK-NEXT: OpFunctionEnd
+
+ %caller = OpFunction %float None %caller_ty
+ %caller_arg = OpFunctionParameter %si_ty
+%caller_entry = OpLabel
+ %caller_call = OpFunctionCall %void %f %caller_arg
+ OpReturnValue %float_0
+ OpFunctionEnd
+
+
+ %main = OpFunction %void None %voidfn
+ %main_0 = OpLabel
+ OpReturn
+ OpFunctionEnd
diff --git a/test/tint/unittest/reader/combined_texture_sampler/SplitCombinedImageSamplerPassTest_FunctionCall_Sampler_NoChange.spvasm b/test/tint/unittest/reader/combined_texture_sampler/SplitCombinedImageSamplerPassTest_FunctionCall_Sampler_NoChange.spvasm
new file mode 100644
index 0000000..e7f5b4e
--- /dev/null
+++ b/test/tint/unittest/reader/combined_texture_sampler/SplitCombinedImageSamplerPassTest_FunctionCall_Sampler_NoChange.spvasm
@@ -0,0 +1,81 @@
+ OpCapability Shader
+ OpCapability RuntimeDescriptorArray
+ OpExtension "SPV_EXT_descriptor_indexing"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ OpName %main "main"
+ OpName %main_0 "main_0"
+ OpName %voidfn "voidfn"
+
+ OpName %f "f"
+ OpName %f_ty "f_ty"
+ OpName %i_ty "i_ty"
+ OpName %s_ty "s_ty"
+ OpName %p_i_ty "p_i_ty"
+ OpName %p_s_ty "p_s_ty"
+
+ OpName %caller_ty "caller_ty"
+ OpName %caller "caller"
+ OpName %caller_entry "caller_entry"
+ OpName %caller_call "caller_call"
+ OpName %caller_arg "caller_arg"
+ %float = OpTypeFloat 32
+ %uint = OpTypeInt 32 0
+ %int = OpTypeInt 32 1
+ %uint_0 = OpConstant %uint 0
+ %uint_1 = OpConstant %uint 1
+ %uint_3 = OpConstant %uint 3
+ %float_0 = OpConstant %float 0
+ %v2float = OpTypeVector %float 2
+ %v3float = OpTypeVector %float 3
+ %v4float = OpTypeVector %float 4
+ %13 = OpConstantNull %v2float
+ %14 = OpConstantNull %v3float
+ %15 = OpConstantNull %v4float
+ %void = OpTypeVoid
+ %voidfn = OpTypeFunction %void
+
+ %i_ty = OpTypeImage %float 2D 0 0 0 1 Unknown
+ %s_ty = OpTypeSampler
+ %p_i_ty = OpTypePointer UniformConstant %i_ty
+ %p_s_ty = OpTypePointer UniformConstant %s_ty
+
+
+ ; CHECK: %f_ty = OpTypeFunction %void %s_ty
+ %f_ty = OpTypeFunction %void %s_ty
+ %caller_ty = OpTypeFunction %float %s_ty
+
+ ; The called function does not change
+ ; CHECK: %f = OpFunction %void None %f_ty
+ ; CHECK-NEXT: = OpFunctionParameter %s_ty
+ ; CHECK-NEXT: = OpLabel
+ ; CHECK-NEXT: OpReturn
+ ; CHECK-NEXT: OpFunctionEnd
+
+ %f = OpFunction %void None %f_ty
+ %100 = OpFunctionParameter %s_ty
+ %110 = OpLabel
+ OpReturn
+ OpFunctionEnd
+
+ ; The caller does not change
+ ; CHECK: %caller = OpFunction %float None %caller_ty
+ ; CHECK-NEXT: %caller_arg = OpFunctionParameter %s_ty
+ ; CHECK-NEXT: %caller_entry = OpLabel
+ ; CHECK-NEXT: OpFunctionCall %void %f %caller_arg
+ ; CHECK-NEXT: OpReturnValue %float_0
+ ; CHECK-NEXT: OpFunctionEnd
+
+ %caller = OpFunction %float None %caller_ty
+ %caller_arg = OpFunctionParameter %s_ty
+%caller_entry = OpLabel
+ %caller_call = OpFunctionCall %void %f %caller_arg
+ OpReturnValue %float_0
+ OpFunctionEnd
+
+
+ %main = OpFunction %void None %voidfn
+ %main_0 = OpLabel
+ OpReturn
+ OpFunctionEnd
diff --git a/test/tint/unittest/reader/combined_texture_sampler/SplitCombinedImageSamplerPassTest_FunctionType_ReplaceArrayArg.spvasm b/test/tint/unittest/reader/combined_texture_sampler/SplitCombinedImageSamplerPassTest_FunctionType_ReplaceArrayArg.spvasm
new file mode 100644
index 0000000..a56a114
--- /dev/null
+++ b/test/tint/unittest/reader/combined_texture_sampler/SplitCombinedImageSamplerPassTest_FunctionType_ReplaceArrayArg.spvasm
@@ -0,0 +1,51 @@
+ OpCapability Shader
+ OpCapability RuntimeDescriptorArray
+ OpExtension "SPV_EXT_descriptor_indexing"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ OpName %main "main"
+ OpName %main_0 "main_0"
+ OpName %voidfn "voidfn"
+
+ OpName %f_ty "f_ty"
+ OpName %sampler_ty "sampler_ty"
+ OpName %image_ty "image_ty"
+ OpName %sampled_image_ty "sampled_image_ty"
+ OpName %ptr_array_si_ty "ptr_array_si_ty"
+
+ %float = OpTypeFloat 32
+ %uint = OpTypeInt 32 0
+ %int = OpTypeInt 32 1
+ %uint_0 = OpConstant %uint 0
+ %uint_1 = OpConstant %uint 1
+ %uint_3 = OpConstant %uint 3
+ %float_0 = OpConstant %float 0
+ %v2float = OpTypeVector %float 2
+ %v3float = OpTypeVector %float 3
+ %v4float = OpTypeVector %float 4
+ %13 = OpConstantNull %v2float
+ %14 = OpConstantNull %v3float
+ %15 = OpConstantNull %v4float
+ %void = OpTypeVoid
+ %voidfn = OpTypeFunction %void
+
+
+ %sampler_ty = OpTypeSampler
+ %image_ty = OpTypeImage %float 2D 0 0 0 1 Unknown
+ %sampled_image_ty = OpTypeSampledImage %image_ty
+ %array_si_ty = OpTypeArray %sampled_image_ty %uint_3
+ %ptr_array_si_ty = OpTypePointer UniformConstant %array_si_ty
+
+ ; CHECK: %[[array_i_ty:\w+]] = OpTypeArray %image_ty %uint_3
+ ; CHECK: %[[ptr_array_i_ty:\w+]] = OpTypePointer UniformConstant %[[array_i_ty]]
+ ; CHECK: %[[array_s_ty:\w+]] = OpTypeArray %sampler_ty %uint_3
+ ; CHECK: %[[ptr_array_s_ty:\w+]] = OpTypePointer UniformConstant %[[array_s_ty]]
+
+ %f_ty = OpTypeFunction %float %uint %ptr_array_si_ty %float
+ ; CHECK: %f_ty = OpTypeFunction %float %uint %[[ptr_array_i_ty]] %[[ptr_array_s_ty]] %float
+
+ %main = OpFunction %void None %voidfn
+ %main_0 = OpLabel
+ OpReturn
+ OpFunctionEnd
diff --git a/test/tint/unittest/reader/combined_texture_sampler/SplitCombinedImageSamplerPassTest_FunctionType_ReplaceSampledImageArg.spvasm b/test/tint/unittest/reader/combined_texture_sampler/SplitCombinedImageSamplerPassTest_FunctionType_ReplaceSampledImageArg.spvasm
new file mode 100644
index 0000000..bcd1ec1
--- /dev/null
+++ b/test/tint/unittest/reader/combined_texture_sampler/SplitCombinedImageSamplerPassTest_FunctionType_ReplaceSampledImageArg.spvasm
@@ -0,0 +1,43 @@
+ OpCapability Shader
+ OpCapability RuntimeDescriptorArray
+ OpExtension "SPV_EXT_descriptor_indexing"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ OpName %main "main"
+ OpName %main_0 "main_0"
+ OpName %voidfn "voidfn"
+
+ OpName %f_ty "f_ty"
+ OpName %sampler_ty "sampler_ty"
+ OpName %image_ty "image_ty"
+ OpName %sampled_image_ty "sampled_image_ty"
+
+ %float = OpTypeFloat 32
+ %uint = OpTypeInt 32 0
+ %int = OpTypeInt 32 1
+ %uint_0 = OpConstant %uint 0
+ %uint_1 = OpConstant %uint 1
+ %uint_3 = OpConstant %uint 3
+ %float_0 = OpConstant %float 0
+ %v2float = OpTypeVector %float 2
+ %v3float = OpTypeVector %float 3
+ %v4float = OpTypeVector %float 4
+ %13 = OpConstantNull %v2float
+ %14 = OpConstantNull %v3float
+ %15 = OpConstantNull %v4float
+ %void = OpTypeVoid
+ %voidfn = OpTypeFunction %void
+
+
+ %sampler_ty = OpTypeSampler
+ %image_ty = OpTypeImage %float 2D 0 0 0 1 Unknown
+ %sampled_image_ty = OpTypeSampledImage %image_ty
+
+ %f_ty = OpTypeFunction %float %sampled_image_ty %float
+ ; CHECK: %f_ty = OpTypeFunction %float %image_ty %sampler_ty %float
+
+ %main = OpFunction %void None %voidfn
+ %main_0 = OpLabel
+ OpReturn
+ OpFunctionEnd
diff --git a/test/tint/unittest/reader/combined_texture_sampler/SplitCombinedImageSamplerPassTest_ImageOnly_NoChange.spvasm b/test/tint/unittest/reader/combined_texture_sampler/SplitCombinedImageSamplerPassTest_ImageOnly_NoChange.spvasm
new file mode 100644
index 0000000..a42e47f
--- /dev/null
+++ b/test/tint/unittest/reader/combined_texture_sampler/SplitCombinedImageSamplerPassTest_ImageOnly_NoChange.spvasm
@@ -0,0 +1,34 @@
+ OpCapability Shader
+ OpCapability RuntimeDescriptorArray
+ OpExtension "SPV_EXT_descriptor_indexing"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ OpName %main "main"
+ OpName %main_0 "main_0"
+ OpName %voidfn "voidfn"
+ OpDecorate %100 DescriptorSet 0
+ OpDecorate %100 Binding 0
+ %float = OpTypeFloat 32
+ %uint = OpTypeInt 32 0
+ %int = OpTypeInt 32 1
+ %uint_0 = OpConstant %uint 0
+ %uint_1 = OpConstant %uint 1
+ %uint_3 = OpConstant %uint 3
+ %float_0 = OpConstant %float 0
+ %v2float = OpTypeVector %float 2
+ %v3float = OpTypeVector %float 3
+ %v4float = OpTypeVector %float 4
+ %13 = OpConstantNull %v2float
+ %14 = OpConstantNull %v3float
+ %15 = OpConstantNull %v4float
+ %void = OpTypeVoid
+ %voidfn = OpTypeFunction %void
+ %10 = OpTypeImage %float 2D 0 0 0 1 Unknown
+%_ptr_UniformConstant_10 = OpTypePointer UniformConstant %10
+ %100 = OpVariable %_ptr_UniformConstant_10 UniformConstant
+ %main = OpFunction %void None %voidfn
+ %main_0 = OpLabel
+ %6 = OpLoad %10 %100
+ OpReturn
+ OpFunctionEnd
diff --git a/test/tint/unittest/reader/combined_texture_sampler/SplitCombinedImageSamplerPassTest_PtrArraySampledImageOnly_DeletesPtrType.spvasm b/test/tint/unittest/reader/combined_texture_sampler/SplitCombinedImageSamplerPassTest_PtrArraySampledImageOnly_DeletesPtrType.spvasm
new file mode 100644
index 0000000..aa15ec1
--- /dev/null
+++ b/test/tint/unittest/reader/combined_texture_sampler/SplitCombinedImageSamplerPassTest_PtrArraySampledImageOnly_DeletesPtrType.spvasm
@@ -0,0 +1,36 @@
+ OpCapability Shader
+ OpCapability RuntimeDescriptorArray
+ OpExtension "SPV_EXT_descriptor_indexing"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ OpName %main "main"
+ OpName %main_0 "main_0"
+ OpName %voidfn "voidfn"
+ %float = OpTypeFloat 32
+ %uint = OpTypeInt 32 0
+ %int = OpTypeInt 32 1
+ %uint_0 = OpConstant %uint 0
+ %uint_1 = OpConstant %uint 1
+ %uint_3 = OpConstant %uint 3
+ %float_0 = OpConstant %float 0
+ %v2float = OpTypeVector %float 2
+ %v3float = OpTypeVector %float 3
+ %v4float = OpTypeVector %float 4
+ %13 = OpConstantNull %v2float
+ %14 = OpConstantNull %v3float
+ %15 = OpConstantNull %v4float
+ %void = OpTypeVoid
+ %voidfn = OpTypeFunction %void
+
+ ; CHECK: OpCapability Shader
+ ; CHECK-NOT: OpTypePointer UniformConstant
+ ; CHECK: OpFunction %void
+ %100 = OpTypeImage %float 2D 0 0 0 1 Unknown
+ %101 = OpTypeSampledImage %100
+ %103 = OpTypeArray %101 %uint_1
+ %104 = OpTypePointer UniformConstant %103
+ %main = OpFunction %void None %voidfn
+ %main_0 = OpLabel
+ OpReturn
+ OpFunctionEnd
diff --git a/test/tint/unittest/reader/combined_texture_sampler/SplitCombinedImageSamplerPassTest_PtrRtArraySampledImageOnly_DeletesPtrType.spvasm b/test/tint/unittest/reader/combined_texture_sampler/SplitCombinedImageSamplerPassTest_PtrRtArraySampledImageOnly_DeletesPtrType.spvasm
new file mode 100644
index 0000000..4ea6247
--- /dev/null
+++ b/test/tint/unittest/reader/combined_texture_sampler/SplitCombinedImageSamplerPassTest_PtrRtArraySampledImageOnly_DeletesPtrType.spvasm
@@ -0,0 +1,36 @@
+ OpCapability Shader
+ OpCapability RuntimeDescriptorArray
+ OpExtension "SPV_EXT_descriptor_indexing"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ OpName %main "main"
+ OpName %main_0 "main_0"
+ OpName %voidfn "voidfn"
+ %float = OpTypeFloat 32
+ %uint = OpTypeInt 32 0
+ %int = OpTypeInt 32 1
+ %uint_0 = OpConstant %uint 0
+ %uint_1 = OpConstant %uint 1
+ %uint_3 = OpConstant %uint 3
+ %float_0 = OpConstant %float 0
+ %v2float = OpTypeVector %float 2
+ %v3float = OpTypeVector %float 3
+ %v4float = OpTypeVector %float 4
+ %13 = OpConstantNull %v2float
+ %14 = OpConstantNull %v3float
+ %15 = OpConstantNull %v4float
+ %void = OpTypeVoid
+ %voidfn = OpTypeFunction %void
+
+ ; CHECK: OpCapability Shader
+ ; CHECK-NOT: OpTypePointer UniformConstant
+ ; CHECK: OpFunction %void
+ %100 = OpTypeImage %float 2D 0 0 0 1 Unknown
+ %101 = OpTypeSampledImage %100
+ %103 = OpTypeRuntimeArray %101
+ %104 = OpTypePointer UniformConstant %103
+ %main = OpFunction %void None %voidfn
+ %main_0 = OpLabel
+ OpReturn
+ OpFunctionEnd
diff --git a/test/tint/unittest/reader/combined_texture_sampler/SplitCombinedImageSamplerPassTest_PtrSampledImageOnly_DeletesPtrType.spvasm b/test/tint/unittest/reader/combined_texture_sampler/SplitCombinedImageSamplerPassTest_PtrSampledImageOnly_DeletesPtrType.spvasm
new file mode 100644
index 0000000..d19bfac
--- /dev/null
+++ b/test/tint/unittest/reader/combined_texture_sampler/SplitCombinedImageSamplerPassTest_PtrSampledImageOnly_DeletesPtrType.spvasm
@@ -0,0 +1,35 @@
+ OpCapability Shader
+ OpCapability RuntimeDescriptorArray
+ OpExtension "SPV_EXT_descriptor_indexing"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ OpName %main "main"
+ OpName %main_0 "main_0"
+ OpName %voidfn "voidfn"
+ %float = OpTypeFloat 32
+ %uint = OpTypeInt 32 0
+ %int = OpTypeInt 32 1
+ %uint_0 = OpConstant %uint 0
+ %uint_1 = OpConstant %uint 1
+ %uint_3 = OpConstant %uint 3
+ %float_0 = OpConstant %float 0
+ %v2float = OpTypeVector %float 2
+ %v3float = OpTypeVector %float 3
+ %v4float = OpTypeVector %float 4
+ %13 = OpConstantNull %v2float
+ %14 = OpConstantNull %v3float
+ %15 = OpConstantNull %v4float
+ %void = OpTypeVoid
+ %voidfn = OpTypeFunction %void
+
+ ; CHECK: OpCapability Shader
+ ; CHECK-NOT: OpTypePointer UniformConstant
+ ; CHECK: OpFunction %void
+ %100 = OpTypeImage %float 2D 0 0 0 1 Unknown
+ %101 = OpTypeSampledImage %100
+ %102 = OpTypePointer UniformConstant %101
+ %main = OpFunction %void None %voidfn
+ %main_0 = OpLabel
+ OpReturn
+ OpFunctionEnd
diff --git a/test/tint/unittest/reader/combined_texture_sampler/SplitCombinedImageSamplerPassTest_SamplerOnly_NoChange.spvasm b/test/tint/unittest/reader/combined_texture_sampler/SplitCombinedImageSamplerPassTest_SamplerOnly_NoChange.spvasm
new file mode 100644
index 0000000..27cb9eb
--- /dev/null
+++ b/test/tint/unittest/reader/combined_texture_sampler/SplitCombinedImageSamplerPassTest_SamplerOnly_NoChange.spvasm
@@ -0,0 +1,34 @@
+ OpCapability Shader
+ OpCapability RuntimeDescriptorArray
+ OpExtension "SPV_EXT_descriptor_indexing"
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ OpName %main "main"
+ OpName %main_0 "main_0"
+ OpName %voidfn "voidfn"
+ OpDecorate %100 DescriptorSet 0
+ OpDecorate %100 Binding 0
+ %float = OpTypeFloat 32
+ %uint = OpTypeInt 32 0
+ %int = OpTypeInt 32 1
+ %uint_0 = OpConstant %uint 0
+ %uint_1 = OpConstant %uint 1
+ %uint_3 = OpConstant %uint 3
+ %float_0 = OpConstant %float 0
+ %v2float = OpTypeVector %float 2
+ %v3float = OpTypeVector %float 3
+ %v4float = OpTypeVector %float 4
+ %13 = OpConstantNull %v2float
+ %14 = OpConstantNull %v3float
+ %15 = OpConstantNull %v4float
+ %void = OpTypeVoid
+ %voidfn = OpTypeFunction %void
+ %10 = OpTypeSampler
+%_ptr_UniformConstant_10 = OpTypePointer UniformConstant %10
+ %100 = OpVariable %_ptr_UniformConstant_10 UniformConstant
+ %main = OpFunction %void None %voidfn
+ %main_0 = OpLabel
+ %6 = OpLoad %10 %100
+ OpReturn
+ OpFunctionEnd