spirv-reader: convert unsigned ConstOffset

Bug: tint:109
Fixed: tint:348
Change-Id: Ie3d1a6b6276ccb5184c5138d38931f7674324d59
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/35580
Commit-Queue: David Neto <dneto@google.com>
Reviewed-by: Ben Clayton <bclayton@google.com>
Auto-Submit: David Neto <dneto@google.com>
diff --git a/src/reader/spirv/function.cc b/src/reader/spirv/function.cc
index effad4f..29907df 100644
--- a/src/reader/spirv/function.cc
+++ b/src/reader/spirv/function.cc
@@ -4052,8 +4052,7 @@
   }
   if (arg_index < num_args &&
       (image_operands_mask & SpvImageOperandsConstOffsetMask)) {
-    // TODO(dneto): convert to signed integer if needed
-    params.push_back(MakeOperand(inst, arg_index).expr);
+    params.push_back(ToSignedIfUnsigned(MakeOperand(inst, arg_index)).expr);
     image_operands_mask ^= SpvImageOperandsConstOffsetMask;
     arg_index++;
   }
diff --git a/src/reader/spirv/parser_impl_handle_test.cc b/src/reader/spirv/parser_impl_handle_test.cc
index e170a28..e0ee403 100644
--- a/src/reader/spirv/parser_impl_handle_test.cc
+++ b/src/reader/spirv/parser_impl_handle_test.cc
@@ -1244,6 +1244,7 @@
      OpName %coords123 "coords123"
      OpName %coords1234 "coords1234"
      OpName %offsets2d "offsets2d"
+     OpName %u_offsets2d "u_offsets2d"
      OpDecorate %10 DescriptorSet 0
      OpDecorate %10 Binding 0
      OpDecorate %20 DescriptorSet 2
@@ -1289,6 +1290,9 @@
      %value_offset = OpCompositeConstruct %v2int %int_3 %int_4
      %offsets2d = OpCopyObject %v2int %value_offset
 
+     %u_value_offset = OpCompositeConstruct %v2uint %uint_3 %uint_4
+     %u_offsets2d = OpCopyObject %v2uint %u_value_offset
+
      %sam = OpLoad %sampler %10
      %im = OpLoad %im_ty %20
      %sampled_image = OpSampledImage %si_ty %im %sam
@@ -1575,9 +1579,7 @@
             )
           })"},
 
-        // OpImageSampleImplicitLod with Bias and ConstOffset
-        // TODO(dneto): OpImageSampleImplicitLod with Bias and unsigned
-        // ConstOffset
+        // OpImageSampleImplicitLod with Bias and signed ConstOffset
         ImageAccessCase{"%float 2D 0 0 0 1 Unknown",
                         "%result = OpImageSampleImplicitLod "
                         "%v4float %sampled_image %coords12 Bias|ConstOffset "
@@ -1612,6 +1614,46 @@
               Identifier[not set]{offsets2d}
             )
           })"},
+
+        // OpImageSampleImplicitLod with Bias and unsigned ConstOffset
+        // Convert ConstOffset to signed
+        ImageAccessCase{"%float 2D 0 0 0 1 Unknown",
+                        "%result = OpImageSampleImplicitLod "
+                        "%v4float %sampled_image %coords12 Bias|ConstOffset "
+                        "%float_7 %u_offsets2d",
+                        R"(
+  Variable{
+    Decorations{
+      SetDecoration{0}
+      BindingDecoration{0}
+    }
+    x_10
+    uniform_constant
+    __sampler_sampler
+  }
+  Variable{
+    Decorations{
+      SetDecoration{2}
+      BindingDecoration{1}
+    }
+    x_20
+    uniform_constant
+    __sampled_texture_2d__f32
+  })",
+                        R"(
+          Call[not set]{
+            Identifier[not set]{textureSampleBias}
+            (
+              Identifier[not set]{x_20}
+              Identifier[not set]{x_10}
+              Identifier[not set]{coords12}
+              ScalarConstructor[not set]{7.000000}
+              TypeConstructor[not set]{
+                __vec_2__i32
+                Identifier[not set]{u_offsets2d}
+              }
+            )
+          })"},
         // OpImageSampleImplicitLod arrayed with Bias
         ImageAccessCase{"%float 2D 0 1 0 1 Unknown",
                         "%result = OpImageSampleImplicitLod "
@@ -1984,8 +2026,6 @@
           })"},
 
         // OpImageSampleExplicitLod - using Lod and ConstOffset
-        // TODO(dneto) OpImageSampleExplicitLod - using Lod and unsigned
-        // ConstOffset
         ImageAccessCase{"%float 2D 0 0 0 1 Unknown",
                         "%result = OpImageSampleExplicitLod "
                         "%v4float %sampled_image %coords12 Lod|ConstOffset "
@@ -2021,6 +2061,46 @@
             )
           })"},
 
