Fix operand access of composite in upgrade memory model (#3021)

Fixes #2992

* Accessing aggregate subtype used the wrong operand
* Added a test
diff --git a/source/opt/upgrade_memory_model.cpp b/source/opt/upgrade_memory_model.cpp
index f3bee9e..ab25205 100644
--- a/source/opt/upgrade_memory_model.cpp
+++ b/source/opt/upgrade_memory_model.cpp
@@ -429,7 +429,7 @@
     } else {
       assert(spvOpcodeIsComposite(element_inst->opcode()));
       element_inst = context()->get_def_use_mgr()->GetDef(
-          element_inst->GetSingleWordInOperand(1u));
+          element_inst->GetSingleWordInOperand(0u));
     }
   }
 
diff --git a/test/opt/upgrade_memory_model_test.cpp b/test/opt/upgrade_memory_model_test.cpp
index b6b596d..7f64ffd 100644
--- a/test/opt/upgrade_memory_model_test.cpp
+++ b/test/opt/upgrade_memory_model_test.cpp
@@ -2236,4 +2236,37 @@
   SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
 }
 
+TEST_F(UpgradeMemoryModelTest, CoherentStructMemberInArray) {
+  const std::string text = R"(
+; CHECK-NOT: OpMemberDecorate
+; CHECK: [[int:%[a-zA-Z0-9_]+]] = OpTypeInt 32 0
+; CHECK: [[device:%[a-zA-Z0-9_]+]] = OpConstant [[int]] 1
+; CHECK: OpLoad [[int]] {{.*}} MakePointerVisible|NonPrivatePointer
+OpCapability Shader
+OpCapability Linkage
+OpMemoryModel Logical GLSL450
+OpMemberDecorate %inner 1 Coherent
+%void = OpTypeVoid
+%int = OpTypeInt 32 0
+%int_0 = OpConstant %int 0
+%int_1 = OpConstant %int 1
+%int_4 = OpConstant %int 4
+%inner = OpTypeStruct %int %int
+%array = OpTypeArray %inner %int_4
+%struct = OpTypeStruct %array
+%ptr_ssbo_struct = OpTypePointer StorageBuffer %struct
+%ptr_ssbo_int = OpTypePointer StorageBuffer %int
+%ssbo_var = OpVariable %ptr_ssbo_struct StorageBuffer
+%void_fn = OpTypeFunction %void
+%func = OpFunction %void None %void_fn
+%entry = OpLabel
+%gep = OpAccessChain %ptr_ssbo_int %ssbo_var %int_0 %int_0 %int_1
+%ld = OpLoad %int %gep
+OpReturn
+OpFunctionEnd
+)";
+
+  SinglePassRunAndMatch<opt::UpgradeMemoryModel>(text, true);
+}
+
 }  // namespace