spirv-fuzz: Avoid invalidating analyses in various transformations (#4205)

Avoids invalidating all analyses in transformations that add
constants, OpUndef and global and local variables.
diff --git a/source/fuzz/fuzzer_util.cpp b/source/fuzz/fuzzer_util.cpp
index 9f58755..aa0d30e 100644
--- a/source/fuzz/fuzzer_util.cpp
+++ b/source/fuzz/fuzzer_util.cpp
@@ -837,9 +837,10 @@
   }
 }
 
-void AddGlobalVariable(opt::IRContext* context, uint32_t result_id,
-                       uint32_t type_id, SpvStorageClass storage_class,
-                       uint32_t initializer_id) {
+opt::Instruction* AddGlobalVariable(opt::IRContext* context, uint32_t result_id,
+                                    uint32_t type_id,
+                                    SpvStorageClass storage_class,
+                                    uint32_t initializer_id) {
   // Check various preconditions.
   assert(result_id != 0 && "Result id can't be 0");
 
@@ -874,16 +875,20 @@
     operands.push_back({SPV_OPERAND_TYPE_ID, {initializer_id}});
   }
 
-  context->module()->AddGlobalValue(MakeUnique<opt::Instruction>(
-      context, SpvOpVariable, type_id, result_id, std::move(operands)));
+  auto new_instruction = MakeUnique<opt::Instruction>(
+      context, SpvOpVariable, type_id, result_id, std::move(operands));
+  auto result = new_instruction.get();
+  context->module()->AddGlobalValue(std::move(new_instruction));
 
   AddVariableIdToEntryPointInterfaces(context, result_id);
   UpdateModuleIdBound(context, result_id);
+
+  return result;
 }
 