+        // OpImageSampleExplicitLod - using Lod and unsigned ConstOffset
+        // Convert the ConstOffset operand to signed
+        ImageAccessCase{"%float 2D 0 0 0 1 Unknown",
+                        "%result = OpImageSampleExplicitLod "
+                        "%v4float %sampled_image %coords12 Lod|ConstOffset "
+                        "%float_null %u_offsets2d",
+                        R"(
+  Variable{
+    Decorations{
+      SetDecoration{0}
+      BindingDecoration{0}
+    }
+    x_10
+    uniform_constant
+    __sampler_sampler
+  }
+  Variable{
+    Decorations{
+      SetDecoration{2}
+      BindingDecoration{1}
+    }
+    x_20
+    uniform_constant
+    __sampled_texture_2d__f32
+  })",
+                        R"(
+          Call[not set]{
+            Identifier[not set]{textureSampleLevel}
+            (
+              Identifier[not set]{x_20}
+              Identifier[not set]{x_10}
+              Identifier[not set]{coords12}
+              ScalarConstructor[not set]{0.000000}
+              TypeConstructor[not set]{
+                __vec_2__i32
+                Identifier[not set]{u_offsets2d}
+              }
+            )
+          })"},
+
         // OpImageSampleExplicitLod arrayed - using Lod and ConstOffset
         ImageAccessCase{"%float 2D 0 1 0 1 Unknown",
                         "%result = OpImageSampleExplicitLod "
@@ -2150,8 +2230,6 @@
           })"},
 
         // OpImageSampleExplicitLod - using Grad and ConstOffset
-        // TODO(dneto): OpImageSampleExplicitLod - using Grad and unsigned
-        // ConstOffset
         ImageAccessCase{"%float 2D 0 0 0 1 Unknown",
                         "%result = OpImageSampleExplicitLod "
                         "%v4float %sampled_image %coords12 Grad|ConstOffset "
@@ -2187,9 +2265,48 @@
               Identifier[not set]{offsets2d}
             )
           })"},
+
+        // OpImageSampleExplicitLod - using Grad and unsigned ConstOffset
+        ImageAccessCase{"%float 2D 0 0 0 1 Unknown",
+                        "%result = OpImageSampleExplicitLod "
+                        "%v4float %sampled_image %coords12 Grad|ConstOffset "
+                        "%float_7 %float_null %u_offsets2d",
+                        R"(
+  Variable{
+    Decorations{
+      SetDecoration{0}
+      BindingDecoration{0}
+    }
+    x_10
+    uniform_constant
+    __sampler_sampler
+  }
+  Variable{
+    Decorations{
+      SetDecoration{2}
+      BindingDecoration{1}
+    }
+    x_20
+    uniform_constant
+    __sampled_texture_2d__f32
+  })",
+                        R"(
+          Call[not set]{
+            Identifier[not set]{textureSampleGrad}
+            (
+              Identifier[not set]{x_20}
+              Identifier[not set]{x_10}
+              Identifier[not set]{coords12}
+              ScalarConstructor[not set]{7.000000}
+              ScalarConstructor[not set]{0.000000}
+              TypeConstructor[not set]{
+                __vec_2__i32
+                Identifier[not set]{u_offsets2d}
+              }
+            )
+          })"},
+
         // OpImageSampleExplicitLod arrayed - using Grad and ConstOffset
-        // TODO(dneto): OpImageSampleExplicitLod - using Grad and unsigned
-        // ConstOffset
         ImageAccessCase{"%float 2D 0 1 0 1 Unknown",
                         "%result = OpImageSampleExplicitLod "
                         "%v4float %sampled_image %coords123 Grad|ConstOffset "
@@ -2234,6 +2351,57 @@
               ScalarConstructor[not set]{0.000000}
               Identifier[not set]{offsets2d}
             )
+          })"},
+
+        // OpImageSampleExplicitLod arrayed - using Grad and unsigned
+        // ConstOffset
+        ImageAccessCase{"%float 2D 0 1 0 1 Unknown",
+                        "%result = OpImageSampleExplicitLod "
+                        "%v4float %sampled_image %coords123 Grad|ConstOffset "
+                        "%float_7 %float_null %u_offsets2d",
+                        R"(
+  Variable{
+    Decorations{
+      SetDecoration{0}
+      BindingDecoration{0}
+    }
+    x_10
+    uniform_constant
+    __sampler_sampler
+  }
+  Variable{
+    Decorations{
+      SetDecoration{2}
+      BindingDecoration{1}
+    }
+    x_20
+    uniform_constant
+    __sampled_texture_2d_array__f32
+  })",
+                        R"(
+          Call[not set]{
+            Identifier[not set]{textureSampleGrad}
+            (
+              Identifier[not set]{x_20}
+              Identifier[not set]{x_10}
+              MemberAccessor[not set]{
+                Identifier[not set]{coords123}
+                Identifier[not set]{xy}
+              }
+              TypeConstructor[not set]{
+                __i32
+                MemberAccessor[not set]{
+                  Identifier[not set]{coords123}
+                  Identifier[not set]{z}
+                }
+              }
+              ScalarConstructor[not set]{7.000000}
+              ScalarConstructor[not set]{0.000000}
+              TypeConstructor[not set]{
+                __vec_2__i32
+                Identifier[not set]{u_offsets2d}
+              }
+            )
           })"}));
 
 // Test crbug.com/378: