diff --git a/source/fuzz/fuzzer_pass_donate_modules.cpp b/source/fuzz/fuzzer_pass_donate_modules.cpp
index b043b7f..bb48303 100644
--- a/source/fuzz/fuzzer_pass_donate_modules.cpp
+++ b/source/fuzz/fuzzer_pass_donate_modules.cpp
@@ -167,336 +167,385 @@
     std::map<uint32_t, uint32_t>* original_id_to_donated_id) {
   // Consider every type/global/constant/undef in the module.
   for (auto& type_or_value : donor_ir_context->module()->types_values()) {
-    // Each such instruction generates a result id, and as part of donation we
-    // need to associate the donor's result id with a new result id.  That new
-    // result id will either be the id of some existing instruction, or a fresh
-    // id.  This variable captures it.
-    uint32_t new_result_id;
+    HandleTypeOrValue(type_or_value, original_id_to_donated_id);
+  }
+}
 
-    // Decide how to handle each kind of instruction on a case-by-case basis.
-    //
-    // Because the donor module is required to be valid, when we encounter a
-    // type comprised of component types (e.g. an aggregate or pointer), we know
-    // that its component types will have been considered previously, and that
-    // |original_id_to_donated_id| will already contain an entry for them.
-    switch (type_or_value.opcode()) {
-      case SpvOpTypeVoid: {
-        // Void has to exist already in order for us to have an entry point.
-        // Get the existing id of void.
-        opt::analysis::Void void_type;
-        new_result_id = GetIRContext()->get_type_mgr()->GetId(&void_type);
-        assert(new_result_id &&
-               "The module being transformed will always have 'void' type "
-               "declared.");
-      } break;
-      case SpvOpTypeBool: {
-        // Bool cannot be declared multiple times, so use its existing id if
-        // present, or add a declaration of Bool with a fresh id if not.
-        opt::analysis::Bool bool_type;
-        auto bool_type_id = GetIRContext()->get_type_mgr()->GetId(&bool_type);
-        if (bool_type_id) {
-          new_result_id = bool_type_id;
-        } else {
-          new_result_id = GetFuzzerContext()->GetFreshId();
-          ApplyTransformation(TransformationAddTypeBoolean(new_result_id));
-        }
-      } break;
-      case SpvOpTypeInt: {
-        // Int cannot be declared multiple times with the same width and
-        // signedness, so check whether an existing identical Int type is
-        // present and use its id if so.  Otherwise add a declaration of the
-        // Int type used by the donor, with a fresh id.
-        const uint32_t width = type_or_value.GetSingleWordInOperand(0);
-        const bool is_signed =
-            static_cast<bool>(type_or_value.GetSingleWordInOperand(1));
-        opt::analysis::Integer int_type(width, is_signed);
-        auto int_type_id = GetIRContext()->get_type_mgr()->GetId(&int_type);
-        if (int_type_id) {
-          new_result_id = int_type_id;
-        } else {
-          new_result_id = GetFuzzerContext()->GetFreshId();
-          ApplyTransformation(
-              TransformationAddTypeInt(new_result_id, width, is_signed));
-        }
-      } break;
-      case SpvOpTypeFloat: {
-        // Similar to SpvOpTypeInt.
-        const uint32_t width = type_or_value.GetSingleWordInOperand(0);
-        opt::analysis::Float float_type(width);
-        auto float_type_id = GetIRContext()->get_type_mgr()->GetId(&float_type);
-        if (float_type_id) {
-          new_result_id = float_type_id;
-        } else {
-          new_result_id = GetFuzzerContext()->GetFreshId();
-          ApplyTransformation(TransformationAddTypeFloat(new_result_id, width));
-        }
-      } break;
-      case SpvOpTypeVector: {
-        // It is not legal to have two Vector type declarations with identical
-        // element types and element counts, so check whether an existing
-        // identical Vector type is present and use its id if so.  Otherwise add
-        // a declaration of the Vector type used by the donor, with a fresh id.
+void FuzzerPassDonateModules::HandleTypeOrValue(
+    const opt::Instruction& type_or_value,
+    std::map<uint32_t, uint32_t>* original_id_to_donated_id) {
+  // The type/value instruction generates a result id, and we need to associate
+  // the donor's result id with a new result id.  That new result id will either
+  // be the id of some existing instruction, or a fresh id.  This variable
+  // captures it.
+  uint32_t new_result_id;
 
-        // When considering the vector's component type id, we look up the id
-        // use in the donor to find the id to which this has been remapped.
-        uint32_t component_type_id = original_id_to_donated_id->at(
-            type_or_value.GetSingleWordInOperand(0));
-        auto component_type =
-            GetIRContext()->get_type_mgr()->GetType(component_type_id);
-        assert(component_type && "The base type should be registered.");
-        auto component_count = type_or_value.GetSingleWordInOperand(1);
-        opt::analysis::Vector vector_type(component_type, component_count);
-        auto vector_type_id =
-            GetIRContext()->get_type_mgr()->GetId(&vector_type);
-        if (vector_type_id) {
-          new_result_id = vector_type_id;
-        } else {
-          new_result_id = GetFuzzerContext()->GetFreshId();
-          ApplyTransformation(TransformationAddTypeVector(
-              new_result_id, component_type_id, component_count));
-        }
-      } break;
-      case SpvOpTypeMatrix: {
-        // Similar to SpvOpTypeVector.
-        uint32_t column_type_id = original_id_to_donated_id->at(
-            type_or_value.GetSingleWordInOperand(0));
-        auto column_type =
-            GetIRContext()->get_type_mgr()->GetType(column_type_id);
-        assert(column_type && column_type->AsVector() &&
-               "The column type should be a registered vector type.");
-        auto column_count = type_or_value.GetSingleWordInOperand(1);
-        opt::analysis::Matrix matrix_type(column_type, column_count);
-        auto matrix_type_id =
-            GetIRContext()->get_type_mgr()->GetId(&matrix_type);
-        if (matrix_type_id) {
-          new_result_id = matrix_type_id;
-        } else {
-          new_result_id = GetFuzzerContext()->GetFreshId();
-          ApplyTransformation(TransformationAddTypeMatrix(
-              new_result_id, column_type_id, column_count));
-        }
-
-      } break;
-      case SpvOpTypeArray: {
-        // It is OK to have multiple structurally identical array types, so
-        // we go ahead and add a remapped version of the type declared by the
-        // donor.
-        uint32_t component_type_id = type_or_value.GetSingleWordInOperand(0);
+  // Decide how to handle each kind of instruction on a case-by-case basis.
+  //
+  // Because the donor module is required to be valid, when we encounter a
+  // type comprised of component types (e.g. an aggregate or pointer), we know
+  // that its component types will have been considered previously, and that
+  // |original_id_to_donated_id| will already contain an entry for them.
+  switch (type_or_value.opcode()) {
+    case SpvOpTypeImage:
+    case SpvOpTypeSampledImage:
+    case SpvOpTypeSampler:
+      // We do not donate types and variables that relate to images and
+      // samplers, so we skip these types and subsequently skip anything that
+      // depends on them.
+      return;
+    case SpvOpTypeVoid: {
+      // Void has to exist already in order for us to have an entry point.
+      // Get the existing id of void.
+      opt::analysis::Void void_type;
+      new_result_id = GetIRContext()->get_type_mgr()->GetId(&void_type);
+      assert(new_result_id &&
+             "The module being transformed will always have 'void' type "
+             "declared.");
+    } break;
+    case SpvOpTypeBool: {
+      // Bool cannot be declared multiple times, so use its existing id if
+      // present, or add a declaration of Bool with a fresh id if not.
+      opt::analysis::Bool bool_type;
+      auto bool_type_id = GetIRContext()->get_type_mgr()->GetId(&bool_type);
+      if (bool_type_id) {
+        new_result_id = bool_type_id;
+      } else {
         new_result_id = GetFuzzerContext()->GetFreshId();
-        ApplyTransformation(TransformationAddTypeArray(
-            new_result_id, original_id_to_donated_id->at(component_type_id),
-            original_id_to_donated_id->at(
-                type_or_value.GetSingleWordInOperand(1))));
-      } break;
-      case SpvOpTypeRuntimeArray: {
-        // A runtime array is allowed as the final member of an SSBO.  During
-        // donation we turn runtime arrays into fixed-size arrays.  For dead
-        // code donations this is OK because the array is never indexed into at
-        // runtime, so it does not matter what its size is.  For live-safe code,
-        // all accesses are made in-bounds, so this is also OK.
-        //
-        // The special OpArrayLength instruction, which works on runtime arrays,
-        // is rewritten to yield the fixed length that is used for the array.
-
-        uint32_t component_type_id = type_or_value.GetSingleWordInOperand(0);
-        new_result_id = GetFuzzerContext()->GetFreshId();
-        ApplyTransformation(TransformationAddTypeArray(
-            new_result_id, original_id_to_donated_id->at(component_type_id),
-            FindOrCreate32BitIntegerConstant(
-                GetFuzzerContext()->GetRandomSizeForNewArray(), false)));
-      } break;
-      case SpvOpTypeStruct: {
-        // Similar to SpvOpTypeArray.
-        std::vector<uint32_t> member_type_ids;
-        for (uint32_t i = 0; i < type_or_value.NumInOperands(); i++) {
-          auto component_type_id = type_or_value.GetSingleWordInOperand(i);
-          member_type_ids.push_back(
-              original_id_to_donated_id->at(component_type_id));
-        }
+        ApplyTransformation(TransformationAddTypeBoolean(new_result_id));
+      }
+    } break;
+    case SpvOpTypeInt: {
+      // Int cannot be declared multiple times with the same width and
+      // signedness, so check whether an existing identical Int type is
+      // present and use its id if so.  Otherwise add a declaration of the
+      // Int type used by the donor, with a fresh id.
+      const uint32_t width = type_or_value.GetSingleWordInOperand(0);
+      const bool is_signed =
+          static_cast<bool>(type_or_value.GetSingleWordInOperand(1));
+      opt::analysis::Integer int_type(width, is_signed);
+      auto int_type_id = GetIRContext()->get_type_mgr()->GetId(&int_type);
+      if (int_type_id) {
+        new_result_id = int_type_id;
+      } else {
         new_result_id = GetFuzzerContext()->GetFreshId();
         ApplyTransformation(
-            TransformationAddTypeStruct(new_result_id, member_type_ids));
-      } break;
-      case SpvOpTypePointer: {
-        // Similar to SpvOpTypeArray.
-        uint32_t pointee_type_id = type_or_value.GetSingleWordInOperand(1);
+            TransformationAddTypeInt(new_result_id, width, is_signed));
+      }
+    } break;
+    case SpvOpTypeFloat: {
+      // Similar to SpvOpTypeInt.
+      const uint32_t width = type_or_value.GetSingleWordInOperand(0);
+      opt::analysis::Float float_type(width);
+      auto float_type_id = GetIRContext()->get_type_mgr()->GetId(&float_type);
+      if (float_type_id) {
+        new_result_id = float_type_id;
+      } else {
         new_result_id = GetFuzzerContext()->GetFreshId();
-        ApplyTransformation(TransformationAddTypePointer(
-            new_result_id,
-            AdaptStorageClass(static_cast<SpvStorageClass>(
-                type_or_value.GetSingleWordInOperand(0))),
-            original_id_to_donated_id->at(pointee_type_id)));
-      } break;
-      case SpvOpTypeFunction: {
-        // It is not OK to have multiple function types that use identical ids
-        // for their return and parameter types.  We thus go through all
-        // existing function types to look for a match.  We do not use the
-        // type manager here because we want to regard two function types that
-        // are structurally identical but that differ with respect to the
-        // actual ids used for pointer types as different.
-        //
-        // Example:
-        //
-        // %1 = OpTypeVoid
-        // %2 = OpTypeInt 32 0
-        // %3 = OpTypePointer Function %2
-        // %4 = OpTypePointer Function %2
-        // %5 = OpTypeFunction %1 %3
-        // %6 = OpTypeFunction %1 %4
-        //
-        // We regard %5 and %6 as distinct function types here, even though
-        // they both have the form "uint32* -> void"
+        ApplyTransformation(TransformationAddTypeFloat(new_result_id, width));
+      }
+    } break;
+    case SpvOpTypeVector: {
+      // It is not legal to have two Vector type declarations with identical
+      // element types and element counts, so check whether an existing
+      // identical Vector type is present and use its id if so.  Otherwise add
+      // a declaration of the Vector type used by the donor, with a fresh id.
 
-        std::vector<uint32_t> return_and_parameter_types;
-        for (uint32_t i = 0; i < type_or_value.NumInOperands(); i++) {
-          uint32_t return_or_parameter_type =
-              type_or_value.GetSingleWordInOperand(i);
-          return_and_parameter_types.push_back(
-              original_id_to_donated_id->at(return_or_parameter_type));
-        }
-        uint32_t existing_function_id = fuzzerutil::FindFunctionType(
-            GetIRContext(), return_and_parameter_types);
-        if (existing_function_id) {
-          new_result_id = existing_function_id;
-        } else {
-          // No match was found, so add a remapped version of the function type
-          // to the module, with a fresh id.
-          new_result_id = GetFuzzerContext()->GetFreshId();
-          std::vector<uint32_t> argument_type_ids;
-          for (uint32_t i = 1; i < type_or_value.NumInOperands(); i++) {
-            argument_type_ids.push_back(original_id_to_donated_id->at(
-                type_or_value.GetSingleWordInOperand(i)));
-          }
-          ApplyTransformation(TransformationAddTypeFunction(
-              new_result_id,
-              original_id_to_donated_id->at(
-                  type_or_value.GetSingleWordInOperand(0)),
-              argument_type_ids));
-        }
-      } break;
-      case SpvOpConstantTrue:
-      case SpvOpConstantFalse: {
-        // It is OK to have duplicate definitions of True and False, so add
-        // these to the module, using a remapped Bool type.
+      // When considering the vector's component type id, we look up the id
+      // use in the donor to find the id to which this has been remapped.
+      uint32_t component_type_id = original_id_to_donated_id->at(
+          type_or_value.GetSingleWordInOperand(0));
+      auto component_type =
+          GetIRContext()->get_type_mgr()->GetType(component_type_id);
+      assert(component_type && "The base type should be registered.");
+      auto component_count = type_or_value.GetSingleWordInOperand(1);
+      opt::analysis::Vector vector_type(component_type, component_count);
+      auto vector_type_id = GetIRContext()->get_type_mgr()->GetId(&vector_type);
+      if (vector_type_id) {
+        new_result_id = vector_type_id;
+      } else {
         new_result_id = GetFuzzerContext()->GetFreshId();
-        ApplyTransformation(TransformationAddConstantBoolean(
-            new_result_id, type_or_value.opcode() == SpvOpConstantTrue));
-      } break;
-      case SpvOpConstant: {
-        // It is OK to have duplicate constant definitions, so add this to the
-        // module using a remapped result type.
+        ApplyTransformation(TransformationAddTypeVector(
+            new_result_id, component_type_id, component_count));
+      }
+    } break;
+    case SpvOpTypeMatrix: {
+      // Similar to SpvOpTypeVector.
+      uint32_t column_type_id = original_id_to_donated_id->at(
+          type_or_value.GetSingleWordInOperand(0));
+      auto column_type =
+          GetIRContext()->get_type_mgr()->GetType(column_type_id);
+      assert(column_type && column_type->AsVector() &&
+             "The column type should be a registered vector type.");
+      auto column_count = type_or_value.GetSingleWordInOperand(1);
+      opt::analysis::Matrix matrix_type(column_type, column_count);
+      auto matrix_type_id = GetIRContext()->get_type_mgr()->GetId(&matrix_type);
+      if (matrix_type_id) {
+        new_result_id = matrix_type_id;
+      } else {
         new_result_id = GetFuzzerContext()->GetFreshId();
-        std::vector<uint32_t> data_words;
-        type_or_value.ForEachInOperand(
-            [&data_words](const uint32_t* in_operand) {
-              data_words.push_back(*in_operand);
-            });
-        ApplyTransformation(TransformationAddConstantScalar(
-            new_result_id,
-            original_id_to_donated_id->at(type_or_value.type_id()),
-            data_words));
-      } break;
-      case SpvOpConstantComposite: {
-        assert(original_id_to_donated_id->count(type_or_value.type_id()) &&
-               "Composite types for which it is possible to create a constant "
-               "should have been donated.");
+        ApplyTransformation(TransformationAddTypeMatrix(
+            new_result_id, column_type_id, column_count));
+      }
 
-        // It is OK to have duplicate constant composite definitions, so add
-        // this to the module using remapped versions of all consituent ids and
-        // the result type.
-        new_result_id = GetFuzzerContext()->GetFreshId();
-        std::vector<uint32_t> constituent_ids;
-        type_or_value.ForEachInId(
-            [&constituent_ids,
-             &original_id_to_donated_id](const uint32_t* constituent_id) {
-              assert(original_id_to_donated_id->count(*constituent_id) &&
-                     "The constants used to construct this composite should "
-                     "have been donated.");
-              constituent_ids.push_back(
-                  original_id_to_donated_id->at(*constituent_id));
-            });
-        ApplyTransformation(TransformationAddConstantComposite(
-            new_result_id,
-            original_id_to_donated_id->at(type_or_value.type_id()),
-            constituent_ids));
-      } break;
-      case SpvOpConstantNull: {
-        // It is fine to have multiple OpConstantNull instructions of the same
-        // type, so we just add this to the recipient module.
-        new_result_id = GetFuzzerContext()->GetFreshId();
-        ApplyTransformation(TransformationAddConstantNull(
-            new_result_id,
-            original_id_to_donated_id->at(type_or_value.type_id())));
-      } break;
-      case SpvOpVariable: {
-        // This is a global variable that could have one of various storage
-        // classes.  However, we change all global variable pointer storage
-        // classes (such as Uniform, Input and Output) to private when donating
-        // pointer types, with the exception of the Workgroup storage class.
-        //
-        // Thus this variable's pointer type is guaranteed to have storage class
-        // Private or Workgroup.
-        //
-        // We add a global variable with either Private or Workgroup storage
-        // class, using remapped versions of the result type and initializer ids
-        // for the global variable in the donor.
-        //
-        // We regard the added variable as having an irrelevant value.  This
-        // means that future passes can add stores to the variable in any
-        // way they wish, and pass them as pointer parameters to functions
-        // without worrying about whether their data might get modified.
-        new_result_id = GetFuzzerContext()->GetFreshId();
-        uint32_t remapped_pointer_type =
-            original_id_to_donated_id->at(type_or_value.type_id());
-        uint32_t initializer_id;
-        SpvStorageClass storage_class =
-            static_cast<SpvStorageClass>(type_or_value.GetSingleWordInOperand(
-                0)) == SpvStorageClassWorkgroup
-                ? SpvStorageClassWorkgroup
-                : SpvStorageClassPrivate;
-        if (type_or_value.NumInOperands() == 1) {
-          // The variable did not have an initializer.  Initialize it to zero
-          // if it has Private storage class (to limit problems associated with
-          // uninitialized data), and leave it uninitialized if it has Workgroup
-          // storage class (as Workgroup variables cannot have initializers).
+    } break;
+    case SpvOpTypeArray: {
+      // It is OK to have multiple structurally identical array types, so
+      // we go ahead and add a remapped version of the type declared by the
+      // donor.
+      uint32_t component_type_id = type_or_value.GetSingleWordInOperand(0);
+      if (!original_id_to_donated_id->count(component_type_id)) {
+        // We did not donate the component type of this array type, so we
+        // cannot donate the array type.
+        return;
+      }
+      new_result_id = GetFuzzerContext()->GetFreshId();
+      ApplyTransformation(TransformationAddTypeArray(
+          new_result_id, original_id_to_donated_id->at(component_type_id),
+          original_id_to_donated_id->at(
+              type_or_value.GetSingleWordInOperand(1))));
+    } break;
+    case SpvOpTypeRuntimeArray: {
+      // A runtime array is allowed as the final member of an SSBO.  During
+      // donation we turn runtime arrays into fixed-size arrays.  For dead
+      // code donations this is OK because the array is never indexed into at
+      // runtime, so it does not matter what its size is.  For live-safe code,
+      // all accesses are made in-bounds, so this is also OK.
+      //
+      // The special OpArrayLength instruction, which works on runtime arrays,
+      // is rewritten to yield the fixed length that is used for the array.
 
-          // TODO(https://github.com/KhronosGroup/SPIRV-Tools/issues/3275): we
-          //  could initialize Workgroup variables at the start of an entry
-          //  point, and should do so if their uninitialized nature proves
-          //  problematic.
-          initializer_id =
-              storage_class == SpvStorageClassWorkgroup
-                  ? 0
-                  : FindOrCreateZeroConstant(
-                        fuzzerutil::GetPointeeTypeIdFromPointerType(
-                            GetIRContext(), remapped_pointer_type));
-        } else {
-          // The variable already had an initializer; use its remapped id.
-          initializer_id = original_id_to_donated_id->at(
-              type_or_value.GetSingleWordInOperand(1));
+      uint32_t component_type_id = type_or_value.GetSingleWordInOperand(0);
+      if (!original_id_to_donated_id->count(component_type_id)) {
+        // We did not donate the component type of this runtime array type, so
+        // we cannot donate it as a fixed-size array.
+        return;
+      }
+      new_result_id = GetFuzzerContext()->GetFreshId();
+      ApplyTransformation(TransformationAddTypeArray(
+          new_result_id, original_id_to_donated_id->at(component_type_id),
+          FindOrCreate32BitIntegerConstant(
+              GetFuzzerContext()->GetRandomSizeForNewArray(), false)));
+    } break;
+    case SpvOpTypeStruct: {
+      // Similar to SpvOpTypeArray.
+      std::vector<uint32_t> member_type_ids;
+      for (uint32_t i = 0; i < type_or_value.NumInOperands(); i++) {
+        auto component_type_id = type_or_value.GetSingleWordInOperand(i);
+        if (!original_id_to_donated_id->count(component_type_id)) {
+          // We did not donate every member type for this struct type, so we
+          // cannot donate the struct type.
+          return;
         }
-        ApplyTransformation(TransformationAddGlobalVariable(
-            new_result_id, remapped_pointer_type, storage_class, initializer_id,
-            true));
-      } break;
-      case SpvOpUndef: {
-        // It is fine to have multiple Undef instructions of the same type, so
-        // we just add this to the recipient module.
+        member_type_ids.push_back(
+            original_id_to_donated_id->at(component_type_id));
+      }
+      new_result_id = GetFuzzerContext()->GetFreshId();
+      ApplyTransformation(
+          TransformationAddTypeStruct(new_result_id, member_type_ids));
+    } break;
+    case SpvOpTypePointer: {
+      // Similar to SpvOpTypeArray.
+      uint32_t pointee_type_id = type_or_value.GetSingleWordInOperand(1);
+      if (!original_id_to_donated_id->count(pointee_type_id)) {
+        // We did not donate the pointee type for this pointer type, so we
+        // cannot donate the pointer type.
+        return;
+      }
+      new_result_id = GetFuzzerContext()->GetFreshId();
+      ApplyTransformation(TransformationAddTypePointer(
+          new_result_id,
+          AdaptStorageClass(static_cast<SpvStorageClass>(
+              type_or_value.GetSingleWordInOperand(0))),
+          original_id_to_donated_id->at(pointee_type_id)));
+    } break;
+    case SpvOpTypeFunction: {
+      // It is not OK to have multiple function types that use identical ids
+      // for their return and parameter types.  We thus go through all
+      // existing function types to look for a match.  We do not use the
+      // type manager here because we want to regard two function types that
+      // are structurally identical but that differ with respect to the
+      // actual ids used for pointer types as different.
+      //
+      // Example:
+      //
+      // %1 = OpTypeVoid
+      // %2 = OpTypeInt 32 0
+      // %3 = OpTypePointer Function %2
+      // %4 = OpTypePointer Function %2
+      // %5 = OpTypeFunction %1 %3
+      // %6 = OpTypeFunction %1 %4
+      //
+      // We regard %5 and %6 as distinct function types here, even though
+      // they both have the form "uint32* -> void"
+
+      std::vector<uint32_t> return_and_parameter_types;
+      for (uint32_t i = 0; i < type_or_value.NumInOperands(); i++) {
+        uint32_t return_or_parameter_type =
+            type_or_value.GetSingleWordInOperand(i);
+        if (!original_id_to_donated_id->count(return_or_parameter_type)) {
+          // We did not donate every return/parameter type for this function
+          // type, so we cannot donate the function type.
+          return;
+        }
+        return_and_parameter_types.push_back(
+            original_id_to_donated_id->at(return_or_parameter_type));
+      }
+      uint32_t existing_function_id = fuzzerutil::FindFunctionType(
+          GetIRContext(), return_and_parameter_types);
+      if (existing_function_id) {
+        new_result_id = existing_function_id;
+      } else {
+        // No match was found, so add a remapped version of the function type
+        // to the module, with a fresh id.
         new_result_id = GetFuzzerContext()->GetFreshId();
-        ApplyTransformation(TransformationAddGlobalUndef(
+        std::vector<uint32_t> argument_type_ids;
+        for (uint32_t i = 1; i < type_or_value.NumInOperands(); i++) {
+          argument_type_ids.push_back(original_id_to_donated_id->at(
+              type_or_value.GetSingleWordInOperand(i)));
+        }
+        ApplyTransformation(TransformationAddTypeFunction(
             new_result_id,
-            original_id_to_donated_id->at(type_or_value.type_id())));
-      } break;
-      default: {
-        assert(0 && "Unknown type/value.");
-        new_result_id = 0;
-      } break;
-    }
-    // Update the id mapping to associate the instruction's result id with its
-    // corresponding id in the recipient.
-    original_id_to_donated_id->insert(
-        {type_or_value.result_id(), new_result_id});
+            original_id_to_donated_id->at(
+                type_or_value.GetSingleWordInOperand(0)),
+            argument_type_ids));
+      }
+    } break;
+    case SpvOpConstantTrue:
+    case SpvOpConstantFalse: {
+      // It is OK to have duplicate definitions of True and False, so add
+      // these to the module, using a remapped Bool type.
+      new_result_id = GetFuzzerContext()->GetFreshId();
+      ApplyTransformation(TransformationAddConstantBoolean(
+          new_result_id, type_or_value.opcode() == SpvOpConstantTrue));
+    } break;
+    case SpvOpConstant: {
+      // It is OK to have duplicate constant definitions, so add this to the
+      // module using a remapped result type.
+      new_result_id = GetFuzzerContext()->GetFreshId();
+      std::vector<uint32_t> data_words;
+      type_or_value.ForEachInOperand([&data_words](const uint32_t* in_operand) {
+        data_words.push_back(*in_operand);
+      });
+      ApplyTransformation(TransformationAddConstantScalar(
+          new_result_id, original_id_to_donated_id->at(type_or_value.type_id()),
+          data_words));
+    } break;
+    case SpvOpConstantComposite: {
+      assert(original_id_to_donated_id->count(type_or_value.type_id()) &&
+             "Composite types for which it is possible to create a constant "
+             "should have been donated.");
+
+      // It is OK to have duplicate constant composite definitions, so add
+      // this to the module using remapped versions of all consituent ids and
+      // the result type.
+      new_result_id = GetFuzzerContext()->GetFreshId();
+      std::vector<uint32_t> constituent_ids;
+      type_or_value.ForEachInId([&constituent_ids, &original_id_to_donated_id](
+                                    const uint32_t* constituent_id) {
+        assert(original_id_to_donated_id->count(*constituent_id) &&
+               "The constants used to construct this composite should "
+               "have been donated.");
+        constituent_ids.push_back(
+            original_id_to_donated_id->at(*constituent_id));
+      });
+      ApplyTransformation(TransformationAddConstantComposite(
+          new_result_id, original_id_to_donated_id->at(type_or_value.type_id()),
+          constituent_ids));
+    } break;
+    case SpvOpConstantNull: {
+      if (!original_id_to_donated_id->count(type_or_value.type_id())) {
+        // We did not donate the type associated with this null constant, so
+        // we cannot donate the null constant.
+        return;
+      }
+
+      // It is fine to have multiple OpConstantNull instructions of the same
+      // type, so we just add this to the recipient module.
+      new_result_id = GetFuzzerContext()->GetFreshId();
+      ApplyTransformation(TransformationAddConstantNull(
+          new_result_id,
+          original_id_to_donated_id->at(type_or_value.type_id())));
+    } break;
+    case SpvOpVariable: {
+      if (!original_id_to_donated_id->count(type_or_value.type_id())) {
+        // We did not donate the pointer type associated with this variable,
+        // so we cannot donate the variable.
+        return;
+      }
+
+      // This is a global variable that could have one of various storage
+      // classes.  However, we change all global variable pointer storage
+      // classes (such as Uniform, Input and Output) to private when donating
+      // pointer types, with the exception of the Workgroup storage class.
+      //
+      // Thus this variable's pointer type is guaranteed to have storage class
+      // Private or Workgroup.
+      //
+      // We add a global variable with either Private or Workgroup storage
+      // class, using remapped versions of the result type and initializer ids
+      // for the global variable in the donor.
+      //
+      // We regard the added variable as having an irrelevant value.  This
+      // means that future passes can add stores to the variable in any
+      // way they wish, and pass them as pointer parameters to functions
+      // without worrying about whether their data might get modified.
+      new_result_id = GetFuzzerContext()->GetFreshId();
+      uint32_t remapped_pointer_type =
+          original_id_to_donated_id->at(type_or_value.type_id());
+      uint32_t initializer_id;
+      SpvStorageClass storage_class =
+          static_cast<SpvStorageClass>(type_or_value.GetSingleWordInOperand(
+              0)) == SpvStorageClassWorkgroup
+              ? SpvStorageClassWorkgroup
+              : SpvStorageClassPrivate;
+      if (type_or_value.NumInOperands() == 1) {
+        // The variable did not have an initializer.  Initialize it to zero
+        // if it has Private storage class (to limit problems associated with
+        // uninitialized data), and leave it uninitialized if it has Workgroup
+        // storage class (as Workgroup variables cannot have initializers).
+
+        // TODO(https://github.com/KhronosGroup/SPIRV-Tools/issues/3275): we
+        //  could initialize Workgroup variables at the start of an entry
+        //  point, and should do so if their uninitialized nature proves
+        //  problematic.
+        initializer_id = storage_class == SpvStorageClassWorkgroup
+                             ? 0
+                             : FindOrCreateZeroConstant(
+                                   fuzzerutil::GetPointeeTypeIdFromPointerType(
+                                       GetIRContext(), remapped_pointer_type));
+      } else {
+        // The variable already had an initializer; use its remapped id.
+        initializer_id = original_id_to_donated_id->at(
+            type_or_value.GetSingleWordInOperand(1));
+      }
+      ApplyTransformation(
+          TransformationAddGlobalVariable(new_result_id, remapped_pointer_type,
+                                          storage_class, initializer_id, true));
+    } break;
+    case SpvOpUndef: {
+      if (!original_id_to_donated_id->count(type_or_value.type_id())) {
+        // We did not donate the type associated with this undef, so we cannot
+        // donate the undef.
+        return;
+      }
+
+      // It is fine to have multiple Undef instructions of the same type, so
+      // we just add this to the recipient module.
+      new_result_id = GetFuzzerContext()->GetFreshId();
+      ApplyTransformation(TransformationAddGlobalUndef(
+          new_result_id,
+          original_id_to_donated_id->at(type_or_value.type_id())));
+    } break;
+    default: {
+      assert(0 && "Unknown type/value.");
+      new_result_id = 0;
+    } break;
   }
+
+  // Update the id mapping to associate the instruction's result id with its
+  // corresponding id in the recipient.
+  original_id_to_donated_id->insert({type_or_value.result_id(), new_result_id});
 }
 
 void FuzzerPassDonateModules::HandleFunctions(
@@ -525,314 +574,49 @@
     }
     assert(function_to_donate && "Function to be donated was not found.");
 
