transform: DMA: Don't load ignore() arguments

ignore() might be passed a structure holding a runtime array.

Fixed: tint:1046
Change-Id: I2beab91d8faabe69409308cf3e24b6403a84dd56
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/60213
Kokoro: Kokoro <noreply+kokoro@google.com>
Reviewed-by: David Neto <dneto@google.com>
Auto-Submit: Ben Clayton <bclayton@google.com>
diff --git a/src/transform/decompose_memory_access.cc b/src/transform/decompose_memory_access.cc
index 8f94f18..09aed03 100644
--- a/src/transform/decompose_memory_access.cc
+++ b/src/transform/decompose_memory_access.cc
@@ -915,11 +915,18 @@
     if (auto* call_expr = node->As<ast::CallExpression>()) {
       auto* call = sem.Get(call_expr);
       if (auto* intrinsic = call->Target()->As<sem::Intrinsic>()) {
+        if (intrinsic->Type() == sem::IntrinsicType::kIgnore) {
+          // ignore(X)
+          // Don't convert X into a load, this isn't actually used.
+          state.TakeAccess(call_expr->params()[0]);
+          continue;
+        }
         if (intrinsic->Type() == sem::IntrinsicType::kArrayLength) {
           // arrayLength(X)
           // Don't convert X into a load, this intrinsic actually requires the
           // real pointer.
           state.TakeAccess(call_expr->params()[0]);
+          continue;
         }
         if (intrinsic->IsAtomic()) {
           if (auto access = state.TakeAccess(call_expr->params()[0])) {
diff --git a/test/bug/tint/1046.wgsl b/test/bug/tint/1046.wgsl
new file mode 100644
index 0000000..c288728
--- /dev/null
+++ b/test/bug/tint/1046.wgsl
@@ -0,0 +1,80 @@
+
+struct PointLight {
+    position : vec4<f32>;
+};
+
+[[block]] struct PointLights {
+    values : [[stride(16)]] array<PointLight>;
+};
+
+[[block]] struct Uniforms {
+    worldView : mat4x4<f32>;
+    proj : mat4x4<f32>;
+    numPointLights : u32;
+    color_source : u32;
+    color : vec4<f32>;
+};
+
+[[binding(0), group(0)]] var<uniform> uniforms : Uniforms;
+[[binding(1), group(0)]] var<storage_buffer, read> pointLights : PointLights;
+[[binding(2), group(0)]] var mySampler: sampler;
+[[binding(3), group(0)]] var myTexture: texture_2d<f32>;
+
+struct FragmentInput {
+    [[builtin(position)]] position  : vec4<f32>;
+    [[location(0)]] view_position   : vec4<f32>;
+    [[location(1)]] normal          : vec4<f32>;
+    [[location(2)]] uv              : vec2<f32>;
+    [[location(3)]] color           : vec4<f32>;
+};
+
+struct FragmentOutput {
+    [[location(0)]] color : vec4<f32>;
+};
+
+fn getColor(fragment : FragmentInput) -> vec4<f32>{
+
+    var color : vec4<f32>;
+
+    if(uniforms.color_source == 0u){
+        // VERTEX COLOR
+
+        color = fragment.color;
+
+    }elseif(uniforms.color_source == 1u){
+        // NORMALS
+
+        // color = vec4<f32>(0.0, 0.0, 1.0, 1.0);
+        color = fragment.normal;
+        color.a = 1.0;
+
+    }elseif(uniforms.color_source == 2u){
+        // uniform color
+
+        color = uniforms.color;
+
+    }elseif(uniforms.color_source == 3u){
+        // TEXTURE
+
+        color = textureSample(myTexture, mySampler, fragment.uv);
+
+    }
+
+    return color;
+};
+
+[[stage(fragment)]]
+fn main(fragment : FragmentInput) -> FragmentOutput {
+
+    var output : FragmentOutput;
+    output.color = vec4<f32>(1.0, 0.0, 0.0, 1.0);
+
+    ignore(uniforms);
+    ignore(mySampler);
+    ignore(myTexture);
+
+    ignore(pointLights);
+    // output.color.x = output.color.x + pointLights.values[0].position.x;
+
+    return output;
+}
diff --git a/test/bug/tint/1046.wgsl.expected.hlsl b/test/bug/tint/1046.wgsl.expected.hlsl
new file mode 100644
index 0000000..fd700b1
--- /dev/null
+++ b/test/bug/tint/1046.wgsl.expected.hlsl
@@ -0,0 +1,61 @@
+cbuffer cbuffer_uniforms : register(b0, space0) {
+  uint4 uniforms[10];
+};
+ByteAddressBuffer pointLights : register(t1, space0);
+SamplerState mySampler : register(s2, space0);
+Texture2D<float4> myTexture : register(t3, space0);
+
+struct FragmentInput {
+  float4 position;
+  float4 view_position;
+  float4 normal;
+  float2 uv;
+  float4 color;
+};
+struct FragmentOutput {
+  float4 color;
+};
+
+float4 getColor(FragmentInput fragment) {
+  float4 color = float4(0.0f, 0.0f, 0.0f, 0.0f);
+  if ((uniforms[8].y == 0u)) {
+    color = fragment.color;
+  } else {
+    if ((uniforms[8].y == 1u)) {
+      color = fragment.normal;
+      color.a = 1.0f;
+    } else {
+      if ((uniforms[8].y == 2u)) {
+        color = asfloat(uniforms[9]);
+      } else {
+        if ((uniforms[8].y == 3u)) {
+          color = myTexture.Sample(mySampler, fragment.uv);
+        }
+      }
+    }
+  }
+  return color;
+}
+
+struct tint_symbol_1 {
+  float4 view_position : TEXCOORD0;
+  float4 normal : TEXCOORD1;
+  float2 uv : TEXCOORD2;
+  float4 color : TEXCOORD3;
+  float4 position : SV_Position;
+};
+struct tint_symbol_2 {
+  float4 color : SV_Target0;
+};
+
+tint_symbol_2 main(tint_symbol_1 tint_symbol) {
+  const FragmentInput fragment = {tint_symbol.position, tint_symbol.view_position, tint_symbol.normal, tint_symbol.uv, tint_symbol.color};
+  FragmentOutput output = (FragmentOutput)0;
+  output.color = float4(1.0f, 0.0f, 0.0f, 1.0f);
+  uniforms;
+  mySampler;
+  myTexture;
+  pointLights;
+  const tint_symbol_2 tint_symbol_5 = {output.color};
+  return tint_symbol_5;
+}
diff --git a/test/bug/tint/1046.wgsl.expected.msl b/test/bug/tint/1046.wgsl.expected.msl
new file mode 100644
index 0000000..0de4fdf
--- /dev/null
+++ b/test/bug/tint/1046.wgsl.expected.msl
@@ -0,0 +1,70 @@
+#include <metal_stdlib>
+
+using namespace metal;
+struct PointLight {
+  /* 0x0000 */ packed_float4 position;
+};
+struct PointLights {
+  /* 0x0000 */ PointLight values[1];
+};
+struct Uniforms {
+  /* 0x0000 */ float4x4 worldView;
+  /* 0x0040 */ float4x4 proj;
+  /* 0x0080 */ uint numPointLights;
+  /* 0x0084 */ uint color_source;
+  /* 0x0088 */ int8_t tint_pad[8];
+  /* 0x0090 */ packed_float4 color;
+};
+struct FragmentInput {
+  float4 position;
+  float4 view_position;
+  float4 normal;
+  float2 uv;
+  float4 color;
+};
+struct FragmentOutput {
+  float4 color;
+};
+struct tint_symbol_4 {
+  float4 view_position [[user(locn0)]];
+  float4 normal [[user(locn1)]];
+  float2 uv [[user(locn2)]];
+  float4 color [[user(locn3)]];
+};
+struct tint_symbol_5 {
+  float4 color [[color(0)]];
+};
+
+float4 getColor(constant Uniforms& uniforms, FragmentInput tint_symbol, texture2d<float, access::sample> tint_symbol_7, sampler tint_symbol_8) {
+  float4 color = 0.0f;
+  if ((uniforms.color_source == 0u)) {
+    color = tint_symbol.color;
+  } else {
+    if ((uniforms.color_source == 1u)) {
+      color = tint_symbol.normal;
+      color.a = 1.0f;
+    } else {
+      if ((uniforms.color_source == 2u)) {
+        color = uniforms.color;
+      } else {
+        if ((uniforms.color_source == 3u)) {
+          color = tint_symbol_7.sample(tint_symbol_8, tint_symbol.uv);
+        }
+      }
+    }
+  }
+  return color;
+}
+
+fragment tint_symbol_5 tint_symbol_1(sampler tint_symbol_9 [[sampler(2)]], texture2d<float, access::sample> tint_symbol_10 [[texture(3)]], float4 tint_symbol_3 [[position]], tint_symbol_4 tint_symbol_2 [[stage_in]], constant Uniforms& uniforms [[buffer(0)]], const device PointLights& pointLights [[buffer(1)]]) {
+  FragmentInput const tint_symbol = {.position=tint_symbol_3, .view_position=tint_symbol_2.view_position, .normal=tint_symbol_2.normal, .uv=tint_symbol_2.uv, .color=tint_symbol_2.color};
+  FragmentOutput output = {};
+  output.color = float4(1.0f, 0.0f, 0.0f, 1.0f);
+  (void) uniforms;
+  (void) tint_symbol_9;
+  (void) tint_symbol_10;
+  (void) pointLights;
+  tint_symbol_5 const tint_symbol_6 = {.color=output.color};
+  return tint_symbol_6;
+}
+
diff --git a/test/bug/tint/1046.wgsl.expected.spvasm b/test/bug/tint/1046.wgsl.expected.spvasm
new file mode 100644
index 0000000..9623706
--- /dev/null
+++ b/test/bug/tint/1046.wgsl.expected.spvasm
@@ -0,0 +1,217 @@
+; SPIR-V
+; Version: 1.3
+; Generator: Google Tint Compiler; 0
+; Bound: 114
+; Schema: 0
+               OpCapability Shader
+               OpMemoryModel Logical GLSL450
+               OpEntryPoint Fragment %main "main" %tint_symbol %tint_symbol_1 %tint_symbol_2 %tint_symbol_3 %tint_symbol_4 %tint_symbol_7
+               OpExecutionMode %main OriginUpperLeft
+               OpName %Uniforms "Uniforms"
+               OpMemberName %Uniforms 0 "worldView"
+               OpMemberName %Uniforms 1 "proj"
+               OpMemberName %Uniforms 2 "numPointLights"
+               OpMemberName %Uniforms 3 "color_source"
+               OpMemberName %Uniforms 4 "color"
+               OpName %uniforms "uniforms"
+               OpName %PointLights "PointLights"
+               OpMemberName %PointLights 0 "values"
+               OpName %PointLight "PointLight"
+               OpMemberName %PointLight 0 "position"
+               OpName %pointLights "pointLights"
+               OpName %mySampler "mySampler"
+               OpName %myTexture "myTexture"
+               OpName %tint_symbol "tint_symbol"
+               OpName %tint_symbol_1 "tint_symbol_1"
+               OpName %tint_symbol_2 "tint_symbol_2"
+               OpName %tint_symbol_3 "tint_symbol_3"
+               OpName %tint_symbol_4 "tint_symbol_4"
+               OpName %tint_symbol_7 "tint_symbol_7"
+               OpName %FragmentInput "FragmentInput"
+               OpMemberName %FragmentInput 0 "position"
+               OpMemberName %FragmentInput 1 "view_position"
+               OpMemberName %FragmentInput 2 "normal"
+               OpMemberName %FragmentInput 3 "uv"
+               OpMemberName %FragmentInput 4 "color"
+               OpName %getColor "getColor"
+               OpName %fragment "fragment"
+               OpName %color "color"
+               OpName %FragmentOutput "FragmentOutput"
+               OpMemberName %FragmentOutput 0 "color"
+               OpName %tint_symbol_8 "tint_symbol_8"
+               OpName %tint_symbol_6 "tint_symbol_6"
+               OpName %main "main"
+               OpName %output "output"
+               OpDecorate %Uniforms Block
+               OpMemberDecorate %Uniforms 0 Offset 0
+               OpMemberDecorate %Uniforms 0 ColMajor
+               OpMemberDecorate %Uniforms 0 MatrixStride 16
+               OpMemberDecorate %Uniforms 1 Offset 64
+               OpMemberDecorate %Uniforms 1 ColMajor
+               OpMemberDecorate %Uniforms 1 MatrixStride 16
+               OpMemberDecorate %Uniforms 2 Offset 128
+               OpMemberDecorate %Uniforms 3 Offset 132
+               OpMemberDecorate %Uniforms 4 Offset 144
+               OpDecorate %uniforms NonWritable
+               OpDecorate %uniforms Binding 0
+               OpDecorate %uniforms DescriptorSet 0
+               OpDecorate %PointLights Block
+               OpMemberDecorate %PointLights 0 Offset 0
+               OpMemberDecorate %PointLight 0 Offset 0
+               OpDecorate %_runtimearr_PointLight ArrayStride 16
+               OpDecorate %pointLights NonWritable
+               OpDecorate %pointLights Binding 1
+               OpDecorate %pointLights DescriptorSet 0
+               OpDecorate %mySampler Binding 2
+               OpDecorate %mySampler DescriptorSet 0
+               OpDecorate %myTexture Binding 3
+               OpDecorate %myTexture DescriptorSet 0
+               OpDecorate %tint_symbol BuiltIn FragCoord
+               OpDecorate %tint_symbol_1 Location 0
+               OpDecorate %tint_symbol_2 Location 1
+               OpDecorate %tint_symbol_3 Location 2
+               OpDecorate %tint_symbol_4 Location 3
+               OpDecorate %tint_symbol_7 Location 0
+               OpMemberDecorate %FragmentInput 0 Offset 0
+               OpMemberDecorate %FragmentInput 1 Offset 16
+               OpMemberDecorate %FragmentInput 2 Offset 32
+               OpMemberDecorate %FragmentInput 3 Offset 48
+               OpMemberDecorate %FragmentInput 4 Offset 64
+               OpMemberDecorate %FragmentOutput 0 Offset 0
+      %float = OpTypeFloat 32
+    %v4float = OpTypeVector %float 4
+%mat4v4float = OpTypeMatrix %v4float 4
+       %uint = OpTypeInt 32 0
+   %Uniforms = OpTypeStruct %mat4v4float %mat4v4float %uint %uint %v4float
+%_ptr_Uniform_Uniforms = OpTypePointer Uniform %Uniforms
+   %uniforms = OpVariable %_ptr_Uniform_Uniforms Uniform
+ %PointLight = OpTypeStruct %v4float
+%_runtimearr_PointLight = OpTypeRuntimeArray %PointLight
+%PointLights = OpTypeStruct %_runtimearr_PointLight
+%_ptr_StorageBuffer_PointLights = OpTypePointer StorageBuffer %PointLights
+%pointLights = OpVariable %_ptr_StorageBuffer_PointLights StorageBuffer
+         %15 = OpTypeSampler
+%_ptr_UniformConstant_15 = OpTypePointer UniformConstant %15
+  %mySampler = OpVariable %_ptr_UniformConstant_15 UniformConstant
+         %18 = OpTypeImage %float 2D 0 0 0 1 Unknown
+%_ptr_UniformConstant_18 = OpTypePointer UniformConstant %18
+  %myTexture = OpVariable %_ptr_UniformConstant_18 UniformConstant
+%_ptr_Input_v4float = OpTypePointer Input %v4float
+%tint_symbol = OpVariable %_ptr_Input_v4float Input
+%tint_symbol_1 = OpVariable %_ptr_Input_v4float Input
+%tint_symbol_2 = OpVariable %_ptr_Input_v4float Input
+    %v2float = OpTypeVector %float 2
+%_ptr_Input_v2float = OpTypePointer Input %v2float
+%tint_symbol_3 = OpVariable %_ptr_Input_v2float Input
+%tint_symbol_4 = OpVariable %_ptr_Input_v4float Input
+%_ptr_Output_v4float = OpTypePointer Output %v4float
+         %29 = OpConstantNull %v4float
+%tint_symbol_7 = OpVariable %_ptr_Output_v4float Output %29
+%FragmentInput = OpTypeStruct %v4float %v4float %v4float %v2float %v4float
+         %30 = OpTypeFunction %v4float %FragmentInput
+%_ptr_Function_v4float = OpTypePointer Function %v4float
+     %uint_3 = OpConstant %uint 3
+%_ptr_Uniform_uint = OpTypePointer Uniform %uint
+     %uint_0 = OpConstant %uint 0
+       %bool = OpTypeBool
+     %uint_1 = OpConstant %uint 1
+%_ptr_Function_float = OpTypePointer Function %float
+    %float_1 = OpConstant %float 1
+     %uint_2 = OpConstant %uint 2
+     %uint_4 = OpConstant %uint 4
+%_ptr_Uniform_v4float = OpTypePointer Uniform %v4float
+         %78 = OpTypeSampledImage %18
+       %void = OpTypeVoid
+%FragmentOutput = OpTypeStruct %v4float
+         %82 = OpTypeFunction %void %FragmentOutput
+         %89 = OpTypeFunction %void
+%_ptr_Function_FragmentOutput = OpTypePointer Function %FragmentOutput
+        %100 = OpConstantNull %FragmentOutput
+    %float_0 = OpConstant %float 0
+        %103 = OpConstantComposite %v4float %float_1 %float_0 %float_0 %float_1
+   %getColor = OpFunction %v4float None %30
+   %fragment = OpFunctionParameter %FragmentInput
+         %34 = OpLabel
+      %color = OpVariable %_ptr_Function_v4float Function %29
+         %39 = OpAccessChain %_ptr_Uniform_uint %uniforms %uint_3
+         %40 = OpLoad %uint %39
+         %42 = OpIEqual %bool %40 %uint_0
+               OpSelectionMerge %44 None
+               OpBranchConditional %42 %45 %46
+         %45 = OpLabel
+         %47 = OpCompositeExtract %v4float %fragment 4
+               OpStore %color %47
+               OpBranch %44
+         %46 = OpLabel
+         %48 = OpAccessChain %_ptr_Uniform_uint %uniforms %uint_3
+         %49 = OpLoad %uint %48
+         %51 = OpIEqual %bool %49 %uint_1
+               OpSelectionMerge %52 None
+               OpBranchConditional %51 %53 %54
+         %53 = OpLabel
+         %55 = OpCompositeExtract %v4float %fragment 2
+               OpStore %color %55
+         %57 = OpAccessChain %_ptr_Function_float %color %uint_3
+               OpStore %57 %float_1
+               OpBranch %52
+         %54 = OpLabel
+         %59 = OpAccessChain %_ptr_Uniform_uint %uniforms %uint_3
+         %60 = OpLoad %uint %59
+         %62 = OpIEqual %bool %60 %uint_2
+               OpSelectionMerge %63 None
+               OpBranchConditional %62 %64 %65
+         %64 = OpLabel
+         %68 = OpAccessChain %_ptr_Uniform_v4float %uniforms %uint_4
+         %69 = OpLoad %v4float %68
+               OpStore %color %69
+               OpBranch %63
+         %65 = OpLabel
+         %70 = OpAccessChain %_ptr_Uniform_uint %uniforms %uint_3
+         %71 = OpLoad %uint %70
+         %72 = OpIEqual %bool %71 %uint_3
+               OpSelectionMerge %73 None
+               OpBranchConditional %72 %74 %73
+         %74 = OpLabel
+         %76 = OpLoad %15 %mySampler
+         %77 = OpLoad %18 %myTexture
+         %79 = OpSampledImage %78 %77 %76
+         %80 = OpCompositeExtract %v2float %fragment 3
+         %75 = OpImageSampleImplicitLod %v4float %79 %80
+               OpStore %color %75
+               OpBranch %73
+         %73 = OpLabel
+               OpBranch %63
+         %63 = OpLabel
+               OpBranch %52
+         %52 = OpLabel
+               OpBranch %44
+         %44 = OpLabel
+         %81 = OpLoad %v4float %color
+               OpReturnValue %81
+               OpFunctionEnd
+%tint_symbol_8 = OpFunction %void None %82
+%tint_symbol_6 = OpFunctionParameter %FragmentOutput
+         %87 = OpLabel
+         %88 = OpCompositeExtract %v4float %tint_symbol_6 0
+               OpStore %tint_symbol_7 %88
+               OpReturn
+               OpFunctionEnd
+       %main = OpFunction %void None %89
+         %91 = OpLabel
+     %output = OpVariable %_ptr_Function_FragmentOutput Function %100
+         %92 = OpLoad %v4float %tint_symbol
+         %93 = OpLoad %v4float %tint_symbol_1
+         %94 = OpLoad %v4float %tint_symbol_2
+         %95 = OpLoad %v2float %tint_symbol_3
+         %96 = OpLoad %v4float %tint_symbol_4
+         %97 = OpCompositeConstruct %FragmentInput %92 %93 %94 %95 %96
+        %101 = OpAccessChain %_ptr_Function_v4float %output %uint_0
+               OpStore %101 %103
+        %105 = OpLoad %Uniforms %uniforms
+        %107 = OpLoad %15 %mySampler
+        %109 = OpLoad %18 %myTexture
+        %111 = OpLoad %PointLights %pointLights
+        %113 = OpLoad %FragmentOutput %output
+        %112 = OpFunctionCall %void %tint_symbol_8 %113
+               OpReturn
+               OpFunctionEnd
diff --git a/test/bug/tint/1046.wgsl.expected.wgsl b/test/bug/tint/1046.wgsl.expected.wgsl
new file mode 100644
index 0000000..f041af8
--- /dev/null
+++ b/test/bug/tint/1046.wgsl.expected.wgsl
@@ -0,0 +1,69 @@
+struct PointLight {
+  position : vec4<f32>;
+};
+
+[[block]]
+struct PointLights {
+  values : [[stride(16)]] array<PointLight>;
+};
+
+[[block]]
+struct Uniforms {
+  worldView : mat4x4<f32>;
+  proj : mat4x4<f32>;
+  numPointLights : u32;
+  color_source : u32;
+  color : vec4<f32>;
+};
+
+[[binding(0), group(0)]] var<uniform> uniforms : Uniforms;
+
+[[binding(1), group(0)]] var<storage, read> pointLights : PointLights;
+
+[[binding(2), group(0)]] var mySampler : sampler;
+
+[[binding(3), group(0)]] var myTexture : texture_2d<f32>;
+
+struct FragmentInput {
+  [[builtin(position)]]
+  position : vec4<f32>;
+  [[location(0)]]
+  view_position : vec4<f32>;
+  [[location(1)]]
+  normal : vec4<f32>;
+  [[location(2)]]
+  uv : vec2<f32>;
+  [[location(3)]]
+  color : vec4<f32>;
+};
+
+struct FragmentOutput {
+  [[location(0)]]
+  color : vec4<f32>;
+};
+
+fn getColor(fragment : FragmentInput) -> vec4<f32> {
+  var color : vec4<f32>;
+  if ((uniforms.color_source == 0u)) {
+    color = fragment.color;
+  } elseif ((uniforms.color_source == 1u)) {
+    color = fragment.normal;
+    color.a = 1.0;
+  } elseif ((uniforms.color_source == 2u)) {
+    color = uniforms.color;
+  } elseif ((uniforms.color_source == 3u)) {
+    color = textureSample(myTexture, mySampler, fragment.uv);
+  }
+  return color;
+}
+
+[[stage(fragment)]]
+fn main(fragment : FragmentInput) -> FragmentOutput {
+  var output : FragmentOutput;
+  output.color = vec4<f32>(1.0, 0.0, 0.0, 1.0);
+  ignore(uniforms);
+  ignore(mySampler);
+  ignore(myTexture);
+  ignore(pointLights);
+  return output;
+}