-void AddLocalVariable(opt::IRContext* context, uint32_t result_id,
-                      uint32_t type_id, uint32_t function_id,
-                      uint32_t initializer_id) {
+opt::Instruction* AddLocalVariable(opt::IRContext* context, uint32_t result_id,
+                                   uint32_t type_id, uint32_t function_id,
+                                   uint32_t initializer_id) {
   // Check various preconditions.
   assert(result_id != 0 && "Result id can't be 0");
 
@@ -904,13 +909,17 @@
   auto* function = FindFunction(context, function_id);
   assert(function && "Function id is invalid");
 
-  function->begin()->begin()->InsertBefore(MakeUnique<opt::Instruction>(
+  auto new_instruction = MakeUnique<opt::Instruction>(
       context, SpvOpVariable, type_id, result_id,
       opt::Instruction::OperandList{
           {SPV_OPERAND_TYPE_STORAGE_CLASS, {SpvStorageClassFunction}},
-          {SPV_OPERAND_TYPE_ID, {initializer_id}}}));
+          {SPV_OPERAND_TYPE_ID, {initializer_id}}});
+  auto result = new_instruction.get();
+  function->begin()->begin()->InsertBefore(std::move(new_instruction));
 
   UpdateModuleIdBound(context, result_id);
+
+  return result;
 }
 
 bool HasDuplicates(const std::vector<uint32_t>& arr) {
diff --git a/source/fuzz/fuzzer_util.h b/source/fuzz/fuzzer_util.h
index 6076ee7..fcbf1c6 100644
--- a/source/fuzz/fuzzer_util.h
+++ b/source/fuzz/fuzzer_util.h
@@ -303,9 +303,12 @@
 // - |initializer_id| must be 0 if |storage_class| is Workgroup, and otherwise
 //   may either be 0 or the id of a constant whose type is the pointee type of
 //   |type_id|.
-void AddGlobalVariable(opt::IRContext* context, uint32_t result_id,
-                       uint32_t type_id, SpvStorageClass storage_class,
-                       uint32_t initializer_id);
+//
+// Returns a pointer to the new global variable instruction.
+opt::Instruction* AddGlobalVariable(opt::IRContext* context, uint32_t result_id,
+                                    uint32_t type_id,
+                                    SpvStorageClass storage_class,
+                                    uint32_t initializer_id);
 
 // Adds an instruction to the start of |function_id|, of the form:
 //   |result_id| = OpVariable |type_id| Function |initializer_id|.
@@ -315,9 +318,11 @@
 // - |initializer_id| must be the id of a constant with the same type as the
 //   pointer's pointee type.
 // - |function_id| must be the id of a function.
-void AddLocalVariable(opt::IRContext* context, uint32_t result_id,
-                      uint32_t type_id, uint32_t function_id,
-                      uint32_t initializer_id);
+//
+// Returns a pointer to the new local variable instruction.
+opt::Instruction* AddLocalVariable(opt::IRContext* context, uint32_t result_id,
+                                   uint32_t type_id, uint32_t function_id,
+                                   uint32_t initializer_id);
 
 // Returns true if the vector |arr| has duplicates.
 bool HasDuplicates(const std::vector<uint32_t>& arr);
diff --git a/source/fuzz/transformation_add_constant_boolean.cpp b/source/fuzz/transformation_add_constant_boolean.cpp
index 937fdbc..3935432 100644
--- a/source/fuzz/transformation_add_constant_boolean.cpp
+++ b/source/fuzz/transformation_add_constant_boolean.cpp
@@ -21,8 +21,8 @@
 namespace fuzz {
 
 TransformationAddConstantBoolean::TransformationAddConstantBoolean(
-    const protobufs::TransformationAddConstantBoolean& message)
-    : message_(message) {}
+    protobufs::TransformationAddConstantBoolean message)
+    : message_(std::move(message)) {}
 
 TransformationAddConstantBoolean::TransformationAddConstantBoolean(
     uint32_t fresh_id, bool is_true, bool is_irrelevant) {
@@ -42,14 +42,18 @@
     TransformationContext* transformation_context) const {
   // Add the boolean constant to the module, ensuring the module's id bound is
   // high enough.
+  auto new_instruction = MakeUnique<opt::Instruction>(
+      ir_context, message_.is_true() ? SpvOpConstantTrue : SpvOpConstantFalse,
+      fuzzerutil::MaybeGetBoolType(ir_context), message_.fresh_id(),
+      opt::Instruction::OperandList());
+  auto new_instruction_ptr = new_instruction.get();
+  ir_context->module()->AddGlobalValue(std::move(new_instruction));
   fuzzerutil::UpdateModuleIdBound(ir_context, message_.fresh_id());
-  ir_context->module()->AddGlobalValue(
-      message_.is_true() ? SpvOpConstantTrue : SpvOpConstantFalse,
-      message_.fresh_id(), fuzzerutil::MaybeGetBoolType(ir_context));
-  // We have added an instruction to the module, so need to be careful about the
-  // validity of existing analyses.
-  ir_context->InvalidateAnalysesExceptFor(
-      opt::IRContext::Analysis::kAnalysisNone);
+
+  // Inform the def-use manager about the new instruction. Invalidate the
+  // constant manager as we have added a new constant.
+  ir_context->get_def_use_mgr()->AnalyzeInstDef(new_instruction_ptr);
+  ir_context->InvalidateAnalyses(opt::IRContext::kAnalysisConstants);
 
   if (message_.is_irrelevant()) {
     transformation_context->GetFactManager()->AddFactIdIsIrrelevant(
diff --git a/source/fuzz/transformation_add_constant_boolean.h b/source/fuzz/transformation_add_constant_boolean.h
index d1d04ef..7f31471 100644
--- a/source/fuzz/transformation_add_constant_boolean.h
+++ b/source/fuzz/transformation_add_constant_boolean.h
@@ -26,7 +26,7 @@
 class TransformationAddConstantBoolean : public Transformation {
  public:
   explicit TransformationAddConstantBoolean(
-      const protobufs::TransformationAddConstantBoolean& message);
+      protobufs::TransformationAddConstantBoolean message);
 
   TransformationAddConstantBoolean(uint32_t fresh_id, bool is_true,
                                    bool is_irrelevant);
diff --git a/source/fuzz/transformation_add_constant_composite.cpp b/source/fuzz/transformation_add_constant_composite.cpp
index 0260321..e6cd5a9 100644
--- a/source/fuzz/transformation_add_constant_composite.cpp
+++ b/source/fuzz/transformation_add_constant_composite.cpp
@@ -22,9 +22,8 @@
 namespace fuzz {
 
 TransformationAddConstantComposite::TransformationAddConstantComposite(
-    const spvtools::fuzz::protobufs::TransformationAddConstantComposite&
-        message)
-    : message_(message) {}
+    spvtools::fuzz::protobufs::TransformationAddConstantComposite message)
+    : message_(std::move(message)) {}
 
 TransformationAddConstantComposite::TransformationAddConstantComposite(
     uint32_t fresh_id, uint32_t type_id,
@@ -120,14 +119,17 @@
   for (auto constituent_id : message_.constituent_id()) {
     in_operands.push_back({SPV_OPERAND_TYPE_ID, {constituent_id}});
   }
-  ir_context->module()->AddGlobalValue(MakeUnique<opt::Instruction>(
+  auto new_instruction = MakeUnique<opt::Instruction>(
       ir_context, SpvOpConstantComposite, message_.type_id(),
-      message_.fresh_id(), in_operands));
+      message_.fresh_id(), in_operands);
+  auto new_instruction_ptr = new_instruction.get();
+  ir_context->module()->AddGlobalValue(std::move(new_instruction));
   fuzzerutil::UpdateModuleIdBound(ir_context, message_.fresh_id());
-  // We have added an instruction to the module, so need to be careful about the
-  // validity of existing analyses.
-  ir_context->InvalidateAnalysesExceptFor(
-      opt::IRContext::Analysis::kAnalysisNone);
+
+  // Inform the def-use manager of the new instruction. Invalidate the constant
+  // manager as we have added a new constant.
+  ir_context->get_def_use_mgr()->AnalyzeInstDefUse(new_instruction_ptr);
+  ir_context->InvalidateAnalyses(opt::IRContext::kAnalysisConstants);
 
   if (message_.is_irrelevant()) {
     transformation_context->GetFactManager()->AddFactIdIsIrrelevant(
diff --git a/source/fuzz/transformation_add_constant_composite.h b/source/fuzz/transformation_add_constant_composite.h
index 9e9222d..94e7a92 100644
--- a/source/fuzz/transformation_add_constant_composite.h
+++ b/source/fuzz/transformation_add_constant_composite.h
@@ -28,7 +28,7 @@
 class TransformationAddConstantComposite : public Transformation {
  public:
   explicit TransformationAddConstantComposite(
-      const protobufs::TransformationAddConstantComposite& message);
+      protobufs::TransformationAddConstantComposite message);
 
   TransformationAddConstantComposite(
       uint32_t fresh_id, uint32_t type_id,
diff --git a/source/fuzz/transformation_add_constant_null.cpp b/source/fuzz/transformation_add_constant_null.cpp
index 3c66ab1..32544e6 100644
--- a/source/fuzz/transformation_add_constant_null.cpp
+++ b/source/fuzz/transformation_add_constant_null.cpp
@@ -20,8 +20,8 @@
 namespace fuzz {
 
 TransformationAddConstantNull::TransformationAddConstantNull(
-    const spvtools::fuzz::protobufs::TransformationAddConstantNull& message)
-    : message_(message) {}
+    spvtools::fuzz::protobufs::TransformationAddConstantNull message)
+    : message_(std::move(message)) {}
 
 TransformationAddConstantNull::TransformationAddConstantNull(uint32_t fresh_id,
                                                              uint32_t type_id) {
@@ -46,14 +46,18 @@
 }
 
 void TransformationAddConstantNull::Apply(
-    opt::IRContext* context, TransformationContext* /*unused*/) const {
-  context->module()->AddGlobalValue(MakeUnique<opt::Instruction>(
-      context, SpvOpConstantNull, message_.type_id(), message_.fresh_id(),
-      opt::Instruction::OperandList()));
-  fuzzerutil::UpdateModuleIdBound(context, message_.fresh_id());
-  // We have added an instruction to the module, so need to be careful about the
-  // validity of existing analyses.
-  context->InvalidateAnalysesExceptFor(opt::IRContext::Analysis::kAnalysisNone);
+    opt::IRContext* ir_context, TransformationContext* /*unused*/) const {
+  auto new_instruction = MakeUnique<opt::Instruction>(
+      ir_context, SpvOpConstantNull, message_.type_id(), message_.fresh_id(),
+      opt::Instruction::OperandList());
+  auto new_instruction_ptr = new_instruction.get();
+  ir_context->module()->AddGlobalValue(std::move(new_instruction));
+  fuzzerutil::UpdateModuleIdBound(ir_context, message_.fresh_id());
+
+  // Inform the def-use manager about the new instruction. Invalidate the
+  // constant manager as we have added a new constant.
+  ir_context->get_def_use_mgr()->AnalyzeInstDef(new_instruction_ptr);
+  ir_context->InvalidateAnalyses(opt::IRContext::kAnalysisConstants);
 }
 
 protobufs::Transformation TransformationAddConstantNull::ToMessage() const {
diff --git a/source/fuzz/transformation_add_constant_null.h b/source/fuzz/transformation_add_constant_null.h
index bd08b1d..bb1d1b7 100644
--- a/source/fuzz/transformation_add_constant_null.h
+++ b/source/fuzz/transformation_add_constant_null.h
@@ -26,7 +26,7 @@
 class TransformationAddConstantNull : public Transformation {
  public:
   explicit TransformationAddConstantNull(
-      const protobufs::TransformationAddConstantNull& message);
+      protobufs::TransformationAddConstantNull message);
 
   TransformationAddConstantNull(uint32_t fresh_id, uint32_t type_id);
 
@@ -34,12 +34,12 @@
   // - |message_.type_id| must be the id of a type for which it is acceptable
   //   to create a null constant
   bool IsApplicable(
-      opt::IRContext* context,
+      opt::IRContext* ir_context,
       const TransformationContext& transformation_context) const override;
 
   // Adds an OpConstantNull instruction to the module, with |message_.type_id|
   // as its type.  The instruction has result id |message_.fresh_id|.
-  void Apply(opt::IRContext* context,
+  void Apply(opt::IRContext* ir_context,
              TransformationContext* transformation_context) const override;
 
   std::unordered_set<uint32_t> GetFreshIds() const override;
diff --git a/source/fuzz/transformation_add_constant_scalar.cpp b/source/fuzz/transformation_add_constant_scalar.cpp
index 9a6642a..a2d95fb 100644
--- a/source/fuzz/transformation_add_constant_scalar.cpp
+++ b/source/fuzz/transformation_add_constant_scalar.cpp
@@ -20,8 +20,8 @@
 namespace fuzz {
 
 TransformationAddConstantScalar::TransformationAddConstantScalar(
-    const spvtools::fuzz::protobufs::TransformationAddConstantScalar& message)
-    : message_(message) {}
+    spvtools::fuzz::protobufs::TransformationAddConstantScalar message)
+    : message_(std::move(message)) {}
 
 TransformationAddConstantScalar::TransformationAddConstantScalar(
     uint32_t fresh_id, uint32_t type_id, const std::vector<uint32_t>& words,
@@ -64,19 +64,21 @@
 void TransformationAddConstantScalar::Apply(
     opt::IRContext* ir_context,
     TransformationContext* transformation_context) const {
-  ir_context->module()->AddGlobalValue(MakeUnique<opt::Instruction>(
+  auto new_instruction = MakeUnique<opt::Instruction>(
       ir_context, SpvOpConstant, message_.type_id(), message_.fresh_id(),
       opt::Instruction::OperandList(
           {{SPV_OPERAND_TYPE_LITERAL_INTEGER,
             std::vector<uint32_t>(message_.word().begin(),
-                                  message_.word().end())}})));
+                                  message_.word().end())}}));
+  auto new_instruction_ptr = new_instruction.get();
+  ir_context->module()->AddGlobalValue(std::move(new_instruction));
 
   fuzzerutil::UpdateModuleIdBound(ir_context, message_.fresh_id());
 
-  // We have added an instruction to the module, so need to be careful about the
-  // validity of existing analyses.
-  ir_context->InvalidateAnalysesExceptFor(
-      opt::IRContext::Analysis::kAnalysisNone);
+  // Inform the def-use manager about the new instruction. Invalidate the
+  // constant manager as we have added a new constant.
+  ir_context->get_def_use_mgr()->AnalyzeInstDef(new_instruction_ptr);
+  ir_context->InvalidateAnalyses(opt::IRContext::kAnalysisConstants);
 
   if (message_.is_irrelevant()) {
     transformation_context->GetFactManager()->AddFactIdIsIrrelevant(
diff --git a/source/fuzz/transformation_add_constant_scalar.h b/source/fuzz/transformation_add_constant_scalar.h
index 3f23907..adb0735 100644
--- a/source/fuzz/transformation_add_constant_scalar.h
+++ b/source/fuzz/transformation_add_constant_scalar.h
@@ -28,7 +28,7 @@
 class TransformationAddConstantScalar : public Transformation {
  public:
   explicit TransformationAddConstantScalar(
-      const protobufs::TransformationAddConstantScalar& message);
+      protobufs::TransformationAddConstantScalar message);
 
   TransformationAddConstantScalar(uint32_t fresh_id, uint32_t type_id,
                                   const std::vector<uint32_t>& words,
diff --git a/source/fuzz/transformation_add_global_undef.cpp b/source/fuzz/transformation_add_global_undef.cpp
index 7a90b82..eb390ea 100644
--- a/source/fuzz/transformation_add_global_undef.cpp
+++ b/source/fuzz/transformation_add_global_undef.cpp
@@ -20,8 +20,8 @@
 namespace fuzz {
 
 TransformationAddGlobalUndef::TransformationAddGlobalUndef(
-    const spvtools::fuzz::protobufs::TransformationAddGlobalUndef& message)
-    : message_(message) {}
+    spvtools::fuzz::protobufs::TransformationAddGlobalUndef message)
+    : message_(std::move(message)) {}
 
 TransformationAddGlobalUndef::TransformationAddGlobalUndef(uint32_t fresh_id,
                                                            uint32_t type_id) {
@@ -42,14 +42,14 @@
 
 void TransformationAddGlobalUndef::Apply(
     opt::IRContext* ir_context, TransformationContext* /*unused*/) const {
-  ir_context->module()->AddGlobalValue(MakeUnique<opt::Instruction>(
+  auto new_instruction = MakeUnique<opt::Instruction>(
       ir_context, SpvOpUndef, message_.type_id(), message_.fresh_id(),
-      opt::Instruction::OperandList()));
+      opt::Instruction::OperandList());
+  auto new_instruction_ptr = new_instruction.get();
+  ir_context->module()->AddGlobalValue(std::move(new_instruction));
   fuzzerutil::UpdateModuleIdBound(ir_context, message_.fresh_id());
-  // We have added an instruction to the module, so need to be careful about the
-  // validity of existing analyses.
-  ir_context->InvalidateAnalysesExceptFor(
-      opt::IRContext::Analysis::kAnalysisNone);
+  // Inform the def-use manager about the new instruction.
+  ir_context->get_def_use_mgr()->AnalyzeInstDef(new_instruction_ptr);
 }
 
 protobufs::Transformation TransformationAddGlobalUndef::ToMessage() const {
diff --git a/source/fuzz/transformation_add_global_undef.h b/source/fuzz/transformation_add_global_undef.h
index 717dc9a..37542c3 100644
--- a/source/fuzz/transformation_add_global_undef.h
+++ b/source/fuzz/transformation_add_global_undef.h
@@ -26,7 +26,7 @@
 class TransformationAddGlobalUndef : public Transformation {
  public:
   explicit TransformationAddGlobalUndef(
-      const protobufs::TransformationAddGlobalUndef& message);
+      protobufs::TransformationAddGlobalUndef message);
 
   TransformationAddGlobalUndef(uint32_t fresh_id, uint32_t type_id);
 
diff --git a/source/fuzz/transformation_add_global_variable.cpp b/source/fuzz/transformation_add_global_variable.cpp
index dd04e48..814d01b 100644
--- a/source/fuzz/transformation_add_global_variable.cpp
+++ b/source/fuzz/transformation_add_global_variable.cpp
@@ -20,8 +20,8 @@
 namespace fuzz {
 
 TransformationAddGlobalVariable::TransformationAddGlobalVariable(
-    const spvtools::fuzz::protobufs::TransformationAddGlobalVariable& message)
-    : message_(message) {}
+    spvtools::fuzz::protobufs::TransformationAddGlobalVariable message)
+    : message_(std::move(message)) {}
 
 TransformationAddGlobalVariable::TransformationAddGlobalVariable(
     uint32_t fresh_id, uint32_t type_id, SpvStorageClass storage_class,
@@ -93,15 +93,13 @@
 void TransformationAddGlobalVariable::Apply(
     opt::IRContext* ir_context,
     TransformationContext* transformation_context) const {
-  fuzzerutil::AddGlobalVariable(
+  opt::Instruction* new_instruction = fuzzerutil::AddGlobalVariable(
       ir_context, message_.fresh_id(), message_.type_id(),
       static_cast<SpvStorageClass>(message_.storage_class()),
       message_.initializer_id());
 
-  // We have added an instruction to the module, so need to be careful about the
-  // validity of existing analyses.
-  ir_context->InvalidateAnalysesExceptFor(
-      opt::IRContext::Analysis::kAnalysisNone);
+  // Inform the def-use manager about the new instruction.
+  ir_context->get_def_use_mgr()->AnalyzeInstDefUse(new_instruction);
 
   if (message_.value_is_irrelevant()) {
     transformation_context->GetFactManager()->AddFactValueOfPointeeIsIrrelevant(
diff --git a/source/fuzz/transformation_add_global_variable.h b/source/fuzz/transformation_add_global_variable.h
index 8d46edb..d74d48a 100644
--- a/source/fuzz/transformation_add_global_variable.h
+++ b/source/fuzz/transformation_add_global_variable.h
@@ -26,7 +26,7 @@
 class TransformationAddGlobalVariable : public Transformation {
  public:
   explicit TransformationAddGlobalVariable(
-      const protobufs::TransformationAddGlobalVariable& message);
+      protobufs::TransformationAddGlobalVariable message);
 
   TransformationAddGlobalVariable(uint32_t fresh_id, uint32_t type_id,
                                   SpvStorageClass storage_class,
diff --git a/source/fuzz/transformation_add_local_variable.cpp b/source/fuzz/transformation_add_local_variable.cpp
index 0a7a3da..21768d2 100644
--- a/source/fuzz/transformation_add_local_variable.cpp
+++ b/source/fuzz/transformation_add_local_variable.cpp
@@ -20,8 +20,8 @@
 namespace fuzz {
 
 TransformationAddLocalVariable::TransformationAddLocalVariable(
-    const spvtools::fuzz::protobufs::TransformationAddLocalVariable& message)
-    : message_(message) {}
+    spvtools::fuzz::protobufs::TransformationAddLocalVariable message)
+    : message_(std::move(message)) {}
 
 TransformationAddLocalVariable::TransformationAddLocalVariable(
     uint32_t fresh_id, uint32_t type_id, uint32_t function_id,
@@ -70,11 +70,17 @@
 void TransformationAddLocalVariable::Apply(
     opt::IRContext* ir_context,
     TransformationContext* transformation_context) const {
-  fuzzerutil::AddLocalVariable(ir_context, message_.fresh_id(),
-                               message_.type_id(), message_.function_id(),
-                               message_.initializer_id());
+  opt::Instruction* new_instruction = fuzzerutil::AddLocalVariable(
+      ir_context, message_.fresh_id(), message_.type_id(),
+      message_.function_id(), message_.initializer_id());
 
-  ir_context->InvalidateAnalysesExceptFor(opt::IRContext::kAnalysisNone);
+  // Inform the def-use manager about the new instruction.
+  ir_context->get_def_use_mgr()->AnalyzeInstDefUse(new_instruction);
+  ir_context->set_instr_block(
+      new_instruction,
+      fuzzerutil::FindFunction(ir_context, message_.function_id())
+          ->entry()
+          .get());
 
   if (message_.value_is_irrelevant()) {
     transformation_context->GetFactManager()->AddFactValueOfPointeeIsIrrelevant(
diff --git a/source/fuzz/transformation_add_local_variable.h b/source/fuzz/transformation_add_local_variable.h
index 963079f..b008a1c 100644
--- a/source/fuzz/transformation_add_local_variable.h
+++ b/source/fuzz/transformation_add_local_variable.h
@@ -26,7 +26,7 @@
 class TransformationAddLocalVariable : public Transformation {
  public:
   explicit TransformationAddLocalVariable(
-      const protobufs::TransformationAddLocalVariable& message);
+      protobufs::TransformationAddLocalVariable message);
 
   TransformationAddLocalVariable(uint32_t fresh_id, uint32_t type_id,
                                  uint32_t function_id, uint32_t initializer_id,
diff --git a/test/fuzz/transformation_add_constant_boolean_test.cpp b/test/fuzz/transformation_add_constant_boolean_test.cpp
index 3506db6..bd8d91c 100644
--- a/test/fuzz/transformation_add_constant_boolean_test.cpp
+++ b/test/fuzz/transformation_add_constant_boolean_test.cpp
@@ -46,6 +46,7 @@
   spvtools::ValidatorOptions validator_options;
   ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options,
                                                kConsoleMessageConsumer));
+
   TransformationContext transformation_context(
       MakeUnique<FactManager>(context.get()), validator_options);
   // True and false can both be added as neither is present.
@@ -68,7 +69,14 @@
   auto add_false = TransformationAddConstantBoolean(8, false, false);
 
   ASSERT_TRUE(add_true.IsApplicable(context.get(), transformation_context));
+  ASSERT_EQ(nullptr, context->get_def_use_mgr()->GetDef(7));
+  ASSERT_EQ(nullptr, context->get_constant_mgr()->FindDeclaredConstant(7));
   ApplyAndCheckFreshIds(add_true, context.get(), &transformation_context);
+  ASSERT_EQ(SpvOpConstantTrue, context->get_def_use_mgr()->GetDef(7)->opcode());
+  ASSERT_TRUE(context->get_constant_mgr()
+                  ->FindDeclaredConstant(7)
+                  ->AsBoolConstant()
+                  ->value());
   ASSERT_TRUE(fuzzerutil::IsValidAndWellFormed(context.get(), validator_options,
                                                kConsoleMessageConsumer));
 
diff --git a/test/fuzz/transformation_add_constant_composite_test.cpp b/test/fuzz/transformation_add_constant_composite_test.cpp
index 2c296fb..e5cbeec 100644
--- a/test/fuzz/transformation_add_constant_composite_test.cpp
+++ b/test/fuzz/transformation_add_constant_composite_test.cpp
@@ -82,10 +82,30 @@
   ASSERT_FALSE(TransformationAddConstantComposite(100, 39, {11, 12}, false)
                    .IsApplicable(context.get(), transformation_context));
 
-  TransformationAddConstantComposite transformations[] = {
-      // %100 = OpConstantComposite %7 %11 %12
-      TransformationAddConstantComposite(100, 7, {11, 12}, false),
+  {
+    // %100 = OpConstantComposite %7 %11 %12
+    TransformationAddConstantComposite transformation(100, 7, {11, 12}, false);
+    ASSERT_EQ(nullptr, context->get_def_use_mgr()->GetDef(100));
+    ASSERT_EQ(nullptr, context->get_constant_mgr()->FindDeclaredConstant(100));
+    ASSERT_TRUE(
+        transformation.IsApplicable(context.get(), transformation_context));
+    ApplyAndCheckFreshIds(transformation, context.get(),
+                          &transformation_context);
+    ASSERT_EQ(SpvOpConstantComposite,
+              context->get_def_use_mgr()->GetDef(100)->opcode());
+    ASSERT_EQ(0.0F, context->get_constant_mgr()
+                        ->FindDeclaredConstant(100)
+                        ->AsVectorConstant()
+                        ->GetComponents()[0]
+                        ->GetFloat());
+    ASSERT_EQ(1.0F, context->get_constant_mgr()
+                        ->FindDeclaredConstant(100)
+                        ->AsVectorConstant()
+                        ->GetComponents()[1]
+                        ->GetFloat());
+  }
 
+  TransformationAddConstantComposite transformations[] = {
       // %101 = OpConstantComposite %7 %14 %15
       TransformationAddConstantComposite(101, 7, {14, 15}, false),
 
diff --git a/test/fuzz/transformation_add_constant_null_test.cpp b/test/fuzz/transformation_add_constant_null_test.cpp
index ce20a67..1553e9f 100644
--- a/test/fuzz/transformation_add_constant_null_test.cpp
+++ b/test/fuzz/transformation_add_constant_null_test.cpp
@@ -78,9 +78,23 @@
   ASSERT_FALSE(TransformationAddConstantNull(100, 22).IsApplicable(
       context.get(), transformation_context));
 
+  {
+    // %100 = OpConstantNull %6
+    TransformationAddConstantNull transformation(100, 6);
+    ASSERT_EQ(nullptr, context->get_def_use_mgr()->GetDef(100));
+    ASSERT_EQ(nullptr, context->get_constant_mgr()->FindDeclaredConstant(100));
+    ASSERT_TRUE(
+        transformation.IsApplicable(context.get(), transformation_context));
+    ApplyAndCheckFreshIds(transformation, context.get(),
+                          &transformation_context);
+    ASSERT_EQ(SpvOpConstantNull,
+              context->get_def_use_mgr()->GetDef(100)->opcode());
+    ASSERT_EQ(
+        0.0F,
+        context->get_constant_mgr()->FindDeclaredConstant(100)->GetFloat());
+  }
+
   TransformationAddConstantNull transformations[] = {
-      // %100 = OpConstantNull %6
-      TransformationAddConstantNull(100, 6),
 
       // %101 = OpConstantNull %7
       TransformationAddConstantNull(101, 7),
diff --git a/test/fuzz/transformation_add_constant_scalar_test.cpp b/test/fuzz/transformation_add_constant_scalar_test.cpp
index a153fb1..91339db 100644
--- a/test/fuzz/transformation_add_constant_scalar_test.cpp
+++ b/test/fuzz/transformation_add_constant_scalar_test.cpp
@@ -171,7 +171,11 @@
       MakeUnique<FactManager>(context.get()), validator_options);
   // Adds 32-bit unsigned integer (1 logical operand with 1 word).
   auto transformation = TransformationAddConstantScalar(19, 2, {4}, false);
+  ASSERT_EQ(nullptr, context->get_def_use_mgr()->GetDef(19));
+  ASSERT_EQ(nullptr, context->get_constant_mgr()->FindDeclaredConstant(19));
   ApplyAndCheckFreshIds(transformation, context.get(), &transformation_context);
+  ASSERT_EQ(SpvOpConstant, context->get_def_use_mgr()->GetDef(19)->opcode());
+  ASSERT_EQ(4, context->get_constant_mgr()->FindDeclaredConstant(19)->GetU32());
   auto* constant_instruction = context->get_def_use_mgr()->GetDef(19);
   EXPECT_EQ(constant_instruction->NumInOperands(), 1);
   EXPECT_EQ(constant_instruction->NumInOperandWords(), 1);
diff --git a/test/fuzz/transformation_add_global_undef_test.cpp b/test/fuzz/transformation_add_global_undef_test.cpp
index c3a49e4..03b9157 100644
--- a/test/fuzz/transformation_add_global_undef_test.cpp
+++ b/test/fuzz/transformation_add_global_undef_test.cpp
@@ -63,9 +63,18 @@
   ASSERT_FALSE(TransformationAddGlobalUndef(100, 3).IsApplicable(
       context.get(), transformation_context));
 
+  {
+    // %100 = OpUndef %6
+    TransformationAddGlobalUndef transformation(100, 6);
+    ASSERT_EQ(nullptr, context->get_def_use_mgr()->GetDef(100));
+    ASSERT_TRUE(
+        transformation.IsApplicable(context.get(), transformation_context));
+    ApplyAndCheckFreshIds(transformation, context.get(),
+                          &transformation_context);
+    ASSERT_EQ(SpvOpUndef, context->get_def_use_mgr()->GetDef(100)->opcode());
+  }
+
   TransformationAddGlobalUndef transformations[] = {
-      // %100 = OpUndef %6
-      TransformationAddGlobalUndef(100, 6),
 
       // %101 = OpUndef %7
       TransformationAddGlobalUndef(101, 7),
diff --git a/test/fuzz/transformation_add_global_variable_test.cpp b/test/fuzz/transformation_add_global_variable_test.cpp
index 747cc32..9531ade 100644
--- a/test/fuzz/transformation_add_global_variable_test.cpp
+++ b/test/fuzz/transformation_add_global_variable_test.cpp
@@ -118,11 +118,24 @@
                                                14, false)
                    .IsApplicable(context.get(), transformation_context));
 
-  TransformationAddGlobalVariable transformations[] = {
-      // %100 = OpVariable %12 Private
-      TransformationAddGlobalVariable(100, 12, SpvStorageClassPrivate, 16,
-                                      true),
+  {
+    // %100 = OpVariable %12 Private
+    ASSERT_EQ(nullptr, context->get_def_use_mgr()->GetDef(100));
+    TransformationAddGlobalVariable transformation(
+        100, 12, SpvStorageClassPrivate, 16, true);
+    ASSERT_TRUE(
+        transformation.IsApplicable(context.get(), transformation_context));
+    ApplyAndCheckFreshIds(transformation, context.get(),
+                          &transformation_context);
+    ASSERT_EQ(SpvOpVariable, context->get_def_use_mgr()->GetDef(100)->opcode());
+    ASSERT_EQ(
+        SpvStorageClassPrivate,
+        static_cast<SpvStorageClass>(
+            context->get_def_use_mgr()->GetDef(100)->GetSingleWordInOperand(
+                0)));
+  }
 
+  TransformationAddGlobalVariable transformations[] = {
       // %101 = OpVariable %10 Private
       TransformationAddGlobalVariable(101, 10, SpvStorageClassPrivate, 40,
                                       false),
diff --git a/test/fuzz/transformation_add_local_variable_test.cpp b/test/fuzz/transformation_add_local_variable_test.cpp
index ed57a28..de88573 100644
--- a/test/fuzz/transformation_add_local_variable_test.cpp
+++ b/test/fuzz/transformation_add_local_variable_test.cpp
@@ -98,10 +98,14 @@
   // %105 = OpVariable %50 Function %51
   {
     TransformationAddLocalVariable transformation(105, 50, 4, 51, true);
+    ASSERT_EQ(nullptr, context->get_def_use_mgr()->GetDef(105));
+    ASSERT_EQ(nullptr, context->get_instr_block(105));
     ASSERT_TRUE(
         transformation.IsApplicable(context.get(), transformation_context));
     ApplyAndCheckFreshIds(transformation, context.get(),
                           &transformation_context);
+    ASSERT_EQ(SpvOpVariable, context->get_def_use_mgr()->GetDef(105)->opcode());
+    ASSERT_EQ(5, context->get_instr_block(105)->id());
   }
 
   // %104 = OpVariable %41 Function %46