+    if (!original_id_to_donated_id->count(
+            function_to_donate->DefInst().GetSingleWordInOperand(1))) {
+      // We were not able to donate this function's type, so we cannot donate
+      // the function.
+      continue;
+    }
+
     // We will collect up protobuf messages representing the donor function's
     // instructions here, and use them to create an AddFunction transformation.
     std::vector<protobufs::Instruction> donated_instructions;
 
-    // Scan through the function, remapping each result id that it generates to
-    // a fresh id.  This is necessary because functions include forward
-    // references, e.g. to labels.
-    function_to_donate->ForEachInst([this, donor_ir_context,
-                                     &original_id_to_donated_id](
-                                        const opt::Instruction* instruction) {
-      if (!instruction->result_id()) {
-        return;
-      }
-      if (IgnoreInstruction(instruction)) {
-        if (instruction->opcode() == SpvOpArrayLength) {
-          // We treat the OpArrayLength instruction specially.  In the donor
-          // shader this gets the length of a runtime array that is the final
-          // member of a struct.  During donation, we will have converted the
-          // runtime array type, and the associated struct field, into a fixed-
-          // size array.  We can then use the constant size of this fixed-sized
-          // array wherever we would have used the result of an OpArrayLength
-          // instruction.
-          uint32_t donated_variable_id = original_id_to_donated_id->at(
-              instruction->GetSingleWordInOperand(0));
-          auto donated_variable_instruction =
-              GetIRContext()->get_def_use_mgr()->GetDef(donated_variable_id);
-          auto pointer_to_struct_instruction =
-              GetIRContext()->get_def_use_mgr()->GetDef(
-                  donated_variable_instruction->type_id());
-          assert(pointer_to_struct_instruction->opcode() == SpvOpTypePointer &&
-                 "Type of variable must be pointer.");
-          auto donated_struct_type_instruction =
-              GetIRContext()->get_def_use_mgr()->GetDef(
-                  pointer_to_struct_instruction->GetSingleWordInOperand(1));
-          assert(
-              donated_struct_type_instruction->opcode() == SpvOpTypeStruct &&
-              "Pointee type of pointer used by OpArrayLength must be struct.");
-          assert(donated_struct_type_instruction->NumInOperands() ==
-                     instruction->GetSingleWordInOperand(1) + 1 &&
-                 "OpArrayLength must refer to the final member of the given "
-                 "struct.");
-          uint32_t fixed_size_array_type_id =
-              donated_struct_type_instruction->GetSingleWordInOperand(
-                  donated_struct_type_instruction->NumInOperands() - 1);
-          auto fixed_size_array_type_instruction =
-              GetIRContext()->get_def_use_mgr()->GetDef(
-                  fixed_size_array_type_id);
-          assert(fixed_size_array_type_instruction->opcode() ==
-                     SpvOpTypeArray &&
-                 "The donated array type must be fixed-size.");
-          auto array_size_id =
-              fixed_size_array_type_instruction->GetSingleWordInOperand(1);
-          original_id_to_donated_id->insert(
-              {instruction->result_id(), array_size_id});
-        } else if (instruction->type_id()) {
-          // If the ignored instruction has a basic result type then we
-          // associate its result id with a constant of that type, so that
-          // instructions that use the result id will use the constant instead.
-          // TODO(https://github.com/KhronosGroup/SPIRV-Tools/issues/3177):
-          //  Using this particular constant is arbitrary, so if we have a
-          //  mechanism for noting that an id use is arbitrary and could be
-          //  fuzzed we should use it here.
-          auto type_inst = donor_ir_context->get_def_use_mgr()->GetDef(
-              instruction->type_id());
-          switch (type_inst->opcode()) {
-            case SpvOpTypeArray:
-            case SpvOpTypeBool:
-            case SpvOpTypeFloat:
-            case SpvOpTypeInt:
-            case SpvOpTypeStruct:
-            case SpvOpTypeVector:
-            case SpvOpTypeMatrix:
-              original_id_to_donated_id->insert(
-                  {instruction->result_id(),
-                   FindOrCreateZeroConstant(
-                       original_id_to_donated_id->at(instruction->type_id()))});
-            default:
-              break;
-          }
-        }
-      } else {
-        original_id_to_donated_id->insert(
-            {instruction->result_id(), GetFuzzerContext()->GetFreshId()});
-      }
-    });
+    // This set tracks the ids of those instructions for which donation was
+    // completely skipped: neither the instruction nor a substitute for it was
+    // donated.
+    std::set<uint32_t> skipped_instructions;
 
     // Consider every instruction of the donor function.
