spirv-fuzz: Fix to FuzzerPassFlattenConditionalBranches (#3865)

Fixes #3864.
diff --git a/source/fuzz/fuzzer_pass_flatten_conditional_branches.cpp b/source/fuzz/fuzzer_pass_flatten_conditional_branches.cpp
index 132d50a..5e79ec8 100644
--- a/source/fuzz/fuzzer_pass_flatten_conditional_branches.cpp
+++ b/source/fuzz/fuzzer_pass_flatten_conditional_branches.cpp
@@ -34,11 +34,12 @@
     default;
 
 void FuzzerPassFlattenConditionalBranches::Apply() {
-  // Get all the selection headers that we want to flatten. We need to collect
-  // all of them first, because, since we are changing the structure of the
-  // module, it's not safe to modify them while iterating.
-  std::vector<opt::BasicBlock*> selection_headers;
   for (auto& function : *GetIRContext()->module()) {
+    // Get all the selection headers that we want to flatten. We need to collect
+    // all of them first, because, since we are changing the structure of the
+    // module, it's not safe to modify them while iterating.
+    std::vector<opt::BasicBlock*> selection_headers;
+
     for (auto& block : function) {
       // Randomly decide whether to consider this block.
       if (!GetFuzzerContext()->ChoosePercentage(
@@ -53,70 +54,71 @@
         selection_headers.emplace_back(&block);
       }
     }
-  }
 
-  // Sort the headers so that those that are more deeply nested are considered
-  // first, possibly enabling outer conditionals to be flattened.
-  std::sort(selection_headers.begin(), selection_headers.end(),
-            ComparatorDeepBlocksFirst(GetIRContext()));
+    // Sort the headers so that those that are more deeply nested are considered
+    // first, possibly enabling outer conditionals to be flattened.
+    std::sort(selection_headers.begin(), selection_headers.end(),
+              ComparatorDeepBlocksFirst(GetIRContext()));
 
-  // Apply the transformation to the headers which can be flattened.
-  for (auto header : selection_headers) {
-    // Make a set to keep track of the instructions that need fresh ids.
-    std::set<opt::Instruction*> instructions_that_need_ids;
+    // Apply the transformation to the headers which can be flattened.
+    for (auto header : selection_headers) {
+      // Make a set to keep track of the instructions that need fresh ids.
+      std::set<opt::Instruction*> instructions_that_need_ids;
 
-    // Do not consider this header if the conditional cannot be flattened.
-    if (!TransformationFlattenConditionalBranch::
-            GetProblematicInstructionsIfConditionalCanBeFlattened(
-                GetIRContext(), header, &instructions_that_need_ids)) {
-      continue;
-    }
-
-    // Some instructions will require to be enclosed inside conditionals because
-    // they have side effects (for example, loads and stores). Some of this have
-    // no result id, so we require instruction descriptors to identify them.
-    // Each of them is associated with the necessary ids for it via a
-    // SideEffectWrapperInfo message.
-    std::vector<protobufs::SideEffectWrapperInfo> wrappers_info;
-
-    for (auto instruction : instructions_that_need_ids) {
-      protobufs::SideEffectWrapperInfo wrapper_info;
-      *wrapper_info.mutable_instruction() =
-          MakeInstructionDescriptor(GetIRContext(), instruction);
-      wrapper_info.set_merge_block_id(GetFuzzerContext()->GetFreshId());
-      wrapper_info.set_execute_block_id(GetFuzzerContext()->GetFreshId());
-
-      // If the instruction has a non-void result id, we need to define more
-      // fresh ids and provide an id of the suitable type whose value can be
-      // copied in order to create a placeholder id.
-      if (TransformationFlattenConditionalBranch::InstructionNeedsPlaceholder(
-              GetIRContext(), *instruction)) {
-        wrapper_info.set_actual_result_id(GetFuzzerContext()->GetFreshId());
-        wrapper_info.set_alternative_block_id(GetFuzzerContext()->GetFreshId());
-        wrapper_info.set_placeholder_result_id(
-            GetFuzzerContext()->GetFreshId());
-
-        // The id will be a zero constant if the type allows it, and an OpUndef
-        // otherwise. We want to avoid using OpUndef, if possible, to avoid
-        // undefined behaviour in the module as much as possible.
-        if (fuzzerutil::CanCreateConstant(
-                *GetIRContext()->get_type_mgr()->GetType(
-                    instruction->type_id()))) {
-          wrapper_info.set_value_to_copy_id(
-              FindOrCreateZeroConstant(instruction->type_id(), true));
-        } else {
-          wrapper_info.set_value_to_copy_id(
-              FindOrCreateGlobalUndef(instruction->type_id()));
-        }
+      // Do not consider this header if the conditional cannot be flattened.
+      if (!TransformationFlattenConditionalBranch::
+              GetProblematicInstructionsIfConditionalCanBeFlattened(
+                  GetIRContext(), header, &instructions_that_need_ids)) {
+        continue;
       }
 
-      wrappers_info.emplace_back(wrapper_info);
-    }
+      // Some instructions will require to be enclosed inside conditionals
+      // because they have side effects (for example, loads and stores). Some of
+      // this have no result id, so we require instruction descriptors to
+      // identify them. Each of them is associated with the necessary ids for it
+      // via a SideEffectWrapperInfo message.
+      std::vector<protobufs::SideEffectWrapperInfo> wrappers_info;
 
-    // Apply the transformation, evenly choosing whether to lay out the true
-    // branch or the false branch first.
-    ApplyTransformation(TransformationFlattenConditionalBranch(
-        header->id(), GetFuzzerContext()->ChooseEven(), wrappers_info));
+      for (auto instruction : instructions_that_need_ids) {
+        protobufs::SideEffectWrapperInfo wrapper_info;
+        *wrapper_info.mutable_instruction() =
+            MakeInstructionDescriptor(GetIRContext(), instruction);
+        wrapper_info.set_merge_block_id(GetFuzzerContext()->GetFreshId());
+        wrapper_info.set_execute_block_id(GetFuzzerContext()->GetFreshId());
+
+        // If the instruction has a non-void result id, we need to define more
+        // fresh ids and provide an id of the suitable type whose value can be
+        // copied in order to create a placeholder id.
+        if (TransformationFlattenConditionalBranch::InstructionNeedsPlaceholder(
+                GetIRContext(), *instruction)) {
+          wrapper_info.set_actual_result_id(GetFuzzerContext()->GetFreshId());
+          wrapper_info.set_alternative_block_id(
+              GetFuzzerContext()->GetFreshId());
+          wrapper_info.set_placeholder_result_id(
+              GetFuzzerContext()->GetFreshId());
+
+          // The id will be a zero constant if the type allows it, and an
+          // OpUndef otherwise. We want to avoid using OpUndef, if possible, to
+          // avoid undefined behaviour in the module as much as possible.
+          if (fuzzerutil::CanCreateConstant(
+                  *GetIRContext()->get_type_mgr()->GetType(
+                      instruction->type_id()))) {
+            wrapper_info.set_value_to_copy_id(
+                FindOrCreateZeroConstant(instruction->type_id(), true));
+          } else {
+            wrapper_info.set_value_to_copy_id(
+                FindOrCreateGlobalUndef(instruction->type_id()));
+          }
+        }
+
+        wrappers_info.emplace_back(wrapper_info);
+      }
+
+      // Apply the transformation, evenly choosing whether to lay out the true
+      // branch or the false branch first.
+      ApplyTransformation(TransformationFlattenConditionalBranch(
+          header->id(), GetFuzzerContext()->ChooseEven(), wrappers_info));
+    }
   }
 }