Handle OpConstantNull in ssa-rewrite (#3362)

ssa-rewrite fails in `MemPass::GetPtr()` when the SPIR-V code contains
`OpLoad` for the result id of `OpConstantNull` because of the out of
index access for an operand to get the base address. This commit fixes
it.

Fixes #3344
diff --git a/source/opt/mem_pass.cpp b/source/opt/mem_pass.cpp
index 04e2e8a..d23d679 100644
--- a/source/opt/mem_pass.cpp
+++ b/source/opt/mem_pass.cpp
@@ -97,6 +97,11 @@
   Instruction* ptrInst = get_def_use_mgr()->GetDef(*varId);
   Instruction* varInst;
 
+  if (ptrInst->opcode() == SpvOpConstantNull) {
+    *varId = 0;
+    return ptrInst;
+  }
+
   if (ptrInst->opcode() != SpvOpVariable &&
       ptrInst->opcode() != SpvOpFunctionParameter) {
     varInst = ptrInst->GetBaseAddress();
diff --git a/test/opt/local_ssa_elim_test.cpp b/test/opt/local_ssa_elim_test.cpp
index 7afbb4c..d29a554 100644
--- a/test/opt/local_ssa_elim_test.cpp
+++ b/test/opt/local_ssa_elim_test.cpp
@@ -1998,6 +1998,32 @@
   EXPECT_EQ(Pass::Status::Failure, std::get<1>(result));
 }
 
+TEST_F(LocalSSAElimTest, OpConstantNull) {
+  const std::string text = R"(
+OpCapability Addresses
+OpCapability Kernel
+OpCapability Int64
+OpMemoryModel Physical64 OpenCL
+OpEntryPoint Kernel %4 "A"
+OpSource OpenCL_C 200000
+%2 = OpTypeVoid
+%3 = OpTypeFunction %2
+%6 = OpTypeInt 32 0
+%11 = OpTypePointer CrossWorkgroup %6
+%16 = OpConstantNull %11
+%20 = OpConstant %6 269484031
+%4 = OpFunction %2 None %3
+%17 = OpLabel
+%18 = OpLoad %6 %16 Aligned 536870912
+%19 = OpBitwiseXor %6 %18 %20
+OpStore %16 %19 Aligned 536870912
+OpReturn
+OpFunctionEnd
+  )";
+
+  SinglePassRunToBinary<SSARewritePass>(text, false);
+}
+
 // TODO(greg-lunarg): Add tests to verify handling of these cases:
 //
 //    No optimization in the presence of