-    function_to_donate->ForEachInst([this, &donated_instructions,
-                                     &original_id_to_donated_id](
-                                        const opt::Instruction* instruction) {
-      if (IgnoreInstruction(instruction)) {
-        return;
-      }
-
-      // Get the instruction's input operands into donation-ready form,
-      // remapping any id uses in the process.
-      opt::Instruction::OperandList input_operands;
-
-      // Consider each input operand in turn.
-      for (uint32_t in_operand_index = 0;
-           in_operand_index < instruction->NumInOperands();
-           in_operand_index++) {
-        std::vector<uint32_t> operand_data;
-        const opt::Operand& in_operand =
-            instruction->GetInOperand(in_operand_index);
-        switch (in_operand.type) {
-          case SPV_OPERAND_TYPE_ID:
-          case SPV_OPERAND_TYPE_TYPE_ID:
-          case SPV_OPERAND_TYPE_RESULT_ID:
-          case SPV_OPERAND_TYPE_MEMORY_SEMANTICS_ID:
-          case SPV_OPERAND_TYPE_SCOPE_ID:
-            // This is an id operand - it consists of a single word of data,
-            // which needs to be remapped so that it is replaced with the
-            // donated form of the id.
-            operand_data.push_back(
-                original_id_to_donated_id->at(in_operand.words[0]));
-            break;
-          default:
-            // For non-id operands, we just add each of the data words.
-            for (auto word : in_operand.words) {
-              operand_data.push_back(word);
-            }
-            break;
-        }
-        input_operands.push_back({in_operand.type, operand_data});
-      }
-
-      if (instruction->opcode() == SpvOpVariable &&
-          instruction->NumInOperands() == 1) {
-        // This is an uninitialized local variable.  Initialize it to zero.
-        input_operands.push_back(
-            {SPV_OPERAND_TYPE_ID,
-             {FindOrCreateZeroConstant(
-                 fuzzerutil::GetPointeeTypeIdFromPointerType(
-                     GetIRContext(),
-                     original_id_to_donated_id->at(instruction->type_id())))}});
-      }
-
-      // Remap the result type and result id (if present) of the
-      // instruction, and turn it into a protobuf message.
-      donated_instructions.push_back(MakeInstructionMessage(
-          instruction->opcode(),
-          instruction->type_id()
-              ? original_id_to_donated_id->at(instruction->type_id())
-              : 0,
-          instruction->result_id()
-              ? original_id_to_donated_id->at(instruction->result_id())
-              : 0,
-          input_operands));
-    });
+    function_to_donate->ForEachInst(
+        [this, &donated_instructions, donor_ir_context,
+         &original_id_to_donated_id,
+         &skipped_instructions](const opt::Instruction* instruction) {
+          if (instruction->opcode() == SpvOpArrayLength) {
+            // We treat OpArrayLength specially.
+            HandleOpArrayLength(*instruction, original_id_to_donated_id,
+                                &donated_instructions);
+          } else if (!CanDonateInstruction(donor_ir_context, *instruction,
+                                           *original_id_to_donated_id,
+                                           skipped_instructions)) {
+            // This is an instruction that we cannot directly donate.
+            HandleDifficultInstruction(*instruction, original_id_to_donated_id,
+                                       &donated_instructions,
+                                       &skipped_instructions);
+          } else {
+            PrepareInstructionForDonation(*instruction, donor_ir_context,
+                                          original_id_to_donated_id,
+                                          &donated_instructions);
+          }
+        });
 
     if (make_livesafe) {
-      // Various types and constants must be in place for a function to be made
-      // live-safe.  Add them if not already present.
-      FindOrCreateBoolType();  // Needed for comparisons
-      FindOrCreatePointerTo32BitIntegerType(
-          false, SpvStorageClassFunction);  // Needed for adding loop limiters
-      FindOrCreate32BitIntegerConstant(
-          0, false);  // Needed for initializing loop limiters
-      FindOrCreate32BitIntegerConstant(
-          1, false);  // Needed for incrementing loop limiters
-
-      // Get a fresh id for the variable that will be used as a loop limiter.
-      const uint32_t loop_limiter_variable_id =
-          GetFuzzerContext()->GetFreshId();
-      // Choose a random loop limit, and add the required constant to the
-      // module if not already there.
-      const uint32_t loop_limit = FindOrCreate32BitIntegerConstant(
-          GetFuzzerContext()->GetRandomLoopLimit(), false);
-
-      // Consider every loop header in the function to donate, and create a
-      // structure capturing the ids to be used for manipulating the loop
-      // limiter each time the loop is iterated.
-      std::vector<protobufs::LoopLimiterInfo> loop_limiters;
-      for (auto& block : *function_to_donate) {
-        if (block.IsLoopHeader()) {
-          protobufs::LoopLimiterInfo loop_limiter;
-          // Grab the loop header's id, mapped to its donated value.
-          loop_limiter.set_loop_header_id(
-              original_id_to_donated_id->at(block.id()));
-          // Get fresh ids that will be used to load the loop limiter, increment
-          // it, compare it with the loop limit, and an id for a new block that
-          // will contain the loop's original terminator.
-          loop_limiter.set_load_id(GetFuzzerContext()->GetFreshId());
-          loop_limiter.set_increment_id(GetFuzzerContext()->GetFreshId());
-          loop_limiter.set_compare_id(GetFuzzerContext()->GetFreshId());
-          loop_limiter.set_logical_op_id(GetFuzzerContext()->GetFreshId());
-          loop_limiters.emplace_back(loop_limiter);
-        }
-      }
-
-      // Consider every access chain in the function to donate, and create a
-      // structure containing the ids necessary to clamp the access chain
-      // indices to be in-bounds.
-      std::vector<protobufs::AccessChainClampingInfo>
-          access_chain_clamping_info;
-      for (auto& block : *function_to_donate) {
-        for (auto& inst : block) {
-          switch (inst.opcode()) {
-            case SpvOpAccessChain:
-            case SpvOpInBoundsAccessChain: {
-              protobufs::AccessChainClampingInfo clamping_info;
-              clamping_info.set_access_chain_id(
-                  original_id_to_donated_id->at(inst.result_id()));
-
-              auto base_object = donor_ir_context->get_def_use_mgr()->GetDef(
-                  inst.GetSingleWordInOperand(0));
-              assert(base_object && "The base object must exist.");
-              auto pointer_type = donor_ir_context->get_def_use_mgr()->GetDef(
-                  base_object->type_id());
-              assert(pointer_type &&
-                     pointer_type->opcode() == SpvOpTypePointer &&
-                     "The base object must have pointer type.");
-
-              auto should_be_composite_type =
-                  donor_ir_context->get_def_use_mgr()->GetDef(
-                      pointer_type->GetSingleWordInOperand(1));
-
-              // Walk the access chain, creating fresh ids to facilitate
-              // clamping each index.  For simplicity we do this for every
-              // index, even though constant indices will not end up being
-              // clamped.
-              for (uint32_t index = 1; index < inst.NumInOperands(); index++) {
-                auto compare_and_select_ids =
-                    clamping_info.add_compare_and_select_ids();
-                compare_and_select_ids->set_first(
-                    GetFuzzerContext()->GetFreshId());
-                compare_and_select_ids->set_second(
-                    GetFuzzerContext()->GetFreshId());
-
-                // Get the bound for the component being indexed into.
-                uint32_t bound;
-                if (should_be_composite_type->opcode() ==
-                    SpvOpTypeRuntimeArray) {
-                  // The donor is indexing into a runtime array.  We do not
-                  // donate runtime arrays.  Instead, we donate a corresponding
-                  // fixed-size array for every runtime array.  We should thus
-                  // find that donor composite type's result id maps to a fixed-
-                  // size array.
-                  auto fixed_size_array_type =
-                      GetIRContext()->get_def_use_mgr()->GetDef(
-                          original_id_to_donated_id->at(
-                              should_be_composite_type->result_id()));
-                  assert(fixed_size_array_type->opcode() == SpvOpTypeArray &&
-                         "A runtime array type in the donor should have been "
-                         "replaced by a fixed-sized array in the recipient.");
-                  // The size of this fixed-size array is a suitable bound.
-                  bound = TransformationAddFunction::GetBoundForCompositeIndex(
-                      GetIRContext(), *fixed_size_array_type);
-                } else {
-                  bound = TransformationAddFunction::GetBoundForCompositeIndex(
-                      donor_ir_context, *should_be_composite_type);
-                }
-                const uint32_t index_id = inst.GetSingleWordInOperand(index);
-                auto index_inst =
-                    donor_ir_context->get_def_use_mgr()->GetDef(index_id);
-                auto index_type_inst =
-                    donor_ir_context->get_def_use_mgr()->GetDef(
-                        index_inst->type_id());
-                assert(index_type_inst->opcode() == SpvOpTypeInt);
-                assert(index_type_inst->GetSingleWordInOperand(0) == 32);
-                opt::analysis::Integer* index_int_type =
-                    donor_ir_context->get_type_mgr()
-                        ->GetType(index_type_inst->result_id())
-                        ->AsInteger();
-                if (index_inst->opcode() != SpvOpConstant) {
-                  // We will have to clamp this index, so we need a constant
-                  // whose value is one less than the bound, to compare
-                  // against and to use as the clamped value.
-                  FindOrCreate32BitIntegerConstant(bound - 1,
-                                                   index_int_type->IsSigned());
-                }
-                should_be_composite_type =
-                    TransformationAddFunction::FollowCompositeIndex(
-                        donor_ir_context, *should_be_composite_type, index_id);
-              }
-              access_chain_clamping_info.push_back(clamping_info);
-              break;
-            }
-            default:
-              break;
-          }
-        }
-      }
-
-      // If the function contains OpKill or OpUnreachable instructions, and has
-      // non-void return type, then we need a value %v to use in order to turn
-      // these into instructions of the form OpReturn %v.
-      uint32_t kill_unreachable_return_value_id;
-      auto function_return_type_inst =
-          donor_ir_context->get_def_use_mgr()->GetDef(
-              function_to_donate->type_id());
-      if (function_return_type_inst->opcode() == SpvOpTypeVoid) {
-        // The return type is void, so we don't need a return value.
-        kill_unreachable_return_value_id = 0;
-      } else {
-        // We do need a return value; we use zero.
-        assert(function_return_type_inst->opcode() != SpvOpTypePointer &&
-               "Function return type must not be a pointer.");
-        kill_unreachable_return_value_id =
-            FindOrCreateZeroConstant(original_id_to_donated_id->at(
-                function_return_type_inst->result_id()));
-      }
-      // Add the function in a livesafe manner.
-      ApplyTransformation(TransformationAddFunction(
-          donated_instructions, loop_limiter_variable_id, loop_limit,
-          loop_limiters, kill_unreachable_return_value_id,
-          access_chain_clamping_info));
+      // Make the function livesafe and then add it.
+      AddLivesafeFunction(*function_to_donate, donor_ir_context,
+                          *original_id_to_donated_id, donated_instructions);
     } else {
       // Add the function in a non-livesafe manner.
       ApplyTransformation(TransformationAddFunction(donated_instructions));
@@ -840,12 +624,20 @@
   }
 }
 
-bool FuzzerPassDonateModules::IgnoreInstruction(
-    const opt::Instruction* instruction) {
-  switch (instruction->opcode()) {
-    case SpvOpArrayLength:
-      // We ignore instructions that get the length of runtime arrays, because
-      // we turn all runtime arrays into fixed-size arrays.
+bool FuzzerPassDonateModules::CanDonateInstruction(
+    opt::IRContext* donor_ir_context, const opt::Instruction& instruction,
+    const std::map<uint32_t, uint32_t>& original_id_to_donated_id,
+    const std::set<uint32_t>& skipped_instructions) const {
+  if (instruction.type_id() &&
+      !original_id_to_donated_id.count(instruction.type_id())) {
+    // We could not donate the result type of this instruction, so we cannot
+    // donate the instruction.
+    return false;
+  }
+
+  // Now consider instructions we specifically want to skip because we do not
+  // yet support them.
+  switch (instruction.opcode()) {
     case SpvOpAtomicLoad:
     case SpvOpAtomicStore:
     case SpvOpAtomicExchange:
@@ -865,6 +657,93 @@
       // We conservatively ignore all atomic instructions at present.
       // TODO(https://github.com/KhronosGroup/SPIRV-Tools/issues/3276): Consider
       //  being less conservative here.
+    case SpvOpImageSampleImplicitLod:
+    case SpvOpImageSampleExplicitLod:
+    case SpvOpImageSampleDrefImplicitLod:
+    case SpvOpImageSampleDrefExplicitLod:
+    case SpvOpImageSampleProjImplicitLod:
+    case SpvOpImageSampleProjExplicitLod:
+    case SpvOpImageSampleProjDrefImplicitLod:
+    case SpvOpImageSampleProjDrefExplicitLod:
+    case SpvOpImageFetch:
+    case SpvOpImageGather:
+    case SpvOpImageDrefGather:
+    case SpvOpImageRead:
+    case SpvOpImageWrite:
+    case SpvOpImageSparseSampleImplicitLod:
+    case SpvOpImageSparseSampleExplicitLod:
+    case SpvOpImageSparseSampleDrefImplicitLod:
+    case SpvOpImageSparseSampleDrefExplicitLod:
+    case SpvOpImageSparseSampleProjImplicitLod:
+    case SpvOpImageSparseSampleProjExplicitLod:
+    case SpvOpImageSparseSampleProjDrefImplicitLod:
+    case SpvOpImageSparseSampleProjDrefExplicitLod:
+    case SpvOpImageSparseFetch:
+    case SpvOpImageSparseGather:
+    case SpvOpImageSparseDrefGather:
+    case SpvOpImageSparseRead:
+    case SpvOpImageSampleFootprintNV:
+    case SpvOpImage:
+    case SpvOpImageQueryFormat:
+    case SpvOpImageQueryLevels:
+    case SpvOpImageQueryLod:
+    case SpvOpImageQueryOrder:
+    case SpvOpImageQuerySamples:
+    case SpvOpImageQuerySize:
+    case SpvOpImageQuerySizeLod:
+    case SpvOpSampledImage:
+      // We ignore all instructions related to accessing images, since we do not
+      // donate images.
+      return false;
+    case SpvOpLoad:
+      switch (donor_ir_context->get_def_use_mgr()
+                  ->GetDef(instruction.type_id())
+                  ->opcode()) {
+        case SpvOpTypeImage:
+        case SpvOpTypeSampledImage:
+        case SpvOpTypeSampler:
+          // Again, we ignore instructions that relate to accessing images.
+          return false;
+        default:
+          break;
+      }
+    default:
+      break;
+  }
+
+  // Examine each id input operand to the instruction.  If it turns out that we
+  // have skipped any of these operands then we cannot donate the instruction.
+  bool result = true;
+  instruction.WhileEachInId(
+      [donor_ir_context, &original_id_to_donated_id, &result,
+       &skipped_instructions](const uint32_t* in_id) -> bool {
+        if (!original_id_to_donated_id.count(*in_id)) {
+          // We do not have a mapped result id for this id operand.  That either
+          // means that it is a forward reference (which is OK), that we skipped
+          // the instruction that generated it (which is not OK), or that it is
+          // the id of a function that we did not donate (which is not OK).  We
+          // check for the latter two cases.
+          if (skipped_instructions.count(*in_id) ||
+              donor_ir_context->get_def_use_mgr()->GetDef(*in_id)->opcode() ==
+                  SpvOpFunction) {
+            result = false;
+            return false;
+          }
+        }
+        return true;
+      });
+  return result;
+}
+
+bool FuzzerPassDonateModules::IsBasicType(
+    const opt::Instruction& instruction) const {
+  switch (instruction.opcode()) {
+    case SpvOpTypeArray:
+    case SpvOpTypeFloat:
+    case SpvOpTypeInt:
+    case SpvOpTypeMatrix:
+    case SpvOpTypeStruct:
+    case SpvOpTypeVector:
       return true;
     default:
       return false;
@@ -917,5 +796,333 @@
   return result;
 }
 
+void FuzzerPassDonateModules::HandleOpArrayLength(
+    const opt::Instruction& instruction,
+    std::map<uint32_t, uint32_t>* original_id_to_donated_id,
+    std::vector<protobufs::Instruction>* donated_instructions) const {
+  assert(instruction.opcode() == SpvOpArrayLength &&
+         "Precondition: instruction must be OpArrayLength.");
+  uint32_t donated_variable_id =
+      original_id_to_donated_id->at(instruction.GetSingleWordInOperand(0));
+  auto donated_variable_instruction =
+      GetIRContext()->get_def_use_mgr()->GetDef(donated_variable_id);
+  auto pointer_to_struct_instruction =
+      GetIRContext()->get_def_use_mgr()->GetDef(
+          donated_variable_instruction->type_id());
+  assert(pointer_to_struct_instruction->opcode() == SpvOpTypePointer &&
+         "Type of variable must be pointer.");
+  auto donated_struct_type_instruction =
+      GetIRContext()->get_def_use_mgr()->GetDef(
+          pointer_to_struct_instruction->GetSingleWordInOperand(1));
+  assert(donated_struct_type_instruction->opcode() == SpvOpTypeStruct &&
+         "Pointee type of pointer used by OpArrayLength must be struct.");
+  assert(donated_struct_type_instruction->NumInOperands() ==
+             instruction.GetSingleWordInOperand(1) + 1 &&
+         "OpArrayLength must refer to the final member of the given "
+         "struct.");
+  uint32_t fixed_size_array_type_id =
+      donated_struct_type_instruction->GetSingleWordInOperand(
+          donated_struct_type_instruction->NumInOperands() - 1);
+  auto fixed_size_array_type_instruction =
+      GetIRContext()->get_def_use_mgr()->GetDef(fixed_size_array_type_id);
+  assert(fixed_size_array_type_instruction->opcode() == SpvOpTypeArray &&
+         "The donated array type must be fixed-size.");
+  auto array_size_id =
+      fixed_size_array_type_instruction->GetSingleWordInOperand(1);
+
+  if (instruction.result_id() &&
+      !original_id_to_donated_id->count(instruction.result_id())) {
+    original_id_to_donated_id->insert(
+        {instruction.result_id(), GetFuzzerContext()->GetFreshId()});
+  }
+
+  donated_instructions->push_back(MakeInstructionMessage(
+      SpvOpCopyObject, original_id_to_donated_id->at(instruction.type_id()),
+      original_id_to_donated_id->at(instruction.result_id()),
+      opt::Instruction::OperandList({{SPV_OPERAND_TYPE_ID, {array_size_id}}})));
+}
+
+void FuzzerPassDonateModules::HandleDifficultInstruction(
+    const opt::Instruction& instruction,
+    std::map<uint32_t, uint32_t>* original_id_to_donated_id,
+    std::vector<protobufs::Instruction>* donated_instructions,
+    std::set<uint32_t>* skipped_instructions) {
+  if (!instruction.result_id()) {
+    // It does not generate a result id, so it can be ignored.
+    return;
+  }
+  if (!original_id_to_donated_id->count(instruction.type_id())) {
+    // We cannot handle this instruction's result type, so we need to skip it
+    // all together.
+    skipped_instructions->insert(instruction.result_id());
+    return;
+  }
+
+  // We now attempt to replace the instruction with an OpCopyObject.
+  // TODO(https://github.com/KhronosGroup/SPIRV-Tools/issues/3278): We could do
+  //  something more refined here - we could check which operands to the
+  //  instruction could not be donated and replace those operands with
+  //  references to other ids (such as constants), so that we still get an
+  //  instruction with the opcode and easy-to-handle operands of the donor
+  //  instruction.
+  auto remapped_type_id = original_id_to_donated_id->at(instruction.type_id());
+  if (!IsBasicType(
+          *GetIRContext()->get_def_use_mgr()->GetDef(remapped_type_id))) {
+    // The instruction has a non-basic result type, so we cannot replace it with
+    // an object copy of a constant.  We thus skip it completely.
+    // TODO(https://github.com/KhronosGroup/SPIRV-Tools/issues/3279): We could
+    //  instead look for an available id of the right type and generate an
+    //  OpCopyObject of that id.
+    skipped_instructions->insert(instruction.result_id());
+    return;
+  }
+
+  // We are going to add an OpCopyObject instruction.  Add a mapping for the
+  // result id of the original instruction if does not already exist (it may
+  // exist in the case that it has been forward-referenced).
+  if (!original_id_to_donated_id->count(instruction.result_id())) {
+    original_id_to_donated_id->insert(
+        {instruction.result_id(), GetFuzzerContext()->GetFreshId()});
+  }
+
+  // We find or add a zero constant to the receiving module for the type in
+  // question, and add an OpCopyObject instruction that copies this zero.
+  // TODO(https://github.com/KhronosGroup/SPIRV-Tools/issues/3177):
+  //  Using this particular constant is arbitrary, so if we have a
+  //  mechanism for noting that an id use is arbitrary and could be
+  //  fuzzed we should use it here.
+  auto zero_constant = FindOrCreateZeroConstant(remapped_type_id);
+  donated_instructions->push_back(MakeInstructionMessage(
+      SpvOpCopyObject, remapped_type_id,
+      original_id_to_donated_id->at(instruction.result_id()),
+      opt::Instruction::OperandList({{SPV_OPERAND_TYPE_ID, {zero_constant}}})));
+}
+
+void FuzzerPassDonateModules::PrepareInstructionForDonation(
+    const opt::Instruction& instruction, opt::IRContext* donor_ir_context,
+    std::map<uint32_t, uint32_t>* original_id_to_donated_id,
+    std::vector<protobufs::Instruction>* donated_instructions) {
+  // Get the instruction's input operands into donation-ready form,
+  // remapping any id uses in the process.
+  opt::Instruction::OperandList input_operands;
+
+  // Consider each input operand in turn.
+  for (uint32_t in_operand_index = 0;
+       in_operand_index < instruction.NumInOperands(); in_operand_index++) {
+    std::vector<uint32_t> operand_data;
+    const opt::Operand& in_operand = instruction.GetInOperand(in_operand_index);
+    // Check whether this operand is an id.
+    if (spvIsIdType(in_operand.type)) {
+      // This is an id operand - it consists of a single word of data,
+      // which needs to be remapped so that it is replaced with the
+      // donated form of the id.
+      auto operand_id = in_operand.words[0];
+      if (!original_id_to_donated_id->count(operand_id)) {
+        // This is a forward reference.  We will choose a corresponding
+        // donor id for the referenced id and update the mapping to
+        // reflect it.
+
+        // Keep release compilers happy because |donor_ir_context| is only used
+        // in this assertion.
+        (void)(donor_ir_context);
+        assert((donor_ir_context->get_def_use_mgr()
+                        ->GetDef(operand_id)
+                        ->opcode() == SpvOpLabel ||
+                instruction.opcode() == SpvOpPhi) &&
+               "Unsupported forward reference.");
+        original_id_to_donated_id->insert(
+            {operand_id, GetFuzzerContext()->GetFreshId()});
+      }
+      operand_data.push_back(original_id_to_donated_id->at(operand_id));
+    } else {
+      // For non-id operands, we just add each of the data words.
+      for (auto word : in_operand.words) {
+        operand_data.push_back(word);
+      }
+    }
+    input_operands.push_back({in_operand.type, operand_data});
+  }
+
+  if (instruction.opcode() == SpvOpVariable &&
+      instruction.NumInOperands() == 1) {
+    // This is an uninitialized local variable.  Initialize it to zero.
+    input_operands.push_back(
+        {SPV_OPERAND_TYPE_ID,
+         {FindOrCreateZeroConstant(fuzzerutil::GetPointeeTypeIdFromPointerType(
+             GetIRContext(),
+             original_id_to_donated_id->at(instruction.type_id())))}});
+  }
+
+  if (instruction.result_id() &&
+      !original_id_to_donated_id->count(instruction.result_id())) {
+    original_id_to_donated_id->insert(
+        {instruction.result_id(), GetFuzzerContext()->GetFreshId()});
+  }
+
+  // Remap the result type and result id (if present) of the
+  // instruction, and turn it into a protobuf message.
+  donated_instructions->push_back(MakeInstructionMessage(
+      instruction.opcode(),
+      instruction.type_id()
+          ? original_id_to_donated_id->at(instruction.type_id())
+          : 0,
+      instruction.result_id()
+          ? original_id_to_donated_id->at(instruction.result_id())
+          : 0,
+      input_operands));
+}
+
+void FuzzerPassDonateModules::AddLivesafeFunction(
+    const opt::Function& function_to_donate, opt::IRContext* donor_ir_context,
+    const std::map<uint32_t, uint32_t>& original_id_to_donated_id,
+    const std::vector<protobufs::Instruction>& donated_instructions) {
+  // Various types and constants must be in place for a function to be made
+  // live-safe.  Add them if not already present.
+  FindOrCreateBoolType();  // Needed for comparisons
+  FindOrCreatePointerTo32BitIntegerType(
+      false, SpvStorageClassFunction);  // Needed for adding loop limiters
+  FindOrCreate32BitIntegerConstant(
+      0, false);  // Needed for initializing loop limiters
+  FindOrCreate32BitIntegerConstant(
+      1, false);  // Needed for incrementing loop limiters
+
+  // Get a fresh id for the variable that will be used as a loop limiter.
+  const uint32_t loop_limiter_variable_id = GetFuzzerContext()->GetFreshId();
+  // Choose a random loop limit, and add the required constant to the
+  // module if not already there.
+  const uint32_t loop_limit = FindOrCreate32BitIntegerConstant(
+      GetFuzzerContext()->GetRandomLoopLimit(), false);
+
+  // Consider every loop header in the function to donate, and create a
+  // structure capturing the ids to be used for manipulating the loop
+  // limiter each time the loop is iterated.
+  std::vector<protobufs::LoopLimiterInfo> loop_limiters;
+  for (auto& block : function_to_donate) {
+    if (block.IsLoopHeader()) {
+      protobufs::LoopLimiterInfo loop_limiter;
+      // Grab the loop header's id, mapped to its donated value.
+      loop_limiter.set_loop_header_id(original_id_to_donated_id.at(block.id()));
+      // Get fresh ids that will be used to load the loop limiter, increment
+      // it, compare it with the loop limit, and an id for a new block that
+      // will contain the loop's original terminator.
+      loop_limiter.set_load_id(GetFuzzerContext()->GetFreshId());
+      loop_limiter.set_increment_id(GetFuzzerContext()->GetFreshId());
+      loop_limiter.set_compare_id(GetFuzzerContext()->GetFreshId());
+      loop_limiter.set_logical_op_id(GetFuzzerContext()->GetFreshId());
+      loop_limiters.emplace_back(loop_limiter);
+    }
+  }
+
+  // Consider every access chain in the function to donate, and create a
+  // structure containing the ids necessary to clamp the access chain
+  // indices to be in-bounds.
+  std::vector<protobufs::AccessChainClampingInfo> access_chain_clamping_info;
+  for (auto& block : function_to_donate) {
+    for (auto& inst : block) {
+      switch (inst.opcode()) {
+        case SpvOpAccessChain:
+        case SpvOpInBoundsAccessChain: {
+          protobufs::AccessChainClampingInfo clamping_info;
+          clamping_info.set_access_chain_id(
+              original_id_to_donated_id.at(inst.result_id()));
+
+          auto base_object = donor_ir_context->get_def_use_mgr()->GetDef(
+              inst.GetSingleWordInOperand(0));
+          assert(base_object && "The base object must exist.");
+          auto pointer_type = donor_ir_context->get_def_use_mgr()->GetDef(
+              base_object->type_id());
+          assert(pointer_type && pointer_type->opcode() == SpvOpTypePointer &&
+                 "The base object must have pointer type.");
+
+          auto should_be_composite_type =
+              donor_ir_context->get_def_use_mgr()->GetDef(
+                  pointer_type->GetSingleWordInOperand(1));
+
+          // Walk the access chain, creating fresh ids to facilitate
+          // clamping each index.  For simplicity we do this for every
+          // index, even though constant indices will not end up being
+          // clamped.
+          for (uint32_t index = 1; index < inst.NumInOperands(); index++) {
+            auto compare_and_select_ids =
+                clamping_info.add_compare_and_select_ids();
+            compare_and_select_ids->set_first(GetFuzzerContext()->GetFreshId());
+            compare_and_select_ids->set_second(
+                GetFuzzerContext()->GetFreshId());
+
+            // Get the bound for the component being indexed into.
+            uint32_t bound;
+            if (should_be_composite_type->opcode() == SpvOpTypeRuntimeArray) {
+              // The donor is indexing into a runtime array.  We do not
+              // donate runtime arrays.  Instead, we donate a corresponding
+              // fixed-size array for every runtime array.  We should thus
+              // find that donor composite type's result id maps to a fixed-
+              // size array.
+              auto fixed_size_array_type =
+                  GetIRContext()->get_def_use_mgr()->GetDef(
+                      original_id_to_donated_id.at(
+                          should_be_composite_type->result_id()));
+              assert(fixed_size_array_type->opcode() == SpvOpTypeArray &&
+                     "A runtime array type in the donor should have been "
+                     "replaced by a fixed-sized array in the recipient.");
+              // The size of this fixed-size array is a suitable bound.
+              bound = TransformationAddFunction::GetBoundForCompositeIndex(
+                  GetIRContext(), *fixed_size_array_type);
+            } else {
+              bound = TransformationAddFunction::GetBoundForCompositeIndex(
+                  donor_ir_context, *should_be_composite_type);
+            }
+            const uint32_t index_id = inst.GetSingleWordInOperand(index);
+            auto index_inst =
+                donor_ir_context->get_def_use_mgr()->GetDef(index_id);
+            auto index_type_inst = donor_ir_context->get_def_use_mgr()->GetDef(
+                index_inst->type_id());
+            assert(index_type_inst->opcode() == SpvOpTypeInt);
+            assert(index_type_inst->GetSingleWordInOperand(0) == 32);
+            opt::analysis::Integer* index_int_type =
+                donor_ir_context->get_type_mgr()
+                    ->GetType(index_type_inst->result_id())
+                    ->AsInteger();
+            if (index_inst->opcode() != SpvOpConstant) {
+              // We will have to clamp this index, so we need a constant
+              // whose value is one less than the bound, to compare
+              // against and to use as the clamped value.
+              FindOrCreate32BitIntegerConstant(bound - 1,
+                                               index_int_type->IsSigned());
+            }
+            should_be_composite_type =
+                TransformationAddFunction::FollowCompositeIndex(
+                    donor_ir_context, *should_be_composite_type, index_id);
+          }
+          access_chain_clamping_info.push_back(clamping_info);
+          break;
+        }
+        default:
+          break;
+      }
+    }
+  }
+
+  // If the function contains OpKill or OpUnreachable instructions, and has
+  // non-void return type, then we need a value %v to use in order to turn
+  // these into instructions of the form OpReturn %v.
+  uint32_t kill_unreachable_return_value_id;
+  auto function_return_type_inst =
+      donor_ir_context->get_def_use_mgr()->GetDef(function_to_donate.type_id());
+  if (function_return_type_inst->opcode() == SpvOpTypeVoid) {
+    // The return type is void, so we don't need a return value.
+    kill_unreachable_return_value_id = 0;
+  } else {
+    // We do need a return value; we use zero.
+    assert(function_return_type_inst->opcode() != SpvOpTypePointer &&
+           "Function return type must not be a pointer.");
+    kill_unreachable_return_value_id = FindOrCreateZeroConstant(
+        original_id_to_donated_id.at(function_return_type_inst->result_id()));
+  }
+  // Add the function in a livesafe manner.
+  ApplyTransformation(TransformationAddFunction(
+      donated_instructions, loop_limiter_variable_id, loop_limit, loop_limiters,
+      kill_unreachable_return_value_id, access_chain_clamping_info));
+}
+
 }  // namespace fuzz
 }  // namespace spvtools
diff --git a/source/fuzz/fuzzer_pass_donate_modules.h b/source/fuzz/fuzzer_pass_donate_modules.h
index 909f3bc..e61572c 100644
--- a/source/fuzz/fuzzer_pass_donate_modules.h
+++ b/source/fuzz/fuzzer_pass_donate_modules.h
@@ -66,6 +66,11 @@
       opt::IRContext* donor_ir_context,
       std::map<uint32_t, uint32_t>* original_id_to_donated_id);
 
+  // TODO comment
+  void HandleTypeOrValue(
+      const opt::Instruction& type_or_value,
+      std::map<uint32_t, uint32_t>* original_id_to_donated_id);
+
   // Assumes that |donor_ir_context| does not exhibit recursion.  Considers the
   // functions in |donor_ir_context|'s call graph in a reverse-topologically-
   // sorted order (leaves-to-root), adding each function to the recipient
@@ -80,8 +85,64 @@
   // During donation we will have to ignore some instructions, e.g. because they
   // use opcodes that we cannot support or because they reference the ids of
   // instructions that have not been donated.  This function encapsulates the
-  // logic for deciding which instructions should be ignored.
-  bool IgnoreInstruction(const opt::Instruction* instruction);
+  // logic for deciding which whether instruction |instruction| from
+  // |donor_ir_context| can be donated.
+  bool CanDonateInstruction(
+      opt::IRContext* donor_ir_context, const opt::Instruction& instruction,
+      const std::map<uint32_t, uint32_t>& original_id_to_donated_id,
+      const std::set<uint32_t>& skipped_instructions) const;
+
+  // We treat the OpArrayLength instruction specially.  In the donor shader this
+  // instruction yields the length of a runtime array that is the final member
+  // of a struct.  During donation, we will have converted the runtime array
+  // type, and the associated struct field, into a fixed-size array.
+  //
+  // Instead of donating this instruction, we turn it into an OpCopyObject
+  // instruction that copies the size of the fixed-size array.
+  void HandleOpArrayLength(
+      const opt::Instruction& instruction,
+      std::map<uint32_t, uint32_t>* original_id_to_donated_id,
+      std::vector<protobufs::Instruction>* donated_instructions) const;
+
+  // The instruction |instruction| is required to be an instruction that cannot
+  // be easily donated, either because it uses an unsupported opcode, has an
+  // unsupported result type, or uses id operands that could not be donated.
+  //
+  // If |instruction| generates a result id, the function attempts to add a
+  // substitute for |instruction| to |donated_instructions| that has the correct
+  // result type.  If this cannot be done, the instruction's result id is added
+  // to |skipped_instructions|.  The mapping from donor ids to recipient ids is
+  // managed by |original_id_to_donated_id|.
+  void HandleDifficultInstruction(
+      const opt::Instruction& instruction,
+      std::map<uint32_t, uint32_t>* original_id_to_donated_id,
+      std::vector<protobufs::Instruction>* donated_instructions,
+      std::set<uint32_t>* skipped_instructions);
+
+  // Adds an instruction based in |instruction| to |donated_instructions| in a
+  // form ready for donation.  The original instruction comes from
+  // |donor_ir_context|, and |original_id_to_donated_id| maps ids from
+  // |donor_ir_context| to corresponding ids in the recipient module.
+  void PrepareInstructionForDonation(
+      const opt::Instruction& instruction, opt::IRContext* donor_ir_context,
+      std::map<uint32_t, uint32_t>* original_id_to_donated_id,
+      std::vector<protobufs::Instruction>* donated_instructions);
+
+  // Requires that |donated_instructions| represents a prepared version of the
+  // instructions of |function_to_donate| (which comes from |donor_ir_context|)
+  // ready for donation, and |original_id_to_donated_id| maps ids from
+  // |donor_ir_context| to their corresponding ids in the recipient module.
+  //
+  // Adds a livesafe version of the function, based on |donated_instructions|,
+  // to the recipient module.
+  void AddLivesafeFunction(
+      const opt::Function& function_to_donate, opt::IRContext* donor_ir_context,
+      const std::map<uint32_t, uint32_t>& original_id_to_donated_id,
+      const std::vector<protobufs::Instruction>& donated_instructions);
+
+  // Returns true if and only if |instruction| is a scalar, vector, matrix,
+  // array or struct; i.e. it is not an opaque type.
+  bool IsBasicType(const opt::Instruction& instruction) const;
 
   // Returns the ids of all functions in |context| in a topological order in
   // relation to the call graph of |context|, which is assumed to be recursion-
diff --git a/test/fuzz/fuzzer_pass_donate_modules_test.cpp b/test/fuzz/fuzzer_pass_donate_modules_test.cpp
index bbc92b9..432ca4f 100644
--- a/test/fuzz/fuzzer_pass_donate_modules_test.cpp
+++ b/test/fuzz/fuzzer_pass_donate_modules_test.cpp
@@ -496,7 +496,8 @@
   TransformationContext transformation_context(&fact_manager,
                                                validator_options);
 
-  FuzzerContext fuzzer_context(MakeUnique<PseudoRandomGenerator>(0).get(), 100);
+  PseudoRandomGenerator prng(0);
+  FuzzerContext fuzzer_context(&prng, 100);
   protobufs::TransformationSequence transformation_sequence;
 
   FuzzerPassDonateModules fuzzer_pass(recipient_context.get(),
@@ -577,6 +578,486 @@
   ASSERT_TRUE(IsValid(env, recipient_context.get()));
 }
 
+TEST(FuzzerPassDonateModulesTest, DonateCodeThatUsesImages) {
+  std::string recipient_shader = R"(
+               OpCapability Shader
+               OpCapability ImageQuery
+          %1 = OpExtInstImport "GLSL.std.450"
+               OpMemoryModel Logical GLSL450
+               OpEntryPoint Fragment %4 "main"
+               OpExecutionMode %4 OriginUpperLeft
+               OpSource ESSL 320
+               OpSourceExtension "GL_EXT_samplerless_texture_functions"
+          %2 = OpTypeVoid
+          %3 = OpTypeFunction %2
+          %4 = OpFunction %2 None %3
+          %5 = OpLabel
+               OpReturn
+               OpFunctionEnd
+  )";
+
+  std::string donor_shader = R"(
+               OpCapability Shader
+               OpCapability ImageQuery
+          %1 = OpExtInstImport "GLSL.std.450"
+               OpMemoryModel Logical GLSL450
+               OpEntryPoint Fragment %4 "main"
+               OpExecutionMode %4 OriginUpperLeft
+               OpSource ESSL 320
+               OpSourceExtension "GL_EXT_samplerless_texture_functions"
+               OpName %4 "main"
+               OpName %10 "mySampler"
+               OpName %21 "myTexture"
+               OpName %33 "v"
+               OpDecorate %10 RelaxedPrecision
+               OpDecorate %10 DescriptorSet 0
+               OpDecorate %10 Binding 0
+               OpDecorate %11 RelaxedPrecision
+               OpDecorate %21 RelaxedPrecision
+               OpDecorate %21 DescriptorSet 0
+               OpDecorate %21 Binding 1
+               OpDecorate %22 RelaxedPrecision
+               OpDecorate %34 RelaxedPrecision
+               OpDecorate %40 RelaxedPrecision
+               OpDecorate %42 RelaxedPrecision
+               OpDecorate %43 RelaxedPrecision
+          %2 = OpTypeVoid
+          %3 = OpTypeFunction %2
+          %6 = OpTypeFloat 32
+          %7 = OpTypeImage %6 2D 0 0 0 1 Unknown
+          %8 = OpTypeSampledImage %7
+          %9 = OpTypePointer UniformConstant %8
+         %10 = OpVariable %9 UniformConstant
+         %12 = OpTypeInt 32 1
+         %13 = OpConstant %12 2
+         %15 = OpTypeVector %12 2
+         %17 = OpTypeInt 32 0
+         %18 = OpConstant %17 0
+         %20 = OpTypePointer UniformConstant %7
+         %21 = OpVariable %20 UniformConstant
+         %23 = OpConstant %12 1
+         %25 = OpConstant %17 1
+         %27 = OpTypeBool
+         %31 = OpTypeVector %6 4
+         %32 = OpTypePointer Function %31
+         %35 = OpConstantComposite %15 %23 %23
+         %36 = OpConstant %12 3
+         %37 = OpConstant %12 4
+         %38 = OpConstantComposite %15 %36 %37
+          %4 = OpFunction %2 None %3
+          %5 = OpLabel
+         %33 = OpVariable %32 Function
+         %11 = OpLoad %8 %10
+         %14 = OpImage %7 %11
+         %16 = OpImageQuerySizeLod %15 %14 %13
+         %19 = OpCompositeExtract %12 %16 0
+         %22 = OpLoad %7 %21
+         %24 = OpImageQuerySizeLod %15 %22 %23
+         %26 = OpCompositeExtract %12 %24 1
+         %28 = OpSGreaterThan %27 %19 %26
+               OpSelectionMerge %30 None
+               OpBranchConditional %28 %29 %41
+         %29 = OpLabel
+         %34 = OpLoad %8 %10
+         %39 = OpImage %7 %34
+         %40 = OpImageFetch %31 %39 %35 Lod|ConstOffset %13 %38
+               OpStore %33 %40
+               OpBranch %30
+         %41 = OpLabel
+         %42 = OpLoad %7 %21
+         %43 = OpImageFetch %31 %42 %35 Lod|ConstOffset %13 %38
+               OpStore %33 %43
+               OpBranch %30
+         %30 = OpLabel
+               OpReturn
+               OpFunctionEnd
+  )";
+
+  const auto env = SPV_ENV_UNIVERSAL_1_3;
+  const auto consumer = nullptr;
+  const auto recipient_context =
+      BuildModule(env, consumer, recipient_shader, kFuzzAssembleOption);
+  ASSERT_TRUE(IsValid(env, recipient_context.get()));
+
+  const auto donor_context =
+      BuildModule(env, consumer, donor_shader, kFuzzAssembleOption);
+  ASSERT_TRUE(IsValid(env, donor_context.get()));
+
+  FactManager fact_manager;
+  spvtools::ValidatorOptions validator_options;
+  TransformationContext transformation_context(&fact_manager,
+                                               validator_options);
+
+  PseudoRandomGenerator prng(0);
+  FuzzerContext fuzzer_context(&prng, 100);
+  protobufs::TransformationSequence transformation_sequence;
+
+  FuzzerPassDonateModules fuzzer_pass(recipient_context.get(),
+                                      &transformation_context, &fuzzer_context,
+                                      &transformation_sequence, {});
+
+  fuzzer_pass.DonateSingleModule(donor_context.get(), false);
+
+  // We just check that the result is valid.  Checking to what it should be
+  // exactly equal to would be very fragile.
+  ASSERT_TRUE(IsValid(env, recipient_context.get()));
+}
+
+TEST(FuzzerPassDonateModulesTest, DonateCodeThatUsesSampler) {
+  std::string recipient_shader = R"(
+               OpCapability Shader
+               OpCapability ImageQuery
+          %1 = OpExtInstImport "GLSL.std.450"
+               OpMemoryModel Logical GLSL450
+               OpEntryPoint Fragment %4 "main"
+               OpExecutionMode %4 OriginUpperLeft
+               OpSource ESSL 320
+               OpSourceExtension "GL_EXT_samplerless_texture_functions"
+          %2 = OpTypeVoid
+          %3 = OpTypeFunction %2
+          %4 = OpFunction %2 None %3
+          %5 = OpLabel
+               OpReturn
+               OpFunctionEnd
+  )";
+
+  std::string donor_shader = R"(
+               OpCapability Shader
+               OpCapability ImageQuery
+          %1 = OpExtInstImport "GLSL.std.450"
+               OpMemoryModel Logical GLSL450
+               OpEntryPoint Fragment %4 "main"
+               OpExecutionMode %4 OriginUpperLeft
+               OpSource ESSL 320
+               OpDecorate %16 DescriptorSet 0
+               OpDecorate %16 Binding 0
+               OpDecorate %12 DescriptorSet 0
+               OpDecorate %12 Binding 64
+          %2 = OpTypeVoid
+          %3 = OpTypeFunction %2
+         %23 = OpTypeFloat 32
+          %6 = OpTypeImage %23 2D 2 0 0 1 Unknown
+         %47 = OpTypePointer UniformConstant %6
+         %12 = OpVariable %47 UniformConstant
+         %15 = OpTypeSampler
+         %55 = OpTypePointer UniformConstant %15
+         %17 = OpTypeSampledImage %6
+         %16 = OpVariable %55 UniformConstant
+         %37 = OpTypeVector %23 4
+        %109 = OpConstant %23 0
+         %66 = OpConstantComposite %37 %109 %109 %109 %109
+         %56 = OpTypeBool
+         %54 = OpConstantTrue %56
+          %4 = OpFunction %2 None %3
+          %5 = OpLabel
+               OpBranch %50
+         %50 = OpLabel
+         %51 = OpPhi %37 %66 %5 %111 %53
+               OpLoopMerge %52 %53 None
+               OpBranchConditional %54 %53 %52
+         %53 = OpLabel
+        %106 = OpLoad %6 %12
+        %107 = OpLoad %15 %16
+        %110 = OpSampledImage %17 %106 %107
+        %111 = OpImageSampleImplicitLod %37 %110 %66 Bias %109
+               OpBranch %50
+         %52 = OpLabel
+               OpReturn
+               OpFunctionEnd
+  )";
+
+  const auto env = SPV_ENV_UNIVERSAL_1_3;
+  const auto consumer = nullptr;
+  const auto recipient_context =
+      BuildModule(env, consumer, recipient_shader, kFuzzAssembleOption);
+  ASSERT_TRUE(IsValid(env, recipient_context.get()));
+
+  const auto donor_context =
+      BuildModule(env, consumer, donor_shader, kFuzzAssembleOption);
+  ASSERT_TRUE(IsValid(env, donor_context.get()));
+
+  FactManager fact_manager;
+  spvtools::ValidatorOptions validator_options;
+  TransformationContext transformation_context(&fact_manager,
+                                               validator_options);
+
+  PseudoRandomGenerator prng(0);
+  FuzzerContext fuzzer_context(&prng, 100);
+  protobufs::TransformationSequence transformation_sequence;
+
+  FuzzerPassDonateModules fuzzer_pass(recipient_context.get(),
+                                      &transformation_context, &fuzzer_context,
+                                      &transformation_sequence, {});
+
+  fuzzer_pass.DonateSingleModule(donor_context.get(), false);
+
+  // We just check that the result is valid.  Checking to what it should be
+  // exactly equal to would be very fragile.
+  ASSERT_TRUE(IsValid(env, recipient_context.get()));
+}
+
+TEST(FuzzerPassDonateModulesTest, DonateCodeThatUsesImageStructField) {
+  std::string recipient_shader = R"(
+               OpCapability Shader
+               OpCapability ImageQuery
+          %1 = OpExtInstImport "GLSL.std.450"
+               OpMemoryModel Logical GLSL450
+               OpEntryPoint Fragment %4 "main"
+               OpExecutionMode %4 OriginUpperLeft
+               OpSource ESSL 320
+               OpSourceExtension "GL_EXT_samplerless_texture_functions"
+          %2 = OpTypeVoid
+          %3 = OpTypeFunction %2
+          %4 = OpFunction %2 None %3
+          %5 = OpLabel
+               OpReturn
+               OpFunctionEnd
+  )";
+
+  std::string donor_shader = R"(
+               OpCapability Shader
+               OpCapability ImageQuery
+          %1 = OpExtInstImport "GLSL.std.450"
+               OpMemoryModel Logical GLSL450
+               OpEntryPoint Fragment %4 "main"
+               OpExecutionMode %4 OriginUpperLeft
+               OpSource ESSL 320
+               OpSourceExtension "GL_EXT_samplerless_texture_functions"
+               OpName %4 "main"
+               OpName %10 "mySampler"
+               OpName %21 "myTexture"
+               OpName %33 "v"
+               OpDecorate %10 RelaxedPrecision
+               OpDecorate %10 DescriptorSet 0
+               OpDecorate %10 Binding 0
+               OpDecorate %11 RelaxedPrecision
+               OpDecorate %21 RelaxedPrecision
+               OpDecorate %21 DescriptorSet 0
+               OpDecorate %21 Binding 1
+               OpDecorate %22 RelaxedPrecision
+               OpDecorate %34 RelaxedPrecision
+               OpDecorate %40 RelaxedPrecision
+               OpDecorate %42 RelaxedPrecision
+               OpDecorate %43 RelaxedPrecision
+          %2 = OpTypeVoid
+          %3 = OpTypeFunction %2
+          %6 = OpTypeFloat 32
+          %7 = OpTypeImage %6 2D 0 0 0 1 Unknown
+          %8 = OpTypeSampledImage %7
+          %9 = OpTypePointer UniformConstant %8
+         %10 = OpVariable %9 UniformConstant
+         %12 = OpTypeInt 32 1
+         %13 = OpConstant %12 2
+         %15 = OpTypeVector %12 2
+         %17 = OpTypeInt 32 0
+         %18 = OpConstant %17 0
+         %20 = OpTypePointer UniformConstant %7
+         %21 = OpVariable %20 UniformConstant
+         %23 = OpConstant %12 1
+         %25 = OpConstant %17 1
+         %27 = OpTypeBool
+         %31 = OpTypeVector %6 4
+         %32 = OpTypePointer Function %31
+         %35 = OpConstantComposite %15 %23 %23
+         %36 = OpConstant %12 3
+         %37 = OpConstant %12 4
+         %38 = OpConstantComposite %15 %36 %37
+        %201 = OpTypeStruct %7 %7
+          %4 = OpFunction %2 None %3
+          %5 = OpLabel
+         %33 = OpVariable %32 Function
+         %11 = OpLoad %8 %10
+         %14 = OpImage %7 %11
+         %22 = OpLoad %7 %21
+        %200 = OpCompositeConstruct %201 %14 %22
+        %202 = OpCompositeExtract %7 %200 0
+        %203 = OpCompositeExtract %7 %200 1
+         %24 = OpImageQuerySizeLod %15 %203 %23
+         %16 = OpImageQuerySizeLod %15 %202 %13
+         %26 = OpCompositeExtract %12 %24 1
+         %19 = OpCompositeExtract %12 %16 0
+         %28 = OpSGreaterThan %27 %19 %26
+               OpSelectionMerge %30 None
+               OpBranchConditional %28 %29 %41
+         %29 = OpLabel
+         %34 = OpLoad %8 %10
+         %39 = OpImage %7 %34
+         %40 = OpImageFetch %31 %39 %35 Lod|ConstOffset %13 %38
+               OpStore %33 %40
+               OpBranch %30
+         %41 = OpLabel
+         %42 = OpLoad %7 %21
+         %43 = OpImageFetch %31 %42 %35 Lod|ConstOffset %13 %38
+               OpStore %33 %43
+               OpBranch %30
+         %30 = OpLabel
+               OpReturn
+               OpFunctionEnd
+  )";
+
+  const auto env = SPV_ENV_UNIVERSAL_1_3;
+  const auto consumer = nullptr;
+  const auto recipient_context =
+      BuildModule(env, consumer, recipient_shader, kFuzzAssembleOption);
+  ASSERT_TRUE(IsValid(env, recipient_context.get()));
+
+  const auto donor_context =
+      BuildModule(env, consumer, donor_shader, kFuzzAssembleOption);
+  ASSERT_TRUE(IsValid(env, donor_context.get()));
+
+  FactManager fact_manager;
+  spvtools::ValidatorOptions validator_options;
+  TransformationContext transformation_context(&fact_manager,
+                                               validator_options);
+
+  PseudoRandomGenerator prng(0);
+  FuzzerContext fuzzer_context(&prng, 100);
+  protobufs::TransformationSequence transformation_sequence;
+
+  FuzzerPassDonateModules fuzzer_pass(recipient_context.get(),
+                                      &transformation_context, &fuzzer_context,
+                                      &transformation_sequence, {});
+
+  fuzzer_pass.DonateSingleModule(donor_context.get(), false);
+
+  // We just check that the result is valid.  Checking to what it should be
+  // exactly equal to would be very fragile.
+  ASSERT_TRUE(IsValid(env, recipient_context.get()));
+}
+
+TEST(FuzzerPassDonateModulesTest, DonateCodeThatUsesImageFunctionParameter) {
+  std::string recipient_shader = R"(
+               OpCapability Shader
+               OpCapability ImageQuery
+          %1 = OpExtInstImport "GLSL.std.450"
+               OpMemoryModel Logical GLSL450
+               OpEntryPoint Fragment %4 "main"
+               OpExecutionMode %4 OriginUpperLeft
+               OpSource ESSL 320
+               OpSourceExtension "GL_EXT_samplerless_texture_functions"
+          %2 = OpTypeVoid
+          %3 = OpTypeFunction %2
+          %4 = OpFunction %2 None %3
+          %5 = OpLabel
+               OpReturn
+               OpFunctionEnd
+  )";
+
+  std::string donor_shader = R"(
+               OpCapability Shader
+               OpCapability ImageQuery
+          %1 = OpExtInstImport "GLSL.std.450"
+               OpMemoryModel Logical GLSL450
+               OpEntryPoint Fragment %4 "main"
+               OpExecutionMode %4 OriginUpperLeft
+               OpSource ESSL 320
+               OpSourceExtension "GL_EXT_samplerless_texture_functions"
+               OpName %4 "main"
+               OpName %10 "mySampler"
+               OpName %21 "myTexture"
+               OpName %33 "v"
+               OpDecorate %10 RelaxedPrecision
+               OpDecorate %10 DescriptorSet 0
+               OpDecorate %10 Binding 0
+               OpDecorate %11 RelaxedPrecision
+               OpDecorate %21 RelaxedPrecision
+               OpDecorate %21 DescriptorSet 0
+               OpDecorate %21 Binding 1
+               OpDecorate %22 RelaxedPrecision
+               OpDecorate %34 RelaxedPrecision
+               OpDecorate %40 RelaxedPrecision
+               OpDecorate %42 RelaxedPrecision
+               OpDecorate %43 RelaxedPrecision
+          %2 = OpTypeVoid
+          %3 = OpTypeFunction %2
+          %6 = OpTypeFloat 32
+          %7 = OpTypeImage %6 2D 0 0 0 1 Unknown
+          %8 = OpTypeSampledImage %7
+          %9 = OpTypePointer UniformConstant %8
+         %10 = OpVariable %9 UniformConstant
+         %12 = OpTypeInt 32 1
+         %13 = OpConstant %12 2
+         %15 = OpTypeVector %12 2
+         %17 = OpTypeInt 32 0
+         %18 = OpConstant %17 0
+         %20 = OpTypePointer UniformConstant %7
+         %21 = OpVariable %20 UniformConstant
+         %23 = OpConstant %12 1
+         %25 = OpConstant %17 1
+         %27 = OpTypeBool
+         %31 = OpTypeVector %6 4
+         %32 = OpTypePointer Function %31
+         %35 = OpConstantComposite %15 %23 %23
+         %36 = OpConstant %12 3
+         %37 = OpConstant %12 4
+         %38 = OpConstantComposite %15 %36 %37
+        %201 = OpTypeFunction %15 %7 %12
+          %4 = OpFunction %2 None %3
+          %5 = OpLabel
+         %33 = OpVariable %32 Function
+         %11 = OpLoad %8 %10
+         %14 = OpImage %7 %11
+         %16 = OpFunctionCall %15 %200 %14 %13
+         %19 = OpCompositeExtract %12 %16 0
+         %22 = OpLoad %7 %21
+         %24 = OpImageQuerySizeLod %15 %22 %23
+         %26 = OpCompositeExtract %12 %24 1
+         %28 = OpSGreaterThan %27 %19 %26
+               OpSelectionMerge %30 None
+               OpBranchConditional %28 %29 %41
+         %29 = OpLabel
+         %34 = OpLoad %8 %10
+         %39 = OpImage %7 %34
+         %40 = OpImageFetch %31 %39 %35 Lod|ConstOffset %13 %38
+               OpStore %33 %40
+               OpBranch %30
+         %41 = OpLabel
+         %42 = OpLoad %7 %21
+         %43 = OpImageFetch %31 %42 %35 Lod|ConstOffset %13 %38
+               OpStore %33 %43
+               OpBranch %30
+         %30 = OpLabel
+               OpReturn
+               OpFunctionEnd
+        %200 = OpFunction %15 None %201
+        %202 = OpFunctionParameter %7
+        %203 = OpFunctionParameter %12
+        %204 = OpLabel
+        %205 = OpImageQuerySizeLod %15 %202 %203
+               OpReturnValue %205
+               OpFunctionEnd
+  )";
+
+  const auto env = SPV_ENV_UNIVERSAL_1_3;
+  const auto consumer = nullptr;
+  const auto recipient_context =
+      BuildModule(env, consumer, recipient_shader, kFuzzAssembleOption);
+  ASSERT_TRUE(IsValid(env, recipient_context.get()));
+
+  const auto donor_context =
+      BuildModule(env, consumer, donor_shader, kFuzzAssembleOption);
+  ASSERT_TRUE(IsValid(env, donor_context.get()));
+
+  FactManager fact_manager;
+  spvtools::ValidatorOptions validator_options;
+  TransformationContext transformation_context(&fact_manager,
+                                               validator_options);
+
+  PseudoRandomGenerator prng(0);
+  FuzzerContext fuzzer_context(&prng, 100);
+  protobufs::TransformationSequence transformation_sequence;
+
+  FuzzerPassDonateModules fuzzer_pass(recipient_context.get(),
+                                      &transformation_context, &fuzzer_context,
+                                      &transformation_sequence, {});
+
+  fuzzer_pass.DonateSingleModule(donor_context.get(), false);
+
+  // We just check that the result is valid.  Checking to what it should be
+  // exactly equal to would be very fragile.
+  ASSERT_TRUE(IsValid(env, recipient_context.get()));
+}
+
 TEST(FuzzerPassDonateModulesTest, DonateComputeShaderWithRuntimeArray) {
   std::string recipient_shader = R"(
                OpCapability Shader
