_ZN8spvtools17ExtensionToStringENS_9ExtensionE:
    1|  1.60k|const char* ExtensionToString(Extension extension) {
    2|  1.60k|  switch (extension) {
  ------------------
  |  Branch (2:11): [True: 0, False: 1.60k]
  ------------------
    3|      0|    case Extension::kSPV_AMD_gcn_shader:
  ------------------
  |  Branch (3:5): [True: 0, False: 1.60k]
  ------------------
    4|      0|      return "SPV_AMD_gcn_shader";
    5|      0|    case Extension::kSPV_AMD_gpu_shader_half_float:
  ------------------
  |  Branch (5:5): [True: 0, False: 1.60k]
  ------------------
    6|      0|      return "SPV_AMD_gpu_shader_half_float";
    7|      0|    case Extension::kSPV_AMD_gpu_shader_half_float_fetch:
  ------------------
  |  Branch (7:5): [True: 0, False: 1.60k]
  ------------------
    8|      0|      return "SPV_AMD_gpu_shader_half_float_fetch";
    9|      0|    case Extension::kSPV_AMD_gpu_shader_int16:
  ------------------
  |  Branch (9:5): [True: 0, False: 1.60k]
  ------------------
   10|      0|      return "SPV_AMD_gpu_shader_int16";
   11|      0|    case Extension::kSPV_AMD_shader_ballot:
  ------------------
  |  Branch (11:5): [True: 0, False: 1.60k]
  ------------------
   12|      0|      return "SPV_AMD_shader_ballot";
   13|      0|    case Extension::kSPV_AMD_shader_early_and_late_fragment_tests:
  ------------------
  |  Branch (13:5): [True: 0, False: 1.60k]
  ------------------
   14|      0|      return "SPV_AMD_shader_early_and_late_fragment_tests";
   15|      1|    case Extension::kSPV_AMD_shader_explicit_vertex_parameter:
  ------------------
  |  Branch (15:5): [True: 1, False: 1.60k]
  ------------------
   16|      1|      return "SPV_AMD_shader_explicit_vertex_parameter";
   17|      0|    case Extension::kSPV_AMD_shader_fragment_mask:
  ------------------
  |  Branch (17:5): [True: 0, False: 1.60k]
  ------------------
   18|      0|      return "SPV_AMD_shader_fragment_mask";
   19|      0|    case Extension::kSPV_AMD_shader_image_load_store_lod:
  ------------------
  |  Branch (19:5): [True: 0, False: 1.60k]
  ------------------
   20|      0|      return "SPV_AMD_shader_image_load_store_lod";
   21|      0|    case Extension::kSPV_AMD_shader_trinary_minmax:
  ------------------
  |  Branch (21:5): [True: 0, False: 1.60k]
  ------------------
   22|      0|      return "SPV_AMD_shader_trinary_minmax";
   23|      0|    case Extension::kSPV_AMD_texture_gather_bias_lod:
  ------------------
  |  Branch (23:5): [True: 0, False: 1.60k]
  ------------------
   24|      0|      return "SPV_AMD_texture_gather_bias_lod";
   25|      0|    case Extension::kSPV_ARM_core_builtins:
  ------------------
  |  Branch (25:5): [True: 0, False: 1.60k]
  ------------------
   26|      0|      return "SPV_ARM_core_builtins";
   27|      0|    case Extension::kSPV_EXT_demote_to_helper_invocation:
  ------------------
  |  Branch (27:5): [True: 0, False: 1.60k]
  ------------------
   28|      0|      return "SPV_EXT_demote_to_helper_invocation";
   29|      3|    case Extension::kSPV_EXT_descriptor_indexing:
  ------------------
  |  Branch (29:5): [True: 3, False: 1.60k]
  ------------------
   30|      3|      return "SPV_EXT_descriptor_indexing";
   31|      0|    case Extension::kSPV_EXT_fragment_fully_covered:
  ------------------
  |  Branch (31:5): [True: 0, False: 1.60k]
  ------------------
   32|      0|      return "SPV_EXT_fragment_fully_covered";
   33|      1|    case Extension::kSPV_EXT_fragment_invocation_density:
  ------------------
  |  Branch (33:5): [True: 1, False: 1.60k]
  ------------------
   34|      1|      return "SPV_EXT_fragment_invocation_density";
   35|      2|    case Extension::kSPV_EXT_fragment_shader_interlock:
  ------------------
  |  Branch (35:5): [True: 2, False: 1.60k]
  ------------------
   36|      2|      return "SPV_EXT_fragment_shader_interlock";
   37|    518|    case Extension::kSPV_EXT_mesh_shader:
  ------------------
  |  Branch (37:5): [True: 518, False: 1.08k]
  ------------------
   38|    518|      return "SPV_EXT_mesh_shader";
   39|      2|    case Extension::kSPV_EXT_opacity_micromap:
  ------------------
  |  Branch (39:5): [True: 2, False: 1.60k]
  ------------------
   40|      2|      return "SPV_EXT_opacity_micromap";
   41|      0|    case Extension::kSPV_EXT_physical_storage_buffer:
  ------------------
  |  Branch (41:5): [True: 0, False: 1.60k]
  ------------------
   42|      0|      return "SPV_EXT_physical_storage_buffer";
   43|      0|    case Extension::kSPV_EXT_shader_atomic_float16_add:
  ------------------
  |  Branch (43:5): [True: 0, False: 1.60k]
  ------------------
   44|      0|      return "SPV_EXT_shader_atomic_float16_add";
   45|      0|    case Extension::kSPV_EXT_shader_atomic_float_add:
  ------------------
  |  Branch (45:5): [True: 0, False: 1.60k]
  ------------------
   46|      0|      return "SPV_EXT_shader_atomic_float_add";
   47|      0|    case Extension::kSPV_EXT_shader_atomic_float_min_max:
  ------------------
  |  Branch (47:5): [True: 0, False: 1.60k]
  ------------------
   48|      0|      return "SPV_EXT_shader_atomic_float_min_max";
   49|      0|    case Extension::kSPV_EXT_shader_image_int64:
  ------------------
  |  Branch (49:5): [True: 0, False: 1.60k]
  ------------------
   50|      0|      return "SPV_EXT_shader_image_int64";
   51|      0|    case Extension::kSPV_EXT_shader_stencil_export:
  ------------------
  |  Branch (51:5): [True: 0, False: 1.60k]
  ------------------
   52|      0|      return "SPV_EXT_shader_stencil_export";
   53|      0|    case Extension::kSPV_EXT_shader_viewport_index_layer:
  ------------------
  |  Branch (53:5): [True: 0, False: 1.60k]
  ------------------
   54|      0|      return "SPV_EXT_shader_viewport_index_layer";
   55|      1|    case Extension::kSPV_GOOGLE_decorate_string:
  ------------------
  |  Branch (55:5): [True: 1, False: 1.60k]
  ------------------
   56|      1|      return "SPV_GOOGLE_decorate_string";
   57|      2|    case Extension::kSPV_GOOGLE_hlsl_functionality1:
  ------------------
  |  Branch (57:5): [True: 2, False: 1.60k]
  ------------------
   58|      2|      return "SPV_GOOGLE_hlsl_functionality1";
   59|      0|    case Extension::kSPV_GOOGLE_user_type:
  ------------------
  |  Branch (59:5): [True: 0, False: 1.60k]
  ------------------
   60|      0|      return "SPV_GOOGLE_user_type";
   61|      0|    case Extension::kSPV_INTEL_arbitrary_precision_fixed_point:
  ------------------
  |  Branch (61:5): [True: 0, False: 1.60k]
  ------------------
   62|      0|      return "SPV_INTEL_arbitrary_precision_fixed_point";
   63|      0|    case Extension::kSPV_INTEL_arbitrary_precision_floating_point:
  ------------------
  |  Branch (63:5): [True: 0, False: 1.60k]
  ------------------
   64|      0|      return "SPV_INTEL_arbitrary_precision_floating_point";
   65|      0|    case Extension::kSPV_INTEL_arbitrary_precision_integers:
  ------------------
  |  Branch (65:5): [True: 0, False: 1.60k]
  ------------------
   66|      0|      return "SPV_INTEL_arbitrary_precision_integers";
   67|      0|    case Extension::kSPV_INTEL_blocking_pipes:
  ------------------
  |  Branch (67:5): [True: 0, False: 1.60k]
  ------------------
   68|      0|      return "SPV_INTEL_blocking_pipes";
   69|      0|    case Extension::kSPV_INTEL_debug_module:
  ------------------
  |  Branch (69:5): [True: 0, False: 1.60k]
  ------------------
   70|      0|      return "SPV_INTEL_debug_module";
   71|      0|    case Extension::kSPV_INTEL_device_side_avc_motion_estimation:
  ------------------
  |  Branch (71:5): [True: 0, False: 1.60k]
  ------------------
   72|      0|      return "SPV_INTEL_device_side_avc_motion_estimation";
   73|      1|    case Extension::kSPV_INTEL_float_controls2:
  ------------------
  |  Branch (73:5): [True: 1, False: 1.60k]
  ------------------
   74|      1|      return "SPV_INTEL_float_controls2";
   75|      0|    case Extension::kSPV_INTEL_fp_fast_math_mode:
  ------------------
  |  Branch (75:5): [True: 0, False: 1.60k]
  ------------------
   76|      0|      return "SPV_INTEL_fp_fast_math_mode";
   77|      0|    case Extension::kSPV_INTEL_fpga_argument_interfaces:
  ------------------
  |  Branch (77:5): [True: 0, False: 1.60k]
  ------------------
   78|      0|      return "SPV_INTEL_fpga_argument_interfaces";
   79|      0|    case Extension::kSPV_INTEL_fpga_buffer_location:
  ------------------
  |  Branch (79:5): [True: 0, False: 1.60k]
  ------------------
   80|      0|      return "SPV_INTEL_fpga_buffer_location";
   81|      0|    case Extension::kSPV_INTEL_fpga_cluster_attributes:
  ------------------
  |  Branch (81:5): [True: 0, False: 1.60k]
  ------------------
   82|      0|      return "SPV_INTEL_fpga_cluster_attributes";
   83|      0|    case Extension::kSPV_INTEL_fpga_dsp_control:
  ------------------
  |  Branch (83:5): [True: 0, False: 1.60k]
  ------------------
   84|      0|      return "SPV_INTEL_fpga_dsp_control";
   85|      0|    case Extension::kSPV_INTEL_fpga_invocation_pipelining_attributes:
  ------------------
  |  Branch (85:5): [True: 0, False: 1.60k]
  ------------------
   86|      0|      return "SPV_INTEL_fpga_invocation_pipelining_attributes";
   87|      0|    case Extension::kSPV_INTEL_fpga_loop_controls:
  ------------------
  |  Branch (87:5): [True: 0, False: 1.60k]
  ------------------
   88|      0|      return "SPV_INTEL_fpga_loop_controls";
   89|      0|    case Extension::kSPV_INTEL_fpga_memory_accesses:
  ------------------
  |  Branch (89:5): [True: 0, False: 1.60k]
  ------------------
   90|      0|      return "SPV_INTEL_fpga_memory_accesses";
   91|      0|    case Extension::kSPV_INTEL_fpga_memory_attributes:
  ------------------
  |  Branch (91:5): [True: 0, False: 1.60k]
  ------------------
   92|      0|      return "SPV_INTEL_fpga_memory_attributes";
   93|      0|    case Extension::kSPV_INTEL_fpga_reg:
  ------------------
  |  Branch (93:5): [True: 0, False: 1.60k]
  ------------------
   94|      0|      return "SPV_INTEL_fpga_reg";
   95|      0|    case Extension::kSPV_INTEL_function_pointers:
  ------------------
  |  Branch (95:5): [True: 0, False: 1.60k]
  ------------------
   96|      0|      return "SPV_INTEL_function_pointers";
   97|      0|    case Extension::kSPV_INTEL_inline_assembly:
  ------------------
  |  Branch (97:5): [True: 0, False: 1.60k]
  ------------------
   98|      0|      return "SPV_INTEL_inline_assembly";
   99|      0|    case Extension::kSPV_INTEL_io_pipes:
  ------------------
  |  Branch (99:5): [True: 0, False: 1.60k]
  ------------------
  100|      0|      return "SPV_INTEL_io_pipes";
  101|      0|    case Extension::kSPV_INTEL_kernel_attributes:
  ------------------
  |  Branch (101:5): [True: 0, False: 1.60k]
  ------------------
  102|      0|      return "SPV_INTEL_kernel_attributes";
  103|      0|    case Extension::kSPV_INTEL_long_constant_composite:
  ------------------
  |  Branch (103:5): [True: 0, False: 1.60k]
  ------------------
  104|      0|      return "SPV_INTEL_long_constant_composite";
  105|      0|    case Extension::kSPV_INTEL_loop_fuse:
  ------------------
  |  Branch (105:5): [True: 0, False: 1.60k]
  ------------------
  106|      0|      return "SPV_INTEL_loop_fuse";
  107|      0|    case Extension::kSPV_INTEL_media_block_io:
  ------------------
  |  Branch (107:5): [True: 0, False: 1.60k]
  ------------------
  108|      0|      return "SPV_INTEL_media_block_io";
  109|      0|    case Extension::kSPV_INTEL_memory_access_aliasing:
  ------------------
  |  Branch (109:5): [True: 0, False: 1.60k]
  ------------------
  110|      0|      return "SPV_INTEL_memory_access_aliasing";
  111|      0|    case Extension::kSPV_INTEL_optnone:
  ------------------
  |  Branch (111:5): [True: 0, False: 1.60k]
  ------------------
  112|      0|      return "SPV_INTEL_optnone";
  113|      0|    case Extension::kSPV_INTEL_runtime_aligned:
  ------------------
  |  Branch (113:5): [True: 0, False: 1.60k]
  ------------------
  114|      0|      return "SPV_INTEL_runtime_aligned";
  115|      0|    case Extension::kSPV_INTEL_shader_integer_functions2:
  ------------------
  |  Branch (115:5): [True: 0, False: 1.60k]
  ------------------
  116|      0|      return "SPV_INTEL_shader_integer_functions2";
  117|      0|    case Extension::kSPV_INTEL_split_barrier:
  ------------------
  |  Branch (117:5): [True: 0, False: 1.60k]
  ------------------
  118|      0|      return "SPV_INTEL_split_barrier";
  119|      0|    case Extension::kSPV_INTEL_subgroups:
  ------------------
  |  Branch (119:5): [True: 0, False: 1.60k]
  ------------------
  120|      0|      return "SPV_INTEL_subgroups";
  121|      0|    case Extension::kSPV_INTEL_unstructured_loop_controls:
  ------------------
  |  Branch (121:5): [True: 0, False: 1.60k]
  ------------------
  122|      0|      return "SPV_INTEL_unstructured_loop_controls";
  123|      0|    case Extension::kSPV_INTEL_usm_storage_classes:
  ------------------
  |  Branch (123:5): [True: 0, False: 1.60k]
  ------------------
  124|      0|      return "SPV_INTEL_usm_storage_classes";
  125|      0|    case Extension::kSPV_INTEL_variable_length_array:
  ------------------
  |  Branch (125:5): [True: 0, False: 1.60k]
  ------------------
  126|      0|      return "SPV_INTEL_variable_length_array";
  127|      1|    case Extension::kSPV_INTEL_vector_compute:
  ------------------
  |  Branch (127:5): [True: 1, False: 1.60k]
  ------------------
  128|      1|      return "SPV_INTEL_vector_compute";
  129|      3|    case Extension::kSPV_KHR_16bit_storage:
  ------------------
  |  Branch (129:5): [True: 3, False: 1.60k]
  ------------------
  130|      3|      return "SPV_KHR_16bit_storage";
  131|      2|    case Extension::kSPV_KHR_8bit_storage:
  ------------------
  |  Branch (131:5): [True: 2, False: 1.60k]
  ------------------
  132|      2|      return "SPV_KHR_8bit_storage";
  133|      0|    case Extension::kSPV_KHR_bit_instructions:
  ------------------
  |  Branch (133:5): [True: 0, False: 1.60k]
  ------------------
  134|      0|      return "SPV_KHR_bit_instructions";
  135|      0|    case Extension::kSPV_KHR_device_group:
  ------------------
  |  Branch (135:5): [True: 0, False: 1.60k]
  ------------------
  136|      0|      return "SPV_KHR_device_group";
  137|      0|    case Extension::kSPV_KHR_expect_assume:
  ------------------
  |  Branch (137:5): [True: 0, False: 1.60k]
  ------------------
  138|      0|      return "SPV_KHR_expect_assume";
  139|      0|    case Extension::kSPV_KHR_float_controls:
  ------------------
  |  Branch (139:5): [True: 0, False: 1.60k]
  ------------------
  140|      0|      return "SPV_KHR_float_controls";
  141|      3|    case Extension::kSPV_KHR_fragment_shader_barycentric:
  ------------------
  |  Branch (141:5): [True: 3, False: 1.60k]
  ------------------
  142|      3|      return "SPV_KHR_fragment_shader_barycentric";
  143|      0|    case Extension::kSPV_KHR_fragment_shading_rate:
  ------------------
  |  Branch (143:5): [True: 0, False: 1.60k]
  ------------------
  144|      0|      return "SPV_KHR_fragment_shading_rate";
  145|      0|    case Extension::kSPV_KHR_integer_dot_product:
  ------------------
  |  Branch (145:5): [True: 0, False: 1.60k]
  ------------------
  146|      0|      return "SPV_KHR_integer_dot_product";
  147|      0|    case Extension::kSPV_KHR_linkonce_odr:
  ------------------
  |  Branch (147:5): [True: 0, False: 1.60k]
  ------------------
  148|      0|      return "SPV_KHR_linkonce_odr";
  149|      0|    case Extension::kSPV_KHR_multiview:
  ------------------
  |  Branch (149:5): [True: 0, False: 1.60k]
  ------------------
  150|      0|      return "SPV_KHR_multiview";
  151|      0|    case Extension::kSPV_KHR_no_integer_wrap_decoration:
  ------------------
  |  Branch (151:5): [True: 0, False: 1.60k]
  ------------------
  152|      0|      return "SPV_KHR_no_integer_wrap_decoration";
  153|      0|    case Extension::kSPV_KHR_non_semantic_info:
  ------------------
  |  Branch (153:5): [True: 0, False: 1.60k]
  ------------------
  154|      0|      return "SPV_KHR_non_semantic_info";
  155|      0|    case Extension::kSPV_KHR_physical_storage_buffer:
  ------------------
  |  Branch (155:5): [True: 0, False: 1.60k]
  ------------------
  156|      0|      return "SPV_KHR_physical_storage_buffer";
  157|      0|    case Extension::kSPV_KHR_post_depth_coverage:
  ------------------
  |  Branch (157:5): [True: 0, False: 1.60k]
  ------------------
  158|      0|      return "SPV_KHR_post_depth_coverage";
  159|      0|    case Extension::kSPV_KHR_ray_cull_mask:
  ------------------
  |  Branch (159:5): [True: 0, False: 1.60k]
  ------------------
  160|      0|      return "SPV_KHR_ray_cull_mask";
  161|      4|    case Extension::kSPV_KHR_ray_query:
  ------------------
  |  Branch (161:5): [True: 4, False: 1.60k]
  ------------------
  162|      4|      return "SPV_KHR_ray_query";
  163|      4|    case Extension::kSPV_KHR_ray_tracing:
  ------------------
  |  Branch (163:5): [True: 4, False: 1.60k]
  ------------------
  164|      4|      return "SPV_KHR_ray_tracing";
  165|      0|    case Extension::kSPV_KHR_shader_atomic_counter_ops:
  ------------------
  |  Branch (165:5): [True: 0, False: 1.60k]
  ------------------
  166|      0|      return "SPV_KHR_shader_atomic_counter_ops";
  167|      0|    case Extension::kSPV_KHR_shader_ballot:
  ------------------
  |  Branch (167:5): [True: 0, False: 1.60k]
  ------------------
  168|      0|      return "SPV_KHR_shader_ballot";
  169|      0|    case Extension::kSPV_KHR_shader_clock:
  ------------------
  |  Branch (169:5): [True: 0, False: 1.60k]
  ------------------
  170|      0|      return "SPV_KHR_shader_clock";
  171|      0|    case Extension::kSPV_KHR_shader_draw_parameters:
  ------------------
  |  Branch (171:5): [True: 0, False: 1.60k]
  ------------------
  172|      0|      return "SPV_KHR_shader_draw_parameters";
  173|      0|    case Extension::kSPV_KHR_storage_buffer_storage_class:
  ------------------
  |  Branch (173:5): [True: 0, False: 1.60k]
  ------------------
  174|      0|      return "SPV_KHR_storage_buffer_storage_class";
  175|      0|    case Extension::kSPV_KHR_subgroup_rotate:
  ------------------
  |  Branch (175:5): [True: 0, False: 1.60k]
  ------------------
  176|      0|      return "SPV_KHR_subgroup_rotate";
  177|      0|    case Extension::kSPV_KHR_subgroup_uniform_control_flow:
  ------------------
  |  Branch (177:5): [True: 0, False: 1.60k]
  ------------------
  178|      0|      return "SPV_KHR_subgroup_uniform_control_flow";
  179|      0|    case Extension::kSPV_KHR_subgroup_vote:
  ------------------
  |  Branch (179:5): [True: 0, False: 1.60k]
  ------------------
  180|      0|      return "SPV_KHR_subgroup_vote";
  181|      0|    case Extension::kSPV_KHR_terminate_invocation:
  ------------------
  |  Branch (181:5): [True: 0, False: 1.60k]
  ------------------
  182|      0|      return "SPV_KHR_terminate_invocation";
  183|      0|    case Extension::kSPV_KHR_uniform_group_instructions:
  ------------------
  |  Branch (183:5): [True: 0, False: 1.60k]
  ------------------
  184|      0|      return "SPV_KHR_uniform_group_instructions";
  185|      1|    case Extension::kSPV_KHR_variable_pointers:
  ------------------
  |  Branch (185:5): [True: 1, False: 1.60k]
  ------------------
  186|      1|      return "SPV_KHR_variable_pointers";
  187|      0|    case Extension::kSPV_KHR_vulkan_memory_model:
  ------------------
  |  Branch (187:5): [True: 0, False: 1.60k]
  ------------------
  188|      0|      return "SPV_KHR_vulkan_memory_model";
  189|    520|    case Extension::kSPV_KHR_workgroup_memory_explicit_layout:
  ------------------
  |  Branch (189:5): [True: 520, False: 1.08k]
  ------------------
  190|    520|      return "SPV_KHR_workgroup_memory_explicit_layout";
  191|      0|    case Extension::kSPV_NVX_multiview_per_view_attributes:
  ------------------
  |  Branch (191:5): [True: 0, False: 1.60k]
  ------------------
  192|      0|      return "SPV_NVX_multiview_per_view_attributes";
  193|      0|    case Extension::kSPV_NV_bindless_texture:
  ------------------
  |  Branch (193:5): [True: 0, False: 1.60k]
  ------------------
  194|      0|      return "SPV_NV_bindless_texture";
  195|      0|    case Extension::kSPV_NV_compute_shader_derivatives:
  ------------------
  |  Branch (195:5): [True: 0, False: 1.60k]
  ------------------
  196|      0|      return "SPV_NV_compute_shader_derivatives";
  197|      0|    case Extension::kSPV_NV_cooperative_matrix:
  ------------------
  |  Branch (197:5): [True: 0, False: 1.60k]
  ------------------
  198|      0|      return "SPV_NV_cooperative_matrix";
  199|      3|    case Extension::kSPV_NV_fragment_shader_barycentric:
  ------------------
  |  Branch (199:5): [True: 3, False: 1.60k]
  ------------------
  200|      3|      return "SPV_NV_fragment_shader_barycentric";
  201|      0|    case Extension::kSPV_NV_geometry_shader_passthrough:
  ------------------
  |  Branch (201:5): [True: 0, False: 1.60k]
  ------------------
  202|      0|      return "SPV_NV_geometry_shader_passthrough";
  203|      1|    case Extension::kSPV_NV_mesh_shader:
  ------------------
  |  Branch (203:5): [True: 1, False: 1.60k]
  ------------------
  204|      1|      return "SPV_NV_mesh_shader";
  205|      0|    case Extension::kSPV_NV_ray_tracing:
  ------------------
  |  Branch (205:5): [True: 0, False: 1.60k]
  ------------------
  206|      0|      return "SPV_NV_ray_tracing";
  207|      0|    case Extension::kSPV_NV_ray_tracing_motion_blur:
  ------------------
  |  Branch (207:5): [True: 0, False: 1.60k]
  ------------------
  208|      0|      return "SPV_NV_ray_tracing_motion_blur";
  209|      0|    case Extension::kSPV_NV_sample_mask_override_coverage:
  ------------------
  |  Branch (209:5): [True: 0, False: 1.60k]
  ------------------
  210|      0|      return "SPV_NV_sample_mask_override_coverage";
  211|      1|    case Extension::kSPV_NV_shader_image_footprint:
  ------------------
  |  Branch (211:5): [True: 1, False: 1.60k]
  ------------------
  212|      1|      return "SPV_NV_shader_image_footprint";
  213|    517|    case Extension::kSPV_NV_shader_invocation_reorder:
  ------------------
  |  Branch (213:5): [True: 517, False: 1.08k]
  ------------------
  214|    517|      return "SPV_NV_shader_invocation_reorder";
  215|      0|    case Extension::kSPV_NV_shader_sm_builtins:
  ------------------
  |  Branch (215:5): [True: 0, False: 1.60k]
  ------------------
  216|      0|      return "SPV_NV_shader_sm_builtins";
  217|      0|    case Extension::kSPV_NV_shader_subgroup_partitioned:
  ------------------
  |  Branch (217:5): [True: 0, False: 1.60k]
  ------------------
  218|      0|      return "SPV_NV_shader_subgroup_partitioned";
  219|      1|    case Extension::kSPV_NV_shading_rate:
  ------------------
  |  Branch (219:5): [True: 1, False: 1.60k]
  ------------------
  220|      1|      return "SPV_NV_shading_rate";
  221|      9|    case Extension::kSPV_NV_stereo_view_rendering:
  ------------------
  |  Branch (221:5): [True: 9, False: 1.59k]
  ------------------
  222|      9|      return "SPV_NV_stereo_view_rendering";
  223|      3|    case Extension::kSPV_NV_viewport_array2:
  ------------------
  |  Branch (223:5): [True: 3, False: 1.60k]
  ------------------
  224|      3|      return "SPV_NV_viewport_array2";
  225|      0|    case Extension::kSPV_VALIDATOR_ignore_type_decl_unique:
  ------------------
  |  Branch (225:5): [True: 0, False: 1.60k]
  ------------------
  226|      0|      return "SPV_VALIDATOR_ignore_type_decl_unique";
  227|  1.60k|  }
  228|       |
  229|      0|  return "";
  230|  1.60k|}
_ZN8spvtools22GetExtensionFromStringEPKcPNS_9ExtensionE:
  233|  5.42k|    bool GetExtensionFromString(const char* str, Extension* extension) {
  234|  5.42k|        static const char* known_ext_strs[] = { "SPV_AMD_gcn_shader", "SPV_AMD_gpu_shader_half_float", "SPV_AMD_gpu_shader_half_float_fetch", "SPV_AMD_gpu_shader_int16", "SPV_AMD_shader_ballot", "SPV_AMD_shader_early_and_late_fragment_tests", "SPV_AMD_shader_explicit_vertex_parameter", "SPV_AMD_shader_fragment_mask", "SPV_AMD_shader_image_load_store_lod", "SPV_AMD_shader_trinary_minmax", "SPV_AMD_texture_gather_bias_lod", "SPV_ARM_core_builtins", "SPV_EXT_demote_to_helper_invocation", "SPV_EXT_descriptor_indexing", "SPV_EXT_fragment_fully_covered", "SPV_EXT_fragment_invocation_density", "SPV_EXT_fragment_shader_interlock", "SPV_EXT_mesh_shader", "SPV_EXT_opacity_micromap", "SPV_EXT_physical_storage_buffer", "SPV_EXT_shader_atomic_float16_add", "SPV_EXT_shader_atomic_float_add", "SPV_EXT_shader_atomic_float_min_max", "SPV_EXT_shader_image_int64", "SPV_EXT_shader_stencil_export", "SPV_EXT_shader_viewport_index_layer", "SPV_GOOGLE_decorate_string", "SPV_GOOGLE_hlsl_functionality1", "SPV_GOOGLE_user_type", "SPV_INTEL_arbitrary_precision_fixed_point", "SPV_INTEL_arbitrary_precision_floating_point", "SPV_INTEL_arbitrary_precision_integers", "SPV_INTEL_blocking_pipes", "SPV_INTEL_debug_module", "SPV_INTEL_device_side_avc_motion_estimation", "SPV_INTEL_float_controls2", "SPV_INTEL_fp_fast_math_mode", "SPV_INTEL_fpga_argument_interfaces", "SPV_INTEL_fpga_buffer_location", "SPV_INTEL_fpga_cluster_attributes", "SPV_INTEL_fpga_dsp_control", "SPV_INTEL_fpga_invocation_pipelining_attributes", "SPV_INTEL_fpga_loop_controls", "SPV_INTEL_fpga_memory_accesses", "SPV_INTEL_fpga_memory_attributes", "SPV_INTEL_fpga_reg", "SPV_INTEL_function_pointers", "SPV_INTEL_inline_assembly", "SPV_INTEL_io_pipes", "SPV_INTEL_kernel_attributes", "SPV_INTEL_long_constant_composite", "SPV_INTEL_loop_fuse", "SPV_INTEL_media_block_io", "SPV_INTEL_memory_access_aliasing", "SPV_INTEL_optnone", "SPV_INTEL_runtime_aligned", "SPV_INTEL_shader_integer_functions2", "SPV_INTEL_split_barrier", "SPV_INTEL_subgroups", "SPV_INTEL_unstructured_loop_controls", "SPV_INTEL_usm_storage_classes", "SPV_INTEL_variable_length_array", "SPV_INTEL_vector_compute", "SPV_KHR_16bit_storage", "SPV_KHR_8bit_storage", "SPV_KHR_bit_instructions", "SPV_KHR_device_group", "SPV_KHR_expect_assume", "SPV_KHR_float_controls", "SPV_KHR_fragment_shader_barycentric", "SPV_KHR_fragment_shading_rate", "SPV_KHR_integer_dot_product", "SPV_KHR_linkonce_odr", "SPV_KHR_multiview", "SPV_KHR_no_integer_wrap_decoration", "SPV_KHR_non_semantic_info", "SPV_KHR_physical_storage_buffer", "SPV_KHR_post_depth_coverage", "SPV_KHR_ray_cull_mask", "SPV_KHR_ray_query", "SPV_KHR_ray_tracing", "SPV_KHR_shader_atomic_counter_ops", "SPV_KHR_shader_ballot", "SPV_KHR_shader_clock", "SPV_KHR_shader_draw_parameters", "SPV_KHR_storage_buffer_storage_class", "SPV_KHR_subgroup_rotate", "SPV_KHR_subgroup_uniform_control_flow", "SPV_KHR_subgroup_vote", "SPV_KHR_terminate_invocation", "SPV_KHR_uniform_group_instructions", "SPV_KHR_variable_pointers", "SPV_KHR_vulkan_memory_model", "SPV_KHR_workgroup_memory_explicit_layout", "SPV_NVX_multiview_per_view_attributes", "SPV_NV_bindless_texture", "SPV_NV_compute_shader_derivatives", "SPV_NV_cooperative_matrix", "SPV_NV_fragment_shader_barycentric", "SPV_NV_geometry_shader_passthrough", "SPV_NV_mesh_shader", "SPV_NV_ray_tracing", "SPV_NV_ray_tracing_motion_blur", "SPV_NV_sample_mask_override_coverage", "SPV_NV_shader_image_footprint", "SPV_NV_shader_invocation_reorder", "SPV_NV_shader_sm_builtins", "SPV_NV_shader_subgroup_partitioned", "SPV_NV_shading_rate", "SPV_NV_stereo_view_rendering", "SPV_NV_viewport_array2", "SPV_VALIDATOR_ignore_type_decl_unique" };
  235|  5.42k|        static const Extension known_ext_ids[] = { Extension::kSPV_AMD_gcn_shader, Extension::kSPV_AMD_gpu_shader_half_float, Extension::kSPV_AMD_gpu_shader_half_float_fetch, Extension::kSPV_AMD_gpu_shader_int16, Extension::kSPV_AMD_shader_ballot, Extension::kSPV_AMD_shader_early_and_late_fragment_tests, Extension::kSPV_AMD_shader_explicit_vertex_parameter, Extension::kSPV_AMD_shader_fragment_mask, Extension::kSPV_AMD_shader_image_load_store_lod, Extension::kSPV_AMD_shader_trinary_minmax, Extension::kSPV_AMD_texture_gather_bias_lod, Extension::kSPV_ARM_core_builtins, Extension::kSPV_EXT_demote_to_helper_invocation, Extension::kSPV_EXT_descriptor_indexing, Extension::kSPV_EXT_fragment_fully_covered, Extension::kSPV_EXT_fragment_invocation_density, Extension::kSPV_EXT_fragment_shader_interlock, Extension::kSPV_EXT_mesh_shader, Extension::kSPV_EXT_opacity_micromap, Extension::kSPV_EXT_physical_storage_buffer, Extension::kSPV_EXT_shader_atomic_float16_add, Extension::kSPV_EXT_shader_atomic_float_add, Extension::kSPV_EXT_shader_atomic_float_min_max, Extension::kSPV_EXT_shader_image_int64, Extension::kSPV_EXT_shader_stencil_export, Extension::kSPV_EXT_shader_viewport_index_layer, Extension::kSPV_GOOGLE_decorate_string, Extension::kSPV_GOOGLE_hlsl_functionality1, Extension::kSPV_GOOGLE_user_type, Extension::kSPV_INTEL_arbitrary_precision_fixed_point, Extension::kSPV_INTEL_arbitrary_precision_floating_point, Extension::kSPV_INTEL_arbitrary_precision_integers, Extension::kSPV_INTEL_blocking_pipes, Extension::kSPV_INTEL_debug_module, Extension::kSPV_INTEL_device_side_avc_motion_estimation, Extension::kSPV_INTEL_float_controls2, Extension::kSPV_INTEL_fp_fast_math_mode, Extension::kSPV_INTEL_fpga_argument_interfaces, Extension::kSPV_INTEL_fpga_buffer_location, Extension::kSPV_INTEL_fpga_cluster_attributes, Extension::kSPV_INTEL_fpga_dsp_control, Extension::kSPV_INTEL_fpga_invocation_pipelining_attributes, Extension::kSPV_INTEL_fpga_loop_controls, Extension::kSPV_INTEL_fpga_memory_accesses, Extension::kSPV_INTEL_fpga_memory_attributes, Extension::kSPV_INTEL_fpga_reg, Extension::kSPV_INTEL_function_pointers, Extension::kSPV_INTEL_inline_assembly, Extension::kSPV_INTEL_io_pipes, Extension::kSPV_INTEL_kernel_attributes, Extension::kSPV_INTEL_long_constant_composite, Extension::kSPV_INTEL_loop_fuse, Extension::kSPV_INTEL_media_block_io, Extension::kSPV_INTEL_memory_access_aliasing, Extension::kSPV_INTEL_optnone, Extension::kSPV_INTEL_runtime_aligned, Extension::kSPV_INTEL_shader_integer_functions2, Extension::kSPV_INTEL_split_barrier, Extension::kSPV_INTEL_subgroups, Extension::kSPV_INTEL_unstructured_loop_controls, Extension::kSPV_INTEL_usm_storage_classes, Extension::kSPV_INTEL_variable_length_array, Extension::kSPV_INTEL_vector_compute, Extension::kSPV_KHR_16bit_storage, Extension::kSPV_KHR_8bit_storage, Extension::kSPV_KHR_bit_instructions, Extension::kSPV_KHR_device_group, Extension::kSPV_KHR_expect_assume, Extension::kSPV_KHR_float_controls, Extension::kSPV_KHR_fragment_shader_barycentric, Extension::kSPV_KHR_fragment_shading_rate, Extension::kSPV_KHR_integer_dot_product, Extension::kSPV_KHR_linkonce_odr, Extension::kSPV_KHR_multiview, Extension::kSPV_KHR_no_integer_wrap_decoration, Extension::kSPV_KHR_non_semantic_info, Extension::kSPV_KHR_physical_storage_buffer, Extension::kSPV_KHR_post_depth_coverage, Extension::kSPV_KHR_ray_cull_mask, Extension::kSPV_KHR_ray_query, Extension::kSPV_KHR_ray_tracing, Extension::kSPV_KHR_shader_atomic_counter_ops, Extension::kSPV_KHR_shader_ballot, Extension::kSPV_KHR_shader_clock, Extension::kSPV_KHR_shader_draw_parameters, Extension::kSPV_KHR_storage_buffer_storage_class, Extension::kSPV_KHR_subgroup_rotate, Extension::kSPV_KHR_subgroup_uniform_control_flow, Extension::kSPV_KHR_subgroup_vote, Extension::kSPV_KHR_terminate_invocation, Extension::kSPV_KHR_uniform_group_instructions, Extension::kSPV_KHR_variable_pointers, Extension::kSPV_KHR_vulkan_memory_model, Extension::kSPV_KHR_workgroup_memory_explicit_layout, Extension::kSPV_NVX_multiview_per_view_attributes, Extension::kSPV_NV_bindless_texture, Extension::kSPV_NV_compute_shader_derivatives, Extension::kSPV_NV_cooperative_matrix, Extension::kSPV_NV_fragment_shader_barycentric, Extension::kSPV_NV_geometry_shader_passthrough, Extension::kSPV_NV_mesh_shader, Extension::kSPV_NV_ray_tracing, Extension::kSPV_NV_ray_tracing_motion_blur, Extension::kSPV_NV_sample_mask_override_coverage, Extension::kSPV_NV_shader_image_footprint, Extension::kSPV_NV_shader_invocation_reorder, Extension::kSPV_NV_shader_sm_builtins, Extension::kSPV_NV_shader_subgroup_partitioned, Extension::kSPV_NV_shading_rate, Extension::kSPV_NV_stereo_view_rendering, Extension::kSPV_NV_viewport_array2, Extension::kSPV_VALIDATOR_ignore_type_decl_unique };
  236|  5.42k|        const auto b = std::begin(known_ext_strs);
  237|  5.42k|        const auto e = std::end(known_ext_strs);
  238|  5.42k|        const auto found = std::equal_range(
  239|  5.42k|            b, e, str, [](const char* str1, const char* str2) {
  240|  5.42k|                return std::strcmp(str1, str2) < 0;
  241|  5.42k|            });
  242|  5.42k|        if (found.first == e || found.first == found.second) return false;
  ------------------
  |  Branch (242:13): [True: 807, False: 4.62k]
  |  Branch (242:33): [True: 2.96k, False: 1.65k]
  ------------------
  243|       |
  244|  1.65k|        *extension = known_ext_ids[found.first - b];
  245|  1.65k|        return true;
  246|  5.42k|    }
enum_string_mapping.cpp:_ZZN8spvtools22GetExtensionFromStringEPKcPNS_9ExtensionEENK3$_0clES1_S1_:
  239|  63.4k|            b, e, str, [](const char* str1, const char* str2) {
  240|  63.4k|                return std::strcmp(str1, str2) < 0;
  241|  63.4k|            });

_ZN3spvorENS_19MemorySemanticsMaskES0_:
 2686|  1.48k|inline MemorySemanticsMask operator|(MemorySemanticsMask a, MemorySemanticsMask b) { return MemorySemanticsMask(unsigned(a) | unsigned(b)); }

_ZNK8spvtools15AssemblyGrammar7isValidEv:
  171|  4.45k|bool AssemblyGrammar::isValid() const {
  172|  4.45k|  return operandTable_ && opcodeTable_ && extInstTable_;
  ------------------
  |  Branch (172:10): [True: 4.45k, False: 0]
  |  Branch (172:27): [True: 4.45k, False: 0]
  |  Branch (172:43): [True: 4.45k, False: 0]
  ------------------
  173|  4.45k|}
_ZNK8spvtools15AssemblyGrammar26filterCapsAgainstTargetEnvEPKN3spv10CapabilityEj:
  176|   454k|    const spv::Capability* cap_array, uint32_t count) const {
  177|   454k|  CapabilitySet cap_set;
  178|   500k|  for (uint32_t i = 0; i < count; ++i) {
  ------------------
  |  Branch (178:24): [True: 45.7k, False: 454k]
  ------------------
  179|  45.7k|    spv_operand_desc cap_desc = {};
  180|  45.7k|    if (SPV_SUCCESS == lookupOperand(SPV_OPERAND_TYPE_CAPABILITY,
  ------------------
  |  Branch (180:9): [True: 45.4k, False: 297]
  ------------------
  181|  45.7k|                                     static_cast<uint32_t>(cap_array[i]),
  182|  45.7k|                                     &cap_desc)) {
  183|       |      // spvOperandTableValueLookup() filters capabilities internally
  184|       |      // according to the current target environment by itself. So we
  185|       |      // should be safe to add this capability if the lookup succeeds.
  186|  45.4k|      cap_set.Add(cap_array[i]);
  187|  45.4k|    }
  188|  45.7k|  }
  189|   454k|  return cap_set;
  190|   454k|}
_ZNK8spvtools15AssemblyGrammar12lookupOpcodeEN3spv2OpEPPK17spv_opcode_desc_t:
  198|  2.73M|                                           spv_opcode_desc* desc) const {
  199|  2.73M|  return spvOpcodeTableValueLookup(target_env_, opcodeTable_, opcode, desc);
  200|  2.73M|}
_ZNK8spvtools15AssemblyGrammar13lookupOperandE18spv_operand_type_tjPPK18spv_operand_desc_t:
  211|  1.06M|                                            spv_operand_desc* desc) const {
  212|  1.06M|  return spvOperandTableValueLookup(target_env_, operandTable_, type, operand,
  213|  1.06M|                                    desc);
  214|  1.06M|}
_ZNK8spvtools15AssemblyGrammar24lookupSpecConstantOpcodeEN3spv2OpE:
  229|    195|spv_result_t AssemblyGrammar::lookupSpecConstantOpcode(spv::Op opcode) const {
  230|    195|  const auto* last = kOpSpecConstantOpcodes + kNumOpSpecConstantOpcodes;
  231|    195|  const auto* found =
  232|    195|      std::find_if(kOpSpecConstantOpcodes, last,
  233|    195|                   [opcode](const SpecConstantOpcodeEntry& entry) {
  234|    195|                     return opcode == entry.opcode;
  235|    195|                   });
  236|    195|  if (found == last) return SPV_ERROR_INVALID_LOOKUP;
  ------------------
  |  Branch (236:7): [True: 39, False: 156]
  ------------------
  237|    156|  return SPV_SUCCESS;
  238|    195|}
_ZNK8spvtools15AssemblyGrammar13lookupExtInstE19spv_ext_inst_type_tjPPK19spv_ext_inst_desc_t:
  254|  16.2k|                                            spv_ext_inst_desc* extInst) const {
  255|  16.2k|  return spvExtInstTableValueLookup(extInstTable_, type, firstWord, extInst);
  256|  16.2k|}
assembly_grammar.cpp:_ZZNK8spvtools15AssemblyGrammar24lookupSpecConstantOpcodeEN3spv2OpEENK3$_1clERKNS_12_GLOBAL__N_123SpecConstantOpcodeEntryE:
  233|  6.46k|                   [opcode](const SpecConstantOpcodeEntry& entry) {
  234|  6.46k|                     return opcode == entry.opcode;
  235|  6.46k|                   });

_ZN8spvtools15AssemblyGrammarC2EPK13spv_context_t:
   34|  65.4k|        extInstTable_(context->ext_inst_table) {}
_ZNK8spvtools15AssemblyGrammar17lookupOperandNameE18spv_operand_type_tj:
   72|      1|                                uint32_t operand) const {
   73|      1|    spv_operand_desc desc = nullptr;
   74|      1|    if (lookupOperand(type, operand, &desc) != SPV_SUCCESS || !desc) {
  ------------------
  |  Branch (74:9): [True: 0, False: 1]
  |  Branch (74:63): [True: 0, False: 1]
  ------------------
   75|      0|      return "Unknown";
   76|      0|    }
   77|      1|    return desc->name;
   78|      1|  }

_Z18spvBinaryHeaderGetP18spv_const_binary_t16spv_endianness_tP12spv_header_t:
   40|  48.1k|                                spv_header_t* pHeader) {
   41|  48.1k|  if (!binary->code) return SPV_ERROR_INVALID_BINARY;
  ------------------
  |  Branch (41:7): [True: 0, False: 48.1k]
  ------------------
   42|  48.1k|  if (binary->wordCount < SPV_INDEX_INSTRUCTION)
  ------------------
  |  |   39|  48.1k|#define SPV_INDEX_INSTRUCTION 5u
  ------------------
  |  Branch (42:7): [True: 6, False: 48.1k]
  ------------------
   43|      6|    return SPV_ERROR_INVALID_BINARY;
   44|  48.1k|  if (!pHeader) return SPV_ERROR_INVALID_POINTER;
  ------------------
  |  Branch (44:7): [True: 0, False: 48.1k]
  ------------------
   45|       |
   46|       |  // TODO: Validation checking?
   47|  48.1k|  pHeader->magic = spvFixWord(binary->code[SPV_INDEX_MAGIC_NUMBER], endian);
  ------------------
  |  |   34|  48.1k|#define SPV_INDEX_MAGIC_NUMBER 0u
  ------------------
   48|  48.1k|  pHeader->version = spvFixWord(binary->code[SPV_INDEX_VERSION_NUMBER], endian);
  ------------------
  |  |   35|  48.1k|#define SPV_INDEX_VERSION_NUMBER 1u
  ------------------
   49|       |  // Per 2.3.1 version's high and low bytes are 0
   50|  48.1k|  if ((pHeader->version & 0x000000ff) || pHeader->version & 0xff000000)
  ------------------
  |  Branch (50:7): [True: 24, False: 48.0k]
  |  Branch (50:42): [True: 39, False: 48.0k]
  ------------------
   51|     63|    return SPV_ERROR_INVALID_BINARY;
   52|       |  // Minimum version was 1.0 and max version is defined by SPV_VERSION.
   53|  48.0k|  if (pHeader->version < SPV_SPIRV_VERSION_WORD(1, 0) ||
  ------------------
  |  |   26|  96.0k|  ((uint32_t(uint8_t(MAJOR)) << 16) | (uint32_t(uint8_t(MINOR)) << 8))
  ------------------
  |  Branch (53:7): [True: 24, False: 48.0k]
  ------------------
   54|  48.0k|      pHeader->version > SPV_VERSION)
  ------------------
  |  |   54|  48.0k|#define SPV_VERSION 0x10600
  ------------------
  |  Branch (54:7): [True: 63, False: 47.9k]
  ------------------
   55|     87|    return SPV_ERROR_INVALID_BINARY;
   56|       |
   57|  47.9k|  pHeader->generator =
   58|  47.9k|      spvFixWord(binary->code[SPV_INDEX_GENERATOR_NUMBER], endian);
  ------------------
  |  |   36|  47.9k|#define SPV_INDEX_GENERATOR_NUMBER 2u
  ------------------
   59|  47.9k|  pHeader->bound = spvFixWord(binary->code[SPV_INDEX_BOUND], endian);
  ------------------
  |  |   37|  47.9k|#define SPV_INDEX_BOUND 3u
  ------------------
   60|  47.9k|  pHeader->schema = spvFixWord(binary->code[SPV_INDEX_SCHEMA], endian);
  ------------------
  |  |   38|  47.9k|#define SPV_INDEX_SCHEMA 4u
  ------------------
   61|  47.9k|  pHeader->instructions = &binary->code[SPV_INDEX_INSTRUCTION];
  ------------------
  |  |   39|  47.9k|#define SPV_INDEX_INSTRUCTION 5u
  ------------------
   62|       |
   63|  47.9k|  return SPV_SUCCESS;
   64|  48.0k|}
_Z29spvDecodeLiteralStringOperandRK24spv_parsed_instruction_tt:
   67|  12.0k|                                          const uint16_t operand_index) {
   68|  12.0k|  assert(operand_index < inst.num_operands);
   69|      0|  const spv_parsed_operand_t& operand = inst.operands[operand_index];
   70|       |
   71|  12.0k|  return spvtools::utils::MakeString(inst.words + operand.offset,
   72|  12.0k|                                     operand.num_words);
   73|  12.0k|}
spvBinaryParse:
  815|  40.0k|                            spv_diagnostic* diagnostic) {
  816|  40.0k|  spv_context_t hijack_context = *context;
  817|  40.0k|  if (diagnostic) {
  ------------------
  |  Branch (817:7): [True: 12.6k, False: 27.4k]
  ------------------
  818|  12.6k|    *diagnostic = nullptr;
  819|  12.6k|    spvtools::UseDiagnosticAsMessageConsumer(&hijack_context, diagnostic);
  820|  12.6k|  }
  821|  40.0k|  Parser parser(&hijack_context, user_data, parsed_header, parsed_instruction);
  822|  40.0k|  return parser.parse(code, num_words, diagnostic);
  823|  40.0k|}
binary.cpp:_ZN12_GLOBAL__N_16ParserC2EPK13spv_context_tPvPF12spv_result_tS4_16spv_endianness_tjjjjjEPFS5_S4_PK24spv_parsed_instruction_tE:
   89|  40.0k|        parsed_instruction_fn_(parsed_instruction_fn) {}
binary.cpp:_ZN12_GLOBAL__N_16Parser5StateC2Ev:
  211|  80.1k|    State() : State(0, 0, nullptr) {}
binary.cpp:_ZN12_GLOBAL__N_16Parser5StateC2EPKjmPP16spv_diagnostic_t:
  204|   120k|          requires_endian_conversion(false) {
  205|       |      // Temporary storage for parser state within a single instruction.
  206|       |      // Most instructions require fewer than 25 words or operands.
  207|   120k|      operands.reserve(25);
  208|   120k|      endian_converted_words.reserve(25);
  209|   120k|      expected_operands.reserve(25);
  210|   120k|    }
binary.cpp:_ZN12_GLOBAL__N_16Parser5parseEPKjmPP16spv_diagnostic_t:
  240|  40.0k|                           spv_diagnostic* diagnostic_arg) {
  241|  40.0k|  _ = State(words, num_words, diagnostic_arg);
  242|       |
  243|  40.0k|  const spv_result_t result = parseModule();
  244|       |
  245|       |  // Clear the module state.  The tables might be big.
  246|  40.0k|  _ = State();
  247|       |
  248|  40.0k|  return result;
  249|  40.0k|}
binary.cpp:_ZN12_GLOBAL__N_16Parser11parseModuleEv:
  251|  40.0k|spv_result_t Parser::parseModule() {
  252|  40.0k|  if (!_.words) return diagnostic() << "Missing module.";
  ------------------
  |  Branch (252:7): [True: 3, False: 40.0k]
  ------------------
  253|       |
  254|  40.0k|  if (_.num_words < SPV_INDEX_INSTRUCTION)
  ------------------
  |  |   39|  40.0k|#define SPV_INDEX_INSTRUCTION 5u
  ------------------
  |  Branch (254:7): [True: 118, False: 39.9k]
  ------------------
  255|    118|    return diagnostic() << "Module has incomplete header: only " << _.num_words
  256|    118|                        << " words instead of " << SPV_INDEX_INSTRUCTION;
  ------------------
  |  |   39|    118|#define SPV_INDEX_INSTRUCTION 5u
  ------------------
  257|       |
  258|       |  // Check the magic number and detect the module's endianness.
  259|  39.9k|  spv_const_binary_t binary{_.words, _.num_words};
  260|  39.9k|  if (spvBinaryEndianness(&binary, &_.endian)) {
  ------------------
  |  Branch (260:7): [True: 30, False: 39.9k]
  ------------------
  261|     30|    return diagnostic() << "Invalid SPIR-V magic number '" << std::hex
  262|     30|                        << _.words[0] << "'.";
  263|     30|  }
  264|  39.9k|  _.requires_endian_conversion = !spvIsHostEndian(_.endian);
  265|       |
  266|       |  // Process the header.
  267|  39.9k|  spv_header_t header;
  268|  39.9k|  if (spvBinaryHeaderGet(&binary, _.endian, &header)) {
  ------------------
  |  Branch (268:7): [True: 100, False: 39.8k]
  ------------------
  269|       |    // It turns out there is no way to trigger this error since the only
  270|       |    // failure cases are already handled above, with better messages.
  271|    100|    return diagnostic(SPV_ERROR_INTERNAL)
  272|    100|           << "Internal error: unhandled header parse failure";
  273|    100|  }
  274|  39.8k|  if (parsed_header_fn_) {
  ------------------
  |  Branch (274:7): [True: 12.5k, False: 27.2k]
  ------------------
  275|  12.5k|    if (auto error = parsed_header_fn_(user_data_, _.endian, header.magic,
  ------------------
  |  Branch (275:14): [True: 0, False: 12.5k]
  ------------------
  276|  12.5k|                                       header.version, header.generator,
  277|  12.5k|                                       header.bound, header.schema)) {
  278|      0|      return error;
  279|      0|    }
  280|  12.5k|  }
  281|       |
  282|       |  // Process the instructions.
  283|  39.8k|  _.word_index = SPV_INDEX_INSTRUCTION;
  ------------------
  |  |   39|  39.8k|#define SPV_INDEX_INSTRUCTION 5u
  ------------------
  284|  1.98M|  while (_.word_index < _.num_words)
  ------------------
  |  Branch (284:10): [True: 1.95M, False: 25.4k]
  ------------------
  285|  1.95M|    if (auto error = parseInstruction()) return error;
  ------------------
  |  Branch (285:14): [True: 14.3k, False: 1.94M]
  ------------------
  286|       |
  287|       |  // Running off the end should already have been reported earlier.
  288|  25.4k|  assert(_.word_index == _.num_words);
  289|       |
  290|      0|  return SPV_SUCCESS;
  291|  39.8k|}
binary.cpp:_ZN12_GLOBAL__N_16Parser10diagnosticEv:
  151|  3.08k|  spvtools::DiagnosticStream diagnostic() {
  152|       |    // The default failure for parsing is invalid binary.
  153|  3.08k|    return diagnostic(SPV_ERROR_INVALID_BINARY);
  154|  3.08k|  }
binary.cpp:_ZN12_GLOBAL__N_16Parser10diagnosticE12spv_result_t:
  145|  3.37k|  spvtools::DiagnosticStream diagnostic(spv_result_t error) {
  146|  3.37k|    return spvtools::DiagnosticStream({0, 0, _.instruction_count}, consumer_,
  147|  3.37k|                                      "", error);
  148|  3.37k|  }
binary.cpp:_ZN12_GLOBAL__N_16Parser16parseInstructionEv:
  293|  1.95M|spv_result_t Parser::parseInstruction() {
  294|  1.95M|  _.instruction_count++;
  295|       |
  296|       |  // The zero values for all members except for opcode are the
  297|       |  // correct initial values.
  298|  1.95M|  spv_parsed_instruction_t inst = {};
  299|       |
  300|  1.95M|  const uint32_t first_word = peek();
  301|       |
  302|       |  // If the module's endianness is different from the host native endianness,
  303|       |  // then converted_words contains the endian-translated words in the
  304|       |  // instruction.
  305|  1.95M|  _.endian_converted_words.clear();
  306|  1.95M|  _.endian_converted_words.push_back(first_word);
  307|       |
  308|       |  // After a successful parse of the instruction, the inst.operands member
  309|       |  // will point to this vector's storage.
  310|  1.95M|  _.operands.clear();
  311|       |
  312|  1.95M|  assert(_.word_index < _.num_words);
  313|       |  // Decompose and check the first word.
  314|      0|  uint16_t inst_word_count = 0;
  315|  1.95M|  spvOpcodeSplit(first_word, &inst_word_count, &inst.opcode);
  316|  1.95M|  if (inst_word_count < 1) {
  ------------------
  |  Branch (316:7): [True: 70, False: 1.95M]
  ------------------
  317|     70|    return diagnostic() << "Invalid instruction word count: "
  318|     70|                        << inst_word_count;
  319|     70|  }
  320|  1.95M|  spv_opcode_desc opcode_desc;
  321|  1.95M|  if (grammar_.lookupOpcode(static_cast<spv::Op>(inst.opcode), &opcode_desc))
  ------------------
  |  Branch (321:7): [True: 224, False: 1.95M]
  ------------------
  322|    224|    return diagnostic() << "Invalid opcode: " << inst.opcode;
  323|       |
  324|       |  // Advance past the opcode word.  But remember the of the start
  325|       |  // of the instruction.
  326|  1.95M|  const size_t inst_offset = _.word_index;
  327|  1.95M|  _.word_index++;
  328|       |
  329|       |  // Maintains the ordered list of expected operand types.
  330|       |  // For many instructions we only need the {numTypes, operandTypes}
  331|       |  // entries in opcode_desc.  However, sometimes we need to modify
  332|       |  // the list as we parse the operands. This occurs when an operand
  333|       |  // has its own logical operands (such as the LocalSize operand for
  334|       |  // ExecutionMode), or for extended instructions that may have their
  335|       |  // own operands depending on the selected extended instruction.
  336|  1.95M|  _.expected_operands.clear();
  337|  6.53M|  for (auto i = 0; i < opcode_desc->numTypes; i++)
  ------------------
  |  Branch (337:20): [True: 4.57M, False: 1.95M]
  ------------------
  338|  4.57M|    _.expected_operands.push_back(
  339|  4.57M|        opcode_desc->operandTypes[opcode_desc->numTypes - i - 1]);
  340|       |
  341|  9.67M|  while (_.word_index < inst_offset + inst_word_count) {
  ------------------
  |  Branch (341:10): [True: 7.72M, False: 1.95M]
  ------------------
  342|  7.72M|    const uint16_t inst_word_index = uint16_t(_.word_index - inst_offset);
  343|  7.72M|    if (_.expected_operands.empty()) {
  ------------------
  |  Branch (343:9): [True: 375, False: 7.72M]
  ------------------
  344|    375|      return diagnostic() << "Invalid instruction Op" << opcode_desc->name
  345|    375|                          << " starting at word " << inst_offset
  346|    375|                          << ": expected no more operands after "
  347|    375|                          << inst_word_index
  348|    375|                          << " words, but stated word count is "
  349|    375|                          << inst_word_count << ".";
  350|    375|    }
  351|       |
  352|  7.72M|    spv_operand_type_t type =
  353|  7.72M|        spvTakeFirstMatchableOperand(&_.expected_operands);
  354|       |
  355|  7.72M|    if (auto error =
  ------------------
  |  Branch (355:14): [True: 2.31k, False: 7.71M]
  ------------------
  356|  7.72M|            parseOperand(inst_offset, &inst, type, &_.endian_converted_words,
  357|  7.72M|                         &_.operands, &_.expected_operands)) {
  358|  2.31k|      return error;
  359|  2.31k|    }
  360|  7.72M|  }
  361|       |
  362|  1.95M|  if (!_.expected_operands.empty() &&
  ------------------
  |  Branch (362:7): [True: 561k, False: 1.39M]
  ------------------
  363|  1.95M|      !spvOperandIsOptional(_.expected_operands.back())) {
  ------------------
  |  Branch (363:7): [True: 61, False: 561k]
  ------------------
  364|     61|    return diagnostic() << "End of input reached while decoding Op"
  365|     61|                        << opcode_desc->name << " starting at word "
  366|     61|                        << inst_offset << ": expected more operands after "
  367|     61|                        << inst_word_count << " words.";
  368|     61|  }
  369|       |
  370|  1.95M|  if ((inst_offset + inst_word_count) != _.word_index) {
  ------------------
  |  Branch (370:7): [True: 87, False: 1.95M]
  ------------------
  371|     87|    return diagnostic() << "Invalid word count: Op" << opcode_desc->name
  372|     87|                        << " starting at word " << inst_offset
  373|     87|                        << " says it has " << inst_word_count
  374|     87|                        << " words, but found " << _.word_index - inst_offset
  375|     87|                        << " words instead.";
  376|     87|  }
  377|       |
  378|       |  // Check the computed length of the endian-converted words vector against
  379|       |  // the declared number of words in the instruction.  If endian conversion
  380|       |  // is required, then they should match.  If no endian conversion was
  381|       |  // performed, then the vector only contains the initial opcode/word-count
  382|       |  // word.
  383|  1.95M|  assert(!_.requires_endian_conversion ||
  384|  1.95M|         (inst_word_count == _.endian_converted_words.size()));
  385|      0|  assert(_.requires_endian_conversion ||
  386|  1.95M|         (_.endian_converted_words.size() == 1));
  387|       |
  388|      0|  recordNumberType(inst_offset, &inst);
  389|       |
  390|  1.95M|  if (_.requires_endian_conversion) {
  ------------------
  |  Branch (390:7): [True: 301k, False: 1.65M]
  ------------------
  391|       |    // We must wait until here to set this pointer, because the vector might
  392|       |    // have been be resized while we accumulated its elements.
  393|   301k|    inst.words = _.endian_converted_words.data();
  394|  1.65M|  } else {
  395|       |    // If no conversion is required, then just point to the underlying binary.
  396|       |    // This saves time and space.
  397|  1.65M|    inst.words = _.words + inst_offset;
  398|  1.65M|  }
  399|  1.95M|  inst.num_words = inst_word_count;
  400|       |
  401|       |  // We must wait until here to set this pointer, because the vector might
  402|       |  // have been be resized while we accumulated its elements.
  403|  1.95M|  inst.operands = _.operands.data();
  404|  1.95M|  inst.num_operands = uint16_t(_.operands.size());
  405|       |
  406|       |  // Issue the callback.  The callee should know that all the storage in inst
  407|       |  // is transient, and will disappear immediately afterward.
  408|  1.95M|  if (parsed_instruction_fn_) {
  ------------------
  |  Branch (408:7): [True: 1.95M, False: 0]
  ------------------
  409|  1.95M|    if (auto error = parsed_instruction_fn_(user_data_, &inst)) return error;
  ------------------
  |  Branch (409:14): [True: 11.2k, False: 1.94M]
  ------------------
  410|  1.95M|  }
  411|       |
  412|  1.94M|  return SPV_SUCCESS;
  413|  1.95M|}
binary.cpp:_ZNK12_GLOBAL__N_16Parser4peekEv:
  171|  9.67M|  uint32_t peek() const { return peekAt(_.word_index); }
binary.cpp:_ZNK12_GLOBAL__N_16Parser6peekAtEm:
  174|  9.82M|  uint32_t peekAt(size_t index) const {
  175|  9.82M|    assert(index < _.num_words);
  176|      0|    return spvFixWord(_.words[index], _.endian);
  177|  9.82M|  }
binary.cpp:_ZN12_GLOBAL__N_16Parser12parseOperandEmP24spv_parsed_instruction_t18spv_operand_type_tPNSt3__16vectorIjNS4_9allocatorIjEEEEPNS5_I20spv_parsed_operand_tNS6_ISA_EEEEPNS5_IS3_NS6_IS3_EEEE:
  420|  7.72M|                                  spv_operand_pattern_t* expected_operands) {
  421|  7.72M|  const spv::Op opcode = static_cast<spv::Op>(inst->opcode);
  422|       |  // We'll fill in this result as we go along.
  423|  7.72M|  spv_parsed_operand_t parsed_operand;
  424|  7.72M|  parsed_operand.offset = uint16_t(_.word_index - inst_offset);
  425|       |  // Most operands occupy one word.  This might be be adjusted later.
  426|  7.72M|  parsed_operand.num_words = 1;
  427|       |  // The type argument is the one used by the grammar to parse the instruction.
  428|       |  // But it can exposes internal parser details such as whether an operand is
  429|       |  // optional or actually represents a variable-length sequence of operands.
  430|       |  // The resulting type should be adjusted to avoid those internal details.
  431|       |  // In most cases, the resulting operand type is the same as the grammar type.
  432|  7.72M|  parsed_operand.type = type;
  433|       |
  434|       |  // Assume non-numeric values.  This will be updated for literal numbers.
  435|  7.72M|  parsed_operand.number_kind = SPV_NUMBER_NONE;
  436|  7.72M|  parsed_operand.number_bit_width = 0;
  437|       |
  438|  7.72M|  if (_.word_index >= _.num_words)
  ------------------
  |  Branch (438:7): [True: 575, False: 7.71M]
  ------------------
  439|    575|    return exhaustedInputDiagnostic(inst_offset, opcode, type);
  440|       |
  441|  7.71M|  const uint32_t word = peek();
  442|       |
  443|       |  // Do the words in this operand have to be converted to native endianness?
  444|       |  // True for all but literal strings.
  445|  7.71M|  bool convert_operand_endianness = true;
  446|       |
  447|  7.71M|  switch (type) {
  448|   515k|    case SPV_OPERAND_TYPE_TYPE_ID:
  ------------------
  |  Branch (448:5): [True: 515k, False: 7.20M]
  ------------------
  449|   515k|      if (!word)
  ------------------
  |  Branch (449:11): [True: 9, False: 515k]
  ------------------
  450|      9|        return diagnostic(SPV_ERROR_INVALID_ID) << "Error: Type Id is 0";
  451|   515k|      inst->type_id = word;
  452|   515k|      break;
  453|       |
  454|   881k|    case SPV_OPERAND_TYPE_RESULT_ID:
  ------------------
  |  Branch (454:5): [True: 881k, False: 6.83M]
  ------------------
  455|   881k|      if (!word)
  ------------------
  |  Branch (455:11): [True: 12, False: 881k]
  ------------------
  456|     12|        return diagnostic(SPV_ERROR_INVALID_ID) << "Error: Result Id is 0";
  457|   881k|      inst->result_id = word;
  458|       |      // Save the result ID to type ID mapping.
  459|       |      // In the grammar, type ID always appears before result ID.
  460|   881k|      if (_.id_to_type_id.find(inst->result_id) != _.id_to_type_id.end())
  ------------------
  |  Branch (460:11): [True: 6, False: 881k]
  ------------------
  461|      6|        return diagnostic(SPV_ERROR_INVALID_ID)
  462|      6|               << "Id " << inst->result_id << " is defined more than once";
  463|       |      // Record it.
  464|       |      // A regular value maps to its type.  Some instructions (e.g. OpLabel)
  465|       |      // have no type Id, and will map to 0.  The result Id for a
  466|       |      // type-generating instruction (e.g. OpTypeInt) maps to itself.
  467|   881k|      _.id_to_type_id[inst->result_id] =
  468|   881k|          spvOpcodeGeneratesType(opcode) ? inst->result_id : inst->type_id;
  ------------------
  |  Branch (468:11): [True: 136k, False: 745k]
  ------------------
  469|   881k|      break;
  470|       |
  471|  1.80M|    case SPV_OPERAND_TYPE_ID:
  ------------------
  |  Branch (471:5): [True: 1.80M, False: 5.91M]
  ------------------
  472|  4.57M|    case SPV_OPERAND_TYPE_OPTIONAL_ID:
  ------------------
  |  Branch (472:5): [True: 2.76M, False: 4.95M]
  ------------------
  473|  4.57M|      if (!word) return diagnostic(SPV_ERROR_INVALID_ID) << "Id is 0";
  ------------------
  |  Branch (473:11): [True: 25, False: 4.57M]
  ------------------
  474|  4.57M|      parsed_operand.type = SPV_OPERAND_TYPE_ID;
  475|       |
  476|  4.57M|      if (opcode == spv::Op::OpExtInst && parsed_operand.offset == 3) {
  ------------------
  |  Branch (476:11): [True: 38.9k, False: 4.53M]
  |  Branch (476:43): [True: 16.2k, False: 22.6k]
  ------------------
  477|       |        // The current word is the extended instruction set Id.
  478|       |        // Set the extended instruction set type for the current instruction.
  479|  16.2k|        auto ext_inst_type_iter = _.import_id_to_ext_inst_type.find(word);
  480|  16.2k|        if (ext_inst_type_iter == _.import_id_to_ext_inst_type.end()) {
  ------------------
  |  Branch (480:13): [True: 143, False: 16.0k]
  ------------------
  481|    143|          return diagnostic(SPV_ERROR_INVALID_ID)
  482|    143|                 << "OpExtInst set Id " << word
  483|    143|                 << " does not reference an OpExtInstImport result Id";
  484|    143|        }
  485|  16.0k|        inst->ext_inst_type = ext_inst_type_iter->second;
  486|  16.0k|      }
  487|  4.57M|      break;
  488|       |
  489|  4.57M|    case SPV_OPERAND_TYPE_SCOPE_ID:
  ------------------
  |  Branch (489:5): [True: 5.14k, False: 7.71M]
  ------------------
  490|  7.68k|    case SPV_OPERAND_TYPE_MEMORY_SEMANTICS_ID:
  ------------------
  |  Branch (490:5): [True: 2.54k, False: 7.71M]
  ------------------
  491|       |      // Check for trivially invalid values.  The operand descriptions already
  492|       |      // have the word "ID" in them.
  493|  7.68k|      if (!word) return diagnostic() << spvOperandTypeStr(type) << " is 0";
  ------------------
  |  Branch (493:11): [True: 6, False: 7.67k]
  ------------------
  494|  7.67k|      break;
  495|       |
  496|  16.0k|    case SPV_OPERAND_TYPE_EXTENSION_INSTRUCTION_NUMBER: {
  ------------------
  |  Branch (496:5): [True: 16.0k, False: 7.70M]
  ------------------
  497|  16.0k|      assert(spv::Op::OpExtInst == opcode);
  498|      0|      assert(inst->ext_inst_type != SPV_EXT_INST_TYPE_NONE);
  499|      0|      spv_ext_inst_desc ext_inst;
  500|  16.0k|      if (grammar_.lookupExtInst(inst->ext_inst_type, word, &ext_inst) ==
  ------------------
  |  Branch (500:11): [True: 15.6k, False: 404]
  ------------------
  501|  16.0k|          SPV_SUCCESS) {
  502|       |        // if we know about this ext inst, push the expected operands
  503|  15.6k|        spvPushOperandTypes(ext_inst->operandTypes, expected_operands);
  504|  15.6k|      } else {
  505|       |        // if we don't know this extended instruction and the set isn't
  506|       |        // non-semantic, we cannot process further
  507|    404|        if (!spvExtInstIsNonSemantic(inst->ext_inst_type)) {
  ------------------
  |  Branch (507:13): [True: 22, False: 382]
  ------------------
  508|     22|          return diagnostic()
  509|     22|                 << "Invalid extended instruction number: " << word;
  510|    382|        } else {
  511|       |          // for non-semantic instruction sets, we know the form of all such
  512|       |          // extended instructions contains a series of IDs as parameters
  513|    382|          expected_operands->push_back(SPV_OPERAND_TYPE_VARIABLE_ID);
  514|    382|        }
  515|    404|      }
  516|  16.0k|    } break;
  517|       |
  518|  16.0k|    case SPV_OPERAND_TYPE_SPEC_CONSTANT_OP_NUMBER: {
  ------------------
  |  Branch (518:5): [True: 238, False: 7.71M]
  ------------------
  519|    238|      assert(spv::Op::OpSpecConstantOp == opcode);
  520|    238|      if (word > static_cast<uint32_t>(spv::Op::Max) ||
  ------------------
  |  Branch (520:11): [True: 43, False: 195]
  ------------------
  521|    238|          grammar_.lookupSpecConstantOpcode(spv::Op(word))) {
  ------------------
  |  Branch (521:11): [True: 39, False: 156]
  ------------------
  522|     82|        return diagnostic()
  523|     82|               << "Invalid " << spvOperandTypeStr(type) << ": " << word;
  524|     82|      }
  525|    156|      spv_opcode_desc opcode_entry = nullptr;
  526|    156|      if (grammar_.lookupOpcode(spv::Op(word), &opcode_entry)) {
  ------------------
  |  Branch (526:11): [True: 0, False: 156]
  ------------------
  527|      0|        return diagnostic(SPV_ERROR_INTERNAL)
  528|      0|               << "OpSpecConstant opcode table out of sync";
  529|      0|      }
  530|       |      // OpSpecConstant opcodes must have a type and result. We've already
  531|       |      // processed them, so skip them when preparing to parse the other
  532|       |      // operants for the opcode.
  533|    156|      assert(opcode_entry->hasType);
  534|      0|      assert(opcode_entry->hasResult);
  535|      0|      assert(opcode_entry->numTypes >= 2);
  536|      0|      spvPushOperandTypes(opcode_entry->operandTypes + 2, expected_operands);
  537|    156|    } break;
  538|       |
  539|   104k|    case SPV_OPERAND_TYPE_LITERAL_INTEGER:
  ------------------
  |  Branch (539:5): [True: 104k, False: 7.61M]
  ------------------
  540|   575k|    case SPV_OPERAND_TYPE_OPTIONAL_LITERAL_INTEGER:
  ------------------
  |  Branch (540:5): [True: 471k, False: 7.24M]
  ------------------
  541|       |      // These are regular single-word literal integer operands.
  542|       |      // Post-parsing validation should check the range of the parsed value.
  543|   575k|      parsed_operand.type = SPV_OPERAND_TYPE_LITERAL_INTEGER;
  544|       |      // It turns out they are always unsigned integers!
  545|   575k|      parsed_operand.number_kind = SPV_NUMBER_UNSIGNED_INT;
  546|   575k|      parsed_operand.number_bit_width = 32;
  547|   575k|      break;
  548|       |
  549|  73.7k|    case SPV_OPERAND_TYPE_TYPED_LITERAL_NUMBER:
  ------------------
  |  Branch (549:5): [True: 73.7k, False: 7.64M]
  ------------------
  550|   178k|    case SPV_OPERAND_TYPE_OPTIONAL_TYPED_LITERAL_INTEGER:
  ------------------
  |  Branch (550:5): [True: 104k, False: 7.61M]
  ------------------
  551|   178k|      parsed_operand.type = SPV_OPERAND_TYPE_TYPED_LITERAL_NUMBER;
  552|   178k|      if (opcode == spv::Op::OpSwitch) {
  ------------------
  |  Branch (552:11): [True: 104k, False: 73.7k]
  ------------------
  553|       |        // The literal operands have the same type as the value
  554|       |        // referenced by the selector Id.
  555|   104k|        const uint32_t selector_id = peekAt(inst_offset + 1);
  556|   104k|        const auto type_id_iter = _.id_to_type_id.find(selector_id);
  557|   104k|        if (type_id_iter == _.id_to_type_id.end() ||
  ------------------
  |  Branch (557:13): [True: 133, False: 104k]
  |  Branch (557:13): [True: 135, False: 104k]
  ------------------
  558|   104k|            type_id_iter->second == 0) {
  ------------------
  |  Branch (558:13): [True: 2, False: 104k]
  ------------------
  559|    135|          return diagnostic() << "Invalid OpSwitch: selector id " << selector_id
  560|    135|                              << " has no type";
  561|    135|        }
  562|   104k|        uint32_t type_id = type_id_iter->second;
  563|       |
  564|   104k|        if (selector_id == type_id) {
  ------------------
  |  Branch (564:13): [True: 15, False: 104k]
  ------------------
  565|       |          // Recall that by convention, a result ID that is a type definition
  566|       |          // maps to itself.
  567|     15|          return diagnostic() << "Invalid OpSwitch: selector id " << selector_id
  568|     15|                              << " is a type, not a value";
  569|     15|        }
  570|   104k|        if (auto error = setNumericTypeInfoForType(&parsed_operand, type_id))
  ------------------
  |  Branch (570:18): [True: 43, False: 104k]
  ------------------
  571|     43|          return error;
  572|   104k|        if (parsed_operand.number_kind != SPV_NUMBER_UNSIGNED_INT &&
  ------------------
  |  Branch (572:13): [True: 69.3k, False: 34.8k]
  ------------------
  573|   104k|            parsed_operand.number_kind != SPV_NUMBER_SIGNED_INT) {
  ------------------
  |  Branch (573:13): [True: 3, False: 69.3k]
  ------------------
  574|      3|          return diagnostic() << "Invalid OpSwitch: selector id " << selector_id
  575|      3|                              << " is not a scalar integer";
  576|      3|        }
  577|   104k|      } else {
  578|  73.7k|        assert(opcode == spv::Op::OpConstant ||
  579|  73.7k|               opcode == spv::Op::OpSpecConstant);
  580|       |        // The literal number type is determined by the type Id for the
  581|       |        // constant.
  582|      0|        assert(inst->type_id);
  583|  73.7k|        if (auto error =
  ------------------
  |  Branch (583:18): [True: 218, False: 73.5k]
  ------------------
  584|  73.7k|                setNumericTypeInfoForType(&parsed_operand, inst->type_id))
  585|    218|          return error;
  586|  73.7k|      }
  587|   177k|      break;
  588|       |
  589|   177k|    case SPV_OPERAND_TYPE_LITERAL_STRING:
  ------------------
  |  Branch (589:5): [True: 141k, False: 7.57M]
  ------------------
  590|   141k|    case SPV_OPERAND_TYPE_OPTIONAL_LITERAL_STRING: {
  ------------------
  |  Branch (590:5): [True: 30, False: 7.71M]
  ------------------
  591|   141k|      const size_t max_words = _.num_words - _.word_index;
  592|   141k|      std::string string =
  593|   141k|          spvtools::utils::MakeString(_.words + _.word_index, max_words, false);
  594|       |
  595|   141k|      if (string.length() == max_words * 4)
  ------------------
  |  Branch (595:11): [True: 32, False: 141k]
  ------------------
  596|     32|        return exhaustedInputDiagnostic(inst_offset, opcode, type);
  597|       |
  598|       |      // Make sure we can record the word count without overflow.
  599|       |      //
  600|       |      // This error can't currently be triggered because of validity
  601|       |      // checks elsewhere.
  602|   141k|      const size_t string_num_words = string.length() / 4 + 1;
  603|   141k|      if (string_num_words > std::numeric_limits<uint16_t>::max()) {
  ------------------
  |  Branch (603:11): [True: 3, False: 141k]
  ------------------
  604|      3|        return diagnostic() << "Literal string is longer than "
  605|      3|                            << std::numeric_limits<uint16_t>::max()
  606|      3|                            << " words: " << string_num_words << " words long";
  607|      3|      }
  608|   141k|      parsed_operand.num_words = uint16_t(string_num_words);
  609|   141k|      parsed_operand.type = SPV_OPERAND_TYPE_LITERAL_STRING;
  610|       |
  611|   141k|      if (spv::Op::OpExtInstImport == opcode) {
  ------------------
  |  Branch (611:11): [True: 8.56k, False: 133k]
  ------------------
  612|       |        // Record the extended instruction type for the ID for this import.
  613|       |        // There is only one string literal argument to OpExtInstImport,
  614|       |        // so it's sufficient to guard this just on the opcode.
  615|  8.56k|        const spv_ext_inst_type_t ext_inst_type =
  616|  8.56k|            spvExtInstImportTypeGet(string.c_str());
  617|  8.56k|        if (SPV_EXT_INST_TYPE_NONE == ext_inst_type) {
  ------------------
  |  Branch (617:13): [True: 695, False: 7.86k]
  ------------------
  618|    695|          return diagnostic()
  619|    695|                 << "Invalid extended instruction import '" << string << "'";
  620|    695|        }
  621|       |        // We must have parsed a valid result ID.  It's a condition
  622|       |        // of the grammar, and we only accept non-zero result Ids.
  623|  7.86k|        assert(inst->result_id);
  624|      0|        _.import_id_to_ext_inst_type[inst->result_id] = ext_inst_type;
  625|  7.86k|      }
  626|   141k|    } break;
  627|       |
  628|   141k|    case SPV_OPERAND_TYPE_CAPABILITY:
  ------------------
  |  Branch (628:5): [True: 35.8k, False: 7.68M]
  ------------------
  629|  38.8k|    case SPV_OPERAND_TYPE_SOURCE_LANGUAGE:
  ------------------
  |  Branch (629:5): [True: 2.94k, False: 7.71M]
  ------------------
  630|  53.0k|    case SPV_OPERAND_TYPE_EXECUTION_MODEL:
  ------------------
  |  Branch (630:5): [True: 14.1k, False: 7.70M]
  ------------------
  631|  80.4k|    case SPV_OPERAND_TYPE_ADDRESSING_MODEL:
  ------------------
  |  Branch (631:5): [True: 27.4k, False: 7.69M]
  ------------------
  632|   107k|    case SPV_OPERAND_TYPE_MEMORY_MODEL:
  ------------------
  |  Branch (632:5): [True: 27.4k, False: 7.69M]
  ------------------
  633|   124k|    case SPV_OPERAND_TYPE_EXECUTION_MODE:
  ------------------
  |  Branch (633:5): [True: 17.0k, False: 7.70M]
  ------------------
  634|   197k|    case SPV_OPERAND_TYPE_STORAGE_CLASS:
  ------------------
  |  Branch (634:5): [True: 72.3k, False: 7.64M]
  ------------------
  635|   198k|    case SPV_OPERAND_TYPE_DIMENSIONALITY:
  ------------------
  |  Branch (635:5): [True: 1.11k, False: 7.71M]
  ------------------
  636|   198k|    case SPV_OPERAND_TYPE_SAMPLER_ADDRESSING_MODE:
  ------------------
  |  Branch (636:5): [True: 29, False: 7.71M]
  ------------------
  637|   198k|    case SPV_OPERAND_TYPE_SAMPLER_FILTER_MODE:
  ------------------
  |  Branch (637:5): [True: 19, False: 7.71M]
  ------------------
  638|   199k|    case SPV_OPERAND_TYPE_SAMPLER_IMAGE_FORMAT:
  ------------------
  |  Branch (638:5): [True: 1.10k, False: 7.71M]
  ------------------
  639|   199k|    case SPV_OPERAND_TYPE_FP_ROUNDING_MODE:
  ------------------
  |  Branch (639:5): [True: 332, False: 7.71M]
  ------------------
  640|   199k|    case SPV_OPERAND_TYPE_LINKAGE_TYPE:
  ------------------
  |  Branch (640:5): [True: 54, False: 7.71M]
  ------------------
  641|   199k|    case SPV_OPERAND_TYPE_ACCESS_QUALIFIER:
  ------------------
  |  Branch (641:5): [True: 59, False: 7.71M]
  ------------------
  642|   199k|    case SPV_OPERAND_TYPE_OPTIONAL_ACCESS_QUALIFIER:
  ------------------
  |  Branch (642:5): [True: 6, False: 7.71M]
  ------------------
  643|   199k|    case SPV_OPERAND_TYPE_FUNCTION_PARAMETER_ATTRIBUTE:
  ------------------
  |  Branch (643:5): [True: 46, False: 7.71M]
  ------------------
  644|   476k|    case SPV_OPERAND_TYPE_DECORATION:
  ------------------
  |  Branch (644:5): [True: 276k, False: 7.44M]
  ------------------
  645|   681k|    case SPV_OPERAND_TYPE_BUILT_IN:
  ------------------
  |  Branch (645:5): [True: 205k, False: 7.51M]
  ------------------
  646|   681k|    case SPV_OPERAND_TYPE_GROUP_OPERATION:
  ------------------
  |  Branch (646:5): [True: 37, False: 7.71M]
  ------------------
  647|   681k|    case SPV_OPERAND_TYPE_KERNEL_ENQ_FLAGS:
  ------------------
  |  Branch (647:5): [True: 0, False: 7.71M]
  ------------------
  648|   681k|    case SPV_OPERAND_TYPE_KERNEL_PROFILING_INFO:
  ------------------
  |  Branch (648:5): [True: 0, False: 7.71M]
  ------------------
  649|   681k|    case SPV_OPERAND_TYPE_RAY_FLAGS:
  ------------------
  |  Branch (649:5): [True: 0, False: 7.71M]
  ------------------
  650|   681k|    case SPV_OPERAND_TYPE_RAY_QUERY_INTERSECTION:
  ------------------
  |  Branch (650:5): [True: 0, False: 7.71M]
  ------------------
  651|   681k|    case SPV_OPERAND_TYPE_RAY_QUERY_COMMITTED_INTERSECTION_TYPE:
  ------------------
  |  Branch (651:5): [True: 0, False: 7.71M]
  ------------------
  652|   681k|    case SPV_OPERAND_TYPE_RAY_QUERY_CANDIDATE_INTERSECTION_TYPE:
  ------------------
  |  Branch (652:5): [True: 0, False: 7.71M]
  ------------------
  653|   681k|    case SPV_OPERAND_TYPE_DEBUG_BASE_TYPE_ATTRIBUTE_ENCODING:
  ------------------
  |  Branch (653:5): [True: 2, False: 7.71M]
  ------------------
  654|   681k|    case SPV_OPERAND_TYPE_DEBUG_COMPOSITE_TYPE:
  ------------------
  |  Branch (654:5): [True: 10, False: 7.71M]
  ------------------
  655|   682k|    case SPV_OPERAND_TYPE_DEBUG_TYPE_QUALIFIER:
  ------------------
  |  Branch (655:5): [True: 10, False: 7.71M]
  ------------------
  656|   682k|    case SPV_OPERAND_TYPE_DEBUG_OPERATION:
  ------------------
  |  Branch (656:5): [True: 8, False: 7.71M]
  ------------------
  657|   682k|    case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_BASE_TYPE_ATTRIBUTE_ENCODING:
  ------------------
  |  Branch (657:5): [True: 0, False: 7.71M]
  ------------------
  658|   682k|    case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_COMPOSITE_TYPE:
  ------------------
  |  Branch (658:5): [True: 3, False: 7.71M]
  ------------------
  659|   682k|    case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_TYPE_QUALIFIER:
  ------------------
  |  Branch (659:5): [True: 7, False: 7.71M]
  ------------------
  660|   682k|    case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_OPERATION:
  ------------------
  |  Branch (660:5): [True: 2, False: 7.71M]
  ------------------
  661|   682k|    case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_IMPORTED_ENTITY:
  ------------------
  |  Branch (661:5): [True: 0, False: 7.71M]
  ------------------
  662|   682k|    case SPV_OPERAND_TYPE_FPDENORM_MODE:
  ------------------
  |  Branch (662:5): [True: 27, False: 7.71M]
  ------------------
  663|   682k|    case SPV_OPERAND_TYPE_FPOPERATION_MODE:
  ------------------
  |  Branch (663:5): [True: 0, False: 7.71M]
  ------------------
  664|   682k|    case SPV_OPERAND_TYPE_QUANTIZATION_MODES:
  ------------------
  |  Branch (664:5): [True: 0, False: 7.71M]
  ------------------
  665|   682k|    case SPV_OPERAND_TYPE_OVERFLOW_MODES:
  ------------------
  |  Branch (665:5): [True: 0, False: 7.71M]
  ------------------
  666|   682k|    case SPV_OPERAND_TYPE_PACKED_VECTOR_FORMAT:
  ------------------
  |  Branch (666:5): [True: 0, False: 7.71M]
  ------------------
  667|   682k|    case SPV_OPERAND_TYPE_OPTIONAL_PACKED_VECTOR_FORMAT: {
  ------------------
  |  Branch (667:5): [True: 23, False: 7.71M]
  ------------------
  668|       |      // A single word that is a plain enum value.
  669|       |
  670|       |      // Map an optional operand type to its corresponding concrete type.
  671|   682k|      if (type == SPV_OPERAND_TYPE_OPTIONAL_ACCESS_QUALIFIER)
  ------------------
  |  Branch (671:11): [True: 6, False: 682k]
  ------------------
  672|      6|        parsed_operand.type = SPV_OPERAND_TYPE_ACCESS_QUALIFIER;
  673|   682k|      if (type == SPV_OPERAND_TYPE_OPTIONAL_PACKED_VECTOR_FORMAT)
  ------------------
  |  Branch (673:11): [True: 23, False: 682k]
  ------------------
  674|     23|        parsed_operand.type = SPV_OPERAND_TYPE_PACKED_VECTOR_FORMAT;
  675|       |
  676|   682k|      spv_operand_desc entry;
  677|   682k|      if (grammar_.lookupOperand(type, word, &entry)) {
  ------------------
  |  Branch (677:11): [True: 166, False: 681k]
  ------------------
  678|    166|        return diagnostic()
  679|    166|               << "Invalid " << spvOperandTypeStr(parsed_operand.type)
  680|    166|               << " operand: " << word;
  681|    166|      }
  682|       |      // Prepare to accept operands to this operand, if needed.
  683|   681k|      spvPushOperandTypes(entry->operandTypes, expected_operands);
  684|   681k|    } break;
  685|       |
  686|  1.79k|    case SPV_OPERAND_TYPE_FP_FAST_MATH_MODE:
  ------------------
  |  Branch (686:5): [True: 1.79k, False: 7.71M]
  ------------------
  687|  21.6k|    case SPV_OPERAND_TYPE_FUNCTION_CONTROL:
  ------------------
  |  Branch (687:5): [True: 19.8k, False: 7.69M]
  ------------------
  688|   102k|    case SPV_OPERAND_TYPE_LOOP_CONTROL:
  ------------------
  |  Branch (688:5): [True: 81.3k, False: 7.63M]
  ------------------
  689|   102k|    case SPV_OPERAND_TYPE_IMAGE:
  ------------------
  |  Branch (689:5): [True: 15, False: 7.71M]
  ------------------
  690|   102k|    case SPV_OPERAND_TYPE_OPTIONAL_IMAGE:
  ------------------
  |  Branch (690:5): [True: 36, False: 7.71M]
  ------------------
  691|   104k|    case SPV_OPERAND_TYPE_OPTIONAL_MEMORY_ACCESS:
  ------------------
  |  Branch (691:5): [True: 1.35k, False: 7.71M]
  ------------------
  692|   148k|    case SPV_OPERAND_TYPE_SELECTION_CONTROL:
  ------------------
  |  Branch (692:5): [True: 44.5k, False: 7.67M]
  ------------------
  693|   148k|    case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_INFO_FLAGS:
  ------------------
  |  Branch (693:5): [True: 11, False: 7.71M]
  ------------------
  694|   148k|    case SPV_OPERAND_TYPE_DEBUG_INFO_FLAGS: {
  ------------------
  |  Branch (694:5): [True: 17, False: 7.71M]
  ------------------
  695|       |      // This operand is a mask.
  696|       |
  697|       |      // Map an optional operand type to its corresponding concrete type.
  698|   148k|      if (type == SPV_OPERAND_TYPE_OPTIONAL_IMAGE)
  ------------------
  |  Branch (698:11): [True: 36, False: 148k]
  ------------------
  699|     36|        parsed_operand.type = SPV_OPERAND_TYPE_IMAGE;
  700|   148k|      else if (type == SPV_OPERAND_TYPE_OPTIONAL_MEMORY_ACCESS)
  ------------------
  |  Branch (700:16): [True: 1.35k, False: 147k]
  ------------------
  701|  1.35k|        parsed_operand.type = SPV_OPERAND_TYPE_MEMORY_ACCESS;
  702|       |
  703|       |      // Check validity of set mask bits. Also prepare for operands for those
  704|       |      // masks if they have any.  To get operand order correct, scan from
  705|       |      // MSB to LSB since we can only prepend operands to a pattern.
  706|       |      // The only case in the grammar where you have more than one mask bit
  707|       |      // having an operand is for image operands.  See SPIR-V 3.14 Image
  708|       |      // Operands.
  709|   148k|      uint32_t remaining_word = word;
  710|   932k|      for (uint32_t mask = (1u << 31); remaining_word; mask >>= 1) {
  ------------------
  |  Branch (710:40): [True: 783k, False: 148k]
  ------------------
  711|   783k|        if (remaining_word & mask) {
  ------------------
  |  Branch (711:13): [True: 40.2k, False: 743k]
  ------------------
  712|  40.2k|          spv_operand_desc entry;
  713|  40.2k|          if (grammar_.lookupOperand(type, mask, &entry)) {
  ------------------
  |  Branch (713:15): [True: 110, False: 40.1k]
  ------------------
  714|    110|            return diagnostic()
  715|    110|                   << "Invalid " << spvOperandTypeStr(parsed_operand.type)
  716|    110|                   << " operand: " << word << " has invalid mask component "
  717|    110|                   << mask;
  718|    110|          }
  719|  40.1k|          remaining_word ^= mask;
  720|  40.1k|          spvPushOperandTypes(entry->operandTypes, expected_operands);
  721|  40.1k|        }
  722|   783k|      }
  723|   148k|      if (word == 0) {
  ------------------
  |  Branch (723:11): [True: 123k, False: 25.0k]
  ------------------
  724|       |        // An all-zeroes mask *might* also be valid.
  725|   123k|        spv_operand_desc entry;
  726|   123k|        if (SPV_SUCCESS == grammar_.lookupOperand(type, 0, &entry)) {
  ------------------
  |  Branch (726:13): [True: 123k, False: 0]
  ------------------
  727|       |          // Prepare for its operands, if any.
  728|   123k|          spvPushOperandTypes(entry->operandTypes, expected_operands);
  729|   123k|        }
  730|   123k|      }
  731|   148k|    } break;
  732|      0|    default:
  ------------------
  |  Branch (732:5): [True: 0, False: 7.71M]
  ------------------
  733|      0|      return diagnostic() << "Internal error: Unhandled operand type: " << type;
  734|  7.71M|  }
  735|       |
  736|  7.71M|  assert(spvOperandIsConcrete(parsed_operand.type));
  737|       |
  738|      0|  operands->push_back(parsed_operand);
  739|       |
  740|  7.71M|  const size_t index_after_operand = _.word_index + parsed_operand.num_words;
  741|       |
  742|       |  // Avoid buffer overrun for the cases where the operand has more than one
  743|       |  // word, and where it isn't a string.  (Those other cases have already been
  744|       |  // handled earlier.)  For example, this error can occur for a multi-word
  745|       |  // argument to OpConstant, or a multi-word case literal operand for OpSwitch.
  746|  7.71M|  if (_.num_words < index_after_operand)
  ------------------
  |  Branch (746:7): [True: 11, False: 7.71M]
  ------------------
  747|     11|    return exhaustedInputDiagnostic(inst_offset, opcode, type);
  748|       |
  749|  7.71M|  if (_.requires_endian_conversion) {
  ------------------
  |  Branch (749:7): [True: 3.09M, False: 4.61M]
  ------------------
  750|       |    // Copy instruction words.  Translate to native endianness as needed.
  751|  3.09M|    if (convert_operand_endianness) {
  ------------------
  |  Branch (751:9): [True: 3.09M, False: 0]
  ------------------
  752|  3.09M|      const spv_endianness_t endianness = _.endian;
  753|  3.09M|      std::transform(_.words + _.word_index, _.words + index_after_operand,
  754|  3.09M|                     std::back_inserter(*words),
  755|  3.09M|                     [endianness](const uint32_t raw_word) {
  756|  3.09M|                       return spvFixWord(raw_word, endianness);
  757|  3.09M|                     });
  758|  3.09M|    } else {
  759|      0|      words->insert(words->end(), _.words + _.word_index,
  760|      0|                    _.words + index_after_operand);
  761|      0|    }
  762|  3.09M|  }
  763|       |
  764|       |  // Advance past the operand.
  765|  7.71M|  _.word_index = index_after_operand;
  766|       |
  767|  7.71M|  return SPV_SUCCESS;
  768|  7.71M|}
binary.cpp:_ZN12_GLOBAL__N_16Parser24exhaustedInputDiagnosticEmN3spv2OpE18spv_operand_type_t:
  160|    618|                                        spv_operand_type_t type) {
  161|    618|    return diagnostic() << "End of input reached while decoding Op"
  162|    618|                        << spvOpcodeString(opcode) << " starting at word "
  163|    618|                        << inst_offset
  164|    618|                        << ((_.word_index < _.num_words) ? ": truncated "
  ------------------
  |  Branch (164:29): [True: 43, False: 575]
  ------------------
  165|    618|                                                         : ": missing ")
  166|    618|                        << spvOperandTypeStr(type) << " operand at word offset "
  167|    618|                        << _.word_index - inst_offset << ".";
  168|    618|  }
binary.cpp:_ZN12_GLOBAL__N_16Parser25setNumericTypeInfoForTypeEP20spv_parsed_operand_tj:
  771|   178k|    spv_parsed_operand_t* parsed_operand, uint32_t type_id) {
  772|   178k|  assert(type_id != 0);
  773|      0|  auto type_info_iter = _.type_id_to_number_type_info.find(type_id);
  774|   178k|  if (type_info_iter == _.type_id_to_number_type_info.end()) {
  ------------------
  |  Branch (774:7): [True: 256, False: 177k]
  ------------------
  775|    256|    return diagnostic() << "Type Id " << type_id << " is not a type";
  776|    256|  }
  777|   177k|  const NumberType& info = type_info_iter->second;
  778|   177k|  if (info.type == SPV_NUMBER_NONE) {
  ------------------
  |  Branch (778:7): [True: 5, False: 177k]
  ------------------
  779|       |    // This is a valid type, but for something other than a scalar number.
  780|      5|    return diagnostic() << "Type Id " << type_id
  781|      5|                        << " is not a scalar numeric type";
  782|      5|  }
  783|       |
  784|   177k|  parsed_operand->number_kind = info.type;
  785|   177k|  parsed_operand->number_bit_width = info.bit_width;
  786|       |  // Round up the word count.
  787|   177k|  parsed_operand->num_words = static_cast<uint16_t>((info.bit_width + 31) / 32);
  788|   177k|  return SPV_SUCCESS;
  789|   177k|}
binary.cpp:_ZZN12_GLOBAL__N_16Parser12parseOperandEmP24spv_parsed_instruction_t18spv_operand_type_tPNSt3__16vectorIjNS4_9allocatorIjEEEEPNS5_I20spv_parsed_operand_tNS6_ISA_EEEEPNS5_IS3_NS6_IS3_EEEEENK3$_0clEj:
  755|  3.72M|                     [endianness](const uint32_t raw_word) {
  756|  3.72M|                       return spvFixWord(raw_word, endianness);
  757|  3.72M|                     });
binary.cpp:_ZN12_GLOBAL__N_16Parser16recordNumberTypeEmPK24spv_parsed_instruction_t:
  792|  1.95M|                              const spv_parsed_instruction_t* inst) {
  793|  1.95M|  const spv::Op opcode = static_cast<spv::Op>(inst->opcode);
  794|  1.95M|  if (spvOpcodeGeneratesType(opcode)) {
  ------------------
  |  Branch (794:7): [True: 136k, False: 1.82M]
  ------------------
  795|   136k|    NumberType info = {SPV_NUMBER_NONE, 0};
  796|   136k|    if (spv::Op::OpTypeInt == opcode) {
  ------------------
  |  Branch (796:9): [True: 14.4k, False: 121k]
  ------------------
  797|  14.4k|      const bool is_signed = peekAt(inst_offset + 3) != 0;
  798|  14.4k|      info.type = is_signed ? SPV_NUMBER_SIGNED_INT : SPV_NUMBER_UNSIGNED_INT;
  ------------------
  |  Branch (798:19): [True: 8.32k, False: 6.15k]
  ------------------
  799|  14.4k|      info.bit_width = peekAt(inst_offset + 2);
  800|   121k|    } else if (spv::Op::OpTypeFloat == opcode) {
  ------------------
  |  Branch (800:16): [True: 8.45k, False: 113k]
  ------------------
  801|  8.45k|      info.type = SPV_NUMBER_FLOATING;
  802|  8.45k|      info.bit_width = peekAt(inst_offset + 2);
  803|  8.45k|    }
  804|       |    // The *result* Id of a type generating instruction is the type Id.
  805|   136k|    _.type_id_to_number_type_info[inst->result_id] = info;
  806|   136k|  }
  807|  1.95M|}

_ZN8spvtools3CFAINS_3val10BasicBlockEE19DepthFirstTraversalEPKS2_NSt3__18functionIFPKNS6_6vectorIPS2_NS6_9allocatorIS9_EEEES5_EEENS7_IFvS5_EEESI_NS7_IFbS5_EEE:
  168|  25.2k|                                  std::function<bool(cbb_ptr)> terminal) {
  169|  25.2k|  DepthFirstTraversal(entry, successor_func, preorder, postorder,
  170|  25.2k|                      /* backedge = */ {}, terminal);
  171|  25.2k|}
_ZN8spvtools3CFAINS_3val10BasicBlockEE19CalculateDominatorsERKNSt3__16vectorIPKS2_NS4_9allocatorIS7_EEEENS4_8functionIFPKNS5_IPS2_NS8_ISE_EEEES7_EEE:
  219|  4.54k|    const std::vector<cbb_ptr>& postorder, get_blocks_func predecessor_func) {
  220|  4.54k|  struct block_detail {
  221|  4.54k|    size_t dominator;  ///< The index of blocks's dominator in post order array
  222|  4.54k|    size_t postorder_index;  ///< The index of the block in the post order array
  223|  4.54k|  };
  224|  4.54k|  const size_t undefined_dom = postorder.size();
  225|       |
  226|  4.54k|  std::unordered_map<cbb_ptr, block_detail> idoms;
  227|   101k|  for (size_t i = 0; i < postorder.size(); i++) {
  ------------------
  |  Branch (227:22): [True: 96.7k, False: 4.54k]
  ------------------
  228|  96.7k|    idoms[postorder[i]] = {undefined_dom, i};
  229|  96.7k|  }
  230|  4.54k|  idoms[postorder.back()].dominator = idoms[postorder.back()].postorder_index;
  231|       |
  232|  4.54k|  bool changed = true;
  233|  14.3k|  while (changed) {
  ------------------
  |  Branch (233:10): [True: 9.75k, False: 4.54k]
  ------------------
  234|  9.75k|    changed = false;
  235|   251k|    for (auto b = postorder.rbegin() + 1; b != postorder.rend(); ++b) {
  ------------------
  |  Branch (235:43): [True: 241k, False: 9.75k]
  ------------------
  236|   241k|      const std::vector<BB*>& predecessors = *predecessor_func(*b);
  237|       |      // Find the first processed/reachable predecessor that is reachable
  238|       |      // in the forward traversal.
  239|   241k|      auto res = std::find_if(std::begin(predecessors), std::end(predecessors),
  240|   241k|                              [&idoms, undefined_dom](BB* pred) {
  241|   241k|                                return idoms.count(pred) &&
  242|   241k|                                       idoms[pred].dominator != undefined_dom;
  243|   241k|                              });
  244|   241k|      if (res == end(predecessors)) continue;
  ------------------
  |  Branch (244:11): [True: 77, False: 241k]
  ------------------
  245|   241k|      const BB* idom = *res;
  246|   241k|      size_t idom_idx = idoms[idom].postorder_index;
  247|       |
  248|       |      // all other predecessors
  249|   429k|      for (const auto* p : predecessors) {
  ------------------
  |  Branch (249:26): [True: 429k, False: 241k]
  ------------------
  250|   429k|        if (idom == p) continue;
  ------------------
  |  Branch (250:13): [True: 272k, False: 157k]
  ------------------
  251|       |        // Only consider nodes reachable in the forward traversal.
  252|       |        // Otherwise the intersection doesn't make sense and will never
  253|       |        // terminate.
  254|   157k|        if (!idoms.count(p)) continue;
  ------------------
  |  Branch (254:13): [True: 23.3k, False: 134k]
  ------------------
  255|   134k|        if (idoms[p].dominator != undefined_dom) {
  ------------------
  |  Branch (255:13): [True: 120k, False: 13.6k]
  ------------------
  256|   120k|          size_t finger1 = idoms[p].postorder_index;
  257|   120k|          size_t finger2 = idom_idx;
  258|   249k|          while (finger1 != finger2) {
  ------------------
  |  Branch (258:18): [True: 129k, False: 120k]
  ------------------
  259|   433k|            while (finger1 < finger2) {
  ------------------
  |  Branch (259:20): [True: 304k, False: 129k]
  ------------------
  260|   304k|              finger1 = idoms[postorder[finger1]].dominator;
  261|   304k|            }
  262|   207k|            while (finger2 < finger1) {
  ------------------
  |  Branch (262:20): [True: 78.1k, False: 129k]
  ------------------
  263|  78.1k|              finger2 = idoms[postorder[finger2]].dominator;
  264|  78.1k|            }
  265|   129k|          }
  266|   120k|          idom_idx = finger1;
  267|   120k|        }
  268|   134k|      }
  269|   241k|      if (idoms[*b].dominator != idom_idx) {
  ------------------
  |  Branch (269:11): [True: 95.0k, False: 146k]
  ------------------
  270|  95.0k|        idoms[*b].dominator = idom_idx;
  271|  95.0k|        changed = true;
  272|  95.0k|      }
  273|   241k|    }
  274|  9.75k|  }
  275|       |
  276|  4.54k|  std::vector<std::pair<bb_ptr, bb_ptr>> out;
  277|  96.7k|  for (auto idom : idoms) {
  ------------------
  |  Branch (277:18): [True: 96.7k, False: 4.54k]
  ------------------
  278|       |    // At this point if there is no dominator for the node, just make it
  279|       |    // reflexive.
  280|  96.7k|    auto dominator = std::get<1>(idom).dominator;
  281|  96.7k|    if (dominator == undefined_dom) {
  ------------------
  |  Branch (281:9): [True: 33, False: 96.7k]
  ------------------
  282|     33|      dominator = std::get<1>(idom).postorder_index;
  283|     33|    }
  284|       |    // NOTE: performing a const cast for convenient usage with
  285|       |    // UpdateImmediateDominators
  286|  96.7k|    out.push_back({const_cast<BB*>(std::get<0>(idom)),
  287|  96.7k|                   const_cast<BB*>(postorder[dominator])});
  288|  96.7k|  }
  289|       |
  290|       |  // Sort by postorder index to generate a deterministic ordering of edges.
  291|  4.54k|  std::sort(
  292|  4.54k|      out.begin(), out.end(),
  293|  4.54k|      [&idoms](const std::pair<bb_ptr, bb_ptr>& lhs,
  294|  4.54k|               const std::pair<bb_ptr, bb_ptr>& rhs) {
  295|  4.54k|        assert(lhs.first);
  296|  4.54k|        assert(lhs.second);
  297|  4.54k|        assert(rhs.first);
  298|  4.54k|        assert(rhs.second);
  299|  4.54k|        auto lhs_indices = std::make_pair(idoms[lhs.first].postorder_index,
  300|  4.54k|                                          idoms[lhs.second].postorder_index);
  301|  4.54k|        auto rhs_indices = std::make_pair(idoms[rhs.first].postorder_index,
  302|  4.54k|                                          idoms[rhs.second].postorder_index);
  303|  4.54k|        return lhs_indices < rhs_indices;
  304|  4.54k|      });
  305|  4.54k|  return out;
  306|  4.54k|}
_ZZN8spvtools3CFAINS_3val10BasicBlockEE19CalculateDominatorsERKNSt3__16vectorIPKS2_NS4_9allocatorIS7_EEEENS4_8functionIFPKNS5_IPS2_NS8_ISE_EEEES7_EEEENKUlSE_E_clESE_:
  240|   251k|                              [&idoms, undefined_dom](BB* pred) {
  241|   251k|                                return idoms.count(pred) &&
  ------------------
  |  Branch (241:40): [True: 242k, False: 8.77k]
  ------------------
  242|   251k|                                       idoms[pred].dominator != undefined_dom;
  ------------------
  |  Branch (242:40): [True: 241k, False: 1.15k]
  ------------------
  243|   251k|                              });
_ZZN8spvtools3CFAINS_3val10BasicBlockEE19CalculateDominatorsERKNSt3__16vectorIPKS2_NS4_9allocatorIS7_EEEENS4_8functionIFPKNS5_IPS2_NS8_ISE_EEEES7_EEEENKUlRKNS4_4pairISE_SE_EESO_E_clESO_SO_:
  294|   567k|               const std::pair<bb_ptr, bb_ptr>& rhs) {
  295|   567k|        assert(lhs.first);
  296|      0|        assert(lhs.second);
  297|      0|        assert(rhs.first);
  298|      0|        assert(rhs.second);
  299|      0|        auto lhs_indices = std::make_pair(idoms[lhs.first].postorder_index,
  300|   567k|                                          idoms[lhs.second].postorder_index);
  301|   567k|        auto rhs_indices = std::make_pair(idoms[rhs.first].postorder_index,
  302|   567k|                                          idoms[rhs.second].postorder_index);
  303|   567k|        return lhs_indices < rhs_indices;
  304|   567k|      });
_ZN8spvtools3CFAINS_3val10BasicBlockEE19DepthFirstTraversalEPKS2_NSt3__18functionIFPKNS6_6vectorIPS2_NS6_9allocatorIS9_EEEES5_EEENS7_IFvS5_EEESI_NS7_IFvS5_S5_EEENS7_IFbS5_EEE:
  179|  26.7k|    std::function<bool(cbb_ptr)> terminal) {
  180|  26.7k|  assert(successor_func && "The successor function cannot be empty.");
  181|      0|  assert(preorder && "The preorder function cannot be empty.");
  182|      0|  assert(postorder && "The postorder function cannot be empty.");
  183|      0|  assert(terminal && "The terminal function cannot be empty.");
  184|       |
  185|      0|  std::unordered_set<uint32_t> processed;
  186|       |
  187|       |  /// NOTE: work_list is the sequence of nodes from the root node to the node
  188|       |  /// being processed in the traversal
  189|  26.7k|  std::vector<block_info> work_list;
  190|  26.7k|  work_list.reserve(10);
  191|       |
  192|  26.7k|  work_list.push_back({entry, std::begin(*successor_func(entry))});
  193|  26.7k|  preorder(entry);
  194|  26.7k|  processed.insert(entry->id());
  195|       |
  196|  1.31M|  while (!work_list.empty()) {
  ------------------
  |  Branch (196:10): [True: 1.29M, False: 26.7k]
  ------------------
  197|  1.29M|    block_info& top = work_list.back();
  198|  1.29M|    if (terminal(top.block) || top.iter == end(*successor_func(top.block))) {
  ------------------
  |  Branch (198:9): [True: 0, False: 1.29M]
  |  Branch (198:9): [True: 508k, False: 783k]
  |  Branch (198:32): [True: 508k, False: 783k]
  ------------------
  199|   508k|      postorder(top.block);
  200|   508k|      work_list.pop_back();
  201|   783k|    } else {
  202|   783k|      BB* child = *top.iter;
  203|   783k|      top.iter++;
  204|   783k|      if (backedge && FindInWorkList(work_list, child->id())) {
  ------------------
  |  Branch (204:11): [True: 63.8k, False: 719k]
  |  Branch (204:23): [True: 4.17k, False: 59.6k]
  ------------------
  205|  4.17k|        backedge(top.block, child);
  206|  4.17k|      }
  207|   783k|      if (processed.count(child->id()) == 0) {
  ------------------
  |  Branch (207:11): [True: 481k, False: 301k]
  ------------------
  208|   481k|        preorder(child);
  209|   481k|        work_list.emplace_back(
  210|   481k|            block_info{child, std::begin(*successor_func(child))});
  211|   481k|        processed.insert(child->id());
  212|   481k|      }
  213|   783k|    }
  214|  1.29M|  }
  215|  26.7k|}
_ZN8spvtools3CFAINS_3val10BasicBlockEE14FindInWorkListERKNSt3__16vectorINS3_10block_infoENS4_9allocatorIS6_EEEEj:
  156|  63.8k|                             uint32_t id) {
  157|   618k|  for (const auto& b : work_list) {
  ------------------
  |  Branch (157:22): [True: 618k, False: 59.6k]
  ------------------
  158|   618k|    if (b.block->id() == id) return true;
  ------------------
  |  Branch (158:9): [True: 4.17k, False: 614k]
  ------------------
  159|   618k|  }
  160|  59.6k|  return false;
  161|  63.8k|}
_ZN8spvtools3CFAINS_3val10BasicBlockEE19ComputeAugmentedCFGERNSt3__16vectorIPS2_NS4_9allocatorIS6_EEEES6_S6_PNS4_13unordered_mapIPKS2_S9_NS4_4hashISD_EENS4_8equal_toISD_EENS7_INS4_4pairIKSD_S9_EEEEEESN_NS4_8functionIFPKS9_SD_EEESS_:
  353|  3.89k|    get_blocks_func succ_func, get_blocks_func pred_func) {
  354|       |  // Compute the successors of the pseudo-entry block, and
  355|       |  // the predecessors of the pseudo exit block.
  356|  3.89k|  auto sources = TraversalRoots(ordered_blocks, succ_func, pred_func);
  357|       |
  358|       |  // For the predecessor traversals, reverse the order of blocks.  This
  359|       |  // will affect the post-dominance calculation as follows:
  360|       |  //  - Suppose you have blocks A and B, with A appearing before B in
  361|       |  //    the list of blocks.
  362|       |  //  - Also, A branches only to B, and B branches only to A.
  363|       |  //  - We want to compute A as dominating B, and B as post-dominating B.
  364|       |  // By using reversed blocks for predecessor traversal roots discovery,
  365|       |  // we'll add an edge from B to the pseudo-exit node, rather than from A.
  366|       |  // All this is needed to correctly process the dominance/post-dominance
  367|       |  // constraint when A is a loop header that points to itself as its
  368|       |  // own continue target, and B is the latch block for the loop.
  369|  3.89k|  std::vector<BB*> reversed_blocks(ordered_blocks.rbegin(),
  370|  3.89k|                                   ordered_blocks.rend());
  371|  3.89k|  auto sinks = TraversalRoots(reversed_blocks, pred_func, succ_func);
  372|       |
  373|       |  // Wire up the pseudo entry block.
  374|  3.89k|  (*augmented_successors_map)[pseudo_entry_block] = sources;
  375|  9.05k|  for (auto block : sources) {
  ------------------
  |  Branch (375:19): [True: 9.05k, False: 3.89k]
  ------------------
  376|  9.05k|    auto& augmented_preds = (*augmented_predecessors_map)[block];
  377|  9.05k|    const auto preds = pred_func(block);
  378|  9.05k|    augmented_preds.reserve(1 + preds->size());
  379|  9.05k|    augmented_preds.push_back(pseudo_entry_block);
  380|  9.05k|    augmented_preds.insert(augmented_preds.end(), preds->begin(), preds->end());
  381|  9.05k|  }
  382|       |
  383|       |  // Wire up the pseudo exit block.
  384|  3.89k|  (*augmented_predecessors_map)[pseudo_exit_block] = sinks;
  385|  11.6k|  for (auto block : sinks) {
  ------------------
  |  Branch (385:19): [True: 11.6k, False: 3.89k]
  ------------------
  386|  11.6k|    auto& augmented_succ = (*augmented_successors_map)[block];
  387|  11.6k|    const auto succ = succ_func(block);
  388|  11.6k|    augmented_succ.reserve(1 + succ->size());
  389|  11.6k|    augmented_succ.push_back(pseudo_exit_block);
  390|  11.6k|    augmented_succ.insert(augmented_succ.end(), succ->begin(), succ->end());
  391|  11.6k|  }
  392|  3.89k|}
_ZN8spvtools3CFAINS_3val10BasicBlockEE14TraversalRootsERKNSt3__16vectorIPS2_NS4_9allocatorIS6_EEEENS4_8functionIFPSA_PKS2_EEESH_:
  311|  7.78k|                                         get_blocks_func pred_func) {
  312|       |  // The set of nodes which have been visited from any of the roots so far.
  313|  7.78k|  std::unordered_set<const BB*> visited;
  314|       |
  315|  7.78k|  auto mark_visited = [&visited](const BB* b) { visited.insert(b); };
  316|  7.78k|  auto ignore_block = [](const BB*) {};
  317|  7.78k|  auto no_terminal_blocks = [](const BB*) { return false; };
  318|       |
  319|  7.78k|  auto traverse_from_root = [&mark_visited, &succ_func, &ignore_block,
  320|  7.78k|                             &no_terminal_blocks](const BB* entry) {
  321|  7.78k|    DepthFirstTraversal(entry, succ_func, mark_visited, ignore_block,
  322|  7.78k|                        no_terminal_blocks);
  323|  7.78k|  };
  324|       |
  325|  7.78k|  std::vector<BB*> result;
  326|       |
  327|       |  // First collect nodes without predecessors.
  328|  96.9k|  for (auto block : blocks) {
  ------------------
  |  Branch (328:19): [True: 96.9k, False: 7.78k]
  ------------------
  329|  96.9k|    if (pred_func(block)->empty()) {
  ------------------
  |  Branch (329:9): [True: 18.4k, False: 78.5k]
  ------------------
  330|  18.4k|      assert(visited.count(block) == 0 && "Malformed graph!");
  331|      0|      result.push_back(block);
  332|  18.4k|      traverse_from_root(block);
  333|  18.4k|    }
  334|  96.9k|  }
  335|       |
  336|       |  // Now collect other stranded nodes.  These must be in unreachable cycles.
  337|  96.9k|  for (auto block : blocks) {
  ------------------
  |  Branch (337:19): [True: 96.9k, False: 7.78k]
  ------------------
  338|  96.9k|    if (visited.count(block) == 0) {
  ------------------
  |  Branch (338:9): [True: 2.23k, False: 94.7k]
  ------------------
  339|  2.23k|      result.push_back(block);
  340|  2.23k|      traverse_from_root(block);
  341|  2.23k|    }
  342|  96.9k|  }
  343|       |
  344|  7.78k|  return result;
  345|  7.78k|}
_ZZN8spvtools3CFAINS_3val10BasicBlockEE14TraversalRootsERKNSt3__16vectorIPS2_NS4_9allocatorIS6_EEEENS4_8functionIFPSA_PKS2_EEESH_ENKUlSF_E2_clESF_:
  320|  20.6k|                             &no_terminal_blocks](const BB* entry) {
  321|  20.6k|    DepthFirstTraversal(entry, succ_func, mark_visited, ignore_block,
  322|  20.6k|                        no_terminal_blocks);
  323|  20.6k|  };
_ZZN8spvtools3CFAINS_3val10BasicBlockEE14TraversalRootsERKNSt3__16vectorIPS2_NS4_9allocatorIS6_EEEENS4_8functionIFPSA_PKS2_EEESH_ENKUlSF_E_clESF_:
  315|   373k|  auto mark_visited = [&visited](const BB* b) { visited.insert(b); };
_ZZN8spvtools3CFAINS_3val10BasicBlockEE14TraversalRootsERKNSt3__16vectorIPS2_NS4_9allocatorIS6_EEEENS4_8functionIFPSA_PKS2_EEESH_ENKUlSF_E0_clESF_:
  316|   373k|  auto ignore_block = [](const BB*) {};
_ZZN8spvtools3CFAINS_3val10BasicBlockEE14TraversalRootsERKNSt3__16vectorIPS2_NS4_9allocatorIS6_EEEENS4_8functionIFPSA_PKS2_EEESH_ENKUlSF_E1_clESF_:
  317|   938k|  auto no_terminal_blocks = [](const BB*) { return false; };

spvDiagnosticCreate:
   28|  1.20k|                                   const char* message) {
   29|  1.20k|  spv_diagnostic diagnostic = new spv_diagnostic_t;
   30|  1.20k|  if (!diagnostic) return nullptr;
  ------------------
  |  Branch (30:7): [True: 0, False: 1.20k]
  ------------------
   31|  1.20k|  size_t length = strlen(message) + 1;
   32|  1.20k|  diagnostic->error = new char[length];
   33|  1.20k|  if (!diagnostic->error) {
  ------------------
  |  Branch (33:7): [True: 0, False: 1.20k]
  ------------------
   34|      0|    delete diagnostic;
   35|      0|    return nullptr;
   36|      0|  }
   37|  1.20k|  diagnostic->position = *position;
   38|  1.20k|  diagnostic->isTextSource = false;
   39|  1.20k|  memset(diagnostic->error, 0, length);
   40|  1.20k|  strcpy(diagnostic->error, message);
   41|  1.20k|  return diagnostic;
   42|  1.20k|}
spvDiagnosticDestroy:
   44|  13.8k|void spvDiagnosticDestroy(spv_diagnostic diagnostic) {
   45|  13.8k|  if (!diagnostic) return;
  ------------------
  |  Branch (45:7): [True: 12.6k, False: 1.20k]
  ------------------
   46|  1.20k|  delete[] diagnostic->error;
   47|  1.20k|  delete diagnostic;
   48|  1.20k|}
_ZN8spvtools16DiagnosticStreamC2EOS0_:
   78|     18|      error_(other.error_) {
   79|       |  // Prevent the other object from emitting output during destruction.
   80|     18|  other.error_ = SPV_FAILED_MATCH;
   81|       |  // Some platforms are missing support for std::ostringstream functionality,
   82|       |  // including:  move constructor, swap method.  Either would have been a
   83|       |  // better choice than copying the string.
   84|     18|  stream_ << other.stream_.str();
   85|     18|}
_ZN8spvtools16DiagnosticStreamD2Ev:
   87|  13.5k|DiagnosticStream::~DiagnosticStream() {
   88|  13.5k|  if (error_ != SPV_FAILED_MATCH && consumer_ != nullptr) {
  ------------------
  |  Branch (88:7): [True: 13.5k, False: 18]
  |  Branch (88:37): [True: 12.2k, False: 1.33k]
  ------------------
   89|  12.2k|    auto level = SPV_MSG_ERROR;
   90|  12.2k|    switch (error_) {
   91|      0|      case SPV_SUCCESS:
  ------------------
  |  Branch (91:7): [True: 0, False: 12.2k]
  ------------------
   92|      0|      case SPV_REQUESTED_TERMINATION:  // Essentially success.
  ------------------
  |  Branch (92:7): [True: 0, False: 12.2k]
  ------------------
   93|      0|        level = SPV_MSG_INFO;
   94|      0|        break;
   95|  1.77k|      case SPV_WARNING:
  ------------------
  |  Branch (95:7): [True: 1.77k, False: 10.4k]
  ------------------
   96|  1.77k|        level = SPV_MSG_WARNING;
   97|  1.77k|        break;
   98|      0|      case SPV_UNSUPPORTED:
  ------------------
  |  Branch (98:7): [True: 0, False: 12.2k]
  ------------------
   99|    100|      case SPV_ERROR_INTERNAL:
  ------------------
  |  Branch (99:7): [True: 100, False: 12.1k]
  ------------------
  100|    100|      case SPV_ERROR_INVALID_TABLE:
  ------------------
  |  Branch (100:7): [True: 0, False: 12.2k]
  ------------------
  101|    100|        level = SPV_MSG_INTERNAL_ERROR;
  102|    100|        break;
  103|      0|      case SPV_ERROR_OUT_OF_MEMORY:
  ------------------
  |  Branch (103:7): [True: 0, False: 12.2k]
  ------------------
  104|      0|        level = SPV_MSG_FATAL;
  105|      0|        break;
  106|  10.3k|      default:
  ------------------
  |  Branch (106:7): [True: 10.3k, False: 1.87k]
  ------------------
  107|  10.3k|        break;
  108|  12.2k|    }
  109|  12.2k|    if (disassembled_instruction_.size() > 0)
  ------------------
  |  Branch (109:9): [True: 4.43k, False: 7.78k]
  ------------------
  110|  4.43k|      stream_ << std::endl << "  " << disassembled_instruction_ << std::endl;
  111|       |
  112|  12.2k|    consumer_(level, "input", position_, stream_.str().c_str());
  113|  12.2k|  }
  114|  13.5k|}
_ZN8spvtools30UseDiagnosticAsMessageConsumerEP13spv_context_tPP16spv_diagnostic_t:
  117|  12.6k|                                    spv_diagnostic* diagnostic) {
  118|  12.6k|  assert(diagnostic && *diagnostic == nullptr);
  119|       |
  120|      0|  auto create_diagnostic = [diagnostic](spv_message_level_t, const char*,
  121|  12.6k|                                        const spv_position_t& position,
  122|  12.6k|                                        const char* message) {
  123|  12.6k|    auto p = position;
  124|  12.6k|    spvDiagnosticDestroy(*diagnostic);  // Avoid memory leak.
  125|  12.6k|    *diagnostic = spvDiagnosticCreate(&p, message);
  126|  12.6k|  };
  127|  12.6k|  SetContextMessageConsumer(context, std::move(create_diagnostic));
  128|  12.6k|}
diagnostic.cpp:_ZZN8spvtools30UseDiagnosticAsMessageConsumerEP13spv_context_tPP16spv_diagnostic_tENK3$_0clE19spv_message_level_tPKcRK14spv_position_tS8_:
  122|  1.20k|                                        const char* message) {
  123|  1.20k|    auto p = position;
  124|  1.20k|    spvDiagnosticDestroy(*diagnostic);  // Avoid memory leak.
  125|  1.20k|    *diagnostic = spvDiagnosticCreate(&p, message);
  126|  1.20k|  };

_ZN8spvtools16DiagnosticStreamcv12spv_result_tEv:
   57|  12.2k|  operator spv_result_t() { return error_; }
_ZN8spvtools16DiagnosticStreamC2E14spv_position_tRKNSt3__18functionIFv19spv_message_level_tPKcRKS1_S6_EEERKNS2_12basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEE12spv_result_t:
   37|  13.5k|        error_(error) {}
_ZN8spvtools16DiagnosticStreamlsIA15_cEERS0_RKT_:
   51|    328|  DiagnosticStream& operator<<(const T& val) {
   52|    328|    stream_ << val;
   53|    328|    return *this;
   54|    328|  }
_ZN8spvtools16DiagnosticStreamlsIA35_cEERS0_RKT_:
   51|    671|  DiagnosticStream& operator<<(const T& val) {
   52|    671|    stream_ << val;
   53|    671|    return *this;
   54|    671|  }
_ZN8spvtools16DiagnosticStreamlsIA30_cEERS0_RKT_:
   51|  1.84k|  DiagnosticStream& operator<<(const T& val) {
   52|  1.84k|    stream_ << val;
   53|  1.84k|    return *this;
   54|  1.84k|  }
_ZN8spvtools16DiagnosticStreamlsIA24_cEERS0_RKT_:
   51|    203|  DiagnosticStream& operator<<(const T& val) {
   52|    203|    stream_ << val;
   53|    203|    return *this;
   54|    203|  }
_ZN8spvtools16DiagnosticStreamlsIA22_cEERS0_RKT_:
   51|    351|  DiagnosticStream& operator<<(const T& val) {
   52|    351|    stream_ << val;
   53|    351|    return *this;
   54|    351|  }
_ZN8spvtools16DiagnosticStreamlsIA65_cEERS0_RKT_:
   51|     17|  DiagnosticStream& operator<<(const T& val) {
   52|     17|    stream_ << val;
   53|     17|    return *this;
   54|     17|  }
_ZN8spvtools16DiagnosticStreamlsIA31_cEERS0_RKT_:
   51|    445|  DiagnosticStream& operator<<(const T& val) {
   52|    445|    stream_ << val;
   53|    445|    return *this;
   54|    445|  }
_ZN8spvtools16DiagnosticStreamlsIA47_cEERS0_RKT_:
   51|    129|  DiagnosticStream& operator<<(const T& val) {
   52|    129|    stream_ << val;
   53|    129|    return *this;
   54|    129|  }
_ZN8spvtools16DiagnosticStreamlsIA54_cEERS0_RKT_:
   51|     40|  DiagnosticStream& operator<<(const T& val) {
   52|     40|    stream_ << val;
   53|     40|    return *this;
   54|     40|  }
_ZN8spvtools16DiagnosticStreamlsImEERS0_RKT_:
   51|  2.12k|  DiagnosticStream& operator<<(const T& val) {
   52|  2.12k|    stream_ << val;
   53|  2.12k|    return *this;
   54|  2.12k|  }
_ZN8spvtools16DiagnosticStreamlsIA26_cEERS0_RKT_:
   51|    243|  DiagnosticStream& operator<<(const T& val) {
   52|    243|    stream_ << val;
   53|    243|    return *this;
   54|    243|  }
_ZN8spvtools16DiagnosticStreamlsIA29_cEERS0_RKT_:
   51|    269|  DiagnosticStream& operator<<(const T& val) {
   52|    269|    stream_ << val;
   53|    269|    return *this;
   54|    269|  }
_ZN8spvtools16DiagnosticStreamlsIPKcEERS0_RKT_:
   51|  4.14k|  DiagnosticStream& operator<<(const T& val) {
   52|  4.14k|    stream_ << val;
   53|  4.14k|    return *this;
   54|  4.14k|  }
_ZN8spvtools16DiagnosticStreamlsIA12_cEERS0_RKT_:
   51|    197|  DiagnosticStream& operator<<(const T& val) {
   52|    197|    stream_ << val;
   53|    197|    return *this;
   54|    197|  }
_ZN8spvtools16DiagnosticStreamlsIA40_cEERS0_RKT_:
   51|    693|  DiagnosticStream& operator<<(const T& val) {
   52|    693|    stream_ << val;
   53|    693|    return *this;
   54|    693|  }
_ZN8spvtools16DiagnosticStreamlsIjEERS0_RKT_:
   51|  3.56k|  DiagnosticStream& operator<<(const T& val) {
   52|  3.56k|    stream_ << val;
   53|  3.56k|    return *this;
   54|  3.56k|  }
_ZN8spvtools16DiagnosticStreamlsIA36_cEERS0_RKT_:
   51|    232|  DiagnosticStream& operator<<(const T& val) {
   52|    232|    stream_ << val;
   53|    232|    return *this;
   54|    232|  }
_ZN8spvtools16DiagnosticStreamlsIA3_cEERS0_RKT_:
   51|    446|  DiagnosticStream& operator<<(const T& val) {
   52|    446|    stream_ << val;
   53|    446|    return *this;
   54|    446|  }
_ZN8spvtools16DiagnosticStreamlsIA55_cEERS0_RKT_:
   51|     34|  DiagnosticStream& operator<<(const T& val) {
   52|     34|    stream_ << val;
   53|     34|    return *this;
   54|     34|  }
_ZN8spvtools16DiagnosticStreamlsIA23_cEERS0_RKT_:
   51|    649|  DiagnosticStream& operator<<(const T& val) {
   52|    649|    stream_ << val;
   53|    649|    return *this;
   54|    649|  }
_ZN8spvtools16DiagnosticStreamlsIA9_cEERS0_RKT_:
   51|    882|  DiagnosticStream& operator<<(const T& val) {
   52|    882|    stream_ << val;
   53|    882|    return *this;
   54|    882|  }
_ZN8spvtools16DiagnosticStreamlsIA10_cEERS0_RKT_:
   51|     33|  DiagnosticStream& operator<<(const T& val) {
   52|     33|    stream_ << val;
   53|     33|    return *this;
   54|     33|  }
_ZN8spvtools16DiagnosticStreamlsIA49_cEERS0_RKT_:
   51|    177|  DiagnosticStream& operator<<(const T& val) {
   52|    177|    stream_ << val;
   53|    177|    return *this;
   54|    177|  }
_ZN8spvtools16DiagnosticStreamlsIA104_cEERS0_RKT_:
   51|      5|  DiagnosticStream& operator<<(const T& val) {
   52|      5|    stream_ << val;
   53|      5|    return *this;
   54|      5|  }
_ZN8spvtools16DiagnosticStreamlsIA25_cEERS0_RKT_:
   51|    927|  DiagnosticStream& operator<<(const T& val) {
   52|    927|    stream_ << val;
   53|    927|    return *this;
   54|    927|  }
_ZN8spvtools16DiagnosticStreamlsIA48_cEERS0_RKT_:
   51|     44|  DiagnosticStream& operator<<(const T& val) {
   52|     44|    stream_ << val;
   53|     44|    return *this;
   54|     44|  }
_ZN8spvtools16DiagnosticStreamlsIA38_cEERS0_RKT_:
   51|  2.21k|  DiagnosticStream& operator<<(const T& val) {
   52|  2.21k|    stream_ << val;
   53|  2.21k|    return *this;
   54|  2.21k|  }
_ZN8spvtools16DiagnosticStreamlsINSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEEEERS0_RKT_:
   51|  5.91k|  DiagnosticStream& operator<<(const T& val) {
   52|  5.91k|    stream_ << val;
   53|  5.91k|    return *this;
   54|  5.91k|  }
_ZN8spvtools16DiagnosticStreamlsIA2_cEERS0_RKT_:
   51|  2.76k|  DiagnosticStream& operator<<(const T& val) {
   52|  2.76k|    stream_ << val;
   53|  2.76k|    return *this;
   54|  2.76k|  }
_ZN8spvtools16DiagnosticStreamlsIA11_cEERS0_RKT_:
   51|    335|  DiagnosticStream& operator<<(const T& val) {
   52|    335|    stream_ << val;
   53|    335|    return *this;
   54|    335|  }
_ZN8spvtools16DiagnosticStreamlsIA32_cEERS0_RKT_:
   51|    299|  DiagnosticStream& operator<<(const T& val) {
   52|    299|    stream_ << val;
   53|    299|    return *this;
   54|    299|  }
_ZN8spvtools16DiagnosticStreamlsIA51_cEERS0_RKT_:
   51|    715|  DiagnosticStream& operator<<(const T& val) {
   52|    715|    stream_ << val;
   53|    715|    return *this;
   54|    715|  }
_ZN8spvtools16DiagnosticStreamlsIA33_cEERS0_RKT_:
   51|    106|  DiagnosticStream& operator<<(const T& val) {
   52|    106|    stream_ << val;
   53|    106|    return *this;
   54|    106|  }
_ZN8spvtools16DiagnosticStreamlsIA8_cEERS0_RKT_:
   51|    136|  DiagnosticStream& operator<<(const T& val) {
   52|    136|    stream_ << val;
   53|    136|    return *this;
   54|    136|  }
_ZN8spvtools16DiagnosticStreamlsIA7_cEERS0_RKT_:
   51|    230|  DiagnosticStream& operator<<(const T& val) {
   52|    230|    stream_ << val;
   53|    230|    return *this;
   54|    230|  }
_ZN8spvtools16DiagnosticStreamlsIA42_cEERS0_RKT_:
   51|     19|  DiagnosticStream& operator<<(const T& val) {
   52|     19|    stream_ << val;
   53|     19|    return *this;
   54|     19|  }
_ZN8spvtools16DiagnosticStreamlsIA37_cEERS0_RKT_:
   51|    129|  DiagnosticStream& operator<<(const T& val) {
   52|    129|    stream_ << val;
   53|    129|    return *this;
   54|    129|  }
_ZN8spvtools16DiagnosticStreamlsIA41_cEERS0_RKT_:
   51|     51|  DiagnosticStream& operator<<(const T& val) {
   52|     51|    stream_ << val;
   53|     51|    return *this;
   54|     51|  }
_ZN8spvtools16DiagnosticStreamlsIA63_cEERS0_RKT_:
   51|    668|  DiagnosticStream& operator<<(const T& val) {
   52|    668|    stream_ << val;
   53|    668|    return *this;
   54|    668|  }
_ZN8spvtools16DiagnosticStreamlsIA61_cEERS0_RKT_:
   51|    679|  DiagnosticStream& operator<<(const T& val) {
   52|    679|    stream_ << val;
   53|    679|    return *this;
   54|    679|  }
_ZN8spvtools16DiagnosticStreamlsIA44_cEERS0_RKT_:
   51|    182|  DiagnosticStream& operator<<(const T& val) {
   52|    182|    stream_ << val;
   53|    182|    return *this;
   54|    182|  }
_ZN8spvtools16DiagnosticStreamlsIA69_cEERS0_RKT_:
   51|     19|  DiagnosticStream& operator<<(const T& val) {
   52|     19|    stream_ << val;
   53|     19|    return *this;
   54|     19|  }
_ZN8spvtools16DiagnosticStreamlsIA101_cEERS0_RKT_:
   51|    774|  DiagnosticStream& operator<<(const T& val) {
   52|    774|    stream_ << val;
   53|    774|    return *this;
   54|    774|  }
_ZN8spvtools16DiagnosticStreamlsIA13_cEERS0_RKT_:
   51|    403|  DiagnosticStream& operator<<(const T& val) {
   52|    403|    stream_ << val;
   53|    403|    return *this;
   54|    403|  }
_ZN8spvtools16DiagnosticStreamlsIA93_cEERS0_RKT_:
   51|      3|  DiagnosticStream& operator<<(const T& val) {
   52|      3|    stream_ << val;
   53|      3|    return *this;
   54|      3|  }
_ZN8spvtools16DiagnosticStreamlsIA52_cEERS0_RKT_:
   51|    102|  DiagnosticStream& operator<<(const T& val) {
   52|    102|    stream_ << val;
   53|    102|    return *this;
   54|    102|  }
_ZN8spvtools16DiagnosticStreamlsIA46_cEERS0_RKT_:
   51|     46|  DiagnosticStream& operator<<(const T& val) {
   52|     46|    stream_ << val;
   53|     46|    return *this;
   54|     46|  }
_ZN8spvtools16DiagnosticStreamlsIA53_cEERS0_RKT_:
   51|     43|  DiagnosticStream& operator<<(const T& val) {
   52|     43|    stream_ << val;
   53|     43|    return *this;
   54|     43|  }
_ZN8spvtools16DiagnosticStreamlsIA45_cEERS0_RKT_:
   51|     74|  DiagnosticStream& operator<<(const T& val) {
   52|     74|    stream_ << val;
   53|     74|    return *this;
   54|     74|  }
_ZN8spvtools16DiagnosticStreamlsIA67_cEERS0_RKT_:
   51|     11|  DiagnosticStream& operator<<(const T& val) {
   52|     11|    stream_ << val;
   53|     11|    return *this;
   54|     11|  }
_ZN8spvtools16DiagnosticStreamlsIA19_cEERS0_RKT_:
   51|  1.42k|  DiagnosticStream& operator<<(const T& val) {
   52|  1.42k|    stream_ << val;
   53|  1.42k|    return *this;
   54|  1.42k|  }
_ZN8spvtools16DiagnosticStreamlsIA28_cEERS0_RKT_:
   51|     91|  DiagnosticStream& operator<<(const T& val) {
   52|     91|    stream_ << val;
   53|     91|    return *this;
   54|     91|  }
_ZN8spvtools16DiagnosticStreamlsIA76_cEERS0_RKT_:
   51|      9|  DiagnosticStream& operator<<(const T& val) {
   52|      9|    stream_ << val;
   53|      9|    return *this;
   54|      9|  }
_ZN8spvtools16DiagnosticStreamlsIA34_cEERS0_RKT_:
   51|    483|  DiagnosticStream& operator<<(const T& val) {
   52|    483|    stream_ << val;
   53|    483|    return *this;
   54|    483|  }
_ZN8spvtools16DiagnosticStreamlsIA39_cEERS0_RKT_:
   51|    736|  DiagnosticStream& operator<<(const T& val) {
   52|    736|    stream_ << val;
   53|    736|    return *this;
   54|    736|  }
_ZN8spvtools16DiagnosticStreamlsIA43_cEERS0_RKT_:
   51|     21|  DiagnosticStream& operator<<(const T& val) {
   52|     21|    stream_ << val;
   53|     21|    return *this;
   54|     21|  }
_ZN8spvtools16DiagnosticStreamlsIA57_cEERS0_RKT_:
   51|     78|  DiagnosticStream& operator<<(const T& val) {
   52|     78|    stream_ << val;
   53|     78|    return *this;
   54|     78|  }
_ZN8spvtools16DiagnosticStreamlsIA16_cEERS0_RKT_:
   51|    143|  DiagnosticStream& operator<<(const T& val) {
   52|    143|    stream_ << val;
   53|    143|    return *this;
   54|    143|  }
_ZN8spvtools16DiagnosticStreamlsIA17_cEERS0_RKT_:
   51|    423|  DiagnosticStream& operator<<(const T& val) {
   52|    423|    stream_ << val;
   53|    423|    return *this;
   54|    423|  }
_ZN8spvtools16DiagnosticStreamlsIA58_cEERS0_RKT_:
   51|    112|  DiagnosticStream& operator<<(const T& val) {
   52|    112|    stream_ << val;
   53|    112|    return *this;
   54|    112|  }
_ZN8spvtools16DiagnosticStreamlsIA59_cEERS0_RKT_:
   51|     12|  DiagnosticStream& operator<<(const T& val) {
   52|     12|    stream_ << val;
   53|     12|    return *this;
   54|     12|  }
_ZN8spvtools16DiagnosticStreamlsIA64_cEERS0_RKT_:
   51|      1|  DiagnosticStream& operator<<(const T& val) {
   52|      1|    stream_ << val;
   53|      1|    return *this;
   54|      1|  }
_ZN8spvtools16DiagnosticStreamlsIA14_cEERS0_RKT_:
   51|    369|  DiagnosticStream& operator<<(const T& val) {
   52|    369|    stream_ << val;
   53|    369|    return *this;
   54|    369|  }
_ZN8spvtools16DiagnosticStreamlsIA60_cEERS0_RKT_:
   51|      3|  DiagnosticStream& operator<<(const T& val) {
   52|      3|    stream_ << val;
   53|      3|    return *this;
   54|      3|  }
_ZN8spvtools16DiagnosticStreamlsIA62_cEERS0_RKT_:
   51|      3|  DiagnosticStream& operator<<(const T& val) {
   52|      3|    stream_ << val;
   53|      3|    return *this;
   54|      3|  }
_ZN8spvtools16DiagnosticStreamlsIA50_cEERS0_RKT_:
   51|     51|  DiagnosticStream& operator<<(const T& val) {
   52|     51|    stream_ << val;
   53|     51|    return *this;
   54|     51|  }
_ZN8spvtools16DiagnosticStreamlsIA27_cEERS0_RKT_:
   51|     58|  DiagnosticStream& operator<<(const T& val) {
   52|     58|    stream_ << val;
   53|     58|    return *this;
   54|     58|  }
_ZN8spvtools16DiagnosticStreamlsIA75_cEERS0_RKT_:
   51|     32|  DiagnosticStream& operator<<(const T& val) {
   52|     32|    stream_ << val;
   53|     32|    return *this;
   54|     32|  }
_ZN8spvtools16DiagnosticStreamlsIA70_cEERS0_RKT_:
   51|      9|  DiagnosticStream& operator<<(const T& val) {
   52|      9|    stream_ << val;
   53|      9|    return *this;
   54|      9|  }
_ZN8spvtools16DiagnosticStreamlsIA56_cEERS0_RKT_:
   51|    232|  DiagnosticStream& operator<<(const T& val) {
   52|    232|    stream_ << val;
   53|    232|    return *this;
   54|    232|  }
_ZN8spvtools16DiagnosticStreamlsIA68_cEERS0_RKT_:
   51|     43|  DiagnosticStream& operator<<(const T& val) {
   52|     43|    stream_ << val;
   53|     43|    return *this;
   54|     43|  }
_ZN8spvtools16DiagnosticStreamlsIA6_cEERS0_RKT_:
   51|     38|  DiagnosticStream& operator<<(const T& val) {
   52|     38|    stream_ << val;
   53|     38|    return *this;
   54|     38|  }
_ZN8spvtools16DiagnosticStreamlsIA112_cEERS0_RKT_:
   51|      1|  DiagnosticStream& operator<<(const T& val) {
   52|      1|    stream_ << val;
   53|      1|    return *this;
   54|      1|  }
_ZN8spvtools16DiagnosticStreamlsIA18_cEERS0_RKT_:
   51|    265|  DiagnosticStream& operator<<(const T& val) {
   52|    265|    stream_ << val;
   53|    265|    return *this;
   54|    265|  }
_ZN8spvtools16DiagnosticStreamlsIA91_cEERS0_RKT_:
   51|      1|  DiagnosticStream& operator<<(const T& val) {
   52|      1|    stream_ << val;
   53|      1|    return *this;
   54|      1|  }
_ZN8spvtools16DiagnosticStreamlsIA90_cEERS0_RKT_:
   51|      2|  DiagnosticStream& operator<<(const T& val) {
   52|      2|    stream_ << val;
   53|      2|    return *this;
   54|      2|  }
_ZN8spvtools16DiagnosticStreamlsIA92_cEERS0_RKT_:
   51|     30|  DiagnosticStream& operator<<(const T& val) {
   52|     30|    stream_ << val;
   53|     30|    return *this;
   54|     30|  }
_ZN8spvtools16DiagnosticStreamlsIA71_cEERS0_RKT_:
   51|      4|  DiagnosticStream& operator<<(const T& val) {
   52|      4|    stream_ << val;
   53|      4|    return *this;
   54|      4|  }
_ZN8spvtools16DiagnosticStreamlsIA95_cEERS0_RKT_:
   51|      1|  DiagnosticStream& operator<<(const T& val) {
   52|      1|    stream_ << val;
   53|      1|    return *this;
   54|      1|  }
_ZN8spvtools16DiagnosticStreamlsIA106_cEERS0_RKT_:
   51|     11|  DiagnosticStream& operator<<(const T& val) {
   52|     11|    stream_ << val;
   53|     11|    return *this;
   54|     11|  }
_ZN8spvtools16DiagnosticStreamlsIA84_cEERS0_RKT_:
   51|      8|  DiagnosticStream& operator<<(const T& val) {
   52|      8|    stream_ << val;
   53|      8|    return *this;
   54|      8|  }
_ZN8spvtools16DiagnosticStreamlsIA20_cEERS0_RKT_:
   51|     54|  DiagnosticStream& operator<<(const T& val) {
   52|     54|    stream_ << val;
   53|     54|    return *this;
   54|     54|  }
_ZN8spvtools16DiagnosticStreamlsIA73_cEERS0_RKT_:
   51|    203|  DiagnosticStream& operator<<(const T& val) {
   52|    203|    stream_ << val;
   53|    203|    return *this;
   54|    203|  }
_ZN8spvtools16DiagnosticStreamlsIA78_cEERS0_RKT_:
   51|     12|  DiagnosticStream& operator<<(const T& val) {
   52|     12|    stream_ << val;
   53|     12|    return *this;
   54|     12|  }
_ZN8spvtools16DiagnosticStreamlsIA66_cEERS0_RKT_:
   51|      4|  DiagnosticStream& operator<<(const T& val) {
   52|      4|    stream_ << val;
   53|      4|    return *this;
   54|      4|  }
_ZN8spvtools16DiagnosticStreamlsIA21_cEERS0_RKT_:
   51|     79|  DiagnosticStream& operator<<(const T& val) {
   52|     79|    stream_ << val;
   53|     79|    return *this;
   54|     79|  }
_ZN8spvtools16DiagnosticStreamlsIA5_cEERS0_RKT_:
   51|    290|  DiagnosticStream& operator<<(const T& val) {
   52|    290|    stream_ << val;
   53|    290|    return *this;
   54|    290|  }
_ZN8spvtools16DiagnosticStreamlsIA74_cEERS0_RKT_:
   51|     17|  DiagnosticStream& operator<<(const T& val) {
   52|     17|    stream_ << val;
   53|     17|    return *this;
   54|     17|  }
_ZN8spvtools16DiagnosticStreamlsIA129_cEERS0_RKT_:
   51|      1|  DiagnosticStream& operator<<(const T& val) {
   52|      1|    stream_ << val;
   53|      1|    return *this;
   54|      1|  }
_ZN8spvtools16DiagnosticStreamlsIA120_cEERS0_RKT_:
   51|      1|  DiagnosticStream& operator<<(const T& val) {
   52|      1|    stream_ << val;
   53|      1|    return *this;
   54|      1|  }
_ZN8spvtools16DiagnosticStreamlsIA114_cEERS0_RKT_:
   51|      4|  DiagnosticStream& operator<<(const T& val) {
   52|      4|    stream_ << val;
   53|      4|    return *this;
   54|      4|  }
_ZN8spvtools16DiagnosticStreamlsIA110_cEERS0_RKT_:
   51|      3|  DiagnosticStream& operator<<(const T& val) {
   52|      3|    stream_ << val;
   53|      3|    return *this;
   54|      3|  }
_ZN8spvtools16DiagnosticStreamlsIA196_cEERS0_RKT_:
   51|     10|  DiagnosticStream& operator<<(const T& val) {
   52|     10|    stream_ << val;
   53|     10|    return *this;
   54|     10|  }
_ZN8spvtools16DiagnosticStreamlsIA170_cEERS0_RKT_:
   51|      1|  DiagnosticStream& operator<<(const T& val) {
   52|      1|    stream_ << val;
   53|      1|    return *this;
   54|      1|  }
_ZN8spvtools16DiagnosticStreamlsIA82_cEERS0_RKT_:
   51|      1|  DiagnosticStream& operator<<(const T& val) {
   52|      1|    stream_ << val;
   53|      1|    return *this;
   54|      1|  }
_ZN8spvtools16DiagnosticStreamlsIA4_cEERS0_RKT_:
   51|    253|  DiagnosticStream& operator<<(const T& val) {
   52|    253|    stream_ << val;
   53|    253|    return *this;
   54|    253|  }
_ZN8spvtools16DiagnosticStreamlsIA85_cEERS0_RKT_:
   51|      2|  DiagnosticStream& operator<<(const T& val) {
   52|      2|    stream_ << val;
   53|      2|    return *this;
   54|      2|  }
_ZN8spvtools16DiagnosticStreamlsItEERS0_RKT_:
   51|  1.19k|  DiagnosticStream& operator<<(const T& val) {
   52|  1.19k|    stream_ << val;
   53|  1.19k|    return *this;
   54|  1.19k|  }
_ZN8spvtools16DiagnosticStreamlsIA288_cEERS0_RKT_:
   51|      1|  DiagnosticStream& operator<<(const T& val) {
   52|      1|    stream_ << val;
   53|      1|    return *this;
   54|      1|  }
_ZN8spvtools16DiagnosticStreamlsIA107_cEERS0_RKT_:
   51|      6|  DiagnosticStream& operator<<(const T& val) {
   52|      6|    stream_ << val;
   53|      6|    return *this;
   54|      6|  }
_ZN8spvtools16DiagnosticStreamlsIA124_cEERS0_RKT_:
   51|      1|  DiagnosticStream& operator<<(const T& val) {
   52|      1|    stream_ << val;
   53|      1|    return *this;
   54|      1|  }
_ZN8spvtools16DiagnosticStreamlsIA118_cEERS0_RKT_:
   51|      5|  DiagnosticStream& operator<<(const T& val) {
   52|      5|    stream_ << val;
   53|      5|    return *this;
   54|      5|  }
_ZN8spvtools16DiagnosticStreamlsIA166_cEERS0_RKT_:
   51|      3|  DiagnosticStream& operator<<(const T& val) {
   52|      3|    stream_ << val;
   53|      3|    return *this;
   54|      3|  }
_ZN8spvtools16DiagnosticStreamlsIA136_cEERS0_RKT_:
   51|      2|  DiagnosticStream& operator<<(const T& val) {
   52|      2|    stream_ << val;
   53|      2|    return *this;
   54|      2|  }
_ZN8spvtools16DiagnosticStreamlsIA116_cEERS0_RKT_:
   51|      2|  DiagnosticStream& operator<<(const T& val) {
   52|      2|    stream_ << val;
   53|      2|    return *this;
   54|      2|  }
_ZN8spvtools16DiagnosticStreamlsIlEERS0_RKT_:
   51|      9|  DiagnosticStream& operator<<(const T& val) {
   52|      9|    stream_ << val;
   53|      9|    return *this;
   54|      9|  }
_ZN8spvtools16DiagnosticStreamlsIFRNSt3__18ios_baseES4_EEERS0_RKT_:
   51|     30|  DiagnosticStream& operator<<(const T& val) {
   52|     30|    stream_ << val;
   53|     30|    return *this;
   54|     30|  }

_ZN8spvtools11disassemble23InstructionDisassemblerC2ERKNS_15AssemblyGrammarERNSt3__113basic_ostreamIcNS5_11char_traitsIcEEEEjNS5_8functionIFNS5_12basic_stringIcS8_NS5_9allocatorIcEEEEjEEE:
  215|  4.45k|      name_mapper_(std::move(name_mapper)) {}
_ZN8spvtools11disassemble23InstructionDisassembler15EmitInstructionERK24spv_parsed_instruction_tm:
  246|  4.45k|    const spv_parsed_instruction_t& inst, size_t inst_byte_offset) {
  247|  4.45k|  auto opcode = static_cast<spv::Op>(inst.opcode);
  248|       |
  249|  4.45k|  if (inst.result_id) {
  ------------------
  |  Branch (249:7): [True: 2.95k, False: 1.49k]
  ------------------
  250|  2.95k|    SetBlue();
  251|  2.95k|    const std::string id_name = name_mapper_(inst.result_id);
  252|  2.95k|    if (indent_)
  ------------------
  |  Branch (252:9): [True: 0, False: 2.95k]
  ------------------
  253|      0|      stream_ << std::setw(std::max(0, indent_ - 3 - int(id_name.size())));
  254|  2.95k|    stream_ << "%" << id_name;
  255|  2.95k|    ResetColor();
  256|  2.95k|    stream_ << " = ";
  257|  2.95k|  } else {
  258|  1.49k|    stream_ << std::string(indent_, ' ');
  259|  1.49k|  }
  260|       |
  261|  4.45k|  stream_ << "Op" << spvOpcodeString(opcode);
  262|       |
  263|   489k|  for (uint16_t i = 0; i < inst.num_operands; i++) {
  ------------------
  |  Branch (263:24): [True: 484k, False: 4.45k]
  ------------------
  264|   484k|    const spv_operand_type_t type = inst.operands[i].type;
  265|   484k|    assert(type != SPV_OPERAND_TYPE_NONE);
  266|   484k|    if (type == SPV_OPERAND_TYPE_RESULT_ID) continue;
  ------------------
  |  Branch (266:9): [True: 2.95k, False: 481k]
  ------------------
  267|   481k|    stream_ << " ";
  268|   481k|    EmitOperand(inst, i);
  269|   481k|  }
  270|       |
  271|  4.45k|  if (comment_ && opcode == spv::Op::OpName) {
  ------------------
  |  Branch (271:7): [True: 0, False: 4.45k]
  |  Branch (271:19): [True: 0, False: 0]
  ------------------
  272|      0|    const spv_parsed_operand_t& operand = inst.operands[0];
  273|      0|    const uint32_t word = inst.words[operand.offset];
  274|      0|    stream_ << "  ; id %" << word;
  275|      0|  }
  276|       |
  277|  4.45k|  if (show_byte_offset_) {
  ------------------
  |  Branch (277:7): [True: 0, False: 4.45k]
  ------------------
  278|      0|    SetGrey();
  279|      0|    auto saved_flags = stream_.flags();
  280|      0|    auto saved_fill = stream_.fill();
  281|      0|    stream_ << " ; 0x" << std::setw(8) << std::hex << std::setfill('0')
  282|      0|            << inst_byte_offset;
  283|      0|    stream_.flags(saved_flags);
  284|      0|    stream_.fill(saved_fill);
  285|      0|    ResetColor();
  286|      0|  }
  287|  4.45k|  stream_ << "\n";
  288|  4.45k|}
_ZN8spvtools11disassemble23InstructionDisassembler18EmitSectionCommentERK24spv_parsed_instruction_tRbS5_S5_:
  292|  4.45k|    bool& inserted_debug_space, bool& inserted_type_space) {
  293|  4.45k|  auto opcode = static_cast<spv::Op>(inst.opcode);
  294|  4.45k|  if (comment_ && opcode == spv::Op::OpFunction) {
  ------------------
  |  Branch (294:7): [True: 0, False: 4.45k]
  |  Branch (294:19): [True: 0, False: 0]
  ------------------
  295|      0|    stream_ << std::endl;
  296|      0|    stream_ << std::string(indent_, ' ');
  297|      0|    stream_ << "; Function " << name_mapper_(inst.result_id) << std::endl;
  298|      0|  }
  299|  4.45k|  if (comment_ && !inserted_decoration_space && spvOpcodeIsDecoration(opcode)) {
  ------------------
  |  Branch (299:7): [True: 0, False: 4.45k]
  |  Branch (299:19): [True: 0, False: 0]
  |  Branch (299:49): [True: 0, False: 0]
  ------------------
  300|      0|    inserted_decoration_space = true;
  301|      0|    stream_ << std::endl;
  302|      0|    stream_ << std::string(indent_, ' ');
  303|      0|    stream_ << "; Annotations" << std::endl;
  304|      0|  }
  305|  4.45k|  if (comment_ && !inserted_debug_space && spvOpcodeIsDebug(opcode)) {
  ------------------
  |  Branch (305:7): [True: 0, False: 4.45k]
  |  Branch (305:19): [True: 0, False: 0]
  |  Branch (305:44): [True: 0, False: 0]
  ------------------
  306|      0|    inserted_debug_space = true;
  307|      0|    stream_ << std::endl;
  308|      0|    stream_ << std::string(indent_, ' ');
  309|      0|    stream_ << "; Debug Information" << std::endl;
  310|      0|  }
  311|  4.45k|  if (comment_ && !inserted_type_space && spvOpcodeGeneratesType(opcode)) {
  ------------------
  |  Branch (311:7): [True: 0, False: 4.45k]
  |  Branch (311:19): [True: 0, False: 0]
  |  Branch (311:43): [True: 0, False: 0]
  ------------------
  312|      0|    inserted_type_space = true;
  313|      0|    stream_ << std::endl;
  314|      0|    stream_ << std::string(indent_, ' ');
  315|      0|    stream_ << "; Types, variables and constants" << std::endl;
  316|      0|  }
  317|  4.45k|}
_ZN8spvtools11disassemble23InstructionDisassembler11EmitOperandERK24spv_parsed_instruction_tt:
  320|   481k|                                          const uint16_t operand_index) {
  321|   481k|  assert(operand_index < inst.num_operands);
  322|      0|  const spv_parsed_operand_t& operand = inst.operands[operand_index];
  323|   481k|  const uint32_t word = inst.words[operand.offset];
  324|   481k|  switch (operand.type) {
  325|      0|    case SPV_OPERAND_TYPE_RESULT_ID:
  ------------------
  |  Branch (325:5): [True: 0, False: 481k]
  ------------------
  326|      0|      assert(false && "<result-id> is not supposed to be handled here");
  327|      0|      SetBlue();
  328|      0|      stream_ << "%" << name_mapper_(word);
  329|      0|      break;
  330|   398k|    case SPV_OPERAND_TYPE_ID:
  ------------------
  |  Branch (330:5): [True: 398k, False: 82.8k]
  ------------------
  331|   400k|    case SPV_OPERAND_TYPE_TYPE_ID:
  ------------------
  |  Branch (331:5): [True: 1.30k, False: 480k]
  ------------------
  332|   400k|    case SPV_OPERAND_TYPE_SCOPE_ID:
  ------------------
  |  Branch (332:5): [True: 77, False: 481k]
  ------------------
  333|   400k|    case SPV_OPERAND_TYPE_MEMORY_SEMANTICS_ID:
  ------------------
  |  Branch (333:5): [True: 43, False: 481k]
  ------------------
  334|   400k|      SetYellow();
  335|   400k|      stream_ << "%" << name_mapper_(word);
  336|   400k|      break;
  337|     86|    case SPV_OPERAND_TYPE_EXTENSION_INSTRUCTION_NUMBER: {
  ------------------
  |  Branch (337:5): [True: 86, False: 481k]
  ------------------
  338|     86|      spv_ext_inst_desc ext_inst;
  339|     86|      SetRed();
  340|     86|      if (grammar_.lookupExtInst(inst.ext_inst_type, word, &ext_inst) ==
  ------------------
  |  Branch (340:11): [True: 79, False: 7]
  ------------------
  341|     86|          SPV_SUCCESS) {
  342|     79|        stream_ << ext_inst->name;
  343|     79|      } else {
  344|      7|        if (!spvExtInstIsNonSemantic(inst.ext_inst_type)) {
  ------------------
  |  Branch (344:13): [True: 0, False: 7]
  ------------------
  345|      0|          assert(false && "should have caught this earlier");
  346|      7|        } else {
  347|       |          // for non-semantic instruction sets we can just print the number
  348|      7|          stream_ << word;
  349|      7|        }
  350|      7|      }
  351|     86|    } break;
  352|     12|    case SPV_OPERAND_TYPE_SPEC_CONSTANT_OP_NUMBER: {
  ------------------
  |  Branch (352:5): [True: 12, False: 481k]
  ------------------
  353|     12|      spv_opcode_desc opcode_desc;
  354|     12|      if (grammar_.lookupOpcode(spv::Op(word), &opcode_desc))
  ------------------
  |  Branch (354:11): [True: 0, False: 12]
  ------------------
  355|      0|        assert(false && "should have caught this earlier");
  356|      0|      SetRed();
  357|     12|      stream_ << opcode_desc->name;
  358|     12|    } break;
  359|  77.1k|    case SPV_OPERAND_TYPE_LITERAL_INTEGER:
  ------------------
  |  Branch (359:5): [True: 77.1k, False: 404k]
  ------------------
  360|  79.0k|    case SPV_OPERAND_TYPE_TYPED_LITERAL_NUMBER: {
  ------------------
  |  Branch (360:5): [True: 1.83k, False: 479k]
  ------------------
  361|  79.0k|      SetRed();
  362|  79.0k|      EmitNumericLiteral(&stream_, inst, operand);
  363|  79.0k|      ResetColor();
  364|  79.0k|    } break;
  365|    828|    case SPV_OPERAND_TYPE_LITERAL_STRING: {
  ------------------
  |  Branch (365:5): [True: 828, False: 480k]
  ------------------
  366|    828|      stream_ << "\"";
  367|    828|      SetGreen();
  368|       |
  369|    828|      std::string str = spvDecodeLiteralStringOperand(inst, operand_index);
  370|   384k|      for (char const& c : str) {
  ------------------
  |  Branch (370:26): [True: 384k, False: 828]
  ------------------
  371|   384k|        if (c == '"' || c == '\\') stream_ << '\\';
  ------------------
  |  Branch (371:13): [True: 67, False: 384k]
  |  Branch (371:25): [True: 219, False: 384k]
  ------------------
  372|   384k|        stream_ << c;
  373|   384k|      }
  374|    828|      ResetColor();
  375|    828|      stream_ << '"';
  376|    828|    } break;
  377|     51|    case SPV_OPERAND_TYPE_CAPABILITY:
  ------------------
  |  Branch (377:5): [True: 51, False: 481k]
  ------------------
  378|     55|    case SPV_OPERAND_TYPE_SOURCE_LANGUAGE:
  ------------------
  |  Branch (378:5): [True: 4, False: 481k]
  ------------------
  379|    191|    case SPV_OPERAND_TYPE_EXECUTION_MODEL:
  ------------------
  |  Branch (379:5): [True: 136, False: 481k]
  ------------------
  380|    208|    case SPV_OPERAND_TYPE_ADDRESSING_MODEL:
  ------------------
  |  Branch (380:5): [True: 17, False: 481k]
  ------------------
  381|    225|    case SPV_OPERAND_TYPE_MEMORY_MODEL:
  ------------------
  |  Branch (381:5): [True: 17, False: 481k]
  ------------------
  382|    285|    case SPV_OPERAND_TYPE_EXECUTION_MODE:
  ------------------
  |  Branch (382:5): [True: 60, False: 481k]
  ------------------
  383|    412|    case SPV_OPERAND_TYPE_STORAGE_CLASS:
  ------------------
  |  Branch (383:5): [True: 127, False: 481k]
  ------------------
  384|    512|    case SPV_OPERAND_TYPE_DIMENSIONALITY:
  ------------------
  |  Branch (384:5): [True: 100, False: 481k]
  ------------------
  385|    513|    case SPV_OPERAND_TYPE_SAMPLER_ADDRESSING_MODE:
  ------------------
  |  Branch (385:5): [True: 1, False: 481k]
  ------------------
  386|    514|    case SPV_OPERAND_TYPE_SAMPLER_FILTER_MODE:
  ------------------
  |  Branch (386:5): [True: 1, False: 481k]
  ------------------
  387|    614|    case SPV_OPERAND_TYPE_SAMPLER_IMAGE_FORMAT:
  ------------------
  |  Branch (387:5): [True: 100, False: 481k]
  ------------------
  388|    616|    case SPV_OPERAND_TYPE_FP_ROUNDING_MODE:
  ------------------
  |  Branch (388:5): [True: 2, False: 481k]
  ------------------
  389|    617|    case SPV_OPERAND_TYPE_LINKAGE_TYPE:
  ------------------
  |  Branch (389:5): [True: 1, False: 481k]
  ------------------
  390|    621|    case SPV_OPERAND_TYPE_ACCESS_QUALIFIER:
  ------------------
  |  Branch (390:5): [True: 4, False: 481k]
  ------------------
  391|    623|    case SPV_OPERAND_TYPE_FUNCTION_PARAMETER_ATTRIBUTE:
  ------------------
  |  Branch (391:5): [True: 2, False: 481k]
  ------------------
  392|    820|    case SPV_OPERAND_TYPE_DECORATION:
  ------------------
  |  Branch (392:5): [True: 197, False: 481k]
  ------------------
  393|    949|    case SPV_OPERAND_TYPE_BUILT_IN:
  ------------------
  |  Branch (393:5): [True: 129, False: 481k]
  ------------------
  394|    951|    case SPV_OPERAND_TYPE_GROUP_OPERATION:
  ------------------
  |  Branch (394:5): [True: 2, False: 481k]
  ------------------
  395|    951|    case SPV_OPERAND_TYPE_KERNEL_ENQ_FLAGS:
  ------------------
  |  Branch (395:5): [True: 0, False: 481k]
  ------------------
  396|    951|    case SPV_OPERAND_TYPE_KERNEL_PROFILING_INFO:
  ------------------
  |  Branch (396:5): [True: 0, False: 481k]
  ------------------
  397|    951|    case SPV_OPERAND_TYPE_RAY_FLAGS:
  ------------------
  |  Branch (397:5): [True: 0, False: 481k]
  ------------------
  398|    951|    case SPV_OPERAND_TYPE_RAY_QUERY_INTERSECTION:
  ------------------
  |  Branch (398:5): [True: 0, False: 481k]
  ------------------
  399|    951|    case SPV_OPERAND_TYPE_RAY_QUERY_COMMITTED_INTERSECTION_TYPE:
  ------------------
  |  Branch (399:5): [True: 0, False: 481k]
  ------------------
  400|    951|    case SPV_OPERAND_TYPE_RAY_QUERY_CANDIDATE_INTERSECTION_TYPE:
  ------------------
  |  Branch (400:5): [True: 0, False: 481k]
  ------------------
  401|    951|    case SPV_OPERAND_TYPE_DEBUG_BASE_TYPE_ATTRIBUTE_ENCODING:
  ------------------
  |  Branch (401:5): [True: 0, False: 481k]
  ------------------
  402|    952|    case SPV_OPERAND_TYPE_DEBUG_COMPOSITE_TYPE:
  ------------------
  |  Branch (402:5): [True: 1, False: 481k]
  ------------------
  403|    953|    case SPV_OPERAND_TYPE_DEBUG_TYPE_QUALIFIER:
  ------------------
  |  Branch (403:5): [True: 1, False: 481k]
  ------------------
  404|    954|    case SPV_OPERAND_TYPE_DEBUG_OPERATION:
  ------------------
  |  Branch (404:5): [True: 1, False: 481k]
  ------------------
  405|    954|    case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_BASE_TYPE_ATTRIBUTE_ENCODING:
  ------------------
  |  Branch (405:5): [True: 0, False: 481k]
  ------------------
  406|    954|    case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_COMPOSITE_TYPE:
  ------------------
  |  Branch (406:5): [True: 0, False: 481k]
  ------------------
  407|    954|    case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_TYPE_QUALIFIER:
  ------------------
  |  Branch (407:5): [True: 0, False: 481k]
  ------------------
  408|    954|    case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_OPERATION:
  ------------------
  |  Branch (408:5): [True: 0, False: 481k]
  ------------------
  409|    954|    case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_IMPORTED_ENTITY:
  ------------------
  |  Branch (409:5): [True: 0, False: 481k]
  ------------------
  410|    956|    case SPV_OPERAND_TYPE_FPDENORM_MODE:
  ------------------
  |  Branch (410:5): [True: 2, False: 481k]
  ------------------
  411|    956|    case SPV_OPERAND_TYPE_FPOPERATION_MODE:
  ------------------
  |  Branch (411:5): [True: 0, False: 481k]
  ------------------
  412|    956|    case SPV_OPERAND_TYPE_QUANTIZATION_MODES:
  ------------------
  |  Branch (412:5): [True: 0, False: 481k]
  ------------------
  413|    956|    case SPV_OPERAND_TYPE_OVERFLOW_MODES: {
  ------------------
  |  Branch (413:5): [True: 0, False: 481k]
  ------------------
  414|    956|      spv_operand_desc entry;
  415|    956|      if (grammar_.lookupOperand(operand.type, word, &entry))
  ------------------
  |  Branch (415:11): [True: 0, False: 956]
  ------------------
  416|      0|        assert(false && "should have caught this earlier");
  417|      0|      stream_ << entry->name;
  418|    956|    } break;
  419|      7|    case SPV_OPERAND_TYPE_FP_FAST_MATH_MODE:
  ------------------
  |  Branch (419:5): [True: 7, False: 481k]
  ------------------
  420|    457|    case SPV_OPERAND_TYPE_FUNCTION_CONTROL:
  ------------------
  |  Branch (420:5): [True: 450, False: 481k]
  ------------------
  421|    515|    case SPV_OPERAND_TYPE_LOOP_CONTROL:
  ------------------
  |  Branch (421:5): [True: 58, False: 481k]
  ------------------
  422|    519|    case SPV_OPERAND_TYPE_IMAGE:
  ------------------
  |  Branch (422:5): [True: 4, False: 481k]
  ------------------
  423|    529|    case SPV_OPERAND_TYPE_MEMORY_ACCESS:
  ------------------
  |  Branch (423:5): [True: 10, False: 481k]
  ------------------
  424|    537|    case SPV_OPERAND_TYPE_SELECTION_CONTROL:
  ------------------
  |  Branch (424:5): [True: 8, False: 481k]
  ------------------
  425|    540|    case SPV_OPERAND_TYPE_DEBUG_INFO_FLAGS:
  ------------------
  |  Branch (425:5): [True: 3, False: 481k]
  ------------------
  426|    540|    case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_INFO_FLAGS:
  ------------------
  |  Branch (426:5): [True: 0, False: 481k]
  ------------------
  427|    540|      EmitMaskOperand(operand.type, word);
  428|    540|      break;
  429|      2|    default:
  ------------------
  |  Branch (429:5): [True: 2, False: 481k]
  ------------------
  430|      2|      if (spvOperandIsConcreteMask(operand.type)) {
  ------------------
  |  Branch (430:11): [True: 0, False: 2]
  ------------------
  431|      0|        EmitMaskOperand(operand.type, word);
  432|      2|      } else if (spvOperandIsConcrete(operand.type)) {
  ------------------
  |  Branch (432:18): [True: 2, False: 0]
  ------------------
  433|      2|        spv_operand_desc entry;
  434|      2|        if (grammar_.lookupOperand(operand.type, word, &entry))
  ------------------
  |  Branch (434:13): [True: 0, False: 2]
  ------------------
  435|      0|          assert(false && "should have caught this earlier");
  436|      0|        stream_ << entry->name;
  437|      2|      } else {
  438|      0|        assert(false && "unhandled or invalid case");
  439|      0|      }
  440|      0|      break;
  441|   481k|  }
  442|   481k|  ResetColor();
  443|   481k|}
_ZN8spvtools11disassemble23InstructionDisassembler15EmitMaskOperandE18spv_operand_type_tj:
  446|    540|                                              const uint32_t word) {
  447|       |  // Scan the mask from least significant bit to most significant bit.  For each
  448|       |  // set bit, emit the name of that bit. Separate multiple names with '|'.
  449|    540|  uint32_t remaining_word = word;
  450|    540|  uint32_t mask;
  451|    540|  int num_emitted = 0;
  452|  2.29k|  for (mask = 1; remaining_word; mask <<= 1) {
  ------------------
  |  Branch (452:18): [True: 1.75k, False: 540]
  ------------------
  453|  1.75k|    if (remaining_word & mask) {
  ------------------
  |  Branch (453:9): [True: 460, False: 1.29k]
  ------------------
  454|    460|      remaining_word ^= mask;
  455|    460|      spv_operand_desc entry;
  456|    460|      if (grammar_.lookupOperand(type, mask, &entry))
  ------------------
  |  Branch (456:11): [True: 0, False: 460]
  ------------------
  457|      0|        assert(false && "should have caught this earlier");
  458|    460|      if (num_emitted) stream_ << "|";
  ------------------
  |  Branch (458:11): [True: 207, False: 253]
  ------------------
  459|    460|      stream_ << entry->name;
  460|    460|      num_emitted++;
  461|    460|    }
  462|  1.75k|  }
  463|    540|  if (!num_emitted) {
  ------------------
  |  Branch (463:7): [True: 287, False: 253]
  ------------------
  464|       |    // An operand value of 0 was provided, so represent it by the name
  465|       |    // of the 0 value. In many cases, that's "None".
  466|    287|    spv_operand_desc entry;
  467|    287|    if (SPV_SUCCESS == grammar_.lookupOperand(type, 0, &entry))
  ------------------
  |  Branch (467:9): [True: 287, False: 0]
  ------------------
  468|    287|      stream_ << entry->name;
  469|    287|  }
  470|    540|}
_ZN8spvtools11disassemble23InstructionDisassembler10ResetColorEv:
  472|   564k|void InstructionDisassembler::ResetColor() {
  473|   564k|  if (color_) stream_ << spvtools::clr::reset{print_};
  ------------------
  |  Branch (473:7): [True: 0, False: 564k]
  ------------------
  474|   564k|}
_ZN8spvtools11disassemble23InstructionDisassembler7SetBlueEv:
  478|  2.95k|void InstructionDisassembler::SetBlue() {
  479|  2.95k|  if (color_) stream_ << spvtools::clr::blue{print_};
  ------------------
  |  Branch (479:7): [True: 0, False: 2.95k]
  ------------------
  480|  2.95k|}
_ZN8spvtools11disassemble23InstructionDisassembler9SetYellowEv:
  481|   400k|void InstructionDisassembler::SetYellow() {
  482|   400k|  if (color_) stream_ << spvtools::clr::yellow{print_};
  ------------------
  |  Branch (482:7): [True: 0, False: 400k]
  ------------------
  483|   400k|}
_ZN8spvtools11disassemble23InstructionDisassembler6SetRedEv:
  484|  79.1k|void InstructionDisassembler::SetRed() {
  485|  79.1k|  if (color_) stream_ << spvtools::clr::red{print_};
  ------------------
  |  Branch (485:7): [True: 0, False: 79.1k]
  ------------------
  486|  79.1k|}
_ZN8spvtools11disassemble23InstructionDisassembler8SetGreenEv:
  487|    828|void InstructionDisassembler::SetGreen() {
  488|    828|  if (color_) stream_ << spvtools::clr::green{print_};
  ------------------
  |  Branch (488:7): [True: 0, False: 828]
  ------------------
  489|    828|}
_ZN8spvtools26spvInstructionBinaryToTextE14spv_target_envPKjmS2_mj:
  497|  4.45k|                                       const uint32_t options) {
  498|  4.45k|  spv_context context = spvContextCreate(env);
  499|  4.45k|  const AssemblyGrammar grammar(context);
  500|  4.45k|  if (!grammar.isValid()) {
  ------------------
  |  Branch (500:7): [True: 0, False: 4.45k]
  ------------------
  501|      0|    spvContextDestroy(context);
  502|      0|    return "";
  503|      0|  }
  504|       |
  505|       |  // Generate friendly names for Ids if requested.
  506|  4.45k|  std::unique_ptr<FriendlyNameMapper> friendly_mapper;
  507|  4.45k|  NameMapper name_mapper = GetTrivialNameMapper();
  508|  4.45k|  if (options & SPV_BINARY_TO_TEXT_OPTION_FRIENDLY_NAMES) {
  ------------------
  |  Branch (508:7): [True: 4.45k, False: 0]
  ------------------
  509|  4.45k|    friendly_mapper = MakeUnique<FriendlyNameMapper>(context, code, wordCount);
  510|  4.45k|    name_mapper = friendly_mapper->GetNameMapper();
  511|  4.45k|  }
  512|       |
  513|       |  // Now disassemble!
  514|  4.45k|  Disassembler disassembler(grammar, options, name_mapper);
  515|  4.45k|  WrappedDisassembler wrapped(&disassembler, instCode, instWordCount);
  516|  4.45k|  spvBinaryParse(context, &wrapped, code, wordCount, DisassembleTargetHeader,
  517|  4.45k|                 DisassembleTargetInstruction, nullptr);
  518|       |
  519|  4.45k|  spv_text text = nullptr;
  520|  4.45k|  std::string output;
  521|  4.45k|  if (disassembler.SaveTextResult(&text) == SPV_SUCCESS) {
  ------------------
  |  Branch (521:7): [True: 4.45k, False: 0]
  ------------------
  522|  4.45k|    output.assign(text->str, text->str + text->length);
  523|       |    // Drop trailing newline characters.
  524|  8.90k|    while (!output.empty() && output.back() == '\n') output.pop_back();
  ------------------
  |  Branch (524:12): [True: 8.90k, False: 0]
  |  Branch (524:31): [True: 4.45k, False: 4.45k]
  ------------------
  525|  4.45k|  }
  526|  4.45k|  spvTextDestroy(text);
  527|  4.45k|  spvContextDestroy(context);
  528|       |
  529|  4.45k|  return output;
  530|  4.45k|}
disassemble.cpp:_ZN8spvtools12_GLOBAL__N_112DisassemblerC2ERKNS_15AssemblyGrammarEjNSt3__18functionIFNS5_12basic_stringIcNS5_11char_traitsIcEENS5_9allocatorIcEEEEjEEE:
   57|  4.45k|        byte_offset_(0) {}
disassemble.cpp:_ZN8spvtools12_GLOBAL__N_119WrappedDisassemblerC2EPNS0_12DisassemblerEPKjm:
  156|  4.45k|      : disassembler_(dis), inst_binary_(binary), word_count_(wc) {}
disassemble.cpp:_ZN8spvtools12_GLOBAL__N_123DisassembleTargetHeaderEPv16spv_endianness_tjjjjj:
  171|  4.45k|                                     uint32_t schema) {
  172|  4.45k|  assert(user_data);
  173|      0|  auto wrapped = static_cast<WrappedDisassembler*>(user_data);
  174|  4.45k|  return wrapped->disassembler()->HandleHeader(endian, version, generator,
  175|  4.45k|                                               id_bound, schema);
  176|  4.45k|}
disassemble.cpp:_ZN8spvtools12_GLOBAL__N_119WrappedDisassembler12disassemblerEv:
  158|  8.90k|  Disassembler* disassembler() { return disassembler_; }
disassemble.cpp:_ZN8spvtools12_GLOBAL__N_112Disassembler12HandleHeaderE16spv_endianness_tjjjj:
   87|  4.45k|                                        uint32_t id_bound, uint32_t schema) {
   88|  4.45k|  endian_ = endian;
   89|       |
   90|  4.45k|  if (header_) {
  ------------------
  |  Branch (90:7): [True: 0, False: 4.45k]
  ------------------
   91|      0|    instruction_disassembler_.EmitHeaderSpirv();
   92|      0|    instruction_disassembler_.EmitHeaderVersion(version);
   93|      0|    instruction_disassembler_.EmitHeaderGenerator(generator);
   94|      0|    instruction_disassembler_.EmitHeaderIdBound(id_bound);
   95|      0|    instruction_disassembler_.EmitHeaderSchema(schema);
   96|      0|  }
   97|       |
   98|  4.45k|  byte_offset_ = SPV_INDEX_INSTRUCTION * sizeof(uint32_t);
  ------------------
  |  |   39|  4.45k|#define SPV_INDEX_INSTRUCTION 5u
  ------------------
   99|       |
  100|  4.45k|  return SPV_SUCCESS;
  101|  4.45k|}
disassemble.cpp:_ZN8spvtools12_GLOBAL__N_128DisassembleTargetInstructionEPvPK24spv_parsed_instruction_t:
  179|   158k|    void* user_data, const spv_parsed_instruction_t* parsed_instruction) {
  180|   158k|  assert(user_data);
  181|      0|  auto wrapped = static_cast<WrappedDisassembler*>(user_data);
  182|       |  // Check if this is the instruction we want to disassemble.
  183|   158k|  if (wrapped->word_count() == parsed_instruction->num_words &&
  ------------------
  |  Branch (183:7): [True: 46.9k, False: 111k]
  ------------------
  184|   158k|      std::equal(wrapped->inst_binary(),
  ------------------
  |  Branch (184:7): [True: 4.45k, False: 42.4k]
  ------------------
  185|  46.9k|                 wrapped->inst_binary() + wrapped->word_count(),
  186|  46.9k|                 parsed_instruction->words)) {
  187|       |    // Found the target instruction. Disassemble it and signal that we should
  188|       |    // stop searching so we don't output the same instruction again.
  189|  4.45k|    if (auto error =
  ------------------
  |  Branch (189:14): [True: 0, False: 4.45k]
  ------------------
  190|  4.45k|            wrapped->disassembler()->HandleInstruction(*parsed_instruction))
  191|      0|      return error;
  192|  4.45k|    return SPV_REQUESTED_TERMINATION;
  193|  4.45k|  }
  194|   153k|  return SPV_SUCCESS;
  195|   158k|}
disassemble.cpp:_ZNK8spvtools12_GLOBAL__N_119WrappedDisassembler10word_countEv:
  160|   205k|  size_t word_count() const { return word_count_; }
disassemble.cpp:_ZNK8spvtools12_GLOBAL__N_119WrappedDisassembler11inst_binaryEv:
  159|  93.8k|  const uint32_t* inst_binary() const { return inst_binary_; }
disassemble.cpp:_ZN8spvtools12_GLOBAL__N_112Disassembler17HandleInstructionERK24spv_parsed_instruction_t:
  104|  4.45k|    const spv_parsed_instruction_t& inst) {
  105|  4.45k|  instruction_disassembler_.EmitSectionComment(inst, inserted_decoration_space_,
  106|  4.45k|                                               inserted_debug_space_,
  107|  4.45k|                                               inserted_type_space_);
  108|       |
  109|  4.45k|  instruction_disassembler_.EmitInstruction(inst, byte_offset_);
  110|       |
  111|  4.45k|  byte_offset_ += inst.num_words * sizeof(uint32_t);
  112|       |
  113|  4.45k|  return SPV_SUCCESS;
  114|  4.45k|}
disassemble.cpp:_ZNK8spvtools12_GLOBAL__N_112Disassembler14SaveTextResultEPP10spv_text_t:
  116|  4.45k|spv_result_t Disassembler::SaveTextResult(spv_text* text_result) const {
  117|  4.45k|  if (!print_) {
  ------------------
  |  Branch (117:7): [True: 4.45k, False: 0]
  ------------------
  118|  4.45k|    size_t length = text_.str().size();
  119|  4.45k|    char* str = new char[length + 1];
  120|  4.45k|    if (!str) return SPV_ERROR_OUT_OF_MEMORY;
  ------------------
  |  Branch (120:9): [True: 0, False: 4.45k]
  ------------------
  121|  4.45k|    strncpy(str, text_.str().c_str(), length + 1);
  122|  4.45k|    spv_text text = new spv_text_t();
  123|  4.45k|    if (!text) {
  ------------------
  |  Branch (123:9): [True: 0, False: 4.45k]
  ------------------
  124|      0|      delete[] str;
  125|      0|      return SPV_ERROR_OUT_OF_MEMORY;
  126|      0|    }
  127|  4.45k|    text->str = str;
  128|  4.45k|    text->length = length;
  129|  4.45k|    *text_result = text;
  130|  4.45k|  }
  131|  4.45k|  return SPV_SUCCESS;
  132|  4.45k|}

_ZNK8spvtools7EnumSetIN3spv10CapabilityEE8ContainsES2_:
  101|   789k|  bool Contains(EnumType c) const { return ContainsWord(ToWord(c)); }
_ZNK8spvtools7EnumSetIN3spv10CapabilityEE12ContainsWordEj:
  160|   789k|  bool ContainsWord(uint32_t word) const {
  161|       |    // We shouldn't call Overflow() since this is a const method.
  162|   789k|    if (auto bits = AsMask(word)) {
  ------------------
  |  Branch (162:14): [True: 771k, False: 17.5k]
  ------------------
  163|   771k|      return (mask_ & bits) != 0;
  164|   771k|    } else if (auto overflow = overflow_.get()) {
  ------------------
  |  Branch (164:21): [True: 594, False: 16.9k]
  ------------------
  165|    594|      return overflow->find(word) != overflow->end();
  166|    594|    }
  167|       |    // The word is large, but the set doesn't have large members, so
  168|       |    // it doesn't have an overflow set.
  169|  16.9k|    return false;
  170|   789k|  }
_ZNK8spvtools7EnumSetIN3spv10CapabilityEE6AsMaskEj:
  182|  1.84M|  uint64_t AsMask(uint32_t word) const {
  183|  1.84M|    if (word > 63) return 0;
  ------------------
  |  Branch (183:9): [True: 20.8k, False: 1.82M]
  ------------------
  184|  1.82M|    return uint64_t(1) << word;
  185|  1.84M|  }
_ZNK8spvtools7EnumSetIN3spv10CapabilityEE6ToWordES2_:
  173|   859k|  uint32_t ToWord(EnumType value) const {
  174|   859k|    static_assert(sizeof(EnumType) <= sizeof(uint32_t),
  175|   859k|                  "EnumType must statically castable to uint32_t");
  176|   859k|    return static_cast<uint32_t>(value);
  177|   859k|  }
_ZNK8spvtools7EnumSetINS_9ExtensionEE8ContainsES1_:
  101|  24.7k|  bool Contains(EnumType c) const { return ContainsWord(ToWord(c)); }
_ZNK8spvtools7EnumSetINS_9ExtensionEE12ContainsWordEj:
  160|  24.7k|  bool ContainsWord(uint32_t word) const {
  161|       |    // We shouldn't call Overflow() since this is a const method.
  162|  24.7k|    if (auto bits = AsMask(word)) {
  ------------------
  |  Branch (162:14): [True: 154, False: 24.6k]
  ------------------
  163|    154|      return (mask_ & bits) != 0;
  164|  24.6k|    } else if (auto overflow = overflow_.get()) {
  ------------------
  |  Branch (164:21): [True: 1.07k, False: 23.5k]
  ------------------
  165|  1.07k|      return overflow->find(word) != overflow->end();
  166|  1.07k|    }
  167|       |    // The word is large, but the set doesn't have large members, so
  168|       |    // it doesn't have an overflow set.
  169|  23.5k|    return false;
  170|  24.7k|  }
_ZNK8spvtools7EnumSetINS_9ExtensionEE6AsMaskEj:
  182|  28.1k|  uint64_t AsMask(uint32_t word) const {
  183|  28.1k|    if (word > 63) return 0;
  ------------------
  |  Branch (183:9): [True: 25.0k, False: 3.18k]
  ------------------
  184|  3.18k|    return uint64_t(1) << word;
  185|  28.1k|  }
_ZNK8spvtools7EnumSetINS_9ExtensionEE6ToWordES1_:
  173|  25.4k|  uint32_t ToWord(EnumType value) const {
  174|  25.4k|    static_assert(sizeof(EnumType) <= sizeof(uint32_t),
  175|  25.4k|                  "EnumType must statically castable to uint32_t");
  176|  25.4k|    return static_cast<uint32_t>(value);
  177|  25.4k|  }
_ZN8spvtools7EnumSetINS_9ExtensionEEC2EjPKS1_:
   50|   384k|  EnumSet(uint32_t count, const EnumType* ptr) {
   51|   384k|    for (uint32_t i = 0; i < count; ++i) Add(ptr[i]);
  ------------------
  |  Branch (51:26): [True: 530, False: 384k]
  ------------------
   52|   384k|  }
_ZN8spvtools7EnumSetINS_9ExtensionEE3AddES1_:
   94|    723|  void Add(EnumType c) { AddWord(ToWord(c)); }
_ZN8spvtools7EnumSetINS_9ExtensionEE7AddWordEj:
  140|    723|  void AddWord(uint32_t word) {
  141|    723|    if (auto new_bits = AsMask(word)) {
  ------------------
  |  Branch (141:14): [True: 339, False: 384]
  ------------------
  142|    339|      mask_ |= new_bits;
  143|    384|    } else {
  144|    384|      Overflow().insert(word);
  145|    384|    }
  146|    723|  }
_ZN8spvtools7EnumSetINS_9ExtensionEE8OverflowEv:
  189|    384|  OverflowSetType& Overflow() {
  190|    384|    if (overflow_.get() == nullptr) {
  ------------------
  |  Branch (190:9): [True: 325, False: 59]
  ------------------
  191|    325|      overflow_ = MakeUnique<OverflowSetType>();
  192|    325|    }
  193|    384|    return *overflow_;
  194|    384|  }
_ZNK8spvtools7EnumSetINS_9ExtensionEE7IsEmptyEv:
  115|   384k|  bool IsEmpty() const {
  116|   384k|    if (mask_) return false;
  ------------------
  |  Branch (116:9): [True: 290, False: 384k]
  ------------------
  117|   384k|    if (overflow_ && !overflow_->empty()) return false;
  ------------------
  |  Branch (117:9): [True: 233, False: 383k]
  |  Branch (117:22): [True: 233, False: 0]
  ------------------
  118|   383k|    return true;
  119|   384k|  }
_ZN8spvtools7EnumSetIN3spv10CapabilityEEC2Ev:
   43|   610k|  EnumSet() {}
_ZNK8spvtools7EnumSetIN3spv10CapabilityEE7ForEachENSt3__18functionIFvS2_EEE:
  105|  15.3k|  void ForEach(std::function<void(EnumType)> f) const {
  106|   997k|    for (uint32_t i = 0; i < 64; ++i) {
  ------------------
  |  Branch (106:26): [True: 982k, False: 15.3k]
  ------------------
  107|   982k|      if (mask_ & AsMask(i)) f(static_cast<EnumType>(i));
  ------------------
  |  Branch (107:11): [True: 9.18k, False: 973k]
  ------------------
  108|   982k|    }
  109|  15.3k|    if (overflow_) {
  ------------------
  |  Branch (109:9): [True: 174, False: 15.1k]
  ------------------
  110|    190|      for (uint32_t c : *overflow_) f(static_cast<EnumType>(c));
  ------------------
  |  Branch (110:23): [True: 190, False: 174]
  ------------------
  111|    174|    }
  112|  15.3k|  }
_ZN8spvtools7EnumSetIN3spv10CapabilityEE3AddES2_:
   94|  69.9k|  void Add(EnumType c) { AddWord(ToWord(c)); }
_ZN8spvtools7EnumSetIN3spv10CapabilityEE7AddWordEj:
  140|  69.9k|  void AddWord(uint32_t word) {
  141|  69.9k|    if (auto new_bits = AsMask(word)) {
  ------------------
  |  Branch (141:14): [True: 66.6k, False: 3.28k]
  ------------------
  142|  66.6k|      mask_ |= new_bits;
  143|  66.6k|    } else {
  144|  3.28k|      Overflow().insert(word);
  145|  3.28k|    }
  146|  69.9k|  }
_ZN8spvtools7EnumSetIN3spv10CapabilityEE8OverflowEv:
  189|  3.28k|  OverflowSetType& Overflow() {
  190|  3.28k|    if (overflow_.get() == nullptr) {
  ------------------
  |  Branch (190:9): [True: 2.40k, False: 879]
  ------------------
  191|  2.40k|      overflow_ = MakeUnique<OverflowSetType>();
  192|  2.40k|    }
  193|  3.28k|    return *overflow_;
  194|  3.28k|  }
_ZN8spvtools7EnumSetIN3spv10CapabilityEEaSERKS3_:
   63|  66.7k|  EnumSet& operator=(const EnumSet& other) {
   64|  66.7k|    if (&other != this) {
  ------------------
  |  Branch (64:9): [True: 66.7k, False: 0]
  ------------------
   65|  66.7k|      mask_ = other.mask_;
   66|  66.7k|      overflow_.reset(other.overflow_ ? new OverflowSetType(*other.overflow_)
  ------------------
  |  Branch (66:23): [True: 1.61k, False: 65.1k]
  ------------------
   67|  66.7k|                                      : nullptr);
   68|  66.7k|    }
   69|  66.7k|    return *this;
   70|  66.7k|  }
_ZNK8spvtools7EnumSetIN3spv10CapabilityEE7IsEmptyEv:
  115|   507k|  bool IsEmpty() const {
  116|   507k|    if (mask_) return false;
  ------------------
  |  Branch (116:9): [True: 68.1k, False: 439k]
  ------------------
  117|   439k|    if (overflow_ && !overflow_->empty()) return false;
  ------------------
  |  Branch (117:9): [True: 170, False: 439k]
  |  Branch (117:22): [True: 170, False: 0]
  ------------------
  118|   439k|    return true;
  119|   439k|  }
_ZN8spvtools7EnumSetINS_9ExtensionEEC2Ev:
   43|  8.24k|  EnumSet() {}
_ZN8spvtools7EnumSetIN3spv10CapabilityEEC2EjPKS2_:
   50|  15.2k|  EnumSet(uint32_t count, const EnumType* ptr) {
   51|  24.5k|    for (uint32_t i = 0; i < count; ++i) Add(ptr[i]);
  ------------------
  |  Branch (51:26): [True: 9.26k, False: 15.2k]
  ------------------
   52|  15.2k|  }
_ZNK8spvtools7EnumSetIN3spv10CapabilityEE8HasAnyOfERKS3_:
  123|   447k|  bool HasAnyOf(const EnumSet<EnumType>& in_set) const {
  124|   447k|    if (in_set.IsEmpty()) return true;
  ------------------
  |  Branch (124:9): [True: 411k, False: 35.9k]
  ------------------
  125|       |
  126|  35.9k|    if (mask_ & in_set.mask_) return true;
  ------------------
  |  Branch (126:9): [True: 35.7k, False: 130]
  ------------------
  127|       |
  128|    130|    if (!overflow_ || !in_set.overflow_) return false;
  ------------------
  |  Branch (128:9): [True: 88, False: 42]
  |  Branch (128:23): [True: 1, False: 41]
  ------------------
  129|       |
  130|     43|    for (uint32_t item : *in_set.overflow_) {
  ------------------
  |  Branch (130:24): [True: 43, False: 7]
  ------------------
  131|     43|      if (overflow_->find(item) != overflow_->end()) return true;
  ------------------
  |  Branch (131:11): [True: 34, False: 9]
  ------------------
  132|     43|    }
  133|       |
  134|      7|    return false;
  135|     41|  }
_ZNK8spvtools7EnumSetINS_9ExtensionEE8HasAnyOfERKS2_:
  123|    521|  bool HasAnyOf(const EnumSet<EnumType>& in_set) const {
  124|    521|    if (in_set.IsEmpty()) return true;
  ------------------
  |  Branch (124:9): [True: 0, False: 521]
  ------------------
  125|       |
  126|    521|    if (mask_ & in_set.mask_) return true;
  ------------------
  |  Branch (126:9): [True: 272, False: 249]
  ------------------
  127|       |
  128|    249|    if (!overflow_ || !in_set.overflow_) return false;
  ------------------
  |  Branch (128:9): [True: 36, False: 213]
  |  Branch (128:23): [True: 2, False: 211]
  ------------------
  129|       |
  130|    214|    for (uint32_t item : *in_set.overflow_) {
  ------------------
  |  Branch (130:24): [True: 214, False: 4]
  ------------------
  131|    214|      if (overflow_->find(item) != overflow_->end()) return true;
  ------------------
  |  Branch (131:11): [True: 207, False: 7]
  ------------------
  132|    214|    }
  133|       |
  134|      4|    return false;
  135|    211|  }
_ZNK8spvtools7EnumSetINS_9ExtensionEE7ForEachENSt3__18functionIFvS1_EEE:
  105|     42|  void ForEach(std::function<void(EnumType)> f) const {
  106|  2.73k|    for (uint32_t i = 0; i < 64; ++i) {
  ------------------
  |  Branch (106:26): [True: 2.68k, False: 42]
  ------------------
  107|  2.68k|      if (mask_ & AsMask(i)) f(static_cast<EnumType>(i));
  ------------------
  |  Branch (107:11): [True: 17, False: 2.67k]
  ------------------
  108|  2.68k|    }
  109|     42|    if (overflow_) {
  ------------------
  |  Branch (109:9): [True: 27, False: 15]
  ------------------
  110|     34|      for (uint32_t c : *overflow_) f(static_cast<EnumType>(c));
  ------------------
  |  Branch (110:23): [True: 34, False: 27]
  ------------------
  111|     27|    }
  112|     42|  }

_Z18spvExtInstTableGetPPK20spv_ext_inst_table_t14spv_target_env:
   71|  12.6k|                                spv_target_env env) {
   72|  12.6k|  if (!pExtInstTable) return SPV_ERROR_INVALID_POINTER;
  ------------------
  |  Branch (72:7): [True: 0, False: 12.6k]
  ------------------
   73|       |
   74|  12.6k|  switch (env) {
   75|       |    // The extended instruction sets are all version 1.0 so far.
   76|      0|    case SPV_ENV_UNIVERSAL_1_0:
  ------------------
  |  Branch (76:5): [True: 0, False: 12.6k]
  ------------------
   77|      0|    case SPV_ENV_VULKAN_1_0:
  ------------------
  |  Branch (77:5): [True: 0, False: 12.6k]
  ------------------
   78|      0|    case SPV_ENV_UNIVERSAL_1_1:
  ------------------
  |  Branch (78:5): [True: 0, False: 12.6k]
  ------------------
   79|      0|    case SPV_ENV_UNIVERSAL_1_2:
  ------------------
  |  Branch (79:5): [True: 0, False: 12.6k]
  ------------------
   80|      0|    case SPV_ENV_OPENCL_1_2:
  ------------------
  |  Branch (80:5): [True: 0, False: 12.6k]
  ------------------
   81|      0|    case SPV_ENV_OPENCL_EMBEDDED_1_2:
  ------------------
  |  Branch (81:5): [True: 0, False: 12.6k]
  ------------------
   82|      0|    case SPV_ENV_OPENCL_2_0:
  ------------------
  |  Branch (82:5): [True: 0, False: 12.6k]
  ------------------
   83|      0|    case SPV_ENV_OPENCL_EMBEDDED_2_0:
  ------------------
  |  Branch (83:5): [True: 0, False: 12.6k]
  ------------------
   84|      0|    case SPV_ENV_OPENCL_2_1:
  ------------------
  |  Branch (84:5): [True: 0, False: 12.6k]
  ------------------
   85|      0|    case SPV_ENV_OPENCL_EMBEDDED_2_1:
  ------------------
  |  Branch (85:5): [True: 0, False: 12.6k]
  ------------------
   86|      0|    case SPV_ENV_OPENCL_2_2:
  ------------------
  |  Branch (86:5): [True: 0, False: 12.6k]
  ------------------
   87|      0|    case SPV_ENV_OPENCL_EMBEDDED_2_2:
  ------------------
  |  Branch (87:5): [True: 0, False: 12.6k]
  ------------------
   88|      0|    case SPV_ENV_OPENGL_4_0:
  ------------------
  |  Branch (88:5): [True: 0, False: 12.6k]
  ------------------
   89|  12.6k|    case SPV_ENV_OPENGL_4_1:
  ------------------
  |  Branch (89:5): [True: 12.6k, False: 0]
  ------------------
   90|  12.6k|    case SPV_ENV_OPENGL_4_2:
  ------------------
  |  Branch (90:5): [True: 0, False: 12.6k]
  ------------------
   91|  12.6k|    case SPV_ENV_OPENGL_4_3:
  ------------------
  |  Branch (91:5): [True: 0, False: 12.6k]
  ------------------
   92|  12.6k|    case SPV_ENV_OPENGL_4_5:
  ------------------
  |  Branch (92:5): [True: 0, False: 12.6k]
  ------------------
   93|  12.6k|    case SPV_ENV_UNIVERSAL_1_3:
  ------------------
  |  Branch (93:5): [True: 0, False: 12.6k]
  ------------------
   94|  12.6k|    case SPV_ENV_VULKAN_1_1:
  ------------------
  |  Branch (94:5): [True: 0, False: 12.6k]
  ------------------
   95|  12.6k|    case SPV_ENV_VULKAN_1_1_SPIRV_1_4:
  ------------------
  |  Branch (95:5): [True: 0, False: 12.6k]
  ------------------
   96|  12.6k|    case SPV_ENV_UNIVERSAL_1_4:
  ------------------
  |  Branch (96:5): [True: 0, False: 12.6k]
  ------------------
   97|  12.6k|    case SPV_ENV_UNIVERSAL_1_5:
  ------------------
  |  Branch (97:5): [True: 0, False: 12.6k]
  ------------------
   98|  12.6k|    case SPV_ENV_VULKAN_1_2:
  ------------------
  |  Branch (98:5): [True: 0, False: 12.6k]
  ------------------
   99|  12.6k|    case SPV_ENV_UNIVERSAL_1_6:
  ------------------
  |  Branch (99:5): [True: 0, False: 12.6k]
  ------------------
  100|  12.6k|    case SPV_ENV_VULKAN_1_3:
  ------------------
  |  Branch (100:5): [True: 0, False: 12.6k]
  ------------------
  101|  12.6k|      *pExtInstTable = &kTable_1_0;
  102|  12.6k|      return SPV_SUCCESS;
  103|      0|    default:
  ------------------
  |  Branch (103:5): [True: 0, False: 12.6k]
  ------------------
  104|      0|      return SPV_ERROR_INVALID_TABLE;
  105|  12.6k|  }
  106|  12.6k|}
_Z23spvExtInstImportTypeGetPKc:
  108|  8.56k|spv_ext_inst_type_t spvExtInstImportTypeGet(const char* name) {
  109|       |  // The names are specified by the respective extension instruction
  110|       |  // specifications.
  111|  8.56k|  if (!strcmp("GLSL.std.450", name)) {
  ------------------
  |  Branch (111:7): [True: 5.18k, False: 3.37k]
  ------------------
  112|  5.18k|    return SPV_EXT_INST_TYPE_GLSL_STD_450;
  113|  5.18k|  }
  114|  3.37k|  if (!strcmp("OpenCL.std", name)) {
  ------------------
  |  Branch (114:7): [True: 52, False: 3.32k]
  ------------------
  115|     52|    return SPV_EXT_INST_TYPE_OPENCL_STD;
  116|     52|  }
  117|  3.32k|  if (!strcmp("SPV_AMD_shader_explicit_vertex_parameter", name)) {
  ------------------
  |  Branch (117:7): [True: 6, False: 3.31k]
  ------------------
  118|      6|    return SPV_EXT_INST_TYPE_SPV_AMD_SHADER_EXPLICIT_VERTEX_PARAMETER;
  119|      6|  }
  120|  3.31k|  if (!strcmp("SPV_AMD_shader_trinary_minmax", name)) {
  ------------------
  |  Branch (120:7): [True: 0, False: 3.31k]
  ------------------
  121|      0|    return SPV_EXT_INST_TYPE_SPV_AMD_SHADER_TRINARY_MINMAX;
  122|      0|  }
  123|  3.31k|  if (!strcmp("SPV_AMD_gcn_shader", name)) {
  ------------------
  |  Branch (123:7): [True: 21, False: 3.29k]
  ------------------
  124|     21|    return SPV_EXT_INST_TYPE_SPV_AMD_GCN_SHADER;
  125|     21|  }
  126|  3.29k|  if (!strcmp("SPV_AMD_shader_ballot", name)) {
  ------------------
  |  Branch (126:7): [True: 9, False: 3.28k]
  ------------------
  127|      9|    return SPV_EXT_INST_TYPE_SPV_AMD_SHADER_BALLOT;
  128|      9|  }
  129|  3.28k|  if (!strcmp("DebugInfo", name)) {
  ------------------
  |  Branch (129:7): [True: 2.00k, False: 1.28k]
  ------------------
  130|  2.00k|    return SPV_EXT_INST_TYPE_DEBUGINFO;
  131|  2.00k|  }
  132|  1.28k|  if (!strcmp("OpenCL.DebugInfo.100", name)) {
  ------------------
  |  Branch (132:7): [True: 45, False: 1.23k]
  ------------------
  133|     45|    return SPV_EXT_INST_TYPE_OPENCL_DEBUGINFO_100;
  134|     45|  }
  135|  1.23k|  if (!strcmp("NonSemantic.Shader.DebugInfo.100", name)) {
  ------------------
  |  Branch (135:7): [True: 2, False: 1.23k]
  ------------------
  136|      2|    return SPV_EXT_INST_TYPE_NONSEMANTIC_SHADER_DEBUGINFO_100;
  137|      2|  }
  138|  1.23k|  if (!strncmp("NonSemantic.ClspvReflection.", name, 28)) {
  ------------------
  |  Branch (138:7): [True: 28, False: 1.20k]
  ------------------
  139|     28|    return SPV_EXT_INST_TYPE_NONSEMANTIC_CLSPVREFLECTION;
  140|     28|  }
  141|       |  // ensure to add any known non-semantic extended instruction sets
  142|       |  // above this point, and update spvExtInstIsNonSemantic()
  143|  1.20k|  if (!strncmp("NonSemantic.", name, 12)) {
  ------------------
  |  Branch (143:7): [True: 514, False: 695]
  ------------------
  144|    514|    return SPV_EXT_INST_TYPE_NONSEMANTIC_UNKNOWN;
  145|    514|  }
  146|    695|  return SPV_EXT_INST_TYPE_NONE;
  147|  1.20k|}
_Z23spvExtInstIsNonSemantic19spv_ext_inst_type_t:
  149|  48.0k|bool spvExtInstIsNonSemantic(const spv_ext_inst_type_t type) {
  150|  48.0k|  if (type == SPV_EXT_INST_TYPE_NONSEMANTIC_UNKNOWN ||
  ------------------
  |  Branch (150:7): [True: 394, False: 47.6k]
  ------------------
  151|  48.0k|      type == SPV_EXT_INST_TYPE_NONSEMANTIC_SHADER_DEBUGINFO_100 ||
  ------------------
  |  Branch (151:7): [True: 0, False: 47.6k]
  ------------------
  152|  48.0k|      type == SPV_EXT_INST_TYPE_NONSEMANTIC_CLSPVREFLECTION) {
  ------------------
  |  Branch (152:7): [True: 36, False: 47.6k]
  ------------------
  153|    430|    return true;
  154|    430|  }
  155|  47.6k|  return false;
  156|  48.0k|}
_Z21spvExtInstIsDebugInfo19spv_ext_inst_type_t:
  158|  11.6k|bool spvExtInstIsDebugInfo(const spv_ext_inst_type_t type) {
  159|  11.6k|  if (type == SPV_EXT_INST_TYPE_OPENCL_DEBUGINFO_100 ||
  ------------------
  |  Branch (159:7): [True: 0, False: 11.6k]
  ------------------
  160|  11.6k|      type == SPV_EXT_INST_TYPE_NONSEMANTIC_SHADER_DEBUGINFO_100 ||
  ------------------
  |  Branch (160:7): [True: 0, False: 11.6k]
  ------------------
  161|  11.6k|      type == SPV_EXT_INST_TYPE_DEBUGINFO) {
  ------------------
  |  Branch (161:7): [True: 5, False: 11.6k]
  ------------------
  162|      5|    return true;
  163|      5|  }
  164|  11.6k|  return false;
  165|  11.6k|}
_Z26spvExtInstTableValueLookupPK20spv_ext_inst_table_t19spv_ext_inst_type_tjPPK19spv_ext_inst_desc_t:
  192|  16.2k|                                        spv_ext_inst_desc* pEntry) {
  193|  16.2k|  if (!table) return SPV_ERROR_INVALID_TABLE;
  ------------------
  |  Branch (193:7): [True: 0, False: 16.2k]
  ------------------
  194|  16.2k|  if (!pEntry) return SPV_ERROR_INVALID_POINTER;
  ------------------
  |  Branch (194:7): [True: 0, False: 16.2k]
  ------------------
  195|       |
  196|  20.8k|  for (uint32_t groupIndex = 0; groupIndex < table->count; groupIndex++) {
  ------------------
  |  Branch (196:33): [True: 20.3k, False: 411]
  ------------------
  197|  20.3k|    const auto& group = table->groups[groupIndex];
  198|  20.3k|    if (type != group.type) continue;
  ------------------
  |  Branch (198:9): [True: 4.52k, False: 15.8k]
  ------------------
  199|   447k|    for (uint32_t index = 0; index < group.count; index++) {
  ------------------
  |  Branch (199:30): [True: 447k, False: 58]
  ------------------
  200|   447k|      const auto& entry = group.entries[index];
  201|   447k|      if (value == entry.ext_inst) {
  ------------------
  |  Branch (201:11): [True: 15.8k, False: 431k]
  ------------------
  202|  15.8k|        *pEntry = &entry;
  203|  15.8k|        return SPV_SUCCESS;
  204|  15.8k|      }
  205|   447k|    }
  206|  15.8k|  }
  207|       |
  208|    411|  return SPV_ERROR_INVALID_LOOKUP;
  209|  16.2k|}

_ZN8spvtools18GetExtensionStringEPK24spv_parsed_instruction_t:
   26|  5.94k|std::string GetExtensionString(const spv_parsed_instruction_t* inst) {
   27|  5.94k|  if (inst->opcode != static_cast<uint16_t>(spv::Op::OpExtension)) {
  ------------------
  |  Branch (27:7): [True: 0, False: 5.94k]
  ------------------
   28|      0|    return "ERROR_not_op_extension";
   29|      0|  }
   30|       |
   31|  5.94k|  assert(inst->num_operands == 1);
   32|       |
   33|      0|  const auto& operand = inst->operands[0];
   34|  5.94k|  assert(operand.type == SPV_OPERAND_TYPE_LITERAL_STRING);
   35|      0|  assert(inst->num_words > operand.offset);
   36|      0|  (void)operand; /* No unused variables in release builds. */
   37|       |
   38|  5.94k|  return spvDecodeLiteralStringOperand(*inst, 0);
   39|  5.94k|}
_ZN8spvtools20ExtensionSetToStringERKNS_7EnumSetINS_9ExtensionEEE:
   41|     42|std::string ExtensionSetToString(const ExtensionSet& extensions) {
   42|     42|  std::stringstream ss;
   43|     42|  extensions.ForEach(
   44|     42|      [&ss](Extension ext) { ss << ExtensionToString(ext) << " "; });
   45|     42|  return ss.str();
   46|     42|}
extensions.cpp:_ZZN8spvtools20ExtensionSetToStringERKNS_7EnumSetINS_9ExtensionEEEENK3$_0clES1_:
   44|     51|      [&ss](Extension ext) { ss << ExtensionToString(ext) << " "; });

_ZN8spvtools10SpirvToolsC2E14spv_target_env:
   63|  8.24k|SpirvTools::SpirvTools(spv_target_env env) : impl_(new Impl(env)) {
   64|  8.24k|  assert(env != SPV_ENV_WEBGPU_0);
   65|  8.24k|}
_ZN8spvtools10SpirvToolsD2Ev:
   67|  8.24k|SpirvTools::~SpirvTools() {}
_ZN8spvtools10SpirvTools18SetMessageConsumerENSt3__18functionIFv19spv_message_level_tPKcRK14spv_position_tS5_EEE:
   69|  8.24k|void SpirvTools::SetMessageConsumer(MessageConsumer consumer) {
   70|  8.24k|  SetContextMessageConsumer(impl_->context, std::move(consumer));
   71|  8.24k|}
_ZNK8spvtools10SpirvTools8ValidateERKNSt3__16vectorIjNS1_9allocatorIjEEEE:
  145|  8.24k|bool SpirvTools::Validate(const std::vector<uint32_t>& binary) const {
  146|  8.24k|  return Validate(binary.data(), binary.size());
  147|  8.24k|}
_ZNK8spvtools10SpirvTools8ValidateEPKjm:
  150|  8.24k|                          const size_t binary_size) const {
  151|  8.24k|  return spvValidateBinary(impl_->context, binary, binary_size, nullptr) ==
  152|  8.24k|         SPV_SUCCESS;
  153|  8.24k|}
_ZN8spvtools10SpirvTools4ImplC2E14spv_target_env:
   53|  8.24k|  explicit Impl(spv_target_env env) : context(spvContextCreate(env)) {
   54|       |    // The default consumer in spv_context_t is a null consumer, which provides
   55|       |    // equivalent functionality (from the user's perspective) as a real consumer
   56|       |    // does nothing.
   57|  8.24k|  }
_ZN8spvtools10SpirvTools4ImplD2Ev:
   58|  8.24k|  ~Impl() { spvContextDestroy(context); }

_ZN8spvtools20GetTrivialNameMapperEv:
   44|  12.6k|NameMapper GetTrivialNameMapper() { return to_string; }
_ZN8spvtools18FriendlyNameMapperC2EPK13spv_context_tPKjm:
   49|  12.6k|    : grammar_(AssemblyGrammar(context)) {
   50|  12.6k|  spv_diagnostic diag = nullptr;
   51|       |  // We don't care if the parse fails.
   52|  12.6k|  spvBinaryParse(context, this, code, wordCount, nullptr,
   53|  12.6k|                 ParseInstructionForwarder, &diag);
   54|  12.6k|  spvDiagnosticDestroy(diag);
   55|  12.6k|}
_ZN8spvtools18FriendlyNameMapper9NameForIdEj:
   57|   473k|std::string FriendlyNameMapper::NameForId(uint32_t id) {
   58|   473k|  auto iter = name_for_id_.find(id);
   59|   473k|  if (iter == name_for_id_.end()) {
  ------------------
  |  Branch (59:7): [True: 407k, False: 65.6k]
  ------------------
   60|       |    // It must have been an invalid module, so just return a trivial mapping.
   61|       |    // We don't care about uniqueness.
   62|   407k|    return to_string(id);
   63|   407k|  } else {
   64|  65.6k|    return iter->second;
   65|  65.6k|  }
   66|   473k|}
_ZN8spvtools18FriendlyNameMapper8SanitizeERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEE:
   68|   366k|std::string FriendlyNameMapper::Sanitize(const std::string& suggested_name) {
   69|   366k|  if (suggested_name.empty()) return "_";
  ------------------
  |  Branch (69:7): [True: 654, False: 366k]
  ------------------
   70|       |  // Otherwise, replace invalid characters by '_'.
   71|   366k|  std::string result;
   72|   366k|  std::string valid =
   73|   366k|      "abcdefghijklmnopqrstuvwxyz"
   74|   366k|      "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
   75|   366k|      "_0123456789";
   76|   366k|  std::transform(suggested_name.begin(), suggested_name.end(),
   77|   366k|                 std::back_inserter(result), [&valid](const char c) {
   78|   366k|                   return (std::string::npos == valid.find(c)) ? '_' : c;
   79|   366k|                 });
   80|   366k|  return result;
   81|   366k|}
_ZN8spvtools18FriendlyNameMapper8SaveNameEjRKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEE:
   84|   438k|                                  const std::string& suggested_name) {
   85|   438k|  if (name_for_id_.find(id) != name_for_id_.end()) return;
  ------------------
  |  Branch (85:7): [True: 72.1k, False: 366k]
  ------------------
   86|       |
   87|   366k|  const std::string sanitized_suggested_name = Sanitize(suggested_name);
   88|   366k|  std::string name = sanitized_suggested_name;
   89|   366k|  auto inserted = used_names_.insert(name);
   90|   366k|  if (!inserted.second) {
  ------------------
  |  Branch (90:7): [True: 3.82k, False: 362k]
  ------------------
   91|  3.82k|    const std::string base_name = sanitized_suggested_name + "_";
   92|  19.7k|    for (uint32_t index = 0; !inserted.second; ++index) {
  ------------------
  |  Branch (92:30): [True: 15.9k, False: 3.82k]
  ------------------
   93|  15.9k|      name = base_name + to_string(index);
   94|  15.9k|      inserted = used_names_.insert(name);
   95|  15.9k|    }
   96|  3.82k|  }
   97|   366k|  name_for_id_[id] = name;
   98|   366k|}
_ZN8spvtools18FriendlyNameMapper15SaveBuiltInNameEjj:
  101|  73.6k|                                         uint32_t built_in) {
  102|  73.6k|#define GLCASE(name)                  \
  103|  73.6k|  case spv::BuiltIn::name:            \
  104|  73.6k|    SaveName(target_id, "gl_" #name); \
  105|  73.6k|    return;
  106|  73.6k|#define GLCASE2(name, suggested)           \
  107|  73.6k|  case spv::BuiltIn::name:                 \
  108|  73.6k|    SaveName(target_id, "gl_" #suggested); \
  109|  73.6k|    return;
  110|  73.6k|#define CASE(name)              \
  111|  73.6k|  case spv::BuiltIn::name:      \
  112|  73.6k|    SaveName(target_id, #name); \
  113|  73.6k|    return;
  114|  73.6k|  switch (spv::BuiltIn(built_in)) {
  115|    207|    GLCASE(Position)
  ------------------
  |  |  103|    207|  case spv::BuiltIn::name:            \
  |  |  ------------------
  |  |  |  Branch (103:3): [True: 207, False: 73.4k]
  |  |  ------------------
  |  |  104|    207|    SaveName(target_id, "gl_" #name); \
  |  |  105|    207|    return;
  ------------------
  116|    219|    GLCASE(PointSize)
  ------------------
  |  |  103|    219|  case spv::BuiltIn::name:            \
  |  |  ------------------
  |  |  |  Branch (103:3): [True: 219, False: 73.4k]
  |  |  ------------------
  |  |  104|    219|    SaveName(target_id, "gl_" #name); \
  |  |  105|    219|    return;
  ------------------
  117|     51|    GLCASE(ClipDistance)
  ------------------
  |  |  103|     51|  case spv::BuiltIn::name:            \
  |  |  ------------------
  |  |  |  Branch (103:3): [True: 51, False: 73.6k]
  |  |  ------------------
  |  |  104|     51|    SaveName(target_id, "gl_" #name); \
  |  |  105|     51|    return;
  ------------------
  118|     32|    GLCASE(CullDistance)
  ------------------
  |  |  103|     32|  case spv::BuiltIn::name:            \
  |  |  ------------------
  |  |  |  Branch (103:3): [True: 32, False: 73.6k]
  |  |  ------------------
  |  |  104|     32|    SaveName(target_id, "gl_" #name); \
  |  |  105|     32|    return;
  ------------------
  119|     32|    GLCASE2(VertexId, VertexID)
  ------------------
  |  |  107|     32|  case spv::BuiltIn::name:                 \
  |  |  ------------------
  |  |  |  Branch (107:3): [True: 32, False: 73.6k]
  |  |  ------------------
  |  |  108|     32|    SaveName(target_id, "gl_" #suggested); \
  |  |  109|     32|    return;
  ------------------
  120|    202|    GLCASE2(InstanceId, InstanceID)
  ------------------
  |  |  107|    202|  case spv::BuiltIn::name:                 \
  |  |  ------------------
  |  |  |  Branch (107:3): [True: 202, False: 73.4k]
  |  |  ------------------
  |  |  108|    202|    SaveName(target_id, "gl_" #suggested); \
  |  |  109|    202|    return;
  ------------------
  121|    225|    GLCASE2(PrimitiveId, PrimitiveID)
  ------------------
  |  |  107|    225|  case spv::BuiltIn::name:                 \
  |  |  ------------------
  |  |  |  Branch (107:3): [True: 225, False: 73.4k]
  |  |  ------------------
  |  |  108|    225|    SaveName(target_id, "gl_" #suggested); \
  |  |  109|    225|    return;
  ------------------
  122|     49|    GLCASE2(InvocationId, InvocationID)
  ------------------
  |  |  107|     49|  case spv::BuiltIn::name:                 \
  |  |  ------------------
  |  |  |  Branch (107:3): [True: 49, False: 73.6k]
  |  |  ------------------
  |  |  108|     49|    SaveName(target_id, "gl_" #suggested); \
  |  |  109|     49|    return;
  ------------------
  123|    214|    GLCASE(Layer)
  ------------------
  |  |  103|    214|  case spv::BuiltIn::name:            \
  |  |  ------------------
  |  |  |  Branch (103:3): [True: 214, False: 73.4k]
  |  |  ------------------
  |  |  104|    214|    SaveName(target_id, "gl_" #name); \
  |  |  105|    214|    return;
  ------------------
  124|     49|    GLCASE(ViewportIndex)
  ------------------
  |  |  103|     49|  case spv::BuiltIn::name:            \
  |  |  ------------------
  |  |  |  Branch (103:3): [True: 49, False: 73.6k]
  |  |  ------------------
  |  |  104|     49|    SaveName(target_id, "gl_" #name); \
  |  |  105|     49|    return;
  ------------------
  125|     19|    GLCASE(TessLevelOuter)
  ------------------
  |  |  103|     19|  case spv::BuiltIn::name:            \
  |  |  ------------------
  |  |  |  Branch (103:3): [True: 19, False: 73.6k]
  |  |  ------------------
  |  |  104|     19|    SaveName(target_id, "gl_" #name); \
  |  |  105|     19|    return;
  ------------------
  126|    820|    GLCASE(TessLevelInner)
  ------------------
  |  |  103|    820|  case spv::BuiltIn::name:            \
  |  |  ------------------
  |  |  |  Branch (103:3): [True: 820, False: 72.8k]
  |  |  ------------------
  |  |  104|    820|    SaveName(target_id, "gl_" #name); \
  |  |  105|    820|    return;
  ------------------
  127|    272|    GLCASE(TessCoord)
  ------------------
  |  |  103|    272|  case spv::BuiltIn::name:            \
  |  |  ------------------
  |  |  |  Branch (103:3): [True: 272, False: 73.3k]
  |  |  ------------------
  |  |  104|    272|    SaveName(target_id, "gl_" #name); \
  |  |  105|    272|    return;
  ------------------
  128|  8.54k|    GLCASE(PatchVertices)
  ------------------
  |  |  103|  8.54k|  case spv::BuiltIn::name:            \
  |  |  ------------------
  |  |  |  Branch (103:3): [True: 8.54k, False: 65.1k]
  |  |  ------------------
  |  |  104|  8.54k|    SaveName(target_id, "gl_" #name); \
  |  |  105|  8.54k|    return;
  ------------------
  129|    275|    GLCASE(FragCoord)
  ------------------
  |  |  103|    275|  case spv::BuiltIn::name:            \
  |  |  ------------------
  |  |  |  Branch (103:3): [True: 275, False: 73.3k]
  |  |  ------------------
  |  |  104|    275|    SaveName(target_id, "gl_" #name); \
  |  |  105|    275|    return;
  ------------------
  130|    588|    GLCASE(PointCoord)
  ------------------
  |  |  103|    588|  case spv::BuiltIn::name:            \
  |  |  ------------------
  |  |  |  Branch (103:3): [True: 588, False: 73.0k]
  |  |  ------------------
  |  |  104|    588|    SaveName(target_id, "gl_" #name); \
  |  |  105|    588|    return;
  ------------------
  131|     39|    GLCASE(FrontFacing)
  ------------------
  |  |  103|     39|  case spv::BuiltIn::name:            \
  |  |  ------------------
  |  |  |  Branch (103:3): [True: 39, False: 73.6k]
  |  |  ------------------
  |  |  104|     39|    SaveName(target_id, "gl_" #name); \
  |  |  105|     39|    return;
  ------------------
  132|  1.76k|    GLCASE2(SampleId, SampleID)
  ------------------
  |  |  107|  1.76k|  case spv::BuiltIn::name:                 \
  |  |  ------------------
  |  |  |  Branch (107:3): [True: 1.76k, False: 71.8k]
  |  |  ------------------
  |  |  108|  1.76k|    SaveName(target_id, "gl_" #suggested); \
  |  |  109|  1.76k|    return;
  ------------------
  133|    188|    GLCASE(SamplePosition)
  ------------------
  |  |  103|    188|  case spv::BuiltIn::name:            \
  |  |  ------------------
  |  |  |  Branch (103:3): [True: 188, False: 73.4k]
  |  |  ------------------
  |  |  104|    188|    SaveName(target_id, "gl_" #name); \
  |  |  105|    188|    return;
  ------------------
  134|     45|    GLCASE(SampleMask)
  ------------------
  |  |  103|     45|  case spv::BuiltIn::name:            \
  |  |  ------------------
  |  |  |  Branch (103:3): [True: 45, False: 73.6k]
  |  |  ------------------
  |  |  104|     45|    SaveName(target_id, "gl_" #name); \
  |  |  105|     45|    return;
  ------------------
  135|     52|    GLCASE(FragDepth)
  ------------------
  |  |  103|     52|  case spv::BuiltIn::name:            \
  |  |  ------------------
  |  |  |  Branch (103:3): [True: 52, False: 73.6k]
  |  |  ------------------
  |  |  104|     52|    SaveName(target_id, "gl_" #name); \
  |  |  105|     52|    return;
  ------------------
  136|    250|    GLCASE(HelperInvocation)
  ------------------
  |  |  103|    250|  case spv::BuiltIn::name:            \
  |  |  ------------------
  |  |  |  Branch (103:3): [True: 250, False: 73.4k]
  |  |  ------------------
  |  |  104|    250|    SaveName(target_id, "gl_" #name); \
  |  |  105|    250|    return;
  ------------------
  137|  2.43k|    GLCASE2(NumWorkgroups, NumWorkGroups)
  ------------------
  |  |  107|  2.43k|  case spv::BuiltIn::name:                 \
  |  |  ------------------
  |  |  |  Branch (107:3): [True: 2.43k, False: 71.2k]
  |  |  ------------------
  |  |  108|  2.43k|    SaveName(target_id, "gl_" #suggested); \
  |  |  109|  2.43k|    return;
  ------------------
  138|  1.81k|    GLCASE2(WorkgroupSize, WorkGroupSize)
  ------------------
  |  |  107|  1.81k|  case spv::BuiltIn::name:                 \
  |  |  ------------------
  |  |  |  Branch (107:3): [True: 1.81k, False: 71.8k]
  |  |  ------------------
  |  |  108|  1.81k|    SaveName(target_id, "gl_" #suggested); \
  |  |  109|  1.81k|    return;
  ------------------
  139|  6.22k|    GLCASE2(WorkgroupId, WorkGroupID)
  ------------------
  |  |  107|  6.22k|  case spv::BuiltIn::name:                 \
  |  |  ------------------
  |  |  |  Branch (107:3): [True: 6.22k, False: 67.4k]
  |  |  ------------------
  |  |  108|  6.22k|    SaveName(target_id, "gl_" #suggested); \
  |  |  109|  6.22k|    return;
  ------------------
  140|     99|    GLCASE2(LocalInvocationId, LocalInvocationID)
  ------------------
  |  |  107|     99|  case spv::BuiltIn::name:                 \
  |  |  ------------------
  |  |  |  Branch (107:3): [True: 99, False: 73.5k]
  |  |  ------------------
  |  |  108|     99|    SaveName(target_id, "gl_" #suggested); \
  |  |  109|     99|    return;
  ------------------
  141|  18.1k|    GLCASE2(GlobalInvocationId, GlobalInvocationID)
  ------------------
  |  |  107|  18.1k|  case spv::BuiltIn::name:                 \
  |  |  ------------------
  |  |  |  Branch (107:3): [True: 18.1k, False: 55.5k]
  |  |  ------------------
  |  |  108|  18.1k|    SaveName(target_id, "gl_" #suggested); \
  |  |  109|  18.1k|    return;
  ------------------
  142|  2.34k|    GLCASE(LocalInvocationIndex)
  ------------------
  |  |  103|  2.34k|  case spv::BuiltIn::name:            \
  |  |  ------------------
  |  |  |  Branch (103:3): [True: 2.34k, False: 71.3k]
  |  |  ------------------
  |  |  104|  2.34k|    SaveName(target_id, "gl_" #name); \
  |  |  105|  2.34k|    return;
  ------------------
  143|    558|    CASE(WorkDim)
  ------------------
  |  |  111|    558|  case spv::BuiltIn::name:      \
  |  |  ------------------
  |  |  |  Branch (111:3): [True: 558, False: 73.1k]
  |  |  ------------------
  |  |  112|    558|    SaveName(target_id, #name); \
  |  |  113|    558|    return;
  ------------------
  144|  7.48k|    CASE(GlobalSize)
  ------------------
  |  |  111|  7.48k|  case spv::BuiltIn::name:      \
  |  |  ------------------
  |  |  |  Branch (111:3): [True: 7.48k, False: 66.1k]
  |  |  ------------------
  |  |  112|  7.48k|    SaveName(target_id, #name); \
  |  |  113|  7.48k|    return;
  ------------------
  145|     48|    CASE(EnqueuedWorkgroupSize)
  ------------------
  |  |  111|     48|  case spv::BuiltIn::name:      \
  |  |  ------------------
  |  |  |  Branch (111:3): [True: 48, False: 73.6k]
  |  |  ------------------
  |  |  112|     48|    SaveName(target_id, #name); \
  |  |  113|     48|    return;
  ------------------
  146|    316|    CASE(GlobalOffset)
  ------------------
  |  |  111|    316|  case spv::BuiltIn::name:      \
  |  |  ------------------
  |  |  |  Branch (111:3): [True: 316, False: 73.3k]
  |  |  ------------------
  |  |  112|    316|    SaveName(target_id, #name); \
  |  |  113|    316|    return;
  ------------------
  147|  10.3k|    CASE(GlobalLinearId)
  ------------------
  |  |  111|  10.3k|  case spv::BuiltIn::name:      \
  |  |  ------------------
  |  |  |  Branch (111:3): [True: 10.3k, False: 63.2k]
  |  |  ------------------
  |  |  112|  10.3k|    SaveName(target_id, #name); \
  |  |  113|  10.3k|    return;
  ------------------
  148|  1.59k|    CASE(SubgroupSize)
  ------------------
  |  |  111|  1.59k|  case spv::BuiltIn::name:      \
  |  |  ------------------
  |  |  |  Branch (111:3): [True: 1.59k, False: 72.0k]
  |  |  ------------------
  |  |  112|  1.59k|    SaveName(target_id, #name); \
  |  |  113|  1.59k|    return;
  ------------------
  149|     57|    CASE(SubgroupMaxSize)
  ------------------
  |  |  111|     57|  case spv::BuiltIn::name:      \
  |  |  ------------------
  |  |  |  Branch (111:3): [True: 57, False: 73.6k]
  |  |  ------------------
  |  |  112|     57|    SaveName(target_id, #name); \
  |  |  113|     57|    return;
  ------------------
  150|    106|    CASE(NumSubgroups)
  ------------------
  |  |  111|    106|  case spv::BuiltIn::name:      \
  |  |  ------------------
  |  |  |  Branch (111:3): [True: 106, False: 73.5k]
  |  |  ------------------
  |  |  112|    106|    SaveName(target_id, #name); \
  |  |  113|    106|    return;
  ------------------
  151|  1.54k|    CASE(NumEnqueuedSubgroups)
  ------------------
  |  |  111|  1.54k|  case spv::BuiltIn::name:      \
  |  |  ------------------
  |  |  |  Branch (111:3): [True: 1.54k, False: 72.1k]
  |  |  ------------------
  |  |  112|  1.54k|    SaveName(target_id, #name); \
  |  |  113|  1.54k|    return;
  ------------------
  152|     58|    CASE(SubgroupId)
  ------------------
  |  |  111|     58|  case spv::BuiltIn::name:      \
  |  |  ------------------
  |  |  |  Branch (111:3): [True: 58, False: 73.6k]
  |  |  ------------------
  |  |  112|     58|    SaveName(target_id, #name); \
  |  |  113|     58|    return;
  ------------------
  153|    924|    CASE(SubgroupLocalInvocationId)
  ------------------
  |  |  111|    924|  case spv::BuiltIn::name:      \
  |  |  ------------------
  |  |  |  Branch (111:3): [True: 924, False: 72.7k]
  |  |  ------------------
  |  |  112|    924|    SaveName(target_id, #name); \
  |  |  113|    924|    return;
  ------------------
  154|  1.38k|    GLCASE(VertexIndex)
  ------------------
  |  |  103|  1.38k|  case spv::BuiltIn::name:            \
  |  |  ------------------
  |  |  |  Branch (103:3): [True: 1.38k, False: 72.2k]
  |  |  ------------------
  |  |  104|  1.38k|    SaveName(target_id, "gl_" #name); \
  |  |  105|  1.38k|    return;
  ------------------
  155|  3.95k|    GLCASE(InstanceIndex)
  ------------------
  |  |  103|  3.95k|  case spv::BuiltIn::name:            \
  |  |  ------------------
  |  |  |  Branch (103:3): [True: 3.95k, False: 69.7k]
  |  |  ------------------
  |  |  104|  3.95k|    SaveName(target_id, "gl_" #name); \
  |  |  105|  3.95k|    return;
  ------------------
  156|      2|    GLCASE(BaseInstance)
  ------------------
  |  |  103|      2|  case spv::BuiltIn::name:            \
  |  |  ------------------
  |  |  |  Branch (103:3): [True: 2, False: 73.6k]
  |  |  ------------------
  |  |  104|      2|    SaveName(target_id, "gl_" #name); \
  |  |  105|      2|    return;
  ------------------
  157|     10|    CASE(SubgroupEqMaskKHR)
  ------------------
  |  |  111|     10|  case spv::BuiltIn::name:      \
  |  |  ------------------
  |  |  |  Branch (111:3): [True: 10, False: 73.6k]
  |  |  ------------------
  |  |  112|     10|    SaveName(target_id, #name); \
  |  |  113|     10|    return;
  ------------------
  158|     33|    CASE(SubgroupGeMaskKHR)
  ------------------
  |  |  111|     33|  case spv::BuiltIn::name:      \
  |  |  ------------------
  |  |  |  Branch (111:3): [True: 33, False: 73.6k]
  |  |  ------------------
  |  |  112|     33|    SaveName(target_id, #name); \
  |  |  113|     33|    return;
  ------------------
  159|      6|    CASE(SubgroupGtMaskKHR)
  ------------------
  |  |  111|      6|  case spv::BuiltIn::name:      \
  |  |  ------------------
  |  |  |  Branch (111:3): [True: 6, False: 73.6k]
  |  |  ------------------
  |  |  112|      6|    SaveName(target_id, #name); \
  |  |  113|      6|    return;
  ------------------
  160|     10|    CASE(SubgroupLeMaskKHR)
  ------------------
  |  |  111|     10|  case spv::BuiltIn::name:      \
  |  |  ------------------
  |  |  |  Branch (111:3): [True: 10, False: 73.6k]
  |  |  ------------------
  |  |  112|     10|    SaveName(target_id, #name); \
  |  |  113|     10|    return;
  ------------------
  161|     36|    CASE(SubgroupLtMaskKHR)
  ------------------
  |  |  111|     36|  case spv::BuiltIn::name:      \
  |  |  ------------------
  |  |  |  Branch (111:3): [True: 36, False: 73.6k]
  |  |  ------------------
  |  |  112|     36|    SaveName(target_id, #name); \
  |  |  113|     36|    return;
  ------------------
  162|     18|    default:
  ------------------
  |  Branch (162:5): [True: 18, False: 73.6k]
  ------------------
  163|     18|      break;
  164|  73.6k|  }
  165|  73.6k|#undef GLCASE
  166|  73.6k|#undef GLCASE2
  167|  73.6k|#undef CASE
  168|  73.6k|}
_ZN8spvtools18FriendlyNameMapper16ParseInstructionERK24spv_parsed_instruction_t:
  171|   775k|    const spv_parsed_instruction_t& inst) {
  172|   775k|  const auto result_id = inst.result_id;
  173|   775k|  switch (spv::Op(inst.opcode)) {
  174|  5.25k|    case spv::Op::OpName:
  ------------------
  |  Branch (174:5): [True: 5.25k, False: 769k]
  ------------------
  175|  5.25k|      SaveName(inst.words[1], spvDecodeLiteralStringOperand(inst, 1));
  176|  5.25k|      break;
  177|  99.4k|    case spv::Op::OpDecorate:
  ------------------
  |  Branch (177:5): [True: 99.4k, False: 675k]
  ------------------
  178|       |      // Decorations come after OpName.  So OpName will take precedence over
  179|       |      // decorations.
  180|       |      //
  181|       |      // In theory, we should also handle OpGroupDecorate.  But that's unlikely
  182|       |      // to occur.
  183|  99.4k|      if (spv::Decoration(inst.words[2]) == spv::Decoration::BuiltIn) {
  ------------------
  |  Branch (183:11): [True: 73.6k, False: 25.7k]
  ------------------
  184|  73.6k|        assert(inst.num_words > 3);
  185|      0|        SaveBuiltInName(inst.words[1], inst.words[3]);
  186|  73.6k|      }
  187|      0|      break;
  188|  6.07k|    case spv::Op::OpTypeVoid:
  ------------------
  |  Branch (188:5): [True: 6.07k, False: 769k]
  ------------------
  189|  6.07k|      SaveName(result_id, "void");
  190|  6.07k|      break;
  191|  1.83k|    case spv::Op::OpTypeBool:
  ------------------
  |  Branch (191:5): [True: 1.83k, False: 773k]
  ------------------
  192|  1.83k|      SaveName(result_id, "bool");
  193|  1.83k|      break;
  194|  5.65k|    case spv::Op::OpTypeInt: {
  ------------------
  |  Branch (194:5): [True: 5.65k, False: 769k]
  ------------------
  195|  5.65k|      std::string signedness;
  196|  5.65k|      std::string root;
  197|  5.65k|      const auto bit_width = inst.words[2];
  198|  5.65k|      switch (bit_width) {
  199|     47|        case 8:
  ------------------
  |  Branch (199:9): [True: 47, False: 5.60k]
  ------------------
  200|     47|          root = "char";
  201|     47|          break;
  202|     15|        case 16:
  ------------------
  |  Branch (202:9): [True: 15, False: 5.63k]
  ------------------
  203|     15|          root = "short";
  204|     15|          break;
  205|  4.87k|        case 32:
  ------------------
  |  Branch (205:9): [True: 4.87k, False: 773]
  ------------------
  206|  4.87k|          root = "int";
  207|  4.87k|          break;
  208|     15|        case 64:
  ------------------
  |  Branch (208:9): [True: 15, False: 5.63k]
  ------------------
  209|     15|          root = "long";
  210|     15|          break;
  211|    696|        default:
  ------------------
  |  Branch (211:9): [True: 696, False: 4.95k]
  ------------------
  212|    696|          root = to_string(bit_width);
  213|    696|          signedness = "i";
  214|    696|          break;
  215|  5.65k|      }
  216|  5.65k|      if (0 == inst.words[3]) signedness = "u";
  ------------------
  |  Branch (216:11): [True: 2.42k, False: 3.23k]
  ------------------
  217|  5.65k|      SaveName(result_id, signedness + root);
  218|  5.65k|    } break;
  219|  3.29k|    case spv::Op::OpTypeFloat: {
  ------------------
  |  Branch (219:5): [True: 3.29k, False: 771k]
  ------------------
  220|  3.29k|      const auto bit_width = inst.words[2];
  221|  3.29k|      switch (bit_width) {
  222|    101|        case 16:
  ------------------
  |  Branch (222:9): [True: 101, False: 3.19k]
  ------------------
  223|    101|          SaveName(result_id, "half");
  224|    101|          break;
  225|  2.47k|        case 32:
  ------------------
  |  Branch (225:9): [True: 2.47k, False: 829]
  ------------------
  226|  2.47k|          SaveName(result_id, "float");
  227|  2.47k|          break;
  228|     13|        case 64:
  ------------------
  |  Branch (228:9): [True: 13, False: 3.28k]
  ------------------
  229|     13|          SaveName(result_id, "double");
  230|     13|          break;
  231|    715|        default:
  ------------------
  |  Branch (231:9): [True: 715, False: 2.58k]
  ------------------
  232|    715|          SaveName(result_id, std::string("fp") + to_string(bit_width));
  233|    715|          break;
  234|  3.29k|      }
  235|  3.29k|    } break;
  236|  4.28k|    case spv::Op::OpTypeVector:
  ------------------
  |  Branch (236:5): [True: 4.28k, False: 770k]
  ------------------
  237|  4.28k|      SaveName(result_id, std::string("v") + to_string(inst.words[3]) +
  238|  4.28k|                              NameForId(inst.words[2]));
  239|  4.28k|      break;
  240|  1.63k|    case spv::Op::OpTypeMatrix:
  ------------------
  |  Branch (240:5): [True: 1.63k, False: 773k]
  ------------------
  241|  1.63k|      SaveName(result_id, std::string("mat") + to_string(inst.words[3]) +
  242|  1.63k|                              NameForId(inst.words[2]));
  243|  1.63k|      break;
  244|  2.33k|    case spv::Op::OpTypeArray:
  ------------------
  |  Branch (244:5): [True: 2.33k, False: 772k]
  ------------------
  245|  2.33k|      SaveName(result_id, std::string("_arr_") + NameForId(inst.words[2]) +
  246|  2.33k|                              "_" + NameForId(inst.words[3]));
  247|  2.33k|      break;
  248|    310|    case spv::Op::OpTypeRuntimeArray:
  ------------------
  |  Branch (248:5): [True: 310, False: 774k]
  ------------------
  249|    310|      SaveName(result_id,
  250|    310|               std::string("_runtimearr_") + NameForId(inst.words[2]));
  251|    310|      break;
  252|  12.5k|    case spv::Op::OpTypePointer:
  ------------------
  |  Branch (252:5): [True: 12.5k, False: 762k]
  ------------------
  253|  12.5k|      SaveName(result_id, std::string("_ptr_") +
  254|  12.5k|                              NameForEnumOperand(SPV_OPERAND_TYPE_STORAGE_CLASS,
  255|  12.5k|                                                 inst.words[2]) +
  256|  12.5k|                              "_" + NameForId(inst.words[3]));
  257|  12.5k|      break;
  258|     19|    case spv::Op::OpTypePipe:
  ------------------
  |  Branch (258:5): [True: 19, False: 775k]
  ------------------
  259|     19|      SaveName(result_id,
  260|     19|               std::string("Pipe") +
  261|     19|                   NameForEnumOperand(SPV_OPERAND_TYPE_ACCESS_QUALIFIER,
  262|     19|                                      inst.words[2]));
  263|     19|      break;
  264|     94|    case spv::Op::OpTypeEvent:
  ------------------
  |  Branch (264:5): [True: 94, False: 775k]
  ------------------
  265|     94|      SaveName(result_id, "Event");
  266|     94|      break;
  267|    143|    case spv::Op::OpTypeDeviceEvent:
  ------------------
  |  Branch (267:5): [True: 143, False: 775k]
  ------------------
  268|    143|      SaveName(result_id, "DeviceEvent");
  269|    143|      break;
  270|     86|    case spv::Op::OpTypeReserveId:
  ------------------
  |  Branch (270:5): [True: 86, False: 775k]
  ------------------
  271|     86|      SaveName(result_id, "ReserveId");
  272|     86|      break;
  273|    103|    case spv::Op::OpTypeQueue:
  ------------------
  |  Branch (273:5): [True: 103, False: 775k]
  ------------------
  274|    103|      SaveName(result_id, "Queue");
  275|    103|      break;
  276|     63|    case spv::Op::OpTypeOpaque:
  ------------------
  |  Branch (276:5): [True: 63, False: 775k]
  ------------------
  277|     63|      SaveName(result_id, std::string("Opaque_") +
  278|     63|                              Sanitize(spvDecodeLiteralStringOperand(inst, 1)));
  279|     63|      break;
  280|     40|    case spv::Op::OpTypePipeStorage:
  ------------------
  |  Branch (280:5): [True: 40, False: 775k]
  ------------------
  281|     40|      SaveName(result_id, "PipeStorage");
  282|     40|      break;
  283|     61|    case spv::Op::OpTypeNamedBarrier:
  ------------------
  |  Branch (283:5): [True: 61, False: 775k]
  ------------------
  284|     61|      SaveName(result_id, "NamedBarrier");
  285|     61|      break;
  286|  8.28k|    case spv::Op::OpTypeStruct:
  ------------------
  |  Branch (286:5): [True: 8.28k, False: 766k]
  ------------------
  287|       |      // Structs are mapped rather simplisitically. Just indicate that they
  288|       |      // are a struct and then give the raw Id number.
  289|  8.28k|      SaveName(result_id, std::string("_struct_") + to_string(result_id));
  290|  8.28k|      break;
  291|    622|    case spv::Op::OpConstantTrue:
  ------------------
  |  Branch (291:5): [True: 622, False: 774k]
  ------------------
  292|    622|      SaveName(result_id, "true");
  293|    622|      break;
  294|    338|    case spv::Op::OpConstantFalse:
  ------------------
  |  Branch (294:5): [True: 338, False: 774k]
  ------------------
  295|    338|      SaveName(result_id, "false");
  296|    338|      break;
  297|  28.5k|    case spv::Op::OpConstant: {
  ------------------
  |  Branch (297:5): [True: 28.5k, False: 746k]
  ------------------
  298|  28.5k|      std::ostringstream value;
  299|  28.5k|      EmitNumericLiteral(&value, inst, inst.operands[2]);
  300|  28.5k|      auto value_str = value.str();
  301|       |      // Use 'n' to signify negative. Other invalid characters will be mapped
  302|       |      // to underscore.
  303|  28.5k|      for (auto& c : value_str)
  ------------------
  |  Branch (303:20): [True: 144k, False: 28.5k]
  ------------------
  304|   144k|        if (c == '-') c = 'n';
  ------------------
  |  Branch (304:13): [True: 3.26k, False: 141k]
  ------------------
  305|  28.5k|      SaveName(result_id, NameForId(inst.type_id) + "_" + value_str);
  306|  28.5k|    } break;
  307|   594k|    default:
  ------------------
  |  Branch (307:5): [True: 594k, False: 181k]
  ------------------
  308|       |      // If this instruction otherwise defines an Id, then save a mapping for
  309|       |      // it.  This is needed to ensure uniqueness in there is an OpName with
  310|       |      // string something like "1" that might collide with this result_id.
  311|       |      // We should only do this if a name hasn't already been registered by some
  312|       |      // previous forward reference.
  313|   594k|      if (result_id && name_for_id_.find(result_id) == name_for_id_.end())
  ------------------
  |  Branch (313:11): [True: 286k, False: 307k]
  |  Branch (313:11): [True: 283k, False: 310k]
  |  Branch (313:24): [True: 283k, False: 3.12k]
  ------------------
  314|   283k|        SaveName(result_id, to_string(result_id));
  315|   594k|      break;
  316|   775k|  }
  317|   775k|  return SPV_SUCCESS;
  318|   775k|}
_ZN8spvtools18FriendlyNameMapper18NameForEnumOperandE18spv_operand_type_tj:
  321|  12.5k|                                                   uint32_t word) {
  322|  12.5k|  spv_operand_desc desc = nullptr;
  323|  12.5k|  if (SPV_SUCCESS == grammar_.lookupOperand(type, word, &desc)) {
  ------------------
  |  Branch (323:7): [True: 12.5k, False: 0]
  ------------------
  324|  12.5k|    return desc->name;
  325|  12.5k|  } else {
  326|       |    // Invalid input.  Just give something.
  327|      0|    return std::string("StorageClass") + to_string(word);
  328|      0|  }
  329|  12.5k|}
name_mapper.cpp:_ZN8spvtools12_GLOBAL__N_19to_stringEj:
   34|   723k|std::string to_string(uint32_t id) {
   35|       |  // Use stringstream, since some versions of Android compilers lack
   36|       |  // std::to_string.
   37|   723k|  std::stringstream os;
   38|   723k|  os << id;
   39|   723k|  return os.str();
   40|   723k|}
name_mapper.cpp:_ZZN8spvtools18FriendlyNameMapper8SanitizeERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEEENK3$_0clEc:
   77|  1.73M|                 std::back_inserter(result), [&valid](const char c) {
   78|  1.73M|                   return (std::string::npos == valid.find(c)) ? '_' : c;
  ------------------
  |  Branch (78:27): [True: 9.12k, False: 1.72M]
  ------------------
   79|  1.73M|                 });

_ZN8spvtools18FriendlyNameMapper13GetNameMapperEv:
   72|  12.6k|  NameMapper GetNameMapper() {
   73|  12.6k|    return [this](uint32_t id) { return this->NameForId(id); };
   74|  12.6k|  }
_ZN8spvtools18FriendlyNameMapper25ParseInstructionForwarderEPvPK24spv_parsed_instruction_t:
  103|   775k|      void* user_data, const spv_parsed_instruction_t* parsed_instruction) {
  104|   775k|    return reinterpret_cast<FriendlyNameMapper*>(user_data)->ParseInstruction(
  105|   775k|        *parsed_instruction);
  106|   775k|  }
_ZZN8spvtools18FriendlyNameMapper13GetNameMapperEvENKUljE_clEj:
   73|   421k|    return [this](uint32_t id) { return this->NameForId(id); };

_Z14spvOpcodeSplitjPtS_:
   72|  1.96M|                    uint16_t* pOpcode) {
   73|  1.96M|  if (pWordCount) {
  ------------------
  |  Branch (73:7): [True: 1.96M, False: 0]
  ------------------
   74|  1.96M|    *pWordCount = (uint16_t)((0xffff0000 & word) >> 16);
   75|  1.96M|  }
   76|  1.96M|  if (pOpcode) {
  ------------------
  |  Branch (76:7): [True: 1.96M, False: 0]
  ------------------
   77|  1.96M|    *pOpcode = 0x0000ffff & word;
   78|  1.96M|  }
   79|  1.96M|}
_Z17spvOpcodeTableGetPPK18spv_opcode_table_t14spv_target_env:
   81|  12.6k|spv_result_t spvOpcodeTableGet(spv_opcode_table* pInstTable, spv_target_env) {
   82|  12.6k|  if (!pInstTable) return SPV_ERROR_INVALID_POINTER;
  ------------------
  |  Branch (82:7): [True: 0, False: 12.6k]
  ------------------
   83|       |
   84|       |  // Descriptions of each opcode.  Each entry describes the format of the
   85|       |  // instruction that follows a particular opcode.
   86|       |
   87|  12.6k|  *pInstTable = &kOpcodeTable;
   88|  12.6k|  return SPV_SUCCESS;
   89|  12.6k|}
_Z25spvOpcodeTableValueLookup14spv_target_envPK18spv_opcode_table_tN3spv2OpEPPK17spv_opcode_desc_t:
  129|  2.73M|                                       spv_opcode_desc* pEntry) {
  130|  2.73M|  if (!table) return SPV_ERROR_INVALID_TABLE;
  ------------------
  |  Branch (130:7): [True: 0, False: 2.73M]
  ------------------
  131|  2.73M|  if (!pEntry) return SPV_ERROR_INVALID_POINTER;
  ------------------
  |  Branch (131:7): [True: 0, False: 2.73M]
  ------------------
  132|       |
  133|  2.73M|  const auto beg = table->entries;
  134|  2.73M|  const auto end = table->entries + table->count;
  135|       |
  136|  2.73M|  spv_opcode_desc_t needle = {"",    opcode, 0, nullptr, 0,   {},
  137|  2.73M|                              false, false,  0, nullptr, ~0u, ~0u};
  138|       |
  139|  2.73M|  auto comp = [](const spv_opcode_desc_t& lhs, const spv_opcode_desc_t& rhs) {
  140|  2.73M|    return lhs.opcode < rhs.opcode;
  141|  2.73M|  };
  142|       |
  143|       |  // We need to loop here because there can exist multiple symbols for the same
  144|       |  // opcode value, and they can be introduced in different target environments,
  145|       |  // which means they can have different minimal version requirements.
  146|       |  // Assumes the underlying table is already sorted ascendingly according to
  147|       |  // opcode value.
  148|  2.73M|  const auto version = spvVersionForTargetEnv(env);
  149|  2.73M|  for (auto it = std::lower_bound(beg, end, needle, comp);
  150|  2.73M|       it != end && it->opcode == opcode; ++it) {
  ------------------
  |  Branch (150:8): [True: 2.73M, False: 165]
  |  Branch (150:21): [True: 2.73M, False: 59]
  ------------------
  151|       |    // We considers the current opcode as available as long as
  152|       |    // 1. The target environment satisfies the minimal requirement of the
  153|       |    //    opcode; or
  154|       |    // 2. There is at least one extension enabling this opcode.
  155|       |    //
  156|       |    // Note that the second rule assumes the extension enabling this instruction
  157|       |    // is indeed requested in the SPIR-V code; checking that should be
  158|       |    // validator's work.
  159|  2.73M|    if ((version >= it->minVersion && version <= it->lastVersion) ||
  ------------------
  |  Branch (159:10): [True: 2.72M, False: 8.55k]
  |  Branch (159:39): [True: 2.72M, False: 0]
  ------------------
  160|  2.73M|        it->numExtensions > 0u || it->numCapabilities > 0u) {
  ------------------
  |  Branch (160:9): [True: 7.91k, False: 642]
  |  Branch (160:35): [True: 632, False: 10]
  ------------------
  161|  2.73M|      *pEntry = it;
  162|  2.73M|      return SPV_SUCCESS;
  163|  2.73M|    }
  164|  2.73M|  }
  165|       |
  166|    224|  return SPV_ERROR_INVALID_LOOKUP;
  167|  2.73M|}
spvOpcodeString:
  186|  20.3k|const char* spvOpcodeString(const uint32_t opcode) {
  187|  20.3k|  const auto beg = kOpcodeTableEntries;
  188|  20.3k|  const auto end = kOpcodeTableEntries + ARRAY_SIZE(kOpcodeTableEntries);
  ------------------
  |  |   23|  20.3k|#define ARRAY_SIZE(A) (static_cast<uint32_t>(sizeof(A) / sizeof(A[0])))
  ------------------
  189|  20.3k|  spv_opcode_desc_t needle = {"",    static_cast<spv::Op>(opcode),
  190|  20.3k|                              0,     nullptr,
  191|  20.3k|                              0,     {},
  192|  20.3k|                              false, false,
  193|  20.3k|                              0,     nullptr,
  194|  20.3k|                              ~0u,   ~0u};
  195|  20.3k|  auto comp = [](const spv_opcode_desc_t& lhs, const spv_opcode_desc_t& rhs) {
  196|  20.3k|    return lhs.opcode < rhs.opcode;
  197|  20.3k|  };
  198|  20.3k|  auto it = std::lower_bound(beg, end, needle, comp);
  199|  20.3k|  if (it != end && it->opcode == spv::Op(opcode)) {
  ------------------
  |  Branch (199:7): [True: 20.3k, False: 0]
  |  Branch (199:20): [True: 20.3k, False: 0]
  ------------------
  200|  20.3k|    return it->name;
  201|  20.3k|  }
  202|       |
  203|      0|  assert(0 && "Unreachable!");
  204|      0|  return "unknown";
  205|  20.3k|}
_Z15spvOpcodeStringN3spv2OpE:
  207|  20.3k|const char* spvOpcodeString(const spv::Op opcode) {
  208|  20.3k|  return spvOpcodeString(static_cast<uint32_t>(opcode));
  209|  20.3k|}
_Z21spvOpcodeIsScalarTypeN3spv2OpE:
  211|  1.94k|int32_t spvOpcodeIsScalarType(const spv::Op opcode) {
  212|  1.94k|  switch (opcode) {
  213|    157|    case spv::Op::OpTypeInt:
  ------------------
  |  Branch (213:5): [True: 157, False: 1.78k]
  ------------------
  214|  1.92k|    case spv::Op::OpTypeFloat:
  ------------------
  |  Branch (214:5): [True: 1.76k, False: 177]
  ------------------
  215|  1.94k|    case spv::Op::OpTypeBool:
  ------------------
  |  Branch (215:5): [True: 19, False: 1.92k]
  ------------------
  216|  1.94k|      return true;
  217|      1|    default:
  ------------------
  |  Branch (217:5): [True: 1, False: 1.94k]
  ------------------
  218|      1|      return false;
  219|  1.94k|  }
  220|  1.94k|}
_Z23spvOpcodeIsSpecConstantN3spv2OpE:
  222|  2.08k|int32_t spvOpcodeIsSpecConstant(const spv::Op opcode) {
  223|  2.08k|  switch (opcode) {
  224|      0|    case spv::Op::OpSpecConstantTrue:
  ------------------
  |  Branch (224:5): [True: 0, False: 2.08k]
  ------------------
  225|      0|    case spv::Op::OpSpecConstantFalse:
  ------------------
  |  Branch (225:5): [True: 0, False: 2.08k]
  ------------------
  226|    104|    case spv::Op::OpSpecConstant:
  ------------------
  |  Branch (226:5): [True: 104, False: 1.97k]
  ------------------
  227|    104|    case spv::Op::OpSpecConstantComposite:
  ------------------
  |  Branch (227:5): [True: 0, False: 2.08k]
  ------------------
  228|    104|    case spv::Op::OpSpecConstantOp:
  ------------------
  |  Branch (228:5): [True: 0, False: 2.08k]
  ------------------
  229|    104|      return true;
  230|  1.97k|    default:
  ------------------
  |  Branch (230:5): [True: 1.97k, False: 104]
  ------------------
  231|  1.97k|      return false;
  232|  2.08k|  }
  233|  2.08k|}
_Z19spvOpcodeIsConstantN3spv2OpE:
  235|   735k|int32_t spvOpcodeIsConstant(const spv::Op opcode) {
  236|   735k|  switch (opcode) {
  237|    594|    case spv::Op::OpConstantTrue:
  ------------------
  |  Branch (237:5): [True: 594, False: 734k]
  ------------------
  238|    925|    case spv::Op::OpConstantFalse:
  ------------------
  |  Branch (238:5): [True: 331, False: 734k]
  ------------------
  239|  40.5k|    case spv::Op::OpConstant:
  ------------------
  |  Branch (239:5): [True: 39.6k, False: 695k]
  ------------------
  240|  46.6k|    case spv::Op::OpConstantComposite:
  ------------------
  |  Branch (240:5): [True: 6.13k, False: 729k]
  ------------------
  241|  46.6k|    case spv::Op::OpConstantSampler:
  ------------------
  |  Branch (241:5): [True: 0, False: 735k]
  ------------------
  242|  47.0k|    case spv::Op::OpConstantNull:
  ------------------
  |  Branch (242:5): [True: 402, False: 734k]
  ------------------
  243|  47.0k|    case spv::Op::OpConstantFunctionPointerINTEL:
  ------------------
  |  Branch (243:5): [True: 0, False: 735k]
  ------------------
  244|  47.1k|    case spv::Op::OpSpecConstantTrue:
  ------------------
  |  Branch (244:5): [True: 56, False: 735k]
  ------------------
  245|  47.1k|    case spv::Op::OpSpecConstantFalse:
  ------------------
  |  Branch (245:5): [True: 26, False: 735k]
  ------------------
  246|  48.3k|    case spv::Op::OpSpecConstant:
  ------------------
  |  Branch (246:5): [True: 1.18k, False: 734k]
  ------------------
  247|  48.5k|    case spv::Op::OpSpecConstantComposite:
  ------------------
  |  Branch (247:5): [True: 168, False: 735k]
  ------------------
  248|  48.5k|    case spv::Op::OpSpecConstantOp:
  ------------------
  |  Branch (248:5): [True: 32, False: 735k]
  ------------------
  249|  48.5k|      return true;
  250|   686k|    default:
  ------------------
  |  Branch (250:5): [True: 686k, False: 48.5k]
  ------------------
  251|   686k|      return false;
  252|   735k|  }
  253|   735k|}
_Z26spvOpcodeIsConstantOrUndefN3spv2OpE:
  255|  9.11k|bool spvOpcodeIsConstantOrUndef(const spv::Op opcode) {
  256|  9.11k|  return opcode == spv::Op::OpUndef || spvOpcodeIsConstant(opcode);
  ------------------
  |  Branch (256:10): [True: 25, False: 9.09k]
  |  Branch (256:40): [True: 9.09k, False: 2]
  ------------------
  257|  9.11k|}
_Z29spvOpcodeIsScalarSpecConstantN3spv2OpE:
  259|     16|bool spvOpcodeIsScalarSpecConstant(const spv::Op opcode) {
  260|     16|  switch (opcode) {
  261|      0|    case spv::Op::OpSpecConstantTrue:
  ------------------
  |  Branch (261:5): [True: 0, False: 16]
  ------------------
  262|      0|    case spv::Op::OpSpecConstantFalse:
  ------------------
  |  Branch (262:5): [True: 0, False: 16]
  ------------------
  263|     16|    case spv::Op::OpSpecConstant:
  ------------------
  |  Branch (263:5): [True: 16, False: 0]
  ------------------
  264|     16|      return true;
  265|      0|    default:
  ------------------
  |  Branch (265:5): [True: 0, False: 16]
  ------------------
  266|      0|      return false;
  267|     16|  }
  268|     16|}
_Z20spvOpcodeIsCompositeN3spv2OpE:
  270|  2.84k|int32_t spvOpcodeIsComposite(const spv::Op opcode) {
  271|  2.84k|  switch (opcode) {
  272|  1.19k|    case spv::Op::OpTypeVector:
  ------------------
  |  Branch (272:5): [True: 1.19k, False: 1.65k]
  ------------------
  273|  1.19k|    case spv::Op::OpTypeMatrix:
  ------------------
  |  Branch (273:5): [True: 5, False: 2.83k]
  ------------------
  274|  1.28k|    case spv::Op::OpTypeArray:
  ------------------
  |  Branch (274:5): [True: 88, False: 2.75k]
  ------------------
  275|  2.84k|    case spv::Op::OpTypeStruct:
  ------------------
  |  Branch (275:5): [True: 1.55k, False: 1.28k]
  ------------------
  276|  2.84k|    case spv::Op::OpTypeCooperativeMatrixNV:
  ------------------
  |  Branch (276:5): [True: 0, False: 2.84k]
  ------------------
  277|  2.84k|      return true;
  278|      3|    default:
  ------------------
  |  Branch (278:5): [True: 3, False: 2.84k]
  ------------------
  279|      3|      return false;
  280|  2.84k|  }
  281|  2.84k|}
_Z30spvOpcodeReturnsLogicalPointerN3spv2OpE:
  303|  50.7k|int32_t spvOpcodeReturnsLogicalPointer(const spv::Op opcode) {
  304|  50.7k|  switch (opcode) {
  305|  34.7k|    case spv::Op::OpVariable:
  ------------------
  |  Branch (305:5): [True: 34.7k, False: 15.9k]
  ------------------
  306|  49.9k|    case spv::Op::OpAccessChain:
  ------------------
  |  Branch (306:5): [True: 15.2k, False: 35.4k]
  ------------------
  307|  50.1k|    case spv::Op::OpInBoundsAccessChain:
  ------------------
  |  Branch (307:5): [True: 186, False: 50.5k]
  ------------------
  308|  50.7k|    case spv::Op::OpFunctionParameter:
  ------------------
  |  Branch (308:5): [True: 530, False: 50.1k]
  ------------------
  309|  50.7k|    case spv::Op::OpImageTexelPointer:
  ------------------
  |  Branch (309:5): [True: 0, False: 50.7k]
  ------------------
  310|  50.7k|    case spv::Op::OpCopyObject:
  ------------------
  |  Branch (310:5): [True: 6, False: 50.7k]
  ------------------
  311|  50.7k|      return true;
  312|      5|    default:
  ------------------
  |  Branch (312:5): [True: 5, False: 50.7k]
  ------------------
  313|      5|      return false;
  314|  50.7k|  }
  315|  50.7k|}
_Z22spvOpcodeGeneratesTypeN3spv2OpE:
  317|  5.11M|int32_t spvOpcodeGeneratesType(spv::Op op) {
  318|  5.11M|  switch (op) {
  319|  91.3k|    case spv::Op::OpTypeVoid:
  ------------------
  |  Branch (319:5): [True: 91.3k, False: 5.02M]
  ------------------
  320|   118k|    case spv::Op::OpTypeBool:
  ------------------
  |  Branch (320:5): [True: 27.2k, False: 5.08M]
  ------------------
  321|   209k|    case spv::Op::OpTypeInt:
  ------------------
  |  Branch (321:5): [True: 90.7k, False: 5.02M]
  ------------------
  322|   258k|    case spv::Op::OpTypeFloat:
  ------------------
  |  Branch (322:5): [True: 49.2k, False: 5.06M]
  ------------------
  323|   306k|    case spv::Op::OpTypeVector:
  ------------------
  |  Branch (323:5): [True: 48.4k, False: 5.06M]
  ------------------
  324|   320k|    case spv::Op::OpTypeMatrix:
  ------------------
  |  Branch (324:5): [True: 13.4k, False: 5.09M]
  ------------------
  325|   323k|    case spv::Op::OpTypeImage:
  ------------------
  |  Branch (325:5): [True: 3.43k, False: 5.10M]
  ------------------
  326|   327k|    case spv::Op::OpTypeSampler:
  ------------------
  |  Branch (326:5): [True: 3.28k, False: 5.10M]
  ------------------
  327|   328k|    case spv::Op::OpTypeSampledImage:
  ------------------
  |  Branch (327:5): [True: 1.52k, False: 5.11M]
  ------------------
  328|   347k|    case spv::Op::OpTypeArray:
  ------------------
  |  Branch (328:5): [True: 18.5k, False: 5.09M]
  ------------------
  329|   349k|    case spv::Op::OpTypeRuntimeArray:
  ------------------
  |  Branch (329:5): [True: 1.90k, False: 5.10M]
  ------------------
  330|   420k|    case spv::Op::OpTypeStruct:
  ------------------
  |  Branch (330:5): [True: 70.9k, False: 5.04M]
  ------------------
  331|   420k|    case spv::Op::OpTypeOpaque:
  ------------------
  |  Branch (331:5): [True: 604, False: 5.11M]
  ------------------
  332|   542k|    case spv::Op::OpTypePointer:
  ------------------
  |  Branch (332:5): [True: 122k, False: 4.98M]
  ------------------
  333|   597k|    case spv::Op::OpTypeFunction:
  ------------------
  |  Branch (333:5): [True: 54.6k, False: 5.05M]
  ------------------
  334|   598k|    case spv::Op::OpTypeEvent:
  ------------------
  |  Branch (334:5): [True: 610, False: 5.11M]
  ------------------
  335|   598k|    case spv::Op::OpTypeDeviceEvent:
  ------------------
  |  Branch (335:5): [True: 679, False: 5.11M]
  ------------------
  336|   599k|    case spv::Op::OpTypeReserveId:
  ------------------
  |  Branch (336:5): [True: 446, False: 5.11M]
  ------------------
  337|   599k|    case spv::Op::OpTypeQueue:
  ------------------
  |  Branch (337:5): [True: 465, False: 5.11M]
  ------------------
  338|   599k|    case spv::Op::OpTypePipe:
  ------------------
  |  Branch (338:5): [True: 139, False: 5.11M]
  ------------------
  339|   600k|    case spv::Op::OpTypePipeStorage:
  ------------------
  |  Branch (339:5): [True: 248, False: 5.11M]
  ------------------
  340|   600k|    case spv::Op::OpTypeNamedBarrier:
  ------------------
  |  Branch (340:5): [True: 307, False: 5.11M]
  ------------------
  341|   600k|    case spv::Op::OpTypeAccelerationStructureNV:
  ------------------
  |  Branch (341:5): [True: 150, False: 5.11M]
  ------------------
  342|   600k|    case spv::Op::OpTypeCooperativeMatrixNV:
  ------------------
  |  Branch (342:5): [True: 20, False: 5.11M]
  ------------------
  343|       |    // case spv::Op::OpTypeAccelerationStructureKHR: covered by
  344|       |    // spv::Op::OpTypeAccelerationStructureNV
  345|   600k|    case spv::Op::OpTypeRayQueryKHR:
  ------------------
  |  Branch (345:5): [True: 138, False: 5.11M]
  ------------------
  346|   600k|    case spv::Op::OpTypeHitObjectNV:
  ------------------
  |  Branch (346:5): [True: 41, False: 5.11M]
  ------------------
  347|   600k|      return true;
  348|  4.51M|    default:
  ------------------
  |  Branch (348:5): [True: 4.51M, False: 600k]
  ------------------
  349|       |      // In particular, OpTypeForwardPointer does not generate a type,
  350|       |      // but declares a storage class for a pointer type generated
  351|       |      // by a different instruction.
  352|  4.51M|      break;
  353|  5.11M|  }
  354|  4.51M|  return 0;
  355|  5.11M|}
_Z21spvOpcodeIsDecorationN3spv2OpE:
  357|  40.4k|bool spvOpcodeIsDecoration(const spv::Op opcode) {
  358|  40.4k|  switch (opcode) {
  359|  3.70k|    case spv::Op::OpDecorate:
  ------------------
  |  Branch (359:5): [True: 3.70k, False: 36.7k]
  ------------------
  360|  3.70k|    case spv::Op::OpDecorateId:
  ------------------
  |  Branch (360:5): [True: 2, False: 40.4k]
  ------------------
  361|  3.71k|    case spv::Op::OpMemberDecorate:
  ------------------
  |  Branch (361:5): [True: 14, False: 40.4k]
  ------------------
  362|  5.95k|    case spv::Op::OpGroupDecorate:
  ------------------
  |  Branch (362:5): [True: 2.23k, False: 38.1k]
  ------------------
  363|  6.48k|    case spv::Op::OpGroupMemberDecorate:
  ------------------
  |  Branch (363:5): [True: 526, False: 39.9k]
  ------------------
  364|  6.48k|    case spv::Op::OpDecorateStringGOOGLE:
  ------------------
  |  Branch (364:5): [True: 3, False: 40.4k]
  ------------------
  365|  6.48k|    case spv::Op::OpMemberDecorateStringGOOGLE:
  ------------------
  |  Branch (365:5): [True: 1, False: 40.4k]
  ------------------
  366|  6.48k|      return true;
  367|  33.9k|    default:
  ------------------
  |  Branch (367:5): [True: 33.9k, False: 6.48k]
  ------------------
  368|  33.9k|      break;
  369|  40.4k|  }
  370|  33.9k|  return false;
  371|  40.4k|}
_Z17spvOpcodeIsBranchN3spv2OpE:
  402|   246k|bool spvOpcodeIsBranch(spv::Op opcode) {
  403|   246k|  switch (opcode) {
  404|  30.1k|    case spv::Op::OpBranch:
  ------------------
  |  Branch (404:5): [True: 30.1k, False: 216k]
  ------------------
  405|  42.4k|    case spv::Op::OpBranchConditional:
  ------------------
  |  Branch (405:5): [True: 12.3k, False: 234k]
  ------------------
  406|  45.8k|    case spv::Op::OpSwitch:
  ------------------
  |  Branch (406:5): [True: 3.37k, False: 243k]
  ------------------
  407|  45.8k|      return true;
  408|   200k|    default:
  ------------------
  |  Branch (408:5): [True: 200k, False: 45.8k]
  ------------------
  409|   200k|      return false;
  410|   246k|  }
  411|   246k|}
_Z17spvOpcodeIsReturnN3spv2OpE:
  446|   177k|bool spvOpcodeIsReturn(spv::Op opcode) {
  447|   177k|  switch (opcode) {
  448|  2.31k|    case spv::Op::OpReturn:
  ------------------
  |  Branch (448:5): [True: 2.31k, False: 174k]
  ------------------
  449|  2.92k|    case spv::Op::OpReturnValue:
  ------------------
  |  Branch (449:5): [True: 610, False: 176k]
  ------------------
  450|  2.92k|      return true;
  451|   174k|    default:
  ------------------
  |  Branch (451:5): [True: 174k, False: 2.92k]
  ------------------
  452|   174k|      return false;
  453|   177k|  }
  454|   177k|}
_Z16spvOpcodeIsAbortN3spv2OpE:
  456|   174k|bool spvOpcodeIsAbort(spv::Op opcode) {
  457|   174k|  switch (opcode) {
  458|  1.60k|    case spv::Op::OpKill:
  ------------------
  |  Branch (458:5): [True: 1.60k, False: 172k]
  ------------------
  459|  7.03k|    case spv::Op::OpUnreachable:
  ------------------
  |  Branch (459:5): [True: 5.42k, False: 168k]
  ------------------
  460|  7.03k|    case spv::Op::OpTerminateInvocation:
  ------------------
  |  Branch (460:5): [True: 0, False: 174k]
  ------------------
  461|  7.03k|    case spv::Op::OpTerminateRayKHR:
  ------------------
  |  Branch (461:5): [True: 0, False: 174k]
  ------------------
  462|  7.03k|    case spv::Op::OpIgnoreIntersectionKHR:
  ------------------
  |  Branch (462:5): [True: 0, False: 174k]
  ------------------
  463|  7.03k|    case spv::Op::OpEmitMeshTasksEXT:
  ------------------
  |  Branch (463:5): [True: 0, False: 174k]
  ------------------
  464|  7.03k|      return true;
  465|   167k|    default:
  ------------------
  |  Branch (465:5): [True: 167k, False: 7.03k]
  ------------------
  466|   167k|      return false;
  467|   174k|  }
  468|   174k|}
_Z24spvOpcodeIsReturnOrAbortN3spv2OpE:
  470|   177k|bool spvOpcodeIsReturnOrAbort(spv::Op opcode) {
  471|   177k|  return spvOpcodeIsReturn(opcode) || spvOpcodeIsAbort(opcode);
  ------------------
  |  Branch (471:10): [True: 2.92k, False: 174k]
  |  Branch (471:39): [True: 7.03k, False: 167k]
  ------------------
  472|   177k|}
_Z26spvOpcodeIsBlockTerminatorN3spv2OpE:
  474|   217k|bool spvOpcodeIsBlockTerminator(spv::Op opcode) {
  475|   217k|  return spvOpcodeIsBranch(opcode) || spvOpcodeIsReturnOrAbort(opcode);
  ------------------
  |  Branch (475:10): [True: 40.1k, False: 177k]
  |  Branch (475:39): [True: 9.95k, False: 167k]
  ------------------
  476|   217k|}
_Z35spvOpcodeIsNonUniformGroupOperationN3spv2OpE:
  498|   285k|bool spvOpcodeIsNonUniformGroupOperation(spv::Op opcode) {
  499|   285k|  switch (opcode) {
  500|      0|    case spv::Op::OpGroupNonUniformElect:
  ------------------
  |  Branch (500:5): [True: 0, False: 285k]
  ------------------
  501|      0|    case spv::Op::OpGroupNonUniformAll:
  ------------------
  |  Branch (501:5): [True: 0, False: 285k]
  ------------------
  502|      0|    case spv::Op::OpGroupNonUniformAny:
  ------------------
  |  Branch (502:5): [True: 0, False: 285k]
  ------------------
  503|      0|    case spv::Op::OpGroupNonUniformAllEqual:
  ------------------
  |  Branch (503:5): [True: 0, False: 285k]
  ------------------
  504|      0|    case spv::Op::OpGroupNonUniformBroadcast:
  ------------------
  |  Branch (504:5): [True: 0, False: 285k]
  ------------------
  505|      0|    case spv::Op::OpGroupNonUniformBroadcastFirst:
  ------------------
  |  Branch (505:5): [True: 0, False: 285k]
  ------------------
  506|      0|    case spv::Op::OpGroupNonUniformBallot:
  ------------------
  |  Branch (506:5): [True: 0, False: 285k]
  ------------------
  507|      0|    case spv::Op::OpGroupNonUniformInverseBallot:
  ------------------
  |  Branch (507:5): [True: 0, False: 285k]
  ------------------
  508|      0|    case spv::Op::OpGroupNonUniformBallotBitExtract:
  ------------------
  |  Branch (508:5): [True: 0, False: 285k]
  ------------------
  509|      0|    case spv::Op::OpGroupNonUniformBallotBitCount:
  ------------------
  |  Branch (509:5): [True: 0, False: 285k]
  ------------------
  510|      0|    case spv::Op::OpGroupNonUniformBallotFindLSB:
  ------------------
  |  Branch (510:5): [True: 0, False: 285k]
  ------------------
  511|      0|    case spv::Op::OpGroupNonUniformBallotFindMSB:
  ------------------
  |  Branch (511:5): [True: 0, False: 285k]
  ------------------
  512|      0|    case spv::Op::OpGroupNonUniformShuffle:
  ------------------
  |  Branch (512:5): [True: 0, False: 285k]
  ------------------
  513|      0|    case spv::Op::OpGroupNonUniformShuffleXor:
  ------------------
  |  Branch (513:5): [True: 0, False: 285k]
  ------------------
  514|      0|    case spv::Op::OpGroupNonUniformShuffleUp:
  ------------------
  |  Branch (514:5): [True: 0, False: 285k]
  ------------------
  515|      0|    case spv::Op::OpGroupNonUniformShuffleDown:
  ------------------
  |  Branch (515:5): [True: 0, False: 285k]
  ------------------
  516|      0|    case spv::Op::OpGroupNonUniformIAdd:
  ------------------
  |  Branch (516:5): [True: 0, False: 285k]
  ------------------
  517|      0|    case spv::Op::OpGroupNonUniformFAdd:
  ------------------
  |  Branch (517:5): [True: 0, False: 285k]
  ------------------
  518|      0|    case spv::Op::OpGroupNonUniformIMul:
  ------------------
  |  Branch (518:5): [True: 0, False: 285k]
  ------------------
  519|      0|    case spv::Op::OpGroupNonUniformFMul:
  ------------------
  |  Branch (519:5): [True: 0, False: 285k]
  ------------------
  520|      0|    case spv::Op::OpGroupNonUniformSMin:
  ------------------
  |  Branch (520:5): [True: 0, False: 285k]
  ------------------
  521|      0|    case spv::Op::OpGroupNonUniformUMin:
  ------------------
  |  Branch (521:5): [True: 0, False: 285k]
  ------------------
  522|      0|    case spv::Op::OpGroupNonUniformFMin:
  ------------------
  |  Branch (522:5): [True: 0, False: 285k]
  ------------------
  523|      0|    case spv::Op::OpGroupNonUniformSMax:
  ------------------
  |  Branch (523:5): [True: 0, False: 285k]
  ------------------
  524|      0|    case spv::Op::OpGroupNonUniformUMax:
  ------------------
  |  Branch (524:5): [True: 0, False: 285k]
  ------------------
  525|      0|    case spv::Op::OpGroupNonUniformFMax:
  ------------------
  |  Branch (525:5): [True: 0, False: 285k]
  ------------------
  526|      0|    case spv::Op::OpGroupNonUniformBitwiseAnd:
  ------------------
  |  Branch (526:5): [True: 0, False: 285k]
  ------------------
  527|      0|    case spv::Op::OpGroupNonUniformBitwiseOr:
  ------------------
  |  Branch (527:5): [True: 0, False: 285k]
  ------------------
  528|      0|    case spv::Op::OpGroupNonUniformBitwiseXor:
  ------------------
  |  Branch (528:5): [True: 0, False: 285k]
  ------------------
  529|      0|    case spv::Op::OpGroupNonUniformLogicalAnd:
  ------------------
  |  Branch (529:5): [True: 0, False: 285k]
  ------------------
  530|      0|    case spv::Op::OpGroupNonUniformLogicalOr:
  ------------------
  |  Branch (530:5): [True: 0, False: 285k]
  ------------------
  531|      0|    case spv::Op::OpGroupNonUniformLogicalXor:
  ------------------
  |  Branch (531:5): [True: 0, False: 285k]
  ------------------
  532|      0|    case spv::Op::OpGroupNonUniformQuadBroadcast:
  ------------------
  |  Branch (532:5): [True: 0, False: 285k]
  ------------------
  533|      0|    case spv::Op::OpGroupNonUniformQuadSwap:
  ------------------
  |  Branch (533:5): [True: 0, False: 285k]
  ------------------
  534|      0|    case spv::Op::OpGroupNonUniformRotateKHR:
  ------------------
  |  Branch (534:5): [True: 0, False: 285k]
  ------------------
  535|      0|      return true;
  536|   285k|    default:
  ------------------
  |  Branch (536:5): [True: 285k, False: 0]
  ------------------
  537|   285k|      return false;
  538|   285k|  }
  539|   285k|}
_Z16spvOpcodeIsDebugN3spv2OpE:
  628|  40.9k|bool spvOpcodeIsDebug(spv::Op opcode) {
  629|  40.9k|  switch (opcode) {
  630|     13|    case spv::Op::OpName:
  ------------------
  |  Branch (630:5): [True: 13, False: 40.8k]
  ------------------
  631|     22|    case spv::Op::OpMemberName:
  ------------------
  |  Branch (631:5): [True: 9, False: 40.8k]
  ------------------
  632|     23|    case spv::Op::OpSource:
  ------------------
  |  Branch (632:5): [True: 1, False: 40.9k]
  ------------------
  633|     23|    case spv::Op::OpSourceContinued:
  ------------------
  |  Branch (633:5): [True: 0, False: 40.9k]
  ------------------
  634|     23|    case spv::Op::OpSourceExtension:
  ------------------
  |  Branch (634:5): [True: 0, False: 40.9k]
  ------------------
  635|     23|    case spv::Op::OpString:
  ------------------
  |  Branch (635:5): [True: 0, False: 40.9k]
  ------------------
  636|    447|    case spv::Op::OpLine:
  ------------------
  |  Branch (636:5): [True: 424, False: 40.4k]
  ------------------
  637|    447|    case spv::Op::OpNoLine:
  ------------------
  |  Branch (637:5): [True: 0, False: 40.9k]
  ------------------
  638|    447|    case spv::Op::OpModuleProcessed:
  ------------------
  |  Branch (638:5): [True: 0, False: 40.9k]
  ------------------
  639|    447|      return true;
  640|  40.4k|    default:
  ------------------
  |  Branch (640:5): [True: 40.4k, False: 447]
  ------------------
  641|  40.4k|      return false;
  642|  40.9k|  }
  643|  40.9k|}
opcode.cpp:_ZZ25spvOpcodeTableValueLookup14spv_target_envPK18spv_opcode_table_tN3spv2OpEPPK17spv_opcode_desc_tENK3$_1clERS6_SA_:
  139|  26.2M|  auto comp = [](const spv_opcode_desc_t& lhs, const spv_opcode_desc_t& rhs) {
  140|  26.2M|    return lhs.opcode < rhs.opcode;
  141|  26.2M|  };
opcode.cpp:_ZZ15spvOpcodeStringENK3$_2clERK17spv_opcode_desc_tS2_:
  195|   200k|  auto comp = [](const spv_opcode_desc_t& lhs, const spv_opcode_desc_t& rhs) {
  196|   200k|    return lhs.opcode < rhs.opcode;
  197|   200k|  };

_Z18spvOperandTableGetPPK19spv_operand_table_t14spv_target_env:
   44|  12.6k|                                spv_target_env) {
   45|  12.6k|  if (!pOperandTable) return SPV_ERROR_INVALID_POINTER;
  ------------------
  |  Branch (45:7): [True: 0, False: 12.6k]
  ------------------
   46|       |
   47|  12.6k|  *pOperandTable = &kOperandTable;
   48|  12.6k|  return SPV_SUCCESS;
   49|  12.6k|}
_Z26spvOperandTableValueLookup14spv_target_envPK19spv_operand_table_t18spv_operand_type_tjPPK18spv_operand_desc_t:
   96|  1.06M|                                        spv_operand_desc* pEntry) {
   97|  1.06M|  if (!table) return SPV_ERROR_INVALID_TABLE;
  ------------------
  |  Branch (97:7): [True: 0, False: 1.06M]
  ------------------
   98|  1.06M|  if (!pEntry) return SPV_ERROR_INVALID_POINTER;
  ------------------
  |  Branch (98:7): [True: 0, False: 1.06M]
  ------------------
   99|       |
  100|  1.06M|  spv_operand_desc_t needle = {"", value, 0, nullptr, 0, nullptr, {}, ~0u, ~0u};
  101|       |
  102|  1.06M|  auto comp = [](const spv_operand_desc_t& lhs, const spv_operand_desc_t& rhs) {
  103|  1.06M|    return lhs.value < rhs.value;
  104|  1.06M|  };
  105|       |
  106|  27.8M|  for (uint64_t typeIndex = 0; typeIndex < table->count; ++typeIndex) {
  ------------------
  |  Branch (106:32): [True: 27.7M, False: 81.0k]
  ------------------
  107|  27.7M|    const auto& group = table->types[typeIndex];
  108|  27.7M|    if (type != group.type) continue;
  ------------------
  |  Branch (108:9): [True: 26.7M, False: 988k]
  ------------------
  109|       |
  110|   988k|    const auto beg = group.entries;
  111|   988k|    const auto end = group.entries + group.count;
  112|       |
  113|       |    // We need to loop here because there can exist multiple symbols for the
  114|       |    // same operand value, and they can be introduced in different target
  115|       |    // environments, which means they can have different minimal version
  116|       |    // requirements. For example, SubgroupEqMaskKHR can exist in any SPIR-V
  117|       |    // version as long as the SPV_KHR_shader_ballot extension is there; but
  118|       |    // starting from SPIR-V 1.3, SubgroupEqMask, which has the same numeric
  119|       |    // value as SubgroupEqMaskKHR, is available in core SPIR-V without extension
  120|       |    // requirements.
  121|       |    // Assumes the underlying table is already sorted ascendingly according to
  122|       |    // opcode value.
  123|   988k|    const auto version = spvVersionForTargetEnv(env);
  124|   988k|    for (auto it = std::lower_bound(beg, end, needle, comp);
  125|   988k|         it != end && it->value == value; ++it) {
  ------------------
  |  Branch (125:10): [True: 988k, False: 204]
  |  Branch (125:23): [True: 988k, False: 375]
  ------------------
  126|       |      // We consider the current operand as available as long as
  127|       |      // 1. The target environment satisfies the minimal requirement of the
  128|       |      //    operand; or
  129|       |      // 2. There is at least one extension enabling this operand; or
  130|       |      // 3. There is at least one capability enabling this operand.
  131|       |      //
  132|       |      // Note that the second rule assumes the extension enabling this operand
  133|       |      // is indeed requested in the SPIR-V code; checking that should be
  134|       |      // validator's work.
  135|   988k|      if ((version >= it->minVersion && version <= it->lastVersion) ||
  ------------------
  |  Branch (135:12): [True: 979k, False: 8.35k]
  |  Branch (135:41): [True: 979k, False: 0]
  ------------------
  136|   988k|          it->numExtensions > 0u || it->numCapabilities > 0u) {
  ------------------
  |  Branch (136:11): [True: 7.13k, False: 1.22k]
  |  Branch (136:37): [True: 913, False: 309]
  ------------------
  137|   987k|        *pEntry = it;
  138|   987k|        return SPV_SUCCESS;
  139|   987k|      }
  140|   988k|    }
  141|   988k|  }
  142|       |
  143|  81.0k|  return SPV_ERROR_INVALID_LOOKUP;
  144|  1.06M|}
_Z17spvOperandTypeStr18spv_operand_type_t:
  146|    982|const char* spvOperandTypeStr(spv_operand_type_t type) {
  147|    982|  switch (type) {
  148|    176|    case SPV_OPERAND_TYPE_ID:
  ------------------
  |  Branch (148:5): [True: 176, False: 806]
  ------------------
  149|    234|    case SPV_OPERAND_TYPE_OPTIONAL_ID:
  ------------------
  |  Branch (149:5): [True: 58, False: 924]
  ------------------
  150|    234|      return "ID";
  151|     36|    case SPV_OPERAND_TYPE_TYPE_ID:
  ------------------
  |  Branch (151:5): [True: 36, False: 946]
  ------------------
  152|     36|      return "type ID";
  153|     60|    case SPV_OPERAND_TYPE_RESULT_ID:
  ------------------
  |  Branch (153:5): [True: 60, False: 922]
  ------------------
  154|     60|      return "result ID";
  155|     38|    case SPV_OPERAND_TYPE_LITERAL_INTEGER:
  ------------------
  |  Branch (155:5): [True: 38, False: 944]
  ------------------
  156|     53|    case SPV_OPERAND_TYPE_OPTIONAL_LITERAL_INTEGER:
  ------------------
  |  Branch (156:5): [True: 15, False: 967]
  ------------------
  157|     53|    case SPV_OPERAND_TYPE_OPTIONAL_LITERAL_NUMBER:
  ------------------
  |  Branch (157:5): [True: 0, False: 982]
  ------------------
  158|     53|      return "literal number";
  159|     47|    case SPV_OPERAND_TYPE_OPTIONAL_TYPED_LITERAL_INTEGER:
  ------------------
  |  Branch (159:5): [True: 47, False: 935]
  ------------------
  160|     47|      return "possibly multi-word literal integer";
  161|      4|    case SPV_OPERAND_TYPE_TYPED_LITERAL_NUMBER:
  ------------------
  |  Branch (161:5): [True: 4, False: 978]
  ------------------
  162|      4|      return "possibly multi-word literal number";
  163|      6|    case SPV_OPERAND_TYPE_EXTENSION_INSTRUCTION_NUMBER:
  ------------------
  |  Branch (163:5): [True: 6, False: 976]
  ------------------
  164|      6|      return "extension instruction number";
  165|     82|    case SPV_OPERAND_TYPE_SPEC_CONSTANT_OP_NUMBER:
  ------------------
  |  Branch (165:5): [True: 82, False: 900]
  ------------------
  166|     82|      return "OpSpecConstantOp opcode";
  167|     72|    case SPV_OPERAND_TYPE_LITERAL_STRING:
  ------------------
  |  Branch (167:5): [True: 72, False: 910]
  ------------------
  168|     79|    case SPV_OPERAND_TYPE_OPTIONAL_LITERAL_STRING:
  ------------------
  |  Branch (168:5): [True: 7, False: 975]
  ------------------
  169|     79|      return "literal string";
  170|     14|    case SPV_OPERAND_TYPE_SOURCE_LANGUAGE:
  ------------------
  |  Branch (170:5): [True: 14, False: 968]
  ------------------
  171|     14|      return "source language";
  172|      6|    case SPV_OPERAND_TYPE_EXECUTION_MODEL:
  ------------------
  |  Branch (172:5): [True: 6, False: 976]
  ------------------
  173|      6|      return "execution model";
  174|     22|    case SPV_OPERAND_TYPE_ADDRESSING_MODEL:
  ------------------
  |  Branch (174:5): [True: 22, False: 960]
  ------------------
  175|     22|      return "addressing model";
  176|      2|    case SPV_OPERAND_TYPE_MEMORY_MODEL:
  ------------------
  |  Branch (176:5): [True: 2, False: 980]
  ------------------
  177|      2|      return "memory model";
  178|      5|    case SPV_OPERAND_TYPE_EXECUTION_MODE:
  ------------------
  |  Branch (178:5): [True: 5, False: 977]
  ------------------
  179|      5|      return "execution mode";
  180|     13|    case SPV_OPERAND_TYPE_STORAGE_CLASS:
  ------------------
  |  Branch (180:5): [True: 13, False: 969]
  ------------------
  181|     13|      return "storage class";
  182|      7|    case SPV_OPERAND_TYPE_DIMENSIONALITY:
  ------------------
  |  Branch (182:5): [True: 7, False: 975]
  ------------------
  183|      7|      return "dimensionality";
  184|      4|    case SPV_OPERAND_TYPE_SAMPLER_ADDRESSING_MODE:
  ------------------
  |  Branch (184:5): [True: 4, False: 978]
  ------------------
  185|      4|      return "sampler addressing mode";
  186|      4|    case SPV_OPERAND_TYPE_SAMPLER_FILTER_MODE:
  ------------------
  |  Branch (186:5): [True: 4, False: 978]
  ------------------
  187|      4|      return "sampler filter mode";
  188|      4|    case SPV_OPERAND_TYPE_SAMPLER_IMAGE_FORMAT:
  ------------------
  |  Branch (188:5): [True: 4, False: 978]
  ------------------
  189|      4|      return "image format";
  190|      5|    case SPV_OPERAND_TYPE_FP_FAST_MATH_MODE:
  ------------------
  |  Branch (190:5): [True: 5, False: 977]
  ------------------
  191|      5|      return "floating-point fast math mode";
  192|      0|    case SPV_OPERAND_TYPE_FP_ROUNDING_MODE:
  ------------------
  |  Branch (192:5): [True: 0, False: 982]
  ------------------
  193|      0|      return "floating-point rounding mode";
  194|      4|    case SPV_OPERAND_TYPE_LINKAGE_TYPE:
  ------------------
  |  Branch (194:5): [True: 4, False: 978]
  ------------------
  195|      4|      return "linkage type";
  196|     12|    case SPV_OPERAND_TYPE_ACCESS_QUALIFIER:
  ------------------
  |  Branch (196:5): [True: 12, False: 970]
  ------------------
  197|     15|    case SPV_OPERAND_TYPE_OPTIONAL_ACCESS_QUALIFIER:
  ------------------
  |  Branch (197:5): [True: 3, False: 979]
  ------------------
  198|     15|      return "access qualifier";
  199|      4|    case SPV_OPERAND_TYPE_FUNCTION_PARAMETER_ATTRIBUTE:
  ------------------
  |  Branch (199:5): [True: 4, False: 978]
  ------------------
  200|      4|      return "function parameter attribute";
  201|      9|    case SPV_OPERAND_TYPE_DECORATION:
  ------------------
  |  Branch (201:5): [True: 9, False: 973]
  ------------------
  202|      9|      return "decoration";
  203|     12|    case SPV_OPERAND_TYPE_BUILT_IN:
  ------------------
  |  Branch (203:5): [True: 12, False: 970]
  ------------------
  204|     12|      return "built-in";
  205|     46|    case SPV_OPERAND_TYPE_SELECTION_CONTROL:
  ------------------
  |  Branch (205:5): [True: 46, False: 936]
  ------------------
  206|     46|      return "selection control";
  207|     24|    case SPV_OPERAND_TYPE_LOOP_CONTROL:
  ------------------
  |  Branch (207:5): [True: 24, False: 958]
  ------------------
  208|     24|      return "loop control";
  209|     12|    case SPV_OPERAND_TYPE_FUNCTION_CONTROL:
  ------------------
  |  Branch (209:5): [True: 12, False: 970]
  ------------------
  210|     12|      return "function control";
  211|     20|    case SPV_OPERAND_TYPE_MEMORY_SEMANTICS_ID:
  ------------------
  |  Branch (211:5): [True: 20, False: 962]
  ------------------
  212|     20|      return "memory semantics ID";
  213|     17|    case SPV_OPERAND_TYPE_MEMORY_ACCESS:
  ------------------
  |  Branch (213:5): [True: 17, False: 965]
  ------------------
  214|     25|    case SPV_OPERAND_TYPE_OPTIONAL_MEMORY_ACCESS:
  ------------------
  |  Branch (214:5): [True: 8, False: 974]
  ------------------
  215|     25|      return "memory access";
  216|      0|    case SPV_OPERAND_TYPE_FRAGMENT_SHADING_RATE:
  ------------------
  |  Branch (216:5): [True: 0, False: 982]
  ------------------
  217|      0|      return "shading rate";
  218|     46|    case SPV_OPERAND_TYPE_SCOPE_ID:
  ------------------
  |  Branch (218:5): [True: 46, False: 936]
  ------------------
  219|     46|      return "scope ID";
  220|     14|    case SPV_OPERAND_TYPE_GROUP_OPERATION:
  ------------------
  |  Branch (220:5): [True: 14, False: 968]
  ------------------
  221|     14|      return "group operation";
  222|      0|    case SPV_OPERAND_TYPE_KERNEL_ENQ_FLAGS:
  ------------------
  |  Branch (222:5): [True: 0, False: 982]
  ------------------
  223|      0|      return "kernel enqeue flags";
  224|      0|    case SPV_OPERAND_TYPE_KERNEL_PROFILING_INFO:
  ------------------
  |  Branch (224:5): [True: 0, False: 982]
  ------------------
  225|      0|      return "kernel profiling info";
  226|     49|    case SPV_OPERAND_TYPE_CAPABILITY:
  ------------------
  |  Branch (226:5): [True: 49, False: 933]
  ------------------
  227|     49|      return "capability";
  228|      0|    case SPV_OPERAND_TYPE_RAY_FLAGS:
  ------------------
  |  Branch (228:5): [True: 0, False: 982]
  ------------------
  229|      0|      return "ray flags";
  230|      0|    case SPV_OPERAND_TYPE_RAY_QUERY_INTERSECTION:
  ------------------
  |  Branch (230:5): [True: 0, False: 982]
  ------------------
  231|      0|      return "ray query intersection";
  232|      0|    case SPV_OPERAND_TYPE_RAY_QUERY_COMMITTED_INTERSECTION_TYPE:
  ------------------
  |  Branch (232:5): [True: 0, False: 982]
  ------------------
  233|      0|      return "ray query committed intersection type";
  234|      0|    case SPV_OPERAND_TYPE_RAY_QUERY_CANDIDATE_INTERSECTION_TYPE:
  ------------------
  |  Branch (234:5): [True: 0, False: 982]
  ------------------
  235|      0|      return "ray query candidate intersection type";
  236|      0|    case SPV_OPERAND_TYPE_PACKED_VECTOR_FORMAT:
  ------------------
  |  Branch (236:5): [True: 0, False: 982]
  ------------------
  237|      0|    case SPV_OPERAND_TYPE_OPTIONAL_PACKED_VECTOR_FORMAT:
  ------------------
  |  Branch (237:5): [True: 0, False: 982]
  ------------------
  238|      0|      return "packed vector format";
  239|      8|    case SPV_OPERAND_TYPE_IMAGE:
  ------------------
  |  Branch (239:5): [True: 8, False: 974]
  ------------------
  240|      8|    case SPV_OPERAND_TYPE_OPTIONAL_IMAGE:
  ------------------
  |  Branch (240:5): [True: 0, False: 982]
  ------------------
  241|      8|      return "image";
  242|      0|    case SPV_OPERAND_TYPE_OPTIONAL_CIV:
  ------------------
  |  Branch (242:5): [True: 0, False: 982]
  ------------------
  243|      0|      return "context-insensitive value";
  244|      0|    case SPV_OPERAND_TYPE_DEBUG_INFO_FLAGS:
  ------------------
  |  Branch (244:5): [True: 0, False: 982]
  ------------------
  245|      0|      return "debug info flags";
  246|      0|    case SPV_OPERAND_TYPE_DEBUG_BASE_TYPE_ATTRIBUTE_ENCODING:
  ------------------
  |  Branch (246:5): [True: 0, False: 982]
  ------------------
  247|      0|      return "debug base type encoding";
  248|      2|    case SPV_OPERAND_TYPE_DEBUG_COMPOSITE_TYPE:
  ------------------
  |  Branch (248:5): [True: 2, False: 980]
  ------------------
  249|      2|      return "debug composite type";
  250|      2|    case SPV_OPERAND_TYPE_DEBUG_TYPE_QUALIFIER:
  ------------------
  |  Branch (250:5): [True: 2, False: 980]
  ------------------
  251|      2|      return "debug type qualifier";
  252|      0|    case SPV_OPERAND_TYPE_DEBUG_OPERATION:
  ------------------
  |  Branch (252:5): [True: 0, False: 982]
  ------------------
  253|      0|      return "debug operation";
  254|      3|    case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_INFO_FLAGS:
  ------------------
  |  Branch (254:5): [True: 3, False: 979]
  ------------------
  255|      3|      return "OpenCL.DebugInfo.100 debug info flags";
  256|      0|    case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_BASE_TYPE_ATTRIBUTE_ENCODING:
  ------------------
  |  Branch (256:5): [True: 0, False: 982]
  ------------------
  257|      0|      return "OpenCL.DebugInfo.100 debug base type encoding";
  258|      0|    case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_COMPOSITE_TYPE:
  ------------------
  |  Branch (258:5): [True: 0, False: 982]
  ------------------
  259|      0|      return "OpenCL.DebugInfo.100 debug composite type";
  260|      0|    case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_TYPE_QUALIFIER:
  ------------------
  |  Branch (260:5): [True: 0, False: 982]
  ------------------
  261|      0|      return "OpenCL.DebugInfo.100 debug type qualifier";
  262|      0|    case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_OPERATION:
  ------------------
  |  Branch (262:5): [True: 0, False: 982]
  ------------------
  263|      0|      return "OpenCL.DebugInfo.100 debug operation";
  264|      0|    case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_IMPORTED_ENTITY:
  ------------------
  |  Branch (264:5): [True: 0, False: 982]
  ------------------
  265|      0|      return "OpenCL.DebugInfo.100 debug imported entity";
  266|       |
  267|       |    // The next values are for values returned from an instruction, not actually
  268|       |    // an operand.  So the specific strings don't matter.  But let's add them
  269|       |    // for completeness and ease of testing.
  270|      0|    case SPV_OPERAND_TYPE_IMAGE_CHANNEL_ORDER:
  ------------------
  |  Branch (270:5): [True: 0, False: 982]
  ------------------
  271|      0|      return "image channel order";
  272|      0|    case SPV_OPERAND_TYPE_IMAGE_CHANNEL_DATA_TYPE:
  ------------------
  |  Branch (272:5): [True: 0, False: 982]
  ------------------
  273|      0|      return "image channel data type";
  274|       |
  275|      0|    case SPV_OPERAND_TYPE_FPDENORM_MODE:
  ------------------
  |  Branch (275:5): [True: 0, False: 982]
  ------------------
  276|      0|      return "FP denorm mode";
  277|      0|    case SPV_OPERAND_TYPE_FPOPERATION_MODE:
  ------------------
  |  Branch (277:5): [True: 0, False: 982]
  ------------------
  278|      0|      return "FP operation mode";
  279|      0|    case SPV_OPERAND_TYPE_QUANTIZATION_MODES:
  ------------------
  |  Branch (279:5): [True: 0, False: 982]
  ------------------
  280|      0|      return "quantization mode";
  281|      0|    case SPV_OPERAND_TYPE_OVERFLOW_MODES:
  ------------------
  |  Branch (281:5): [True: 0, False: 982]
  ------------------
  282|      0|      return "overflow mode";
  283|       |
  284|      0|    case SPV_OPERAND_TYPE_NONE:
  ------------------
  |  Branch (284:5): [True: 0, False: 982]
  ------------------
  285|      0|      return "NONE";
  286|      0|    default:
  ------------------
  |  Branch (286:5): [True: 0, False: 982]
  ------------------
  287|      0|      break;
  288|    982|  }
  289|      0|  return "unknown";
  290|    982|}
_Z19spvPushOperandTypesPK18spv_operand_type_tPNSt3__16vectorIS_NS2_9allocatorIS_EEEE:
  293|   861k|                         spv_operand_pattern_t* pattern) {
  294|   861k|  const spv_operand_type_t* endTypes;
  295|  1.12M|  for (endTypes = types; *endTypes != SPV_OPERAND_TYPE_NONE; ++endTypes) {
  ------------------
  |  Branch (295:26): [True: 264k, False: 861k]
  ------------------
  296|   264k|  }
  297|       |
  298|  1.12M|  while (endTypes-- != types) {
  ------------------
  |  Branch (298:10): [True: 264k, False: 861k]
  ------------------
  299|   264k|    pattern->push_back(*endTypes);
  300|   264k|  }
  301|   861k|}
spvOperandIsConcrete:
  322|  7.71M|bool spvOperandIsConcrete(spv_operand_type_t type) {
  323|  7.71M|  if (spvIsIdType(type) || spvOperandIsConcreteMask(type)) {
  ------------------
  |  Branch (323:7): [True: 5.97M, False: 1.74M]
  |  Branch (323:28): [True: 148k, False: 1.59M]
  ------------------
  324|  6.12M|    return true;
  325|  6.12M|  }
  326|  1.59M|  switch (type) {
  327|   575k|    case SPV_OPERAND_TYPE_LITERAL_INTEGER:
  ------------------
  |  Branch (327:5): [True: 575k, False: 1.01M]
  ------------------
  328|   591k|    case SPV_OPERAND_TYPE_EXTENSION_INSTRUCTION_NUMBER:
  ------------------
  |  Branch (328:5): [True: 16.0k, False: 1.57M]
  ------------------
  329|   591k|    case SPV_OPERAND_TYPE_SPEC_CONSTANT_OP_NUMBER:
  ------------------
  |  Branch (329:5): [True: 156, False: 1.59M]
  ------------------
  330|   769k|    case SPV_OPERAND_TYPE_TYPED_LITERAL_NUMBER:
  ------------------
  |  Branch (330:5): [True: 177k, False: 1.41M]
  ------------------
  331|   910k|    case SPV_OPERAND_TYPE_LITERAL_STRING:
  ------------------
  |  Branch (331:5): [True: 141k, False: 1.45M]
  ------------------
  332|   913k|    case SPV_OPERAND_TYPE_SOURCE_LANGUAGE:
  ------------------
  |  Branch (332:5): [True: 2.93k, False: 1.58M]
  ------------------
  333|   928k|    case SPV_OPERAND_TYPE_EXECUTION_MODEL:
  ------------------
  |  Branch (333:5): [True: 14.1k, False: 1.57M]
  ------------------
  334|   955k|    case SPV_OPERAND_TYPE_ADDRESSING_MODEL:
  ------------------
  |  Branch (334:5): [True: 27.4k, False: 1.56M]
  ------------------
  335|   982k|    case SPV_OPERAND_TYPE_MEMORY_MODEL:
  ------------------
  |  Branch (335:5): [True: 27.4k, False: 1.56M]
  ------------------
  336|   999k|    case SPV_OPERAND_TYPE_EXECUTION_MODE:
  ------------------
  |  Branch (336:5): [True: 17.0k, False: 1.57M]
  ------------------
  337|  1.07M|    case SPV_OPERAND_TYPE_STORAGE_CLASS:
  ------------------
  |  Branch (337:5): [True: 72.2k, False: 1.52M]
  ------------------
  338|  1.07M|    case SPV_OPERAND_TYPE_DIMENSIONALITY:
  ------------------
  |  Branch (338:5): [True: 1.10k, False: 1.59M]
  ------------------
  339|  1.07M|    case SPV_OPERAND_TYPE_SAMPLER_ADDRESSING_MODE:
  ------------------
  |  Branch (339:5): [True: 25, False: 1.59M]
  ------------------
  340|  1.07M|    case SPV_OPERAND_TYPE_SAMPLER_FILTER_MODE:
  ------------------
  |  Branch (340:5): [True: 15, False: 1.59M]
  ------------------
  341|  1.07M|    case SPV_OPERAND_TYPE_SAMPLER_IMAGE_FORMAT:
  ------------------
  |  Branch (341:5): [True: 1.10k, False: 1.59M]
  ------------------
  342|  1.07M|    case SPV_OPERAND_TYPE_IMAGE_CHANNEL_ORDER:
  ------------------
  |  Branch (342:5): [True: 0, False: 1.59M]
  ------------------
  343|  1.07M|    case SPV_OPERAND_TYPE_IMAGE_CHANNEL_DATA_TYPE:
  ------------------
  |  Branch (343:5): [True: 0, False: 1.59M]
  ------------------
  344|  1.07M|    case SPV_OPERAND_TYPE_FP_ROUNDING_MODE:
  ------------------
  |  Branch (344:5): [True: 332, False: 1.59M]
  ------------------
  345|  1.07M|    case SPV_OPERAND_TYPE_LINKAGE_TYPE:
  ------------------
  |  Branch (345:5): [True: 50, False: 1.59M]
  ------------------
  346|  1.07M|    case SPV_OPERAND_TYPE_ACCESS_QUALIFIER:
  ------------------
  |  Branch (346:5): [True: 55, False: 1.59M]
  ------------------
  347|  1.07M|    case SPV_OPERAND_TYPE_FUNCTION_PARAMETER_ATTRIBUTE:
  ------------------
  |  Branch (347:5): [True: 42, False: 1.59M]
  ------------------
  348|  1.35M|    case SPV_OPERAND_TYPE_DECORATION:
  ------------------
  |  Branch (348:5): [True: 276k, False: 1.31M]
  ------------------
  349|  1.55M|    case SPV_OPERAND_TYPE_BUILT_IN:
  ------------------
  |  Branch (349:5): [True: 205k, False: 1.38M]
  ------------------
  350|  1.55M|    case SPV_OPERAND_TYPE_GROUP_OPERATION:
  ------------------
  |  Branch (350:5): [True: 25, False: 1.59M]
  ------------------
  351|  1.55M|    case SPV_OPERAND_TYPE_KERNEL_ENQ_FLAGS:
  ------------------
  |  Branch (351:5): [True: 0, False: 1.59M]
  ------------------
  352|  1.55M|    case SPV_OPERAND_TYPE_KERNEL_PROFILING_INFO:
  ------------------
  |  Branch (352:5): [True: 0, False: 1.59M]
  ------------------
  353|  1.59M|    case SPV_OPERAND_TYPE_CAPABILITY:
  ------------------
  |  Branch (353:5): [True: 35.8k, False: 1.55M]
  ------------------
  354|  1.59M|    case SPV_OPERAND_TYPE_RAY_FLAGS:
  ------------------
  |  Branch (354:5): [True: 0, False: 1.59M]
  ------------------
  355|  1.59M|    case SPV_OPERAND_TYPE_RAY_QUERY_INTERSECTION:
  ------------------
  |  Branch (355:5): [True: 0, False: 1.59M]
  ------------------
  356|  1.59M|    case SPV_OPERAND_TYPE_RAY_QUERY_COMMITTED_INTERSECTION_TYPE:
  ------------------
  |  Branch (356:5): [True: 0, False: 1.59M]
  ------------------
  357|  1.59M|    case SPV_OPERAND_TYPE_RAY_QUERY_CANDIDATE_INTERSECTION_TYPE:
  ------------------
  |  Branch (357:5): [True: 0, False: 1.59M]
  ------------------
  358|  1.59M|    case SPV_OPERAND_TYPE_DEBUG_BASE_TYPE_ATTRIBUTE_ENCODING:
  ------------------
  |  Branch (358:5): [True: 2, False: 1.59M]
  ------------------
  359|  1.59M|    case SPV_OPERAND_TYPE_DEBUG_COMPOSITE_TYPE:
  ------------------
  |  Branch (359:5): [True: 8, False: 1.59M]
  ------------------
  360|  1.59M|    case SPV_OPERAND_TYPE_DEBUG_TYPE_QUALIFIER:
  ------------------
  |  Branch (360:5): [True: 8, False: 1.59M]
  ------------------
  361|  1.59M|    case SPV_OPERAND_TYPE_DEBUG_OPERATION:
  ------------------
  |  Branch (361:5): [True: 8, False: 1.59M]
  ------------------
  362|  1.59M|    case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_BASE_TYPE_ATTRIBUTE_ENCODING:
  ------------------
  |  Branch (362:5): [True: 0, False: 1.59M]
  ------------------
  363|  1.59M|    case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_COMPOSITE_TYPE:
  ------------------
  |  Branch (363:5): [True: 3, False: 1.59M]
  ------------------
  364|  1.59M|    case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_TYPE_QUALIFIER:
  ------------------
  |  Branch (364:5): [True: 7, False: 1.59M]
  ------------------
  365|  1.59M|    case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_OPERATION:
  ------------------
  |  Branch (365:5): [True: 2, False: 1.59M]
  ------------------
  366|  1.59M|    case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_IMPORTED_ENTITY:
  ------------------
  |  Branch (366:5): [True: 0, False: 1.59M]
  ------------------
  367|  1.59M|    case SPV_OPERAND_TYPE_FPDENORM_MODE:
  ------------------
  |  Branch (367:5): [True: 27, False: 1.59M]
  ------------------
  368|  1.59M|    case SPV_OPERAND_TYPE_FPOPERATION_MODE:
  ------------------
  |  Branch (368:5): [True: 0, False: 1.59M]
  ------------------
  369|  1.59M|    case SPV_OPERAND_TYPE_QUANTIZATION_MODES:
  ------------------
  |  Branch (369:5): [True: 0, False: 1.59M]
  ------------------
  370|  1.59M|    case SPV_OPERAND_TYPE_OVERFLOW_MODES:
  ------------------
  |  Branch (370:5): [True: 0, False: 1.59M]
  ------------------
  371|  1.59M|    case SPV_OPERAND_TYPE_PACKED_VECTOR_FORMAT:
  ------------------
  |  Branch (371:5): [True: 25, False: 1.59M]
  ------------------
  372|  1.59M|      return true;
  373|      0|    default:
  ------------------
  |  Branch (373:5): [True: 0, False: 1.59M]
  ------------------
  374|      0|      break;
  375|  1.59M|  }
  376|      0|  return false;
  377|  1.59M|}
spvOperandIsConcreteMask:
  379|  2.70M|bool spvOperandIsConcreteMask(spv_operand_type_t type) {
  380|  2.70M|  switch (type) {
  381|     46|    case SPV_OPERAND_TYPE_IMAGE:
  ------------------
  |  Branch (381:5): [True: 46, False: 2.70M]
  ------------------
  382|  1.84k|    case SPV_OPERAND_TYPE_FP_FAST_MATH_MODE:
  ------------------
  |  Branch (382:5): [True: 1.79k, False: 2.70M]
  ------------------
  383|  56.5k|    case SPV_OPERAND_TYPE_SELECTION_CONTROL:
  ------------------
  |  Branch (383:5): [True: 54.6k, False: 2.64M]
  ------------------
  384|   160k|    case SPV_OPERAND_TYPE_LOOP_CONTROL:
  ------------------
  |  Branch (384:5): [True: 103k, False: 2.59M]
  ------------------
  385|   184k|    case SPV_OPERAND_TYPE_FUNCTION_CONTROL:
  ------------------
  |  Branch (385:5): [True: 24.5k, False: 2.67M]
  ------------------
  386|   185k|    case SPV_OPERAND_TYPE_MEMORY_ACCESS:
  ------------------
  |  Branch (386:5): [True: 1.33k, False: 2.70M]
  ------------------
  387|   185k|    case SPV_OPERAND_TYPE_FRAGMENT_SHADING_RATE:
  ------------------
  |  Branch (387:5): [True: 0, False: 2.70M]
  ------------------
  388|   185k|    case SPV_OPERAND_TYPE_DEBUG_INFO_FLAGS:
  ------------------
  |  Branch (388:5): [True: 17, False: 2.70M]
  ------------------
  389|   185k|    case SPV_OPERAND_TYPE_CLDEBUG100_DEBUG_INFO_FLAGS:
  ------------------
  |  Branch (389:5): [True: 8, False: 2.70M]
  ------------------
  390|   185k|      return true;
  391|  2.51M|    default:
  ------------------
  |  Branch (391:5): [True: 2.51M, False: 185k]
  ------------------
  392|  2.51M|      break;
  393|  2.70M|  }
  394|  2.51M|  return false;
  395|  2.70M|}
_Z20spvOperandIsOptional18spv_operand_type_t:
  397|   561k|bool spvOperandIsOptional(spv_operand_type_t type) {
  398|   561k|  switch (type) {
  399|  42.3k|    case SPV_OPERAND_TYPE_OPTIONAL_ID:
  ------------------
  |  Branch (399:5): [True: 42.3k, False: 518k]
  ------------------
  400|  42.9k|    case SPV_OPERAND_TYPE_OPTIONAL_IMAGE:
  ------------------
  |  Branch (400:5): [True: 574, False: 560k]
  ------------------
  401|   292k|    case SPV_OPERAND_TYPE_OPTIONAL_MEMORY_ACCESS:
  ------------------
  |  Branch (401:5): [True: 250k, False: 311k]
  ------------------
  402|   292k|    case SPV_OPERAND_TYPE_OPTIONAL_LITERAL_INTEGER:
  ------------------
  |  Branch (402:5): [True: 0, False: 561k]
  ------------------
  403|   292k|    case SPV_OPERAND_TYPE_OPTIONAL_LITERAL_NUMBER:
  ------------------
  |  Branch (403:5): [True: 0, False: 561k]
  ------------------
  404|   292k|    case SPV_OPERAND_TYPE_OPTIONAL_TYPED_LITERAL_INTEGER:
  ------------------
  |  Branch (404:5): [True: 0, False: 561k]
  ------------------
  405|   292k|    case SPV_OPERAND_TYPE_OPTIONAL_LITERAL_STRING:
  ------------------
  |  Branch (405:5): [True: 17, False: 561k]
  ------------------
  406|   294k|    case SPV_OPERAND_TYPE_OPTIONAL_ACCESS_QUALIFIER:
  ------------------
  |  Branch (406:5): [True: 1.09k, False: 559k]
  ------------------
  407|   294k|    case SPV_OPERAND_TYPE_OPTIONAL_PACKED_VECTOR_FORMAT:
  ------------------
  |  Branch (407:5): [True: 14, False: 561k]
  ------------------
  408|   294k|    case SPV_OPERAND_TYPE_OPTIONAL_CIV:
  ------------------
  |  Branch (408:5): [True: 0, False: 561k]
  ------------------
  409|   294k|      return true;
  410|   267k|    default:
  ------------------
  |  Branch (410:5): [True: 267k, False: 294k]
  ------------------
  411|   267k|      break;
  412|   561k|  }
  413|       |  // Any variable operand is also optional.
  414|   267k|  return spvOperandIsVariable(type);
  415|   561k|}
_Z20spvOperandIsVariable18spv_operand_type_t:
  417|   267k|bool spvOperandIsVariable(spv_operand_type_t type) {
  418|   267k|  switch (type) {
  419|   182k|    case SPV_OPERAND_TYPE_VARIABLE_ID:
  ------------------
  |  Branch (419:5): [True: 182k, False: 84.5k]
  ------------------
  420|   252k|    case SPV_OPERAND_TYPE_VARIABLE_LITERAL_INTEGER:
  ------------------
  |  Branch (420:5): [True: 69.5k, False: 197k]
  ------------------
  421|   264k|    case SPV_OPERAND_TYPE_VARIABLE_LITERAL_INTEGER_ID:
  ------------------
  |  Branch (421:5): [True: 12.4k, False: 254k]
  ------------------
  422|   266k|    case SPV_OPERAND_TYPE_VARIABLE_ID_LITERAL_INTEGER:
  ------------------
  |  Branch (422:5): [True: 2.45k, False: 264k]
  ------------------
  423|   266k|      return true;
  424|     61|    default:
  ------------------
  |  Branch (424:5): [True: 61, False: 266k]
  ------------------
  425|     61|      break;
  426|   267k|  }
  427|     61|  return false;
  428|   267k|}
_Z28spvExpandOperandSequenceOnce18spv_operand_type_tPNSt3__16vectorIS_NS0_9allocatorIS_EEEE:
  431|  11.0M|                                  spv_operand_pattern_t* pattern) {
  432|  11.0M|  switch (type) {
  433|  2.76M|    case SPV_OPERAND_TYPE_VARIABLE_ID:
  ------------------
  |  Branch (433:5): [True: 2.76M, False: 8.29M]
  ------------------
  434|  2.76M|      pattern->push_back(type);
  435|  2.76M|      pattern->push_back(SPV_OPERAND_TYPE_OPTIONAL_ID);
  436|  2.76M|      return true;
  437|   471k|    case SPV_OPERAND_TYPE_VARIABLE_LITERAL_INTEGER:
  ------------------
  |  Branch (437:5): [True: 471k, False: 10.5M]
  ------------------
  438|   471k|      pattern->push_back(type);
  439|   471k|      pattern->push_back(SPV_OPERAND_TYPE_OPTIONAL_LITERAL_INTEGER);
  440|   471k|      return true;
  441|   104k|    case SPV_OPERAND_TYPE_VARIABLE_LITERAL_INTEGER_ID:
  ------------------
  |  Branch (441:5): [True: 104k, False: 10.9M]
  ------------------
  442|       |      // Represents Zero or more (Literal number, Id) pairs,
  443|       |      // where the literal number must be a scalar integer.
  444|   104k|      pattern->push_back(type);
  445|   104k|      pattern->push_back(SPV_OPERAND_TYPE_ID);
  446|   104k|      pattern->push_back(SPV_OPERAND_TYPE_OPTIONAL_TYPED_LITERAL_INTEGER);
  447|   104k|      return true;
  448|  1.92k|    case SPV_OPERAND_TYPE_VARIABLE_ID_LITERAL_INTEGER:
  ------------------
  |  Branch (448:5): [True: 1.92k, False: 11.0M]
  ------------------
  449|       |      // Represents Zero or more (Id, Literal number) pairs.
  450|  1.92k|      pattern->push_back(type);
  451|  1.92k|      pattern->push_back(SPV_OPERAND_TYPE_LITERAL_INTEGER);
  452|  1.92k|      pattern->push_back(SPV_OPERAND_TYPE_OPTIONAL_ID);
  453|  1.92k|      return true;
  454|  7.72M|    default:
  ------------------
  |  Branch (454:5): [True: 7.72M, False: 3.33M]
  ------------------
  455|  7.72M|      break;
  456|  11.0M|  }
  457|  7.72M|  return false;
  458|  11.0M|}
_Z28spvTakeFirstMatchableOperandPNSt3__16vectorI18spv_operand_type_tNS_9allocatorIS1_EEEE:
  461|  7.72M|    spv_operand_pattern_t* pattern) {
  462|  7.72M|  assert(!pattern->empty());
  463|      0|  spv_operand_type_t result;
  464|  11.0M|  do {
  465|  11.0M|    result = pattern->back();
  466|  11.0M|    pattern->pop_back();
  467|  11.0M|  } while (spvExpandOperandSequenceOnce(result, pattern));
  ------------------
  |  Branch (467:12): [True: 3.33M, False: 7.72M]
  ------------------
  468|  7.72M|  return result;
  469|  7.72M|}
_Z11spvIsIdType18spv_operand_type_t:
  486|  9.37M|bool spvIsIdType(spv_operand_type_t type) {
  487|  9.37M|  switch (type) {
  488|  5.39M|    case SPV_OPERAND_TYPE_ID:
  ------------------
  |  Branch (488:5): [True: 5.39M, False: 3.98M]
  ------------------
  489|  6.12M|    case SPV_OPERAND_TYPE_TYPE_ID:
  ------------------
  |  Branch (489:5): [True: 732k, False: 8.64M]
  ------------------
  490|  7.37M|    case SPV_OPERAND_TYPE_RESULT_ID:
  ------------------
  |  Branch (490:5): [True: 1.24M, False: 8.12M]
  ------------------
  491|  7.38M|    case SPV_OPERAND_TYPE_MEMORY_SEMANTICS_ID:
  ------------------
  |  Branch (491:5): [True: 3.58k, False: 9.37M]
  ------------------
  492|  7.38M|    case SPV_OPERAND_TYPE_SCOPE_ID:
  ------------------
  |  Branch (492:5): [True: 7.17k, False: 9.37M]
  ------------------
  493|  7.38M|      return true;
  494|  1.99M|    default:
  ------------------
  |  Branch (494:5): [True: 1.99M, False: 7.38M]
  ------------------
  495|  1.99M|      return false;
  496|  9.37M|  }
  497|  9.37M|}
_Z38spvOperandCanBeForwardDeclaredFunctionN3spv2OpE:
  515|   388k|    spv::Op opcode) {
  516|   388k|  std::function<bool(unsigned index)> out;
  517|   388k|  if (spvOpcodeGeneratesType(opcode)) {
  ------------------
  |  Branch (517:7): [True: 28.8k, False: 360k]
  ------------------
  518|       |    // All types can use forward pointers.
  519|  28.8k|    out = [](unsigned) { return true; };
  520|  28.8k|    return out;
  521|  28.8k|  }
  522|   360k|  switch (opcode) {
  523|  4.20k|    case spv::Op::OpExecutionMode:
  ------------------
  |  Branch (523:5): [True: 4.20k, False: 355k]
  ------------------
  524|  4.20k|    case spv::Op::OpExecutionModeId:
  ------------------
  |  Branch (524:5): [True: 0, False: 360k]
  ------------------
  525|  7.50k|    case spv::Op::OpEntryPoint:
  ------------------
  |  Branch (525:5): [True: 3.30k, False: 356k]
  ------------------
  526|  9.71k|    case spv::Op::OpName:
  ------------------
  |  Branch (526:5): [True: 2.21k, False: 357k]
  ------------------
  527|  10.0k|    case spv::Op::OpMemberName:
  ------------------
  |  Branch (527:5): [True: 287, False: 359k]
  ------------------
  528|  20.1k|    case spv::Op::OpSelectionMerge:
  ------------------
  |  Branch (528:5): [True: 10.1k, False: 349k]
  ------------------
  529|  35.4k|    case spv::Op::OpDecorate:
  ------------------
  |  Branch (529:5): [True: 15.2k, False: 344k]
  ------------------
  530|  36.7k|    case spv::Op::OpMemberDecorate:
  ------------------
  |  Branch (530:5): [True: 1.23k, False: 358k]
  ------------------
  531|  36.7k|    case spv::Op::OpDecorateId:
  ------------------
  |  Branch (531:5): [True: 2, False: 360k]
  ------------------
  532|  36.7k|    case spv::Op::OpDecorateStringGOOGLE:
  ------------------
  |  Branch (532:5): [True: 12, False: 360k]
  ------------------
  533|  36.7k|    case spv::Op::OpMemberDecorateStringGOOGLE:
  ------------------
  |  Branch (533:5): [True: 2, False: 360k]
  ------------------
  534|  62.3k|    case spv::Op::OpBranch:
  ------------------
  |  Branch (534:5): [True: 25.6k, False: 334k]
  ------------------
  535|  84.5k|    case spv::Op::OpLoopMerge:
  ------------------
  |  Branch (535:5): [True: 22.2k, False: 337k]
  ------------------
  536|  84.5k|      out = [](unsigned) { return true; };
  537|  84.5k|      break;
  538|  1.85k|    case spv::Op::OpGroupDecorate:
  ------------------
  |  Branch (538:5): [True: 1.85k, False: 358k]
  ------------------
  539|  2.37k|    case spv::Op::OpGroupMemberDecorate:
  ------------------
  |  Branch (539:5): [True: 527, False: 359k]
  ------------------
  540|  14.0k|    case spv::Op::OpBranchConditional:
  ------------------
  |  Branch (540:5): [True: 11.6k, False: 348k]
  ------------------
  541|  16.9k|    case spv::Op::OpSwitch:
  ------------------
  |  Branch (541:5): [True: 2.88k, False: 357k]
  ------------------
  542|  16.9k|      out = [](unsigned index) { return index != 0; };
  543|  16.9k|      break;
  544|       |
  545|    700|    case spv::Op::OpFunctionCall:
  ------------------
  |  Branch (545:5): [True: 700, False: 359k]
  ------------------
  546|       |      // The Function parameter.
  547|    700|      out = [](unsigned index) { return index == 2; };
  548|    700|      break;
  549|       |
  550|  8.44k|    case spv::Op::OpPhi:
  ------------------
  |  Branch (550:5): [True: 8.44k, False: 351k]
  ------------------
  551|  8.44k|      out = [](unsigned index) { return index > 1; };
  552|  8.44k|      break;
  553|       |
  554|      1|    case spv::Op::OpEnqueueKernel:
  ------------------
  |  Branch (554:5): [True: 1, False: 360k]
  ------------------
  555|       |      // The Invoke parameter.
  556|      1|      out = [](unsigned index) { return index == 8; };
  557|      1|      break;
  558|       |
  559|      3|    case spv::Op::OpGetKernelNDrangeSubGroupCount:
  ------------------
  |  Branch (559:5): [True: 3, False: 360k]
  ------------------
  560|      4|    case spv::Op::OpGetKernelNDrangeMaxSubGroupSize:
  ------------------
  |  Branch (560:5): [True: 1, False: 360k]
  ------------------
  561|       |      // The Invoke parameter.
  562|      4|      out = [](unsigned index) { return index == 3; };
  563|      4|      break;
  564|       |
  565|      0|    case spv::Op::OpGetKernelWorkGroupSize:
  ------------------
  |  Branch (565:5): [True: 0, False: 360k]
  ------------------
  566|      1|    case spv::Op::OpGetKernelPreferredWorkGroupSizeMultiple:
  ------------------
  |  Branch (566:5): [True: 1, False: 360k]
  ------------------
  567|       |      // The Invoke parameter.
  568|      1|      out = [](unsigned index) { return index == 2; };
  569|      1|      break;
  570|    255|    case spv::Op::OpTypeForwardPointer:
  ------------------
  |  Branch (570:5): [True: 255, False: 359k]
  ------------------
  571|    255|      out = [](unsigned index) { return index == 0; };
  572|    255|      break;
  573|      0|    case spv::Op::OpTypeArray:
  ------------------
  |  Branch (573:5): [True: 0, False: 360k]
  ------------------
  574|      0|      out = [](unsigned index) { return index == 1; };
  575|      0|      break;
  576|   249k|    default:
  ------------------
  |  Branch (576:5): [True: 249k, False: 110k]
  ------------------
  577|   249k|      out = [](unsigned) { return false; };
  578|   249k|      break;
  579|   360k|  }
  580|   360k|  return out;
  581|   360k|}
_Z48spvDbgInfoExtOperandCanBeForwardDeclaredFunction19spv_ext_inst_type_tj:
  584|      5|    spv_ext_inst_type_t ext_type, uint32_t key) {
  585|       |  // The Vulkan debug info extended instruction set is non-semantic so allows no
  586|       |  // forward references ever
  587|      5|  if (ext_type == SPV_EXT_INST_TYPE_NONSEMANTIC_SHADER_DEBUGINFO_100) {
  ------------------
  |  Branch (587:7): [True: 0, False: 5]
  ------------------
  588|      0|    return [](unsigned) { return false; };
  589|      0|  }
  590|       |
  591|       |  // TODO(https://gitlab.khronos.org/spirv/SPIR-V/issues/532): Forward
  592|       |  // references for debug info instructions are still in discussion. We must
  593|       |  // update the following lines of code when we conclude the spec.
  594|      5|  std::function<bool(unsigned index)> out;
  595|      5|  if (ext_type == SPV_EXT_INST_TYPE_OPENCL_DEBUGINFO_100) {
  ------------------
  |  Branch (595:7): [True: 0, False: 5]
  ------------------
  596|      0|    switch (OpenCLDebugInfo100Instructions(key)) {
  597|      0|      case OpenCLDebugInfo100DebugFunction:
  ------------------
  |  Branch (597:7): [True: 0, False: 0]
  ------------------
  598|      0|        out = [](unsigned index) { return index == 13; };
  599|      0|        break;
  600|      0|      case OpenCLDebugInfo100DebugTypeComposite:
  ------------------
  |  Branch (600:7): [True: 0, False: 0]
  ------------------
  601|      0|        out = [](unsigned index) { return index >= 13; };
  602|      0|        break;
  603|      0|      default:
  ------------------
  |  Branch (603:7): [True: 0, False: 0]
  ------------------
  604|      0|        out = [](unsigned) { return false; };
  605|      0|        break;
  606|      0|    }
  607|      5|  } else {
  608|      5|    switch (DebugInfoInstructions(key)) {
  609|      0|      case DebugInfoDebugFunction:
  ------------------
  |  Branch (609:7): [True: 0, False: 5]
  ------------------
  610|      0|        out = [](unsigned index) { return index == 13; };
  611|      0|        break;
  612|      1|      case DebugInfoDebugTypeComposite:
  ------------------
  |  Branch (612:7): [True: 1, False: 4]
  ------------------
  613|      1|        out = [](unsigned index) { return index >= 12; };
  614|      1|        break;
  615|      4|      default:
  ------------------
  |  Branch (615:7): [True: 4, False: 1]
  ------------------
  616|      4|        out = [](unsigned) { return false; };
  617|      4|        break;
  618|      5|    }
  619|      5|  }
  620|      5|  return out;
  621|      5|}
operand.cpp:_ZZ26spvOperandTableValueLookup14spv_target_envPK19spv_operand_table_t18spv_operand_type_tjPPK18spv_operand_desc_tENK3$_0clERS5_S9_:
  102|  5.93M|  auto comp = [](const spv_operand_desc_t& lhs, const spv_operand_desc_t& rhs) {
  103|  5.93M|    return lhs.value < rhs.value;
  104|  5.93M|  };
operand.cpp:_ZZ38spvOperandCanBeForwardDeclaredFunctionN3spv2OpEENK3$_1clEj:
  519|    313|    out = [](unsigned) { return true; };
operand.cpp:_ZZ38spvOperandCanBeForwardDeclaredFunctionN3spv2OpEENK3$_2clEj:
  536|   493k|      out = [](unsigned) { return true; };
operand.cpp:_ZZ38spvOperandCanBeForwardDeclaredFunctionN3spv2OpEENK3$_3clEj:
  542|  47.2k|      out = [](unsigned index) { return index != 0; };
operand.cpp:_ZZ38spvOperandCanBeForwardDeclaredFunctionN3spv2OpEENK3$_4clEj:
  547|    427|      out = [](unsigned index) { return index == 2; };
operand.cpp:_ZZ38spvOperandCanBeForwardDeclaredFunctionN3spv2OpEENK3$_5clEj:
  551|  9.49k|      out = [](unsigned index) { return index > 1; };
operand.cpp:_ZZ38spvOperandCanBeForwardDeclaredFunctionN3spv2OpEENK3$_6clEj:
  556|      1|      out = [](unsigned index) { return index == 8; };
operand.cpp:_ZZ38spvOperandCanBeForwardDeclaredFunctionN3spv2OpEENK3$_7clEj:
  562|      3|      out = [](unsigned index) { return index == 3; };
operand.cpp:_ZZ38spvOperandCanBeForwardDeclaredFunctionN3spv2OpEENK3$_8clEj:
  568|      2|      out = [](unsigned index) { return index == 2; };
operand.cpp:_ZZ38spvOperandCanBeForwardDeclaredFunctionN3spv2OpEENK3$_9clEj:
  571|    254|      out = [](unsigned index) { return index == 0; };
operand.cpp:_ZZ38spvOperandCanBeForwardDeclaredFunctionN3spv2OpEENK4$_11clEj:
  577|     53|      out = [](unsigned) { return false; };

_ZN8spvtools18EmitNumericLiteralEPNSt3__113basic_ostreamIcNS0_11char_traitsIcEEEERK24spv_parsed_instruction_tRK20spv_parsed_operand_t:
   25|   107k|                        const spv_parsed_operand_t& operand) {
   26|   107k|  if (operand.type != SPV_OPERAND_TYPE_LITERAL_INTEGER &&
  ------------------
  |  Branch (26:7): [True: 30.4k, False: 77.1k]
  ------------------
   27|   107k|      operand.type != SPV_OPERAND_TYPE_TYPED_LITERAL_NUMBER &&
  ------------------
  |  Branch (27:7): [True: 0, False: 30.4k]
  ------------------
   28|   107k|      operand.type != SPV_OPERAND_TYPE_OPTIONAL_LITERAL_INTEGER &&
  ------------------
  |  Branch (28:7): [True: 0, False: 0]
  ------------------
   29|   107k|      operand.type != SPV_OPERAND_TYPE_OPTIONAL_TYPED_LITERAL_INTEGER)
  ------------------
  |  Branch (29:7): [True: 0, False: 0]
  ------------------
   30|      0|    return;
   31|   107k|  if (operand.num_words < 1) return;
  ------------------
  |  Branch (31:7): [True: 145, False: 107k]
  ------------------
   32|       |  // TODO(dneto): Support more than 64-bits at a time.
   33|   107k|  if (operand.num_words > 2) return;
  ------------------
  |  Branch (33:7): [True: 56, False: 107k]
  ------------------
   34|       |
   35|   107k|  const uint32_t word = inst.words[operand.offset];
   36|   107k|  if (operand.num_words == 1) {
  ------------------
  |  Branch (36:7): [True: 107k, False: 190]
  ------------------
   37|   107k|    switch (operand.number_kind) {
   38|  18.2k|      case SPV_NUMBER_SIGNED_INT:
  ------------------
  |  Branch (38:7): [True: 18.2k, False: 88.9k]
  ------------------
   39|  18.2k|        *out << int32_t(word);
   40|  18.2k|        break;
   41|  81.9k|      case SPV_NUMBER_UNSIGNED_INT:
  ------------------
  |  Branch (41:7): [True: 81.9k, False: 25.2k]
  ------------------
   42|  81.9k|        *out << word;
   43|  81.9k|        break;
   44|  6.97k|      case SPV_NUMBER_FLOATING:
  ------------------
  |  Branch (44:7): [True: 6.97k, False: 100k]
  ------------------
   45|  6.97k|        if (operand.number_bit_width == 16) {
  ------------------
  |  Branch (45:13): [True: 162, False: 6.81k]
  ------------------
   46|    162|          *out << spvtools::utils::FloatProxy<spvtools::utils::Float16>(
   47|    162|              uint16_t(word & 0xFFFF));
   48|  6.81k|        } else {
   49|       |          // Assume 32-bit floats.
   50|  6.81k|          *out << spvtools::utils::FloatProxy<float>(word);
   51|  6.81k|        }
   52|  6.97k|        break;
   53|      0|      default:
  ------------------
  |  Branch (53:7): [True: 0, False: 107k]
  ------------------
   54|      0|        break;
   55|   107k|    }
   56|   107k|  } else if (operand.num_words == 2) {
  ------------------
  |  Branch (56:14): [True: 190, False: 0]
  ------------------
   57|       |    // Multi-word numbers are presented with lower order words first.
   58|    190|    uint64_t bits =
   59|    190|        uint64_t(word) | (uint64_t(inst.words[operand.offset + 1]) << 32);
   60|    190|    switch (operand.number_kind) {
   61|     44|      case SPV_NUMBER_SIGNED_INT:
  ------------------
  |  Branch (61:7): [True: 44, False: 146]
  ------------------
   62|     44|        *out << int64_t(bits);
   63|     44|        break;
   64|      1|      case SPV_NUMBER_UNSIGNED_INT:
  ------------------
  |  Branch (64:7): [True: 1, False: 189]
  ------------------
   65|      1|        *out << bits;
   66|      1|        break;
   67|    145|      case SPV_NUMBER_FLOATING:
  ------------------
  |  Branch (67:7): [True: 145, False: 45]
  ------------------
   68|       |        // Assume only 64-bit floats.
   69|    145|        *out << spvtools::utils::FloatProxy<double>(bits);
   70|    145|        break;
   71|      0|      default:
  ------------------
  |  Branch (71:7): [True: 0, False: 190]
  ------------------
   72|      0|        break;
   73|    190|    }
   74|    190|  }
   75|   107k|}

_ZN8spvtools10out_streamC2ERNSt3__118basic_stringstreamIcNS1_11char_traitsIcEENS1_9allocatorIcEEEE:
   27|  4.45k|  explicit out_stream(std::stringstream& stream) : pStream(&stream) {}
_ZN8spvtools10out_stream3getEv:
   29|  4.45k|  std::ostream& get() {
   30|  4.45k|    if (pStream) {
  ------------------
  |  Branch (30:9): [True: 4.45k, False: 0]
  ------------------
   31|  4.45k|      return *pStream;
   32|  4.45k|    }
   33|      0|    return std::cout;
   34|  4.45k|  }

_Z10spvFixWordj16spv_endianness_t:
   34|  13.7M|uint32_t spvFixWord(const uint32_t word, const spv_endianness_t endian) {
   35|  13.7M|  if ((SPV_ENDIANNESS_LITTLE == endian && I32_ENDIAN_HOST == I32_ENDIAN_BIG) ||
  ------------------
  |  |   32|  6.63M|#define I32_ENDIAN_HOST (o32_host_order.value)
  ------------------
  |  Branch (35:8): [True: 6.63M, False: 7.15M]
  |  Branch (35:43): [True: 0, False: 6.63M]
  ------------------
   36|  13.7M|      (SPV_ENDIANNESS_BIG == endian && I32_ENDIAN_HOST == I32_ENDIAN_LITTLE)) {
  ------------------
  |  |   32|  7.15M|#define I32_ENDIAN_HOST (o32_host_order.value)
  ------------------
  |  Branch (36:8): [True: 7.15M, False: 6.63M]
  |  Branch (36:40): [True: 7.15M, False: 0]
  ------------------
   37|  7.15M|    return (word & 0x000000ff) << 24 | (word & 0x0000ff00) << 8 |
   38|  7.15M|           (word & 0x00ff0000) >> 8 | (word & 0xff000000) >> 24;
   39|  7.15M|  }
   40|       |
   41|  6.63M|  return word;
   42|  13.7M|}
_Z19spvBinaryEndiannessP18spv_const_binary_tP16spv_endianness_t:
   50|  48.2k|                                 spv_endianness_t* pEndian) {
   51|  48.2k|  if (!binary->code || !binary->wordCount) return SPV_ERROR_INVALID_BINARY;
  ------------------
  |  Branch (51:7): [True: 3, False: 48.2k]
  |  Branch (51:24): [True: 0, False: 48.2k]
  ------------------
   52|  48.2k|  if (!pEndian) return SPV_ERROR_INVALID_POINTER;
  ------------------
  |  Branch (52:7): [True: 0, False: 48.2k]
  ------------------
   53|       |
   54|  48.2k|  uint8_t bytes[4];
   55|  48.2k|  memcpy(bytes, binary->code, sizeof(uint32_t));
   56|       |
   57|  48.2k|  if (0x03 == bytes[0] && 0x02 == bytes[1] && 0x23 == bytes[2] &&
  ------------------
  |  Branch (57:7): [True: 43.1k, False: 5.04k]
  |  Branch (57:27): [True: 43.1k, False: 15]
  |  Branch (57:47): [True: 43.1k, False: 19]
  ------------------
   58|  48.2k|      0x07 == bytes[3]) {
  ------------------
  |  Branch (58:7): [True: 43.1k, False: 11]
  ------------------
   59|  43.1k|    *pEndian = SPV_ENDIANNESS_LITTLE;
   60|  43.1k|    return SPV_SUCCESS;
   61|  43.1k|  }
   62|       |
   63|  5.09k|  if (0x07 == bytes[0] && 0x23 == bytes[1] && 0x02 == bytes[2] &&
  ------------------
  |  Branch (63:7): [True: 5.02k, False: 66]
  |  Branch (63:27): [True: 5.01k, False: 14]
  |  Branch (63:47): [True: 5.00k, False: 10]
  ------------------
   64|  5.09k|      0x03 == bytes[3]) {
  ------------------
  |  Branch (64:7): [True: 4.99k, False: 8]
  ------------------
   65|  4.99k|    *pEndian = SPV_ENDIANNESS_BIG;
   66|  4.99k|    return SPV_SUCCESS;
   67|  4.99k|  }
   68|       |
   69|     98|  return SPV_ERROR_INVALID_BINARY;
   70|  5.09k|}
_Z15spvIsHostEndian16spv_endianness_t:
   72|  39.9k|bool spvIsHostEndian(spv_endianness_t endian) {
   73|  39.9k|  return ((SPV_ENDIANNESS_LITTLE == endian) &&
  ------------------
  |  Branch (73:11): [True: 35.8k, False: 4.10k]
  ------------------
   74|  39.9k|          (I32_ENDIAN_LITTLE == I32_ENDIAN_HOST)) ||
  ------------------
  |  |   32|  35.8k|#define I32_ENDIAN_HOST (o32_host_order.value)
  ------------------
  |  Branch (74:11): [True: 35.8k, False: 0]
  ------------------
   75|  39.9k|         ((SPV_ENDIANNESS_BIG == endian) &&
  ------------------
  |  Branch (75:11): [True: 4.10k, False: 0]
  ------------------
   76|  4.10k|          (I32_ENDIAN_BIG == I32_ENDIAN_HOST));
  ------------------
  |  |   32|  4.10k|#define I32_ENDIAN_HOST (o32_host_order.value)
  ------------------
  |  Branch (76:11): [True: 0, False: 4.10k]
  ------------------
   77|  39.9k|}

spvTargetEnvDescription:
   24|     94|const char* spvTargetEnvDescription(spv_target_env env) {
   25|     94|  switch (env) {
  ------------------
  |  Branch (25:11): [True: 0, False: 94]
  ------------------
   26|      0|    case SPV_ENV_UNIVERSAL_1_0:
  ------------------
  |  Branch (26:5): [True: 0, False: 94]
  ------------------
   27|      0|      return "SPIR-V 1.0";
   28|      0|    case SPV_ENV_VULKAN_1_0:
  ------------------
  |  Branch (28:5): [True: 0, False: 94]
  ------------------
   29|      0|      return "SPIR-V 1.0 (under Vulkan 1.0 semantics)";
   30|      0|    case SPV_ENV_UNIVERSAL_1_1:
  ------------------
  |  Branch (30:5): [True: 0, False: 94]
  ------------------
   31|      0|      return "SPIR-V 1.1";
   32|      0|    case SPV_ENV_OPENCL_1_2:
  ------------------
  |  Branch (32:5): [True: 0, False: 94]
  ------------------
   33|      0|      return "SPIR-V 1.0 (under OpenCL 1.2 Full Profile semantics)";
   34|      0|    case SPV_ENV_OPENCL_EMBEDDED_1_2:
  ------------------
  |  Branch (34:5): [True: 0, False: 94]
  ------------------
   35|      0|      return "SPIR-V 1.0 (under OpenCL 1.2 Embedded Profile semantics)";
   36|      0|    case SPV_ENV_OPENCL_2_0:
  ------------------
  |  Branch (36:5): [True: 0, False: 94]
  ------------------
   37|      0|      return "SPIR-V 1.0 (under OpenCL 2.0 Full Profile semantics)";
   38|      0|    case SPV_ENV_OPENCL_EMBEDDED_2_0:
  ------------------
  |  Branch (38:5): [True: 0, False: 94]
  ------------------
   39|      0|      return "SPIR-V 1.0 (under OpenCL 2.0 Embedded Profile semantics)";
   40|      0|    case SPV_ENV_OPENCL_2_1:
  ------------------
  |  Branch (40:5): [True: 0, False: 94]
  ------------------
   41|      0|      return "SPIR-V 1.0 (under OpenCL 2.1 Full Profile semantics)";
   42|      0|    case SPV_ENV_OPENCL_EMBEDDED_2_1:
  ------------------
  |  Branch (42:5): [True: 0, False: 94]
  ------------------
   43|      0|      return "SPIR-V 1.0 (under OpenCL 2.1 Embedded Profile semantics)";
   44|      0|    case SPV_ENV_OPENCL_2_2:
  ------------------
  |  Branch (44:5): [True: 0, False: 94]
  ------------------
   45|      0|      return "SPIR-V 1.2 (under OpenCL 2.2 Full Profile semantics)";
   46|      0|    case SPV_ENV_OPENCL_EMBEDDED_2_2:
  ------------------
  |  Branch (46:5): [True: 0, False: 94]
  ------------------
   47|      0|      return "SPIR-V 1.2 (under OpenCL 2.2 Embedded Profile semantics)";
   48|      0|    case SPV_ENV_OPENGL_4_0:
  ------------------
  |  Branch (48:5): [True: 0, False: 94]
  ------------------
   49|      0|      return "SPIR-V 1.0 (under OpenGL 4.0 semantics)";
   50|     94|    case SPV_ENV_OPENGL_4_1:
  ------------------
  |  Branch (50:5): [True: 94, False: 0]
  ------------------
   51|     94|      return "SPIR-V 1.0 (under OpenGL 4.1 semantics)";
   52|      0|    case SPV_ENV_OPENGL_4_2:
  ------------------
  |  Branch (52:5): [True: 0, False: 94]
  ------------------
   53|      0|      return "SPIR-V 1.0 (under OpenGL 4.2 semantics)";
   54|      0|    case SPV_ENV_OPENGL_4_3:
  ------------------
  |  Branch (54:5): [True: 0, False: 94]
  ------------------
   55|      0|      return "SPIR-V 1.0 (under OpenGL 4.3 semantics)";
   56|      0|    case SPV_ENV_OPENGL_4_5:
  ------------------
  |  Branch (56:5): [True: 0, False: 94]
  ------------------
   57|      0|      return "SPIR-V 1.0 (under OpenGL 4.5 semantics)";
   58|      0|    case SPV_ENV_UNIVERSAL_1_2:
  ------------------
  |  Branch (58:5): [True: 0, False: 94]
  ------------------
   59|      0|      return "SPIR-V 1.2";
   60|      0|    case SPV_ENV_UNIVERSAL_1_3:
  ------------------
  |  Branch (60:5): [True: 0, False: 94]
  ------------------
   61|      0|      return "SPIR-V 1.3";
   62|      0|    case SPV_ENV_VULKAN_1_1:
  ------------------
  |  Branch (62:5): [True: 0, False: 94]
  ------------------
   63|      0|      return "SPIR-V 1.3 (under Vulkan 1.1 semantics)";
   64|      0|    case SPV_ENV_WEBGPU_0:
  ------------------
  |  Branch (64:5): [True: 0, False: 94]
  ------------------
   65|      0|      assert(false && "Deprecated target environment value.");
   66|      0|      break;
   67|      0|    case SPV_ENV_UNIVERSAL_1_4:
  ------------------
  |  Branch (67:5): [True: 0, False: 94]
  ------------------
   68|      0|      return "SPIR-V 1.4";
   69|      0|    case SPV_ENV_VULKAN_1_1_SPIRV_1_4:
  ------------------
  |  Branch (69:5): [True: 0, False: 94]
  ------------------
   70|      0|      return "SPIR-V 1.4 (under Vulkan 1.1 semantics)";
   71|      0|    case SPV_ENV_UNIVERSAL_1_5:
  ------------------
  |  Branch (71:5): [True: 0, False: 94]
  ------------------
   72|      0|      return "SPIR-V 1.5";
   73|      0|    case SPV_ENV_VULKAN_1_2:
  ------------------
  |  Branch (73:5): [True: 0, False: 94]
  ------------------
   74|      0|      return "SPIR-V 1.5 (under Vulkan 1.2 semantics)";
   75|      0|    case SPV_ENV_UNIVERSAL_1_6:
  ------------------
  |  Branch (75:5): [True: 0, False: 94]
  ------------------
   76|      0|      return "SPIR-V 1.6";
   77|      0|    case SPV_ENV_VULKAN_1_3:
  ------------------
  |  Branch (77:5): [True: 0, False: 94]
  ------------------
   78|      0|      return "SPIR-V 1.6 (under Vulkan 1.3 semantics)";
   79|      0|    case SPV_ENV_MAX:
  ------------------
  |  Branch (79:5): [True: 0, False: 94]
  ------------------
   80|      0|      assert(false && "Invalid target environment value.");
   81|      0|      break;
   82|     94|  }
   83|      0|  return "";
   84|     94|}
_Z22spvVersionForTargetEnv14spv_target_env:
   86|  3.73M|uint32_t spvVersionForTargetEnv(spv_target_env env) {
   87|  3.73M|  switch (env) {
  ------------------
  |  Branch (87:11): [True: 0, False: 3.73M]
  ------------------
   88|      0|    case SPV_ENV_UNIVERSAL_1_0:
  ------------------
  |  Branch (88:5): [True: 0, False: 3.73M]
  ------------------
   89|      0|    case SPV_ENV_VULKAN_1_0:
  ------------------
  |  Branch (89:5): [True: 0, False: 3.73M]
  ------------------
   90|      0|    case SPV_ENV_OPENCL_1_2:
  ------------------
  |  Branch (90:5): [True: 0, False: 3.73M]
  ------------------
   91|      0|    case SPV_ENV_OPENCL_EMBEDDED_1_2:
  ------------------
  |  Branch (91:5): [True: 0, False: 3.73M]
  ------------------
   92|      0|    case SPV_ENV_OPENCL_2_0:
  ------------------
  |  Branch (92:5): [True: 0, False: 3.73M]
  ------------------
   93|      0|    case SPV_ENV_OPENCL_EMBEDDED_2_0:
  ------------------
  |  Branch (93:5): [True: 0, False: 3.73M]
  ------------------
   94|      0|    case SPV_ENV_OPENCL_2_1:
  ------------------
  |  Branch (94:5): [True: 0, False: 3.73M]
  ------------------
   95|      0|    case SPV_ENV_OPENCL_EMBEDDED_2_1:
  ------------------
  |  Branch (95:5): [True: 0, False: 3.73M]
  ------------------
   96|      0|    case SPV_ENV_OPENGL_4_0:
  ------------------
  |  Branch (96:5): [True: 0, False: 3.73M]
  ------------------
   97|  3.73M|    case SPV_ENV_OPENGL_4_1:
  ------------------
  |  Branch (97:5): [True: 3.73M, False: 0]
  ------------------
   98|  3.73M|    case SPV_ENV_OPENGL_4_2:
  ------------------
  |  Branch (98:5): [True: 0, False: 3.73M]
  ------------------
   99|  3.73M|    case SPV_ENV_OPENGL_4_3:
  ------------------
  |  Branch (99:5): [True: 0, False: 3.73M]
  ------------------
  100|  3.73M|    case SPV_ENV_OPENGL_4_5:
  ------------------
  |  Branch (100:5): [True: 0, False: 3.73M]
  ------------------
  101|  3.73M|      return SPV_SPIRV_VERSION_WORD(1, 0);
  ------------------
  |  |   26|  3.73M|  ((uint32_t(uint8_t(MAJOR)) << 16) | (uint32_t(uint8_t(MINOR)) << 8))
  ------------------
  102|      0|    case SPV_ENV_UNIVERSAL_1_1:
  ------------------
  |  Branch (102:5): [True: 0, False: 3.73M]
  ------------------
  103|      0|      return SPV_SPIRV_VERSION_WORD(1, 1);
  ------------------
  |  |   26|      0|  ((uint32_t(uint8_t(MAJOR)) << 16) | (uint32_t(uint8_t(MINOR)) << 8))
  ------------------
  104|      0|    case SPV_ENV_UNIVERSAL_1_2:
  ------------------
  |  Branch (104:5): [True: 0, False: 3.73M]
  ------------------
  105|      0|    case SPV_ENV_OPENCL_2_2:
  ------------------
  |  Branch (105:5): [True: 0, False: 3.73M]
  ------------------
  106|      0|    case SPV_ENV_OPENCL_EMBEDDED_2_2:
  ------------------
  |  Branch (106:5): [True: 0, False: 3.73M]
  ------------------
  107|      0|      return SPV_SPIRV_VERSION_WORD(1, 2);
  ------------------
  |  |   26|      0|  ((uint32_t(uint8_t(MAJOR)) << 16) | (uint32_t(uint8_t(MINOR)) << 8))
  ------------------
  108|      0|    case SPV_ENV_UNIVERSAL_1_3:
  ------------------
  |  Branch (108:5): [True: 0, False: 3.73M]
  ------------------
  109|      0|    case SPV_ENV_VULKAN_1_1:
  ------------------
  |  Branch (109:5): [True: 0, False: 3.73M]
  ------------------
  110|      0|      return SPV_SPIRV_VERSION_WORD(1, 3);
  ------------------
  |  |   26|      0|  ((uint32_t(uint8_t(MAJOR)) << 16) | (uint32_t(uint8_t(MINOR)) << 8))
  ------------------
  111|      0|    case SPV_ENV_WEBGPU_0:
  ------------------
  |  Branch (111:5): [True: 0, False: 3.73M]
  ------------------
  112|      0|      assert(false && "Deprecated target environment value.");
  113|      0|      break;
  114|      0|    case SPV_ENV_UNIVERSAL_1_4:
  ------------------
  |  Branch (114:5): [True: 0, False: 3.73M]
  ------------------
  115|      0|    case SPV_ENV_VULKAN_1_1_SPIRV_1_4:
  ------------------
  |  Branch (115:5): [True: 0, False: 3.73M]
  ------------------
  116|      0|      return SPV_SPIRV_VERSION_WORD(1, 4);
  ------------------
  |  |   26|      0|  ((uint32_t(uint8_t(MAJOR)) << 16) | (uint32_t(uint8_t(MINOR)) << 8))
  ------------------
  117|      0|    case SPV_ENV_UNIVERSAL_1_5:
  ------------------
  |  Branch (117:5): [True: 0, False: 3.73M]
  ------------------
  118|      0|    case SPV_ENV_VULKAN_1_2:
  ------------------
  |  Branch (118:5): [True: 0, False: 3.73M]
  ------------------
  119|      0|      return SPV_SPIRV_VERSION_WORD(1, 5);
  ------------------
  |  |   26|      0|  ((uint32_t(uint8_t(MAJOR)) << 16) | (uint32_t(uint8_t(MINOR)) << 8))
  ------------------
  120|      0|    case SPV_ENV_UNIVERSAL_1_6:
  ------------------
  |  Branch (120:5): [True: 0, False: 3.73M]
  ------------------
  121|      0|    case SPV_ENV_VULKAN_1_3:
  ------------------
  |  Branch (121:5): [True: 0, False: 3.73M]
  ------------------
  122|      0|      return SPV_SPIRV_VERSION_WORD(1, 6);
  ------------------
  |  |   26|      0|  ((uint32_t(uint8_t(MAJOR)) << 16) | (uint32_t(uint8_t(MINOR)) << 8))
  ------------------
  123|      0|    case SPV_ENV_MAX:
  ------------------
  |  Branch (123:5): [True: 0, False: 3.73M]
  ------------------
  124|      0|      assert(false && "Invalid target environment value.");
  125|      0|      break;
  126|  3.73M|  }
  127|      0|  return SPV_SPIRV_VERSION_WORD(0, 0);
  ------------------
  |  |   26|      0|  ((uint32_t(uint8_t(MAJOR)) << 16) | (uint32_t(uint8_t(MINOR)) << 8))
  ------------------
  128|  3.73M|}
_Z14spvIsVulkanEnv14spv_target_env:
  203|   197k|bool spvIsVulkanEnv(spv_target_env env) {
  204|   197k|  switch (env) {
  ------------------
  |  Branch (204:11): [True: 0, False: 197k]
  ------------------
  205|      0|    case SPV_ENV_UNIVERSAL_1_0:
  ------------------
  |  Branch (205:5): [True: 0, False: 197k]
  ------------------
  206|      0|    case SPV_ENV_OPENCL_1_2:
  ------------------
  |  Branch (206:5): [True: 0, False: 197k]
  ------------------
  207|      0|    case SPV_ENV_OPENCL_EMBEDDED_1_2:
  ------------------
  |  Branch (207:5): [True: 0, False: 197k]
  ------------------
  208|      0|    case SPV_ENV_OPENCL_2_0:
  ------------------
  |  Branch (208:5): [True: 0, False: 197k]
  ------------------
  209|      0|    case SPV_ENV_OPENCL_EMBEDDED_2_0:
  ------------------
  |  Branch (209:5): [True: 0, False: 197k]
  ------------------
  210|      0|    case SPV_ENV_OPENCL_2_1:
  ------------------
  |  Branch (210:5): [True: 0, False: 197k]
  ------------------
  211|      0|    case SPV_ENV_OPENCL_EMBEDDED_2_1:
  ------------------
  |  Branch (211:5): [True: 0, False: 197k]
  ------------------
  212|      0|    case SPV_ENV_OPENGL_4_0:
  ------------------
  |  Branch (212:5): [True: 0, False: 197k]
  ------------------
  213|   197k|    case SPV_ENV_OPENGL_4_1:
  ------------------
  |  Branch (213:5): [True: 197k, False: 0]
  ------------------
  214|   197k|    case SPV_ENV_OPENGL_4_2:
  ------------------
  |  Branch (214:5): [True: 0, False: 197k]
  ------------------
  215|   197k|    case SPV_ENV_OPENGL_4_3:
  ------------------
  |  Branch (215:5): [True: 0, False: 197k]
  ------------------
  216|   197k|    case SPV_ENV_OPENGL_4_5:
  ------------------
  |  Branch (216:5): [True: 0, False: 197k]
  ------------------
  217|   197k|    case SPV_ENV_UNIVERSAL_1_1:
  ------------------
  |  Branch (217:5): [True: 0, False: 197k]
  ------------------
  218|   197k|    case SPV_ENV_UNIVERSAL_1_2:
  ------------------
  |  Branch (218:5): [True: 0, False: 197k]
  ------------------
  219|   197k|    case SPV_ENV_OPENCL_2_2:
  ------------------
  |  Branch (219:5): [True: 0, False: 197k]
  ------------------
  220|   197k|    case SPV_ENV_OPENCL_EMBEDDED_2_2:
  ------------------
  |  Branch (220:5): [True: 0, False: 197k]
  ------------------
  221|   197k|    case SPV_ENV_UNIVERSAL_1_3:
  ------------------
  |  Branch (221:5): [True: 0, False: 197k]
  ------------------
  222|   197k|    case SPV_ENV_UNIVERSAL_1_4:
  ------------------
  |  Branch (222:5): [True: 0, False: 197k]
  ------------------
  223|   197k|    case SPV_ENV_UNIVERSAL_1_5:
  ------------------
  |  Branch (223:5): [True: 0, False: 197k]
  ------------------
  224|   197k|    case SPV_ENV_UNIVERSAL_1_6:
  ------------------
  |  Branch (224:5): [True: 0, False: 197k]
  ------------------
  225|   197k|      return false;
  226|      0|    case SPV_ENV_VULKAN_1_0:
  ------------------
  |  Branch (226:5): [True: 0, False: 197k]
  ------------------
  227|      0|    case SPV_ENV_VULKAN_1_1:
  ------------------
  |  Branch (227:5): [True: 0, False: 197k]
  ------------------
  228|      0|    case SPV_ENV_VULKAN_1_1_SPIRV_1_4:
  ------------------
  |  Branch (228:5): [True: 0, False: 197k]
  ------------------
  229|      0|    case SPV_ENV_VULKAN_1_2:
  ------------------
  |  Branch (229:5): [True: 0, False: 197k]
  ------------------
  230|      0|    case SPV_ENV_VULKAN_1_3:
  ------------------
  |  Branch (230:5): [True: 0, False: 197k]
  ------------------
  231|      0|      return true;
  232|      0|    case SPV_ENV_WEBGPU_0:
  ------------------
  |  Branch (232:5): [True: 0, False: 197k]
  ------------------
  233|      0|      assert(false && "Deprecated target environment value.");
  234|      0|      break;
  235|      0|    case SPV_ENV_MAX:
  ------------------
  |  Branch (235:5): [True: 0, False: 197k]
  ------------------
  236|      0|      assert(false && "Invalid target environment value.");
  237|      0|      break;
  238|   197k|  }
  239|      0|  return false;
  240|   197k|}
_Z14spvIsOpenCLEnv14spv_target_env:
  242|  3.96k|bool spvIsOpenCLEnv(spv_target_env env) {
  243|  3.96k|  switch (env) {
  ------------------
  |  Branch (243:11): [True: 0, False: 3.96k]
  ------------------
  244|      0|    case SPV_ENV_UNIVERSAL_1_0:
  ------------------
  |  Branch (244:5): [True: 0, False: 3.96k]
  ------------------
  245|      0|    case SPV_ENV_VULKAN_1_0:
  ------------------
  |  Branch (245:5): [True: 0, False: 3.96k]
  ------------------
  246|      0|    case SPV_ENV_UNIVERSAL_1_1:
  ------------------
  |  Branch (246:5): [True: 0, False: 3.96k]
  ------------------
  247|      0|    case SPV_ENV_OPENGL_4_0:
  ------------------
  |  Branch (247:5): [True: 0, False: 3.96k]
  ------------------
  248|  3.96k|    case SPV_ENV_OPENGL_4_1:
  ------------------
  |  Branch (248:5): [True: 3.96k, False: 0]
  ------------------
  249|  3.96k|    case SPV_ENV_OPENGL_4_2:
  ------------------
  |  Branch (249:5): [True: 0, False: 3.96k]
  ------------------
  250|  3.96k|    case SPV_ENV_OPENGL_4_3:
  ------------------
  |  Branch (250:5): [True: 0, False: 3.96k]
  ------------------
  251|  3.96k|    case SPV_ENV_OPENGL_4_5:
  ------------------
  |  Branch (251:5): [True: 0, False: 3.96k]
  ------------------
  252|  3.96k|    case SPV_ENV_UNIVERSAL_1_2:
  ------------------
  |  Branch (252:5): [True: 0, False: 3.96k]
  ------------------
  253|  3.96k|    case SPV_ENV_UNIVERSAL_1_3:
  ------------------
  |  Branch (253:5): [True: 0, False: 3.96k]
  ------------------
  254|  3.96k|    case SPV_ENV_VULKAN_1_1:
  ------------------
  |  Branch (254:5): [True: 0, False: 3.96k]
  ------------------
  255|  3.96k|    case SPV_ENV_UNIVERSAL_1_4:
  ------------------
  |  Branch (255:5): [True: 0, False: 3.96k]
  ------------------
  256|  3.96k|    case SPV_ENV_VULKAN_1_1_SPIRV_1_4:
  ------------------
  |  Branch (256:5): [True: 0, False: 3.96k]
  ------------------
  257|  3.96k|    case SPV_ENV_UNIVERSAL_1_5:
  ------------------
  |  Branch (257:5): [True: 0, False: 3.96k]
  ------------------
  258|  3.96k|    case SPV_ENV_VULKAN_1_2:
  ------------------
  |  Branch (258:5): [True: 0, False: 3.96k]
  ------------------
  259|  3.96k|    case SPV_ENV_UNIVERSAL_1_6:
  ------------------
  |  Branch (259:5): [True: 0, False: 3.96k]
  ------------------
  260|  3.96k|    case SPV_ENV_VULKAN_1_3:
  ------------------
  |  Branch (260:5): [True: 0, False: 3.96k]
  ------------------
  261|  3.96k|      return false;
  262|      0|    case SPV_ENV_OPENCL_1_2:
  ------------------
  |  Branch (262:5): [True: 0, False: 3.96k]
  ------------------
  263|      0|    case SPV_ENV_OPENCL_EMBEDDED_1_2:
  ------------------
  |  Branch (263:5): [True: 0, False: 3.96k]
  ------------------
  264|      0|    case SPV_ENV_OPENCL_2_0:
  ------------------
  |  Branch (264:5): [True: 0, False: 3.96k]
  ------------------
  265|      0|    case SPV_ENV_OPENCL_EMBEDDED_2_0:
  ------------------
  |  Branch (265:5): [True: 0, False: 3.96k]
  ------------------
  266|      0|    case SPV_ENV_OPENCL_EMBEDDED_2_1:
  ------------------
  |  Branch (266:5): [True: 0, False: 3.96k]
  ------------------
  267|      0|    case SPV_ENV_OPENCL_EMBEDDED_2_2:
  ------------------
  |  Branch (267:5): [True: 0, False: 3.96k]
  ------------------
  268|      0|    case SPV_ENV_OPENCL_2_1:
  ------------------
  |  Branch (268:5): [True: 0, False: 3.96k]
  ------------------
  269|      0|    case SPV_ENV_OPENCL_2_2:
  ------------------
  |  Branch (269:5): [True: 0, False: 3.96k]
  ------------------
  270|      0|      return true;
  271|      0|    case SPV_ENV_WEBGPU_0:
  ------------------
  |  Branch (271:5): [True: 0, False: 3.96k]
  ------------------
  272|      0|      assert(false && "Deprecated target environment value.");
  273|      0|      break;
  274|      0|    case SPV_ENV_MAX:
  ------------------
  |  Branch (274:5): [True: 0, False: 3.96k]
  ------------------
  275|      0|      assert(false && "Invalid target environment value.");
  276|      0|      break;
  277|  3.96k|  }
  278|      0|  return false;
  279|  3.96k|}
_Z14spvIsOpenGLEnv14spv_target_env:
  281|  2.30k|bool spvIsOpenGLEnv(spv_target_env env) {
  282|  2.30k|  switch (env) {
  ------------------
  |  Branch (282:11): [True: 0, False: 2.30k]
  ------------------
  283|      0|    case SPV_ENV_UNIVERSAL_1_0:
  ------------------
  |  Branch (283:5): [True: 0, False: 2.30k]
  ------------------
  284|      0|    case SPV_ENV_VULKAN_1_0:
  ------------------
  |  Branch (284:5): [True: 0, False: 2.30k]
  ------------------
  285|      0|    case SPV_ENV_UNIVERSAL_1_1:
  ------------------
  |  Branch (285:5): [True: 0, False: 2.30k]
  ------------------
  286|      0|    case SPV_ENV_UNIVERSAL_1_2:
  ------------------
  |  Branch (286:5): [True: 0, False: 2.30k]
  ------------------
  287|      0|    case SPV_ENV_UNIVERSAL_1_3:
  ------------------
  |  Branch (287:5): [True: 0, False: 2.30k]
  ------------------
  288|      0|    case SPV_ENV_VULKAN_1_1:
  ------------------
  |  Branch (288:5): [True: 0, False: 2.30k]
  ------------------
  289|      0|    case SPV_ENV_OPENCL_1_2:
  ------------------
  |  Branch (289:5): [True: 0, False: 2.30k]
  ------------------
  290|      0|    case SPV_ENV_OPENCL_EMBEDDED_1_2:
  ------------------
  |  Branch (290:5): [True: 0, False: 2.30k]
  ------------------
  291|      0|    case SPV_ENV_OPENCL_2_0:
  ------------------
  |  Branch (291:5): [True: 0, False: 2.30k]
  ------------------
  292|      0|    case SPV_ENV_OPENCL_EMBEDDED_2_0:
  ------------------
  |  Branch (292:5): [True: 0, False: 2.30k]
  ------------------
  293|      0|    case SPV_ENV_OPENCL_EMBEDDED_2_1:
  ------------------
  |  Branch (293:5): [True: 0, False: 2.30k]
  ------------------
  294|      0|    case SPV_ENV_OPENCL_EMBEDDED_2_2:
  ------------------
  |  Branch (294:5): [True: 0, False: 2.30k]
  ------------------
  295|      0|    case SPV_ENV_OPENCL_2_1:
  ------------------
  |  Branch (295:5): [True: 0, False: 2.30k]
  ------------------
  296|      0|    case SPV_ENV_OPENCL_2_2:
  ------------------
  |  Branch (296:5): [True: 0, False: 2.30k]
  ------------------
  297|      0|    case SPV_ENV_UNIVERSAL_1_4:
  ------------------
  |  Branch (297:5): [True: 0, False: 2.30k]
  ------------------
  298|      0|    case SPV_ENV_VULKAN_1_1_SPIRV_1_4:
  ------------------
  |  Branch (298:5): [True: 0, False: 2.30k]
  ------------------
  299|      0|    case SPV_ENV_UNIVERSAL_1_5:
  ------------------
  |  Branch (299:5): [True: 0, False: 2.30k]
  ------------------
  300|      0|    case SPV_ENV_VULKAN_1_2:
  ------------------
  |  Branch (300:5): [True: 0, False: 2.30k]
  ------------------
  301|      0|    case SPV_ENV_UNIVERSAL_1_6:
  ------------------
  |  Branch (301:5): [True: 0, False: 2.30k]
  ------------------
  302|      0|    case SPV_ENV_VULKAN_1_3:
  ------------------
  |  Branch (302:5): [True: 0, False: 2.30k]
  ------------------
  303|      0|      return false;
  304|      0|    case SPV_ENV_OPENGL_4_0:
  ------------------
  |  Branch (304:5): [True: 0, False: 2.30k]
  ------------------
  305|  2.30k|    case SPV_ENV_OPENGL_4_1:
  ------------------
  |  Branch (305:5): [True: 2.30k, False: 0]
  ------------------
  306|  2.30k|    case SPV_ENV_OPENGL_4_2:
  ------------------
  |  Branch (306:5): [True: 0, False: 2.30k]
  ------------------
  307|  2.30k|    case SPV_ENV_OPENGL_4_3:
  ------------------
  |  Branch (307:5): [True: 0, False: 2.30k]
  ------------------
  308|  2.30k|    case SPV_ENV_OPENGL_4_5:
  ------------------
  |  Branch (308:5): [True: 0, False: 2.30k]
  ------------------
  309|  2.30k|      return true;
  310|      0|    case SPV_ENV_WEBGPU_0:
  ------------------
  |  Branch (310:5): [True: 0, False: 2.30k]
  ------------------
  311|      0|      assert(false && "Deprecated target environment value.");
  312|      0|      break;
  313|      0|    case SPV_ENV_MAX:
  ------------------
  |  Branch (313:5): [True: 0, False: 2.30k]
  ------------------
  314|      0|      assert(false && "Invalid target environment value.");
  315|      0|      break;
  316|  2.30k|  }
  317|      0|  return false;
  318|  2.30k|}
_Z13spvIsValidEnv14spv_target_env:
  320|  8.24k|bool spvIsValidEnv(spv_target_env env) {
  321|  8.24k|  switch (env) {
  ------------------
  |  Branch (321:11): [True: 0, False: 8.24k]
  ------------------
  322|      0|    case SPV_ENV_UNIVERSAL_1_0:
  ------------------
  |  Branch (322:5): [True: 0, False: 8.24k]
  ------------------
  323|      0|    case SPV_ENV_VULKAN_1_0:
  ------------------
  |  Branch (323:5): [True: 0, False: 8.24k]
  ------------------
  324|      0|    case SPV_ENV_UNIVERSAL_1_1:
  ------------------
  |  Branch (324:5): [True: 0, False: 8.24k]
  ------------------
  325|      0|    case SPV_ENV_UNIVERSAL_1_2:
  ------------------
  |  Branch (325:5): [True: 0, False: 8.24k]
  ------------------
  326|      0|    case SPV_ENV_UNIVERSAL_1_3:
  ------------------
  |  Branch (326:5): [True: 0, False: 8.24k]
  ------------------
  327|      0|    case SPV_ENV_VULKAN_1_1:
  ------------------
  |  Branch (327:5): [True: 0, False: 8.24k]
  ------------------
  328|      0|    case SPV_ENV_OPENCL_1_2:
  ------------------
  |  Branch (328:5): [True: 0, False: 8.24k]
  ------------------
  329|      0|    case SPV_ENV_OPENCL_EMBEDDED_1_2:
  ------------------
  |  Branch (329:5): [True: 0, False: 8.24k]
  ------------------
  330|      0|    case SPV_ENV_OPENCL_2_0:
  ------------------
  |  Branch (330:5): [True: 0, False: 8.24k]
  ------------------
  331|      0|    case SPV_ENV_OPENCL_EMBEDDED_2_0:
  ------------------
  |  Branch (331:5): [True: 0, False: 8.24k]
  ------------------
  332|      0|    case SPV_ENV_OPENCL_EMBEDDED_2_1:
  ------------------
  |  Branch (332:5): [True: 0, False: 8.24k]
  ------------------
  333|      0|    case SPV_ENV_OPENCL_EMBEDDED_2_2:
  ------------------
  |  Branch (333:5): [True: 0, False: 8.24k]
  ------------------
  334|      0|    case SPV_ENV_OPENCL_2_1:
  ------------------
  |  Branch (334:5): [True: 0, False: 8.24k]
  ------------------
  335|      0|    case SPV_ENV_OPENCL_2_2:
  ------------------
  |  Branch (335:5): [True: 0, False: 8.24k]
  ------------------
  336|      0|    case SPV_ENV_UNIVERSAL_1_4:
  ------------------
  |  Branch (336:5): [True: 0, False: 8.24k]
  ------------------
  337|      0|    case SPV_ENV_VULKAN_1_1_SPIRV_1_4:
  ------------------
  |  Branch (337:5): [True: 0, False: 8.24k]
  ------------------
  338|      0|    case SPV_ENV_UNIVERSAL_1_5:
  ------------------
  |  Branch (338:5): [True: 0, False: 8.24k]
  ------------------
  339|      0|    case SPV_ENV_VULKAN_1_2:
  ------------------
  |  Branch (339:5): [True: 0, False: 8.24k]
  ------------------
  340|      0|    case SPV_ENV_UNIVERSAL_1_6:
  ------------------
  |  Branch (340:5): [True: 0, False: 8.24k]
  ------------------
  341|      0|    case SPV_ENV_VULKAN_1_3:
  ------------------
  |  Branch (341:5): [True: 0, False: 8.24k]
  ------------------
  342|      0|    case SPV_ENV_OPENGL_4_0:
  ------------------
  |  Branch (342:5): [True: 0, False: 8.24k]
  ------------------
  343|  8.24k|    case SPV_ENV_OPENGL_4_1:
  ------------------
  |  Branch (343:5): [True: 8.24k, False: 0]
  ------------------
  344|  8.24k|    case SPV_ENV_OPENGL_4_2:
  ------------------
  |  Branch (344:5): [True: 0, False: 8.24k]
  ------------------
  345|  8.24k|    case SPV_ENV_OPENGL_4_3:
  ------------------
  |  Branch (345:5): [True: 0, False: 8.24k]
  ------------------
  346|  8.24k|    case SPV_ENV_OPENGL_4_5:
  ------------------
  |  Branch (346:5): [True: 0, False: 8.24k]
  ------------------
  347|  8.24k|      return true;
  348|      0|    case SPV_ENV_WEBGPU_0:
  ------------------
  |  Branch (348:5): [True: 0, False: 8.24k]
  ------------------
  349|      0|    case SPV_ENV_MAX:
  ------------------
  |  Branch (349:5): [True: 0, False: 8.24k]
  ------------------
  350|      0|      break;
  351|  8.24k|  }
  352|      0|  return false;
  353|  8.24k|}

spvValidatorOptionsCreate:
   51|  8.24k|spv_validator_options spvValidatorOptionsCreate(void) {
   52|  8.24k|  return new spv_validator_options_t;
   53|  8.24k|}
spvValidatorOptionsDestroy:
   55|  8.24k|void spvValidatorOptionsDestroy(spv_validator_options options) {
   56|  8.24k|  delete options;
   57|  8.24k|}

_ZN23spv_validator_options_tC2Ev:
   52|  8.24k|        use_friendly_names(true) {}

spvContextCreate:
   19|  12.6k|spv_context spvContextCreate(spv_target_env env) {
   20|  12.6k|  switch (env) {
   21|      0|    case SPV_ENV_UNIVERSAL_1_0:
  ------------------
  |  Branch (21:5): [True: 0, False: 12.6k]
  ------------------
   22|      0|    case SPV_ENV_VULKAN_1_0:
  ------------------
  |  Branch (22:5): [True: 0, False: 12.6k]
  ------------------
   23|      0|    case SPV_ENV_UNIVERSAL_1_1:
  ------------------
  |  Branch (23:5): [True: 0, False: 12.6k]
  ------------------
   24|      0|    case SPV_ENV_OPENCL_1_2:
  ------------------
  |  Branch (24:5): [True: 0, False: 12.6k]
  ------------------
   25|      0|    case SPV_ENV_OPENCL_EMBEDDED_1_2:
  ------------------
  |  Branch (25:5): [True: 0, False: 12.6k]
  ------------------
   26|      0|    case SPV_ENV_OPENCL_2_0:
  ------------------
  |  Branch (26:5): [True: 0, False: 12.6k]
  ------------------
   27|      0|    case SPV_ENV_OPENCL_EMBEDDED_2_0:
  ------------------
  |  Branch (27:5): [True: 0, False: 12.6k]
  ------------------
   28|      0|    case SPV_ENV_OPENCL_2_1:
  ------------------
  |  Branch (28:5): [True: 0, False: 12.6k]
  ------------------
   29|      0|    case SPV_ENV_OPENCL_EMBEDDED_2_1:
  ------------------
  |  Branch (29:5): [True: 0, False: 12.6k]
  ------------------
   30|      0|    case SPV_ENV_OPENCL_2_2:
  ------------------
  |  Branch (30:5): [True: 0, False: 12.6k]
  ------------------
   31|      0|    case SPV_ENV_OPENCL_EMBEDDED_2_2:
  ------------------
  |  Branch (31:5): [True: 0, False: 12.6k]
  ------------------
   32|      0|    case SPV_ENV_OPENGL_4_0:
  ------------------
  |  Branch (32:5): [True: 0, False: 12.6k]
  ------------------
   33|  12.6k|    case SPV_ENV_OPENGL_4_1:
  ------------------
  |  Branch (33:5): [True: 12.6k, False: 0]
  ------------------
   34|  12.6k|    case SPV_ENV_OPENGL_4_2:
  ------------------
  |  Branch (34:5): [True: 0, False: 12.6k]
  ------------------
   35|  12.6k|    case SPV_ENV_OPENGL_4_3:
  ------------------
  |  Branch (35:5): [True: 0, False: 12.6k]
  ------------------
   36|  12.6k|    case SPV_ENV_OPENGL_4_5:
  ------------------
  |  Branch (36:5): [True: 0, False: 12.6k]
  ------------------
   37|  12.6k|    case SPV_ENV_UNIVERSAL_1_2:
  ------------------
  |  Branch (37:5): [True: 0, False: 12.6k]
  ------------------
   38|  12.6k|    case SPV_ENV_UNIVERSAL_1_3:
  ------------------
  |  Branch (38:5): [True: 0, False: 12.6k]
  ------------------
   39|  12.6k|    case SPV_ENV_VULKAN_1_1:
  ------------------
  |  Branch (39:5): [True: 0, False: 12.6k]
  ------------------
   40|  12.6k|    case SPV_ENV_VULKAN_1_1_SPIRV_1_4:
  ------------------
  |  Branch (40:5): [True: 0, False: 12.6k]
  ------------------
   41|  12.6k|    case SPV_ENV_UNIVERSAL_1_4:
  ------------------
  |  Branch (41:5): [True: 0, False: 12.6k]
  ------------------
   42|  12.6k|    case SPV_ENV_UNIVERSAL_1_5:
  ------------------
  |  Branch (42:5): [True: 0, False: 12.6k]
  ------------------
   43|  12.6k|    case SPV_ENV_VULKAN_1_2:
  ------------------
  |  Branch (43:5): [True: 0, False: 12.6k]
  ------------------
   44|  12.6k|    case SPV_ENV_UNIVERSAL_1_6:
  ------------------
  |  Branch (44:5): [True: 0, False: 12.6k]
  ------------------
   45|  12.6k|    case SPV_ENV_VULKAN_1_3:
  ------------------
  |  Branch (45:5): [True: 0, False: 12.6k]
  ------------------
   46|  12.6k|      break;
   47|      0|    default:
  ------------------
  |  Branch (47:5): [True: 0, False: 12.6k]
  ------------------
   48|      0|      return nullptr;
   49|  12.6k|  }
   50|       |
   51|  12.6k|  spv_opcode_table opcode_table;
   52|  12.6k|  spv_operand_table operand_table;
   53|  12.6k|  spv_ext_inst_table ext_inst_table;
   54|       |
   55|  12.6k|  spvOpcodeTableGet(&opcode_table, env);
   56|  12.6k|  spvOperandTableGet(&operand_table, env);
   57|  12.6k|  spvExtInstTableGet(&ext_inst_table, env);
   58|       |
   59|  12.6k|  return new spv_context_t{env, opcode_table, operand_table, ext_inst_table,
   60|  12.6k|                           nullptr /* a null default consumer */};
   61|  12.6k|}
spvContextDestroy:
   63|  12.6k|void spvContextDestroy(spv_context context) { delete context; }
_ZN8spvtools25SetContextMessageConsumerEP13spv_context_tNSt3__18functionIFv19spv_message_level_tPKcRK14spv_position_tS6_EEE:
   66|  20.9k|                                         spvtools::MessageConsumer consumer) {
   67|  20.9k|  context->consumer = std::move(consumer);
   68|  20.9k|}

spvTextDestroy:
  846|  4.45k|void spvTextDestroy(spv_text text) {
  847|  4.45k|  if (text) {
  ------------------
  |  Branch (847:7): [True: 4.45k, False: 0]
  ------------------
  848|  4.45k|    if (text->str) delete[] text->str;
  ------------------
  |  Branch (848:9): [True: 4.45k, False: 0]
  ------------------
  849|  4.45k|    delete text;
  850|  4.45k|  }
  851|  4.45k|}

_ZN8spvtools5utils11BitwiseCastIfjEET_T0_:
   28|  6.81k|Dest BitwiseCast(Src source) {
   29|  6.81k|  Dest dest;
   30|  6.81k|  static_assert(sizeof(source) == sizeof(dest),
   31|  6.81k|                "BitwiseCast: Source and destination must have the same size");
   32|  6.81k|  std::memcpy(&dest, &source, sizeof(dest));
   33|  6.81k|  return dest;
   34|  6.81k|}
_ZN8spvtools5utils11BitwiseCastIdmEET_T0_:
   28|    145|Dest BitwiseCast(Src source) {
   29|    145|  Dest dest;
   30|    145|  static_assert(sizeof(source) == sizeof(dest),
   31|    145|                "BitwiseCast: Source and destination must have the same size");
   32|    145|  std::memcpy(&dest, &source, sizeof(dest));
   33|    145|  return dest;
   34|    145|}
_ZN8spvtools5utils12CountSetBitsIjEEmT_:
   97|    373|size_t CountSetBits(T word) {
   98|    373|  static_assert(std::is_integral<T>::value,
   99|    373|                "CountSetBits requires integer type");
  100|    373|  size_t count = 0;
  101|    546|  while (word) {
  ------------------
  |  Branch (101:10): [True: 173, False: 373]
  ------------------
  102|    173|    word &= word - 1;
  103|    173|    ++count;
  104|    173|  }
  105|    373|  return count;
  106|    373|}

_ZN8spvtools5utils16FloatProxyTraitsIfE10getAsFloatERKj:
   82|  6.81k|  static float getAsFloat(const uint_type& t) { return BitwiseCast<float>(t); }
_ZN8spvtools5utils16FloatProxyTraitsIdE10getAsFloatERKm:
  102|    145|  static double getAsFloat(const uint_type& t) {
  103|    145|    return BitwiseCast<double>(t);
  104|    145|  }
_ZN8spvtools5utilslsINS0_7Float16EEERNSt3__113basic_ostreamIcNS3_11char_traitsIcEEEES8_RKNS0_10FloatProxyIT_EE:
 1251|    162|                                         const FloatProxy<Float16>& value) {
 1252|    162|  os << HexFloat<FloatProxy<Float16>>(value);
 1253|    162|  return os;
 1254|    162|}
_ZNK8spvtools5utils10FloatProxyIfE4dataEv:
  161|    755|  uint_type data() const { return data_; }
_ZNK8spvtools5utils10FloatProxyIfE10getAsFloatEv:
  158|  6.81k|  T getAsFloat() const { return FloatProxyTraits<T>::getAsFloat(data_); }
_ZNK8spvtools5utils8HexFloatINS0_10FloatProxyINS0_7Float16EEENS0_14HexFloatTraitsIS4_EEE5valueEv:
  297|    162|  T value() const { return value_; }
_ZNK8spvtools5utils10FloatProxyINS0_7Float16EE4dataEv:
  161|    162|  uint_type data() const { return data_; }
_ZN8spvtools5utilslsINS0_10FloatProxyINS0_7Float16EEENS0_14HexFloatTraitsIS4_EEEERNSt3__113basic_ostreamIcNS7_11char_traitsIcEEEESC_RKNS0_8HexFloatIT_T0_EE:
  739|    162|std::ostream& operator<<(std::ostream& os, const HexFloat<T, Traits>& value) {
  740|    162|  using HF = HexFloat<T, Traits>;
  741|    162|  using uint_type = typename HF::uint_type;
  742|    162|  using int_type = typename HF::int_type;
  743|       |
  744|    162|  static_assert(HF::num_used_bits != 0,
  745|    162|                "num_used_bits must be non-zero for a valid float");
  746|    162|  static_assert(HF::num_exponent_bits != 0,
  747|    162|                "num_exponent_bits must be non-zero for a valid float");
  748|    162|  static_assert(HF::num_fraction_bits != 0,
  749|    162|                "num_fractin_bits must be non-zero for a valid float");
  750|       |
  751|    162|  const uint_type bits = value.value().data();
  752|    162|  const char* const sign = (bits & HF::sign_mask) ? "-" : "";
  ------------------
  |  Branch (752:28): [True: 26, False: 136]
  ------------------
  753|    162|  const uint_type exponent = static_cast<uint_type>(
  754|    162|      (bits & HF::exponent_mask) >> HF::num_fraction_bits);
  755|       |
  756|    162|  uint_type fraction = static_cast<uint_type>((bits & HF::fraction_encode_mask)
  757|    162|                                              << HF::num_overflow_bits);
  758|       |
  759|    162|  const bool is_zero = exponent == 0 && fraction == 0;
  ------------------
  |  Branch (759:24): [True: 107, False: 55]
  |  Branch (759:41): [True: 76, False: 31]
  ------------------
  760|    162|  const bool is_denorm = exponent == 0 && !is_zero;
  ------------------
  |  Branch (760:26): [True: 107, False: 55]
  |  Branch (760:43): [True: 31, False: 76]
  ------------------
  761|       |
  762|       |  // exponent contains the biased exponent we have to convert it back into
  763|       |  // the normal range.
  764|    162|  int_type int_exponent = static_cast<int_type>(exponent - HF::exponent_bias);
  765|       |  // If the number is all zeros, then we actually have to NOT shift the
  766|       |  // exponent.
  767|    162|  int_exponent = is_zero ? 0 : int_exponent;
  ------------------
  |  Branch (767:18): [True: 76, False: 86]
  ------------------
  768|       |
  769|       |  // If we are denorm, then start shifting, and decreasing the exponent until
  770|       |  // our leading bit is 1.
  771|       |
  772|    162|  if (is_denorm) {
  ------------------
  |  Branch (772:7): [True: 31, False: 131]
  ------------------
  773|    218|    while ((fraction & HF::fraction_top_bit) == 0) {
  ------------------
  |  Branch (773:12): [True: 187, False: 31]
  ------------------
  774|    187|      fraction = static_cast<uint_type>(fraction << 1);
  775|    187|      int_exponent = static_cast<int_type>(int_exponent - 1);
  776|    187|    }
  777|       |    // Since this is denormalized, we have to consume the leading 1 since it
  778|       |    // will end up being implicit.
  779|     31|    fraction = static_cast<uint_type>(fraction << 1);  // eat the leading 1
  780|     31|    fraction &= HF::fraction_represent_mask;
  781|     31|  }
  782|       |
  783|    162|  uint_type fraction_nibbles = HF::fraction_nibbles;
  784|       |  // We do not have to display any trailing 0s, since this represents the
  785|       |  // fractional part.
  786|    532|  while (fraction_nibbles > 0 && (fraction & 0xF) == 0) {
  ------------------
  |  Branch (786:10): [True: 425, False: 107]
  |  Branch (786:34): [True: 370, False: 55]
  ------------------
  787|       |    // Shift off any trailing values;
  788|    370|    fraction = static_cast<uint_type>(fraction >> 4);
  789|    370|    --fraction_nibbles;
  790|    370|  }
  791|       |
  792|    162|  const auto saved_flags = os.flags();
  793|    162|  const auto saved_fill = os.fill();
  794|       |
  795|    162|  os << sign << "0x" << (is_zero ? '0' : '1');
  ------------------
  |  Branch (795:26): [True: 76, False: 86]
  ------------------
  796|    162|  if (fraction_nibbles) {
  ------------------
  |  Branch (796:7): [True: 55, False: 107]
  ------------------
  797|       |    // Make sure to keep the leading 0s in place, since this is the fractional
  798|       |    // part.
  799|     55|    os << "." << std::setw(static_cast<int>(fraction_nibbles))
  800|     55|       << std::setfill('0') << std::hex << fraction;
  801|     55|  }
  802|    162|  os << "p" << std::dec << (int_exponent >= 0 ? "+" : "") << int_exponent;
  ------------------
  |  Branch (802:29): [True: 104, False: 58]
  ------------------
  803|       |
  804|    162|  os.flags(saved_flags);
  805|    162|  os.fill(saved_fill);
  806|       |
  807|    162|  return os;
  808|    162|}
_ZN8spvtools5utils8HexFloatINS0_10FloatProxyIfEENS0_14HexFloatTraitsIS3_EEEC2ES3_:
  295|    755|  explicit HexFloat(T f) : value_(f) {}
_ZN8spvtools5utils8HexFloatINS0_10FloatProxyINS0_7Float16EEENS0_14HexFloatTraitsIS4_EEEC2ES4_:
  295|    162|  explicit HexFloat(T f) : value_(f) {}
_ZN8spvtools5utils10FloatProxyINS0_7Float16EEC2Et:
  149|    162|  FloatProxy(uint_type val) { data_ = val; }
_ZN8spvtools5utils10FloatProxyIfEC2Ej:
  149|  6.81k|  FloatProxy(uint_type val) { data_ = val; }
_ZN8spvtools5utils8HexFloatINS0_10FloatProxyIdEENS0_14HexFloatTraitsIS3_EEEC2ES3_:
  295|    113|  explicit HexFloat(T f) : value_(f) {}
_ZNK8spvtools5utils10FloatProxyIdE4dataEv:
  161|    113|  uint_type data() const { return data_; }
_ZNK8spvtools5utils10FloatProxyIdE10getAsFloatEv:
  158|    145|  T getAsFloat() const { return FloatProxyTraits<T>::getAsFloat(data_); }
_ZN8spvtools5utils10FloatProxyIdEC2Em:
  149|    145|  FloatProxy(uint_type val) { data_ = val; }
_ZN8spvtools5utilslsIfEERNSt3__113basic_ostreamIcNS2_11char_traitsIcEEEES7_RKNS0_10FloatProxyIT_EE:
 1232|  6.81k|std::ostream& operator<<(std::ostream& os, const FloatProxy<T>& value) {
 1233|  6.81k|  auto float_val = value.getAsFloat();
 1234|  6.81k|  switch (std::fpclassify(float_val)) {
 1235|    525|    case FP_ZERO:
  ------------------
  |  Branch (1235:5): [True: 525, False: 6.28k]
  ------------------
 1236|  6.05k|    case FP_NORMAL: {
  ------------------
  |  Branch (1236:5): [True: 5.53k, False: 1.28k]
  ------------------
 1237|  6.05k|      auto saved_precision = os.precision();
 1238|  6.05k|      os.precision(std::numeric_limits<T>::max_digits10);
 1239|  6.05k|      os << float_val;
 1240|  6.05k|      os.precision(saved_precision);
 1241|  6.05k|    } break;
 1242|    755|    default:
  ------------------
  |  Branch (1242:5): [True: 755, False: 6.05k]
  ------------------
 1243|    755|      os << HexFloat<FloatProxy<T>>(value);
 1244|    755|      break;
 1245|  6.81k|  }
 1246|  6.81k|  return os;
 1247|  6.81k|}
_ZN8spvtools5utilslsINS0_10FloatProxyIfEENS0_14HexFloatTraitsIS3_EEEERNSt3__113basic_ostreamIcNS6_11char_traitsIcEEEESB_RKNS0_8HexFloatIT_T0_EE:
  739|    755|std::ostream& operator<<(std::ostream& os, const HexFloat<T, Traits>& value) {
  740|    755|  using HF = HexFloat<T, Traits>;
  741|    755|  using uint_type = typename HF::uint_type;
  742|    755|  using int_type = typename HF::int_type;
  743|       |
  744|    755|  static_assert(HF::num_used_bits != 0,
  745|    755|                "num_used_bits must be non-zero for a valid float");
  746|    755|  static_assert(HF::num_exponent_bits != 0,
  747|    755|                "num_exponent_bits must be non-zero for a valid float");
  748|    755|  static_assert(HF::num_fraction_bits != 0,
  749|    755|                "num_fractin_bits must be non-zero for a valid float");
  750|       |
  751|    755|  const uint_type bits = value.value().data();
  752|    755|  const char* const sign = (bits & HF::sign_mask) ? "-" : "";
  ------------------
  |  Branch (752:28): [True: 197, False: 558]
  ------------------
  753|    755|  const uint_type exponent = static_cast<uint_type>(
  754|    755|      (bits & HF::exponent_mask) >> HF::num_fraction_bits);
  755|       |
  756|    755|  uint_type fraction = static_cast<uint_type>((bits & HF::fraction_encode_mask)
  757|    755|                                              << HF::num_overflow_bits);
  758|       |
  759|    755|  const bool is_zero = exponent == 0 && fraction == 0;
  ------------------
  |  Branch (759:24): [True: 649, False: 106]
  |  Branch (759:41): [True: 0, False: 649]
  ------------------
  760|    755|  const bool is_denorm = exponent == 0 && !is_zero;
  ------------------
  |  Branch (760:26): [True: 649, False: 106]
  |  Branch (760:43): [True: 649, False: 0]
  ------------------
  761|       |
  762|       |  // exponent contains the biased exponent we have to convert it back into
  763|       |  // the normal range.
  764|    755|  int_type int_exponent = static_cast<int_type>(exponent - HF::exponent_bias);
  765|       |  // If the number is all zeros, then we actually have to NOT shift the
  766|       |  // exponent.
  767|    755|  int_exponent = is_zero ? 0 : int_exponent;
  ------------------
  |  Branch (767:18): [True: 0, False: 755]
  ------------------
  768|       |
  769|       |  // If we are denorm, then start shifting, and decreasing the exponent until
  770|       |  // our leading bit is 1.
  771|       |
  772|    755|  if (is_denorm) {
  ------------------
  |  Branch (772:7): [True: 649, False: 106]
  ------------------
  773|  6.83k|    while ((fraction & HF::fraction_top_bit) == 0) {
  ------------------
  |  Branch (773:12): [True: 6.18k, False: 649]
  ------------------
  774|  6.18k|      fraction = static_cast<uint_type>(fraction << 1);
  775|  6.18k|      int_exponent = static_cast<int_type>(int_exponent - 1);
  776|  6.18k|    }
  777|       |    // Since this is denormalized, we have to consume the leading 1 since it
  778|       |    // will end up being implicit.
  779|    649|    fraction = static_cast<uint_type>(fraction << 1);  // eat the leading 1
  780|    649|    fraction &= HF::fraction_represent_mask;
  781|    649|  }
  782|       |
  783|    755|  uint_type fraction_nibbles = HF::fraction_nibbles;
  784|       |  // We do not have to display any trailing 0s, since this represents the
  785|       |  // fractional part.
  786|  3.25k|  while (fraction_nibbles > 0 && (fraction & 0xF) == 0) {
  ------------------
  |  Branch (786:10): [True: 3.17k, False: 79]
  |  Branch (786:34): [True: 2.49k, False: 676]
  ------------------
  787|       |    // Shift off any trailing values;
  788|  2.49k|    fraction = static_cast<uint_type>(fraction >> 4);
  789|  2.49k|    --fraction_nibbles;
  790|  2.49k|  }
  791|       |
  792|    755|  const auto saved_flags = os.flags();
  793|    755|  const auto saved_fill = os.fill();
  794|       |
  795|    755|  os << sign << "0x" << (is_zero ? '0' : '1');
  ------------------
  |  Branch (795:26): [True: 0, False: 755]
  ------------------
  796|    755|  if (fraction_nibbles) {
  ------------------
  |  Branch (796:7): [True: 676, False: 79]
  ------------------
  797|       |    // Make sure to keep the leading 0s in place, since this is the fractional
  798|       |    // part.
  799|    676|    os << "." << std::setw(static_cast<int>(fraction_nibbles))
  800|    676|       << std::setfill('0') << std::hex << fraction;
  801|    676|  }
  802|    755|  os << "p" << std::dec << (int_exponent >= 0 ? "+" : "") << int_exponent;
  ------------------
  |  Branch (802:29): [True: 106, False: 649]
  ------------------
  803|       |
  804|    755|  os.flags(saved_flags);
  805|    755|  os.fill(saved_fill);
  806|       |
  807|    755|  return os;
  808|    755|}
_ZNK8spvtools5utils8HexFloatINS0_10FloatProxyIfEENS0_14HexFloatTraitsIS3_EEE5valueEv:
  297|    755|  T value() const { return value_; }
_ZN8spvtools5utilslsIdEERNSt3__113basic_ostreamIcNS2_11char_traitsIcEEEES7_RKNS0_10FloatProxyIT_EE:
 1232|    145|std::ostream& operator<<(std::ostream& os, const FloatProxy<T>& value) {
 1233|    145|  auto float_val = value.getAsFloat();
 1234|    145|  switch (std::fpclassify(float_val)) {
 1235|     11|    case FP_ZERO:
  ------------------
  |  Branch (1235:5): [True: 11, False: 134]
  ------------------
 1236|     32|    case FP_NORMAL: {
  ------------------
  |  Branch (1236:5): [True: 21, False: 124]
  ------------------
 1237|     32|      auto saved_precision = os.precision();
 1238|     32|      os.precision(std::numeric_limits<T>::max_digits10);
 1239|     32|      os << float_val;
 1240|     32|      os.precision(saved_precision);
 1241|     32|    } break;
 1242|    113|    default:
  ------------------
  |  Branch (1242:5): [True: 113, False: 32]
  ------------------
 1243|    113|      os << HexFloat<FloatProxy<T>>(value);
 1244|    113|      break;
 1245|    145|  }
 1246|    145|  return os;
 1247|    145|}
_ZN8spvtools5utilslsINS0_10FloatProxyIdEENS0_14HexFloatTraitsIS3_EEEERNSt3__113basic_ostreamIcNS6_11char_traitsIcEEEESB_RKNS0_8HexFloatIT_T0_EE:
  739|    113|std::ostream& operator<<(std::ostream& os, const HexFloat<T, Traits>& value) {
  740|    113|  using HF = HexFloat<T, Traits>;
  741|    113|  using uint_type = typename HF::uint_type;
  742|    113|  using int_type = typename HF::int_type;
  743|       |
  744|    113|  static_assert(HF::num_used_bits != 0,
  745|    113|                "num_used_bits must be non-zero for a valid float");
  746|    113|  static_assert(HF::num_exponent_bits != 0,
  747|    113|                "num_exponent_bits must be non-zero for a valid float");
  748|    113|  static_assert(HF::num_fraction_bits != 0,
  749|    113|                "num_fractin_bits must be non-zero for a valid float");
  750|       |
  751|    113|  const uint_type bits = value.value().data();
  752|    113|  const char* const sign = (bits & HF::sign_mask) ? "-" : "";
  ------------------
  |  Branch (752:28): [True: 60, False: 53]
  ------------------
  753|    113|  const uint_type exponent = static_cast<uint_type>(
  754|    113|      (bits & HF::exponent_mask) >> HF::num_fraction_bits);
  755|       |
  756|    113|  uint_type fraction = static_cast<uint_type>((bits & HF::fraction_encode_mask)
  757|    113|                                              << HF::num_overflow_bits);
  758|       |
  759|    113|  const bool is_zero = exponent == 0 && fraction == 0;
  ------------------
  |  Branch (759:24): [True: 55, False: 58]
  |  Branch (759:41): [True: 0, False: 55]
  ------------------
  760|    113|  const bool is_denorm = exponent == 0 && !is_zero;
  ------------------
  |  Branch (760:26): [True: 55, False: 58]
  |  Branch (760:43): [True: 55, False: 0]
  ------------------
  761|       |
  762|       |  // exponent contains the biased exponent we have to convert it back into
  763|       |  // the normal range.
  764|    113|  int_type int_exponent = static_cast<int_type>(exponent - HF::exponent_bias);
  765|       |  // If the number is all zeros, then we actually have to NOT shift the
  766|       |  // exponent.
  767|    113|  int_exponent = is_zero ? 0 : int_exponent;
  ------------------
  |  Branch (767:18): [True: 0, False: 113]
  ------------------
  768|       |
  769|       |  // If we are denorm, then start shifting, and decreasing the exponent until
  770|       |  // our leading bit is 1.
  771|       |
  772|    113|  if (is_denorm) {
  ------------------
  |  Branch (772:7): [True: 55, False: 58]
  ------------------
  773|    525|    while ((fraction & HF::fraction_top_bit) == 0) {
  ------------------
  |  Branch (773:12): [True: 470, False: 55]
  ------------------
  774|    470|      fraction = static_cast<uint_type>(fraction << 1);
  775|    470|      int_exponent = static_cast<int_type>(int_exponent - 1);
  776|    470|    }
  777|       |    // Since this is denormalized, we have to consume the leading 1 since it
  778|       |    // will end up being implicit.
  779|     55|    fraction = static_cast<uint_type>(fraction << 1);  // eat the leading 1
  780|     55|    fraction &= HF::fraction_represent_mask;
  781|     55|  }
  782|       |
  783|    113|  uint_type fraction_nibbles = HF::fraction_nibbles;
  784|       |  // We do not have to display any trailing 0s, since this represents the
  785|       |  // fractional part.
  786|    490|  while (fraction_nibbles > 0 && (fraction & 0xF) == 0) {
  ------------------
  |  Branch (786:10): [True: 474, False: 16]
  |  Branch (786:34): [True: 377, False: 97]
  ------------------
  787|       |    // Shift off any trailing values;
  788|    377|    fraction = static_cast<uint_type>(fraction >> 4);
  789|    377|    --fraction_nibbles;
  790|    377|  }
  791|       |
  792|    113|  const auto saved_flags = os.flags();
  793|    113|  const auto saved_fill = os.fill();
  794|       |
  795|    113|  os << sign << "0x" << (is_zero ? '0' : '1');
  ------------------
  |  Branch (795:26): [True: 0, False: 113]
  ------------------
  796|    113|  if (fraction_nibbles) {
  ------------------
  |  Branch (796:7): [True: 97, False: 16]
  ------------------
  797|       |    // Make sure to keep the leading 0s in place, since this is the fractional
  798|       |    // part.
  799|     97|    os << "." << std::setw(static_cast<int>(fraction_nibbles))
  800|     97|       << std::setfill('0') << std::hex << fraction;
  801|     97|  }
  802|    113|  os << "p" << std::dec << (int_exponent >= 0 ? "+" : "") << int_exponent;
  ------------------
  |  Branch (802:29): [True: 58, False: 55]
  ------------------
  803|       |
  804|    113|  os.flags(saved_flags);
  805|    113|  os.fill(saved_fill);
  806|       |
  807|    113|  return os;
  808|    113|}
_ZNK8spvtools5utils8HexFloatINS0_10FloatProxyIdEENS0_14HexFloatTraitsIS3_EEE5valueEv:
  297|    113|  T value() const { return value_; }

_ZN8spvtools10MakeUniqueINSt3__13setIjNS1_4lessIjEENS1_9allocatorIjEEEEJEEENS1_10unique_ptrIT_NS1_14default_deleteIS9_EEEEDpOT0_:
   24|  2.73k|std::unique_ptr<T> MakeUnique(Args&&... args) {
   25|  2.73k|  return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
   26|  2.73k|}
_ZN8spvtools10MakeUniqueINS_18FriendlyNameMapperEJRKPK13spv_context_tRPKjRKmEEENSt3__110unique_ptrIT_NSC_14default_deleteISE_EEEEDpOT0_:
   24|  8.24k|std::unique_ptr<T> MakeUnique(Args&&... args) {
   25|  8.24k|  return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
   26|  8.24k|}
_ZN8spvtools10MakeUniqueINS_18FriendlyNameMapperEJRP13spv_context_tRPKjRKmEEENSt3__110unique_ptrIT_NSA_14default_deleteISC_EEEEDpOT0_:
   24|  4.45k|std::unique_ptr<T> MakeUnique(Args&&... args) {
   25|  4.45k|  return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
   26|  4.45k|}

_ZN8spvtools5utils17CardinalToOrdinalEm:
   24|     52|std::string CardinalToOrdinal(size_t cardinal) {
   25|     52|  const size_t mod10 = cardinal % 10;
   26|     52|  const size_t mod100 = cardinal % 100;
   27|     52|  std::string suffix;
   28|     52|  if (mod10 == 1 && mod100 != 11)
  ------------------
  |  Branch (28:7): [True: 49, False: 3]
  |  Branch (28:21): [True: 49, False: 0]
  ------------------
   29|     49|    suffix = "st";
   30|      3|  else if (mod10 == 2 && mod100 != 12)
  ------------------
  |  Branch (30:12): [True: 1, False: 2]
  |  Branch (30:26): [True: 1, False: 0]
  ------------------
   31|      1|    suffix = "nd";
   32|      2|  else if (mod10 == 3 && mod100 != 13)
  ------------------
  |  Branch (32:12): [True: 1, False: 1]
  |  Branch (32:26): [True: 1, False: 0]
  ------------------
   33|      1|    suffix = "rd";
   34|      1|  else
   35|      1|    suffix = "th";
   36|       |
   37|     52|  return ToString(cardinal) + suffix;
   38|     52|}

_ZN8spvtools5utils10MakeStringEPKjmb:
  119|   168k|                              bool assert_found_terminating_null = true) {
  120|   168k|  return MakeString(words, words + num_words, assert_found_terminating_null);
  121|   168k|}
_ZN8spvtools5utils10MakeStringIPKjEENSt3__112basic_stringIcNS4_11char_traitsIcEENS4_9allocatorIcEEEET_SB_b:
   84|   168k|                              bool assert_found_terminating_null = true) {
   85|   168k|  std::string result;
   86|   168k|  constexpr size_t kCharsPerWord = sizeof(*first);
   87|   168k|  static_assert(kCharsPerWord == 4, "expect 4-byte word");
   88|       |
   89|  1.43M|  for (InputIt pos = first; pos != last; ++pos) {
  ------------------
  |  Branch (89:29): [True: 1.43M, False: 32]
  ------------------
   90|  1.43M|    uint32_t word = *pos;
   91|  6.59M|    for (size_t byte_index = 0; byte_index < kCharsPerWord; byte_index++) {
  ------------------
  |  Branch (91:33): [True: 5.32M, False: 1.26M]
  ------------------
   92|  5.32M|      uint32_t extracted_word = (word >> (8 * byte_index)) & 0xFF;
   93|  5.32M|      char c = static_cast<char>(extracted_word);
   94|  5.32M|      if (c == 0) {
  ------------------
  |  Branch (94:11): [True: 168k, False: 5.15M]
  ------------------
   95|   168k|        return result;
   96|   168k|      }
   97|  5.15M|      result += c;
   98|  5.15M|    }
   99|  1.43M|  }
  100|     32|  assert(!assert_found_terminating_null &&
  101|     32|         "Did not find terminating null for the string.");
  102|      0|  (void)assert_found_terminating_null; /* No unused parameters in release
  103|       |                                          builds. */
  104|     32|  return result;
  105|   168k|}
_ZN8spvtools5utils8ToStringImEENSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEET_:
   32|     52|std::string ToString(T val) {
   33|     52|  static_assert(
   34|     52|      std::is_arithmetic<T>::value,
   35|     52|      "spvtools::utils::ToString is restricted to only arithmetic values");
   36|     52|  std::stringstream os;
   37|     52|  os << val;
   38|     52|  return os.str();
   39|     52|}

_ZN8spvtools3val10BasicBlockC2Ej:
   35|   185k|      terminator_(nullptr) {}
_ZN8spvtools3val10BasicBlock21SetImmediateDominatorEPS1_:
   37|  26.1k|void BasicBlock::SetImmediateDominator(BasicBlock* dom_block) {
   38|  26.1k|  immediate_dominator_ = dom_block;
   39|  26.1k|}
_ZN8spvtools3val10BasicBlock31SetImmediateStructuralDominatorEPS1_:
   41|  30.0k|void BasicBlock::SetImmediateStructuralDominator(BasicBlock* dom_block) {
   42|  30.0k|  immediate_structural_dominator_ = dom_block;
   43|  30.0k|}
_ZN8spvtools3val10BasicBlock35SetImmediateStructuralPostDominatorEPS1_:
   45|  37.4k|void BasicBlock::SetImmediateStructuralPostDominator(BasicBlock* pdom_block) {
   46|  37.4k|  immediate_structural_post_dominator_ = pdom_block;
   47|  37.4k|}
_ZNK8spvtools3val10BasicBlock19immediate_dominatorEv:
   49|   123k|const BasicBlock* BasicBlock::immediate_dominator() const {
   50|   123k|  return immediate_dominator_;
   51|   123k|}
_ZNK8spvtools3val10BasicBlock30immediate_structural_dominatorEv:
   53|  2.18M|const BasicBlock* BasicBlock::immediate_structural_dominator() const {
   54|  2.18M|  return immediate_structural_dominator_;
   55|  2.18M|}
_ZNK8spvtools3val10BasicBlock35immediate_structural_post_dominatorEv:
   57|  18.3k|const BasicBlock* BasicBlock::immediate_structural_post_dominator() const {
   58|  18.3k|  return immediate_structural_post_dominator_;
   59|  18.3k|}
_ZN8spvtools3val10BasicBlock19immediate_dominatorEv:
   61|  67.4k|BasicBlock* BasicBlock::immediate_dominator() { return immediate_dominator_; }
_ZN8spvtools3val10BasicBlock18RegisterSuccessorsERKNSt3__16vectorIPS1_NS2_9allocatorIS4_EEEE:
   70|  50.1k|    const std::vector<BasicBlock*>& next_blocks) {
   71|  70.5k|  for (auto& block : next_blocks) {
  ------------------
  |  Branch (71:20): [True: 70.5k, False: 50.1k]
  ------------------
   72|  70.5k|    block->predecessors_.push_back(this);
   73|  70.5k|    successors_.push_back(block);
   74|       |
   75|       |    // Register structural successors/predecessors too.
   76|  70.5k|    block->structural_predecessors_.push_back(this);
   77|  70.5k|    structural_successors_.push_back(block);
   78|  70.5k|  }
   79|  50.1k|}
_ZNK8spvtools3val10BasicBlock9dominatesERKS1_:
   81|  50.6k|bool BasicBlock::dominates(const BasicBlock& other) const {
   82|  50.6k|  return (this == &other) ||
  ------------------
  |  Branch (82:10): [True: 43.1k, False: 7.52k]
  ------------------
   83|  50.6k|         !(other.dom_end() ==
  ------------------
  |  Branch (83:10): [True: 7.47k, False: 47]
  ------------------
   84|  7.52k|           std::find(other.dom_begin(), other.dom_end(), this));
   85|  50.6k|}
_ZNK8spvtools3val10BasicBlock22structurally_dominatesERKS1_:
   87|   185k|bool BasicBlock::structurally_dominates(const BasicBlock& other) const {
   88|   185k|  return (this == &other) || !(other.structural_dom_end() ==
  ------------------
  |  Branch (88:10): [True: 23.5k, False: 161k]
  |  Branch (88:30): [True: 80.9k, False: 81.0k]
  ------------------
   89|   161k|                               std::find(other.structural_dom_begin(),
   90|   161k|                                         other.structural_dom_end(), this));
   91|   185k|}
_ZNK8spvtools3val10BasicBlock26structurally_postdominatesERKS1_:
   93|  4.64k|bool BasicBlock::structurally_postdominates(const BasicBlock& other) const {
   94|  4.64k|  return (this == &other) || !(other.structural_pdom_end() ==
  ------------------
  |  Branch (94:10): [True: 2.75k, False: 1.88k]
  |  Branch (94:30): [True: 1.80k, False: 74]
  ------------------
   95|  1.88k|                               std::find(other.structural_pdom_begin(),
   96|  1.88k|                                         other.structural_pdom_end(), this));
   97|  4.64k|}
_ZN8spvtools3val10BasicBlock17DominatorIteratorC2Ev:
   99|   342k|BasicBlock::DominatorIterator::DominatorIterator() : current_(nullptr) {}
_ZN8spvtools3val10BasicBlock17DominatorIteratorC2EPKS1_NSt3__18functionIFS4_S4_EEE:
  104|   171k|    : current_(block), dom_func_(dominator_func) {}
_ZN8spvtools3val10BasicBlock17DominatorIteratorppEv:
  106|  1.15M|BasicBlock::DominatorIterator& BasicBlock::DominatorIterator::operator++() {
  107|  1.15M|  if (current_ == dom_func_(current_)) {
  ------------------
  |  Branch (107:7): [True: 74, False: 1.15M]
  ------------------
  108|     74|    current_ = nullptr;
  109|  1.15M|  } else {
  110|  1.15M|    current_ = dom_func_(current_);
  111|  1.15M|  }
  112|  1.15M|  return *this;
  113|  1.15M|}
_ZNK8spvtools3val10BasicBlock9dom_beginEv:
  115|  7.52k|const BasicBlock::DominatorIterator BasicBlock::dom_begin() const {
  116|  7.52k|  return DominatorIterator(
  117|  7.52k|      this, [](const BasicBlock* b) { return b->immediate_dominator(); });
  118|  7.52k|}
_ZNK8spvtools3val10BasicBlock7dom_endEv:
  125|  15.0k|const BasicBlock::DominatorIterator BasicBlock::dom_end() const {
  126|  15.0k|  return DominatorIterator();
  127|  15.0k|}
_ZNK8spvtools3val10BasicBlock20structural_dom_beginEv:
  133|   161k|const BasicBlock::DominatorIterator BasicBlock::structural_dom_begin() const {
  134|   161k|  return DominatorIterator(this, [](const BasicBlock* b) {
  135|   161k|    return b->immediate_structural_dominator();
  136|   161k|  });
  137|   161k|}
_ZNK8spvtools3val10BasicBlock18structural_dom_endEv:
  145|   323k|const BasicBlock::DominatorIterator BasicBlock::structural_dom_end() const {
  146|   323k|  return DominatorIterator();
  147|   323k|}
_ZNK8spvtools3val10BasicBlock21structural_pdom_beginEv:
  153|  1.88k|const BasicBlock::DominatorIterator BasicBlock::structural_pdom_begin() const {
  154|  1.88k|  return DominatorIterator(this, [](const BasicBlock* b) {
  155|  1.88k|    return b->immediate_structural_post_dominator();
  156|  1.88k|  });
  157|  1.88k|}
_ZNK8spvtools3val10BasicBlock19structural_pdom_endEv:
  165|  3.76k|const BasicBlock::DominatorIterator BasicBlock::structural_pdom_end() const {
  166|  3.76k|  return DominatorIterator();
  167|  3.76k|}
_ZN8spvtools3valeqERKNS0_10BasicBlock17DominatorIteratorES4_:
  174|  1.50M|                const BasicBlock::DominatorIterator& rhs) {
  175|  1.50M|  return lhs.current_ == rhs.current_;
  176|  1.50M|}
_ZN8spvtools3valneERKNS0_10BasicBlock17DominatorIteratorES4_:
  179|  1.33M|                const BasicBlock::DominatorIterator& rhs) {
  180|  1.33M|  return !(lhs == rhs);
  181|  1.33M|}
_ZN8spvtools3val10BasicBlock17DominatorIteratordeEv:
  183|  1.24M|const BasicBlock*& BasicBlock::DominatorIterator::operator*() {
  184|  1.24M|  return current_;
  185|  1.24M|}
basic_block.cpp:_ZZNK8spvtools3val10BasicBlock9dom_beginEvENK3$_0clEPKS1_:
  117|   123k|      this, [](const BasicBlock* b) { return b->immediate_dominator(); });
basic_block.cpp:_ZZNK8spvtools3val10BasicBlock20structural_dom_beginEvENK3$_2clEPKS1_:
  134|  2.17M|  return DominatorIterator(this, [](const BasicBlock* b) {
  135|  2.17M|    return b->immediate_structural_dominator();
  136|  2.17M|  });
basic_block.cpp:_ZZNK8spvtools3val10BasicBlock21structural_pdom_beginEvENK3$_4clEPKS1_:
  154|  18.3k|  return DominatorIterator(this, [](const BasicBlock* b) {
  155|  18.3k|    return b->immediate_structural_post_dominator();
  156|  18.3k|  });

_ZN8spvtools3val10BasicBlock14set_terminatorEPKNS0_11InstructionE:
  155|  50.1k|  void set_terminator(const Instruction* t) { terminator_ = t; }
_ZNK8spvtools3val10BasicBlock2idEv:
   51|  3.85M|  uint32_t id() const { return id_; }
_ZNK8spvtools3val10BasicBlock12predecessorsEv:
   54|  73.1k|  const std::vector<BasicBlock*>* predecessors() const {
   55|  73.1k|    return &predecessors_;
   56|  73.1k|  }
_ZN8spvtools3val10BasicBlock12predecessorsEv:
   59|  31.5k|  std::vector<BasicBlock*>* predecessors() { return &predecessors_; }
_ZNK8spvtools3val10BasicBlock10successorsEv:
   62|  90.9k|  const std::vector<BasicBlock*>* successors() const { return &successors_; }
_ZN8spvtools3val10BasicBlock10successorsEv:
   65|  81.5k|  std::vector<BasicBlock*>* successors() { return &successors_; }
_ZNK8spvtools3val10BasicBlock23structural_predecessorsEv:
   73|  1.06M|  const std::vector<BasicBlock*>* structural_predecessors() const {
   74|  1.06M|    return &structural_predecessors_;
   75|  1.06M|  }
_ZN8spvtools3val10BasicBlock21structural_successorsEv:
   78|  77.3k|  std::vector<BasicBlock*>* structural_successors() {
   79|  77.3k|    return &structural_successors_;
   80|  77.3k|  }
_ZNK8spvtools3val10BasicBlock21structural_successorsEv:
   83|   852k|  const std::vector<BasicBlock*>* structural_successors() const {
   84|   852k|    return &structural_successors_;
   85|   852k|  }
_ZNK8spvtools3val10BasicBlock9reachableEv:
   88|  99.0k|  bool reachable() const { return reachable_; }
_ZNK8spvtools3val10BasicBlock22structurally_reachableEv:
   91|   164k|  bool structurally_reachable() const { return structurally_reachable_; }
_ZNK8spvtools3val10BasicBlock7is_typeENS0_9BlockTypeE:
   94|   198k|  bool is_type(BlockType type) const {
   95|   198k|    if (type == kBlockTypeUndefined) return type_.none();
  ------------------
  |  Branch (95:9): [True: 0, False: 198k]
  ------------------
   96|   198k|    return type_.test(type);
   97|   198k|  }
_ZN8spvtools3val10BasicBlock13set_reachableEb:
  100|  32.6k|  void set_reachable(bool reachability) { reachable_ = reachability; }
_ZN8spvtools3val10BasicBlock26set_structurally_reachableEb:
  103|  38.4k|  void set_structurally_reachable(bool reachability) {
  104|  38.4k|    structurally_reachable_ = reachability;
  105|  38.4k|  }
_ZN8spvtools3val10BasicBlock8set_typeENS0_9BlockTypeE:
  108|  86.9k|  void set_type(BlockType type) {
  109|  86.9k|    if (type == kBlockTypeUndefined)
  ------------------
  |  Branch (109:9): [True: 0, False: 86.9k]
  ------------------
  110|      0|      type_.reset();
  111|  86.9k|    else
  112|  86.9k|      type_.set(type);
  113|  86.9k|  }
_ZNK8spvtools3val10BasicBlock5labelEv:
  149|  7.75k|  const Instruction* label() const { return label_; }
_ZN8spvtools3val10BasicBlock9set_labelEPKNS0_11InstructionE:
  152|  50.8k|  void set_label(const Instruction* t) { label_ = t; }
_ZNK8spvtools3val10BasicBlock10terminatorEv:
  158|  41.9k|  const Instruction* terminator() const { return terminator_; }
_ZNK8spvtools3val10BasicBlockeqERKj:
  168|  70.7k|  bool operator==(const uint32_t& other_id) const { return other_id == id_; }
_ZN8spvtools3val10BasicBlock27RegisterStructuralSuccessorEPS1_:
  182|  54.5k|  void RegisterStructuralSuccessor(BasicBlock* block) {
  183|  54.5k|    block->structural_predecessors_.push_back(this);
  184|  54.5k|    structural_successors_.push_back(block);
  185|  54.5k|  }

_ZN8spvtools3val9ConstructC2ENS0_13ConstructTypeEPNS0_10BasicBlockES4_NSt3__16vectorIPS1_NS5_9allocatorIS7_EEEE:
   32|  54.5k|      exit_block_(exit) {}
_ZNK8spvtools3val9Construct4typeEv:
   34|   309k|ConstructType Construct::type() const { return type_; }
_ZNK8spvtools3val9Construct24corresponding_constructsEv:
   36|  2.97k|const std::vector<Construct*>& Construct::corresponding_constructs() const {
   37|  2.97k|  return corresponding_constructs_;
   38|  2.97k|}
_ZN8spvtools3val9Construct24corresponding_constructsEv:
   39|  11.4k|std::vector<Construct*>& Construct::corresponding_constructs() {
   40|  11.4k|  return corresponding_constructs_;
   41|  11.4k|}
_ZN8spvtools3val21ValidateConstructSizeENS0_13ConstructTypeEm:
   43|  44.3k|bool ValidateConstructSize(ConstructType type, size_t size) {
   44|  44.3k|  switch (type) {
   45|      0|    case ConstructType::kSelection:
  ------------------
  |  Branch (45:5): [True: 0, False: 44.3k]
  ------------------
   46|      0|      return size == 0;
   47|  22.1k|    case ConstructType::kContinue:
  ------------------
  |  Branch (47:5): [True: 22.1k, False: 22.1k]
  ------------------
   48|  22.1k|      return size == 1;
   49|  22.1k|    case ConstructType::kLoop:
  ------------------
  |  Branch (49:5): [True: 22.1k, False: 22.1k]
  ------------------
   50|  22.1k|      return size == 1;
   51|      0|    case ConstructType::kCase:
  ------------------
  |  Branch (51:5): [True: 0, False: 44.3k]
  ------------------
   52|      0|      return size >= 1;
   53|      0|    default:
  ------------------
  |  Branch (53:5): [True: 0, False: 44.3k]
  ------------------
   54|      0|      assert(1 == 0 && "Type not defined");
   55|  44.3k|  }
   56|      0|  return false;
   57|  44.3k|}
_ZN8spvtools3val9Construct28set_corresponding_constructsENSt3__16vectorIPS1_NS2_9allocatorIS4_EEEE:
   60|  44.3k|    std::vector<Construct*> constructs) {
   61|  44.3k|  assert(ValidateConstructSize(type_, constructs.size()));
   62|      0|  corresponding_constructs_ = constructs;
   63|  44.3k|}
_ZNK8spvtools3val9Construct11entry_blockEv:
   65|  75.6k|const BasicBlock* Construct::entry_block() const { return entry_block_; }
_ZN8spvtools3val9Construct11entry_blockEv:
   66|  54.5k|BasicBlock* Construct::entry_block() { return entry_block_; }
_ZNK8spvtools3val9Construct10exit_blockEv:
   68|  20.0k|const BasicBlock* Construct::exit_block() const { return exit_block_; }
_ZN8spvtools3val9Construct8set_exitEPNS0_10BasicBlockE:
   71|  3.97k|void Construct::set_exit(BasicBlock* block) { exit_block_ = block; }
_ZNK8spvtools3val9Construct6blocksEPNS0_8FunctionE:
   73|  6.11k|Construct::ConstructBlockSet Construct::blocks(Function* /*function*/) const {
   74|  6.11k|  const auto header = entry_block();
   75|  6.11k|  const auto exit = exit_block();
   76|  6.11k|  const bool is_continue = type() == ConstructType::kContinue;
   77|  6.11k|  const bool is_loop = type() == ConstructType::kLoop;
   78|  6.11k|  const BasicBlock* continue_header = nullptr;
   79|  6.11k|  if (is_loop) {
  ------------------
  |  Branch (79:7): [True: 1.48k, False: 4.63k]
  ------------------
   80|       |    // The only corresponding construct for a loop is the continue.
   81|  1.48k|    continue_header = (*corresponding_constructs().begin())->entry_block();
   82|  1.48k|  }
   83|  6.11k|  std::vector<BasicBlock*> stack;
   84|  6.11k|  stack.push_back(const_cast<BasicBlock*>(header));
   85|  6.11k|  ConstructBlockSet construct_blocks;
   86|  81.5k|  while (!stack.empty()) {
  ------------------
  |  Branch (86:10): [True: 75.4k, False: 6.11k]
  ------------------
   87|  75.4k|    auto* block = stack.back();
   88|  75.4k|    stack.pop_back();
   89|       |
   90|  75.4k|    if (header->structurally_dominates(*block)) {
  ------------------
  |  Branch (90:9): [True: 69.6k, False: 5.77k]
  ------------------
   91|  69.6k|      bool include = false;
   92|  69.6k|      if (is_continue && exit->structurally_postdominates(*block)) {
  ------------------
  |  Branch (92:11): [True: 3.24k, False: 66.4k]
  |  Branch (92:26): [True: 3.18k, False: 62]
  ------------------
   93|       |        // Continue construct include blocks dominated by the continue target
   94|       |        // and post-dominated by the back-edge block.
   95|  3.18k|        include = true;
   96|  66.5k|      } else if (!exit->structurally_dominates(*block)) {
  ------------------
  |  Branch (96:18): [True: 55.8k, False: 10.6k]
  ------------------
   97|       |        // Selection and loop constructs include blocks dominated by the header
   98|       |        // and not dominated by the merge.
   99|  55.8k|        include = true;
  100|  55.8k|        if (is_loop && continue_header->structurally_dominates(*block)) {
  ------------------
  |  Branch (100:13): [True: 18.4k, False: 37.3k]
  |  Branch (100:24): [True: 3.62k, False: 14.8k]
  ------------------
  101|       |          // Loop constructs have an additional constraint that they do not
  102|       |          // include blocks dominated by the continue construct. Since all
  103|       |          // blocks in the continue construct are dominated by the continue
  104|       |          // target, we just test for dominance by continue target.
  105|  3.62k|          include = false;
  106|  3.62k|        }
  107|  55.8k|      }
  108|  69.6k|      if (include) {
  ------------------
  |  Branch (108:11): [True: 55.4k, False: 14.2k]
  ------------------
  109|  55.4k|        if (!construct_blocks.insert(block).second) continue;
  ------------------
  |  Branch (109:13): [True: 16.4k, False: 38.9k]
  ------------------
  110|       |
  111|  69.3k|        for (auto succ : *block->structural_successors()) {
  ------------------
  |  Branch (111:24): [True: 69.3k, False: 38.9k]
  ------------------
  112|  69.3k|          stack.push_back(succ);
  113|  69.3k|        }
  114|  38.9k|      }
  115|  69.6k|    }
  116|  75.4k|  }
  117|       |
  118|  6.11k|  return construct_blocks;
  119|  6.11k|}
_ZNK8spvtools3val9Construct16IsStructuredExitERNS0_17ValidationState_tEPNS0_10BasicBlockE:
  121|  13.6k|bool Construct::IsStructuredExit(ValidationState_t& _, BasicBlock* dest) const {
  122|       |  // Structured Exits:
  123|       |  // - Selection:
  124|       |  //  - branch to its merge
  125|       |  //  - branch to nearest enclosing loop merge or continue
  126|       |  //  - branch to nearest enclosing switch selection merge
  127|       |  // - Loop:
  128|       |  //  - branch to its merge
  129|       |  //  - branch to its continue
  130|       |  // - Continue:
  131|       |  //  - branch to loop header
  132|       |  //  - branch to loop merge
  133|       |  //
  134|       |  // Note: we will never see a case construct here.
  135|  13.6k|  assert(type() != ConstructType::kCase);
  136|  13.6k|  if (type() == ConstructType::kLoop) {
  ------------------
  |  Branch (136:7): [True: 4.41k, False: 9.27k]
  ------------------
  137|  4.41k|    auto header = entry_block();
  138|  4.41k|    auto terminator = header->terminator();
  139|  4.41k|    auto index = terminator - &_.ordered_instructions()[0];
  140|  4.41k|    auto merge_inst = &_.ordered_instructions()[index - 1];
  141|  4.41k|    auto merge_block_id = merge_inst->GetOperandAs<uint32_t>(0u);
  142|  4.41k|    auto continue_block_id = merge_inst->GetOperandAs<uint32_t>(1u);
  143|  4.41k|    if (dest->id() == merge_block_id || dest->id() == continue_block_id) {
  ------------------
  |  Branch (143:9): [True: 2.27k, False: 2.14k]
  |  Branch (143:41): [True: 2.12k, False: 12]
  ------------------
  144|  4.40k|      return true;
  145|  4.40k|    }
  146|  9.27k|  } else if (type() == ConstructType::kContinue) {
  ------------------
  |  Branch (146:14): [True: 1.49k, False: 7.78k]
  ------------------
  147|  1.49k|    auto loop_construct = corresponding_constructs()[0];
  148|  1.49k|    auto header = loop_construct->entry_block();
  149|  1.49k|    auto terminator = header->terminator();
  150|  1.49k|    auto index = terminator - &_.ordered_instructions()[0];
  151|  1.49k|    auto merge_inst = &_.ordered_instructions()[index - 1];
  152|  1.49k|    auto merge_block_id = merge_inst->GetOperandAs<uint32_t>(0u);
  153|  1.49k|    if (dest == header || dest->id() == merge_block_id) {
  ------------------
  |  Branch (153:9): [True: 1.34k, False: 144]
  |  Branch (153:27): [True: 140, False: 4]
  ------------------
  154|  1.48k|      return true;
  155|  1.48k|    }
  156|  7.78k|  } else {
  157|  7.78k|    assert(type() == ConstructType::kSelection);
  158|  7.78k|    if (dest == exit_block()) {
  ------------------
  |  Branch (158:9): [True: 3.61k, False: 4.17k]
  ------------------
  159|  3.61k|      return true;
  160|  3.61k|    }
  161|       |
  162|       |    // The next block in the traversal is either:
  163|       |    //  i.  The header block that declares |block| as its merge block.
  164|       |    //  ii. The immediate dominator of |block|.
  165|  4.17k|    auto NextBlock = [](const BasicBlock* block) -> const BasicBlock* {
  166|  4.17k|      for (auto& use : block->label()->uses()) {
  167|  4.17k|        if ((use.first->opcode() == spv::Op::OpLoopMerge ||
  168|  4.17k|             use.first->opcode() == spv::Op::OpSelectionMerge) &&
  169|  4.17k|            use.second == 1 &&
  170|  4.17k|            use.first->block()->structurally_dominates(*block) &&
  171|       |            // A header likely declared itself as its merge.
  172|  4.17k|            use.first->block() != block) {
  173|  4.17k|          return use.first->block();
  174|  4.17k|        }
  175|  4.17k|      }
  176|  4.17k|      return block->immediate_structural_dominator();
  177|  4.17k|    };
  178|       |
  179|  4.17k|    bool seen_switch = false;
  180|  4.17k|    auto header = entry_block();
  181|  4.17k|    auto block = NextBlock(header);
  182|  7.66k|    while (block) {
  ------------------
  |  Branch (182:12): [True: 7.65k, False: 8]
  ------------------
  183|  7.65k|      auto terminator = block->terminator();
  184|  7.65k|      auto index = terminator - &_.ordered_instructions()[0];
  185|  7.65k|      auto merge_inst = &_.ordered_instructions()[index - 1];
  186|  7.65k|      if (merge_inst->opcode() == spv::Op::OpLoopMerge ||
  ------------------
  |  Branch (186:11): [True: 4.03k, False: 3.62k]
  ------------------
  187|  7.65k|          (header->terminator()->opcode() != spv::Op::OpSwitch &&
  ------------------
  |  Branch (187:12): [True: 3.40k, False: 221]
  ------------------
  188|  3.62k|           merge_inst->opcode() == spv::Op::OpSelectionMerge &&
  ------------------
  |  Branch (188:12): [True: 2.79k, False: 601]
  ------------------
  189|  4.87k|           terminator->opcode() == spv::Op::OpSwitch)) {
  ------------------
  |  Branch (189:12): [True: 841, False: 1.95k]
  ------------------
  190|  4.87k|        auto merge_target = merge_inst->GetOperandAs<uint32_t>(0u);
  191|  4.87k|        auto merge_block = merge_inst->function()->GetBlock(merge_target).first;
  192|  4.87k|        if (merge_block->structurally_dominates(*header)) {
  ------------------
  |  Branch (192:13): [True: 701, False: 4.17k]
  ------------------
  193|    701|          block = NextBlock(block);
  194|    701|          continue;
  195|    701|        }
  196|       |
  197|  4.17k|        if ((!seen_switch || merge_inst->opcode() == spv::Op::OpLoopMerge) &&
  ------------------
  |  Branch (197:14): [True: 4.16k, False: 12]
  |  Branch (197:30): [True: 11, False: 1]
  ------------------
  198|  4.17k|            dest->id() == merge_target) {
  ------------------
  |  Branch (198:13): [True: 2.43k, False: 1.74k]
  ------------------
  199|  2.43k|          return true;
  200|  2.43k|        } else if (merge_inst->opcode() == spv::Op::OpLoopMerge) {
  ------------------
  |  Branch (200:20): [True: 1.73k, False: 14]
  ------------------
  201|  1.73k|          auto continue_target = merge_inst->GetOperandAs<uint32_t>(1u);
  202|  1.73k|          if (dest->id() == continue_target) {
  ------------------
  |  Branch (202:15): [True: 1.70k, False: 26]
  ------------------
  203|  1.70k|            return true;
  204|  1.70k|          }
  205|  1.73k|        }
  206|       |
  207|     40|        if (terminator->opcode() == spv::Op::OpSwitch) {
  ------------------
  |  Branch (207:13): [True: 14, False: 26]
  ------------------
  208|     14|          seen_switch = true;
  209|     14|        }
  210|       |
  211|       |        // Hit an enclosing loop and didn't break or continue.
  212|     40|        if (merge_inst->opcode() == spv::Op::OpLoopMerge) return false;
  ------------------
  |  Branch (212:13): [True: 26, False: 14]
  ------------------
  213|     40|      }
  214|       |
  215|  2.79k|      block = NextBlock(block);
  216|  2.79k|    }
  217|  4.17k|  }
  218|       |
  219|     24|  return false;
  220|  13.6k|}
construct.cpp:_ZZNK8spvtools3val9Construct16IsStructuredExitERNS0_17ValidationState_tEPNS0_10BasicBlockEENK3$_0clEPKS4_:
  165|  7.66k|    auto NextBlock = [](const BasicBlock* block) -> const BasicBlock* {
  166|  9.85k|      for (auto& use : block->label()->uses()) {
  ------------------
  |  Branch (166:22): [True: 9.85k, False: 6.59k]
  ------------------
  167|  9.85k|        if ((use.first->opcode() == spv::Op::OpLoopMerge ||
  ------------------
  |  Branch (167:14): [True: 572, False: 9.28k]
  ------------------
  168|  9.85k|             use.first->opcode() == spv::Op::OpSelectionMerge) &&
  ------------------
  |  Branch (168:14): [True: 618, False: 8.66k]
  ------------------
  169|  9.85k|            use.second == 1 &&
  ------------------
  |  Branch (169:13): [True: 1.15k, False: 34]
  ------------------
  170|  9.85k|            use.first->block()->structurally_dominates(*block) &&
  ------------------
  |  Branch (170:13): [True: 1.08k, False: 74]
  ------------------
  171|       |            // A header likely declared itself as its merge.
  172|  9.85k|            use.first->block() != block) {
  ------------------
  |  Branch (172:13): [True: 1.07k, False: 9]
  ------------------
  173|  1.07k|          return use.first->block();
  174|  1.07k|        }
  175|  9.85k|      }
  176|  6.59k|      return block->immediate_structural_dominator();
  177|  7.66k|    };

_ZNK8spvtools3val12less_than_idclEPKNS0_10BasicBlockES4_:
   30|   881k|  bool operator()(const BasicBlock* lhs, const BasicBlock* rhs) const {
   31|   881k|    return lhs->id() < rhs->id();
   32|   881k|  }
_ZNK8spvtools3val9Construct21ExitBlockIsMergeBlockEv:
  102|  6.13k|  bool ExitBlockIsMergeBlock() const {
  103|  6.13k|    return type_ == ConstructType::kLoop || type_ == ConstructType::kSelection;
  ------------------
  |  Branch (103:12): [True: 1.48k, False: 4.64k]
  |  Branch (103:45): [True: 3.25k, False: 1.39k]
  ------------------
  104|  6.13k|  }

_ZN8spvtools3val10DecorationC2EN3spv10DecorationERKNSt3__16vectorIjNS4_9allocatorIjEEEEj:
   64|  15.0k|      : dec_type_(t), params_(parameters), struct_member_index_(member_index) {}
_ZN8spvtools3val10Decoration23set_struct_member_indexEj:
   66|  1.53k|  void set_struct_member_index(uint32_t index) { struct_member_index_ = index; }
_ZNK8spvtools3val10Decoration19struct_member_indexEv:
   67|  1.26k|  int struct_member_index() const { return struct_member_index_; }
_ZNK8spvtools3val10Decoration8dec_typeEv:
   68|  40.4k|  spv::Decoration dec_type() const { return dec_type_; }
_ZNK8spvtools3val10Decoration6paramsEv:
   70|    439|  const std::vector<uint32_t>& params() const { return params_; }
_ZNK8spvtools3val10DecorationltERKS1_:
   72|   240k|  inline bool operator<(const Decoration& rhs) const {
   73|       |    // Note: Sort by struct_member_index_ first, then type, so look up can be
   74|       |    // efficient using lower_bound() and upper_bound().
   75|   240k|    if (struct_member_index_ < rhs.struct_member_index_) return true;
  ------------------
  |  Branch (75:9): [True: 2.88k, False: 237k]
  ------------------
   76|   237k|    if (rhs.struct_member_index_ < struct_member_index_) return false;
  ------------------
  |  Branch (76:9): [True: 3.14k, False: 234k]
  ------------------
   77|   234k|    if (dec_type_ < rhs.dec_type_) return true;
  ------------------
  |  Branch (77:9): [True: 47.3k, False: 186k]
  ------------------
   78|   186k|    if (rhs.dec_type_ < dec_type_) return false;
  ------------------
  |  Branch (78:9): [True: 39.8k, False: 147k]
  ------------------
   79|   147k|    return params_ < rhs.params_;
   80|   186k|  }

_ZN8spvtools3val8FunctionC2EjjN3spv19FunctionControlMaskEj:
   50|  4.78k|      parameter_ids_() {}
_ZNK8spvtools3val8Function12IsFirstBlockEj:
   52|  70.7k|bool Function::IsFirstBlock(uint32_t block_id) const {
   53|  70.7k|  return !ordered_blocks_.empty() && *first_block() == block_id;
  ------------------
  |  Branch (53:10): [True: 70.7k, False: 0]
  |  Branch (53:38): [True: 5, False: 70.7k]
  ------------------
   54|  70.7k|}
_ZN8spvtools3val8Function25RegisterFunctionParameterEjj:
   57|    734|                                                 uint32_t type_id) {
   58|    734|  assert(current_block_ == nullptr &&
   59|    734|         "RegisterFunctionParameter can only be called when parsing the binary "
   60|    734|         "outside of a block");
   61|       |  // TODO(umar): Validate function parameter type order and count
   62|       |  // TODO(umar): Use these variables to validate parameter type
   63|      0|  (void)parameter_id;
   64|    734|  (void)type_id;
   65|    734|  return SPV_SUCCESS;
   66|    734|}
_ZN8spvtools3val8Function17RegisterLoopMergeEjj:
   69|  22.1k|                                         uint32_t continue_id) {
   70|  22.1k|  RegisterBlock(merge_id, false);
   71|  22.1k|  RegisterBlock(continue_id, false);
   72|  22.1k|  BasicBlock& merge_block = blocks_.at(merge_id);
   73|  22.1k|  BasicBlock& continue_target_block = blocks_.at(continue_id);
   74|  22.1k|  assert(current_block_ &&
   75|  22.1k|         "RegisterLoopMerge must be called when called within a block");
   76|      0|  current_block_->RegisterStructuralSuccessor(&merge_block);
   77|  22.1k|  current_block_->RegisterStructuralSuccessor(&continue_target_block);
   78|       |
   79|  22.1k|  current_block_->set_type(kBlockTypeLoop);
   80|  22.1k|  merge_block.set_type(kBlockTypeMerge);
   81|  22.1k|  continue_target_block.set_type(kBlockTypeContinue);
   82|  22.1k|  Construct& loop_construct =
   83|  22.1k|      AddConstruct({ConstructType::kLoop, current_block_, &merge_block});
   84|  22.1k|  Construct& continue_construct =
   85|  22.1k|      AddConstruct({ConstructType::kContinue, &continue_target_block});
   86|       |
   87|  22.1k|  continue_construct.set_corresponding_constructs({&loop_construct});
   88|  22.1k|  loop_construct.set_corresponding_constructs({&continue_construct});
   89|  22.1k|  merge_block_header_[&merge_block] = current_block_;
   90|  22.1k|  if (continue_target_headers_.find(&continue_target_block) ==
  ------------------
  |  Branch (90:7): [True: 21.9k, False: 211]
  ------------------
   91|  22.1k|      continue_target_headers_.end()) {
   92|  21.9k|    continue_target_headers_[&continue_target_block] = {current_block_};
   93|  21.9k|  } else {
   94|    211|    continue_target_headers_[&continue_target_block].push_back(current_block_);
   95|    211|  }
   96|       |
   97|  22.1k|  return SPV_SUCCESS;
   98|  22.1k|}
_ZN8spvtools3val8Function22RegisterSelectionMergeEj:
  100|  10.1k|spv_result_t Function::RegisterSelectionMerge(uint32_t merge_id) {
  101|  10.1k|  RegisterBlock(merge_id, false);
  102|  10.1k|  BasicBlock& merge_block = blocks_.at(merge_id);
  103|  10.1k|  current_block_->set_type(kBlockTypeSelection);
  104|  10.1k|  merge_block.set_type(kBlockTypeMerge);
  105|  10.1k|  merge_block_header_[&merge_block] = current_block_;
  106|  10.1k|  current_block_->RegisterStructuralSuccessor(&merge_block);
  107|       |
  108|  10.1k|  AddConstruct({ConstructType::kSelection, current_block(), &merge_block});
  109|       |
  110|  10.1k|  return SPV_SUCCESS;
  111|  10.1k|}
_ZN8spvtools3val8Function27RegisterSetFunctionDeclTypeENS0_12FunctionDeclE:
  113|  4.72k|spv_result_t Function::RegisterSetFunctionDeclType(FunctionDecl type) {
  114|  4.72k|  assert(declaration_type_ == FunctionDecl::kFunctionDeclUnknown);
  115|      0|  declaration_type_ = type;
  116|  4.72k|  return SPV_SUCCESS;
  117|  4.72k|}
_ZN8spvtools3val8Function13RegisterBlockEjb:
  119|   105k|spv_result_t Function::RegisterBlock(uint32_t block_id, bool is_definition) {
  120|   105k|  assert(
  121|   105k|      declaration_type_ == FunctionDecl::kFunctionDeclDefinition &&
  122|   105k|      "RegisterBlocks can only be called after declaration_type_ is defined");
  123|       |
  124|      0|  std::unordered_map<uint32_t, BasicBlock>::iterator inserted_block;
  125|   105k|  bool success = false;
  126|   105k|  tie(inserted_block, success) =
  127|   105k|      blocks_.insert({block_id, BasicBlock(block_id)});
  128|   105k|  if (is_definition) {  // new block definition
  ------------------
  |  Branch (128:7): [True: 50.8k, False: 54.5k]
  ------------------
  129|  50.8k|    assert(current_block_ == nullptr &&
  130|  50.8k|           "Register Block can only be called when parsing a binary outside of "
  131|  50.8k|           "a BasicBlock");
  132|       |
  133|      0|    undefined_blocks_.erase(block_id);
  134|  50.8k|    current_block_ = &inserted_block->second;
  135|  50.8k|    ordered_blocks_.push_back(current_block_);
  136|  54.5k|  } else if (success) {  // Block doesn't exist but this is not a definition
  ------------------
  |  Branch (136:14): [True: 52.7k, False: 1.74k]
  ------------------
  137|  52.7k|    undefined_blocks_.insert(block_id);
  138|  52.7k|  }
  139|       |
  140|      0|  return SPV_SUCCESS;
  141|   105k|}
_ZN8spvtools3val8Function16RegisterBlockEndENSt3__16vectorIjNS2_9allocatorIjEEEE:
  143|  50.1k|void Function::RegisterBlockEnd(std::vector<uint32_t> next_list) {
  144|  50.1k|  assert(
  145|  50.1k|      current_block_ &&
  146|  50.1k|      "RegisterBlockEnd can only be called when parsing a binary in a block");
  147|      0|  std::vector<BasicBlock*> next_blocks;
  148|  50.1k|  next_blocks.reserve(next_list.size());
  149|       |
  150|  50.1k|  std::unordered_map<uint32_t, BasicBlock>::iterator inserted_block;
  151|  50.1k|  bool success;
  152|  70.5k|  for (uint32_t successor_id : next_list) {
  ------------------
  |  Branch (152:30): [True: 70.5k, False: 50.1k]
  ------------------
  153|  70.5k|    tie(inserted_block, success) =
  154|  70.5k|        blocks_.insert({successor_id, BasicBlock(successor_id)});
  155|  70.5k|    if (success) {
  ------------------
  |  Branch (155:9): [True: 37.9k, False: 32.6k]
  ------------------
  156|  37.9k|      undefined_blocks_.insert(successor_id);
  157|  37.9k|    }
  158|  70.5k|    next_blocks.push_back(&inserted_block->second);
  159|  70.5k|  }
  160|       |
  161|  50.1k|  if (current_block_->is_type(kBlockTypeLoop)) {
  ------------------
  |  Branch (161:7): [True: 4.94k, False: 45.1k]
  ------------------
  162|       |    // For each loop header, record the set of its successors, and include
  163|       |    // its continue target if the continue target is not the loop header
  164|       |    // itself.
  165|  4.94k|    std::vector<BasicBlock*>& next_blocks_plus_continue_target =
  166|  4.94k|        loop_header_successors_plus_continue_target_map_[current_block_];
  167|  4.94k|    next_blocks_plus_continue_target = next_blocks;
  168|  4.94k|    auto continue_target =
  169|  4.94k|        FindConstructForEntryBlock(current_block_, ConstructType::kLoop)
  170|  4.94k|            .corresponding_constructs()
  171|  4.94k|            .back()
  172|  4.94k|            ->entry_block();
  173|  4.94k|    if (continue_target != current_block_) {
  ------------------
  |  Branch (173:9): [True: 4.78k, False: 155]
  ------------------
  174|  4.78k|      next_blocks_plus_continue_target.push_back(continue_target);
  175|  4.78k|    }
  176|  4.94k|  }
  177|       |
  178|  50.1k|  current_block_->RegisterSuccessors(next_blocks);
  179|  50.1k|  current_block_ = nullptr;
  180|  50.1k|  return;
  181|  50.1k|}
_ZN8spvtools3val8Function19RegisterFunctionEndEv:
  183|  3.89k|void Function::RegisterFunctionEnd() {
  184|  3.89k|  if (!end_has_been_registered_) {
  ------------------
  |  Branch (184:7): [True: 3.89k, False: 0]
  ------------------
  185|  3.89k|    end_has_been_registered_ = true;
  186|       |
  187|  3.89k|    ComputeAugmentedCFG();
  188|  3.89k|  }
  189|  3.89k|}
_ZNK8spvtools3val8Function11block_countEv:
  191|  5.64k|size_t Function::block_count() const { return blocks_.size(); }
_ZNK8spvtools3val8Function21undefined_block_countEv:
  193|  1.81k|size_t Function::undefined_block_count() const {
  194|  1.81k|  return undefined_blocks_.size();
  195|  1.81k|}
_ZN8spvtools3val8Function14ordered_blocksEv:
  200|  6.98k|std::vector<BasicBlock*>& Function::ordered_blocks() { return ordered_blocks_; }
_ZNK8spvtools3val8Function13current_blockEv:
  202|   548k|const BasicBlock* Function::current_block() const { return current_block_; }
_ZN8spvtools3val8Function13current_blockEv:
  203|   384k|BasicBlock* Function::current_block() { return current_block_; }
_ZN8spvtools3val8Function10constructsEv:
  208|  3.34k|std::list<Construct>& Function::constructs() { return cfg_constructs_; }
_ZNK8spvtools3val8Function11first_blockEv:
  210|  70.7k|const BasicBlock* Function::first_block() const {
  211|  70.7k|  if (ordered_blocks_.empty()) return nullptr;
  ------------------
  |  Branch (211:7): [True: 0, False: 70.7k]
  ------------------
  212|  70.7k|  return ordered_blocks_[0];
  213|  70.7k|}
_ZN8spvtools3val8Function11first_blockEv:
  214|  8.98k|BasicBlock* Function::first_block() {
  215|  8.98k|  if (ordered_blocks_.empty()) return nullptr;
  ------------------
  |  Branch (215:7): [True: 738, False: 8.24k]
  ------------------
  216|  8.24k|  return ordered_blocks_[0];
  217|  8.98k|}
_ZNK8spvtools3val8Function11IsBlockTypeEjNS0_9BlockTypeE:
  219|  35.9k|bool Function::IsBlockType(uint32_t merge_block_id, BlockType type) const {
  220|  35.9k|  bool ret = false;
  221|  35.9k|  const BasicBlock* block;
  222|  35.9k|  std::tie(block, std::ignore) = GetBlock(merge_block_id);
  223|  35.9k|  if (block) {
  ------------------
  |  Branch (223:7): [True: 4.63k, False: 31.2k]
  ------------------
  224|  4.63k|    ret = block->is_type(type);
  225|  4.63k|  }
  226|  35.9k|  return ret;
  227|  35.9k|}
_ZNK8spvtools3val8Function8GetBlockEj:
  229|  56.4k|std::pair<const BasicBlock*, bool> Function::GetBlock(uint32_t block_id) const {
  230|  56.4k|  const auto b = blocks_.find(block_id);
  231|  56.4k|  if (b != end(blocks_)) {
  ------------------
  |  Branch (231:7): [True: 25.1k, False: 31.2k]
  ------------------
  232|  25.1k|    const BasicBlock* block = &(b->second);
  233|  25.1k|    bool defined =
  234|  25.1k|        undefined_blocks_.find(block->id()) == std::end(undefined_blocks_);
  235|  25.1k|    return std::make_pair(block, defined);
  236|  31.2k|  } else {
  237|  31.2k|    return std::make_pair(nullptr, false);
  238|  31.2k|  }
  239|  56.4k|}
_ZN8spvtools3val8Function8GetBlockEj:
  241|  14.3k|std::pair<BasicBlock*, bool> Function::GetBlock(uint32_t block_id) {
  242|  14.3k|  const BasicBlock* out;
  243|  14.3k|  bool defined;
  244|  14.3k|  std::tie(out, defined) =
  245|  14.3k|      const_cast<const Function*>(this)->GetBlock(block_id);
  246|  14.3k|  return std::make_pair(const_cast<BasicBlock*>(out), defined);
  247|  14.3k|}
_ZNK8spvtools3val8Function30AugmentedCFGSuccessorsFunctionEv:
  249|  1.53k|Function::GetBlocksFunction Function::AugmentedCFGSuccessorsFunction() const {
  250|  1.53k|  return [this](const BasicBlock* block) {
  251|  1.53k|    auto where = augmented_successors_map_.find(block);
  252|  1.53k|    return where == augmented_successors_map_.end() ? block->successors()
  253|  1.53k|                                                    : &(*where).second;
  254|  1.53k|  };
  255|  1.53k|}
_ZNK8spvtools3val8Function32AugmentedCFGPredecessorsFunctionEv:
  257|  1.53k|Function::GetBlocksFunction Function::AugmentedCFGPredecessorsFunction() const {
  258|  1.53k|  return [this](const BasicBlock* block) {
  259|  1.53k|    auto where = augmented_predecessors_map_.find(block);
  260|  1.53k|    return where == augmented_predecessors_map_.end() ? block->predecessors()
  261|  1.53k|                                                      : &(*where).second;
  262|  1.53k|  };
  263|  1.53k|}
_ZNK8spvtools3val8Function40AugmentedStructuralCFGSuccessorsFunctionEv:
  266|  4.51k|    const {
  267|  4.51k|  return [this](const BasicBlock* block) {
  268|  4.51k|    auto where = augmented_successors_map_.find(block);
  269|  4.51k|    return where == augmented_successors_map_.end()
  270|  4.51k|               ? block->structural_successors()
  271|  4.51k|               : &(*where).second;
  272|  4.51k|  };
  273|  4.51k|}
_ZNK8spvtools3val8Function42AugmentedStructuralCFGPredecessorsFunctionEv:
  276|  3.01k|Function::AugmentedStructuralCFGPredecessorsFunction() const {
  277|  3.01k|  return [this](const BasicBlock* block) {
  278|  3.01k|    auto where = augmented_predecessors_map_.find(block);
  279|  3.01k|    return where == augmented_predecessors_map_.end()
  280|  3.01k|               ? block->structural_predecessors()
  281|  3.01k|               : &(*where).second;
  282|  3.01k|  };
  283|  3.01k|}
_ZN8spvtools3val8Function19ComputeAugmentedCFGEv:
  285|  3.89k|void Function::ComputeAugmentedCFG() {
  286|       |  // Compute the successors of the pseudo-entry block, and
  287|       |  // the predecessors of the pseudo exit block.
  288|  3.89k|  auto succ_func = [](const BasicBlock* b) {
  289|  3.89k|    return b->structural_successors();
  290|  3.89k|  };
  291|  3.89k|  auto pred_func = [](const BasicBlock* b) {
  292|  3.89k|    return b->structural_predecessors();
  293|  3.89k|  };
  294|  3.89k|  CFA<BasicBlock>::ComputeAugmentedCFG(
  295|  3.89k|      ordered_blocks_, &pseudo_entry_block_, &pseudo_exit_block_,
  296|  3.89k|      &augmented_successors_map_, &augmented_predecessors_map_, succ_func,
  297|  3.89k|      pred_func);
  298|  3.89k|}
_ZN8spvtools3val8Function12AddConstructERKNS0_9ConstructE:
  300|  54.5k|Construct& Function::AddConstruct(const Construct& new_construct) {
  301|  54.5k|  cfg_constructs_.push_back(new_construct);
  302|  54.5k|  auto& result = cfg_constructs_.back();
  303|  54.5k|  entry_block_to_construct_[std::make_pair(new_construct.entry_block(),
  304|  54.5k|                                           new_construct.type())] = &result;
  305|  54.5k|  return result;
  306|  54.5k|}
_ZN8spvtools3val8Function26FindConstructForEntryBlockEPKNS0_10BasicBlockENS0_13ConstructTypeE:
  309|  4.94k|                                                ConstructType type) {
  310|  4.94k|  auto where =
  311|  4.94k|      entry_block_to_construct_.find(std::make_pair(entry_block, type));
  312|  4.94k|  assert(where != entry_block_to_construct_.end());
  313|      0|  auto construct_ptr = (*where).second;
  314|  4.94k|  assert(construct_ptr);
  315|      0|  return *construct_ptr;
  316|  4.94k|}
_ZN8spvtools3val8Function13GetBlockDepthEPNS0_10BasicBlockE:
  318|  59.7k|int Function::GetBlockDepth(BasicBlock* bb) {
  319|       |  // Guard against nullptr.
  320|  59.7k|  if (!bb) {
  ------------------
  |  Branch (320:7): [True: 0, False: 59.7k]
  ------------------
  321|      0|    return 0;
  322|      0|  }
  323|       |  // Only calculate the depth if it's not already calculated.
  324|       |  // This function uses memoization to avoid duplicate CFG depth calculations.
  325|  59.7k|  if (block_depth_.find(bb) != block_depth_.end()) {
  ------------------
  |  Branch (325:7): [True: 25.3k, False: 34.3k]
  ------------------
  326|  25.3k|    return block_depth_[bb];
  327|  25.3k|  }
  328|       |  // Avoid recursion. Something is wrong if the same block is encountered
  329|       |  // multiple times.
  330|  34.3k|  block_depth_[bb] = 0;
  331|       |
  332|  34.3k|  BasicBlock* bb_dom = bb->immediate_dominator();
  333|  34.3k|  if (!bb_dom || bb == bb_dom) {
  ------------------
  |  Branch (333:7): [True: 10.4k, False: 23.9k]
  |  Branch (333:18): [True: 0, False: 23.9k]
  ------------------
  334|       |    // This block has no dominator, so it's at depth 0.
  335|  10.4k|    block_depth_[bb] = 0;
  336|  23.9k|  } else if (bb->is_type(kBlockTypeContinue)) {
  ------------------
  |  Branch (336:14): [True: 2.50k, False: 21.4k]
  ------------------
  337|       |    // This rule must precede the rule for merge blocks in order to set up
  338|       |    // depths correctly. If a block is both a merge and continue then the merge
  339|       |    // is nested within the continue's loop (or the graph is incorrect).
  340|       |    // The depth of the continue block entry point is 1 + loop header depth.
  341|  2.50k|    Construct* continue_construct =
  342|  2.50k|        entry_block_to_construct_[std::make_pair(bb, ConstructType::kContinue)];
  343|  2.50k|    assert(continue_construct);
  344|       |    // Continue construct has only 1 corresponding construct (loop header).
  345|      0|    Construct* loop_construct =
  346|  2.50k|        continue_construct->corresponding_constructs()[0];
  347|  2.50k|    assert(loop_construct);
  348|      0|    BasicBlock* loop_header = loop_construct->entry_block();
  349|       |    // The continue target may be the loop itself (while 1).
  350|       |    // In such cases, the depth of the continue block is: 1 + depth of the
  351|       |    // loop's dominator block.
  352|  2.50k|    if (loop_header == bb) {
  ------------------
  |  Branch (352:9): [True: 80, False: 2.42k]
  ------------------
  353|     80|      block_depth_[bb] = 1 + GetBlockDepth(bb_dom);
  354|  2.42k|    } else {
  355|  2.42k|      block_depth_[bb] = 1 + GetBlockDepth(loop_header);
  356|  2.42k|    }
  357|  21.4k|  } else if (bb->is_type(kBlockTypeMerge)) {
  ------------------
  |  Branch (357:14): [True: 6.23k, False: 15.2k]
  ------------------
  358|       |    // If this is a merge block, its depth is equal to the block before
  359|       |    // branching.
  360|  6.23k|    BasicBlock* header = merge_block_header_[bb];
  361|  6.23k|    assert(header);
  362|      0|    block_depth_[bb] = GetBlockDepth(header);
  363|  15.2k|  } else if (bb_dom->is_type(kBlockTypeSelection) ||
  ------------------
  |  Branch (363:14): [True: 8.11k, False: 7.13k]
  ------------------
  364|  15.2k|             bb_dom->is_type(kBlockTypeLoop)) {
  ------------------
  |  Branch (364:14): [True: 2.50k, False: 4.62k]
  ------------------
  365|       |    // The dominator of the given block is a header block. So, the nesting
  366|       |    // depth of this block is: 1 + nesting depth of the header.
  367|  10.6k|    block_depth_[bb] = 1 + GetBlockDepth(bb_dom);
  368|  10.6k|  } else {
  369|  4.62k|    block_depth_[bb] = GetBlockDepth(bb_dom);
  370|  4.62k|  }
  371|      0|  return block_depth_[bb];
  372|  59.7k|}
_ZN8spvtools3val8Function32RegisterExecutionModelLimitationEN3spv14ExecutionModelERKNSt3__112basic_stringIcNS4_11char_traitsIcEENS4_9allocatorIcEEEE:
  375|  1.60k|                                                const std::string& message) {
  376|  1.60k|  execution_model_limitations_.push_back(
  377|  1.60k|      [model, message](spv::ExecutionModel in_model, std::string* out_message) {
  378|  1.60k|        if (model != in_model) {
  379|  1.60k|          if (out_message) {
  380|  1.60k|            *out_message = message;
  381|  1.60k|          }
  382|  1.60k|          return false;
  383|  1.60k|        }
  384|  1.60k|        return true;
  385|  1.60k|      });
  386|  1.60k|}
_ZNK8spvtools3val8Function30IsCompatibleWithExecutionModelEN3spv14ExecutionModelEPNSt3__112basic_stringIcNS4_11char_traitsIcEENS4_9allocatorIcEEEE:
  389|    582|                                              std::string* reason) const {
  390|    582|  bool return_value = true;
  391|    582|  std::stringstream ss_reason;
  392|       |
  393|    733|  for (const auto& is_compatible : execution_model_limitations_) {
  ------------------
  |  Branch (393:34): [True: 733, False: 582]
  ------------------
  394|    733|    std::string message;
  395|    733|    if (!is_compatible(model, &message)) {
  ------------------
  |  Branch (395:9): [True: 610, False: 123]
  ------------------
  396|    610|      if (!reason) return false;
  ------------------
  |  Branch (396:11): [True: 0, False: 610]
  ------------------
  397|    610|      return_value = false;
  398|    610|      if (!message.empty()) {
  ------------------
  |  Branch (398:11): [True: 610, False: 0]
  ------------------
  399|    610|        ss_reason << message << "\n";
  400|    610|      }
  401|    610|    }
  402|    733|  }
  403|       |
  404|    582|  if (!return_value && reason) {
  ------------------
  |  Branch (404:7): [True: 93, False: 489]
  |  Branch (404:24): [True: 93, False: 0]
  ------------------
  405|     93|    *reason = ss_reason.str();
  406|     93|  }
  407|       |
  408|    582|  return return_value;
  409|    582|}
_ZNK8spvtools3val8Function16CheckLimitationsERKNS0_17ValidationState_tEPKS1_PNSt3__112basic_stringIcNS7_11char_traitsIcEENS7_9allocatorIcEEEE:
  413|    388|                                std::string* reason) const {
  414|    388|  bool return_value = true;
  415|    388|  std::stringstream ss_reason;
  416|       |
  417|    388|  for (const auto& is_compatible : limitations_) {
  ------------------
  |  Branch (417:34): [True: 62, False: 388]
  ------------------
  418|     62|    std::string message;
  419|     62|    if (!is_compatible(_, entry_point, &message)) {
  ------------------
  |  Branch (419:9): [True: 5, False: 57]
  ------------------
  420|      5|      if (!reason) return false;
  ------------------
  |  Branch (420:11): [True: 0, False: 5]
  ------------------
  421|      5|      return_value = false;
  422|      5|      if (!message.empty()) {
  ------------------
  |  Branch (422:11): [True: 5, False: 0]
  ------------------
  423|      5|        ss_reason << message << "\n";
  424|      5|      }
  425|      5|    }
  426|     62|  }
  427|       |
  428|    388|  if (!return_value && reason) {
  ------------------
  |  Branch (428:7): [True: 4, False: 384]
  |  Branch (428:24): [True: 4, False: 0]
  ------------------
  429|      4|    *reason = ss_reason.str();
  430|      4|  }
  431|       |
  432|    388|  return return_value;
  433|    388|}
function.cpp:_ZZNK8spvtools3val8Function30AugmentedCFGSuccessorsFunctionEvENK3$_0clEPKNS0_10BasicBlockE:
  250|  92.4k|  return [this](const BasicBlock* block) {
  251|  92.4k|    auto where = augmented_successors_map_.find(block);
  252|  92.4k|    return where == augmented_successors_map_.end() ? block->successors()
  ------------------
  |  Branch (252:12): [True: 86.8k, False: 5.66k]
  ------------------
  253|  92.4k|                                                    : &(*where).second;
  254|  92.4k|  };
function.cpp:_ZZNK8spvtools3val8Function32AugmentedCFGPredecessorsFunctionEvENK3$_1clEPKNS0_10BasicBlockE:
  258|  61.2k|  return [this](const BasicBlock* block) {
  259|  61.2k|    auto where = augmented_predecessors_map_.find(block);
  260|  61.2k|    return where == augmented_predecessors_map_.end() ? block->predecessors()
  ------------------
  |  Branch (260:12): [True: 58.2k, False: 2.99k]
  ------------------
  261|  61.2k|                                                      : &(*where).second;
  262|  61.2k|  };
function.cpp:_ZZNK8spvtools3val8Function40AugmentedStructuralCFGSuccessorsFunctionEvENK3$_2clEPKNS0_10BasicBlockE:
  267|   360k|  return [this](const BasicBlock* block) {
  268|   360k|    auto where = augmented_successors_map_.find(block);
  269|   360k|    return where == augmented_successors_map_.end()
  ------------------
  |  Branch (269:12): [True: 298k, False: 62.3k]
  ------------------
  270|   360k|               ? block->structural_successors()
  271|   360k|               : &(*where).second;
  272|   360k|  };
function.cpp:_ZZNK8spvtools3val8Function42AugmentedStructuralCFGPredecessorsFunctionEvENK3$_3clEPKNS0_10BasicBlockE:
  277|   213k|  return [this](const BasicBlock* block) {
  278|   213k|    auto where = augmented_predecessors_map_.find(block);
  279|   213k|    return where == augmented_predecessors_map_.end()
  ------------------
  |  Branch (279:12): [True: 187k, False: 26.5k]
  ------------------
  280|   213k|               ? block->structural_predecessors()
  281|   213k|               : &(*where).second;
  282|   213k|  };
function.cpp:_ZZN8spvtools3val8Function19ComputeAugmentedCFGEvENK3$_4clEPKNS0_10BasicBlockE:
  288|   553k|  auto succ_func = [](const BasicBlock* b) {
  289|   553k|    return b->structural_successors();
  290|   553k|  };
function.cpp:_ZZN8spvtools3val8Function19ComputeAugmentedCFGEvENK3$_5clEPKNS0_10BasicBlockE:
  291|   876k|  auto pred_func = [](const BasicBlock* b) {
  292|   876k|    return b->structural_predecessors();
  293|   876k|  };
function.cpp:_ZZN8spvtools3val8Function32RegisterExecutionModelLimitationEN3spv14ExecutionModelERKNSt3__112basic_stringIcNS4_11char_traitsIcEENS4_9allocatorIcEEEEENK3$_6clES3_PSA_:
  377|    475|      [model, message](spv::ExecutionModel in_model, std::string* out_message) {
  378|    475|        if (model != in_model) {
  ------------------
  |  Branch (378:13): [True: 443, False: 32]
  ------------------
  379|    443|          if (out_message) {
  ------------------
  |  Branch (379:15): [True: 443, False: 0]
  ------------------
  380|    443|            *out_message = message;
  381|    443|          }
  382|    443|          return false;
  383|    443|        }
  384|     32|        return true;
  385|    475|      });

_ZN8spvtools3val8Function21AddFunctionCallTargetEj:
  236|    700|  void AddFunctionCallTarget(uint32_t call_target_id) {
  237|    700|    function_call_targets_.insert(call_target_id);
  238|    700|  }
_ZNK8spvtools3val24bb_constr_type_pair_hashclERKNSt3__14pairIPKNS0_10BasicBlockENS0_13ConstructTypeEEE:
   38|  61.9k|      const std::pair<const BasicBlock*, ConstructType>& p) const {
   39|  61.9k|    auto h1 = std::hash<const BasicBlock*>{}(p.first);
   40|  61.9k|    auto h2 = std::hash<std::underlying_type<ConstructType>::type>{}(
   41|  61.9k|        static_cast<std::underlying_type<ConstructType>::type>(p.second));
   42|  61.9k|    return (h1 ^ h2);
   43|  61.9k|  }
_ZNK8spvtools3val8Function2idEv:
  142|   101k|  uint32_t id() const { return id_; }
_ZNK8spvtools3val8Function15GetResultTypeIdEv:
  145|  2.69k|  uint32_t GetResultTypeId() const { return result_type_id_; }
_ZNK8spvtools3val8Function16undefined_blocksEv:
  149|      6|  const std::unordered_set<uint32_t>& undefined_blocks() const {
  150|      6|    return undefined_blocks_;
  151|      6|  }
_ZN8spvtools3val8Function18pseudo_entry_blockEv:
  174|  25.6k|  BasicBlock* pseudo_entry_block() { return &pseudo_entry_block_; }
_ZN8spvtools3val8Function17pseudo_exit_blockEv:
  180|  1.50k|  BasicBlock* pseudo_exit_block() { return &pseudo_exit_block_; }
_ZN8spvtools3val8Function32RegisterExecutionModelLimitationENSt3__18functionIFbN3spv14ExecutionModelEPNS2_12basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEEEEE:
  215|    617|      std::function<bool(spv::ExecutionModel, std::string*)> is_compatible) {
  216|    617|    execution_model_limitations_.push_back(is_compatible);
  217|    617|  }
_ZN8spvtools3val8Function18RegisterLimitationENSt3__18functionIFbRKNS0_17ValidationState_tEPKS1_PNS2_12basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEEEEE:
  222|    225|                              is_compatible) {
  223|    225|    limitations_.push_back(is_compatible);
  224|    225|  }
_ZNK8spvtools3val8Function21function_call_targetsEv:
  241|  3.94k|  const std::set<uint32_t> function_call_targets() const {
  242|  3.94k|    return function_call_targets_;
  243|  3.94k|  }

_ZN8spvtools3val11InstructionC2EPK24spv_parsed_instruction_t:
   30|   499k|             inst->num_operands}) {}
_ZN8spvtools3val11Instruction11RegisterUseEPKS1_j:
   32|   456k|void Instruction::RegisterUse(const Instruction* inst, uint32_t index) {
   33|   456k|  uses_.push_back(std::make_pair(inst, index));
   34|   456k|}
_ZNK8spvtools3val11Instruction12GetOperandAsINSt3__112basic_stringIcNS3_11char_traitsIcEENS3_9allocatorIcEEEEEET_m:
   48|  14.7k|std::string Instruction::GetOperandAs<std::string>(size_t index) const {
   49|  14.7k|  const spv_parsed_operand_t& o = operands_.at(index);
   50|  14.7k|  assert(o.offset + o.num_words <= inst_.num_words);
   51|      0|  return spvtools::utils::MakeString(words_.data() + o.offset, o.num_words);
   52|  14.7k|}

_ZNK8spvtools3val11Instruction6opcodeEv:
   45|  20.2M|  spv::Op opcode() const { return static_cast<spv::Op>(inst_.opcode); }
_ZNK8spvtools3val11Instruction12GetOperandAsIjEET_m:
  102|   763k|  T GetOperandAs(size_t index) const {
  103|   763k|    const spv_parsed_operand_t& o = operands_.at(index);
  104|   763k|    assert(o.num_words * 4 >= sizeof(T));
  105|      0|    assert(o.offset + o.num_words <= inst_.num_words);
  106|      0|    return *reinterpret_cast<const T*>(&words_[o.offset]);
  107|   763k|  }
_ZNK8spvtools3val11Instruction12GetOperandAsIN3spv14ExecutionModelEEET_m:
  102|  12.2k|  T GetOperandAs(size_t index) const {
  103|  12.2k|    const spv_parsed_operand_t& o = operands_.at(index);
  104|  12.2k|    assert(o.num_words * 4 >= sizeof(T));
  105|      0|    assert(o.offset + o.num_words <= inst_.num_words);
  106|      0|    return *reinterpret_cast<const T*>(&words_[o.offset]);
  107|  12.2k|  }
_ZNK8spvtools3val11Instruction8operandsEv:
   77|  6.38M|  const std::vector<spv_parsed_operand_t>& operands() const {
   78|  6.38M|    return operands_;
   79|  6.38M|  }
_ZNK8spvtools3val11Instruction4wordEm:
   66|  4.39M|  uint32_t word(size_t index) const { return words_[index]; }
_ZNK8spvtools3val11Instruction7operandEm:
   72|  4.38M|  const spv_parsed_operand_t& operand(size_t idx) const {
   73|  4.38M|    return operands_[idx];
   74|  4.38M|  }
_ZN8spvtools3val11Instruction12set_functionEPNS0_8FunctionE:
   50|   273k|  void set_function(Function* func) { function_ = func; }
_ZN8spvtools3val11Instruction9set_blockEPNS0_10BasicBlockE:
   55|   273k|  void set_block(BasicBlock* b) { block_ = b; }
_ZNK8spvtools3val11Instruction2idEv:
   43|  1.33M|  uint32_t id() const { return inst_.result_id; }
_ZNK8spvtools3val11Instruction7type_idEv:
   44|  3.47M|  uint32_t type_id() const { return inst_.type_id; }
_ZNK8spvtools3val11Instruction8functionEv:
   49|   543k|  const Function* function() const { return function_; }
_ZNK8spvtools3val11Instruction5blockEv:
   54|   150k|  const BasicBlock* block() const { return block_; }
_ZNK8spvtools3val11Instruction4usesEv:
   61|  42.6k|  const std::vector<std::pair<const Instruction*, uint32_t>>& uses() const {
   62|  42.6k|    return uses_;
   63|  42.6k|  }
_ZNK8spvtools3val11Instruction5wordsEv:
   69|   404k|  const std::vector<uint32_t>& words() const { return words_; }
_ZNK8spvtools3val11Instruction6c_instEv:
   82|  7.34k|  const spv_parsed_instruction_t& c_inst() const { return inst_; }
_ZNK8spvtools3val11Instruction13ext_inst_typeEv:
   85|  13.9k|  const spv_ext_inst_type_t& ext_inst_type() const {
   86|  13.9k|    return inst_.ext_inst_type;
   87|  13.9k|  }
_ZNK8spvtools3val11Instruction13IsNonSemanticEv:
   89|   356k|  bool IsNonSemantic() const {
   90|   356k|    return opcode() == spv::Op::OpExtInst &&
  ------------------
  |  Branch (90:12): [True: 44.2k, False: 312k]
  ------------------
   91|   356k|           spvExtInstIsNonSemantic(inst_.ext_inst_type);
  ------------------
  |  Branch (91:12): [True: 29, False: 44.1k]
  ------------------
   92|   356k|  }
_ZNK8spvtools3val11Instruction11IsDebugInfoEv:
   95|  40.1k|  bool IsDebugInfo() const {
   96|  40.1k|    return opcode() == spv::Op::OpExtInst &&
  ------------------
  |  Branch (96:12): [True: 3.51k, False: 36.6k]
  ------------------
   97|  40.1k|           spvExtInstIsDebugInfo(inst_.ext_inst_type);
  ------------------
  |  Branch (97:12): [True: 0, False: 3.51k]
  ------------------
   98|  40.1k|  }
_ZNK8spvtools3val11Instruction7LineNumEv:
  109|  4.96k|  size_t LineNum() const { return line_num_; }
_ZN8spvtools3val11Instruction10SetLineNumEm:
  110|   499k|  void SetLineNum(size_t pos) { line_num_ = pos; }
_ZNK8spvtools3val11Instruction12GetOperandAsIN3spv12StorageClassEEET_m:
  102|   175k|  T GetOperandAs(size_t index) const {
  103|   175k|    const spv_parsed_operand_t& o = operands_.at(index);
  104|   175k|    assert(o.num_words * 4 >= sizeof(T));
  105|      0|    assert(o.offset + o.num_words <= inst_.num_words);
  106|      0|    return *reinterpret_cast<const T*>(&words_[o.offset]);
  107|   175k|  }
_ZNK8spvtools3val11Instruction12GetOperandAsIN3spv10DecorationEEET_m:
  102|  14.0k|  T GetOperandAs(size_t index) const {
  103|  14.0k|    const spv_parsed_operand_t& o = operands_.at(index);
  104|  14.0k|    assert(o.num_words * 4 >= sizeof(T));
  105|      0|    assert(o.offset + o.num_words <= inst_.num_words);
  106|      0|    return *reinterpret_cast<const T*>(&words_[o.offset]);
  107|  14.0k|  }
_ZNK8spvtools3val11Instruction12GetOperandAsIN3spv7BuiltInEEET_m:
  102|    229|  T GetOperandAs(size_t index) const {
  103|    229|    const spv_parsed_operand_t& o = operands_.at(index);
  104|    229|    assert(o.num_words * 4 >= sizeof(T));
  105|      0|    assert(o.offset + o.num_words <= inst_.num_words);
  106|      0|    return *reinterpret_cast<const T*>(&words_[o.offset]);
  107|    229|  }
_ZNK8spvtools3val11Instruction12GetOperandAsIKjEET_m:
  102|  7.03k|  T GetOperandAs(size_t index) const {
  103|  7.03k|    const spv_parsed_operand_t& o = operands_.at(index);
  104|  7.03k|    assert(o.num_words * 4 >= sizeof(T));
  105|      0|    assert(o.offset + o.num_words <= inst_.num_words);
  106|      0|    return *reinterpret_cast<const T*>(&words_[o.offset]);
  107|  7.03k|  }
_ZNK8spvtools3val11Instruction12GetOperandAsIN3spv16LoopControlShiftEEET_m:
  102|  3.57k|  T GetOperandAs(size_t index) const {
  103|  3.57k|    const spv_parsed_operand_t& o = operands_.at(index);
  104|  3.57k|    assert(o.num_words * 4 >= sizeof(T));
  105|      0|    assert(o.offset + o.num_words <= inst_.num_words);
  106|      0|    return *reinterpret_cast<const T*>(&words_[o.offset]);
  107|  3.57k|  }
_ZNK8spvtools3val11Instruction12GetOperandAsIN3spv2OpEEET_m:
  102|     19|  T GetOperandAs(size_t index) const {
  103|     19|    const spv_parsed_operand_t& o = operands_.at(index);
  104|     19|    assert(o.num_words * 4 >= sizeof(T));
  105|      0|    assert(o.offset + o.num_words <= inst_.num_words);
  106|      0|    return *reinterpret_cast<const T*>(&words_[o.offset]);
  107|     19|  }
_ZNK8spvtools3val11Instruction12GetOperandAsIN3spv10CapabilityEEET_m:
  102|  7.02k|  T GetOperandAs(size_t index) const {
  103|  7.02k|    const spv_parsed_operand_t& o = operands_.at(index);
  104|  7.02k|    assert(o.num_words * 4 >= sizeof(T));
  105|      0|    assert(o.offset + o.num_words <= inst_.num_words);
  106|      0|    return *reinterpret_cast<const T*>(&words_[o.offset]);
  107|  7.02k|  }
_ZNK8spvtools3val11Instruction12GetOperandAsIN3spv15AddressingModelEEET_m:
  102|  5.43k|  T GetOperandAs(size_t index) const {
  103|  5.43k|    const spv_parsed_operand_t& o = operands_.at(index);
  104|  5.43k|    assert(o.num_words * 4 >= sizeof(T));
  105|      0|    assert(o.offset + o.num_words <= inst_.num_words);
  106|      0|    return *reinterpret_cast<const T*>(&words_[o.offset]);
  107|  5.43k|  }
_ZNK8spvtools3val11Instruction12GetOperandAsIN3spv11MemoryModelEEET_m:
  102|  5.43k|  T GetOperandAs(size_t index) const {
  103|  5.43k|    const spv_parsed_operand_t& o = operands_.at(index);
  104|  5.43k|    assert(o.num_words * 4 >= sizeof(T));
  105|      0|    assert(o.offset + o.num_words <= inst_.num_words);
  106|      0|    return *reinterpret_cast<const T*>(&words_[o.offset]);
  107|  5.43k|  }
_ZNK8spvtools3val11Instruction12GetOperandAsIN3spv19FunctionControlMaskEEET_m:
  102|  4.78k|  T GetOperandAs(size_t index) const {
  103|  4.78k|    const spv_parsed_operand_t& o = operands_.at(index);
  104|  4.78k|    assert(o.num_words * 4 >= sizeof(T));
  105|      0|    assert(o.offset + o.num_words <= inst_.num_words);
  106|      0|    return *reinterpret_cast<const T*>(&words_[o.offset]);
  107|  4.78k|  }
_ZNK8spvtools3val11Instruction12GetOperandAsIN3spv13ExecutionModeEEET_m:
  102|  1.49k|  T GetOperandAs(size_t index) const {
  103|  1.49k|    const spv_parsed_operand_t& o = operands_.at(index);
  104|  1.49k|    assert(o.num_words * 4 >= sizeof(T));
  105|      0|    assert(o.offset + o.num_words <= inst_.num_words);
  106|      0|    return *reinterpret_cast<const T*>(&words_[o.offset]);
  107|  1.49k|  }

spvValidateBinary:
  428|  8.24k|                               spv_diagnostic* pDiagnostic) {
  429|  8.24k|  spv_context_t hijack_context = *context;
  430|  8.24k|  if (pDiagnostic) {
  ------------------
  |  Branch (430:7): [True: 0, False: 8.24k]
  ------------------
  431|      0|    *pDiagnostic = nullptr;
  432|      0|    spvtools::UseDiagnosticAsMessageConsumer(&hijack_context, pDiagnostic);
  433|      0|  }
  434|       |
  435|       |  // This interface is used for default command line options.
  436|  8.24k|  spv_validator_options default_options = spvValidatorOptionsCreate();
  437|       |
  438|       |  // Create the ValidationState using the context and default options.
  439|  8.24k|  spvtools::val::ValidationState_t vstate(&hijack_context, default_options,
  440|  8.24k|                                          words, num_words,
  441|  8.24k|                                          kDefaultMaxNumOfWarnings);
  442|       |
  443|  8.24k|  spv_result_t result =
  444|  8.24k|      spvtools::val::ValidateBinaryUsingContextAndValidationState(
  445|  8.24k|          hijack_context, words, num_words, pDiagnostic, &vstate);
  446|       |
  447|  8.24k|  spvValidatorOptionsDestroy(default_options);
  448|  8.24k|  return result;
  449|  8.24k|}
validate.cpp:_ZN8spvtools3val12_GLOBAL__N_144ValidateBinaryUsingContextAndValidationStateERK13spv_context_tPKjmPP16spv_diagnostic_tPNS0_17ValidationState_tE:
  157|  8.24k|    spv_diagnostic* pDiagnostic, ValidationState_t* vstate) {
  158|  8.24k|  auto binary = std::unique_ptr<spv_const_binary_t>(
  159|  8.24k|      new spv_const_binary_t{words, num_words});
  160|       |
  161|  8.24k|  spv_endianness_t endian;
  162|  8.24k|  spv_position_t position = {};
  163|  8.24k|  if (spvBinaryEndianness(binary.get(), &endian)) {
  ------------------
  |  Branch (163:7): [True: 71, False: 8.16k]
  ------------------
  164|     71|    return DiagnosticStream(position, context.consumer, "",
  165|     71|                            SPV_ERROR_INVALID_BINARY)
  166|     71|           << "Invalid SPIR-V magic number.";
  167|     71|  }
  168|       |
  169|  8.16k|  spv_header_t header;
  170|  8.16k|  if (spvBinaryHeaderGet(binary.get(), endian, &header)) {
  ------------------
  |  Branch (170:7): [True: 56, False: 8.11k]
  ------------------
  171|     56|    return DiagnosticStream(position, context.consumer, "",
  172|     56|                            SPV_ERROR_INVALID_BINARY)
  173|     56|           << "Invalid SPIR-V header.";
  174|     56|  }
  175|       |
  176|  8.11k|  if (header.version > spvVersionForTargetEnv(context.target_env)) {
  ------------------
  |  Branch (176:7): [True: 94, False: 8.01k]
  ------------------
  177|     94|    return DiagnosticStream(position, context.consumer, "",
  178|     94|                            SPV_ERROR_WRONG_VERSION)
  179|     94|           << "Invalid SPIR-V binary version "
  180|     94|           << SPV_SPIRV_VERSION_MAJOR_PART(header.version) << "."
  ------------------
  |  |   28|     94|#define SPV_SPIRV_VERSION_MAJOR_PART(WORD) ((uint32_t(WORD) >> 16) & 0xff)
  ------------------
  181|     94|           << SPV_SPIRV_VERSION_MINOR_PART(header.version)
  ------------------
  |  |   30|     94|#define SPV_SPIRV_VERSION_MINOR_PART(WORD) ((uint32_t(WORD) >> 8) & 0xff)
  ------------------
  182|     94|           << " for target environment "
  183|     94|           << spvTargetEnvDescription(context.target_env) << ".";
  184|     94|  }
  185|       |
  186|  8.01k|  if (header.bound > vstate->options()->universal_limits_.max_id_bound) {
  ------------------
  |  Branch (186:7): [True: 663, False: 7.35k]
  ------------------
  187|    663|    return DiagnosticStream(position, context.consumer, "",
  188|    663|                            SPV_ERROR_INVALID_BINARY)
  189|    663|           << "Invalid SPIR-V.  The id bound is larger than the max id bound "
  190|    663|           << vstate->options()->universal_limits_.max_id_bound << ".";
  191|    663|  }
  192|       |
  193|       |  // Look for OpExtension instructions and register extensions.
  194|       |  // This parse should not produce any error messages. Hijack the context and
  195|       |  // replace the message consumer so that we do not pollute any state in input
  196|       |  // consumer.
  197|  7.35k|  spv_context_t hijacked_context = context;
  198|  7.35k|  hijacked_context.consumer = [](spv_message_level_t, const char*,
  199|  7.35k|                                 const spv_position_t&, const char*) {};
  200|  7.35k|  spvBinaryParse(&hijacked_context, vstate, words, num_words,
  201|  7.35k|                 /* parsed_header = */ nullptr, ProcessExtensions,
  202|  7.35k|                 /* diagnostic = */ nullptr);
  203|       |
  204|       |  // Parse the module and perform inline validation checks. These checks do
  205|       |  // not require the knowledge of the whole module.
  206|  7.35k|  if (auto error = spvBinaryParse(&context, vstate, words, num_words,
  ------------------
  |  Branch (206:12): [True: 643, False: 6.71k]
  ------------------
  207|  7.35k|                                  /*parsed_header =*/nullptr,
  208|  7.35k|                                  ProcessInstruction, pDiagnostic)) {
  209|    643|    return error;
  210|    643|  }
  211|       |
  212|  6.71k|  bool has_mask_task_nv = false;
  213|  6.71k|  bool has_mask_task_ext = false;
  214|  6.71k|  std::vector<Instruction*> visited_entry_points;
  215|   389k|  for (auto& instruction : vstate->ordered_instructions()) {
  ------------------
  |  Branch (215:26): [True: 389k, False: 5.08k]
  ------------------
  216|   389k|    {
  217|       |      // In order to do this work outside of Process Instruction we need to be
  218|       |      // able to, briefly, de-const the instruction.
  219|   389k|      Instruction* inst = const_cast<Instruction*>(&instruction);
  220|       |
  221|   389k|      if (inst->opcode() == spv::Op::OpEntryPoint) {
  ------------------
  |  Branch (221:11): [True: 3.33k, False: 385k]
  ------------------
  222|  3.33k|        const auto entry_point = inst->GetOperandAs<uint32_t>(1);
  223|  3.33k|        const auto execution_model = inst->GetOperandAs<spv::ExecutionModel>(0);
  224|  3.33k|        const std::string desc_name = inst->GetOperandAs<std::string>(2);
  225|       |
  226|  3.33k|        ValidationState_t::EntryPointDescription desc;
  227|  3.33k|        desc.name = desc_name;
  228|       |
  229|  3.33k|        std::vector<uint32_t> interfaces;
  230|   399k|        for (size_t j = 3; j < inst->operands().size(); ++j)
  ------------------
  |  Branch (230:28): [True: 396k, False: 3.33k]
  ------------------
  231|   396k|          desc.interfaces.push_back(inst->word(inst->operand(j).offset));
  232|       |
  233|  3.33k|        vstate->RegisterEntryPoint(entry_point, execution_model,
  234|  3.33k|                                   std::move(desc));
  235|       |
  236|  3.33k|        if (visited_entry_points.size() > 0) {
  ------------------
  |  Branch (236:13): [True: 1.27k, False: 2.05k]
  ------------------
  237|  7.16k|          for (const Instruction* check_inst : visited_entry_points) {
  ------------------
  |  Branch (237:46): [True: 7.16k, False: 1.24k]
  ------------------
  238|  7.16k|            const auto check_execution_model =
  239|  7.16k|                check_inst->GetOperandAs<spv::ExecutionModel>(0);
  240|  7.16k|            const std::string check_name =
  241|  7.16k|                check_inst->GetOperandAs<std::string>(2);
  242|       |
  243|  7.16k|            if (desc_name == check_name &&
  ------------------
  |  Branch (243:17): [True: 149, False: 7.02k]
  ------------------
  244|  7.16k|                execution_model == check_execution_model) {
  ------------------
  |  Branch (244:17): [True: 27, False: 122]
  ------------------
  245|     27|              return vstate->diag(SPV_ERROR_INVALID_DATA, inst)
  246|     27|                     << "2 Entry points cannot share the same name and "
  247|     27|                        "ExecutionMode.";
  248|     27|            }
  249|  7.16k|          }
  250|  1.27k|        }
  251|  3.30k|        visited_entry_points.push_back(inst);
  252|       |
  253|  3.30k|        has_mask_task_nv |= (execution_model == spv::ExecutionModel::TaskNV ||
  ------------------
  |  Branch (253:30): [True: 0, False: 3.30k]
  ------------------
  254|  3.30k|                             execution_model == spv::ExecutionModel::MeshNV);
  ------------------
  |  Branch (254:30): [True: 0, False: 3.30k]
  ------------------
  255|  3.30k|        has_mask_task_ext |= (execution_model == spv::ExecutionModel::TaskEXT ||
  ------------------
  |  Branch (255:31): [True: 1, False: 3.30k]
  ------------------
  256|  3.30k|                              execution_model == spv::ExecutionModel::MeshEXT);
  ------------------
  |  Branch (256:31): [True: 0, False: 3.30k]
  ------------------
  257|  3.30k|      }
  258|   389k|      if (inst->opcode() == spv::Op::OpFunctionCall) {
  ------------------
  |  Branch (258:11): [True: 702, False: 388k]
  ------------------
  259|    702|        if (!vstate->in_function_body()) {
  ------------------
  |  Branch (259:13): [True: 2, False: 700]
  ------------------
  260|      2|          return vstate->diag(SPV_ERROR_INVALID_LAYOUT, &instruction)
  261|      2|                 << "A FunctionCall must happen within a function body.";
  262|      2|        }
  263|       |
  264|    700|        const auto called_id = inst->GetOperandAs<uint32_t>(2);
  265|    700|        vstate->AddFunctionCallTarget(called_id);
  266|    700|      }
  267|       |
  268|   389k|      if (vstate->in_function_body()) {
  ------------------
  |  Branch (268:11): [True: 273k, False: 115k]
  ------------------
  269|   273k|        inst->set_function(&(vstate->current_function()));
  270|   273k|        inst->set_block(vstate->current_function().current_block());
  271|       |
  272|   273k|        if (vstate->in_block() && spvOpcodeIsBlockTerminator(inst->opcode())) {
  ------------------
  |  Branch (272:13): [True: 217k, False: 55.7k]
  |  Branch (272:35): [True: 50.1k, False: 167k]
  ------------------
  273|  50.1k|          vstate->current_function().current_block()->set_terminator(inst);
  274|  50.1k|        }
  275|   273k|      }
  276|       |
  277|   389k|      if (auto error = IdPass(*vstate, inst)) return error;
  ------------------
  |  Branch (277:16): [True: 379, False: 388k]
  ------------------
  278|   389k|    }
  279|       |
  280|   388k|    if (auto error = CapabilityPass(*vstate, &instruction)) return error;
  ------------------
  |  Branch (280:14): [True: 0, False: 388k]
  ------------------
  281|   388k|    if (auto error = ModuleLayoutPass(*vstate, &instruction)) return error;
  ------------------
  |  Branch (281:14): [True: 791, False: 387k]
  ------------------
  282|   387k|    if (auto error = CfgPass(*vstate, &instruction)) return error;
  ------------------
  |  Branch (282:14): [True: 34, False: 387k]
  ------------------
  283|   387k|    if (auto error = InstructionPass(*vstate, &instruction)) return error;
  ------------------
  |  Branch (283:14): [True: 398, False: 387k]
  ------------------
  284|       |
  285|       |    // Now that all of the checks are done, update the state.
  286|   387k|    {
  287|   387k|      Instruction* inst = const_cast<Instruction*>(&instruction);
  288|   387k|      vstate->RegisterInstruction(inst);
  289|   387k|      if (inst->opcode() == spv::Op::OpTypeForwardPointer) {
  ------------------
  |  Branch (289:11): [True: 251, False: 387k]
  ------------------
  290|    251|        vstate->RegisterForwardPointer(inst->GetOperandAs<uint32_t>(0));
  291|    251|      }
  292|   387k|    }
  293|   387k|  }
  294|       |
  295|  5.08k|  if (!vstate->has_memory_model_specified())
  ------------------
  |  Branch (295:7): [True: 141, False: 4.94k]
  ------------------
  296|    141|    return vstate->diag(SPV_ERROR_INVALID_LAYOUT, nullptr)
  297|    141|           << "Missing required OpMemoryModel instruction.";
  298|       |
  299|  4.94k|  if (vstate->in_function_body())
  ------------------
  |  Branch (299:7): [True: 663, False: 4.27k]
  ------------------
  300|    663|    return vstate->diag(SPV_ERROR_INVALID_LAYOUT, nullptr)
  301|    663|           << "Missing OpFunctionEnd at end of module.";
  302|       |
  303|  4.27k|  if (vstate->HasCapability(spv::Capability::BindlessTextureNV) &&
  ------------------
  |  Branch (303:7): [True: 0, False: 4.27k]
  ------------------
  304|  4.27k|      !vstate->has_samplerimage_variable_address_mode_specified())
  ------------------
  |  Branch (304:7): [True: 0, False: 0]
  ------------------
  305|      0|    return vstate->diag(SPV_ERROR_INVALID_LAYOUT, nullptr)
  306|      0|           << "Missing required OpSamplerImageAddressingModeNV instruction.";
  307|       |
  308|  4.27k|  if (has_mask_task_ext && has_mask_task_nv)
  ------------------
  |  Branch (308:7): [True: 0, False: 4.27k]
  |  Branch (308:28): [True: 0, False: 0]
  ------------------
  309|      0|    return vstate->diag(SPV_ERROR_INVALID_LAYOUT, nullptr)
  310|      0|           << vstate->VkErrorID(7102)
  311|      0|           << "Module can't mix MeshEXT/TaskEXT with MeshNV/TaskNV Execution "
  312|      0|              "Model.";
  313|       |
  314|       |  // Catch undefined forward references before performing further checks.
  315|  4.27k|  if (auto error = ValidateForwardDecls(*vstate)) return error;
  ------------------
  |  Branch (315:12): [True: 602, False: 3.67k]
  ------------------
  316|       |
  317|       |  // Calculate reachability after all the blocks are parsed, but early that it
  318|       |  // can be relied on in subsequent pases.
  319|  3.67k|  ReachabilityPass(*vstate);
  320|       |
  321|       |  // ID usage needs be handled in its own iteration of the instructions,
  322|       |  // between the two others. It depends on the first loop to have been
  323|       |  // finished, so that all instructions have been registered. And the following
  324|       |  // loop depends on all of the usage data being populated. Thus it cannot live
  325|       |  // in either of those iterations.
  326|       |  // It should also live after the forward declaration check, since it will
  327|       |  // have problems with missing forward declarations, but give less useful error
  328|       |  // messages.
  329|   313k|  for (size_t i = 0; i < vstate->ordered_instructions().size(); ++i) {
  ------------------
  |  Branch (329:22): [True: 310k, False: 3.67k]
  ------------------
  330|   310k|    auto& instruction = vstate->ordered_instructions()[i];
  331|   310k|    if (auto error = UpdateIdUse(*vstate, &instruction)) return error;
  ------------------
  |  Branch (331:14): [True: 0, False: 310k]
  ------------------
  332|   310k|  }
  333|       |
  334|       |  // Validate individual opcodes.
  335|   289k|  for (size_t i = 0; i < vstate->ordered_instructions().size(); ++i) {
  ------------------
  |  Branch (335:22): [True: 286k, False: 2.43k]
  ------------------
  336|   286k|    auto& instruction = vstate->ordered_instructions()[i];
  337|       |
  338|       |    // Keep these passes in the order they appear in the SPIR-V specification
  339|       |    // sections to maintain test consistency.
  340|   286k|    if (auto error = MiscPass(*vstate, &instruction)) return error;
  ------------------
  |  Branch (340:14): [True: 2, False: 286k]
  ------------------
  341|   286k|    if (auto error = DebugPass(*vstate, &instruction)) return error;
  ------------------
  |  Branch (341:14): [True: 13, False: 286k]
  ------------------
  342|   286k|    if (auto error = AnnotationPass(*vstate, &instruction)) return error;
  ------------------
  |  Branch (342:14): [True: 67, False: 286k]
  ------------------
  343|   286k|    if (auto error = ExtensionPass(*vstate, &instruction)) return error;
  ------------------
  |  Branch (343:14): [True: 78, False: 286k]
  ------------------
  344|   286k|    if (auto error = ModeSettingPass(*vstate, &instruction)) return error;
  ------------------
  |  Branch (344:14): [True: 49, False: 286k]
  ------------------
  345|   286k|    if (auto error = TypePass(*vstate, &instruction)) return error;
  ------------------
  |  Branch (345:14): [True: 296, False: 286k]
  ------------------
  346|   286k|    if (auto error = ConstantPass(*vstate, &instruction)) return error;
  ------------------
  |  Branch (346:14): [True: 51, False: 286k]
  ------------------
  347|   286k|    if (auto error = MemoryPass(*vstate, &instruction)) return error;
  ------------------
  |  Branch (347:14): [True: 101, False: 285k]
  ------------------
  348|   285k|    if (auto error = FunctionPass(*vstate, &instruction)) return error;
  ------------------
  |  Branch (348:14): [True: 44, False: 285k]
  ------------------
  349|   285k|    if (auto error = ImagePass(*vstate, &instruction)) return error;
  ------------------
  |  Branch (349:14): [True: 166, False: 285k]
  ------------------
  350|   285k|    if (auto error = ConversionPass(*vstate, &instruction)) return error;
  ------------------
  |  Branch (350:14): [True: 34, False: 285k]
  ------------------
  351|   285k|    if (auto error = CompositesPass(*vstate, &instruction)) return error;
  ------------------
  |  Branch (351:14): [True: 116, False: 285k]
  ------------------
  352|   285k|    if (auto error = ArithmeticsPass(*vstate, &instruction)) return error;
  ------------------
  |  Branch (352:14): [True: 66, False: 285k]
  ------------------
  353|   285k|    if (auto error = BitwisePass(*vstate, &instruction)) return error;
  ------------------
  |  Branch (353:14): [True: 15, False: 285k]
  ------------------
  354|   285k|    if (auto error = LogicalsPass(*vstate, &instruction)) return error;
  ------------------
  |  Branch (354:14): [True: 40, False: 285k]
  ------------------
  355|   285k|    if (auto error = ControlFlowPass(*vstate, &instruction)) return error;
  ------------------
  |  Branch (355:14): [True: 68, False: 285k]
  ------------------
  356|   285k|    if (auto error = DerivativesPass(*vstate, &instruction)) return error;
  ------------------
  |  Branch (356:14): [True: 2, False: 285k]
  ------------------
  357|   285k|    if (auto error = AtomicsPass(*vstate, &instruction)) return error;
  ------------------
  |  Branch (357:14): [True: 13, False: 285k]
  ------------------
  358|   285k|    if (auto error = PrimitivesPass(*vstate, &instruction)) return error;
  ------------------
  |  Branch (358:14): [True: 0, False: 285k]
  ------------------
  359|   285k|    if (auto error = BarriersPass(*vstate, &instruction)) return error;
  ------------------
  |  Branch (359:14): [True: 18, False: 285k]
  ------------------
  360|       |    // Group
  361|       |    // Device-Side Enqueue
  362|       |    // Pipe
  363|   285k|    if (auto error = NonUniformPass(*vstate, &instruction)) return error;
  ------------------
  |  Branch (363:14): [True: 0, False: 285k]
  ------------------
  364|       |
  365|   285k|    if (auto error = LiteralsPass(*vstate, &instruction)) return error;
  ------------------
  |  Branch (365:14): [True: 7, False: 285k]
  ------------------
  366|   285k|    if (auto error = RayQueryPass(*vstate, &instruction)) return error;
  ------------------
  |  Branch (366:14): [True: 0, False: 285k]
  ------------------
  367|   285k|    if (auto error = RayTracingPass(*vstate, &instruction)) return error;
  ------------------
  |  Branch (367:14): [True: 0, False: 285k]
  ------------------
  368|   285k|    if (auto error = RayReorderNVPass(*vstate, &instruction)) return error;
  ------------------
  |  Branch (368:14): [True: 0, False: 285k]
  ------------------
  369|   285k|    if (auto error = MeshShadingPass(*vstate, &instruction)) return error;
  ------------------
  |  Branch (369:14): [True: 0, False: 285k]
  ------------------
  370|   285k|  }
  371|       |
  372|       |  // Validate the preconditions involving adjacent instructions. e.g.
  373|       |  // spv::Op::OpPhi must only be preceded by spv::Op::OpLabel, spv::Op::OpPhi,
  374|       |  // or spv::Op::OpLine.
  375|  2.43k|  if (auto error = ValidateAdjacency(*vstate)) return error;
  ------------------
  |  Branch (375:12): [True: 20, False: 2.41k]
  ------------------
  376|       |
  377|  2.41k|  if (auto error = ValidateEntryPoints(*vstate)) return error;
  ------------------
  |  Branch (377:12): [True: 776, False: 1.63k]
  ------------------
  378|       |  // CFG checks are performed after the binary has been parsed
  379|       |  // and the CFGPass has collected information about the control flow
  380|  1.63k|  if (auto error = PerformCfgChecks(*vstate)) return error;
  ------------------
  |  Branch (380:12): [True: 560, False: 1.07k]
  ------------------
  381|  1.07k|  if (auto error = CheckIdDefinitionDominateUse(*vstate)) return error;
  ------------------
  |  Branch (381:12): [True: 51, False: 1.02k]
  ------------------
  382|  1.02k|  if (auto error = ValidateDecorations(*vstate)) return error;
  ------------------
  |  Branch (382:12): [True: 359, False: 664]
  ------------------
  383|    664|  if (auto error = ValidateInterfaces(*vstate)) return error;
  ------------------
  |  Branch (383:12): [True: 31, False: 633]
  ------------------
  384|       |  // TODO(dsinclair): Restructure ValidateBuiltins so we can move into the
  385|       |  // for() above as it loops over all ordered_instructions internally.
  386|    633|  if (auto error = ValidateBuiltIns(*vstate)) return error;
  ------------------
  |  Branch (386:12): [True: 0, False: 633]
  ------------------
  387|       |  // These checks must be performed after individual opcode checks because
  388|       |  // those checks register the limitation checked here.
  389|  69.9k|  for (const auto& inst : vstate->ordered_instructions()) {
  ------------------
  |  Branch (389:25): [True: 69.9k, False: 536]
  ------------------
  390|  69.9k|    if (auto error = ValidateExecutionLimitations(*vstate, &inst)) return error;
  ------------------
  |  Branch (390:14): [True: 97, False: 69.8k]
  ------------------
  391|  69.8k|    if (auto error = ValidateSmallTypeUses(*vstate, &inst)) return error;
  ------------------
  |  Branch (391:14): [True: 0, False: 69.8k]
  ------------------
  392|  69.8k|  }
  393|       |
  394|    536|  return SPV_SUCCESS;
  395|    633|}
validate.cpp:_ZZN8spvtools3val12_GLOBAL__N_144ValidateBinaryUsingContextAndValidationStateERK13spv_context_tPKjmPP16spv_diagnostic_tPNS0_17ValidationState_tEENK3$_0clE19spv_message_level_tPKcRK14spv_position_tSF_:
  199|    337|                                 const spv_position_t&, const char*) {};
validate.cpp:_ZN8spvtools3val12_GLOBAL__N_117ProcessExtensionsEPvPK24spv_parsed_instruction_t:
   73|  16.9k|                               const spv_parsed_instruction_t* inst) {
   74|  16.9k|  const spv::Op opcode = static_cast<spv::Op>(inst->opcode);
   75|  16.9k|  if (opcode == spv::Op::OpCapability) return SPV_SUCCESS;
  ------------------
  |  Branch (75:7): [True: 7.12k, False: 9.85k]
  ------------------
   76|       |
   77|  9.85k|  if (opcode == spv::Op::OpExtension) {
  ------------------
  |  Branch (77:7): [True: 3.05k, False: 6.80k]
  ------------------
   78|  3.05k|    ValidationState_t& _ = *(reinterpret_cast<ValidationState_t*>(user_data));
   79|  3.05k|    RegisterExtension(_, inst);
   80|  3.05k|    return SPV_SUCCESS;
   81|  3.05k|  }
   82|       |
   83|       |  // OpExtension block is finished, requesting termination.
   84|  6.80k|  return SPV_REQUESTED_TERMINATION;
   85|  9.85k|}
validate.cpp:_ZN8spvtools3val12_GLOBAL__N_117RegisterExtensionERNS0_17ValidationState_tEPK24spv_parsed_instruction_t:
   56|  3.05k|                       const spv_parsed_instruction_t* inst) {
   57|  3.05k|  const std::string extension_str = spvtools::GetExtensionString(inst);
   58|  3.05k|  Extension extension;
   59|  3.05k|  if (!GetExtensionFromString(extension_str.c_str(), &extension)) {
  ------------------
  |  Branch (59:7): [True: 1.99k, False: 1.05k]
  ------------------
   60|       |    // The error will be logged in the ProcessInstruction pass.
   61|  1.99k|    return;
   62|  1.99k|  }
   63|       |
   64|  1.05k|  _.RegisterExtension(extension);
   65|  1.05k|}
validate.cpp:_ZN8spvtools3val12_GLOBAL__N_118ProcessInstructionEPvPK24spv_parsed_instruction_t:
   88|   499k|                                const spv_parsed_instruction_t* inst) {
   89|   499k|  ValidationState_t& _ = *(reinterpret_cast<ValidationState_t*>(user_data));
   90|       |
   91|   499k|  auto* instruction = _.AddOrderedInstruction(inst);
   92|   499k|  _.RegisterDebugInstruction(instruction);
   93|       |
   94|   499k|  return SPV_SUCCESS;
   95|   499k|}
validate.cpp:_ZN8spvtools3val12_GLOBAL__N_120ValidateForwardDeclsERNS0_17ValidationState_tE:
   97|  4.27k|spv_result_t ValidateForwardDecls(ValidationState_t& _) {
   98|  4.27k|  if (_.unresolved_forward_id_count() == 0) return SPV_SUCCESS;
  ------------------
  |  Branch (98:7): [True: 3.67k, False: 602]
  ------------------
   99|       |
  100|    602|  std::stringstream ss;
  101|    602|  std::vector<uint32_t> ids = _.UnresolvedForwardIds();
  102|       |
  103|    602|  std::transform(
  104|    602|      std::begin(ids), std::end(ids),
  105|    602|      std::ostream_iterator<std::string>(ss, " "),
  106|    602|      bind(&ValidationState_t::getIdName, std::ref(_), std::placeholders::_1));
  107|       |
  108|    602|  auto id_str = ss.str();
  109|    602|  return _.diag(SPV_ERROR_INVALID_ID, nullptr)
  110|    602|         << "The following forward referenced IDs have not been defined:\n"
  111|    602|         << id_str.substr(0, id_str.size() - 1);
  112|  4.27k|}
validate.cpp:_ZN8spvtools3val12_GLOBAL__N_119ValidateEntryPointsERNS0_17ValidationState_tE:
  122|  2.41k|spv_result_t ValidateEntryPoints(ValidationState_t& _) {
  123|  2.41k|  _.ComputeFunctionToEntryPointMapping();
  124|  2.41k|  _.ComputeRecursiveEntryPoints();
  125|       |
  126|  2.41k|  if (_.entry_points().empty() && !_.HasCapability(spv::Capability::Linkage)) {
  ------------------
  |  Branch (126:7): [True: 1.07k, False: 1.33k]
  |  Branch (126:35): [True: 774, False: 300]
  ------------------
  127|    774|    return _.diag(SPV_ERROR_INVALID_BINARY, nullptr)
  128|    774|           << "No OpEntryPoint instruction was found. This is only allowed if "
  129|    774|              "the Linkage capability is being used.";
  130|    774|  }
  131|       |
  132|  1.63k|  for (const auto& entry_point : _.entry_points()) {
  ------------------
  |  Branch (132:32): [True: 1.49k, False: 1.63k]
  ------------------
  133|  1.49k|    if (_.IsFunctionCallTarget(entry_point)) {
  ------------------
  |  Branch (133:9): [True: 2, False: 1.49k]
  ------------------
  134|      2|      return _.diag(SPV_ERROR_INVALID_BINARY, _.FindDef(entry_point))
  135|      2|             << "A function (" << entry_point
  136|      2|             << ") may not be targeted by both an OpEntryPoint instruction and "
  137|      2|                "an OpFunctionCall instruction.";
  138|      2|    }
  139|       |
  140|       |    // For Vulkan, the static function-call graph for an entry point
  141|       |    // must not contain cycles.
  142|  1.49k|    if (spvIsVulkanEnv(_.context()->target_env)) {
  ------------------
  |  Branch (142:9): [True: 0, False: 1.49k]
  ------------------
  143|      0|      if (_.recursive_entry_points().find(entry_point) !=
  ------------------
  |  Branch (143:11): [True: 0, False: 0]
  ------------------
  144|      0|          _.recursive_entry_points().end()) {
  145|      0|        return _.diag(SPV_ERROR_INVALID_BINARY, _.FindDef(entry_point))
  146|      0|               << _.VkErrorID(4634)
  147|      0|               << "Entry points may not have a call graph with cycles.";
  148|      0|      }
  149|      0|    }
  150|  1.49k|  }
  151|       |
  152|  1.63k|  return SPV_SUCCESS;
  153|  1.63k|}

_ZN8spvtools3val17ValidateAdjacencyERNS0_17ValidationState_tE:
   42|  2.43k|spv_result_t ValidateAdjacency(ValidationState_t& _) {
   43|  2.43k|  const auto& instructions = _.ordered_instructions();
   44|  2.43k|  int adjacency_status = PHI_AND_VAR_INVALID;
   45|       |
   46|   242k|  for (size_t i = 0; i < instructions.size(); ++i) {
  ------------------
  |  Branch (46:22): [True: 240k, False: 2.41k]
  ------------------
   47|   240k|    const auto& inst = instructions[i];
   48|   240k|    switch (inst.opcode()) {
   49|  2.03k|      case spv::Op::OpFunction:
  ------------------
  |  Branch (49:7): [True: 2.03k, False: 238k]
  ------------------
   50|  2.40k|      case spv::Op::OpFunctionParameter:
  ------------------
  |  Branch (50:7): [True: 369, False: 239k]
  ------------------
   51|  2.40k|        adjacency_status = IN_NEW_FUNCTION;
   52|  2.40k|        break;
   53|  35.9k|      case spv::Op::OpLabel:
  ------------------
  |  Branch (53:7): [True: 35.9k, False: 204k]
  ------------------
   54|  35.9k|        adjacency_status =
   55|  35.9k|            adjacency_status == IN_NEW_FUNCTION ? IN_ENTRY_BLOCK : PHI_VALID;
  ------------------
  |  Branch (55:13): [True: 1.73k, False: 34.2k]
  ------------------
   56|  35.9k|        break;
   57|  1.25k|      case spv::Op::OpExtInst:
  ------------------
  |  Branch (57:7): [True: 1.25k, False: 239k]
  ------------------
   58|       |        // If it is a debug info instruction, we do not change the status to
   59|       |        // allow debug info instructions before OpVariable in a function.
   60|       |        // TODO(https://gitlab.khronos.org/spirv/SPIR-V/issues/533): We need
   61|       |        // to discuss the location of DebugScope, DebugNoScope, DebugDeclare,
   62|       |        // and DebugValue.
   63|       |        // NOTE: This does not apply to the non-semantic vulkan debug info.
   64|  1.25k|        if (!spvExtInstIsDebugInfo(inst.ext_inst_type()) ||
  ------------------
  |  Branch (64:13): [True: 1.25k, False: 0]
  ------------------
   65|  1.25k|            inst.ext_inst_type() ==
  ------------------
  |  Branch (65:13): [True: 0, False: 0]
  ------------------
   66|  1.25k|                SPV_EXT_INST_TYPE_NONSEMANTIC_SHADER_DEBUGINFO_100) {
   67|  1.25k|          adjacency_status = PHI_AND_VAR_INVALID;
   68|  1.25k|        }
   69|  1.25k|        break;
   70|  5.89k|      case spv::Op::OpPhi:
  ------------------
  |  Branch (70:7): [True: 5.89k, False: 234k]
  ------------------
   71|  5.89k|        if (adjacency_status != PHI_VALID) {
  ------------------
  |  Branch (71:13): [True: 9, False: 5.88k]
  ------------------
   72|      9|          return _.diag(SPV_ERROR_INVALID_DATA, &inst)
   73|      9|                 << "OpPhi must appear within a non-entry block before all "
   74|      9|                 << "non-OpPhi instructions "
   75|      9|                 << "(except for OpLine, which can be mixed with OpPhi).";
   76|      9|        }
   77|  5.88k|        break;
   78|  5.88k|      case spv::Op::OpLine:
  ------------------
  |  Branch (78:7): [True: 16, False: 240k]
  ------------------
   79|  12.4k|      case spv::Op::OpNoLine:
  ------------------
  |  Branch (79:7): [True: 12.3k, False: 227k]
  ------------------
   80|  12.4k|        break;
   81|  3.19k|      case spv::Op::OpLoopMerge:
  ------------------
  |  Branch (81:7): [True: 3.19k, False: 237k]
  ------------------
   82|  3.19k|        adjacency_status = PHI_AND_VAR_INVALID;
   83|  3.19k|        if (i != (instructions.size() - 1)) {
  ------------------
  |  Branch (83:13): [True: 3.19k, False: 0]
  ------------------
   84|  3.19k|          switch (instructions[i + 1].opcode()) {
   85|  1.24k|            case spv::Op::OpBranch:
  ------------------
  |  Branch (85:13): [True: 1.24k, False: 1.95k]
  ------------------
   86|  3.18k|            case spv::Op::OpBranchConditional:
  ------------------
  |  Branch (86:13): [True: 1.94k, False: 1.24k]
  ------------------
   87|  3.18k|              break;
   88|      6|            default:
  ------------------
  |  Branch (88:13): [True: 6, False: 3.18k]
  ------------------
   89|      6|              return _.diag(SPV_ERROR_INVALID_DATA, &inst)
   90|      6|                     << "OpLoopMerge must immediately precede either an "
   91|      6|                     << "OpBranch or OpBranchConditional instruction. "
   92|      6|                     << "OpLoopMerge must be the second-to-last instruction in "
   93|      6|                     << "its block.";
   94|  3.19k|          }
   95|  3.19k|        }
   96|  3.18k|        break;
   97|  7.20k|      case spv::Op::OpSelectionMerge:
  ------------------
  |  Branch (97:7): [True: 7.20k, False: 233k]
  ------------------
   98|  7.20k|        adjacency_status = PHI_AND_VAR_INVALID;
   99|  7.20k|        if (i != (instructions.size() - 1)) {
  ------------------
  |  Branch (99:13): [True: 7.20k, False: 0]
  ------------------
  100|  7.20k|          switch (instructions[i + 1].opcode()) {
  101|  5.40k|            case spv::Op::OpBranchConditional:
  ------------------
  |  Branch (101:13): [True: 5.40k, False: 1.80k]
  ------------------
  102|  7.20k|            case spv::Op::OpSwitch:
  ------------------
  |  Branch (102:13): [True: 1.79k, False: 5.41k]
  ------------------
  103|  7.20k|              break;
  104|      4|            default:
  ------------------
  |  Branch (104:13): [True: 4, False: 7.20k]
  ------------------
  105|      4|              return _.diag(SPV_ERROR_INVALID_DATA, &inst)
  106|      4|                     << "OpSelectionMerge must immediately precede either an "
  107|      4|                     << "OpBranchConditional or OpSwitch instruction. "
  108|      4|                     << "OpSelectionMerge must be the second-to-last "
  109|      4|                     << "instruction in its block.";
  110|  7.20k|          }
  111|  7.20k|        }
  112|  7.20k|        break;
  113|  7.20k|      case spv::Op::OpVariable:
  ------------------
  |  Branch (113:7): [True: 5.17k, False: 235k]
  ------------------
  114|  5.17k|        if (inst.GetOperandAs<spv::StorageClass>(2) ==
  ------------------
  |  Branch (114:13): [True: 3.44k, False: 1.73k]
  ------------------
  115|  5.17k|                spv::StorageClass::Function &&
  116|  5.17k|            adjacency_status != IN_ENTRY_BLOCK) {
  ------------------
  |  Branch (116:13): [True: 1, False: 3.44k]
  ------------------
  117|      1|          return _.diag(SPV_ERROR_INVALID_DATA, &inst)
  118|      1|                 << "All OpVariable instructions in a function must be the "
  119|      1|                    "first instructions in the first block.";
  120|      1|        }
  121|  5.17k|        break;
  122|   166k|      default:
  ------------------
  |  Branch (122:7): [True: 166k, False: 73.4k]
  ------------------
  123|   166k|        adjacency_status = PHI_AND_VAR_INVALID;
  124|   166k|        break;
  125|   240k|    }
  126|   240k|  }
  127|       |
  128|  2.41k|  return SPV_SUCCESS;
  129|  2.43k|}

_ZN8spvtools3val14AnnotationPassERNS0_17ValidationState_tEPKNS0_11InstructionE:
  493|   286k|spv_result_t AnnotationPass(ValidationState_t& _, const Instruction* inst) {
  494|   286k|  switch (inst->opcode()) {
  495|  13.2k|    case spv::Op::OpDecorate:
  ------------------
  |  Branch (495:5): [True: 13.2k, False: 273k]
  ------------------
  496|  13.2k|      if (auto error = ValidateDecorate(_, inst)) return error;
  ------------------
  |  Branch (496:16): [True: 18, False: 13.2k]
  ------------------
  497|  13.2k|      break;
  498|  13.2k|    case spv::Op::OpDecorateId:
  ------------------
  |  Branch (498:5): [True: 0, False: 286k]
  ------------------
  499|      0|      if (auto error = ValidateDecorateId(_, inst)) return error;
  ------------------
  |  Branch (499:16): [True: 0, False: 0]
  ------------------
  500|      0|      break;
  501|       |    // TODO(dneto): spv::Op::OpDecorateStringGOOGLE
  502|       |    // See https://github.com/KhronosGroup/SPIRV-Tools/issues/2253
  503|    833|    case spv::Op::OpMemberDecorate:
  ------------------
  |  Branch (503:5): [True: 833, False: 285k]
  ------------------
  504|    833|      if (auto error = ValidateMemberDecorate(_, inst)) return error;
  ------------------
  |  Branch (504:16): [True: 19, False: 814]
  ------------------
  505|    814|      break;
  506|    814|    case spv::Op::OpDecorationGroup:
  ------------------
  |  Branch (506:5): [True: 391, False: 286k]
  ------------------
  507|    391|      if (auto error = ValidateDecorationGroup(_, inst)) return error;
  ------------------
  |  Branch (507:16): [True: 3, False: 388]
  ------------------
  508|    388|      break;
  509|  1.70k|    case spv::Op::OpGroupDecorate:
  ------------------
  |  Branch (509:5): [True: 1.70k, False: 284k]
  ------------------
  510|  1.70k|      if (auto error = ValidateGroupDecorate(_, inst)) return error;
  ------------------
  |  Branch (510:16): [True: 7, False: 1.69k]
  ------------------
  511|  1.69k|      break;
  512|  1.69k|    case spv::Op::OpGroupMemberDecorate:
  ------------------
  |  Branch (512:5): [True: 389, False: 286k]
  ------------------
  513|    389|      if (auto error = ValidateGroupMemberDecorate(_, inst)) return error;
  ------------------
  |  Branch (513:16): [True: 20, False: 369]
  ------------------
  514|    369|      break;
  515|   270k|    default:
  ------------------
  |  Branch (515:5): [True: 270k, False: 16.5k]
  ------------------
  516|   270k|      break;
  517|   286k|  }
  518|       |
  519|       |  // In order to validate decoration rules, we need to know all the decorations
  520|       |  // that are applied to any given <id>.
  521|   286k|  RegisterDecorations(_, inst);
  522|       |
  523|   286k|  return SPV_SUCCESS;
  524|   286k|}
validate_annotation.cpp:_ZN8spvtools3val12_GLOBAL__N_116ValidateDecorateERNS0_17ValidationState_tEPKNS0_11InstructionE:
  250|  13.2k|spv_result_t ValidateDecorate(ValidationState_t& _, const Instruction* inst) {
  251|  13.2k|  const auto decoration = inst->GetOperandAs<spv::Decoration>(1);
  252|  13.2k|  const auto target_id = inst->GetOperandAs<uint32_t>(0);
  253|  13.2k|  const auto target = _.FindDef(target_id);
  254|  13.2k|  if (!target) {
  ------------------
  |  Branch (254:7): [True: 0, False: 13.2k]
  ------------------
  255|      0|    return _.diag(SPV_ERROR_INVALID_ID, inst) << "target is not defined";
  256|      0|  }
  257|       |
  258|  13.2k|  if (spvIsVulkanEnv(_.context()->target_env)) {
  ------------------
  |  Branch (258:7): [True: 0, False: 13.2k]
  ------------------
  259|      0|    if ((decoration == spv::Decoration::GLSLShared) ||
  ------------------
  |  Branch (259:9): [True: 0, False: 0]
  ------------------
  260|      0|        (decoration == spv::Decoration::GLSLPacked)) {
  ------------------
  |  Branch (260:9): [True: 0, False: 0]
  ------------------
  261|      0|      return _.diag(SPV_ERROR_INVALID_ID, inst)
  262|      0|             << _.VkErrorID(4669) << "OpDecorate decoration '"
  263|      0|             << _.SpvDecorationString(decoration)
  264|      0|             << "' is not valid for the Vulkan execution environment.";
  265|      0|    }
  266|      0|  }
  267|       |
  268|  13.2k|  if (DecorationTakesIdParameters(decoration)) {
  ------------------
  |  Branch (268:7): [True: 0, False: 13.2k]
  ------------------
  269|      0|    return _.diag(SPV_ERROR_INVALID_ID, inst)
  270|      0|           << "Decorations taking ID parameters may not be used with "
  271|      0|              "OpDecorateId";
  272|      0|  }
  273|       |
  274|  13.2k|  if (target->opcode() != spv::Op::OpDecorationGroup) {
  ------------------
  |  Branch (274:7): [True: 9.16k, False: 4.10k]
  ------------------
  275|  9.16k|    if (IsMemberDecorationOnly(decoration)) {
  ------------------
  |  Branch (275:9): [True: 0, False: 9.16k]
  ------------------
  276|      0|      return _.diag(SPV_ERROR_INVALID_ID, inst)
  277|      0|             << _.SpvDecorationString(decoration)
  278|      0|             << " can only be applied to structure members";
  279|      0|    }
  280|       |
  281|  9.16k|    if (auto error = ValidateDecorationTarget(_, decoration, inst, target)) {
  ------------------
  |  Branch (281:14): [True: 18, False: 9.15k]
  ------------------
  282|     18|      return error;
  283|     18|    }
  284|  9.16k|  }
  285|       |
  286|       |  // TODO: Add validations for all decorations.
  287|  13.2k|  return SPV_SUCCESS;
  288|  13.2k|}
validate_annotation.cpp:_ZN8spvtools3val12_GLOBAL__N_127DecorationTakesIdParametersEN3spv10DecorationE:
   27|  13.2k|bool DecorationTakesIdParameters(spv::Decoration type) {
   28|  13.2k|  switch (type) {
   29|      0|    case spv::Decoration::UniformId:
  ------------------
  |  Branch (29:5): [True: 0, False: 13.2k]
  ------------------
   30|      0|    case spv::Decoration::AlignmentId:
  ------------------
  |  Branch (30:5): [True: 0, False: 13.2k]
  ------------------
   31|      0|    case spv::Decoration::MaxByteOffsetId:
  ------------------
  |  Branch (31:5): [True: 0, False: 13.2k]
  ------------------
   32|      0|    case spv::Decoration::HlslCounterBufferGOOGLE:
  ------------------
  |  Branch (32:5): [True: 0, False: 13.2k]
  ------------------
   33|      0|      return true;
   34|  13.2k|    default:
  ------------------
  |  Branch (34:5): [True: 13.2k, False: 0]
  ------------------
   35|  13.2k|      break;
   36|  13.2k|  }
   37|  13.2k|  return false;
   38|  13.2k|}
validate_annotation.cpp:_ZN8spvtools3val12_GLOBAL__N_122IsMemberDecorationOnlyEN3spv10DecorationE:
   40|  9.16k|bool IsMemberDecorationOnly(spv::Decoration dec) {
   41|  9.16k|  switch (dec) {
   42|      0|    case spv::Decoration::RowMajor:
  ------------------
  |  Branch (42:5): [True: 0, False: 9.16k]
  ------------------
   43|      0|    case spv::Decoration::ColMajor:
  ------------------
  |  Branch (43:5): [True: 0, False: 9.16k]
  ------------------
   44|      0|    case spv::Decoration::MatrixStride:
  ------------------
  |  Branch (44:5): [True: 0, False: 9.16k]
  ------------------
   45|       |      // SPIR-V spec bug? Offset is generated on variables when dealing with
   46|       |      // transform feedback.
   47|       |      // case spv::Decoration::Offset:
   48|      0|      return true;
   49|  9.16k|    default:
  ------------------
  |  Branch (49:5): [True: 9.16k, False: 0]
  ------------------
   50|  9.16k|      break;
   51|  9.16k|  }
   52|  9.16k|  return false;
   53|  9.16k|}
validate_annotation.cpp:_ZN8spvtools3val12_GLOBAL__N_124ValidateDecorationTargetERNS0_17ValidationState_tEN3spv10DecorationEPKNS0_11InstructionES8_:
  100|  9.16k|                                      const Instruction* target) {
  101|  9.16k|  auto fail = [&_, dec, inst, target](uint32_t vuid) -> DiagnosticStream {
  102|  9.16k|    DiagnosticStream ds = std::move(
  103|  9.16k|        _.diag(SPV_ERROR_INVALID_ID, inst)
  104|  9.16k|        << _.VkErrorID(vuid) << _.SpvDecorationString(dec)
  105|  9.16k|        << " decoration on target <id> " << _.getIdName(target->id()) << " ");
  106|  9.16k|    return ds;
  107|  9.16k|  };
  108|  9.16k|  switch (dec) {
  109|     16|    case spv::Decoration::SpecId:
  ------------------
  |  Branch (109:5): [True: 16, False: 9.15k]
  ------------------
  110|     16|      if (!spvOpcodeIsScalarSpecConstant(target->opcode())) {
  ------------------
  |  Branch (110:11): [True: 0, False: 16]
  ------------------
  111|      0|        return fail(0) << "must be a scalar specialization constant";
  112|      0|      }
  113|     16|      break;
  114|    254|    case spv::Decoration::Block:
  ------------------
  |  Branch (114:5): [True: 254, False: 8.91k]
  ------------------
  115|    314|    case spv::Decoration::BufferBlock:
  ------------------
  |  Branch (115:5): [True: 60, False: 9.10k]
  ------------------
  116|    379|    case spv::Decoration::GLSLShared:
  ------------------
  |  Branch (116:5): [True: 65, False: 9.10k]
  ------------------
  117|    425|    case spv::Decoration::GLSLPacked:
  ------------------
  |  Branch (117:5): [True: 46, False: 9.12k]
  ------------------
  118|    428|    case spv::Decoration::CPacked:
  ------------------
  |  Branch (118:5): [True: 3, False: 9.16k]
  ------------------
  119|    428|      if (target->opcode() != spv::Op::OpTypeStruct) {
  ------------------
  |  Branch (119:11): [True: 2, False: 426]
  ------------------
  120|      2|        return fail(0) << "must be a structure type";
  121|      2|      }
  122|    426|      break;
  123|    426|    case spv::Decoration::ArrayStride:
  ------------------
  |  Branch (123:5): [True: 146, False: 9.02k]
  ------------------
  124|    146|      if (target->opcode() != spv::Op::OpTypeArray &&
  ------------------
  |  Branch (124:11): [True: 31, False: 115]
  ------------------
  125|    146|          target->opcode() != spv::Op::OpTypeRuntimeArray &&
  ------------------
  |  Branch (125:11): [True: 25, False: 6]
  ------------------
  126|    146|          target->opcode() != spv::Op::OpTypePointer) {
  ------------------
  |  Branch (126:11): [True: 3, False: 22]
  ------------------
  127|      3|        return fail(0) << "must be an array or pointer type";
  128|      3|      }
  129|    143|      break;
  130|    232|    case spv::Decoration::BuiltIn:
  ------------------
  |  Branch (130:5): [True: 232, False: 8.93k]
  ------------------
  131|    232|      if (target->opcode() != spv::Op::OpVariable &&
  ------------------
  |  Branch (131:11): [True: 94, False: 138]
  ------------------
  132|    232|          !spvOpcodeIsConstant(target->opcode())) {
  ------------------
  |  Branch (132:11): [True: 0, False: 94]
  ------------------
  133|      0|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
  134|      0|               << "BuiltIns can only target variables, structure members or "
  135|      0|                  "constants";
  136|      0|      }
  137|    232|      if (_.HasCapability(spv::Capability::Shader) &&
  ------------------
  |  Branch (137:11): [True: 229, False: 3]
  ------------------
  138|    232|          inst->GetOperandAs<spv::BuiltIn>(2) == spv::BuiltIn::WorkgroupSize) {
  ------------------
  |  Branch (138:11): [True: 93, False: 136]
  ------------------
  139|     93|        if (!spvOpcodeIsConstant(target->opcode())) {
  ------------------
  |  Branch (139:13): [True: 0, False: 93]
  ------------------
  140|      0|          return fail(0) << "must be a constant for WorkgroupSize";
  141|      0|        }
  142|    139|      } else if (target->opcode() != spv::Op::OpVariable) {
  ------------------
  |  Branch (142:18): [True: 1, False: 138]
  ------------------
  143|      1|        return fail(0) << "must be a variable";
  144|      1|      }
  145|    231|      break;
  146|    231|    case spv::Decoration::NoPerspective:
  ------------------
  |  Branch (146:5): [True: 52, False: 9.11k]
  ------------------
  147|     77|    case spv::Decoration::Flat:
  ------------------
  |  Branch (147:5): [True: 25, False: 9.14k]
  ------------------
  148|     77|    case spv::Decoration::Patch:
  ------------------
  |  Branch (148:5): [True: 0, False: 9.16k]
  ------------------
  149|    310|    case spv::Decoration::Centroid:
  ------------------
  |  Branch (149:5): [True: 233, False: 8.93k]
  ------------------
  150|    328|    case spv::Decoration::Sample:
  ------------------
  |  Branch (150:5): [True: 18, False: 9.15k]
  ------------------
  151|    507|    case spv::Decoration::Restrict:
  ------------------
  |  Branch (151:5): [True: 179, False: 8.98k]
  ------------------
  152|  1.33k|    case spv::Decoration::Aliased:
  ------------------
  |  Branch (152:5): [True: 823, False: 8.34k]
  ------------------
  153|  1.44k|    case spv::Decoration::Volatile:
  ------------------
  |  Branch (153:5): [True: 114, False: 9.05k]
  ------------------
  154|  1.50k|    case spv::Decoration::Coherent:
  ------------------
  |  Branch (154:5): [True: 60, False: 9.10k]
  ------------------
  155|  1.55k|    case spv::Decoration::NonWritable:
  ------------------
  |  Branch (155:5): [True: 51, False: 9.11k]
  ------------------
  156|  1.56k|    case spv::Decoration::NonReadable:
  ------------------
  |  Branch (156:5): [True: 9, False: 9.15k]
  ------------------
  157|  1.56k|    case spv::Decoration::XfbBuffer:
  ------------------
  |  Branch (157:5): [True: 4, False: 9.16k]
  ------------------
  158|  1.57k|    case spv::Decoration::XfbStride:
  ------------------
  |  Branch (158:5): [True: 2, False: 9.16k]
  ------------------
  159|  3.32k|    case spv::Decoration::Component:
  ------------------
  |  Branch (159:5): [True: 1.75k, False: 7.41k]
  ------------------
  160|  3.32k|    case spv::Decoration::Stream:
  ------------------
  |  Branch (160:5): [True: 8, False: 9.16k]
  ------------------
  161|  3.32k|    case spv::Decoration::RestrictPointer:
  ------------------
  |  Branch (161:5): [True: 0, False: 9.16k]
  ------------------
  162|  3.32k|    case spv::Decoration::AliasedPointer:
  ------------------
  |  Branch (162:5): [True: 0, False: 9.16k]
  ------------------
  163|  3.32k|      if (target->opcode() != spv::Op::OpVariable &&
  ------------------
  |  Branch (163:11): [True: 17, False: 3.31k]
  ------------------
  164|  3.32k|          target->opcode() != spv::Op::OpFunctionParameter) {
  ------------------
  |  Branch (164:11): [True: 6, False: 11]
  ------------------
  165|      6|        return fail(0) << "must be a memory object declaration";
  166|      6|      }
  167|  3.32k|      if (_.GetIdOpcode(target->type_id()) != spv::Op::OpTypePointer) {
  ------------------
  |  Branch (167:11): [True: 3, False: 3.31k]
  ------------------
  168|      3|        return fail(0) << "must be a pointer type";
  169|      3|      }
  170|  3.31k|      break;
  171|  3.31k|    case spv::Decoration::Invariant:
  ------------------
  |  Branch (171:5): [True: 243, False: 8.92k]
  ------------------
  172|    251|    case spv::Decoration::Constant:
  ------------------
  |  Branch (172:5): [True: 8, False: 9.16k]
  ------------------
  173|    603|    case spv::Decoration::Location:
  ------------------
  |  Branch (173:5): [True: 352, False: 8.81k]
  ------------------
  174|    741|    case spv::Decoration::Index:
  ------------------
  |  Branch (174:5): [True: 138, False: 9.03k]
  ------------------
  175|  1.21k|    case spv::Decoration::Binding:
  ------------------
  |  Branch (175:5): [True: 474, False: 8.69k]
  ------------------
  176|  1.39k|    case spv::Decoration::DescriptorSet:
  ------------------
  |  Branch (176:5): [True: 179, False: 8.98k]
  ------------------
  177|  1.39k|    case spv::Decoration::InputAttachmentIndex:
  ------------------
  |  Branch (177:5): [True: 0, False: 9.16k]
  ------------------
  178|  1.39k|      if (target->opcode() != spv::Op::OpVariable) {
  ------------------
  |  Branch (178:11): [True: 3, False: 1.39k]
  ------------------
  179|      3|        return fail(0) << "must be a variable";
  180|      3|      }
  181|  1.39k|      break;
  182|  3.62k|    default:
  ------------------
  |  Branch (182:5): [True: 3.62k, False: 5.54k]
  ------------------
  183|  3.62k|      break;
  184|  9.16k|  }
  185|       |
  186|  9.15k|  if (spvIsVulkanEnv(_.context()->target_env)) {
  ------------------
  |  Branch (186:7): [True: 0, False: 9.15k]
  ------------------
  187|       |    // The following were all checked as pointer types above.
  188|      0|    spv::StorageClass sc = spv::StorageClass::Uniform;
  189|      0|    const auto type = _.FindDef(target->type_id());
  190|      0|    if (type && type->operands().size() > 2) {
  ------------------
  |  Branch (190:9): [True: 0, False: 0]
  |  Branch (190:17): [True: 0, False: 0]
  ------------------
  191|      0|      sc = type->GetOperandAs<spv::StorageClass>(1);
  192|      0|    }
  193|      0|    switch (dec) {
  194|      0|      case spv::Decoration::Location:
  ------------------
  |  Branch (194:7): [True: 0, False: 0]
  ------------------
  195|      0|      case spv::Decoration::Component:
  ------------------
  |  Branch (195:7): [True: 0, False: 0]
  ------------------
  196|       |        // Location is used for input, output and ray tracing stages.
  197|      0|        if (sc != spv::StorageClass::Input && sc != spv::StorageClass::Output &&
  ------------------
  |  Branch (197:13): [True: 0, False: 0]
  |  Branch (197:47): [True: 0, False: 0]
  ------------------
  198|      0|            sc != spv::StorageClass::RayPayloadKHR &&
  ------------------
  |  Branch (198:13): [True: 0, False: 0]
  ------------------
  199|      0|            sc != spv::StorageClass::IncomingRayPayloadKHR &&
  ------------------
  |  Branch (199:13): [True: 0, False: 0]
  ------------------
  200|      0|            sc != spv::StorageClass::HitAttributeKHR &&
  ------------------
  |  Branch (200:13): [True: 0, False: 0]
  ------------------
  201|      0|            sc != spv::StorageClass::CallableDataKHR &&
  ------------------
  |  Branch (201:13): [True: 0, False: 0]
  ------------------
  202|      0|            sc != spv::StorageClass::IncomingCallableDataKHR &&
  ------------------
  |  Branch (202:13): [True: 0, False: 0]
  ------------------
  203|      0|            sc != spv::StorageClass::ShaderRecordBufferKHR &&
  ------------------
  |  Branch (203:13): [True: 0, False: 0]
  ------------------
  204|      0|            sc != spv::StorageClass::HitObjectAttributeNV) {
  ------------------
  |  Branch (204:13): [True: 0, False: 0]
  ------------------
  205|      0|          return _.diag(SPV_ERROR_INVALID_ID, target)
  206|      0|                 << _.VkErrorID(6672) << _.SpvDecorationString(dec)
  207|      0|                 << " decoration must not be applied to this storage class";
  208|      0|        }
  209|      0|        break;
  210|      0|      case spv::Decoration::Index:
  ------------------
  |  Branch (210:7): [True: 0, False: 0]
  ------------------
  211|       |        // Langauge from SPIR-V definition of Index
  212|      0|        if (sc != spv::StorageClass::Output) {
  ------------------
  |  Branch (212:13): [True: 0, False: 0]
  ------------------
  213|      0|          return fail(0) << "must be in the Output storage class";
  214|      0|        }
  215|      0|        break;
  216|      0|      case spv::Decoration::Binding:
  ------------------
  |  Branch (216:7): [True: 0, False: 0]
  ------------------
  217|      0|      case spv::Decoration::DescriptorSet:
  ------------------
  |  Branch (217:7): [True: 0, False: 0]
  ------------------
  218|      0|        if (sc != spv::StorageClass::StorageBuffer &&
  ------------------
  |  Branch (218:13): [True: 0, False: 0]
  ------------------
  219|      0|            sc != spv::StorageClass::Uniform &&
  ------------------
  |  Branch (219:13): [True: 0, False: 0]
  ------------------
  220|      0|            sc != spv::StorageClass::UniformConstant) {
  ------------------
  |  Branch (220:13): [True: 0, False: 0]
  ------------------
  221|      0|          return fail(6491) << "must be in the StorageBuffer, Uniform, or "
  222|      0|                               "UniformConstant storage class";
  223|      0|        }
  224|      0|        break;
  225|      0|      case spv::Decoration::InputAttachmentIndex:
  ------------------
  |  Branch (225:7): [True: 0, False: 0]
  ------------------
  226|      0|        if (sc != spv::StorageClass::UniformConstant) {
  ------------------
  |  Branch (226:13): [True: 0, False: 0]
  ------------------
  227|      0|          return fail(6678) << "must be in the UniformConstant storage class";
  228|      0|        }
  229|      0|        break;
  230|      0|      case spv::Decoration::Flat:
  ------------------
  |  Branch (230:7): [True: 0, False: 0]
  ------------------
  231|      0|      case spv::Decoration::NoPerspective:
  ------------------
  |  Branch (231:7): [True: 0, False: 0]
  ------------------
  232|      0|      case spv::Decoration::Centroid:
  ------------------
  |  Branch (232:7): [True: 0, False: 0]
  ------------------
  233|      0|      case spv::Decoration::Sample:
  ------------------
  |  Branch (233:7): [True: 0, False: 0]
  ------------------
  234|      0|        if (sc != spv::StorageClass::Input && sc != spv::StorageClass::Output) {
  ------------------
  |  Branch (234:13): [True: 0, False: 0]
  |  Branch (234:47): [True: 0, False: 0]
  ------------------
  235|      0|          return fail(4670) << "storage class must be Input or Output";
  236|      0|        }
  237|      0|        break;
  238|      0|      case spv::Decoration::PerVertexKHR:
  ------------------
  |  Branch (238:7): [True: 0, False: 0]
  ------------------
  239|      0|        if (sc != spv::StorageClass::Input) {
  ------------------
  |  Branch (239:13): [True: 0, False: 0]
  ------------------
  240|      0|          return fail(6777) << "storage class must be Input";
  241|      0|        }
  242|      0|        break;
  243|      0|      default:
  ------------------
  |  Branch (243:7): [True: 0, False: 0]
  ------------------
  244|      0|        break;
  245|      0|    }
  246|      0|  }
  247|  9.15k|  return SPV_SUCCESS;
  248|  9.15k|}
validate_annotation.cpp:_ZZN8spvtools3val12_GLOBAL__N_124ValidateDecorationTargetERNS0_17ValidationState_tEN3spv10DecorationEPKNS0_11InstructionES8_ENK3$_0clEj:
  101|     18|  auto fail = [&_, dec, inst, target](uint32_t vuid) -> DiagnosticStream {
  102|     18|    DiagnosticStream ds = std::move(
  103|     18|        _.diag(SPV_ERROR_INVALID_ID, inst)
  104|     18|        << _.VkErrorID(vuid) << _.SpvDecorationString(dec)
  105|     18|        << " decoration on target <id> " << _.getIdName(target->id()) << " ");
  106|     18|    return ds;
  107|     18|  };
validate_annotation.cpp:_ZN8spvtools3val12_GLOBAL__N_122ValidateMemberDecorateERNS0_17ValidationState_tEPKNS0_11InstructionE:
  307|    833|                                    const Instruction* inst) {
  308|    833|  const auto struct_type_id = inst->GetOperandAs<uint32_t>(0);
  309|    833|  const auto struct_type = _.FindDef(struct_type_id);
  310|    833|  if (!struct_type || spv::Op::OpTypeStruct != struct_type->opcode()) {
  ------------------
  |  Branch (310:7): [True: 0, False: 833]
  |  Branch (310:23): [True: 3, False: 830]
  ------------------
  311|      3|    return _.diag(SPV_ERROR_INVALID_ID, inst)
  312|      3|           << "OpMemberDecorate Structure type <id> "
  313|      3|           << _.getIdName(struct_type_id) << " is not a struct type.";
  314|      3|  }
  315|    830|  const auto member = inst->GetOperandAs<uint32_t>(1);
  316|    830|  const auto member_count =
  317|    830|      static_cast<uint32_t>(struct_type->words().size() - 2);
  318|    830|  if (member_count <= member) {
  ------------------
  |  Branch (318:7): [True: 9, False: 821]
  ------------------
  319|      9|    return _.diag(SPV_ERROR_INVALID_ID, inst)
  320|      9|           << "Index " << member
  321|      9|           << " provided in OpMemberDecorate for struct <id> "
  322|      9|           << _.getIdName(struct_type_id)
  323|      9|           << " is out of bounds. The structure has " << member_count
  324|      9|           << " members. Largest valid index is " << member_count - 1 << ".";
  325|      9|  }
  326|       |
  327|    821|  const auto decoration = inst->GetOperandAs<spv::Decoration>(2);
  328|    821|  if (IsNotMemberDecoration(decoration)) {
  ------------------
  |  Branch (328:7): [True: 7, False: 814]
  ------------------
  329|      7|    return _.diag(SPV_ERROR_INVALID_ID, inst)
  330|      7|           << _.SpvDecorationString(decoration)
  331|      7|           << " cannot be applied to structure members";
  332|      7|  }
  333|       |
  334|    814|  return SPV_SUCCESS;
  335|    821|}
validate_annotation.cpp:_ZN8spvtools3val12_GLOBAL__N_121IsNotMemberDecorationEN3spv10DecorationE:
   55|    821|bool IsNotMemberDecoration(spv::Decoration dec) {
   56|    821|  switch (dec) {
   57|      0|    case spv::Decoration::SpecId:
  ------------------
  |  Branch (57:5): [True: 0, False: 821]
  ------------------
   58|      0|    case spv::Decoration::Block:
  ------------------
  |  Branch (58:5): [True: 0, False: 821]
  ------------------
   59|      0|    case spv::Decoration::BufferBlock:
  ------------------
  |  Branch (59:5): [True: 0, False: 821]
  ------------------
   60|      1|    case spv::Decoration::ArrayStride:
  ------------------
  |  Branch (60:5): [True: 1, False: 820]
  ------------------
   61|      2|    case spv::Decoration::GLSLShared:
  ------------------
  |  Branch (61:5): [True: 1, False: 820]
  ------------------
   62|      2|    case spv::Decoration::GLSLPacked:
  ------------------
  |  Branch (62:5): [True: 0, False: 821]
  ------------------
   63|      2|    case spv::Decoration::CPacked:
  ------------------
  |  Branch (63:5): [True: 0, False: 821]
  ------------------
   64|       |    // TODO: https://github.com/KhronosGroup/glslang/issues/703:
   65|       |    // glslang applies Restrict to structure members.
   66|       |    // case spv::Decoration::Restrict:
   67|      2|    case spv::Decoration::Aliased:
  ------------------
  |  Branch (67:5): [True: 0, False: 821]
  ------------------
   68|      2|    case spv::Decoration::Constant:
  ------------------
  |  Branch (68:5): [True: 0, False: 821]
  ------------------
   69|      3|    case spv::Decoration::Uniform:
  ------------------
  |  Branch (69:5): [True: 1, False: 820]
  ------------------
   70|      3|    case spv::Decoration::UniformId:
  ------------------
  |  Branch (70:5): [True: 0, False: 821]
  ------------------
   71|      3|    case spv::Decoration::SaturatedConversion:
  ------------------
  |  Branch (71:5): [True: 0, False: 821]
  ------------------
   72|      3|    case spv::Decoration::Index:
  ------------------
  |  Branch (72:5): [True: 0, False: 821]
  ------------------
   73|      4|    case spv::Decoration::Binding:
  ------------------
  |  Branch (73:5): [True: 1, False: 820]
  ------------------
   74|      4|    case spv::Decoration::DescriptorSet:
  ------------------
  |  Branch (74:5): [True: 0, False: 821]
  ------------------
   75|      4|    case spv::Decoration::FuncParamAttr:
  ------------------
  |  Branch (75:5): [True: 0, False: 821]
  ------------------
   76|      5|    case spv::Decoration::FPRoundingMode:
  ------------------
  |  Branch (76:5): [True: 1, False: 820]
  ------------------
   77|      5|    case spv::Decoration::FPFastMathMode:
  ------------------
  |  Branch (77:5): [True: 0, False: 821]
  ------------------
   78|      5|    case spv::Decoration::LinkageAttributes:
  ------------------
  |  Branch (78:5): [True: 0, False: 821]
  ------------------
   79|      6|    case spv::Decoration::NoContraction:
  ------------------
  |  Branch (79:5): [True: 1, False: 820]
  ------------------
   80|      7|    case spv::Decoration::InputAttachmentIndex:
  ------------------
  |  Branch (80:5): [True: 1, False: 820]
  ------------------
   81|      7|    case spv::Decoration::Alignment:
  ------------------
  |  Branch (81:5): [True: 0, False: 821]
  ------------------
   82|      7|    case spv::Decoration::MaxByteOffset:
  ------------------
  |  Branch (82:5): [True: 0, False: 821]
  ------------------
   83|      7|    case spv::Decoration::AlignmentId:
  ------------------
  |  Branch (83:5): [True: 0, False: 821]
  ------------------
   84|      7|    case spv::Decoration::MaxByteOffsetId:
  ------------------
  |  Branch (84:5): [True: 0, False: 821]
  ------------------
   85|      7|    case spv::Decoration::NoSignedWrap:
  ------------------
  |  Branch (85:5): [True: 0, False: 821]
  ------------------
   86|      7|    case spv::Decoration::NoUnsignedWrap:
  ------------------
  |  Branch (86:5): [True: 0, False: 821]
  ------------------
   87|      7|    case spv::Decoration::NonUniform:
  ------------------
  |  Branch (87:5): [True: 0, False: 821]
  ------------------
   88|      7|    case spv::Decoration::RestrictPointer:
  ------------------
  |  Branch (88:5): [True: 0, False: 821]
  ------------------
   89|      7|    case spv::Decoration::AliasedPointer:
  ------------------
  |  Branch (89:5): [True: 0, False: 821]
  ------------------
   90|      7|    case spv::Decoration::CounterBuffer:
  ------------------
  |  Branch (90:5): [True: 0, False: 821]
  ------------------
   91|      7|      return true;
   92|    814|    default:
  ------------------
  |  Branch (92:5): [True: 814, False: 7]
  ------------------
   93|    814|      break;
   94|    821|  }
   95|    814|  return false;
   96|    821|}
validate_annotation.cpp:_ZN8spvtools3val12_GLOBAL__N_123ValidateDecorationGroupERNS0_17ValidationState_tEPKNS0_11InstructionE:
  338|    391|                                     const Instruction* inst) {
  339|    391|  const auto decoration_group_id = inst->GetOperandAs<uint32_t>(0);
  340|    391|  const auto decoration_group = _.FindDef(decoration_group_id);
  341|  6.30k|  for (auto pair : decoration_group->uses()) {
  ------------------
  |  Branch (341:18): [True: 6.30k, False: 388]
  ------------------
  342|  6.30k|    auto use = pair.first;
  343|  6.30k|    if (use->opcode() != spv::Op::OpDecorate &&
  ------------------
  |  Branch (343:9): [True: 2.20k, False: 4.10k]
  ------------------
  344|  6.30k|        use->opcode() != spv::Op::OpGroupDecorate &&
  ------------------
  |  Branch (344:9): [True: 405, False: 1.79k]
  ------------------
  345|  6.30k|        use->opcode() != spv::Op::OpGroupMemberDecorate &&
  ------------------
  |  Branch (345:9): [True: 15, False: 390]
  ------------------
  346|  6.30k|        use->opcode() != spv::Op::OpName &&
  ------------------
  |  Branch (346:9): [True: 3, False: 12]
  ------------------
  347|  6.30k|        use->opcode() != spv::Op::OpDecorateId && !use->IsNonSemantic()) {
  ------------------
  |  Branch (347:9): [True: 3, False: 0]
  |  Branch (347:51): [True: 3, False: 0]
  ------------------
  348|      3|      return _.diag(SPV_ERROR_INVALID_ID, inst)
  349|      3|             << "Result id of OpDecorationGroup can only "
  350|      3|             << "be targeted by OpName, OpGroupDecorate, "
  351|      3|             << "OpDecorate, OpDecorateId, and OpGroupMemberDecorate";
  352|      3|    }
  353|  6.30k|  }
  354|    388|  return SPV_SUCCESS;
  355|    391|}
validate_annotation.cpp:_ZN8spvtools3val12_GLOBAL__N_121ValidateGroupDecorateERNS0_17ValidationState_tEPKNS0_11InstructionE:
  358|  1.70k|                                   const Instruction* inst) {
  359|  1.70k|  const auto decoration_group_id = inst->GetOperandAs<uint32_t>(0);
  360|  1.70k|  auto decoration_group = _.FindDef(decoration_group_id);
  361|  1.70k|  if (!decoration_group ||
  ------------------
  |  Branch (361:7): [True: 0, False: 1.70k]
  ------------------
  362|  1.70k|      spv::Op::OpDecorationGroup != decoration_group->opcode()) {
  ------------------
  |  Branch (362:7): [True: 1, False: 1.69k]
  ------------------
  363|      1|    return _.diag(SPV_ERROR_INVALID_ID, inst)
  364|      1|           << "OpGroupDecorate Decoration group <id> "
  365|      1|           << _.getIdName(decoration_group_id) << " is not a decoration group.";
  366|      1|  }
  367|  3.30k|  for (unsigned i = 1; i < inst->operands().size(); ++i) {
  ------------------
  |  Branch (367:24): [True: 1.60k, False: 1.69k]
  ------------------
  368|  1.60k|    auto target_id = inst->GetOperandAs<uint32_t>(i);
  369|  1.60k|    auto target = _.FindDef(target_id);
  370|  1.60k|    if (!target || target->opcode() == spv::Op::OpDecorationGroup) {
  ------------------
  |  Branch (370:9): [True: 0, False: 1.60k]
  |  Branch (370:20): [True: 6, False: 1.60k]
  ------------------
  371|      6|      return _.diag(SPV_ERROR_INVALID_ID, inst)
  372|      6|             << "OpGroupDecorate may not target OpDecorationGroup <id> "
  373|      6|             << _.getIdName(target_id);
  374|      6|    }
  375|  1.60k|  }
  376|  1.69k|  return SPV_SUCCESS;
  377|  1.69k|}
validate_annotation.cpp:_ZN8spvtools3val12_GLOBAL__N_127ValidateGroupMemberDecorateERNS0_17ValidationState_tEPKNS0_11InstructionE:
  380|    389|                                         const Instruction* inst) {
  381|    389|  const auto decoration_group_id = inst->GetOperandAs<uint32_t>(0);
  382|    389|  const auto decoration_group = _.FindDef(decoration_group_id);
  383|    389|  if (!decoration_group ||
  ------------------
  |  Branch (383:7): [True: 0, False: 389]
  ------------------
  384|    389|      spv::Op::OpDecorationGroup != decoration_group->opcode()) {
  ------------------
  |  Branch (384:7): [True: 1, False: 388]
  ------------------
  385|      1|    return _.diag(SPV_ERROR_INVALID_ID, inst)
  386|      1|           << "OpGroupMemberDecorate Decoration group <id> "
  387|      1|           << _.getIdName(decoration_group_id) << " is not a decoration group.";
  388|      1|  }
  389|       |  // Grammar checks ensures that the number of arguments to this instruction
  390|       |  // is an odd number: 1 decoration group + (id,literal) pairs.
  391|    692|  for (size_t i = 1; i + 1 < inst->operands().size(); i += 2) {
  ------------------
  |  Branch (391:22): [True: 323, False: 369]
  ------------------
  392|    323|    const uint32_t struct_id = inst->GetOperandAs<uint32_t>(i);
  393|    323|    const uint32_t index = inst->GetOperandAs<uint32_t>(i + 1);
  394|    323|    auto struct_instr = _.FindDef(struct_id);
  395|    323|    if (!struct_instr || spv::Op::OpTypeStruct != struct_instr->opcode()) {
  ------------------
  |  Branch (395:9): [True: 0, False: 323]
  |  Branch (395:26): [True: 2, False: 321]
  ------------------
  396|      2|      return _.diag(SPV_ERROR_INVALID_ID, inst)
  397|      2|             << "OpGroupMemberDecorate Structure type <id> "
  398|      2|             << _.getIdName(struct_id) << " is not a struct type.";
  399|      2|    }
  400|    321|    const uint32_t num_struct_members =
  401|    321|        static_cast<uint32_t>(struct_instr->words().size() - 2);
  402|    321|    if (index >= num_struct_members) {
  ------------------
  |  Branch (402:9): [True: 17, False: 304]
  ------------------
  403|     17|      return _.diag(SPV_ERROR_INVALID_ID, inst)
  404|     17|             << "Index " << index
  405|     17|             << " provided in OpGroupMemberDecorate for struct <id> "
  406|     17|             << _.getIdName(struct_id)
  407|     17|             << " is out of bounds. The structure has " << num_struct_members
  408|     17|             << " members. Largest valid index is " << num_struct_members - 1
  409|     17|             << ".";
  410|     17|    }
  411|    321|  }
  412|    369|  return SPV_SUCCESS;
  413|    388|}
validate_annotation.cpp:_ZN8spvtools3val12_GLOBAL__N_119RegisterDecorationsERNS0_17ValidationState_tEPKNS0_11InstructionE:
  418|   286k|                                 const Instruction* inst) {
  419|   286k|  switch (inst->opcode()) {
  420|  13.2k|    case spv::Op::OpDecorate:
  ------------------
  |  Branch (420:5): [True: 13.2k, False: 273k]
  ------------------
  421|  13.2k|    case spv::Op::OpDecorateId: {
  ------------------
  |  Branch (421:5): [True: 0, False: 286k]
  ------------------
  422|  13.2k|      const uint32_t target_id = inst->word(1);
  423|  13.2k|      const spv::Decoration dec_type =
  424|  13.2k|          static_cast<spv::Decoration>(inst->word(2));
  425|  13.2k|      std::vector<uint32_t> dec_params;
  426|  13.2k|      if (inst->words().size() > 3) {
  ------------------
  |  Branch (426:11): [True: 6.49k, False: 6.76k]
  ------------------
  427|  6.49k|        dec_params.insert(dec_params.end(), inst->words().begin() + 3,
  428|  6.49k|                          inst->words().end());
  429|  6.49k|      }
  430|  13.2k|      _.RegisterDecorationForId(target_id, Decoration(dec_type, dec_params));
  431|  13.2k|      break;
  432|  13.2k|    }
  433|    814|    case spv::Op::OpMemberDecorate: {
  ------------------
  |  Branch (433:5): [True: 814, False: 285k]
  ------------------
  434|    814|      const uint32_t struct_id = inst->word(1);
  435|    814|      const uint32_t index = inst->word(2);
  436|    814|      const spv::Decoration dec_type =
  437|    814|          static_cast<spv::Decoration>(inst->word(3));
  438|    814|      std::vector<uint32_t> dec_params;
  439|    814|      if (inst->words().size() > 4) {
  ------------------
  |  Branch (439:11): [True: 609, False: 205]
  ------------------
  440|    609|        dec_params.insert(dec_params.end(), inst->words().begin() + 4,
  441|    609|                          inst->words().end());
  442|    609|      }
  443|    814|      _.RegisterDecorationForId(struct_id,
  444|    814|                                Decoration(dec_type, dec_params, index));
  445|    814|      break;
  446|  13.2k|    }
  447|    388|    case spv::Op::OpDecorationGroup: {
  ------------------
  |  Branch (447:5): [True: 388, False: 286k]
  ------------------
  448|       |      // We don't need to do anything right now. Assigning decorations to groups
  449|       |      // will be taken care of via OpGroupDecorate.
  450|    388|      break;
  451|  13.2k|    }
  452|  1.69k|    case spv::Op::OpGroupDecorate: {
  ------------------
  |  Branch (452:5): [True: 1.69k, False: 284k]
  ------------------
  453|       |      // Word 1 is the group <id>. All subsequent words are target <id>s that
  454|       |      // are going to be decorated with the decorations.
  455|  1.69k|      const uint32_t decoration_group_id = inst->word(1);
  456|  1.69k|      std::set<Decoration>& group_decorations =
  457|  1.69k|          _.id_decorations(decoration_group_id);
  458|  3.29k|      for (size_t i = 2; i < inst->words().size(); ++i) {
  ------------------
  |  Branch (458:26): [True: 1.60k, False: 1.69k]
  ------------------
  459|  1.60k|        const uint32_t target_id = inst->word(i);
  460|  1.60k|        _.RegisterDecorationsForId(target_id, group_decorations.begin(),
  461|  1.60k|                                   group_decorations.end());
  462|  1.60k|      }
  463|  1.69k|      break;
  464|  13.2k|    }
  465|    369|    case spv::Op::OpGroupMemberDecorate: {
  ------------------
  |  Branch (465:5): [True: 369, False: 286k]
  ------------------
  466|       |      // Word 1 is the Decoration Group <id> followed by (struct<id>,literal)
  467|       |      // pairs. All decorations of the group should be applied to all the struct
  468|       |      // members that are specified in the instructions.
  469|    369|      const uint32_t decoration_group_id = inst->word(1);
  470|    369|      std::set<Decoration>& group_decorations =
  471|    369|          _.id_decorations(decoration_group_id);
  472|       |      // Grammar checks ensures that the number of arguments to this instruction
  473|       |      // is an odd number: 1 decoration group + (id,literal) pairs.
  474|    673|      for (size_t i = 2; i + 1 < inst->words().size(); i = i + 2) {
  ------------------
  |  Branch (474:26): [True: 304, False: 369]
  ------------------
  475|    304|        const uint32_t struct_id = inst->word(i);
  476|    304|        const uint32_t index = inst->word(i + 1);
  477|       |        // ID validation phase ensures this is in fact a struct instruction and
  478|       |        // that the index is not out of bound.
  479|    304|        _.RegisterDecorationsForStructMember(struct_id, index,
  480|    304|                                             group_decorations.begin(),
  481|    304|                                             group_decorations.end());
  482|    304|      }
  483|    369|      break;
  484|  13.2k|    }
  485|   270k|    default:
  ------------------
  |  Branch (485:5): [True: 270k, False: 16.5k]
  ------------------
  486|   270k|      break;
  487|   286k|  }
  488|   286k|  return SPV_SUCCESS;
  489|   286k|}

_ZN8spvtools3val15ArithmeticsPassERNS0_17ValidationState_tEPKNS0_11InstructionE:
   30|   285k|spv_result_t ArithmeticsPass(ValidationState_t& _, const Instruction* inst) {
   31|   285k|  const spv::Op opcode = inst->opcode();
   32|   285k|  const uint32_t result_type = inst->type_id();
   33|       |
   34|   285k|  switch (opcode) {
   35|  1.07k|    case spv::Op::OpFAdd:
  ------------------
  |  Branch (35:5): [True: 1.07k, False: 284k]
  ------------------
   36|  1.98k|    case spv::Op::OpFSub:
  ------------------
  |  Branch (36:5): [True: 910, False: 284k]
  ------------------
   37|  3.25k|    case spv::Op::OpFMul:
  ------------------
  |  Branch (37:5): [True: 1.26k, False: 284k]
  ------------------
   38|  4.12k|    case spv::Op::OpFDiv:
  ------------------
  |  Branch (38:5): [True: 870, False: 284k]
  ------------------
   39|  4.15k|    case spv::Op::OpFRem:
  ------------------
  |  Branch (39:5): [True: 31, False: 285k]
  ------------------
   40|  4.22k|    case spv::Op::OpFMod:
  ------------------
  |  Branch (40:5): [True: 69, False: 285k]
  ------------------
   41|  4.25k|    case spv::Op::OpFNegate: {
  ------------------
  |  Branch (41:5): [True: 28, False: 285k]
  ------------------
   42|  4.25k|      bool supportsCoopMat =
   43|  4.25k|          (opcode != spv::Op::OpFMul && opcode != spv::Op::OpFRem &&
  ------------------
  |  Branch (43:12): [True: 2.98k, False: 1.26k]
  |  Branch (43:41): [True: 2.95k, False: 31]
  ------------------
   44|  4.25k|           opcode != spv::Op::OpFMod);
  ------------------
  |  Branch (44:12): [True: 2.88k, False: 69]
  ------------------
   45|  4.25k|      if (!_.IsFloatScalarType(result_type) &&
  ------------------
  |  Branch (45:11): [True: 887, False: 3.36k]
  ------------------
   46|  4.25k|          !_.IsFloatVectorType(result_type) &&
  ------------------
  |  Branch (46:11): [True: 3, False: 884]
  ------------------
   47|  4.25k|          !(supportsCoopMat && _.IsFloatCooperativeMatrixType(result_type)))
  ------------------
  |  Branch (47:13): [True: 1, False: 2]
  |  Branch (47:32): [True: 0, False: 1]
  ------------------
   48|      3|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
   49|      3|               << "Expected floating scalar or vector type as Result Type: "
   50|      3|               << spvOpcodeString(opcode);
   51|       |
   52|  12.7k|      for (size_t operand_index = 2; operand_index < inst->operands().size();
  ------------------
  |  Branch (52:38): [True: 8.46k, False: 4.24k]
  ------------------
   53|  8.46k|           ++operand_index) {
   54|  8.46k|        if (_.GetOperandTypeId(inst, operand_index) != result_type)
  ------------------
  |  Branch (54:13): [True: 7, False: 8.46k]
  ------------------
   55|      7|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
   56|      7|                 << "Expected arithmetic operands to be of Result Type: "
   57|      7|                 << spvOpcodeString(opcode) << " operand index "
   58|      7|                 << operand_index;
   59|  8.46k|      }
   60|  4.24k|      break;
   61|  4.25k|    }
   62|       |
   63|  4.24k|    case spv::Op::OpUDiv:
  ------------------
  |  Branch (63:5): [True: 13, False: 285k]
  ------------------
   64|     16|    case spv::Op::OpUMod: {
  ------------------
  |  Branch (64:5): [True: 3, False: 285k]
  ------------------
   65|     16|      bool supportsCoopMat = (opcode == spv::Op::OpUDiv);
   66|     16|      if (!_.IsUnsignedIntScalarType(result_type) &&
  ------------------
  |  Branch (66:11): [True: 12, False: 4]
  ------------------
   67|     16|          !_.IsUnsignedIntVectorType(result_type) &&
  ------------------
  |  Branch (67:11): [True: 8, False: 4]
  ------------------
   68|     16|          !(supportsCoopMat &&
  ------------------
  |  Branch (68:13): [True: 6, False: 2]
  ------------------
   69|      8|            _.IsUnsignedIntCooperativeMatrixType(result_type)))
  ------------------
  |  Branch (69:13): [True: 0, False: 6]
  ------------------
   70|      8|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
   71|      8|               << "Expected unsigned int scalar or vector type as Result Type: "
   72|      8|               << spvOpcodeString(opcode);
   73|       |
   74|     21|      for (size_t operand_index = 2; operand_index < inst->operands().size();
  ------------------
  |  Branch (74:38): [True: 15, False: 6]
  ------------------
   75|     15|           ++operand_index) {
   76|     15|        if (_.GetOperandTypeId(inst, operand_index) != result_type)
  ------------------
  |  Branch (76:13): [True: 2, False: 13]
  ------------------
   77|      2|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
   78|      2|                 << "Expected arithmetic operands to be of Result Type: "
   79|      2|                 << spvOpcodeString(opcode) << " operand index "
   80|      2|                 << operand_index;
   81|     15|      }
   82|      6|      break;
   83|      8|    }
   84|       |
   85|    480|    case spv::Op::OpISub:
  ------------------
  |  Branch (85:5): [True: 480, False: 285k]
  ------------------
   86|  2.66k|    case spv::Op::OpIAdd:
  ------------------
  |  Branch (86:5): [True: 2.18k, False: 283k]
  ------------------
   87|  2.94k|    case spv::Op::OpIMul:
  ------------------
  |  Branch (87:5): [True: 288, False: 285k]
  ------------------
   88|  3.06k|    case spv::Op::OpSDiv:
  ------------------
  |  Branch (88:5): [True: 114, False: 285k]
  ------------------
   89|  3.09k|    case spv::Op::OpSMod:
  ------------------
  |  Branch (89:5): [True: 33, False: 285k]
  ------------------
   90|  3.11k|    case spv::Op::OpSRem:
  ------------------
  |  Branch (90:5): [True: 17, False: 285k]
  ------------------
   91|  3.15k|    case spv::Op::OpSNegate: {
  ------------------
  |  Branch (91:5): [True: 44, False: 285k]
  ------------------
   92|  3.15k|      bool supportsCoopMat =
   93|  3.15k|          (opcode != spv::Op::OpIMul && opcode != spv::Op::OpSRem &&
  ------------------
  |  Branch (93:12): [True: 2.86k, False: 288]
  |  Branch (93:41): [True: 2.85k, False: 17]
  ------------------
   94|  3.15k|           opcode != spv::Op::OpSMod);
  ------------------
  |  Branch (94:12): [True: 2.81k, False: 33]
  ------------------
   95|  3.15k|      if (!_.IsIntScalarType(result_type) && !_.IsIntVectorType(result_type) &&
  ------------------
  |  Branch (95:11): [True: 35, False: 3.12k]
  |  Branch (95:46): [True: 11, False: 24]
  ------------------
   96|  3.15k|          !(supportsCoopMat && _.IsIntCooperativeMatrixType(result_type)))
  ------------------
  |  Branch (96:13): [True: 10, False: 1]
  |  Branch (96:32): [True: 0, False: 10]
  ------------------
   97|     11|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
   98|     11|               << "Expected int scalar or vector type as Result Type: "
   99|     11|               << spvOpcodeString(opcode);
  100|       |
  101|  3.14k|      const uint32_t dimension = _.GetDimension(result_type);
  102|  3.14k|      const uint32_t bit_width = _.GetBitWidth(result_type);
  103|       |
  104|  9.39k|      for (size_t operand_index = 2; operand_index < inst->operands().size();
  ------------------
  |  Branch (104:38): [True: 6.24k, False: 3.14k]
  ------------------
  105|  6.24k|           ++operand_index) {
  106|  6.24k|        const uint32_t type_id = _.GetOperandTypeId(inst, operand_index);
  107|  6.24k|        if (!type_id ||
  ------------------
  |  Branch (107:13): [True: 0, False: 6.24k]
  ------------------
  108|  6.24k|            (!_.IsIntScalarType(type_id) && !_.IsIntVectorType(type_id) &&
  ------------------
  |  Branch (108:14): [True: 46, False: 6.20k]
  |  Branch (108:45): [True: 2, False: 44]
  ------------------
  109|  6.24k|             !(supportsCoopMat && _.IsIntCooperativeMatrixType(result_type))))
  ------------------
  |  Branch (109:16): [True: 1, False: 1]
  |  Branch (109:35): [True: 0, False: 1]
  ------------------
  110|      2|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
  111|      2|                 << "Expected int scalar or vector type as operand: "
  112|      2|                 << spvOpcodeString(opcode) << " operand index "
  113|      2|                 << operand_index;
  114|       |
  115|  6.24k|        if (_.GetDimension(type_id) != dimension)
  ------------------
  |  Branch (115:13): [True: 1, False: 6.24k]
  ------------------
  116|      1|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
  117|      1|                 << "Expected arithmetic operands to have the same dimension "
  118|      1|                 << "as Result Type: " << spvOpcodeString(opcode)
  119|      1|                 << " operand index " << operand_index;
  120|       |
  121|  6.24k|        if (_.GetBitWidth(type_id) != bit_width)
  ------------------
  |  Branch (121:13): [True: 0, False: 6.24k]
  ------------------
  122|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
  123|      0|                 << "Expected arithmetic operands to have the same bit width "
  124|      0|                 << "as Result Type: " << spvOpcodeString(opcode)
  125|      0|                 << " operand index " << operand_index;
  126|  6.24k|      }
  127|  3.14k|      break;
  128|  3.14k|    }
  129|       |
  130|  3.14k|    case spv::Op::OpDot: {
  ------------------
  |  Branch (130:5): [True: 13, False: 285k]
  ------------------
  131|     13|      if (!_.IsFloatScalarType(result_type))
  ------------------
  |  Branch (131:11): [True: 0, False: 13]
  ------------------
  132|      0|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
  133|      0|               << "Expected float scalar type as Result Type: "
  134|      0|               << spvOpcodeString(opcode);
  135|       |
  136|     13|      uint32_t first_vector_num_components = 0;
  137|       |
  138|     39|      for (size_t operand_index = 2; operand_index < inst->operands().size();
  ------------------
  |  Branch (138:38): [True: 26, False: 13]
  ------------------
  139|     26|           ++operand_index) {
  140|     26|        const uint32_t type_id = _.GetOperandTypeId(inst, operand_index);
  141|       |
  142|     26|        if (!type_id || !_.IsFloatVectorType(type_id))
  ------------------
  |  Branch (142:13): [True: 0, False: 26]
  |  Branch (142:25): [True: 0, False: 26]
  ------------------
  143|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
  144|      0|                 << "Expected float vector as operand: "
  145|      0|                 << spvOpcodeString(opcode) << " operand index "
  146|      0|                 << operand_index;
  147|       |
  148|     26|        const uint32_t component_type = _.GetComponentType(type_id);
  149|     26|        if (component_type != result_type)
  ------------------
  |  Branch (149:13): [True: 0, False: 26]
  ------------------
  150|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
  151|      0|                 << "Expected component type to be equal to Result Type: "
  152|      0|                 << spvOpcodeString(opcode) << " operand index "
  153|      0|                 << operand_index;
  154|       |
  155|     26|        const uint32_t num_components = _.GetDimension(type_id);
  156|     26|        if (operand_index == 2) {
  ------------------
  |  Branch (156:13): [True: 13, False: 13]
  ------------------
  157|     13|          first_vector_num_components = num_components;
  158|     13|        } else if (num_components != first_vector_num_components) {
  ------------------
  |  Branch (158:20): [True: 0, False: 13]
  ------------------
  159|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
  160|      0|                 << "Expected operands to have the same number of components: "
  161|      0|                 << spvOpcodeString(opcode);
  162|      0|        }
  163|     26|      }
  164|     13|      break;
  165|     13|    }
  166|       |
  167|    336|    case spv::Op::OpVectorTimesScalar: {
  ------------------
  |  Branch (167:5): [True: 336, False: 285k]
  ------------------
  168|    336|      if (!_.IsFloatVectorType(result_type))
  ------------------
  |  Branch (168:11): [True: 1, False: 335]
  ------------------
  169|      1|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
  170|      1|               << "Expected float vector type as Result Type: "
  171|      1|               << spvOpcodeString(opcode);
  172|       |
  173|    335|      const uint32_t vector_type_id = _.GetOperandTypeId(inst, 2);
  174|    335|      if (result_type != vector_type_id)
  ------------------
  |  Branch (174:11): [True: 2, False: 333]
  ------------------
  175|      2|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
  176|      2|               << "Expected vector operand type to be equal to Result Type: "
  177|      2|               << spvOpcodeString(opcode);
  178|       |
  179|    333|      const uint32_t component_type = _.GetComponentType(vector_type_id);
  180|       |
  181|    333|      const uint32_t scalar_type_id = _.GetOperandTypeId(inst, 3);
  182|    333|      if (component_type != scalar_type_id)
  ------------------
  |  Branch (182:11): [True: 0, False: 333]
  ------------------
  183|      0|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
  184|      0|               << "Expected scalar operand type to be equal to the component "
  185|      0|               << "type of the vector operand: " << spvOpcodeString(opcode);
  186|       |
  187|    333|      break;
  188|    333|    }
  189|       |
  190|    333|    case spv::Op::OpMatrixTimesScalar: {
  ------------------
  |  Branch (190:5): [True: 5, False: 285k]
  ------------------
  191|      5|      if (!_.IsFloatMatrixType(result_type) &&
  ------------------
  |  Branch (191:11): [True: 3, False: 2]
  ------------------
  192|      5|          !_.IsCooperativeMatrixType(result_type))
  ------------------
  |  Branch (192:11): [True: 3, False: 0]
  ------------------
  193|      3|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
  194|      3|               << "Expected float matrix type as Result Type: "
  195|      3|               << spvOpcodeString(opcode);
  196|       |
  197|      2|      const uint32_t matrix_type_id = _.GetOperandTypeId(inst, 2);
  198|      2|      if (result_type != matrix_type_id)
  ------------------
  |  Branch (198:11): [True: 0, False: 2]
  ------------------
  199|      0|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
  200|      0|               << "Expected matrix operand type to be equal to Result Type: "
  201|      0|               << spvOpcodeString(opcode);
  202|       |
  203|      2|      const uint32_t component_type = _.GetComponentType(matrix_type_id);
  204|       |
  205|      2|      const uint32_t scalar_type_id = _.GetOperandTypeId(inst, 3);
  206|      2|      if (component_type != scalar_type_id)
  ------------------
  |  Branch (206:11): [True: 1, False: 1]
  ------------------
  207|      1|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
  208|      1|               << "Expected scalar operand type to be equal to the component "
  209|      1|               << "type of the matrix operand: " << spvOpcodeString(opcode);
  210|       |
  211|      1|      break;
  212|      2|    }
  213|       |
  214|     40|    case spv::Op::OpVectorTimesMatrix: {
  ------------------
  |  Branch (214:5): [True: 40, False: 285k]
  ------------------
  215|     40|      const uint32_t vector_type_id = _.GetOperandTypeId(inst, 2);
  216|     40|      const uint32_t matrix_type_id = _.GetOperandTypeId(inst, 3);
  217|       |
  218|     40|      if (!_.IsFloatVectorType(result_type))
  ------------------
  |  Branch (218:11): [True: 0, False: 40]
  ------------------
  219|      0|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
  220|      0|               << "Expected float vector type as Result Type: "
  221|      0|               << spvOpcodeString(opcode);
  222|       |
  223|     40|      const uint32_t res_component_type = _.GetComponentType(result_type);
  224|       |
  225|     40|      if (!vector_type_id || !_.IsFloatVectorType(vector_type_id))
  ------------------
  |  Branch (225:11): [True: 0, False: 40]
  |  Branch (225:30): [True: 0, False: 40]
  ------------------
  226|      0|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
  227|      0|               << "Expected float vector type as left operand: "
  228|      0|               << spvOpcodeString(opcode);
  229|       |
  230|     40|      if (res_component_type != _.GetComponentType(vector_type_id))
  ------------------
  |  Branch (230:11): [True: 0, False: 40]
  ------------------
  231|      0|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
  232|      0|               << "Expected component types of Result Type and vector to be "
  233|      0|               << "equal: " << spvOpcodeString(opcode);
  234|       |
  235|     40|      uint32_t matrix_num_rows = 0;
  236|     40|      uint32_t matrix_num_cols = 0;
  237|     40|      uint32_t matrix_col_type = 0;
  238|     40|      uint32_t matrix_component_type = 0;
  239|     40|      if (!_.GetMatrixTypeInfo(matrix_type_id, &matrix_num_rows,
  ------------------
  |  Branch (239:11): [True: 1, False: 39]
  ------------------
  240|     40|                               &matrix_num_cols, &matrix_col_type,
  241|     40|                               &matrix_component_type))
  242|      1|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
  243|      1|               << "Expected float matrix type as right operand: "
  244|      1|               << spvOpcodeString(opcode);
  245|       |
  246|     39|      if (res_component_type != matrix_component_type)
  ------------------
  |  Branch (246:11): [True: 0, False: 39]
  ------------------
  247|      0|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
  248|      0|               << "Expected component types of Result Type and matrix to be "
  249|      0|               << "equal: " << spvOpcodeString(opcode);
  250|       |
  251|     39|      if (matrix_num_cols != _.GetDimension(result_type))
  ------------------
  |  Branch (251:11): [True: 0, False: 39]
  ------------------
  252|      0|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
  253|      0|               << "Expected number of columns of the matrix to be equal to "
  254|      0|               << "Result Type vector size: " << spvOpcodeString(opcode);
  255|       |
  256|     39|      if (matrix_num_rows != _.GetDimension(vector_type_id))
  ------------------
  |  Branch (256:11): [True: 1, False: 38]
  ------------------
  257|      1|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
  258|      1|               << "Expected number of rows of the matrix to be equal to the "
  259|      1|               << "vector operand size: " << spvOpcodeString(opcode);
  260|       |
  261|     38|      break;
  262|     39|    }
  263|       |
  264|     38|    case spv::Op::OpMatrixTimesVector: {
  ------------------
  |  Branch (264:5): [True: 24, False: 285k]
  ------------------
  265|     24|      const uint32_t matrix_type_id = _.GetOperandTypeId(inst, 2);
  266|     24|      const uint32_t vector_type_id = _.GetOperandTypeId(inst, 3);
  267|       |
  268|     24|      if (!_.IsFloatVectorType(result_type))
  ------------------
  |  Branch (268:11): [True: 1, False: 23]
  ------------------
  269|      1|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
  270|      1|               << "Expected float vector type as Result Type: "
  271|      1|               << spvOpcodeString(opcode);
  272|       |
  273|     23|      uint32_t matrix_num_rows = 0;
  274|     23|      uint32_t matrix_num_cols = 0;
  275|     23|      uint32_t matrix_col_type = 0;
  276|     23|      uint32_t matrix_component_type = 0;
  277|     23|      if (!_.GetMatrixTypeInfo(matrix_type_id, &matrix_num_rows,
  ------------------
  |  Branch (277:11): [True: 1, False: 22]
  ------------------
  278|     23|                               &matrix_num_cols, &matrix_col_type,
  279|     23|                               &matrix_component_type))
  280|      1|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
  281|      1|               << "Expected float matrix type as left operand: "
  282|      1|               << spvOpcodeString(opcode);
  283|       |
  284|     22|      if (result_type != matrix_col_type)
  ------------------
  |  Branch (284:11): [True: 1, False: 21]
  ------------------
  285|      1|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
  286|      1|               << "Expected column type of the matrix to be equal to Result "
  287|      1|                  "Type: "
  288|      1|               << spvOpcodeString(opcode);
  289|       |
  290|     21|      if (!vector_type_id || !_.IsFloatVectorType(vector_type_id))
  ------------------
  |  Branch (290:11): [True: 0, False: 21]
  |  Branch (290:30): [True: 1, False: 20]
  ------------------
  291|      1|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
  292|      1|               << "Expected float vector type as right operand: "
  293|      1|               << spvOpcodeString(opcode);
  294|       |
  295|     20|      if (matrix_component_type != _.GetComponentType(vector_type_id))
  ------------------
  |  Branch (295:11): [True: 0, False: 20]
  ------------------
  296|      0|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
  297|      0|               << "Expected component types of the operands to be equal: "
  298|      0|               << spvOpcodeString(opcode);
  299|       |
  300|     20|      if (matrix_num_cols != _.GetDimension(vector_type_id))
  ------------------
  |  Branch (300:11): [True: 1, False: 19]
  ------------------
  301|      1|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
  302|      1|               << "Expected number of columns of the matrix to be equal to the "
  303|      1|               << "vector size: " << spvOpcodeString(opcode);
  304|       |
  305|     19|      break;
  306|     20|    }
  307|       |
  308|     19|    case spv::Op::OpMatrixTimesMatrix: {
  ------------------
  |  Branch (308:5): [True: 19, False: 285k]
  ------------------
  309|     19|      const uint32_t left_type_id = _.GetOperandTypeId(inst, 2);
  310|     19|      const uint32_t right_type_id = _.GetOperandTypeId(inst, 3);
  311|       |
  312|     19|      uint32_t res_num_rows = 0;
  313|     19|      uint32_t res_num_cols = 0;
  314|     19|      uint32_t res_col_type = 0;
  315|     19|      uint32_t res_component_type = 0;
  316|     19|      if (!_.GetMatrixTypeInfo(result_type, &res_num_rows, &res_num_cols,
  ------------------
  |  Branch (316:11): [True: 2, False: 17]
  ------------------
  317|     19|                               &res_col_type, &res_component_type))
  318|      2|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
  319|      2|               << "Expected float matrix type as Result Type: "
  320|      2|               << spvOpcodeString(opcode);
  321|       |
  322|     17|      uint32_t left_num_rows = 0;
  323|     17|      uint32_t left_num_cols = 0;
  324|     17|      uint32_t left_col_type = 0;
  325|     17|      uint32_t left_component_type = 0;
  326|     17|      if (!_.GetMatrixTypeInfo(left_type_id, &left_num_rows, &left_num_cols,
  ------------------
  |  Branch (326:11): [True: 1, False: 16]
  ------------------
  327|     17|                               &left_col_type, &left_component_type))
  328|      1|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
  329|      1|               << "Expected float matrix type as left operand: "
  330|      1|               << spvOpcodeString(opcode);
  331|       |
  332|     16|      uint32_t right_num_rows = 0;
  333|     16|      uint32_t right_num_cols = 0;
  334|     16|      uint32_t right_col_type = 0;
  335|     16|      uint32_t right_component_type = 0;
  336|     16|      if (!_.GetMatrixTypeInfo(right_type_id, &right_num_rows, &right_num_cols,
  ------------------
  |  Branch (336:11): [True: 0, False: 16]
  ------------------
  337|     16|                               &right_col_type, &right_component_type))
  338|      0|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
  339|      0|               << "Expected float matrix type as right operand: "
  340|      0|               << spvOpcodeString(opcode);
  341|       |
  342|     16|      if (!_.IsFloatScalarType(res_component_type))
  ------------------
  |  Branch (342:11): [True: 0, False: 16]
  ------------------
  343|      0|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
  344|      0|               << "Expected float matrix type as Result Type: "
  345|      0|               << spvOpcodeString(opcode);
  346|       |
  347|     16|      if (res_col_type != left_col_type)
  ------------------
  |  Branch (347:11): [True: 0, False: 16]
  ------------------
  348|      0|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
  349|      0|               << "Expected column types of Result Type and left matrix to be "
  350|      0|               << "equal: " << spvOpcodeString(opcode);
  351|       |
  352|     16|      if (res_component_type != right_component_type)
  ------------------
  |  Branch (352:11): [True: 0, False: 16]
  ------------------
  353|      0|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
  354|      0|               << "Expected component types of Result Type and right matrix to "
  355|      0|                  "be "
  356|      0|               << "equal: " << spvOpcodeString(opcode);
  357|       |
  358|     16|      if (res_num_cols != right_num_cols)
  ------------------
  |  Branch (358:11): [True: 0, False: 16]
  ------------------
  359|      0|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
  360|      0|               << "Expected number of columns of Result Type and right matrix "
  361|      0|                  "to "
  362|      0|               << "be equal: " << spvOpcodeString(opcode);
  363|       |
  364|     16|      if (left_num_cols != right_num_rows)
  ------------------
  |  Branch (364:11): [True: 0, False: 16]
  ------------------
  365|      0|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
  366|      0|               << "Expected number of columns of left matrix and number of "
  367|      0|                  "rows "
  368|      0|               << "of right matrix to be equal: " << spvOpcodeString(opcode);
  369|       |
  370|     16|      assert(left_num_rows == res_num_rows);
  371|      0|      break;
  372|     16|    }
  373|       |
  374|      1|    case spv::Op::OpOuterProduct: {
  ------------------
  |  Branch (374:5): [True: 1, False: 285k]
  ------------------
  375|      1|      const uint32_t left_type_id = _.GetOperandTypeId(inst, 2);
  376|      1|      const uint32_t right_type_id = _.GetOperandTypeId(inst, 3);
  377|       |
  378|      1|      uint32_t res_num_rows = 0;
  379|      1|      uint32_t res_num_cols = 0;
  380|      1|      uint32_t res_col_type = 0;
  381|      1|      uint32_t res_component_type = 0;
  382|      1|      if (!_.GetMatrixTypeInfo(result_type, &res_num_rows, &res_num_cols,
  ------------------
  |  Branch (382:11): [True: 1, False: 0]
  ------------------
  383|      1|                               &res_col_type, &res_component_type))
  384|      1|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
  385|      1|               << "Expected float matrix type as Result Type: "
  386|      1|               << spvOpcodeString(opcode);
  387|       |
  388|      0|      if (left_type_id != res_col_type)
  ------------------
  |  Branch (388:11): [True: 0, False: 0]
  ------------------
  389|      0|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
  390|      0|               << "Expected column type of Result Type to be equal to the type "
  391|      0|               << "of the left operand: " << spvOpcodeString(opcode);
  392|       |
  393|      0|      if (!right_type_id || !_.IsFloatVectorType(right_type_id))
  ------------------
  |  Branch (393:11): [True: 0, False: 0]
  |  Branch (393:29): [True: 0, False: 0]
  ------------------
  394|      0|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
  395|      0|               << "Expected float vector type as right operand: "
  396|      0|               << spvOpcodeString(opcode);
  397|       |
  398|      0|      if (res_component_type != _.GetComponentType(right_type_id))
  ------------------
  |  Branch (398:11): [True: 0, False: 0]
  ------------------
  399|      0|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
  400|      0|               << "Expected component types of the operands to be equal: "
  401|      0|               << spvOpcodeString(opcode);
  402|       |
  403|      0|      if (res_num_cols != _.GetDimension(right_type_id))
  ------------------
  |  Branch (403:11): [True: 0, False: 0]
  ------------------
  404|      0|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
  405|      0|               << "Expected number of columns of the matrix to be equal to the "
  406|      0|               << "vector size of the right operand: "
  407|      0|               << spvOpcodeString(opcode);
  408|       |
  409|      0|      break;
  410|      0|    }
  411|       |
  412|      7|    case spv::Op::OpIAddCarry:
  ------------------
  |  Branch (412:5): [True: 7, False: 285k]
  ------------------
  413|     17|    case spv::Op::OpISubBorrow:
  ------------------
  |  Branch (413:5): [True: 10, False: 285k]
  ------------------
  414|     20|    case spv::Op::OpUMulExtended:
  ------------------
  |  Branch (414:5): [True: 3, False: 285k]
  ------------------
  415|     25|    case spv::Op::OpSMulExtended: {
  ------------------
  |  Branch (415:5): [True: 5, False: 285k]
  ------------------
  416|     25|      std::vector<uint32_t> result_types;
  417|     25|      if (!_.GetStructMemberTypes(result_type, &result_types))
  ------------------
  |  Branch (417:11): [True: 9, False: 16]
  ------------------
  418|      9|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
  419|      9|               << "Expected a struct as Result Type: "
  420|      9|               << spvOpcodeString(opcode);
  421|       |
  422|     16|      if (result_types.size() != 2)
  ------------------
  |  Branch (422:11): [True: 1, False: 15]
  ------------------
  423|      1|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
  424|      1|               << "Expected Result Type struct to have two members: "
  425|      1|               << spvOpcodeString(opcode);
  426|       |
  427|     15|      if (opcode == spv::Op::OpSMulExtended) {
  ------------------
  |  Branch (427:11): [True: 3, False: 12]
  ------------------
  428|      3|        if (!_.IsIntScalarType(result_types[0]) &&
  ------------------
  |  Branch (428:13): [True: 1, False: 2]
  ------------------
  429|      3|            !_.IsIntVectorType(result_types[0]))
  ------------------
  |  Branch (429:13): [True: 1, False: 0]
  ------------------
  430|      1|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
  431|      1|                 << "Expected Result Type struct member types to be integer "
  432|      1|                    "scalar "
  433|      1|                 << "or vector: " << spvOpcodeString(opcode);
  434|     12|      } else {
  435|     12|        if (!_.IsUnsignedIntScalarType(result_types[0]) &&
  ------------------
  |  Branch (435:13): [True: 1, False: 11]
  ------------------
  436|     12|            !_.IsUnsignedIntVectorType(result_types[0]))
  ------------------
  |  Branch (436:13): [True: 1, False: 0]
  ------------------
  437|      1|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
  438|      1|                 << "Expected Result Type struct member types to be unsigned "
  439|      1|                 << "integer scalar or vector: " << spvOpcodeString(opcode);
  440|     12|      }
  441|       |
  442|     13|      if (result_types[0] != result_types[1])
  ------------------
  |  Branch (442:11): [True: 0, False: 13]
  ------------------
  443|      0|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
  444|      0|               << "Expected Result Type struct member types to be identical: "
  445|      0|               << spvOpcodeString(opcode);
  446|       |
  447|     13|      const uint32_t left_type_id = _.GetOperandTypeId(inst, 2);
  448|     13|      const uint32_t right_type_id = _.GetOperandTypeId(inst, 3);
  449|       |
  450|     13|      if (left_type_id != result_types[0] || right_type_id != result_types[0])
  ------------------
  |  Branch (450:11): [True: 1, False: 12]
  |  Branch (450:46): [True: 1, False: 11]
  ------------------
  451|      2|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
  452|      2|               << "Expected both operands to be of Result Type member type: "
  453|      2|               << spvOpcodeString(opcode);
  454|       |
  455|     11|      break;
  456|     13|    }
  457|       |
  458|     11|    case spv::Op::OpCooperativeMatrixMulAddNV: {
  ------------------
  |  Branch (458:5): [True: 0, False: 285k]
  ------------------
  459|      0|      const uint32_t D_type_id = _.GetOperandTypeId(inst, 1);
  460|      0|      const uint32_t A_type_id = _.GetOperandTypeId(inst, 2);
  461|      0|      const uint32_t B_type_id = _.GetOperandTypeId(inst, 3);
  462|      0|      const uint32_t C_type_id = _.GetOperandTypeId(inst, 4);
  463|       |
  464|      0|      if (!_.IsCooperativeMatrixType(A_type_id)) {
  ------------------
  |  Branch (464:11): [True: 0, False: 0]
  ------------------
  465|      0|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
  466|      0|               << "Expected cooperative matrix type as A Type: "
  467|      0|               << spvOpcodeString(opcode);
  468|      0|      }
  469|      0|      if (!_.IsCooperativeMatrixType(B_type_id)) {
  ------------------
  |  Branch (469:11): [True: 0, False: 0]
  ------------------
  470|      0|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
  471|      0|               << "Expected cooperative matrix type as B Type: "
  472|      0|               << spvOpcodeString(opcode);
  473|      0|      }
  474|      0|      if (!_.IsCooperativeMatrixType(C_type_id)) {
  ------------------
  |  Branch (474:11): [True: 0, False: 0]
  ------------------
  475|      0|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
  476|      0|               << "Expected cooperative matrix type as C Type: "
  477|      0|               << spvOpcodeString(opcode);
  478|      0|      }
  479|      0|      if (!_.IsCooperativeMatrixType(D_type_id)) {
  ------------------
  |  Branch (479:11): [True: 0, False: 0]
  ------------------
  480|      0|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
  481|      0|               << "Expected cooperative matrix type as Result Type: "
  482|      0|               << spvOpcodeString(opcode);
  483|      0|      }
  484|       |
  485|      0|      const auto A = _.FindDef(A_type_id);
  486|      0|      const auto B = _.FindDef(B_type_id);
  487|      0|      const auto C = _.FindDef(C_type_id);
  488|      0|      const auto D = _.FindDef(D_type_id);
  489|       |
  490|      0|      std::tuple<bool, bool, uint32_t> A_scope, B_scope, C_scope, D_scope,
  491|      0|          A_rows, B_rows, C_rows, D_rows, A_cols, B_cols, C_cols, D_cols;
  492|       |
  493|      0|      A_scope = _.EvalInt32IfConst(A->GetOperandAs<uint32_t>(2));
  494|      0|      B_scope = _.EvalInt32IfConst(B->GetOperandAs<uint32_t>(2));
  495|      0|      C_scope = _.EvalInt32IfConst(C->GetOperandAs<uint32_t>(2));
  496|      0|      D_scope = _.EvalInt32IfConst(D->GetOperandAs<uint32_t>(2));
  497|       |
  498|      0|      A_rows = _.EvalInt32IfConst(A->GetOperandAs<uint32_t>(3));
  499|      0|      B_rows = _.EvalInt32IfConst(B->GetOperandAs<uint32_t>(3));
  500|      0|      C_rows = _.EvalInt32IfConst(C->GetOperandAs<uint32_t>(3));
  501|      0|      D_rows = _.EvalInt32IfConst(D->GetOperandAs<uint32_t>(3));
  502|       |
  503|      0|      A_cols = _.EvalInt32IfConst(A->GetOperandAs<uint32_t>(4));
  504|      0|      B_cols = _.EvalInt32IfConst(B->GetOperandAs<uint32_t>(4));
  505|      0|      C_cols = _.EvalInt32IfConst(C->GetOperandAs<uint32_t>(4));
  506|      0|      D_cols = _.EvalInt32IfConst(D->GetOperandAs<uint32_t>(4));
  507|       |
  508|      0|      const auto notEqual = [](std::tuple<bool, bool, uint32_t> X,
  509|      0|                               std::tuple<bool, bool, uint32_t> Y) {
  510|      0|        return (std::get<1>(X) && std::get<1>(Y) &&
  511|      0|                std::get<2>(X) != std::get<2>(Y));
  512|      0|      };
  513|       |
  514|      0|      if (notEqual(A_scope, B_scope) || notEqual(A_scope, C_scope) ||
  ------------------
  |  Branch (514:11): [True: 0, False: 0]
  |  Branch (514:41): [True: 0, False: 0]
  ------------------
  515|      0|          notEqual(A_scope, D_scope) || notEqual(B_scope, C_scope) ||
  ------------------
  |  Branch (515:11): [True: 0, False: 0]
  |  Branch (515:41): [True: 0, False: 0]
  ------------------
  516|      0|          notEqual(B_scope, D_scope) || notEqual(C_scope, D_scope)) {
  ------------------
  |  Branch (516:11): [True: 0, False: 0]
  |  Branch (516:41): [True: 0, False: 0]
  ------------------
  517|      0|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
  518|      0|               << "Cooperative matrix scopes must match: "
  519|      0|               << spvOpcodeString(opcode);
  520|      0|      }
  521|       |
  522|      0|      if (notEqual(A_rows, C_rows) || notEqual(A_rows, D_rows) ||
  ------------------
  |  Branch (522:11): [True: 0, False: 0]
  |  Branch (522:39): [True: 0, False: 0]
  ------------------
  523|      0|          notEqual(C_rows, D_rows)) {
  ------------------
  |  Branch (523:11): [True: 0, False: 0]
  ------------------
  524|      0|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
  525|      0|               << "Cooperative matrix 'M' mismatch: "
  526|      0|               << spvOpcodeString(opcode);
  527|      0|      }
  528|       |
  529|      0|      if (notEqual(B_cols, C_cols) || notEqual(B_cols, D_cols) ||
  ------------------
  |  Branch (529:11): [True: 0, False: 0]
  |  Branch (529:39): [True: 0, False: 0]
  ------------------
  530|      0|          notEqual(C_cols, D_cols)) {
  ------------------
  |  Branch (530:11): [True: 0, False: 0]
  ------------------
  531|      0|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
  532|      0|               << "Cooperative matrix 'N' mismatch: "
  533|      0|               << spvOpcodeString(opcode);
  534|      0|      }
  535|       |
  536|      0|      if (notEqual(A_cols, B_rows)) {
  ------------------
  |  Branch (536:11): [True: 0, False: 0]
  ------------------
  537|      0|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
  538|      0|               << "Cooperative matrix 'K' mismatch: "
  539|      0|               << spvOpcodeString(opcode);
  540|      0|      }
  541|      0|      break;
  542|      0|    }
  543|       |
  544|   277k|    default:
  ------------------
  |  Branch (544:5): [True: 277k, False: 7.88k]
  ------------------
  545|   277k|      break;
  546|   285k|  }
  547|       |
  548|   285k|  return SPV_SUCCESS;
  549|   285k|}

_ZN8spvtools3val11AtomicsPassERNS0_17ValidationState_tEPKNS0_11InstructionE:
  123|   285k|spv_result_t AtomicsPass(ValidationState_t& _, const Instruction* inst) {
  124|   285k|  const spv::Op opcode = inst->opcode();
  125|   285k|  switch (opcode) {
  126|      2|    case spv::Op::OpAtomicLoad:
  ------------------
  |  Branch (126:5): [True: 2, False: 285k]
  ------------------
  127|      2|    case spv::Op::OpAtomicStore:
  ------------------
  |  Branch (127:5): [True: 0, False: 285k]
  ------------------
  128|      2|    case spv::Op::OpAtomicExchange:
  ------------------
  |  Branch (128:5): [True: 0, False: 285k]
  ------------------
  129|      2|    case spv::Op::OpAtomicFAddEXT:
  ------------------
  |  Branch (129:5): [True: 0, False: 285k]
  ------------------
  130|      2|    case spv::Op::OpAtomicCompareExchange:
  ------------------
  |  Branch (130:5): [True: 0, False: 285k]
  ------------------
  131|      2|    case spv::Op::OpAtomicCompareExchangeWeak:
  ------------------
  |  Branch (131:5): [True: 0, False: 285k]
  ------------------
  132|      3|    case spv::Op::OpAtomicIIncrement:
  ------------------
  |  Branch (132:5): [True: 1, False: 285k]
  ------------------
  133|      3|    case spv::Op::OpAtomicIDecrement:
  ------------------
  |  Branch (133:5): [True: 0, False: 285k]
  ------------------
  134|      5|    case spv::Op::OpAtomicIAdd:
  ------------------
  |  Branch (134:5): [True: 2, False: 285k]
  ------------------
  135|      6|    case spv::Op::OpAtomicISub:
  ------------------
  |  Branch (135:5): [True: 1, False: 285k]
  ------------------
  136|      7|    case spv::Op::OpAtomicSMin:
  ------------------
  |  Branch (136:5): [True: 1, False: 285k]
  ------------------
  137|      8|    case spv::Op::OpAtomicUMin:
  ------------------
  |  Branch (137:5): [True: 1, False: 285k]
  ------------------
  138|      8|    case spv::Op::OpAtomicFMinEXT:
  ------------------
  |  Branch (138:5): [True: 0, False: 285k]
  ------------------
  139|      8|    case spv::Op::OpAtomicSMax:
  ------------------
  |  Branch (139:5): [True: 0, False: 285k]
  ------------------
  140|     10|    case spv::Op::OpAtomicUMax:
  ------------------
  |  Branch (140:5): [True: 2, False: 285k]
  ------------------
  141|     10|    case spv::Op::OpAtomicFMaxEXT:
  ------------------
  |  Branch (141:5): [True: 0, False: 285k]
  ------------------
  142|     11|    case spv::Op::OpAtomicAnd:
  ------------------
  |  Branch (142:5): [True: 1, False: 285k]
  ------------------
  143|     12|    case spv::Op::OpAtomicOr:
  ------------------
  |  Branch (143:5): [True: 1, False: 285k]
  ------------------
  144|     13|    case spv::Op::OpAtomicXor:
  ------------------
  |  Branch (144:5): [True: 1, False: 285k]
  ------------------
  145|     13|    case spv::Op::OpAtomicFlagTestAndSet:
  ------------------
  |  Branch (145:5): [True: 0, False: 285k]
  ------------------
  146|     13|    case spv::Op::OpAtomicFlagClear: {
  ------------------
  |  Branch (146:5): [True: 0, False: 285k]
  ------------------
  147|     13|      const uint32_t result_type = inst->type_id();
  148|       |
  149|       |      // All current atomics only are scalar result
  150|       |      // Validate return type first so can just check if pointer type is same
  151|       |      // (if applicable)
  152|     13|      if (HasReturnType(opcode)) {
  ------------------
  |  Branch (152:11): [True: 13, False: 0]
  ------------------
  153|     13|        if (HasOnlyFloatReturnType(opcode) &&
  ------------------
  |  Branch (153:13): [True: 0, False: 13]
  ------------------
  154|     13|            !_.IsFloatScalarType(result_type)) {
  ------------------
  |  Branch (154:13): [True: 0, False: 0]
  ------------------
  155|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
  156|      0|                 << spvOpcodeString(opcode)
  157|      0|                 << ": expected Result Type to be float scalar type";
  158|     13|        } else if (HasOnlyIntReturnType(opcode) &&
  ------------------
  |  Branch (158:20): [True: 11, False: 2]
  ------------------
  159|     13|                   !_.IsIntScalarType(result_type)) {
  ------------------
  |  Branch (159:20): [True: 2, False: 9]
  ------------------
  160|      2|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
  161|      2|                 << spvOpcodeString(opcode)
  162|      2|                 << ": expected Result Type to be integer scalar type";
  163|     11|        } else if (HasIntOrFloatReturnType(opcode) &&
  ------------------
  |  Branch (163:20): [True: 2, False: 9]
  ------------------
  164|     11|                   !_.IsFloatScalarType(result_type) &&
  ------------------
  |  Branch (164:20): [True: 1, False: 1]
  ------------------
  165|     11|                   !_.IsIntScalarType(result_type)) {
  ------------------
  |  Branch (165:20): [True: 1, False: 0]
  ------------------
  166|      1|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
  167|      1|                 << spvOpcodeString(opcode)
  168|      1|                 << ": expected Result Type to be integer or float scalar type";
  169|     10|        } else if (HasOnlyBoolReturnType(opcode) &&
  ------------------
  |  Branch (169:20): [True: 0, False: 10]
  ------------------
  170|     10|                   !_.IsBoolScalarType(result_type)) {
  ------------------
  |  Branch (170:20): [True: 0, False: 0]
  ------------------
  171|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
  172|      0|                 << spvOpcodeString(opcode)
  173|      0|                 << ": expected Result Type to be bool scalar type";
  174|      0|        }
  175|     13|      }
  176|       |
  177|     10|      uint32_t operand_index = HasReturnType(opcode) ? 2 : 0;
  ------------------
  |  Branch (177:32): [True: 10, False: 0]
  ------------------
  178|     10|      const uint32_t pointer_type = _.GetOperandTypeId(inst, operand_index++);
  179|     10|      uint32_t data_type = 0;
  180|     10|      spv::StorageClass storage_class;
  181|     10|      if (!_.GetPointerTypeInfo(pointer_type, &data_type, &storage_class)) {
  ------------------
  |  Branch (181:11): [True: 1, False: 9]
  ------------------
  182|      1|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
  183|      1|               << spvOpcodeString(opcode)
  184|      1|               << ": expected Pointer to be of type OpTypePointer";
  185|      1|      }
  186|       |
  187|       |      // Can't use result_type because OpAtomicStore doesn't have a result
  188|      9|      if (_.IsIntScalarType(data_type) && _.GetBitWidth(data_type) == 64 &&
  ------------------
  |  Branch (188:11): [True: 8, False: 1]
  |  Branch (188:43): [True: 0, False: 8]
  ------------------
  189|      9|          !_.HasCapability(spv::Capability::Int64Atomics)) {
  ------------------
  |  Branch (189:11): [True: 0, False: 0]
  ------------------
  190|      0|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
  191|      0|               << spvOpcodeString(opcode)
  192|      0|               << ": 64-bit atomics require the Int64Atomics capability";
  193|      0|      }
  194|       |
  195|       |      // Validate storage class against universal rules
  196|      9|      if (!IsStorageClassAllowedByUniversalRules(storage_class)) {
  ------------------
  |  Branch (196:11): [True: 1, False: 8]
  ------------------
  197|      1|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
  198|      1|               << spvOpcodeString(opcode)
  199|      1|               << ": storage class forbidden by universal validation rules.";
  200|      1|      }
  201|       |
  202|       |      // Then Shader rules
  203|      8|      if (_.HasCapability(spv::Capability::Shader)) {
  ------------------
  |  Branch (203:11): [True: 8, False: 0]
  ------------------
  204|       |        // Vulkan environment rule
  205|      8|        if (spvIsVulkanEnv(_.context()->target_env)) {
  ------------------
  |  Branch (205:13): [True: 0, False: 8]
  ------------------
  206|      0|          if ((storage_class != spv::StorageClass::Uniform) &&
  ------------------
  |  Branch (206:15): [True: 0, False: 0]
  ------------------
  207|      0|              (storage_class != spv::StorageClass::StorageBuffer) &&
  ------------------
  |  Branch (207:15): [True: 0, False: 0]
  ------------------
  208|      0|              (storage_class != spv::StorageClass::Workgroup) &&
  ------------------
  |  Branch (208:15): [True: 0, False: 0]
  ------------------
  209|      0|              (storage_class != spv::StorageClass::Image) &&
  ------------------
  |  Branch (209:15): [True: 0, False: 0]
  ------------------
  210|      0|              (storage_class != spv::StorageClass::PhysicalStorageBuffer) &&
  ------------------
  |  Branch (210:15): [True: 0, False: 0]
  ------------------
  211|      0|              (storage_class != spv::StorageClass::TaskPayloadWorkgroupEXT)) {
  ------------------
  |  Branch (211:15): [True: 0, False: 0]
  ------------------
  212|      0|            return _.diag(SPV_ERROR_INVALID_DATA, inst)
  213|      0|                   << _.VkErrorID(4686) << spvOpcodeString(opcode)
  214|      0|                   << ": Vulkan spec only allows storage classes for atomic to "
  215|      0|                      "be: Uniform, Workgroup, Image, StorageBuffer, "
  216|      0|                      "PhysicalStorageBuffer or TaskPayloadWorkgroupEXT.";
  217|      0|          }
  218|      8|        } else if (storage_class == spv::StorageClass::Function) {
  ------------------
  |  Branch (218:20): [True: 0, False: 8]
  ------------------
  219|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
  220|      0|                 << spvOpcodeString(opcode)
  221|      0|                 << ": Function storage class forbidden when the Shader "
  222|      0|                    "capability is declared.";
  223|      0|        }
  224|       |
  225|      8|        if (opcode == spv::Op::OpAtomicFAddEXT) {
  ------------------
  |  Branch (225:13): [True: 0, False: 8]
  ------------------
  226|       |          // result type being float checked already
  227|      0|          if ((_.GetBitWidth(result_type) == 16) &&
  ------------------
  |  Branch (227:15): [True: 0, False: 0]
  ------------------
  228|      0|              (!_.HasCapability(spv::Capability::AtomicFloat16AddEXT))) {
  ------------------
  |  Branch (228:15): [True: 0, False: 0]
  ------------------
  229|      0|            return _.diag(SPV_ERROR_INVALID_DATA, inst)
  230|      0|                   << spvOpcodeString(opcode)
  231|      0|                   << ": float add atomics require the AtomicFloat32AddEXT "
  232|      0|                      "capability";
  233|      0|          }
  234|      0|          if ((_.GetBitWidth(result_type) == 32) &&
  ------------------
  |  Branch (234:15): [True: 0, False: 0]
  ------------------
  235|      0|              (!_.HasCapability(spv::Capability::AtomicFloat32AddEXT))) {
  ------------------
  |  Branch (235:15): [True: 0, False: 0]
  ------------------
  236|      0|            return _.diag(SPV_ERROR_INVALID_DATA, inst)
  237|      0|                   << spvOpcodeString(opcode)
  238|      0|                   << ": float add atomics require the AtomicFloat32AddEXT "
  239|      0|                      "capability";
  240|      0|          }
  241|      0|          if ((_.GetBitWidth(result_type) == 64) &&
  ------------------
  |  Branch (241:15): [True: 0, False: 0]
  ------------------
  242|      0|              (!_.HasCapability(spv::Capability::AtomicFloat64AddEXT))) {
  ------------------
  |  Branch (242:15): [True: 0, False: 0]
  ------------------
  243|      0|            return _.diag(SPV_ERROR_INVALID_DATA, inst)
  244|      0|                   << spvOpcodeString(opcode)
  245|      0|                   << ": float add atomics require the AtomicFloat64AddEXT "
  246|      0|                      "capability";
  247|      0|          }
  248|      8|        } else if (opcode == spv::Op::OpAtomicFMinEXT ||
  ------------------
  |  Branch (248:20): [True: 0, False: 8]
  ------------------
  249|      8|                   opcode == spv::Op::OpAtomicFMaxEXT) {
  ------------------
  |  Branch (249:20): [True: 0, False: 8]
  ------------------
  250|      0|          if ((_.GetBitWidth(result_type) == 16) &&
  ------------------
  |  Branch (250:15): [True: 0, False: 0]
  ------------------
  251|      0|              (!_.HasCapability(spv::Capability::AtomicFloat16MinMaxEXT))) {
  ------------------
  |  Branch (251:15): [True: 0, False: 0]
  ------------------
  252|      0|            return _.diag(SPV_ERROR_INVALID_DATA, inst)
  253|      0|                   << spvOpcodeString(opcode)
  254|      0|                   << ": float min/max atomics require the "
  255|      0|                      "AtomicFloat16MinMaxEXT capability";
  256|      0|          }
  257|      0|          if ((_.GetBitWidth(result_type) == 32) &&
  ------------------
  |  Branch (257:15): [True: 0, False: 0]
  ------------------
  258|      0|              (!_.HasCapability(spv::Capability::AtomicFloat32MinMaxEXT))) {
  ------------------
  |  Branch (258:15): [True: 0, False: 0]
  ------------------
  259|      0|            return _.diag(SPV_ERROR_INVALID_DATA, inst)
  260|      0|                   << spvOpcodeString(opcode)
  261|      0|                   << ": float min/max atomics require the "
  262|      0|                      "AtomicFloat32MinMaxEXT capability";
  263|      0|          }
  264|      0|          if ((_.GetBitWidth(result_type) == 64) &&
  ------------------
  |  Branch (264:15): [True: 0, False: 0]
  ------------------
  265|      0|              (!_.HasCapability(spv::Capability::AtomicFloat64MinMaxEXT))) {
  ------------------
  |  Branch (265:15): [True: 0, False: 0]
  ------------------
  266|      0|            return _.diag(SPV_ERROR_INVALID_DATA, inst)
  267|      0|                   << spvOpcodeString(opcode)
  268|      0|                   << ": float min/max atomics require the "
  269|      0|                      "AtomicFloat64MinMaxEXT capability";
  270|      0|          }
  271|      0|        }
  272|      8|      }
  273|       |
  274|       |      // And finally OpenCL environment rules
  275|      8|      if (spvIsOpenCLEnv(_.context()->target_env)) {
  ------------------
  |  Branch (275:11): [True: 0, False: 8]
  ------------------
  276|      0|        if ((storage_class != spv::StorageClass::Function) &&
  ------------------
  |  Branch (276:13): [True: 0, False: 0]
  ------------------
  277|      0|            (storage_class != spv::StorageClass::Workgroup) &&
  ------------------
  |  Branch (277:13): [True: 0, False: 0]
  ------------------
  278|      0|            (storage_class != spv::StorageClass::CrossWorkgroup) &&
  ------------------
  |  Branch (278:13): [True: 0, False: 0]
  ------------------
  279|      0|            (storage_class != spv::StorageClass::Generic)) {
  ------------------
  |  Branch (279:13): [True: 0, False: 0]
  ------------------
  280|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
  281|      0|                 << spvOpcodeString(opcode)
  282|      0|                 << ": storage class must be Function, Workgroup, "
  283|      0|                    "CrossWorkGroup or Generic in the OpenCL environment.";
  284|      0|        }
  285|       |
  286|      0|        if (_.context()->target_env == SPV_ENV_OPENCL_1_2) {
  ------------------
  |  Branch (286:13): [True: 0, False: 0]
  ------------------
  287|      0|          if (storage_class == spv::StorageClass::Generic) {
  ------------------
  |  Branch (287:15): [True: 0, False: 0]
  ------------------
  288|      0|            return _.diag(SPV_ERROR_INVALID_DATA, inst)
  289|      0|                   << "Storage class cannot be Generic in OpenCL 1.2 "
  290|      0|                      "environment";
  291|      0|          }
  292|      0|        }
  293|      0|      }
  294|       |
  295|       |      // If result and pointer type are different, need to do special check here
  296|      8|      if (opcode == spv::Op::OpAtomicFlagTestAndSet ||
  ------------------
  |  Branch (296:11): [True: 0, False: 8]
  ------------------
  297|      8|          opcode == spv::Op::OpAtomicFlagClear) {
  ------------------
  |  Branch (297:11): [True: 0, False: 8]
  ------------------
  298|      0|        if (!_.IsIntScalarType(data_type) || _.GetBitWidth(data_type) != 32) {
  ------------------
  |  Branch (298:13): [True: 0, False: 0]
  |  Branch (298:46): [True: 0, False: 0]
  ------------------
  299|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
  300|      0|                 << spvOpcodeString(opcode)
  301|      0|                 << ": expected Pointer to point to a value of 32-bit integer "
  302|      0|                    "type";
  303|      0|        }
  304|      8|      } else if (opcode == spv::Op::OpAtomicStore) {
  ------------------
  |  Branch (304:18): [True: 0, False: 8]
  ------------------
  305|      0|        if (!_.IsFloatScalarType(data_type) && !_.IsIntScalarType(data_type)) {
  ------------------
  |  Branch (305:13): [True: 0, False: 0]
  |  Branch (305:48): [True: 0, False: 0]
  ------------------
  306|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
  307|      0|                 << spvOpcodeString(opcode)
  308|      0|                 << ": expected Pointer to be a pointer to integer or float "
  309|      0|                 << "scalar type";
  310|      0|        }
  311|      8|      } else if (data_type != result_type) {
  ------------------
  |  Branch (311:18): [True: 1, False: 7]
  ------------------
  312|      1|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
  313|      1|               << spvOpcodeString(opcode)
  314|      1|               << ": expected Pointer to point to a value of type Result "
  315|      1|                  "Type";
  316|      1|      }
  317|       |
  318|      7|      auto memory_scope = inst->GetOperandAs<const uint32_t>(operand_index++);
  319|      7|      if (auto error = ValidateMemoryScope(_, inst, memory_scope)) {
  ------------------
  |  Branch (319:16): [True: 3, False: 4]
  ------------------
  320|      3|        return error;
  321|      3|      }
  322|       |
  323|      4|      const auto equal_semantics_index = operand_index++;
  324|      4|      if (auto error = ValidateMemorySemantics(_, inst, equal_semantics_index,
  ------------------
  |  Branch (324:16): [True: 1, False: 3]
  ------------------
  325|      4|                                               memory_scope))
  326|      1|        return error;
  327|       |
  328|      3|      if (opcode == spv::Op::OpAtomicCompareExchange ||
  ------------------
  |  Branch (328:11): [True: 0, False: 3]
  ------------------
  329|      3|          opcode == spv::Op::OpAtomicCompareExchangeWeak) {
  ------------------
  |  Branch (329:11): [True: 0, False: 3]
  ------------------
  330|      0|        const auto unequal_semantics_index = operand_index++;
  331|      0|        if (auto error = ValidateMemorySemantics(
  ------------------
  |  Branch (331:18): [True: 0, False: 0]
  ------------------
  332|      0|                _, inst, unequal_semantics_index, memory_scope))
  333|      0|          return error;
  334|       |
  335|       |        // Volatile bits must match for equal and unequal semantics. Previous
  336|       |        // checks guarantee they are 32-bit constants, but we need to recheck
  337|       |        // whether they are evaluatable constants.
  338|      0|        bool is_int32 = false;
  339|      0|        bool is_equal_const = false;
  340|      0|        bool is_unequal_const = false;
  341|      0|        uint32_t equal_value = 0;
  342|      0|        uint32_t unequal_value = 0;
  343|      0|        std::tie(is_int32, is_equal_const, equal_value) = _.EvalInt32IfConst(
  344|      0|            inst->GetOperandAs<uint32_t>(equal_semantics_index));
  345|      0|        std::tie(is_int32, is_unequal_const, unequal_value) =
  346|      0|            _.EvalInt32IfConst(
  347|      0|                inst->GetOperandAs<uint32_t>(unequal_semantics_index));
  348|      0|        if (is_equal_const && is_unequal_const &&
  ------------------
  |  Branch (348:13): [True: 0, False: 0]
  |  Branch (348:31): [True: 0, False: 0]
  ------------------
  349|      0|            ((equal_value & uint32_t(spv::MemorySemanticsMask::Volatile)) ^
  ------------------
  |  Branch (349:13): [True: 0, False: 0]
  ------------------
  350|      0|             (unequal_value & uint32_t(spv::MemorySemanticsMask::Volatile)))) {
  351|      0|          return _.diag(SPV_ERROR_INVALID_ID, inst)
  352|      0|                 << "Volatile mask setting must match for Equal and Unequal "
  353|      0|                    "memory semantics";
  354|      0|        }
  355|      0|      }
  356|       |
  357|      3|      if (opcode == spv::Op::OpAtomicStore) {
  ------------------
  |  Branch (357:11): [True: 0, False: 3]
  ------------------
  358|      0|        const uint32_t value_type = _.GetOperandTypeId(inst, 3);
  359|      0|        if (value_type != data_type) {
  ------------------
  |  Branch (359:13): [True: 0, False: 0]
  ------------------
  360|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
  361|      0|                 << spvOpcodeString(opcode)
  362|      0|                 << ": expected Value type and the type pointed to by "
  363|      0|                    "Pointer to be the same";
  364|      0|        }
  365|      3|      } else if (opcode != spv::Op::OpAtomicLoad &&
  ------------------
  |  Branch (365:18): [True: 3, False: 0]
  ------------------
  366|      3|                 opcode != spv::Op::OpAtomicIIncrement &&
  ------------------
  |  Branch (366:18): [True: 3, False: 0]
  ------------------
  367|      3|                 opcode != spv::Op::OpAtomicIDecrement &&
  ------------------
  |  Branch (367:18): [True: 3, False: 0]
  ------------------
  368|      3|                 opcode != spv::Op::OpAtomicFlagTestAndSet &&
  ------------------
  |  Branch (368:18): [True: 3, False: 0]
  ------------------
  369|      3|                 opcode != spv::Op::OpAtomicFlagClear) {
  ------------------
  |  Branch (369:18): [True: 3, False: 0]
  ------------------
  370|      3|        const uint32_t value_type = _.GetOperandTypeId(inst, operand_index++);
  371|      3|        if (value_type != result_type) {
  ------------------
  |  Branch (371:13): [True: 3, False: 0]
  ------------------
  372|      3|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
  373|      3|                 << spvOpcodeString(opcode)
  374|      3|                 << ": expected Value to be of type Result Type";
  375|      3|        }
  376|      3|      }
  377|       |
  378|      0|      if (opcode == spv::Op::OpAtomicCompareExchange ||
  ------------------
  |  Branch (378:11): [True: 0, False: 0]
  ------------------
  379|      0|          opcode == spv::Op::OpAtomicCompareExchangeWeak) {
  ------------------
  |  Branch (379:11): [True: 0, False: 0]
  ------------------
  380|      0|        const uint32_t comparator_type =
  381|      0|            _.GetOperandTypeId(inst, operand_index++);
  382|      0|        if (comparator_type != result_type) {
  ------------------
  |  Branch (382:13): [True: 0, False: 0]
  ------------------
  383|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
  384|      0|                 << spvOpcodeString(opcode)
  385|      0|                 << ": expected Comparator to be of type Result Type";
  386|      0|        }
  387|      0|      }
  388|       |
  389|      0|      break;
  390|      0|    }
  391|       |
  392|   285k|    default:
  ------------------
  |  Branch (392:5): [True: 285k, False: 13]
  ------------------
  393|   285k|      break;
  394|   285k|  }
  395|       |
  396|   285k|  return SPV_SUCCESS;
  397|   285k|}
validate_atomics.cpp:_ZN12_GLOBAL__N_113HasReturnTypeEN3spv2OpE:
   51|     23|bool HasReturnType(spv::Op opcode) {
   52|     23|  switch (opcode) {
   53|      0|    case spv::Op::OpAtomicStore:
  ------------------
  |  Branch (53:5): [True: 0, False: 23]
  ------------------
   54|      0|    case spv::Op::OpAtomicFlagClear:
  ------------------
  |  Branch (54:5): [True: 0, False: 23]
  ------------------
   55|      0|      return false;
   56|      0|      break;
   57|     23|    default:
  ------------------
  |  Branch (57:5): [True: 23, False: 0]
  ------------------
   58|     23|      return true;
   59|     23|  }
   60|     23|}
validate_atomics.cpp:_ZN12_GLOBAL__N_122HasOnlyFloatReturnTypeEN3spv2OpE:
   62|     13|bool HasOnlyFloatReturnType(spv::Op opcode) {
   63|     13|  switch (opcode) {
   64|      0|    case spv::Op::OpAtomicFAddEXT:
  ------------------
  |  Branch (64:5): [True: 0, False: 13]
  ------------------
   65|      0|    case spv::Op::OpAtomicFMinEXT:
  ------------------
  |  Branch (65:5): [True: 0, False: 13]
  ------------------
   66|      0|    case spv::Op::OpAtomicFMaxEXT:
  ------------------
  |  Branch (66:5): [True: 0, False: 13]
  ------------------
   67|      0|      return true;
   68|      0|      break;
   69|     13|    default:
  ------------------
  |  Branch (69:5): [True: 13, False: 0]
  ------------------
   70|     13|      return false;
   71|     13|  }
   72|     13|}
validate_atomics.cpp:_ZN12_GLOBAL__N_120HasOnlyIntReturnTypeEN3spv2OpE:
   74|     13|bool HasOnlyIntReturnType(spv::Op opcode) {
   75|     13|  switch (opcode) {
   76|      0|    case spv::Op::OpAtomicCompareExchange:
  ------------------
  |  Branch (76:5): [True: 0, False: 13]
  ------------------
   77|      0|    case spv::Op::OpAtomicCompareExchangeWeak:
  ------------------
  |  Branch (77:5): [True: 0, False: 13]
  ------------------
   78|      1|    case spv::Op::OpAtomicIIncrement:
  ------------------
  |  Branch (78:5): [True: 1, False: 12]
  ------------------
   79|      1|    case spv::Op::OpAtomicIDecrement:
  ------------------
  |  Branch (79:5): [True: 0, False: 13]
  ------------------
   80|      3|    case spv::Op::OpAtomicIAdd:
  ------------------
  |  Branch (80:5): [True: 2, False: 11]
  ------------------
   81|      4|    case spv::Op::OpAtomicISub:
  ------------------
  |  Branch (81:5): [True: 1, False: 12]
  ------------------
   82|      5|    case spv::Op::OpAtomicSMin:
  ------------------
  |  Branch (82:5): [True: 1, False: 12]
  ------------------
   83|      6|    case spv::Op::OpAtomicUMin:
  ------------------
  |  Branch (83:5): [True: 1, False: 12]
  ------------------
   84|      6|    case spv::Op::OpAtomicSMax:
  ------------------
  |  Branch (84:5): [True: 0, False: 13]
  ------------------
   85|      8|    case spv::Op::OpAtomicUMax:
  ------------------
  |  Branch (85:5): [True: 2, False: 11]
  ------------------
   86|      9|    case spv::Op::OpAtomicAnd:
  ------------------
  |  Branch (86:5): [True: 1, False: 12]
  ------------------
   87|     10|    case spv::Op::OpAtomicOr:
  ------------------
  |  Branch (87:5): [True: 1, False: 12]
  ------------------
   88|     11|    case spv::Op::OpAtomicXor:
  ------------------
  |  Branch (88:5): [True: 1, False: 12]
  ------------------
   89|     11|      return true;
   90|      0|      break;
   91|      2|    default:
  ------------------
  |  Branch (91:5): [True: 2, False: 11]
  ------------------
   92|      2|      return false;
   93|     13|  }
   94|     13|}
validate_atomics.cpp:_ZN12_GLOBAL__N_123HasIntOrFloatReturnTypeEN3spv2OpE:
   96|     11|bool HasIntOrFloatReturnType(spv::Op opcode) {
   97|     11|  switch (opcode) {
   98|      2|    case spv::Op::OpAtomicLoad:
  ------------------
  |  Branch (98:5): [True: 2, False: 9]
  ------------------
   99|      2|    case spv::Op::OpAtomicExchange:
  ------------------
  |  Branch (99:5): [True: 0, False: 11]
  ------------------
  100|      2|      return true;
  101|      0|      break;
  102|      9|    default:
  ------------------
  |  Branch (102:5): [True: 9, False: 2]
  ------------------
  103|      9|      return false;
  104|     11|  }
  105|     11|}
validate_atomics.cpp:_ZN12_GLOBAL__N_121HasOnlyBoolReturnTypeEN3spv2OpE:
  107|     10|bool HasOnlyBoolReturnType(spv::Op opcode) {
  108|     10|  switch (opcode) {
  109|      0|    case spv::Op::OpAtomicFlagTestAndSet:
  ------------------
  |  Branch (109:5): [True: 0, False: 10]
  ------------------
  110|      0|      return true;
  111|      0|      break;
  112|     10|    default:
  ------------------
  |  Branch (112:5): [True: 10, False: 0]
  ------------------
  113|     10|      return false;
  114|     10|  }
  115|     10|}
validate_atomics.cpp:_ZN12_GLOBAL__N_137IsStorageClassAllowedByUniversalRulesEN3spv12StorageClassE:
   32|      9|bool IsStorageClassAllowedByUniversalRules(spv::StorageClass storage_class) {
   33|      9|  switch (storage_class) {
   34|      8|    case spv::StorageClass::Uniform:
  ------------------
  |  Branch (34:5): [True: 8, False: 1]
  ------------------
   35|      8|    case spv::StorageClass::StorageBuffer:
  ------------------
  |  Branch (35:5): [True: 0, False: 9]
  ------------------
   36|      8|    case spv::StorageClass::Workgroup:
  ------------------
  |  Branch (36:5): [True: 0, False: 9]
  ------------------
   37|      8|    case spv::StorageClass::CrossWorkgroup:
  ------------------
  |  Branch (37:5): [True: 0, False: 9]
  ------------------
   38|      8|    case spv::StorageClass::Generic:
  ------------------
  |  Branch (38:5): [True: 0, False: 9]
  ------------------
   39|      8|    case spv::StorageClass::AtomicCounter:
  ------------------
  |  Branch (39:5): [True: 0, False: 9]
  ------------------
   40|      8|    case spv::StorageClass::Image:
  ------------------
  |  Branch (40:5): [True: 0, False: 9]
  ------------------
   41|      8|    case spv::StorageClass::Function:
  ------------------
  |  Branch (41:5): [True: 0, False: 9]
  ------------------
   42|      8|    case spv::StorageClass::PhysicalStorageBuffer:
  ------------------
  |  Branch (42:5): [True: 0, False: 9]
  ------------------
   43|      8|    case spv::StorageClass::TaskPayloadWorkgroupEXT:
  ------------------
  |  Branch (43:5): [True: 0, False: 9]
  ------------------
   44|      8|      return true;
   45|      0|      break;
   46|      1|    default:
  ------------------
  |  Branch (46:5): [True: 1, False: 8]
  ------------------
   47|      1|      return false;
   48|      9|  }
   49|      9|}

_ZN8spvtools3val12BarriersPassERNS0_17ValidationState_tEPKNS0_11InstructionE:
   34|   285k|spv_result_t BarriersPass(ValidationState_t& _, const Instruction* inst) {
   35|   285k|  const spv::Op opcode = inst->opcode();
   36|   285k|  const uint32_t result_type = inst->type_id();
   37|       |
   38|   285k|  switch (opcode) {
   39|    392|    case spv::Op::OpControlBarrier: {
  ------------------
  |  Branch (39:5): [True: 392, False: 285k]
  ------------------
   40|    392|      if (_.version() < SPV_SPIRV_VERSION_WORD(1, 3)) {
  ------------------
  |  |   26|    392|  ((uint32_t(uint8_t(MAJOR)) << 16) | (uint32_t(uint8_t(MINOR)) << 8))
  ------------------
  |  Branch (40:11): [True: 392, False: 0]
  ------------------
   41|    392|        _.function(inst->function()->id())
   42|    392|            ->RegisterExecutionModelLimitation(
   43|    392|                [](spv::ExecutionModel model, std::string* message) {
   44|    392|                  if (model != spv::ExecutionModel::TessellationControl &&
   45|    392|                      model != spv::ExecutionModel::GLCompute &&
   46|    392|                      model != spv::ExecutionModel::Kernel &&
   47|    392|                      model != spv::ExecutionModel::TaskNV &&
   48|    392|                      model != spv::ExecutionModel::MeshNV) {
   49|    392|                    if (message) {
   50|    392|                      *message =
   51|    392|                          "OpControlBarrier requires one of the following "
   52|    392|                          "Execution "
   53|    392|                          "Models: TessellationControl, GLCompute, Kernel, "
   54|    392|                          "MeshNV or TaskNV";
   55|    392|                    }
   56|    392|                    return false;
   57|    392|                  }
   58|    392|                  return true;
   59|    392|                });
   60|    392|      }
   61|       |
   62|    392|      const uint32_t execution_scope = inst->word(1);
   63|    392|      const uint32_t memory_scope = inst->word(2);
   64|       |
   65|    392|      if (auto error = ValidateExecutionScope(_, inst, execution_scope)) {
  ------------------
  |  Branch (65:16): [True: 13, False: 379]
  ------------------
   66|     13|        return error;
   67|     13|      }
   68|       |
   69|    379|      if (auto error = ValidateMemoryScope(_, inst, memory_scope)) {
  ------------------
  |  Branch (69:16): [True: 0, False: 379]
  ------------------
   70|      0|        return error;
   71|      0|      }
   72|       |
   73|    379|      if (auto error = ValidateMemorySemantics(_, inst, 2, memory_scope)) {
  ------------------
  |  Branch (73:16): [True: 0, False: 379]
  ------------------
   74|      0|        return error;
   75|      0|      }
   76|    379|      break;
   77|    379|    }
   78|       |
   79|    379|    case spv::Op::OpMemoryBarrier: {
  ------------------
  |  Branch (79:5): [True: 8, False: 285k]
  ------------------
   80|      8|      const uint32_t memory_scope = inst->word(1);
   81|       |
   82|      8|      if (auto error = ValidateMemoryScope(_, inst, memory_scope)) {
  ------------------
  |  Branch (82:16): [True: 2, False: 6]
  ------------------
   83|      2|        return error;
   84|      2|      }
   85|       |
   86|      6|      if (auto error = ValidateMemorySemantics(_, inst, 1, memory_scope)) {
  ------------------
  |  Branch (86:16): [True: 3, False: 3]
  ------------------
   87|      3|        return error;
   88|      3|      }
   89|      3|      break;
   90|      6|    }
   91|       |
   92|      3|    case spv::Op::OpNamedBarrierInitialize: {
  ------------------
  |  Branch (92:5): [True: 0, False: 285k]
  ------------------
   93|      0|      if (_.GetIdOpcode(result_type) != spv::Op::OpTypeNamedBarrier) {
  ------------------
  |  Branch (93:11): [True: 0, False: 0]
  ------------------
   94|      0|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
   95|      0|               << spvOpcodeString(opcode)
   96|      0|               << ": expected Result Type to be OpTypeNamedBarrier";
   97|      0|      }
   98|       |
   99|      0|      const uint32_t subgroup_count_type = _.GetOperandTypeId(inst, 2);
  100|      0|      if (!_.IsIntScalarType(subgroup_count_type) ||
  ------------------
  |  Branch (100:11): [True: 0, False: 0]
  ------------------
  101|      0|          _.GetBitWidth(subgroup_count_type) != 32) {
  ------------------
  |  Branch (101:11): [True: 0, False: 0]
  ------------------
  102|      0|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
  103|      0|               << spvOpcodeString(opcode)
  104|      0|               << ": expected Subgroup Count to be a 32-bit int";
  105|      0|      }
  106|      0|      break;
  107|      0|    }
  108|       |
  109|      0|    case spv::Op::OpMemoryNamedBarrier: {
  ------------------
  |  Branch (109:5): [True: 0, False: 285k]
  ------------------
  110|      0|      const uint32_t named_barrier_type = _.GetOperandTypeId(inst, 0);
  111|      0|      if (_.GetIdOpcode(named_barrier_type) != spv::Op::OpTypeNamedBarrier) {
  ------------------
  |  Branch (111:11): [True: 0, False: 0]
  ------------------
  112|      0|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
  113|      0|               << spvOpcodeString(opcode)
  114|      0|               << ": expected Named Barrier to be of type OpTypeNamedBarrier";
  115|      0|      }
  116|       |
  117|      0|      const uint32_t memory_scope = inst->word(2);
  118|       |
  119|      0|      if (auto error = ValidateMemoryScope(_, inst, memory_scope)) {
  ------------------
  |  Branch (119:16): [True: 0, False: 0]
  ------------------
  120|      0|        return error;
  121|      0|      }
  122|       |
  123|      0|      if (auto error = ValidateMemorySemantics(_, inst, 2, memory_scope)) {
  ------------------
  |  Branch (123:16): [True: 0, False: 0]
  ------------------
  124|      0|        return error;
  125|      0|      }
  126|      0|      break;
  127|      0|    }
  128|       |
  129|   285k|    default:
  ------------------
  |  Branch (129:5): [True: 285k, False: 400]
  ------------------
  130|   285k|      break;
  131|   285k|  }
  132|       |
  133|   285k|  return SPV_SUCCESS;
  134|   285k|}
validate_barriers.cpp:_ZZN8spvtools3val12BarriersPassERNS0_17ValidationState_tEPKNS0_11InstructionEENK3$_0clEN3spv14ExecutionModelEPNSt3__112basic_stringIcNS9_11char_traitsIcEENS9_9allocatorIcEEEE:
   43|    192|                [](spv::ExecutionModel model, std::string* message) {
   44|    192|                  if (model != spv::ExecutionModel::TessellationControl &&
  ------------------
  |  Branch (44:23): [True: 183, False: 9]
  ------------------
   45|    192|                      model != spv::ExecutionModel::GLCompute &&
  ------------------
  |  Branch (45:23): [True: 163, False: 20]
  ------------------
   46|    192|                      model != spv::ExecutionModel::Kernel &&
  ------------------
  |  Branch (46:23): [True: 163, False: 0]
  ------------------
   47|    192|                      model != spv::ExecutionModel::TaskNV &&
  ------------------
  |  Branch (47:23): [True: 163, False: 0]
  ------------------
   48|    192|                      model != spv::ExecutionModel::MeshNV) {
  ------------------
  |  Branch (48:23): [True: 163, False: 0]
  ------------------
   49|    163|                    if (message) {
  ------------------
  |  Branch (49:25): [True: 163, False: 0]
  ------------------
   50|    163|                      *message =
   51|    163|                          "OpControlBarrier requires one of the following "
   52|    163|                          "Execution "
   53|    163|                          "Models: TessellationControl, GLCompute, Kernel, "
   54|    163|                          "MeshNV or TaskNV";
   55|    163|                    }
   56|    163|                    return false;
   57|    163|                  }
   58|     29|                  return true;
   59|    192|                });

_ZN8spvtools3val16ValidateBaseTypeERNS0_17ValidationState_tEPKNS0_11InstructionEj:
   29|    348|                              const uint32_t base_type) {
   30|    348|  const spv::Op opcode = inst->opcode();
   31|       |
   32|    348|  if (!_.IsIntScalarType(base_type) && !_.IsIntVectorType(base_type)) {
  ------------------
  |  Branch (32:7): [True: 3, False: 345]
  |  Branch (32:40): [True: 3, False: 0]
  ------------------
   33|      3|    return _.diag(SPV_ERROR_INVALID_DATA, inst)
   34|      3|           << _.VkErrorID(4781)
   35|      3|           << "Expected int scalar or vector type for Base operand: "
   36|      3|           << spvOpcodeString(opcode);
   37|      3|  }
   38|       |
   39|       |  // Vulkan has a restriction to 32 bit for base
   40|    345|  if (spvIsVulkanEnv(_.context()->target_env)) {
  ------------------
  |  Branch (40:7): [True: 0, False: 345]
  ------------------
   41|      0|    if (_.GetBitWidth(base_type) != 32) {
  ------------------
  |  Branch (41:9): [True: 0, False: 0]
  ------------------
   42|      0|      return _.diag(SPV_ERROR_INVALID_DATA, inst)
   43|      0|             << _.VkErrorID(4781)
   44|      0|             << "Expected 32-bit int type for Base operand: "
   45|      0|             << spvOpcodeString(opcode);
   46|      0|    }
   47|      0|  }
   48|       |
   49|       |  // OpBitCount just needs same number of components
   50|    345|  if (base_type != inst->type_id() && opcode != spv::Op::OpBitCount) {
  ------------------
  |  Branch (50:7): [True: 4, False: 341]
  |  Branch (50:39): [True: 3, False: 1]
  ------------------
   51|      3|    return _.diag(SPV_ERROR_INVALID_DATA, inst)
   52|      3|           << "Expected Base Type to be equal to Result Type: "
   53|      3|           << spvOpcodeString(opcode);
   54|      3|  }
   55|       |
   56|    342|  return SPV_SUCCESS;
   57|    345|}
_ZN8spvtools3val11BitwisePassERNS0_17ValidationState_tEPKNS0_11InstructionE:
   60|   285k|spv_result_t BitwisePass(ValidationState_t& _, const Instruction* inst) {
   61|   285k|  const spv::Op opcode = inst->opcode();
   62|   285k|  const uint32_t result_type = inst->type_id();
   63|       |
   64|   285k|  switch (opcode) {
   65|     12|    case spv::Op::OpShiftRightLogical:
  ------------------
  |  Branch (65:5): [True: 12, False: 285k]
  ------------------
   66|     37|    case spv::Op::OpShiftRightArithmetic:
  ------------------
  |  Branch (66:5): [True: 25, False: 285k]
  ------------------
   67|     60|    case spv::Op::OpShiftLeftLogical: {
  ------------------
  |  Branch (67:5): [True: 23, False: 285k]
  ------------------
   68|     60|      if (!_.IsIntScalarType(result_type) && !_.IsIntVectorType(result_type))
  ------------------
  |  Branch (68:11): [True: 5, False: 55]
  |  Branch (68:46): [True: 1, False: 4]
  ------------------
   69|      1|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
   70|      1|               << "Expected int scalar or vector type as Result Type: "
   71|      1|               << spvOpcodeString(opcode);
   72|       |
   73|     59|      const uint32_t result_dimension = _.GetDimension(result_type);
   74|     59|      const uint32_t base_type = _.GetOperandTypeId(inst, 2);
   75|     59|      const uint32_t shift_type = _.GetOperandTypeId(inst, 3);
   76|       |
   77|     59|      if (!base_type ||
  ------------------
  |  Branch (77:11): [True: 0, False: 59]
  ------------------
   78|     59|          (!_.IsIntScalarType(base_type) && !_.IsIntVectorType(base_type)))
  ------------------
  |  Branch (78:12): [True: 4, False: 55]
  |  Branch (78:45): [True: 0, False: 4]
  ------------------
   79|      0|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
   80|      0|               << "Expected Base to be int scalar or vector: "
   81|      0|               << spvOpcodeString(opcode);
   82|       |
   83|     59|      if (_.GetDimension(base_type) != result_dimension)
  ------------------
  |  Branch (83:11): [True: 0, False: 59]
  ------------------
   84|      0|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
   85|      0|               << "Expected Base to have the same dimension "
   86|      0|               << "as Result Type: " << spvOpcodeString(opcode);
   87|       |
   88|     59|      if (_.GetBitWidth(base_type) != _.GetBitWidth(result_type))
  ------------------
  |  Branch (88:11): [True: 0, False: 59]
  ------------------
   89|      0|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
   90|      0|               << "Expected Base to have the same bit width "
   91|      0|               << "as Result Type: " << spvOpcodeString(opcode);
   92|       |
   93|     59|      if (!shift_type ||
  ------------------
  |  Branch (93:11): [True: 0, False: 59]
  ------------------
   94|     59|          (!_.IsIntScalarType(shift_type) && !_.IsIntVectorType(shift_type)))
  ------------------
  |  Branch (94:12): [True: 5, False: 54]
  |  Branch (94:46): [True: 0, False: 5]
  ------------------
   95|      0|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
   96|      0|               << "Expected Shift to be int scalar or vector: "
   97|      0|               << spvOpcodeString(opcode);
   98|       |
   99|     59|      if (_.GetDimension(shift_type) != result_dimension)
  ------------------
  |  Branch (99:11): [True: 1, False: 58]
  ------------------
  100|      1|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
  101|      1|               << "Expected Shift to have the same dimension "
  102|      1|               << "as Result Type: " << spvOpcodeString(opcode);
  103|     58|      break;
  104|     59|    }
  105|       |
  106|  1.04k|    case spv::Op::OpBitwiseOr:
  ------------------
  |  Branch (106:5): [True: 1.04k, False: 284k]
  ------------------
  107|  1.06k|    case spv::Op::OpBitwiseXor:
  ------------------
  |  Branch (107:5): [True: 18, False: 285k]
  ------------------
  108|  1.31k|    case spv::Op::OpBitwiseAnd:
  ------------------
  |  Branch (108:5): [True: 251, False: 285k]
  ------------------
  109|  1.71k|    case spv::Op::OpNot: {
  ------------------
  |  Branch (109:5): [True: 400, False: 285k]
  ------------------
  110|  1.71k|      if (!_.IsIntScalarType(result_type) && !_.IsIntVectorType(result_type))
  ------------------
  |  Branch (110:11): [True: 5, False: 1.71k]
  |  Branch (110:46): [True: 1, False: 4]
  ------------------
  111|      1|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
  112|      1|               << "Expected int scalar or vector type as Result Type: "
  113|      1|               << spvOpcodeString(opcode);
  114|       |
  115|  1.71k|      const uint32_t result_dimension = _.GetDimension(result_type);
  116|  1.71k|      const uint32_t result_bit_width = _.GetBitWidth(result_type);
  117|       |
  118|  4.74k|      for (size_t operand_index = 2; operand_index < inst->operands().size();
  ------------------
  |  Branch (118:38): [True: 3.02k, False: 1.71k]
  ------------------
  119|  3.02k|           ++operand_index) {
  120|  3.02k|        const uint32_t type_id = _.GetOperandTypeId(inst, operand_index);
  121|  3.02k|        if (!type_id ||
  ------------------
  |  Branch (121:13): [True: 0, False: 3.02k]
  ------------------
  122|  3.02k|            (!_.IsIntScalarType(type_id) && !_.IsIntVectorType(type_id)))
  ------------------
  |  Branch (122:14): [True: 9, False: 3.02k]
  |  Branch (122:45): [True: 0, False: 9]
  ------------------
  123|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
  124|      0|                 << "Expected int scalar or vector as operand: "
  125|      0|                 << spvOpcodeString(opcode) << " operand index "
  126|      0|                 << operand_index;
  127|       |
  128|  3.02k|        if (_.GetDimension(type_id) != result_dimension)
  ------------------
  |  Branch (128:13): [True: 2, False: 3.02k]
  ------------------
  129|      2|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
  130|      2|                 << "Expected operands to have the same dimension "
  131|      2|                 << "as Result Type: " << spvOpcodeString(opcode)
  132|      2|                 << " operand index " << operand_index;
  133|       |
  134|  3.02k|        if (_.GetBitWidth(type_id) != result_bit_width)
  ------------------
  |  Branch (134:13): [True: 0, False: 3.02k]
  ------------------
  135|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
  136|      0|                 << "Expected operands to have the same bit width "
  137|      0|                 << "as Result Type: " << spvOpcodeString(opcode)
  138|      0|                 << " operand index " << operand_index;
  139|  3.02k|      }
  140|  1.71k|      break;
  141|  1.71k|    }
  142|       |
  143|  1.71k|    case spv::Op::OpBitFieldInsert: {
  ------------------
  |  Branch (143:5): [True: 128, False: 285k]
  ------------------
  144|    128|      const uint32_t base_type = _.GetOperandTypeId(inst, 2);
  145|    128|      const uint32_t insert_type = _.GetOperandTypeId(inst, 3);
  146|    128|      const uint32_t offset_type = _.GetOperandTypeId(inst, 4);
  147|    128|      const uint32_t count_type = _.GetOperandTypeId(inst, 5);
  148|       |
  149|    128|      if (spv_result_t error = ValidateBaseType(_, inst, base_type)) {
  ------------------
  |  Branch (149:24): [True: 1, False: 127]
  ------------------
  150|      1|        return error;
  151|      1|      }
  152|       |
  153|    127|      if (insert_type != result_type)
  ------------------
  |  Branch (153:11): [True: 1, False: 126]
  ------------------
  154|      1|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
  155|      1|               << "Expected Insert Type to be equal to Result Type: "
  156|      1|               << spvOpcodeString(opcode);
  157|       |
  158|    126|      if (!offset_type || !_.IsIntScalarType(offset_type))
  ------------------
  |  Branch (158:11): [True: 0, False: 126]
  |  Branch (158:27): [True: 0, False: 126]
  ------------------
  159|      0|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
  160|      0|               << "Expected Offset Type to be int scalar: "
  161|      0|               << spvOpcodeString(opcode);
  162|       |
  163|    126|      if (!count_type || !_.IsIntScalarType(count_type))
  ------------------
  |  Branch (163:11): [True: 0, False: 126]
  |  Branch (163:26): [True: 1, False: 125]
  ------------------
  164|      1|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
  165|      1|               << "Expected Count Type to be int scalar: "
  166|      1|               << spvOpcodeString(opcode);
  167|    125|      break;
  168|    126|    }
  169|       |
  170|    125|    case spv::Op::OpBitFieldSExtract:
  ------------------
  |  Branch (170:5): [True: 77, False: 285k]
  ------------------
  171|     80|    case spv::Op::OpBitFieldUExtract: {
  ------------------
  |  Branch (171:5): [True: 3, False: 285k]
  ------------------
  172|     80|      const uint32_t base_type = _.GetOperandTypeId(inst, 2);
  173|     80|      const uint32_t offset_type = _.GetOperandTypeId(inst, 3);
  174|     80|      const uint32_t count_type = _.GetOperandTypeId(inst, 4);
  175|       |
  176|     80|      if (spv_result_t error = ValidateBaseType(_, inst, base_type)) {
  ------------------
  |  Branch (176:24): [True: 2, False: 78]
  ------------------
  177|      2|        return error;
  178|      2|      }
  179|       |
  180|     78|      if (!offset_type || !_.IsIntScalarType(offset_type))
  ------------------
  |  Branch (180:11): [True: 0, False: 78]
  |  Branch (180:27): [True: 0, False: 78]
  ------------------
  181|      0|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
  182|      0|               << "Expected Offset Type to be int scalar: "
  183|      0|               << spvOpcodeString(opcode);
  184|       |
  185|     78|      if (!count_type || !_.IsIntScalarType(count_type))
  ------------------
  |  Branch (185:11): [True: 0, False: 78]
  |  Branch (185:26): [True: 1, False: 77]
  ------------------
  186|      1|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
  187|      1|               << "Expected Count Type to be int scalar: "
  188|      1|               << spvOpcodeString(opcode);
  189|     77|      break;
  190|     78|    }
  191|       |
  192|     77|    case spv::Op::OpBitReverse: {
  ------------------
  |  Branch (192:5): [True: 54, False: 285k]
  ------------------
  193|     54|      const uint32_t base_type = _.GetOperandTypeId(inst, 2);
  194|       |
  195|     54|      if (spv_result_t error = ValidateBaseType(_, inst, base_type)) {
  ------------------
  |  Branch (195:24): [True: 1, False: 53]
  ------------------
  196|      1|        return error;
  197|      1|      }
  198|       |
  199|     53|      break;
  200|     54|    }
  201|       |
  202|     87|    case spv::Op::OpBitCount: {
  ------------------
  |  Branch (202:5): [True: 87, False: 285k]
  ------------------
  203|     87|      if (!_.IsIntScalarType(result_type) && !_.IsIntVectorType(result_type))
  ------------------
  |  Branch (203:11): [True: 1, False: 86]
  |  Branch (203:46): [True: 1, False: 0]
  ------------------
  204|      1|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
  205|      1|               << "Expected int scalar or vector type as Result Type: "
  206|      1|               << spvOpcodeString(opcode);
  207|       |
  208|     86|      const uint32_t base_type = _.GetOperandTypeId(inst, 2);
  209|       |
  210|     86|      if (spv_result_t error = ValidateBaseType(_, inst, base_type)) {
  ------------------
  |  Branch (210:24): [True: 2, False: 84]
  ------------------
  211|      2|        return error;
  212|      2|      }
  213|       |
  214|     84|      const uint32_t base_dimension = _.GetDimension(base_type);
  215|     84|      const uint32_t result_dimension = _.GetDimension(result_type);
  216|       |
  217|     84|      if (base_dimension != result_dimension)
  ------------------
  |  Branch (217:11): [True: 0, False: 84]
  ------------------
  218|      0|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
  219|      0|               << "Expected Base dimension to be equal to Result Type "
  220|      0|                  "dimension: "
  221|      0|               << spvOpcodeString(opcode);
  222|     84|      break;
  223|     84|    }
  224|       |
  225|   283k|    default:
  ------------------
  |  Branch (225:5): [True: 283k, False: 2.12k]
  ------------------
  226|   283k|      break;
  227|   285k|  }
  228|       |
  229|   285k|  return SPV_SUCCESS;
  230|   285k|}

_ZN8spvtools3val16ValidateBuiltInsERNS0_17ValidationState_tE:
 4383|    633|spv_result_t ValidateBuiltIns(ValidationState_t& _) {
 4384|    633|  BuiltInsValidator validator(_);
 4385|    633|  return validator.Run();
 4386|    633|}
validate_builtins.cpp:_ZN8spvtools3val12_GLOBAL__N_117BuiltInsValidatorC2ERNS0_17ValidationState_tE:
  250|    633|  BuiltInsValidator(ValidationState_t& vstate) : _(vstate) {}
validate_builtins.cpp:_ZN8spvtools3val12_GLOBAL__N_117BuiltInsValidator3RunEv:
 4327|    633|spv_result_t BuiltInsValidator::Run() {
 4328|       |  // First pass: validate all built-ins at definition and seed
 4329|       |  // id_to_at_reference_checks_ with built-ins.
 4330|    633|  if (auto error = ValidateBuiltInsAtDefinition()) {
  ------------------
  |  Branch (4330:12): [True: 0, False: 633]
  ------------------
 4331|      0|    return error;
 4332|      0|  }
 4333|       |
 4334|    633|  if (id_to_at_reference_checks_.empty()) {
  ------------------
  |  Branch (4334:7): [True: 633, False: 0]
  ------------------
 4335|       |    // No validation tasks were seeded. Nothing else to do.
 4336|    633|    return SPV_SUCCESS;
 4337|    633|  }
 4338|       |
 4339|       |  // Second pass: validate every id reference in the module using
 4340|       |  // rules in id_to_at_reference_checks_.
 4341|      0|  for (const Instruction& inst : _.ordered_instructions()) {
  ------------------
  |  Branch (4341:32): [True: 0, False: 0]
  ------------------
 4342|      0|    Update(inst);
 4343|       |
 4344|      0|    std::set<uint32_t> already_checked;
 4345|       |
 4346|      0|    for (const auto& operand : inst.operands()) {
  ------------------
  |  Branch (4346:30): [True: 0, False: 0]
  ------------------
 4347|      0|      if (!spvIsIdType(operand.type)) {
  ------------------
  |  Branch (4347:11): [True: 0, False: 0]
  ------------------
 4348|       |        // Not id.
 4349|      0|        continue;
 4350|      0|      }
 4351|       |
 4352|      0|      const uint32_t id = inst.word(operand.offset);
 4353|      0|      if (id == inst.id()) {
  ------------------
  |  Branch (4353:11): [True: 0, False: 0]
  ------------------
 4354|       |        // No need to check result id.
 4355|      0|        continue;
 4356|      0|      }
 4357|       |
 4358|      0|      if (!already_checked.insert(id).second) {
  ------------------
  |  Branch (4358:11): [True: 0, False: 0]
  ------------------
 4359|       |        // The instruction has already referenced this id.
 4360|      0|        continue;
 4361|      0|      }
 4362|       |
 4363|       |      // Instruction references the id. Run all checks associated with the id
 4364|       |      // on the instruction. id_to_at_reference_checks_ can be modified in the
 4365|       |      // process, iterators are safe because it's a tree-based map.
 4366|      0|      const auto it = id_to_at_reference_checks_.find(id);
 4367|      0|      if (it != id_to_at_reference_checks_.end()) {
  ------------------
  |  Branch (4367:11): [True: 0, False: 0]
  ------------------
 4368|      0|        for (const auto& check : it->second) {
  ------------------
  |  Branch (4368:32): [True: 0, False: 0]
  ------------------
 4369|      0|          if (spv_result_t error = check(inst)) {
  ------------------
  |  Branch (4369:28): [True: 0, False: 0]
  ------------------
 4370|      0|            return error;
 4371|      0|          }
 4372|      0|        }
 4373|      0|      }
 4374|      0|    }
 4375|      0|  }
 4376|       |
 4377|      0|  return SPV_SUCCESS;
 4378|      0|}
validate_builtins.cpp:_ZN8spvtools3val12_GLOBAL__N_117BuiltInsValidator28ValidateBuiltInsAtDefinitionEv:
 4301|    633|spv_result_t BuiltInsValidator::ValidateBuiltInsAtDefinition() {
 4302|  4.94k|  for (const auto& kv : _.id_decorations()) {
  ------------------
  |  Branch (4302:23): [True: 4.94k, False: 633]
  ------------------
 4303|  4.94k|    const uint32_t id = kv.first;
 4304|  4.94k|    const auto& decorations = kv.second;
 4305|  4.94k|    if (decorations.empty()) {
  ------------------
  |  Branch (4305:9): [True: 2.58k, False: 2.35k]
  ------------------
 4306|  2.58k|      continue;
 4307|  2.58k|    }
 4308|       |
 4309|  2.35k|    const Instruction* inst = _.FindDef(id);
 4310|  2.35k|    assert(inst);
 4311|       |
 4312|  2.89k|    for (const auto& decoration : kv.second) {
  ------------------
  |  Branch (4312:33): [True: 2.89k, False: 2.35k]
  ------------------
 4313|  2.89k|      if (decoration.dec_type() != spv::Decoration::BuiltIn) {
  ------------------
  |  Branch (4313:11): [True: 2.81k, False: 80]
  ------------------
 4314|  2.81k|        continue;
 4315|  2.81k|      }
 4316|       |
 4317|     80|      if (spv_result_t error =
  ------------------
  |  Branch (4317:24): [True: 0, False: 80]
  ------------------
 4318|     80|              ValidateSingleBuiltInAtDefinition(decoration, *inst)) {
 4319|      0|        return error;
 4320|      0|      }
 4321|     80|    }
 4322|  2.35k|  }
 4323|       |
 4324|    633|  return SPV_SUCCESS;
 4325|    633|}
validate_builtins.cpp:_ZN8spvtools3val12_GLOBAL__N_117BuiltInsValidator33ValidateSingleBuiltInAtDefinitionERKNS0_10DecorationERKNS0_11InstructionE:
 4114|     80|    const Decoration& decoration, const Instruction& inst) {
 4115|     80|  const spv::BuiltIn label = spv::BuiltIn(decoration.params()[0]);
 4116|       |
 4117|     80|  if (!spvIsVulkanEnv(_.context()->target_env)) {
  ------------------
  |  Branch (4117:7): [True: 80, False: 0]
  ------------------
 4118|       |    // Early return. All currently implemented rules are based on Vulkan spec.
 4119|       |    //
 4120|       |    // TODO: If you are adding validation rules for environments other than
 4121|       |    // Vulkan (or general rules which are not environment independent), then
 4122|       |    // you need to modify or remove this condition. Consider also adding early
 4123|       |    // returns into BuiltIn-specific rules, so that the system doesn't spawn new
 4124|       |    // rules which don't do anything.
 4125|     80|    return SPV_SUCCESS;
 4126|     80|  }
 4127|       |
 4128|       |  // If you are adding a new BuiltIn enum, please register it here.
 4129|       |  // If the newly added enum has validation rules associated with it
 4130|       |  // consider leaving a TODO and/or creating an issue.
 4131|      0|  switch (label) {
 4132|      0|    case spv::BuiltIn::ClipDistance:
  ------------------
  |  Branch (4132:5): [True: 0, False: 0]
  ------------------
 4133|      0|    case spv::BuiltIn::CullDistance: {
  ------------------
  |  Branch (4133:5): [True: 0, False: 0]
  ------------------
 4134|      0|      return ValidateClipOrCullDistanceAtDefinition(decoration, inst);
 4135|      0|    }
 4136|      0|    case spv::BuiltIn::FragCoord: {
  ------------------
  |  Branch (4136:5): [True: 0, False: 0]
  ------------------
 4137|      0|      return ValidateFragCoordAtDefinition(decoration, inst);
 4138|      0|    }
 4139|      0|    case spv::BuiltIn::FragDepth: {
  ------------------
  |  Branch (4139:5): [True: 0, False: 0]
  ------------------
 4140|      0|      return ValidateFragDepthAtDefinition(decoration, inst);
 4141|      0|    }
 4142|      0|    case spv::BuiltIn::FrontFacing: {
  ------------------
  |  Branch (4142:5): [True: 0, False: 0]
  ------------------
 4143|      0|      return ValidateFrontFacingAtDefinition(decoration, inst);
 4144|      0|    }
 4145|      0|    case spv::BuiltIn::GlobalInvocationId:
  ------------------
  |  Branch (4145:5): [True: 0, False: 0]
  ------------------
 4146|      0|    case spv::BuiltIn::LocalInvocationId:
  ------------------
  |  Branch (4146:5): [True: 0, False: 0]
  ------------------
 4147|      0|    case spv::BuiltIn::NumWorkgroups:
  ------------------
  |  Branch (4147:5): [True: 0, False: 0]
  ------------------
 4148|      0|    case spv::BuiltIn::WorkgroupId: {
  ------------------
  |  Branch (4148:5): [True: 0, False: 0]
  ------------------
 4149|      0|      return ValidateComputeShaderI32Vec3InputAtDefinition(decoration, inst);
 4150|      0|    }
 4151|      0|    case spv::BuiltIn::BaryCoordKHR:
  ------------------
  |  Branch (4151:5): [True: 0, False: 0]
  ------------------
 4152|      0|    case spv::BuiltIn::BaryCoordNoPerspKHR: {
  ------------------
  |  Branch (4152:5): [True: 0, False: 0]
  ------------------
 4153|      0|      return ValidateFragmentShaderF32Vec3InputAtDefinition(decoration, inst);
 4154|      0|    }
 4155|      0|    case spv::BuiltIn::HelperInvocation: {
  ------------------
  |  Branch (4155:5): [True: 0, False: 0]
  ------------------
 4156|      0|      return ValidateHelperInvocationAtDefinition(decoration, inst);
 4157|      0|    }
 4158|      0|    case spv::BuiltIn::InvocationId: {
  ------------------
  |  Branch (4158:5): [True: 0, False: 0]
  ------------------
 4159|      0|      return ValidateInvocationIdAtDefinition(decoration, inst);
 4160|      0|    }
 4161|      0|    case spv::BuiltIn::InstanceIndex: {
  ------------------
  |  Branch (4161:5): [True: 0, False: 0]
  ------------------
 4162|      0|      return ValidateInstanceIndexAtDefinition(decoration, inst);
 4163|      0|    }
 4164|      0|    case spv::BuiltIn::Layer:
  ------------------
  |  Branch (4164:5): [True: 0, False: 0]
  ------------------
 4165|      0|    case spv::BuiltIn::ViewportIndex: {
  ------------------
  |  Branch (4165:5): [True: 0, False: 0]
  ------------------
 4166|      0|      return ValidateLayerOrViewportIndexAtDefinition(decoration, inst);
 4167|      0|    }
 4168|      0|    case spv::BuiltIn::PatchVertices: {
  ------------------
  |  Branch (4168:5): [True: 0, False: 0]
  ------------------
 4169|      0|      return ValidatePatchVerticesAtDefinition(decoration, inst);
 4170|      0|    }
 4171|      0|    case spv::BuiltIn::PointCoord: {
  ------------------
  |  Branch (4171:5): [True: 0, False: 0]
  ------------------
 4172|      0|      return ValidatePointCoordAtDefinition(decoration, inst);
 4173|      0|    }
 4174|      0|    case spv::BuiltIn::PointSize: {
  ------------------
  |  Branch (4174:5): [True: 0, False: 0]
  ------------------
 4175|      0|      return ValidatePointSizeAtDefinition(decoration, inst);
 4176|      0|    }
 4177|      0|    case spv::BuiltIn::Position: {
  ------------------
  |  Branch (4177:5): [True: 0, False: 0]
  ------------------
 4178|      0|      return ValidatePositionAtDefinition(decoration, inst);
 4179|      0|    }
 4180|      0|    case spv::BuiltIn::PrimitiveId: {
  ------------------
  |  Branch (4180:5): [True: 0, False: 0]
  ------------------
 4181|      0|      return ValidatePrimitiveIdAtDefinition(decoration, inst);
 4182|      0|    }
 4183|      0|    case spv::BuiltIn::SampleId: {
  ------------------
  |  Branch (4183:5): [True: 0, False: 0]
  ------------------
 4184|      0|      return ValidateSampleIdAtDefinition(decoration, inst);
 4185|      0|    }
 4186|      0|    case spv::BuiltIn::SampleMask: {
  ------------------
  |  Branch (4186:5): [True: 0, False: 0]
  ------------------
 4187|      0|      return ValidateSampleMaskAtDefinition(decoration, inst);
 4188|      0|    }
 4189|      0|    case spv::BuiltIn::SamplePosition: {
  ------------------
  |  Branch (4189:5): [True: 0, False: 0]
  ------------------
 4190|      0|      return ValidateSamplePositionAtDefinition(decoration, inst);
 4191|      0|    }
 4192|      0|    case spv::BuiltIn::SubgroupId:
  ------------------
  |  Branch (4192:5): [True: 0, False: 0]
  ------------------
 4193|      0|    case spv::BuiltIn::NumSubgroups: {
  ------------------
  |  Branch (4193:5): [True: 0, False: 0]
  ------------------
 4194|      0|      return ValidateComputeI32InputAtDefinition(decoration, inst);
 4195|      0|    }
 4196|      0|    case spv::BuiltIn::SubgroupLocalInvocationId:
  ------------------
  |  Branch (4196:5): [True: 0, False: 0]
  ------------------
 4197|      0|    case spv::BuiltIn::SubgroupSize: {
  ------------------
  |  Branch (4197:5): [True: 0, False: 0]
  ------------------
 4198|      0|      return ValidateI32InputAtDefinition(decoration, inst);
 4199|      0|    }
 4200|      0|    case spv::BuiltIn::SubgroupEqMask:
  ------------------
  |  Branch (4200:5): [True: 0, False: 0]
  ------------------
 4201|      0|    case spv::BuiltIn::SubgroupGeMask:
  ------------------
  |  Branch (4201:5): [True: 0, False: 0]
  ------------------
 4202|      0|    case spv::BuiltIn::SubgroupGtMask:
  ------------------
  |  Branch (4202:5): [True: 0, False: 0]
  ------------------
 4203|      0|    case spv::BuiltIn::SubgroupLeMask:
  ------------------
  |  Branch (4203:5): [True: 0, False: 0]
  ------------------
 4204|      0|    case spv::BuiltIn::SubgroupLtMask: {
  ------------------
  |  Branch (4204:5): [True: 0, False: 0]
  ------------------
 4205|      0|      return ValidateI32Vec4InputAtDefinition(decoration, inst);
 4206|      0|    }
 4207|      0|    case spv::BuiltIn::TessCoord: {
  ------------------
  |  Branch (4207:5): [True: 0, False: 0]
  ------------------
 4208|      0|      return ValidateTessCoordAtDefinition(decoration, inst);
 4209|      0|    }
 4210|      0|    case spv::BuiltIn::TessLevelOuter: {
  ------------------
  |  Branch (4210:5): [True: 0, False: 0]
  ------------------
 4211|      0|      return ValidateTessLevelOuterAtDefinition(decoration, inst);
 4212|      0|    }
 4213|      0|    case spv::BuiltIn::TessLevelInner: {
  ------------------
  |  Branch (4213:5): [True: 0, False: 0]
  ------------------
 4214|      0|      return ValidateTessLevelInnerAtDefinition(decoration, inst);
 4215|      0|    }
 4216|      0|    case spv::BuiltIn::VertexIndex: {
  ------------------
  |  Branch (4216:5): [True: 0, False: 0]
  ------------------
 4217|      0|      return ValidateVertexIndexAtDefinition(decoration, inst);
 4218|      0|    }
 4219|      0|    case spv::BuiltIn::WorkgroupSize: {
  ------------------
  |  Branch (4219:5): [True: 0, False: 0]
  ------------------
 4220|      0|      return ValidateWorkgroupSizeAtDefinition(decoration, inst);
 4221|      0|    }
 4222|      0|    case spv::BuiltIn::VertexId: {
  ------------------
  |  Branch (4222:5): [True: 0, False: 0]
  ------------------
 4223|      0|      return ValidateVertexIdAtDefinition(decoration, inst);
 4224|      0|    }
 4225|      0|    case spv::BuiltIn::LocalInvocationIndex: {
  ------------------
  |  Branch (4225:5): [True: 0, False: 0]
  ------------------
 4226|      0|      return ValidateLocalInvocationIndexAtDefinition(decoration, inst);
 4227|      0|    }
 4228|      0|    case spv::BuiltIn::CoreIDARM:
  ------------------
  |  Branch (4228:5): [True: 0, False: 0]
  ------------------
 4229|      0|    case spv::BuiltIn::CoreCountARM:
  ------------------
  |  Branch (4229:5): [True: 0, False: 0]
  ------------------
 4230|      0|    case spv::BuiltIn::CoreMaxIDARM:
  ------------------
  |  Branch (4230:5): [True: 0, False: 0]
  ------------------
 4231|      0|    case spv::BuiltIn::WarpIDARM:
  ------------------
  |  Branch (4231:5): [True: 0, False: 0]
  ------------------
 4232|      0|    case spv::BuiltIn::WarpMaxIDARM:
  ------------------
  |  Branch (4232:5): [True: 0, False: 0]
  ------------------
 4233|      0|    case spv::BuiltIn::WarpsPerSMNV:
  ------------------
  |  Branch (4233:5): [True: 0, False: 0]
  ------------------
 4234|      0|    case spv::BuiltIn::SMCountNV:
  ------------------
  |  Branch (4234:5): [True: 0, False: 0]
  ------------------
 4235|      0|    case spv::BuiltIn::WarpIDNV:
  ------------------
  |  Branch (4235:5): [True: 0, False: 0]
  ------------------
 4236|      0|    case spv::BuiltIn::SMIDNV: {
  ------------------
  |  Branch (4236:5): [True: 0, False: 0]
  ------------------
 4237|      0|      return ValidateNVSMOrARMCoreBuiltinsAtDefinition(decoration, inst);
 4238|      0|    }
 4239|      0|    case spv::BuiltIn::BaseInstance:
  ------------------
  |  Branch (4239:5): [True: 0, False: 0]
  ------------------
 4240|      0|    case spv::BuiltIn::BaseVertex: {
  ------------------
  |  Branch (4240:5): [True: 0, False: 0]
  ------------------
 4241|      0|      return ValidateBaseInstanceOrVertexAtDefinition(decoration, inst);
 4242|      0|    }
 4243|      0|    case spv::BuiltIn::DrawIndex: {
  ------------------
  |  Branch (4243:5): [True: 0, False: 0]
  ------------------
 4244|      0|      return ValidateDrawIndexAtDefinition(decoration, inst);
 4245|      0|    }
 4246|      0|    case spv::BuiltIn::ViewIndex: {
  ------------------
  |  Branch (4246:5): [True: 0, False: 0]
  ------------------
 4247|      0|      return ValidateViewIndexAtDefinition(decoration, inst);
 4248|      0|    }
 4249|      0|    case spv::BuiltIn::DeviceIndex: {
  ------------------
  |  Branch (4249:5): [True: 0, False: 0]
  ------------------
 4250|      0|      return ValidateDeviceIndexAtDefinition(decoration, inst);
 4251|      0|    }
 4252|      0|    case spv::BuiltIn::FragInvocationCountEXT: {
  ------------------
  |  Branch (4252:5): [True: 0, False: 0]
  ------------------
 4253|       |      // alias spv::BuiltIn::InvocationsPerPixelNV
 4254|      0|      return ValidateFragInvocationCountAtDefinition(decoration, inst);
 4255|      0|    }
 4256|      0|    case spv::BuiltIn::FragSizeEXT: {
  ------------------
  |  Branch (4256:5): [True: 0, False: 0]
  ------------------
 4257|       |      // alias spv::BuiltIn::FragmentSizeNV
 4258|      0|      return ValidateFragSizeAtDefinition(decoration, inst);
 4259|      0|    }
 4260|      0|    case spv::BuiltIn::FragStencilRefEXT: {
  ------------------
  |  Branch (4260:5): [True: 0, False: 0]
  ------------------
 4261|      0|      return ValidateFragStencilRefAtDefinition(decoration, inst);
 4262|      0|    }
 4263|      0|    case spv::BuiltIn::FullyCoveredEXT:{
  ------------------
  |  Branch (4263:5): [True: 0, False: 0]
  ------------------
 4264|      0|      return ValidateFullyCoveredAtDefinition(decoration, inst);
 4265|      0|    }
 4266|       |    // Ray tracing builtins
 4267|      0|    case spv::BuiltIn::HitKindKHR:  // alias spv::BuiltIn::HitKindNV
  ------------------
  |  Branch (4267:5): [True: 0, False: 0]
  ------------------
 4268|      0|    case spv::BuiltIn::HitTNV:      // NOT present in KHR
  ------------------
  |  Branch (4268:5): [True: 0, False: 0]
  ------------------
 4269|      0|    case spv::BuiltIn::InstanceId:
  ------------------
  |  Branch (4269:5): [True: 0, False: 0]
  ------------------
 4270|      0|    case spv::BuiltIn::LaunchIdKHR:           // alias spv::BuiltIn::LaunchIdNV
  ------------------
  |  Branch (4270:5): [True: 0, False: 0]
  ------------------
 4271|      0|    case spv::BuiltIn::LaunchSizeKHR:         // alias spv::BuiltIn::LaunchSizeNV
  ------------------
  |  Branch (4271:5): [True: 0, False: 0]
  ------------------
 4272|      0|    case spv::BuiltIn::WorldRayOriginKHR:     // alias spv::BuiltIn::WorldRayOriginNV
  ------------------
  |  Branch (4272:5): [True: 0, False: 0]
  ------------------
 4273|      0|    case spv::BuiltIn::WorldRayDirectionKHR:  // alias spv::BuiltIn::WorldRayDirectionNV
  ------------------
  |  Branch (4273:5): [True: 0, False: 0]
  ------------------
 4274|      0|    case spv::BuiltIn::ObjectRayOriginKHR:    // alias spv::BuiltIn::ObjectRayOriginNV
  ------------------
  |  Branch (4274:5): [True: 0, False: 0]
  ------------------
 4275|      0|    case spv::BuiltIn::ObjectRayDirectionKHR:   // alias
  ------------------
  |  Branch (4275:5): [True: 0, False: 0]
  ------------------
 4276|       |                                            // spv::BuiltIn::ObjectRayDirectionNV
 4277|      0|    case spv::BuiltIn::RayTminKHR:              // alias spv::BuiltIn::RayTminNV
  ------------------
  |  Branch (4277:5): [True: 0, False: 0]
  ------------------
 4278|      0|    case spv::BuiltIn::RayTmaxKHR:              // alias spv::BuiltIn::RayTmaxNV
  ------------------
  |  Branch (4278:5): [True: 0, False: 0]
  ------------------
 4279|      0|    case spv::BuiltIn::InstanceCustomIndexKHR:  // alias
  ------------------
  |  Branch (4279:5): [True: 0, False: 0]
  ------------------
 4280|       |                                            // spv::BuiltIn::InstanceCustomIndexNV
 4281|      0|    case spv::BuiltIn::ObjectToWorldKHR:        // alias spv::BuiltIn::ObjectToWorldNV
  ------------------
  |  Branch (4281:5): [True: 0, False: 0]
  ------------------
 4282|      0|    case spv::BuiltIn::WorldToObjectKHR:        // alias spv::BuiltIn::WorldToObjectNV
  ------------------
  |  Branch (4282:5): [True: 0, False: 0]
  ------------------
 4283|      0|    case spv::BuiltIn::IncomingRayFlagsKHR:    // alias spv::BuiltIn::IncomingRayFlagsNV
  ------------------
  |  Branch (4283:5): [True: 0, False: 0]
  ------------------
 4284|      0|    case spv::BuiltIn::RayGeometryIndexKHR:    // NOT present in NV
  ------------------
  |  Branch (4284:5): [True: 0, False: 0]
  ------------------
 4285|      0|    case spv::BuiltIn::CullMaskKHR: {
  ------------------
  |  Branch (4285:5): [True: 0, False: 0]
  ------------------
 4286|      0|      return ValidateRayTracingBuiltinsAtDefinition(decoration, inst);
 4287|      0|    }
 4288|      0|    case spv::BuiltIn::PrimitiveShadingRateKHR: {
  ------------------
  |  Branch (4288:5): [True: 0, False: 0]
  ------------------
 4289|      0|      return ValidatePrimitiveShadingRateAtDefinition(decoration, inst);
 4290|      0|    }
 4291|      0|    case spv::BuiltIn::ShadingRateKHR: {
  ------------------
  |  Branch (4291:5): [True: 0, False: 0]
  ------------------
 4292|      0|      return ValidateShadingRateAtDefinition(decoration, inst);
 4293|      0|    }
 4294|      0|    default:
  ------------------
  |  Branch (4294:5): [True: 0, False: 0]
  ------------------
 4295|       |      // No validation rules (for the moment).
 4296|      0|      break;
 4297|      0|  }
 4298|      0|  return SPV_SUCCESS;
 4299|      0|}

_ZN8spvtools3val14CapabilityPassERNS0_17ValidationState_tEPKNS0_11InstructionE:
  291|   388k|spv_result_t CapabilityPass(ValidationState_t& _, const Instruction* inst) {
  292|   388k|  if (inst->opcode() != spv::Op::OpCapability) return SPV_SUCCESS;
  ------------------
  |  Branch (292:7): [True: 381k, False: 7.02k]
  ------------------
  293|       |
  294|  7.02k|  assert(inst->operands().size() == 1);
  295|       |
  296|      0|  const spv_parsed_operand_t& operand = inst->operand(0);
  297|       |
  298|  7.02k|  assert(operand.num_words == 1);
  299|      0|  assert(operand.offset < inst->words().size());
  300|       |
  301|      0|  const uint32_t capability = inst->word(operand.offset);
  302|  7.02k|  const auto capability_str = [&_, capability]() {
  303|  7.02k|    spv_operand_desc desc = nullptr;
  304|  7.02k|    if (_.grammar().lookupOperand(SPV_OPERAND_TYPE_CAPABILITY, capability,
  305|  7.02k|                                  &desc) != SPV_SUCCESS ||
  306|  7.02k|        !desc) {
  307|  7.02k|      return std::string("Unknown");
  308|  7.02k|    }
  309|  7.02k|    return std::string(desc->name);
  310|  7.02k|  };
  311|       |
  312|  7.02k|  const auto env = _.context()->target_env;
  313|  7.02k|  const bool opencl_embedded = env == SPV_ENV_OPENCL_EMBEDDED_1_2 ||
  ------------------
  |  Branch (313:32): [True: 0, False: 7.02k]
  ------------------
  314|  7.02k|                               env == SPV_ENV_OPENCL_EMBEDDED_2_0 ||
  ------------------
  |  Branch (314:32): [True: 0, False: 7.02k]
  ------------------
  315|  7.02k|                               env == SPV_ENV_OPENCL_EMBEDDED_2_1 ||
  ------------------
  |  Branch (315:32): [True: 0, False: 7.02k]
  ------------------
  316|  7.02k|                               env == SPV_ENV_OPENCL_EMBEDDED_2_2;
  ------------------
  |  Branch (316:32): [True: 0, False: 7.02k]
  ------------------
  317|  7.02k|  const std::string opencl_profile = opencl_embedded ? "Embedded" : "Full";
  ------------------
  |  Branch (317:38): [True: 0, False: 7.02k]
  ------------------
  318|  7.02k|  if (env == SPV_ENV_VULKAN_1_0) {
  ------------------
  |  Branch (318:7): [True: 0, False: 7.02k]
  ------------------
  319|      0|    if (!IsSupportGuaranteedVulkan_1_0(capability) &&
  ------------------
  |  Branch (319:9): [True: 0, False: 0]
  ------------------
  320|      0|        !IsSupportOptionalVulkan_1_0(capability) &&
  ------------------
  |  Branch (320:9): [True: 0, False: 0]
  ------------------
  321|      0|        !IsEnabledByExtension(_, capability)) {
  ------------------
  |  Branch (321:9): [True: 0, False: 0]
  ------------------
  322|      0|      return _.diag(SPV_ERROR_INVALID_CAPABILITY, inst)
  323|      0|             << "Capability " << capability_str()
  324|      0|             << " is not allowed by Vulkan 1.0 specification"
  325|      0|             << " (or requires extension)";
  326|      0|    }
  327|  7.02k|  } else if (env == SPV_ENV_VULKAN_1_1) {
  ------------------
  |  Branch (327:14): [True: 0, False: 7.02k]
  ------------------
  328|      0|    if (!IsSupportGuaranteedVulkan_1_1(capability) &&
  ------------------
  |  Branch (328:9): [True: 0, False: 0]
  ------------------
  329|      0|        !IsSupportOptionalVulkan_1_1(capability) &&
  ------------------
  |  Branch (329:9): [True: 0, False: 0]
  ------------------
  330|      0|        !IsEnabledByExtension(_, capability)) {
  ------------------
  |  Branch (330:9): [True: 0, False: 0]
  ------------------
  331|      0|      return _.diag(SPV_ERROR_INVALID_CAPABILITY, inst)
  332|      0|             << "Capability " << capability_str()
  333|      0|             << " is not allowed by Vulkan 1.1 specification"
  334|      0|             << " (or requires extension)";
  335|      0|    }
  336|  7.02k|  } else if (env == SPV_ENV_VULKAN_1_2) {
  ------------------
  |  Branch (336:14): [True: 0, False: 7.02k]
  ------------------
  337|      0|    if (!IsSupportGuaranteedVulkan_1_2(capability) &&
  ------------------
  |  Branch (337:9): [True: 0, False: 0]
  ------------------
  338|      0|        !IsSupportOptionalVulkan_1_2(capability) &&
  ------------------
  |  Branch (338:9): [True: 0, False: 0]
  ------------------
  339|      0|        !IsEnabledByExtension(_, capability)) {
  ------------------
  |  Branch (339:9): [True: 0, False: 0]
  ------------------
  340|      0|      return _.diag(SPV_ERROR_INVALID_CAPABILITY, inst)
  341|      0|             << "Capability " << capability_str()
  342|      0|             << " is not allowed by Vulkan 1.2 specification"
  343|      0|             << " (or requires extension)";
  344|      0|    }
  345|  7.02k|  } else if (env == SPV_ENV_OPENCL_1_2 || env == SPV_ENV_OPENCL_EMBEDDED_1_2) {
  ------------------
  |  Branch (345:14): [True: 0, False: 7.02k]
  |  Branch (345:43): [True: 0, False: 7.02k]
  ------------------
  346|      0|    if (!IsSupportGuaranteedOpenCL_1_2(capability, opencl_embedded) &&
  ------------------
  |  Branch (346:9): [True: 0, False: 0]
  ------------------
  347|      0|        !IsSupportOptionalOpenCL_1_2(capability) &&
  ------------------
  |  Branch (347:9): [True: 0, False: 0]
  ------------------
  348|      0|        !IsEnabledByExtension(_, capability) &&
  ------------------
  |  Branch (348:9): [True: 0, False: 0]
  ------------------
  349|      0|        !IsEnabledByCapabilityOpenCL_1_2(_, capability)) {
  ------------------
  |  Branch (349:9): [True: 0, False: 0]
  ------------------
  350|      0|      return _.diag(SPV_ERROR_INVALID_CAPABILITY, inst)
  351|      0|             << "Capability " << capability_str()
  352|      0|             << " is not allowed by OpenCL 1.2 " << opencl_profile
  353|      0|             << " Profile specification"
  354|      0|             << " (or requires extension or capability)";
  355|      0|    }
  356|  7.02k|  } else if (env == SPV_ENV_OPENCL_2_0 || env == SPV_ENV_OPENCL_EMBEDDED_2_0 ||
  ------------------
  |  Branch (356:14): [True: 0, False: 7.02k]
  |  Branch (356:43): [True: 0, False: 7.02k]
  ------------------
  357|  7.02k|             env == SPV_ENV_OPENCL_2_1 || env == SPV_ENV_OPENCL_EMBEDDED_2_1) {
  ------------------
  |  Branch (357:14): [True: 0, False: 7.02k]
  |  Branch (357:43): [True: 0, False: 7.02k]
  ------------------
  358|      0|    if (!IsSupportGuaranteedOpenCL_2_0(capability, opencl_embedded) &&
  ------------------
  |  Branch (358:9): [True: 0, False: 0]
  ------------------
  359|      0|        !IsSupportOptionalOpenCL_1_2(capability) &&
  ------------------
  |  Branch (359:9): [True: 0, False: 0]
  ------------------
  360|      0|        !IsEnabledByExtension(_, capability) &&
  ------------------
  |  Branch (360:9): [True: 0, False: 0]
  ------------------
  361|      0|        !IsEnabledByCapabilityOpenCL_2_0(_, capability)) {
  ------------------
  |  Branch (361:9): [True: 0, False: 0]
  ------------------
  362|      0|      return _.diag(SPV_ERROR_INVALID_CAPABILITY, inst)
  363|      0|             << "Capability " << capability_str()
  364|      0|             << " is not allowed by OpenCL 2.0/2.1 " << opencl_profile
  365|      0|             << " Profile specification"
  366|      0|             << " (or requires extension or capability)";
  367|      0|    }
  368|  7.02k|  } else if (env == SPV_ENV_OPENCL_2_2 || env == SPV_ENV_OPENCL_EMBEDDED_2_2) {
  ------------------
  |  Branch (368:14): [True: 0, False: 7.02k]
  |  Branch (368:43): [True: 0, False: 7.02k]
  ------------------
  369|      0|    if (!IsSupportGuaranteedOpenCL_2_2(capability, opencl_embedded) &&
  ------------------
  |  Branch (369:9): [True: 0, False: 0]
  ------------------
  370|      0|        !IsSupportOptionalOpenCL_1_2(capability) &&
  ------------------
  |  Branch (370:9): [True: 0, False: 0]
  ------------------
  371|      0|        !IsEnabledByExtension(_, capability) &&
  ------------------
  |  Branch (371:9): [True: 0, False: 0]
  ------------------
  372|      0|        !IsEnabledByCapabilityOpenCL_2_0(_, capability)) {
  ------------------
  |  Branch (372:9): [True: 0, False: 0]
  ------------------
  373|      0|      return _.diag(SPV_ERROR_INVALID_CAPABILITY, inst)
  374|      0|             << "Capability " << capability_str()
  375|      0|             << " is not allowed by OpenCL 2.2 " << opencl_profile
  376|      0|             << " Profile specification"
  377|      0|             << " (or requires extension or capability)";
  378|      0|    }
  379|      0|  }
  380|       |
  381|  7.02k|  return SPV_SUCCESS;
  382|  7.02k|}

_ZN8spvtools3val16FirstBlockAssertERNS0_17ValidationState_tEj:
  369|  70.7k|spv_result_t FirstBlockAssert(ValidationState_t& _, uint32_t target) {
  370|  70.7k|  if (_.current_function().IsFirstBlock(target)) {
  ------------------
  |  Branch (370:7): [True: 5, False: 70.7k]
  ------------------
  371|      5|    return _.diag(SPV_ERROR_INVALID_CFG, _.FindDef(_.current_function().id()))
  372|      5|           << "First block " << _.getIdName(target) << " of function "
  373|      5|           << _.getIdName(_.current_function().id()) << " is targeted by block "
  374|      5|           << _.getIdName(_.current_function().current_block()->id());
  375|      5|  }
  376|  70.7k|  return SPV_SUCCESS;
  377|  70.7k|}
_ZN8spvtools3val16MergeBlockAssertERNS0_17ValidationState_tEj:
  379|  32.3k|spv_result_t MergeBlockAssert(ValidationState_t& _, uint32_t merge_block) {
  380|  32.3k|  if (_.current_function().IsBlockType(merge_block, kBlockTypeMerge)) {
  ------------------
  |  Branch (380:7): [True: 28, False: 32.3k]
  ------------------
  381|     28|    return _.diag(SPV_ERROR_INVALID_CFG, _.FindDef(_.current_function().id()))
  382|     28|           << "Block " << _.getIdName(merge_block)
  383|     28|           << " is already a merge block for another header";
  384|     28|  }
  385|  32.3k|  return SPV_SUCCESS;
  386|  32.3k|}
_ZN8spvtools3val33UpdateContinueConstructExitBlocksERNS0_8FunctionERKNSt3__16vectorINS3_4pairIjjEENS3_9allocatorIS6_EEEE:
  392|  1.77k|    const std::vector<std::pair<uint32_t, uint32_t>>& back_edges) {
  393|  1.77k|  auto& constructs = function.constructs();
  394|       |  // TODO(umar): Think of a faster way to do this
  395|  5.20k|  for (auto& edge : back_edges) {
  ------------------
  |  Branch (395:19): [True: 5.20k, False: 1.77k]
  ------------------
  396|  5.20k|    uint32_t back_edge_block_id;
  397|  5.20k|    uint32_t loop_header_block_id;
  398|  5.20k|    std::tie(back_edge_block_id, loop_header_block_id) = edge;
  399|  5.20k|    auto is_this_header = [=](Construct& c) {
  400|  5.20k|      return c.type() == ConstructType::kLoop &&
  401|  5.20k|             c.entry_block()->id() == loop_header_block_id;
  402|  5.20k|    };
  403|       |
  404|   170k|    for (auto construct : constructs) {
  ------------------
  |  Branch (404:25): [True: 170k, False: 5.20k]
  ------------------
  405|   170k|      if (is_this_header(construct)) {
  ------------------
  |  Branch (405:11): [True: 3.97k, False: 166k]
  ------------------
  406|  3.97k|        Construct* continue_construct =
  407|  3.97k|            construct.corresponding_constructs().back();
  408|  3.97k|        assert(continue_construct->type() == ConstructType::kContinue);
  409|       |
  410|      0|        BasicBlock* back_edge_block;
  411|  3.97k|        std::tie(back_edge_block, std::ignore) =
  412|  3.97k|            function.GetBlock(back_edge_block_id);
  413|  3.97k|        continue_construct->set_exit(back_edge_block);
  414|  3.97k|      }
  415|   170k|    }
  416|  5.20k|  }
  417|  1.77k|}
_ZN8spvtools3val14ConstructNamesENS0_13ConstructTypeE:
  420|  6.17k|    ConstructType type) {
  421|  6.17k|  std::string construct_name, header_name, exit_name;
  422|       |
  423|  6.17k|  switch (type) {
  424|  3.26k|    case ConstructType::kSelection:
  ------------------
  |  Branch (424:5): [True: 3.26k, False: 2.90k]
  ------------------
  425|  3.26k|      construct_name = "selection";
  426|  3.26k|      header_name = "selection header";
  427|  3.26k|      exit_name = "merge block";
  428|  3.26k|      break;
  429|  1.49k|    case ConstructType::kLoop:
  ------------------
  |  Branch (429:5): [True: 1.49k, False: 4.67k]
  ------------------
  430|  1.49k|      construct_name = "loop";
  431|  1.49k|      header_name = "loop header";
  432|  1.49k|      exit_name = "merge block";
  433|  1.49k|      break;
  434|  1.41k|    case ConstructType::kContinue:
  ------------------
  |  Branch (434:5): [True: 1.41k, False: 4.76k]
  ------------------
  435|  1.41k|      construct_name = "continue";
  436|  1.41k|      header_name = "continue target";
  437|  1.41k|      exit_name = "back-edge block";
  438|  1.41k|      break;
  439|      0|    case ConstructType::kCase:
  ------------------
  |  Branch (439:5): [True: 0, False: 6.17k]
  ------------------
  440|      0|      construct_name = "case";
  441|      0|      header_name = "case entry block";
  442|      0|      exit_name = "case exit block";
  443|      0|      break;
  444|      0|    default:
  ------------------
  |  Branch (444:5): [True: 0, False: 6.17k]
  ------------------
  445|      0|      assert(1 == 0 && "Not defined type");
  446|  6.17k|  }
  447|       |
  448|  6.17k|  return std::make_tuple(construct_name, header_name, exit_name);
  449|  6.17k|}
_ZN8spvtools3val20ConstructErrorStringERKNS0_9ConstructERKNSt3__112basic_stringIcNS4_11char_traitsIcEENS4_9allocatorIcEEEESC_SC_:
  455|     57|                                 const std::string& dominate_text) {
  456|     57|  std::string construct_name, header_name, exit_name;
  457|     57|  std::tie(construct_name, header_name, exit_name) =
  458|     57|      ConstructNames(construct.type());
  459|       |
  460|       |  // TODO(umar): Add header block for continue constructs to error message
  461|     57|  return "The " + construct_name + " construct with the " + header_name + " " +
  462|     57|         header_string + " " + dominate_text + " the " + exit_name + " " +
  463|     57|         exit_string;
  464|     57|}
_ZN8spvtools3val19FindCaseFallThroughERNS0_17ValidationState_tEPNS0_10BasicBlockEPjPKS3_RKNSt3__113unordered_setIjNS8_4hashIjEENS8_8equal_toIjEENS8_9allocatorIjEEEEPNS0_8FunctionE:
  472|  1.23k|    Function* function) {
  473|  1.23k|  std::vector<BasicBlock*> stack;
  474|  1.23k|  stack.push_back(target_block);
  475|  1.23k|  std::unordered_set<const BasicBlock*> visited;
  476|  1.23k|  bool target_reachable = target_block->structurally_reachable();
  477|  1.23k|  int target_depth = function->GetBlockDepth(target_block);
  478|  18.1k|  while (!stack.empty()) {
  ------------------
  |  Branch (478:10): [True: 16.9k, False: 1.21k]
  ------------------
  479|  16.9k|    auto block = stack.back();
  480|  16.9k|    stack.pop_back();
  481|       |
  482|  16.9k|    if (block == merge) continue;
  ------------------
  |  Branch (482:9): [True: 1.59k, False: 15.3k]
  ------------------
  483|       |
  484|  15.3k|    if (!visited.insert(block).second) continue;
  ------------------
  |  Branch (484:9): [True: 3.76k, False: 11.6k]
  ------------------
  485|       |
  486|  11.6k|    if (target_reachable && block->structurally_reachable() &&
  ------------------
  |  Branch (486:9): [True: 11.6k, False: 0]
  |  Branch (486:29): [True: 11.6k, False: 0]
  ------------------
  487|  11.6k|        target_block->structurally_dominates(*block)) {
  ------------------
  |  Branch (487:9): [True: 11.3k, False: 253]
  ------------------
  488|       |      // Still in the case construct.
  489|  15.7k|      for (auto successor : *block->successors()) {
  ------------------
  |  Branch (489:27): [True: 15.7k, False: 11.3k]
  ------------------
  490|  15.7k|        stack.push_back(successor);
  491|  15.7k|      }
  492|  11.3k|    } else {
  493|       |      // Exiting the case construct to non-merge block.
  494|    253|      if (!case_targets.count(block->id())) {
  ------------------
  |  Branch (494:11): [True: 97, False: 156]
  ------------------
  495|     97|        int depth = function->GetBlockDepth(block);
  496|     97|        if ((depth < target_depth) ||
  ------------------
  |  Branch (496:13): [True: 80, False: 17]
  ------------------
  497|     97|            (depth == target_depth && block->is_type(kBlockTypeContinue))) {
  ------------------
  |  Branch (497:14): [True: 15, False: 2]
  |  Branch (497:39): [True: 3, False: 12]
  ------------------
  498|     83|          continue;
  499|     83|        }
  500|       |
  501|     14|        return _.diag(SPV_ERROR_INVALID_CFG, target_block->label())
  502|     14|               << "Case construct that targets "
  503|     14|               << _.getIdName(target_block->id())
  504|     14|               << " has invalid branch to block " << _.getIdName(block->id())
  505|     14|               << " (not another case construct, corresponding merge, outer "
  506|     14|                  "loop merge or outer loop continue)";
  507|     97|      }
  508|       |
  509|    156|      if (*case_fall_through == 0u) {
  ------------------
  |  Branch (509:11): [True: 150, False: 6]
  ------------------
  510|    150|        if (target_block != block) {
  ------------------
  |  Branch (510:13): [True: 150, False: 0]
  ------------------
  511|    150|          *case_fall_through = block->id();
  512|    150|        }
  513|    150|      } else if (*case_fall_through != block->id()) {
  ------------------
  |  Branch (513:18): [True: 6, False: 0]
  ------------------
  514|       |        // Case construct has at most one branch to another case construct.
  515|      6|        return _.diag(SPV_ERROR_INVALID_CFG, target_block->label())
  516|      6|               << "Case construct that targets "
  517|      6|               << _.getIdName(target_block->id())
  518|      6|               << " has branches to multiple other case construct targets "
  519|      6|               << _.getIdName(*case_fall_through) << " and "
  520|      6|               << _.getIdName(block->id());
  521|      6|      }
  522|    156|    }
  523|  11.6k|  }
  524|       |
  525|  1.21k|  return SPV_SUCCESS;
  526|  1.23k|}
_ZN8spvtools3val22StructuredSwitchChecksERNS0_17ValidationState_tEPNS0_8FunctionEPKNS0_11InstructionEPKNS0_10BasicBlockESA_:
  531|    842|                                    const BasicBlock* merge) {
  532|    842|  std::unordered_set<uint32_t> case_targets;
  533|  3.20k|  for (uint32_t i = 1; i < switch_inst->operands().size(); i += 2) {
  ------------------
  |  Branch (533:24): [True: 2.36k, False: 842]
  ------------------
  534|  2.36k|    uint32_t target = switch_inst->GetOperandAs<uint32_t>(i);
  535|  2.36k|    if (target != merge->id()) case_targets.insert(target);
  ------------------
  |  Branch (535:9): [True: 2.12k, False: 242]
  ------------------
  536|  2.36k|  }
  537|       |  // Tracks how many times each case construct is targeted by another case
  538|       |  // construct.
  539|    842|  std::map<uint32_t, uint32_t> num_fall_through_targeted;
  540|    842|  uint32_t default_case_fall_through = 0u;
  541|    842|  uint32_t default_target = switch_inst->GetOperandAs<uint32_t>(1u);
  542|    842|  bool default_appears_multiple_times = false;
  543|  1.75k|  for (uint32_t i = 3; i < switch_inst->operands().size(); i += 2) {
  ------------------
  |  Branch (543:24): [True: 996, False: 760]
  ------------------
  544|    996|    if (default_target == switch_inst->GetOperandAs<uint32_t>(i)) {
  ------------------
  |  Branch (544:9): [True: 82, False: 914]
  ------------------
  545|     82|      default_appears_multiple_times = true;
  546|     82|      break;
  547|     82|    }
  548|    996|  }
  549|    842|  std::unordered_map<uint32_t, uint32_t> seen_to_fall_through;
  550|  2.61k|  for (uint32_t i = 1; i < switch_inst->operands().size(); i += 2) {
  ------------------
  |  Branch (550:24): [True: 1.86k, False: 758]
  ------------------
  551|  1.86k|    uint32_t target = switch_inst->GetOperandAs<uint32_t>(i);
  552|  1.86k|    if (target == merge->id()) continue;
  ------------------
  |  Branch (552:9): [True: 190, False: 1.67k]
  ------------------
  553|       |
  554|  1.67k|    uint32_t case_fall_through = 0u;
  555|  1.67k|    auto seen_iter = seen_to_fall_through.find(target);
  556|  1.67k|    if (seen_iter == seen_to_fall_through.end()) {
  ------------------
  |  Branch (556:9): [True: 1.25k, False: 415]
  ------------------
  557|  1.25k|      const auto target_block = function->GetBlock(target).first;
  558|       |      // OpSwitch must dominate all its case constructs.
  559|  1.25k|      if (header->structurally_reachable() &&
  ------------------
  |  Branch (559:11): [True: 1.25k, False: 0]
  ------------------
  560|  1.25k|          target_block->structurally_reachable() &&
  ------------------
  |  Branch (560:11): [True: 1.25k, False: 0]
  ------------------
  561|  1.25k|          !header->structurally_dominates(*target_block)) {
  ------------------
  |  Branch (561:11): [True: 24, False: 1.23k]
  ------------------
  562|     24|        return _.diag(SPV_ERROR_INVALID_CFG, header->label())
  563|     24|               << "Switch header " << _.getIdName(header->id())
  564|     24|               << " does not structurally dominate its case construct "
  565|     24|               << _.getIdName(target);
  566|     24|      }
  567|       |
  568|  1.23k|      if (auto error = FindCaseFallThrough(_, target_block, &case_fall_through,
  ------------------
  |  Branch (568:16): [True: 20, False: 1.21k]
  ------------------
  569|  1.23k|                                           merge, case_targets, function)) {
  570|     20|        return error;
  571|     20|      }
  572|       |
  573|       |      // Track how many time the fall through case has been targeted.
  574|  1.21k|      if (case_fall_through != 0u) {
  ------------------
  |  Branch (574:11): [True: 144, False: 1.06k]
  ------------------
  575|    144|        auto where = num_fall_through_targeted.lower_bound(case_fall_through);
  576|    144|        if (where == num_fall_through_targeted.end() ||
  ------------------
  |  Branch (576:13): [True: 107, False: 37]
  |  Branch (576:13): [True: 135, False: 9]
  ------------------
  577|    144|            where->first != case_fall_through) {
  ------------------
  |  Branch (577:13): [True: 28, False: 9]
  ------------------
  578|    135|          num_fall_through_targeted.insert(
  579|    135|              where, std::make_pair(case_fall_through, 1));
  580|    135|        } else {
  581|      9|          where->second++;
  582|      9|        }
  583|    144|      }
  584|  1.21k|      seen_to_fall_through.insert(std::make_pair(target, case_fall_through));
  585|  1.21k|    } else {
  586|    415|      case_fall_through = seen_iter->second;
  587|    415|    }
  588|       |
  589|  1.62k|    if (case_fall_through == default_target &&
  ------------------
  |  Branch (589:9): [True: 83, False: 1.54k]
  ------------------
  590|  1.62k|        !default_appears_multiple_times) {
  ------------------
  |  Branch (590:9): [True: 27, False: 56]
  ------------------
  591|     27|      case_fall_through = default_case_fall_through;
  592|     27|    }
  593|  1.62k|    if (case_fall_through != 0u) {
  ------------------
  |  Branch (593:9): [True: 223, False: 1.40k]
  ------------------
  594|    223|      bool is_default = i == 1;
  595|    223|      if (is_default) {
  ------------------
  |  Branch (595:11): [True: 44, False: 179]
  ------------------
  596|     44|        default_case_fall_through = case_fall_through;
  597|    179|      } else {
  598|       |        // Allow code like:
  599|       |        // case x:
  600|       |        // case y:
  601|       |        //   ...
  602|       |        // case z:
  603|       |        //
  604|       |        // Where x and y target the same block and fall through to z.
  605|    179|        uint32_t j = i;
  606|    274|        while ((j + 2 < switch_inst->operands().size()) &&
  ------------------
  |  Branch (606:16): [True: 261, False: 13]
  ------------------
  607|    274|               target == switch_inst->GetOperandAs<uint32_t>(j + 2)) {
  ------------------
  |  Branch (607:16): [True: 95, False: 166]
  ------------------
  608|     95|          j += 2;
  609|     95|        }
  610|       |        // If Target T1 branches to Target T2, or if Target T1 branches to the
  611|       |        // Default target and the Default target branches to Target T2, then T1
  612|       |        // must immediately precede T2 in the list of OpSwitch Target operands.
  613|    179|        if ((switch_inst->operands().size() < j + 2) ||
  ------------------
  |  Branch (613:13): [True: 13, False: 166]
  ------------------
  614|    179|            (case_fall_through != switch_inst->GetOperandAs<uint32_t>(j + 2))) {
  ------------------
  |  Branch (614:13): [True: 27, False: 139]
  ------------------
  615|     40|          return _.diag(SPV_ERROR_INVALID_CFG, switch_inst)
  616|     40|                 << "Case construct that targets " << _.getIdName(target)
  617|     40|                 << " has branches to the case construct that targets "
  618|     40|                 << _.getIdName(case_fall_through)
  619|     40|                 << ", but does not immediately precede it in the "
  620|     40|                    "OpSwitch's target list";
  621|     40|        }
  622|    179|      }
  623|    223|    }
  624|  1.62k|  }
  625|       |
  626|       |  // Each case construct must be branched to by at most one other case
  627|       |  // construct.
  628|    758|  for (const auto& pair : num_fall_through_targeted) {
  ------------------
  |  Branch (628:25): [True: 44, False: 753]
  ------------------
  629|     44|    if (pair.second > 1) {
  ------------------
  |  Branch (629:9): [True: 5, False: 39]
  ------------------
  630|      5|      return _.diag(SPV_ERROR_INVALID_CFG, _.FindDef(pair.first))
  631|      5|             << "Multiple case constructs have branches to the case construct "
  632|      5|                "that targets "
  633|      5|             << _.getIdName(pair.first);
  634|      5|    }
  635|     44|  }
  636|       |
  637|    753|  return SPV_SUCCESS;
  638|    758|}
_ZN8spvtools3val28ValidateStructuredSelectionsERNS0_17ValidationState_tERKNSt3__16vectorIPKNS0_10BasicBlockENS3_9allocatorIS7_EEEE:
  644|  1.28k|    ValidationState_t& _, const std::vector<const BasicBlock*>& postorder) {
  645|  1.28k|  std::unordered_set<uint32_t> seen;
  646|  11.3k|  for (auto iter = postorder.rbegin(); iter != postorder.rend(); ++iter) {
  ------------------
  |  Branch (646:40): [True: 10.1k, False: 1.24k]
  ------------------
  647|  10.1k|    const auto* block = *iter;
  648|  10.1k|    const auto* terminator = block->terminator();
  649|  10.1k|    if (!terminator) continue;
  ------------------
  |  Branch (649:9): [True: 978, False: 9.16k]
  ------------------
  650|  9.16k|    const auto index = terminator - &_.ordered_instructions()[0];
  651|  9.16k|    auto* merge = &_.ordered_instructions()[index - 1];
  652|       |    // Marks merges and continues as seen.
  653|  9.16k|    if (merge->opcode() == spv::Op::OpSelectionMerge) {
  ------------------
  |  Branch (653:9): [True: 1.73k, False: 7.43k]
  ------------------
  654|  1.73k|      seen.insert(merge->GetOperandAs<uint32_t>(0));
  655|  7.43k|    } else if (merge->opcode() == spv::Op::OpLoopMerge) {
  ------------------
  |  Branch (655:16): [True: 889, False: 6.54k]
  ------------------
  656|    889|      seen.insert(merge->GetOperandAs<uint32_t>(0));
  657|    889|      seen.insert(merge->GetOperandAs<uint32_t>(1));
  658|  6.54k|    } else {
  659|       |      // Only track the pointer if it is a merge instruction.
  660|  6.54k|      merge = nullptr;
  661|  6.54k|    }
  662|       |
  663|       |    // Skip unreachable blocks.
  664|  9.16k|    if (!block->structurally_reachable()) continue;
  ------------------
  |  Branch (664:9): [True: 0, False: 9.16k]
  ------------------
  665|       |
  666|  9.16k|    if (terminator->opcode() == spv::Op::OpBranchConditional) {
  ------------------
  |  Branch (666:9): [True: 2.21k, False: 6.94k]
  ------------------
  667|  2.21k|      const auto true_label = terminator->GetOperandAs<uint32_t>(1);
  668|  2.21k|      const auto false_label = terminator->GetOperandAs<uint32_t>(2);
  669|       |      // Mark the upcoming blocks as seen now, but only error out if this block
  670|       |      // was missing a merge instruction and both labels hadn't been seen
  671|       |      // previously.
  672|  2.21k|      const bool true_label_unseen = seen.insert(true_label).second;
  673|  2.21k|      const bool false_label_unseen = seen.insert(false_label).second;
  674|  2.21k|      if ((!merge || merge->opcode() == spv::Op::OpLoopMerge) &&
  ------------------
  |  Branch (674:12): [True: 367, False: 1.85k]
  |  Branch (674:22): [True: 464, False: 1.38k]
  ------------------
  675|  2.21k|          true_label_unseen && false_label_unseen) {
  ------------------
  |  Branch (675:11): [True: 730, False: 101]
  |  Branch (675:32): [True: 12, False: 718]
  ------------------
  676|     12|        return _.diag(SPV_ERROR_INVALID_CFG, terminator)
  677|     12|               << "Selection must be structured";
  678|     12|      }
  679|  6.94k|    } else if (terminator->opcode() == spv::Op::OpSwitch) {
  ------------------
  |  Branch (679:16): [True: 371, False: 6.57k]
  ------------------
  680|    371|      if (!merge) {
  ------------------
  |  Branch (680:11): [True: 21, False: 350]
  ------------------
  681|     21|        return _.diag(SPV_ERROR_INVALID_CFG, terminator)
  682|     21|               << "OpSwitch must be preceded by an OpSelectionMerge "
  683|     21|                  "instruction";
  684|     21|      }
  685|       |      // Mark the targets as seen.
  686|  1.21k|      for (uint32_t i = 1; i < terminator->operands().size(); i += 2) {
  ------------------
  |  Branch (686:28): [True: 864, False: 350]
  ------------------
  687|    864|        const auto target = terminator->GetOperandAs<uint32_t>(i);
  688|    864|        seen.insert(target);
  689|    864|      }
  690|    350|    }
  691|  9.16k|  }
  692|       |
  693|  1.24k|  return SPV_SUCCESS;
  694|  1.28k|}
_ZN8spvtools3val27StructuredControlFlowChecksERNS0_17ValidationState_tEPNS0_8FunctionERKNSt3__16vectorINS5_4pairIjjEENS5_9allocatorIS8_EEEERKNS6_IPKNS0_10BasicBlockENS9_ISG_EEEE:
  699|  1.77k|    const std::vector<const BasicBlock*>& postorder) {
  700|       |  /// Check all backedges target only loop headers and have exactly one
  701|       |  /// back-edge branching to it
  702|       |
  703|       |  // Map a loop header to blocks with back-edges to the loop header.
  704|  1.77k|  std::map<uint32_t, std::unordered_set<uint32_t>> loop_latch_blocks;
  705|  3.54k|  for (auto back_edge : back_edges) {
  ------------------
  |  Branch (705:23): [True: 3.54k, False: 1.60k]
  ------------------
  706|  3.54k|    uint32_t back_edge_block;
  707|  3.54k|    uint32_t header_block;
  708|  3.54k|    std::tie(back_edge_block, header_block) = back_edge;
  709|  3.54k|    if (!function->IsBlockType(header_block, kBlockTypeLoop)) {
  ------------------
  |  Branch (709:9): [True: 171, False: 3.37k]
  ------------------
  710|    171|      return _.diag(SPV_ERROR_INVALID_CFG, _.FindDef(back_edge_block))
  711|    171|             << "Back-edges (" << _.getIdName(back_edge_block) << " -> "
  712|    171|             << _.getIdName(header_block)
  713|    171|             << ") can only be formed between a block and a loop header.";
  714|    171|    }
  715|  3.37k|    loop_latch_blocks[header_block].insert(back_edge_block);
  716|  3.37k|  }
  717|       |
  718|       |  // Check the loop headers have exactly one back-edge branching to it
  719|  23.3k|  for (BasicBlock* loop_header : function->ordered_blocks()) {
  ------------------
  |  Branch (719:32): [True: 23.3k, False: 1.57k]
  ------------------
  720|  23.3k|    if (!loop_header->structurally_reachable()) continue;
  ------------------
  |  Branch (720:9): [True: 3.00k, False: 20.3k]
  ------------------
  721|  20.3k|    if (!loop_header->is_type(kBlockTypeLoop)) continue;
  ------------------
  |  Branch (721:9): [True: 18.3k, False: 1.98k]
  ------------------
  722|  1.98k|    auto loop_header_id = loop_header->id();
  723|  1.98k|    auto num_latch_blocks = loop_latch_blocks[loop_header_id].size();
  724|  1.98k|    if (num_latch_blocks != 1) {
  ------------------
  |  Branch (724:9): [True: 30, False: 1.95k]
  ------------------
  725|     30|      return _.diag(SPV_ERROR_INVALID_CFG, _.FindDef(loop_header_id))
  726|     30|             << "Loop header " << _.getIdName(loop_header_id)
  727|     30|             << " is targeted by " << num_latch_blocks
  728|     30|             << " back-edge blocks but the standard requires exactly one";
  729|     30|    }
  730|  1.98k|  }
  731|       |
  732|       |  // Check construct rules
  733|  6.43k|  for (const Construct& construct : function->constructs()) {
  ------------------
  |  Branch (733:35): [True: 6.43k, False: 1.28k]
  ------------------
  734|  6.43k|    auto header = construct.entry_block();
  735|  6.43k|    if (!header->structurally_reachable()) continue;
  ------------------
  |  Branch (735:9): [True: 259, False: 6.17k]
  ------------------
  736|  6.17k|    auto merge = construct.exit_block();
  737|       |
  738|  6.17k|    if (!merge) {
  ------------------
  |  Branch (738:9): [True: 0, False: 6.17k]
  ------------------
  739|      0|      std::string construct_name, header_name, exit_name;
  740|      0|      std::tie(construct_name, header_name, exit_name) =
  741|      0|          ConstructNames(construct.type());
  742|      0|      return _.diag(SPV_ERROR_INTERNAL, _.FindDef(header->id()))
  743|      0|             << "Construct " + construct_name + " with " + header_name + " " +
  744|      0|                    _.getIdName(header->id()) + " does not have a " +
  745|      0|                    exit_name + ". This may be a bug in the validator.";
  746|      0|    }
  747|       |
  748|       |    // If the header is reachable, the merge is guaranteed to be structurally
  749|       |    // reachable.
  750|  6.17k|    if (!header->structurally_dominates(*merge)) {
  ------------------
  |  Branch (750:9): [True: 42, False: 6.13k]
  ------------------
  751|     42|      return _.diag(SPV_ERROR_INVALID_CFG, _.FindDef(merge->id()))
  752|     42|             << ConstructErrorString(construct, _.getIdName(header->id()),
  753|     42|                                     _.getIdName(merge->id()),
  754|     42|                                     "does not structurally dominate");
  755|     42|    }
  756|       |
  757|       |    // If it's really a merge block for a selection or loop, then it must be
  758|       |    // *strictly* structrually dominated by the header.
  759|  6.13k|    if (construct.ExitBlockIsMergeBlock() && (header == merge)) {
  ------------------
  |  Branch (759:9): [True: 4.73k, False: 1.39k]
  |  Branch (759:46): [True: 3, False: 4.73k]
  ------------------
  760|      3|      return _.diag(SPV_ERROR_INVALID_CFG, _.FindDef(merge->id()))
  761|      3|             << ConstructErrorString(construct, _.getIdName(header->id()),
  762|      3|                                     _.getIdName(merge->id()),
  763|      3|                                     "does not strictly structurally dominate");
  764|      3|    }
  765|       |
  766|       |    // Check post-dominance for continue constructs.  But dominance and
  767|       |    // post-dominance only make sense when the construct is reachable.
  768|  6.12k|    if (construct.type() == ConstructType::kContinue) {
  ------------------
  |  Branch (768:9): [True: 1.39k, False: 4.73k]
  ------------------
  769|  1.39k|      if (!merge->structurally_postdominates(*header)) {
  ------------------
  |  Branch (769:11): [True: 12, False: 1.38k]
  ------------------
  770|     12|        return _.diag(SPV_ERROR_INVALID_CFG, _.FindDef(merge->id()))
  771|     12|               << ConstructErrorString(construct, _.getIdName(header->id()),
  772|     12|                                       _.getIdName(merge->id()),
  773|     12|                                       "is not structurally post dominated by");
  774|     12|      }
  775|  1.39k|    }
  776|       |
  777|  6.11k|    Construct::ConstructBlockSet construct_blocks = construct.blocks(function);
  778|  6.11k|    std::string construct_name, header_name, exit_name;
  779|  6.11k|    std::tie(construct_name, header_name, exit_name) =
  780|  6.11k|        ConstructNames(construct.type());
  781|  37.6k|    for (auto block : construct_blocks) {
  ------------------
  |  Branch (781:21): [True: 37.6k, False: 6.00k]
  ------------------
  782|       |      // Check that all exits from the construct are via structured exits.
  783|  50.1k|      for (auto succ : *block->successors()) {
  ------------------
  |  Branch (783:22): [True: 50.1k, False: 37.5k]
  ------------------
  784|  50.1k|        if (!construct_blocks.count(succ) &&
  ------------------
  |  Branch (784:13): [True: 13.6k, False: 36.4k]
  ------------------
  785|  50.1k|            !construct.IsStructuredExit(_, succ)) {
  ------------------
  |  Branch (785:13): [True: 50, False: 13.6k]
  ------------------
  786|     50|          return _.diag(SPV_ERROR_INVALID_CFG, _.FindDef(block->id()))
  787|     50|                 << "block <ID> " << _.getIdName(block->id()) << " exits the "
  788|     50|                 << construct_name << " headed by <ID> "
  789|     50|                 << _.getIdName(header->id())
  790|     50|                 << ", but not via a structured exit";
  791|     50|        }
  792|  50.1k|      }
  793|  37.5k|      if (block == header) continue;
  ------------------
  |  Branch (793:11): [True: 5.98k, False: 31.5k]
  ------------------
  794|       |      // Check that for all non-header blocks, all predecessors are within this
  795|       |      // construct.
  796|  36.8k|      for (auto pred : *block->predecessors()) {
  ------------------
  |  Branch (796:22): [True: 36.8k, False: 31.5k]
  ------------------
  797|  36.8k|        if (pred->structurally_reachable() && !construct_blocks.count(pred)) {
  ------------------
  |  Branch (797:13): [True: 36.2k, False: 551]
  |  Branch (797:47): [True: 44, False: 36.2k]
  ------------------
  798|     44|          return _.diag(SPV_ERROR_INVALID_CFG, _.FindDef(pred->id()))
  799|     44|                 << "block <ID> " << pred->id() << " branches to the "
  800|     44|                 << construct_name << " construct, but not to the "
  801|     44|                 << header_name << " <ID> " << header->id();
  802|     44|        }
  803|  36.8k|      }
  804|       |
  805|  31.5k|      if (block->is_type(BlockType::kBlockTypeSelection) ||
  ------------------
  |  Branch (805:11): [True: 7.51k, False: 24.0k]
  ------------------
  806|  31.5k|          block->is_type(BlockType::kBlockTypeLoop)) {
  ------------------
  |  Branch (806:11): [True: 1.56k, False: 22.4k]
  ------------------
  807|  9.08k|        size_t index = (block->terminator() - &_.ordered_instructions()[0]) - 1;
  808|  9.08k|        const auto& merge_inst = _.ordered_instructions()[index];
  809|  9.08k|        if (merge_inst.opcode() == spv::Op::OpSelectionMerge ||
  ------------------
  |  Branch (809:13): [True: 7.51k, False: 1.56k]
  ------------------
  810|  9.08k|            merge_inst.opcode() == spv::Op::OpLoopMerge) {
  ------------------
  |  Branch (810:13): [True: 1.56k, False: 0]
  ------------------
  811|  9.08k|          uint32_t merge_id = merge_inst.GetOperandAs<uint32_t>(0);
  812|  9.08k|          auto merge_block = function->GetBlock(merge_id).first;
  813|  9.08k|          if (merge_block->structurally_reachable() &&
  ------------------
  |  Branch (813:15): [True: 9.08k, False: 0]
  ------------------
  814|  9.08k|              !construct_blocks.count(merge_block)) {
  ------------------
  |  Branch (814:15): [True: 13, False: 9.07k]
  ------------------
  815|     13|            return _.diag(SPV_ERROR_INVALID_CFG, _.FindDef(block->id()))
  816|     13|                   << "Header block " << _.getIdName(block->id())
  817|     13|                   << " is contained in the " << construct_name
  818|     13|                   << " construct headed by " << _.getIdName(header->id())
  819|     13|                   << ", but its merge block " << _.getIdName(merge_id)
  820|     13|                   << " is not";
  821|     13|          }
  822|  9.08k|        }
  823|  9.08k|      }
  824|  31.5k|    }
  825|       |
  826|  6.00k|    if (construct.type() == ConstructType::kLoop) {
  ------------------
  |  Branch (826:9): [True: 1.45k, False: 4.55k]
  ------------------
  827|       |      // If the continue target differs from the loop header, then check that
  828|       |      // all edges into the continue construct come from within the loop.
  829|  1.45k|      const auto index = header->terminator() - &_.ordered_instructions()[0];
  830|  1.45k|      const auto& merge_inst = _.ordered_instructions()[index - 1];
  831|  1.45k|      const auto continue_id = merge_inst.GetOperandAs<uint32_t>(1);
  832|  1.45k|      const auto* continue_inst = _.FindDef(continue_id);
  833|       |      // OpLabel instructions aren't stored as part of the basic block for
  834|       |      // legacy reaasons. Grab the next instruction and use it's block pointer
  835|       |      // instead.
  836|  1.45k|      const auto next_index =
  837|  1.45k|          (continue_inst - &_.ordered_instructions()[0]) + 1;
  838|  1.45k|      const auto& next_inst = _.ordered_instructions()[next_index];
  839|  1.45k|      const auto* continue_target = next_inst.block();
  840|  1.45k|      if (header->id() != continue_id) {
  ------------------
  |  Branch (840:11): [True: 1.40k, False: 48]
  ------------------
  841|  2.20k|        for (auto pred : *continue_target->predecessors()) {
  ------------------
  |  Branch (841:24): [True: 2.20k, False: 1.36k]
  ------------------
  842|       |          // Ignore back-edges from within the continue construct.
  843|  2.20k|          bool is_back_edge = false;
  844|  23.1k|          for (auto back_edge : back_edges) {
  ------------------
  |  Branch (844:31): [True: 23.1k, False: 2.20k]
  ------------------
  845|  23.1k|            uint32_t back_edge_block;
  846|  23.1k|            uint32_t header_block;
  847|  23.1k|            std::tie(back_edge_block, header_block) = back_edge;
  848|  23.1k|            if (header_block == continue_id && back_edge_block == pred->id())
  ------------------
  |  Branch (848:17): [True: 1.83k, False: 21.3k]
  |  Branch (848:48): [True: 1.61k, False: 215]
  ------------------
  849|  1.61k|              is_back_edge = true;
  850|  23.1k|          }
  851|  2.20k|          if (!construct_blocks.count(pred) && !is_back_edge) {
  ------------------
  |  Branch (851:15): [True: 98, False: 2.10k]
  |  Branch (851:48): [True: 41, False: 57]
  ------------------
  852|     41|            return _.diag(SPV_ERROR_INVALID_CFG, pred->terminator())
  853|     41|                   << "Block " << _.getIdName(pred->id())
  854|     41|                   << " branches to the loop continue target "
  855|     41|                   << _.getIdName(continue_id)
  856|     41|                   << ", but is not contained in the associated loop construct "
  857|     41|                   << _.getIdName(header->id());
  858|     41|          }
  859|  2.20k|        }
  860|  1.40k|      }
  861|  1.45k|    }
  862|       |
  863|       |    // Checks rules for case constructs.
  864|  5.96k|    if (construct.type() == ConstructType::kSelection &&
  ------------------
  |  Branch (864:9): [True: 3.18k, False: 2.78k]
  ------------------
  865|  5.96k|        header->terminator()->opcode() == spv::Op::OpSwitch) {
  ------------------
  |  Branch (865:9): [True: 842, False: 2.34k]
  ------------------
  866|    842|      const auto terminator = header->terminator();
  867|    842|      if (auto error =
  ------------------
  |  Branch (867:16): [True: 89, False: 753]
  ------------------
  868|    842|              StructuredSwitchChecks(_, function, terminator, header, merge)) {
  869|     89|        return error;
  870|     89|      }
  871|    842|    }
  872|  5.96k|  }
  873|       |
  874|  1.28k|  if (auto error = ValidateStructuredSelections(_, postorder)) {
  ------------------
  |  Branch (874:12): [True: 33, False: 1.24k]
  ------------------
  875|     33|    return error;
  876|     33|  }
  877|       |
  878|  1.24k|  return SPV_SUCCESS;
  879|  1.28k|}
_ZN8spvtools3val16PerformCfgChecksERNS0_17ValidationState_tE:
  881|  1.63k|spv_result_t PerformCfgChecks(ValidationState_t& _) {
  882|  1.81k|  for (auto& function : _.functions()) {
  ------------------
  |  Branch (882:23): [True: 1.81k, False: 1.07k]
  ------------------
  883|       |    // Check all referenced blocks are defined within a function
  884|  1.81k|    if (function.undefined_block_count() != 0) {
  ------------------
  |  Branch (884:9): [True: 6, False: 1.80k]
  ------------------
  885|      6|      std::string undef_blocks("{");
  886|      6|      bool first = true;
  887|      9|      for (auto undefined_block : function.undefined_blocks()) {
  ------------------
  |  Branch (887:33): [True: 9, False: 6]
  ------------------
  888|      9|        undef_blocks += _.getIdName(undefined_block);
  889|      9|        if (!first) {
  ------------------
  |  Branch (889:13): [True: 3, False: 6]
  ------------------
  890|      3|          undef_blocks += " ";
  891|      3|        }
  892|      9|        first = false;
  893|      9|      }
  894|      6|      return _.diag(SPV_ERROR_INVALID_CFG, _.FindDef(function.id()))
  895|      6|             << "Block(s) " << undef_blocks << "}"
  896|      6|             << " are referenced but not defined in function "
  897|      6|             << _.getIdName(function.id());
  898|      6|    }
  899|       |
  900|       |    // Set each block's immediate dominator.
  901|       |    //
  902|       |    // We want to analyze all the blocks in the function, even in degenerate
  903|       |    // control flow cases including unreachable blocks.  So use the augmented
  904|       |    // CFG to ensure we cover all the blocks.
  905|  1.80k|    std::vector<const BasicBlock*> postorder;
  906|  1.80k|    auto ignore_block = [](const BasicBlock*) {};
  907|  1.80k|    auto no_terminal_blocks = [](const BasicBlock*) { return false; };
  908|  1.80k|    if (!function.ordered_blocks().empty()) {
  ------------------
  |  Branch (908:9): [True: 1.53k, False: 269]
  ------------------
  909|       |      /// calculate dominators
  910|  1.53k|      CFA<BasicBlock>::DepthFirstTraversal(
  911|  1.53k|          function.first_block(), function.AugmentedCFGSuccessorsFunction(),
  912|  1.53k|          ignore_block, [&](const BasicBlock* b) { postorder.push_back(b); },
  913|  1.53k|          no_terminal_blocks);
  914|  1.53k|      auto edges = CFA<BasicBlock>::CalculateDominators(
  915|  1.53k|          postorder, function.AugmentedCFGPredecessorsFunction());
  916|  27.7k|      for (auto edge : edges) {
  ------------------
  |  Branch (916:22): [True: 27.7k, False: 1.53k]
  ------------------
  917|  27.7k|        if (edge.first != edge.second)
  ------------------
  |  Branch (917:13): [True: 26.1k, False: 1.56k]
  ------------------
  918|  26.1k|          edge.first->SetImmediateDominator(edge.second);
  919|  27.7k|      }
  920|  1.53k|    }
  921|       |
  922|  1.80k|    auto& blocks = function.ordered_blocks();
  923|  1.80k|    if (!blocks.empty()) {
  ------------------
  |  Branch (923:9): [True: 1.53k, False: 269]
  ------------------
  924|       |      // Check if the order of blocks in the binary appear before the blocks
  925|       |      // they dominate
  926|  34.5k|      for (auto block = begin(blocks) + 1; block != end(blocks); ++block) {
  ------------------
  |  Branch (926:44): [True: 33.0k, False: 1.51k]
  ------------------
  927|  33.0k|        if (auto idom = (*block)->immediate_dominator()) {
  ------------------
  |  Branch (927:18): [True: 24.1k, False: 8.93k]
  ------------------
  928|  24.1k|          if (idom != function.pseudo_entry_block() &&
  ------------------
  |  Branch (928:15): [True: 24.1k, False: 0]
  |  Branch (928:15): [True: 26, False: 24.1k]
  ------------------
  929|  24.1k|              block == std::find(begin(blocks), block, idom)) {
  ------------------
  |  Branch (929:15): [True: 26, False: 24.1k]
  ------------------
  930|     26|            return _.diag(SPV_ERROR_INVALID_CFG, _.FindDef(idom->id()))
  931|     26|                   << "Block " << _.getIdName((*block)->id())
  932|     26|                   << " appears in the binary before its dominator "
  933|     26|                   << _.getIdName(idom->id());
  934|     26|          }
  935|  24.1k|        }
  936|  33.0k|      }
  937|       |      // If we have structured control flow, check that no block has a control
  938|       |      // flow nesting depth larger than the limit.
  939|  1.51k|      if (_.HasCapability(spv::Capability::Shader)) {
  ------------------
  |  Branch (939:11): [True: 1.50k, False: 4]
  ------------------
  940|  1.50k|        const int control_flow_nesting_depth_limit =
  941|  1.50k|            _.options()->universal_limits_.max_control_flow_nesting_depth;
  942|  35.9k|        for (auto block = begin(blocks); block != end(blocks); ++block) {
  ------------------
  |  Branch (942:42): [True: 34.3k, False: 1.50k]
  ------------------
  943|  34.3k|          if (function.GetBlockDepth(*block) >
  ------------------
  |  Branch (943:15): [True: 0, False: 34.3k]
  ------------------
  944|  34.3k|              control_flow_nesting_depth_limit) {
  945|      0|            return _.diag(SPV_ERROR_INVALID_CFG, _.FindDef((*block)->id()))
  946|      0|                   << "Maximum Control Flow nesting depth exceeded.";
  947|      0|          }
  948|  34.3k|        }
  949|  1.50k|      }
  950|  1.51k|    }
  951|       |
  952|       |    /// Structured control flow checks are only required for shader capabilities
  953|  1.77k|    if (_.HasCapability(spv::Capability::Shader)) {
  ------------------
  |  Branch (953:9): [True: 1.77k, False: 4]
  ------------------
  954|       |      // Calculate structural dominance.
  955|  1.77k|      postorder.clear();
  956|  1.77k|      std::vector<const BasicBlock*> postdom_postorder;
  957|  1.77k|      std::vector<std::pair<uint32_t, uint32_t>> back_edges;
  958|  1.77k|      if (!function.ordered_blocks().empty()) {
  ------------------
  |  Branch (958:11): [True: 1.50k, False: 269]
  ------------------
  959|       |        /// calculate dominators
  960|  1.50k|        CFA<BasicBlock>::DepthFirstTraversal(
  961|  1.50k|            function.first_block(),
  962|  1.50k|            function.AugmentedStructuralCFGSuccessorsFunction(), ignore_block,
  963|  1.50k|            [&](const BasicBlock* b) { postorder.push_back(b); },
  964|  1.50k|            no_terminal_blocks);
  965|  1.50k|        auto edges = CFA<BasicBlock>::CalculateDominators(
  966|  1.50k|            postorder, function.AugmentedStructuralCFGPredecessorsFunction());
  967|  31.5k|        for (auto edge : edges) {
  ------------------
  |  Branch (967:24): [True: 31.5k, False: 1.50k]
  ------------------
  968|  31.5k|          if (edge.first != edge.second)
  ------------------
  |  Branch (968:15): [True: 30.0k, False: 1.50k]
  ------------------
  969|  30.0k|            edge.first->SetImmediateStructuralDominator(edge.second);
  970|  31.5k|        }
  971|       |
  972|       |        /// calculate post dominators
  973|  1.50k|        CFA<BasicBlock>::DepthFirstTraversal(
  974|  1.50k|            function.pseudo_exit_block(),
  975|  1.50k|            function.AugmentedStructuralCFGPredecessorsFunction(), ignore_block,
  976|  1.50k|            [&](const BasicBlock* b) { postdom_postorder.push_back(b); },
  977|  1.50k|            no_terminal_blocks);
  978|  1.50k|        auto postdom_edges = CFA<BasicBlock>::CalculateDominators(
  979|  1.50k|            postdom_postorder,
  980|  1.50k|            function.AugmentedStructuralCFGSuccessorsFunction());
  981|  37.4k|        for (auto edge : postdom_edges) {
  ------------------
  |  Branch (981:24): [True: 37.4k, False: 1.50k]
  ------------------
  982|  37.4k|          edge.first->SetImmediateStructuralPostDominator(edge.second);
  983|  37.4k|        }
  984|       |        /// calculate back edges.
  985|  1.50k|        CFA<BasicBlock>::DepthFirstTraversal(
  986|  1.50k|            function.pseudo_entry_block(),
  987|  1.50k|            function.AugmentedStructuralCFGSuccessorsFunction(), ignore_block,
  988|  1.50k|            ignore_block,
  989|  1.50k|            [&](const BasicBlock* from, const BasicBlock* to) {
  990|       |              // A back edge must be a real edge. Since the augmented successors
  991|       |              // contain structural edges, filter those from consideration.
  992|  1.50k|              for (const auto* succ : *(from->successors())) {
  993|  1.50k|                if (succ == to) back_edges.emplace_back(from->id(), to->id());
  994|  1.50k|              }
  995|  1.50k|            },
  996|  1.50k|            no_terminal_blocks);
  997|  1.50k|      }
  998|  1.77k|      UpdateContinueConstructExitBlocks(function, back_edges);
  999|       |
 1000|  1.77k|      if (auto error =
  ------------------
  |  Branch (1000:16): [True: 528, False: 1.24k]
  ------------------
 1001|  1.77k|              StructuredControlFlowChecks(_, &function, back_edges, postorder))
 1002|    528|        return error;
 1003|  1.77k|    }
 1004|  1.77k|  }
 1005|  1.07k|  return SPV_SUCCESS;
 1006|  1.63k|}
_ZN8spvtools3val7CfgPassERNS0_17ValidationState_tEPKNS0_11InstructionE:
 1008|   387k|spv_result_t CfgPass(ValidationState_t& _, const Instruction* inst) {
 1009|   387k|  spv::Op opcode = inst->opcode();
 1010|   387k|  switch (opcode) {
 1011|  50.8k|    case spv::Op::OpLabel:
  ------------------
  |  Branch (1011:5): [True: 50.8k, False: 337k]
  ------------------
 1012|  50.8k|      if (auto error = _.current_function().RegisterBlock(inst->id()))
  ------------------
  |  Branch (1012:16): [True: 0, False: 50.8k]
  ------------------
 1013|      0|        return error;
 1014|       |
 1015|       |      // TODO(github:1661) This should be done in the
 1016|       |      // ValidationState::RegisterInstruction method but because of the order of
 1017|       |      // passes the OpLabel ends up not being part of the basic block it starts.
 1018|  50.8k|      _.current_function().current_block()->set_label(inst);
 1019|  50.8k|      break;
 1020|  22.2k|    case spv::Op::OpLoopMerge: {
  ------------------
  |  Branch (1020:5): [True: 22.2k, False: 365k]
  ------------------
 1021|  22.2k|      uint32_t merge_block = inst->GetOperandAs<uint32_t>(0);
 1022|  22.2k|      uint32_t continue_block = inst->GetOperandAs<uint32_t>(1);
 1023|  22.2k|      CFG_ASSERT(MergeBlockAssert, merge_block);
  ------------------
  |  |  367|  22.2k|  if (spv_result_t rcode = ASSERT_FUNC(_, TARGET)) return rcode
  |  |  ------------------
  |  |  |  Branch (367:20): [True: 24, False: 22.1k]
  |  |  ------------------
  ------------------
 1024|       |
 1025|  22.1k|      if (auto error = _.current_function().RegisterLoopMerge(merge_block,
  ------------------
  |  Branch (1025:16): [True: 0, False: 22.1k]
  ------------------
 1026|  22.1k|                                                              continue_block))
 1027|      0|        return error;
 1028|  22.1k|    } break;
 1029|  22.1k|    case spv::Op::OpSelectionMerge: {
  ------------------
  |  Branch (1029:5): [True: 10.1k, False: 377k]
  ------------------
 1030|  10.1k|      uint32_t merge_block = inst->GetOperandAs<uint32_t>(0);
 1031|  10.1k|      CFG_ASSERT(MergeBlockAssert, merge_block);
  ------------------
  |  |  367|  10.1k|  if (spv_result_t rcode = ASSERT_FUNC(_, TARGET)) return rcode
  |  |  ------------------
  |  |  |  Branch (367:20): [True: 4, False: 10.1k]
  |  |  ------------------
  ------------------
 1032|       |
 1033|  10.1k|      if (auto error = _.current_function().RegisterSelectionMerge(merge_block))
  ------------------
  |  Branch (1033:16): [True: 0, False: 10.1k]
  ------------------
 1034|      0|        return error;
 1035|  10.1k|    } break;
 1036|  25.6k|    case spv::Op::OpBranch: {
  ------------------
  |  Branch (1036:5): [True: 25.6k, False: 362k]
  ------------------
 1037|  25.6k|      uint32_t target = inst->GetOperandAs<uint32_t>(0);
 1038|  25.6k|      CFG_ASSERT(FirstBlockAssert, target);
  ------------------
  |  |  367|  25.6k|  if (spv_result_t rcode = ASSERT_FUNC(_, TARGET)) return rcode
  |  |  ------------------
  |  |  |  Branch (367:20): [True: 3, False: 25.6k]
  |  |  ------------------
  ------------------
 1039|       |
 1040|  25.6k|      _.current_function().RegisterBlockEnd({target});
 1041|  25.6k|    } break;
 1042|  11.6k|    case spv::Op::OpBranchConditional: {
  ------------------
  |  Branch (1042:5): [True: 11.6k, False: 376k]
  ------------------
 1043|  11.6k|      uint32_t tlabel = inst->GetOperandAs<uint32_t>(1);
 1044|  11.6k|      uint32_t flabel = inst->GetOperandAs<uint32_t>(2);
 1045|  11.6k|      CFG_ASSERT(FirstBlockAssert, tlabel);
  ------------------
  |  |  367|  11.6k|  if (spv_result_t rcode = ASSERT_FUNC(_, TARGET)) return rcode
  |  |  ------------------
  |  |  |  Branch (367:20): [True: 0, False: 11.6k]
  |  |  ------------------
  ------------------
 1046|  11.6k|      CFG_ASSERT(FirstBlockAssert, flabel);
  ------------------
  |  |  367|  11.6k|  if (spv_result_t rcode = ASSERT_FUNC(_, TARGET)) return rcode
  |  |  ------------------
  |  |  |  Branch (367:20): [True: 1, False: 11.6k]
  |  |  ------------------
  ------------------
 1047|       |
 1048|  11.6k|      _.current_function().RegisterBlockEnd({tlabel, flabel});
 1049|  11.6k|    } break;
 1050|       |
 1051|  2.86k|    case spv::Op::OpSwitch: {
  ------------------
  |  Branch (1051:5): [True: 2.86k, False: 384k]
  ------------------
 1052|  2.86k|      std::vector<uint32_t> cases;
 1053|  24.6k|      for (size_t i = 1; i < inst->operands().size(); i += 2) {
  ------------------
  |  Branch (1053:26): [True: 21.7k, False: 2.86k]
  ------------------
 1054|  21.7k|        uint32_t target = inst->GetOperandAs<uint32_t>(i);
 1055|  21.7k|        CFG_ASSERT(FirstBlockAssert, target);
  ------------------
  |  |  367|  21.7k|  if (spv_result_t rcode = ASSERT_FUNC(_, TARGET)) return rcode
  |  |  ------------------
  |  |  |  Branch (367:20): [True: 1, False: 21.7k]
  |  |  ------------------
  ------------------
 1056|  21.7k|        cases.push_back(target);
 1057|  21.7k|      }
 1058|  2.86k|      _.current_function().RegisterBlockEnd({cases});
 1059|  2.86k|    } break;
 1060|  2.31k|    case spv::Op::OpReturn: {
  ------------------
  |  Branch (1060:5): [True: 2.31k, False: 385k]
  ------------------
 1061|  2.31k|      const uint32_t return_type = _.current_function().GetResultTypeId();
 1062|  2.31k|      const Instruction* return_type_inst = _.FindDef(return_type);
 1063|  2.31k|      assert(return_type_inst);
 1064|  2.31k|      if (return_type_inst->opcode() != spv::Op::OpTypeVoid)
  ------------------
  |  Branch (1064:11): [True: 1, False: 2.31k]
  ------------------
 1065|      1|        return _.diag(SPV_ERROR_INVALID_CFG, inst)
 1066|      1|               << "OpReturn can only be called from a function with void "
 1067|      1|               << "return type.";
 1068|  2.31k|      _.current_function().RegisterBlockEnd(std::vector<uint32_t>());
 1069|  2.31k|      break;
 1070|  2.31k|    }
 1071|  1.60k|    case spv::Op::OpKill:
  ------------------
  |  Branch (1071:5): [True: 1.60k, False: 386k]
  ------------------
 1072|  2.21k|    case spv::Op::OpReturnValue:
  ------------------
  |  Branch (1072:5): [True: 610, False: 387k]
  ------------------
 1073|  7.64k|    case spv::Op::OpUnreachable:
  ------------------
  |  Branch (1073:5): [True: 5.42k, False: 382k]
  ------------------
 1074|  7.64k|    case spv::Op::OpTerminateInvocation:
  ------------------
  |  Branch (1074:5): [True: 0, False: 387k]
  ------------------
 1075|  7.64k|    case spv::Op::OpIgnoreIntersectionKHR:
  ------------------
  |  Branch (1075:5): [True: 0, False: 387k]
  ------------------
 1076|  7.64k|    case spv::Op::OpTerminateRayKHR:
  ------------------
  |  Branch (1076:5): [True: 0, False: 387k]
  ------------------
 1077|  7.64k|    case spv::Op::OpEmitMeshTasksEXT:
  ------------------
  |  Branch (1077:5): [True: 0, False: 387k]
  ------------------
 1078|  7.64k|      _.current_function().RegisterBlockEnd(std::vector<uint32_t>());
 1079|       |      // Ops with dedicated passes check for the Execution Model there
 1080|  7.64k|      if (opcode == spv::Op::OpKill) {
  ------------------
  |  Branch (1080:11): [True: 1.60k, False: 6.03k]
  ------------------
 1081|  1.60k|        _.current_function().RegisterExecutionModelLimitation(
 1082|  1.60k|            spv::ExecutionModel::Fragment,
 1083|  1.60k|            "OpKill requires Fragment execution model");
 1084|  1.60k|      }
 1085|  7.64k|      if (opcode == spv::Op::OpTerminateInvocation) {
  ------------------
  |  Branch (1085:11): [True: 0, False: 7.64k]
  ------------------
 1086|      0|        _.current_function().RegisterExecutionModelLimitation(
 1087|      0|            spv::ExecutionModel::Fragment,
 1088|      0|            "OpTerminateInvocation requires Fragment execution model");
 1089|      0|      }
 1090|  7.64k|      if (opcode == spv::Op::OpIgnoreIntersectionKHR) {
  ------------------
  |  Branch (1090:11): [True: 0, False: 7.64k]
  ------------------
 1091|      0|        _.current_function().RegisterExecutionModelLimitation(
 1092|      0|            spv::ExecutionModel::AnyHitKHR,
 1093|      0|            "OpIgnoreIntersectionKHR requires AnyHitKHR execution model");
 1094|      0|      }
 1095|  7.64k|      if (opcode == spv::Op::OpTerminateRayKHR) {
  ------------------
  |  Branch (1095:11): [True: 0, False: 7.64k]
  ------------------
 1096|      0|        _.current_function().RegisterExecutionModelLimitation(
 1097|      0|            spv::ExecutionModel::AnyHitKHR,
 1098|      0|            "OpTerminateRayKHR requires AnyHitKHR execution model");
 1099|      0|      }
 1100|       |
 1101|  7.64k|      break;
 1102|   254k|    default:
  ------------------
  |  Branch (1102:5): [True: 254k, False: 133k]
  ------------------
 1103|   254k|      break;
 1104|   387k|  }
 1105|   387k|  return SPV_SUCCESS;
 1106|   387k|}
_ZN8spvtools3val16ReachabilityPassERNS0_17ValidationState_tE:
 1108|  3.67k|void ReachabilityPass(ValidationState_t& _) {
 1109|  3.67k|  for (auto& f : _.functions()) {
  ------------------
  |  Branch (1109:16): [True: 2.97k, False: 3.67k]
  ------------------
 1110|  2.97k|    std::vector<BasicBlock*> stack;
 1111|  2.97k|    auto entry = f.first_block();
 1112|       |    // Skip function declarations.
 1113|  2.97k|    if (entry) stack.push_back(entry);
  ------------------
  |  Branch (1113:9): [True: 2.60k, False: 369]
  ------------------
 1114|       |
 1115|  47.7k|    while (!stack.empty()) {
  ------------------
  |  Branch (1115:12): [True: 44.7k, False: 2.97k]
  ------------------
 1116|  44.7k|      auto block = stack.back();
 1117|  44.7k|      stack.pop_back();
 1118|       |
 1119|  44.7k|      if (block->reachable()) continue;
  ------------------
  |  Branch (1119:11): [True: 12.1k, False: 32.6k]
  ------------------
 1120|       |
 1121|  32.6k|      block->set_reachable(true);
 1122|  42.1k|      for (auto succ : *block->successors()) {
  ------------------
  |  Branch (1122:22): [True: 42.1k, False: 32.6k]
  ------------------
 1123|  42.1k|        stack.push_back(succ);
 1124|  42.1k|      }
 1125|  32.6k|    }
 1126|  2.97k|  }
 1127|       |
 1128|       |  // Repeat for structural reachability.
 1129|  3.67k|  for (auto& f : _.functions()) {
  ------------------
  |  Branch (1129:16): [True: 2.97k, False: 3.67k]
  ------------------
 1130|  2.97k|    std::vector<BasicBlock*> stack;
 1131|  2.97k|    auto entry = f.first_block();
 1132|       |    // Skip function declarations.
 1133|  2.97k|    if (entry) stack.push_back(entry);
  ------------------
  |  Branch (1133:9): [True: 2.60k, False: 369]
  ------------------
 1134|       |
 1135|  67.1k|    while (!stack.empty()) {
  ------------------
  |  Branch (1135:12): [True: 64.1k, False: 2.97k]
  ------------------
 1136|  64.1k|      auto block = stack.back();
 1137|  64.1k|      stack.pop_back();
 1138|       |
 1139|  64.1k|      if (block->structurally_reachable()) continue;
  ------------------
  |  Branch (1139:11): [True: 25.7k, False: 38.4k]
  ------------------
 1140|       |
 1141|  38.4k|      block->set_structurally_reachable(true);
 1142|  61.5k|      for (auto succ : *block->structural_successors()) {
  ------------------
  |  Branch (1142:22): [True: 61.5k, False: 38.4k]
  ------------------
 1143|  61.5k|        stack.push_back(succ);
 1144|  61.5k|      }
 1145|  38.4k|    }
 1146|  2.97k|  }
 1147|  3.67k|}
_ZN8spvtools3val15ControlFlowPassERNS0_17ValidationState_tEPKNS0_11InstructionE:
 1149|   285k|spv_result_t ControlFlowPass(ValidationState_t& _, const Instruction* inst) {
 1150|   285k|  switch (inst->opcode()) {
 1151|  6.78k|    case spv::Op::OpPhi:
  ------------------
  |  Branch (1151:5): [True: 6.78k, False: 278k]
  ------------------
 1152|  6.78k|      if (auto error = ValidatePhi(_, inst)) return error;
  ------------------
  |  Branch (1152:16): [True: 31, False: 6.74k]
  ------------------
 1153|  6.74k|      break;
 1154|  20.7k|    case spv::Op::OpBranch:
  ------------------
  |  Branch (1154:5): [True: 20.7k, False: 264k]
  ------------------
 1155|  20.7k|      if (auto error = ValidateBranch(_, inst)) return error;
  ------------------
  |  Branch (1155:16): [True: 9, False: 20.7k]
  ------------------
 1156|  20.7k|      break;
 1157|  20.7k|    case spv::Op::OpBranchConditional:
  ------------------
  |  Branch (1157:5): [True: 9.48k, False: 276k]
  ------------------
 1158|  9.48k|      if (auto error = ValidateBranchConditional(_, inst)) return error;
  ------------------
  |  Branch (1158:16): [True: 7, False: 9.48k]
  ------------------
 1159|  9.48k|      break;
 1160|  9.48k|    case spv::Op::OpReturnValue:
  ------------------
  |  Branch (1160:5): [True: 374, False: 285k]
  ------------------
 1161|    374|      if (auto error = ValidateReturnValue(_, inst)) return error;
  ------------------
  |  Branch (1161:16): [True: 5, False: 369]
  ------------------
 1162|    369|      break;
 1163|  2.23k|    case spv::Op::OpSwitch:
  ------------------
  |  Branch (1163:5): [True: 2.23k, False: 283k]
  ------------------
 1164|  2.23k|      if (auto error = ValidateSwitch(_, inst)) return error;
  ------------------
  |  Branch (1164:16): [True: 4, False: 2.22k]
  ------------------
 1165|  2.22k|      break;
 1166|  3.58k|    case spv::Op::OpLoopMerge:
  ------------------
  |  Branch (1166:5): [True: 3.58k, False: 281k]
  ------------------
 1167|  3.58k|      if (auto error = ValidateLoopMerge(_, inst)) return error;
  ------------------
  |  Branch (1167:16): [True: 12, False: 3.57k]
  ------------------
 1168|  3.57k|      break;
 1169|   242k|    default:
  ------------------
  |  Branch (1169:5): [True: 242k, False: 43.1k]
  ------------------
 1170|   242k|      break;
 1171|   285k|  }
 1172|       |
 1173|   285k|  return SPV_SUCCESS;
 1174|   285k|}
validate_cfg.cpp:_ZZN8spvtools3val33UpdateContinueConstructExitBlocksERNS0_8FunctionERKNSt3__16vectorINS3_4pairIjjEENS3_9allocatorIS6_EEEEENK3$_0clERNS0_9ConstructE:
  399|   170k|    auto is_this_header = [=](Construct& c) {
  400|   170k|      return c.type() == ConstructType::kLoop &&
  ------------------
  |  Branch (400:14): [True: 44.0k, False: 126k]
  ------------------
  401|   170k|             c.entry_block()->id() == loop_header_block_id;
  ------------------
  |  Branch (401:14): [True: 3.97k, False: 40.1k]
  ------------------
  402|   170k|    };
validate_cfg.cpp:_ZN8spvtools3val12_GLOBAL__N_111ValidatePhiERNS0_17ValidationState_tEPKNS0_11InstructionE:
   43|  6.78k|spv_result_t ValidatePhi(ValidationState_t& _, const Instruction* inst) {
   44|  6.78k|  auto block = inst->block();
   45|  6.78k|  size_t num_in_ops = inst->words().size() - 3;
   46|  6.78k|  if (num_in_ops % 2 != 0) {
  ------------------
  |  Branch (46:7): [True: 0, False: 6.78k]
  ------------------
   47|      0|    return _.diag(SPV_ERROR_INVALID_ID, inst)
   48|      0|           << "OpPhi does not have an equal number of incoming values and "
   49|      0|              "basic blocks.";
   50|      0|  }
   51|       |
   52|  6.78k|  if (_.IsVoidType(inst->type_id())) {
  ------------------
  |  Branch (52:7): [True: 0, False: 6.78k]
  ------------------
   53|      0|    return _.diag(SPV_ERROR_INVALID_DATA, inst)
   54|      0|           << "OpPhi must not have void result type";
   55|      0|  }
   56|  6.78k|  if (_.IsPointerType(inst->type_id()) &&
  ------------------
  |  Branch (56:7): [True: 0, False: 6.78k]
  ------------------
   57|  6.78k|      _.addressing_model() == spv::AddressingModel::Logical) {
  ------------------
  |  Branch (57:7): [True: 0, False: 0]
  ------------------
   58|      0|    if (!_.features().variable_pointers) {
  ------------------
  |  Branch (58:9): [True: 0, False: 0]
  ------------------
   59|      0|      return _.diag(SPV_ERROR_INVALID_DATA, inst)
   60|      0|             << "Using pointers with OpPhi requires capability "
   61|      0|             << "VariablePointers or VariablePointersStorageBuffer";
   62|      0|    }
   63|      0|  }
   64|       |
   65|  6.78k|  const Instruction* type_inst = _.FindDef(inst->type_id());
   66|  6.78k|  assert(type_inst);
   67|      0|  const spv::Op type_opcode = type_inst->opcode();
   68|       |
   69|  6.78k|  if (!_.options()->before_hlsl_legalization &&
  ------------------
  |  Branch (69:7): [True: 6.78k, False: 0]
  ------------------
   70|  6.78k|      !_.HasCapability(spv::Capability::BindlessTextureNV)) {
  ------------------
  |  Branch (70:7): [True: 6.78k, False: 0]
  ------------------
   71|  6.78k|    if (type_opcode == spv::Op::OpTypeSampledImage ||
  ------------------
  |  Branch (71:9): [True: 0, False: 6.78k]
  ------------------
   72|  6.78k|        (_.HasCapability(spv::Capability::Shader) &&
  ------------------
  |  Branch (72:10): [True: 6.77k, False: 9]
  ------------------
   73|  6.78k|         (type_opcode == spv::Op::OpTypeImage ||
  ------------------
  |  Branch (73:11): [True: 0, False: 6.77k]
  ------------------
   74|  6.77k|          type_opcode == spv::Op::OpTypeSampler))) {
  ------------------
  |  Branch (74:11): [True: 0, False: 6.77k]
  ------------------
   75|      0|      return _.diag(SPV_ERROR_INVALID_ID, inst)
   76|      0|             << "Result type cannot be Op" << spvOpcodeString(type_opcode);
   77|      0|    }
   78|  6.78k|  }
   79|       |
   80|       |  // Create a uniqued vector of predecessor ids for comparison against
   81|       |  // incoming values. OpBranchConditional %cond %label %label produces two
   82|       |  // predecessors in the CFG.
   83|  6.78k|  std::vector<uint32_t> pred_ids;
   84|  6.78k|  std::transform(block->predecessors()->begin(), block->predecessors()->end(),
   85|  6.78k|                 std::back_inserter(pred_ids),
   86|  6.78k|                 [](const BasicBlock* b) { return b->id(); });
   87|  6.78k|  std::sort(pred_ids.begin(), pred_ids.end());
   88|  6.78k|  pred_ids.erase(std::unique(pred_ids.begin(), pred_ids.end()), pred_ids.end());
   89|       |
   90|  6.78k|  size_t num_edges = num_in_ops / 2;
   91|  6.78k|  if (num_edges != pred_ids.size()) {
  ------------------
  |  Branch (91:7): [True: 4, False: 6.77k]
  ------------------
   92|      4|    return _.diag(SPV_ERROR_INVALID_ID, inst)
   93|      4|           << "OpPhi's number of incoming blocks (" << num_edges
   94|      4|           << ") does not match block's predecessor count ("
   95|      4|           << block->predecessors()->size() << ").";
   96|      4|  }
   97|       |
   98|  6.77k|  std::unordered_set<uint32_t> observed_predecessors;
   99|       |
  100|  36.0k|  for (size_t i = 3; i < inst->words().size(); ++i) {
  ------------------
  |  Branch (100:22): [True: 29.3k, False: 6.74k]
  ------------------
  101|  29.3k|    auto inc_id = inst->word(i);
  102|  29.3k|    if (i % 2 == 1) {
  ------------------
  |  Branch (102:9): [True: 14.6k, False: 14.6k]
  ------------------
  103|       |      // Incoming value type must match the phi result type.
  104|  14.6k|      auto inc_type_id = _.GetTypeId(inc_id);
  105|  14.6k|      if (inst->type_id() != inc_type_id) {
  ------------------
  |  Branch (105:11): [True: 9, False: 14.6k]
  ------------------
  106|      9|        return _.diag(SPV_ERROR_INVALID_ID, inst)
  107|      9|               << "OpPhi's result type <id> " << _.getIdName(inst->type_id())
  108|      9|               << " does not match incoming value <id> " << _.getIdName(inc_id)
  109|      9|               << " type <id> " << _.getIdName(inc_type_id) << ".";
  110|      9|      }
  111|  14.6k|    } else {
  112|  14.6k|      if (_.GetIdOpcode(inc_id) != spv::Op::OpLabel) {
  ------------------
  |  Branch (112:11): [True: 9, False: 14.6k]
  ------------------
  113|      9|        return _.diag(SPV_ERROR_INVALID_ID, inst)
  114|      9|               << "OpPhi's incoming basic block <id> " << _.getIdName(inc_id)
  115|      9|               << " is not an OpLabel.";
  116|      9|      }
  117|       |
  118|       |      // Incoming basic block must be an immediate predecessor of the phi's
  119|       |      // block.
  120|  14.6k|      if (!std::binary_search(pred_ids.begin(), pred_ids.end(), inc_id)) {
  ------------------
  |  Branch (120:11): [True: 6, False: 14.6k]
  ------------------
  121|      6|        return _.diag(SPV_ERROR_INVALID_ID, inst)
  122|      6|               << "OpPhi's incoming basic block <id> " << _.getIdName(inc_id)
  123|      6|               << " is not a predecessor of <id> " << _.getIdName(block->id())
  124|      6|               << ".";
  125|      6|      }
  126|       |
  127|       |      // We must not have already seen this predecessor as one of the phi's
  128|       |      // operands.
  129|  14.6k|      if (observed_predecessors.count(inc_id) != 0) {
  ------------------
  |  Branch (129:11): [True: 3, False: 14.6k]
  ------------------
  130|      3|        return _.diag(SPV_ERROR_INVALID_ID, inst)
  131|      3|               << "OpPhi references incoming basic block <id> "
  132|      3|               << _.getIdName(inc_id) << " multiple times.";
  133|      3|      }
  134|       |
  135|       |      // Note the fact that we have now observed this predecessor.
  136|  14.6k|      observed_predecessors.insert(inc_id);
  137|  14.6k|    }
  138|  29.3k|  }
  139|       |
  140|  6.74k|  return SPV_SUCCESS;
  141|  6.77k|}
validate_cfg.cpp:_ZZN8spvtools3val12_GLOBAL__N_111ValidatePhiERNS0_17ValidationState_tEPKNS0_11InstructionEENK3$_7clEPKNS0_10BasicBlockE:
   86|  14.7k|                 [](const BasicBlock* b) { return b->id(); });
validate_cfg.cpp:_ZN8spvtools3val12_GLOBAL__N_114ValidateBranchERNS0_17ValidationState_tEPKNS0_11InstructionE:
  143|  20.7k|spv_result_t ValidateBranch(ValidationState_t& _, const Instruction* inst) {
  144|       |  // target operands must be OpLabel
  145|  20.7k|  const auto id = inst->GetOperandAs<uint32_t>(0);
  146|  20.7k|  const auto target = _.FindDef(id);
  147|  20.7k|  if (!target || spv::Op::OpLabel != target->opcode()) {
  ------------------
  |  Branch (147:7): [True: 0, False: 20.7k]
  |  Branch (147:18): [True: 9, False: 20.7k]
  ------------------
  148|      9|    return _.diag(SPV_ERROR_INVALID_ID, inst)
  149|      9|           << "'Target Label' operands for OpBranch must be the ID "
  150|      9|              "of an OpLabel instruction";
  151|      9|  }
  152|       |
  153|  20.7k|  return SPV_SUCCESS;
  154|  20.7k|}
validate_cfg.cpp:_ZN8spvtools3val12_GLOBAL__N_125ValidateBranchConditionalERNS0_17ValidationState_tEPKNS0_11InstructionE:
  157|  9.48k|                                       const Instruction* inst) {
  158|       |  // num_operands is either 3 or 5 --- if 5, the last two need to be literal
  159|       |  // integers
  160|  9.48k|  const auto num_operands = inst->operands().size();
  161|  9.48k|  if (num_operands != 3 && num_operands != 5) {
  ------------------
  |  Branch (161:7): [True: 1, False: 9.48k]
  |  Branch (161:28): [True: 1, False: 0]
  ------------------
  162|      1|    return _.diag(SPV_ERROR_INVALID_ID, inst)
  163|      1|           << "OpBranchConditional requires either 3 or 5 parameters";
  164|      1|  }
  165|       |
  166|       |  // grab the condition operand and check that it is a bool
  167|  9.48k|  const auto cond_id = inst->GetOperandAs<uint32_t>(0);
  168|  9.48k|  const auto cond_op = _.FindDef(cond_id);
  169|  9.48k|  if (!cond_op || !cond_op->type_id() ||
  ------------------
  |  Branch (169:7): [True: 0, False: 9.48k]
  |  Branch (169:19): [True: 1, False: 9.48k]
  ------------------
  170|  9.48k|      !_.IsBoolScalarType(cond_op->type_id())) {
  ------------------
  |  Branch (170:7): [True: 2, False: 9.48k]
  ------------------
  171|      3|    return _.diag(SPV_ERROR_INVALID_ID, inst) << "Condition operand for "
  172|      3|                                                 "OpBranchConditional must be "
  173|      3|                                                 "of boolean type";
  174|      3|  }
  175|       |
  176|       |  // target operands must be OpLabel
  177|       |  // note that we don't need to check that the target labels are in the same
  178|       |  // function,
  179|       |  // PerformCfgChecks already checks for that
  180|  9.48k|  const auto true_id = inst->GetOperandAs<uint32_t>(1);
  181|  9.48k|  const auto true_target = _.FindDef(true_id);
  182|  9.48k|  if (!true_target || spv::Op::OpLabel != true_target->opcode()) {
  ------------------
  |  Branch (182:7): [True: 0, False: 9.48k]
  |  Branch (182:23): [True: 2, False: 9.48k]
  ------------------
  183|      2|    return _.diag(SPV_ERROR_INVALID_ID, inst)
  184|      2|           << "The 'True Label' operand for OpBranchConditional must be the "
  185|      2|              "ID of an OpLabel instruction";
  186|      2|  }
  187|       |
  188|  9.48k|  const auto false_id = inst->GetOperandAs<uint32_t>(2);
  189|  9.48k|  const auto false_target = _.FindDef(false_id);
  190|  9.48k|  if (!false_target || spv::Op::OpLabel != false_target->opcode()) {
  ------------------
  |  Branch (190:7): [True: 0, False: 9.48k]
  |  Branch (190:24): [True: 1, False: 9.48k]
  ------------------
  191|      1|    return _.diag(SPV_ERROR_INVALID_ID, inst)
  192|      1|           << "The 'False Label' operand for OpBranchConditional must be the "
  193|      1|              "ID of an OpLabel instruction";
  194|      1|  }
  195|       |
  196|  9.48k|  if (_.version() >= SPV_SPIRV_VERSION_WORD(1, 6) && true_id == false_id) {
  ------------------
  |  |   26|  18.9k|  ((uint32_t(uint8_t(MAJOR)) << 16) | (uint32_t(uint8_t(MINOR)) << 8))
  ------------------
  |  Branch (196:7): [True: 0, False: 9.48k]
  |  Branch (196:54): [True: 0, False: 0]
  ------------------
  197|      0|    return _.diag(SPV_ERROR_INVALID_ID, inst)
  198|      0|           << "In SPIR-V 1.6 or later, True Label and False Label must be "
  199|      0|              "different labels";
  200|      0|  }
  201|       |
  202|  9.48k|  return SPV_SUCCESS;
  203|  9.48k|}
validate_cfg.cpp:_ZN8spvtools3val12_GLOBAL__N_119ValidateReturnValueERNS0_17ValidationState_tEPKNS0_11InstructionE:
  238|    374|                                 const Instruction* inst) {
  239|    374|  const auto value_id = inst->GetOperandAs<uint32_t>(0);
  240|    374|  const auto value = _.FindDef(value_id);
  241|    374|  if (!value || !value->type_id()) {
  ------------------
  |  Branch (241:7): [True: 0, False: 374]
  |  Branch (241:17): [True: 0, False: 374]
  ------------------
  242|      0|    return _.diag(SPV_ERROR_INVALID_ID, inst)
  243|      0|           << "OpReturnValue Value <id> " << _.getIdName(value_id)
  244|      0|           << " does not represent a value.";
  245|      0|  }
  246|    374|  auto value_type = _.FindDef(value->type_id());
  247|    374|  if (!value_type || spv::Op::OpTypeVoid == value_type->opcode()) {
  ------------------
  |  Branch (247:7): [True: 0, False: 374]
  |  Branch (247:22): [True: 1, False: 373]
  ------------------
  248|      1|    return _.diag(SPV_ERROR_INVALID_ID, inst)
  249|      1|           << "OpReturnValue value's type <id> "
  250|      1|           << _.getIdName(value->type_id()) << " is missing or void.";
  251|      1|  }
  252|       |
  253|    373|  if (_.addressing_model() == spv::AddressingModel::Logical &&
  ------------------
  |  Branch (253:7): [True: 373, False: 0]
  ------------------
  254|    373|      spv::Op::OpTypePointer == value_type->opcode() &&
  ------------------
  |  Branch (254:7): [True: 0, False: 373]
  ------------------
  255|    373|      !_.features().variable_pointers && !_.options()->relax_logical_pointer) {
  ------------------
  |  Branch (255:7): [True: 0, False: 0]
  |  Branch (255:42): [True: 0, False: 0]
  ------------------
  256|      0|    return _.diag(SPV_ERROR_INVALID_ID, inst)
  257|      0|           << "OpReturnValue value's type <id> "
  258|      0|           << _.getIdName(value->type_id())
  259|      0|           << " is a pointer, which is invalid in the Logical addressing "
  260|      0|              "model.";
  261|      0|  }
  262|       |
  263|    373|  const auto function = inst->function();
  264|    373|  const auto return_type = _.FindDef(function->GetResultTypeId());
  265|    373|  if (!return_type || return_type->id() != value_type->id()) {
  ------------------
  |  Branch (265:7): [True: 0, False: 373]
  |  Branch (265:23): [True: 4, False: 369]
  ------------------
  266|      4|    return _.diag(SPV_ERROR_INVALID_ID, inst)
  267|      4|           << "OpReturnValue Value <id> " << _.getIdName(value_id)
  268|      4|           << "s type does not match OpFunction's return type.";
  269|      4|  }
  270|       |
  271|    369|  return SPV_SUCCESS;
  272|    373|}
validate_cfg.cpp:_ZN8spvtools3val12_GLOBAL__N_114ValidateSwitchERNS0_17ValidationState_tEPKNS0_11InstructionE:
  205|  2.23k|spv_result_t ValidateSwitch(ValidationState_t& _, const Instruction* inst) {
  206|  2.23k|  const auto num_operands = inst->operands().size();
  207|       |  // At least two operands (selector, default), any more than that are
  208|       |  // literal/target.
  209|       |
  210|  2.23k|  const auto sel_type_id = _.GetOperandTypeId(inst, 0);
  211|  2.23k|  if (!_.IsIntScalarType(sel_type_id)) {
  ------------------
  |  Branch (211:7): [True: 2, False: 2.23k]
  ------------------
  212|      2|    return _.diag(SPV_ERROR_INVALID_ID, inst)
  213|      2|           << "Selector type must be OpTypeInt";
  214|      2|  }
  215|       |
  216|  2.23k|  const auto default_label = _.FindDef(inst->GetOperandAs<uint32_t>(1));
  217|  2.23k|  if (default_label->opcode() != spv::Op::OpLabel) {
  ------------------
  |  Branch (217:7): [True: 2, False: 2.22k]
  ------------------
  218|      2|    return _.diag(SPV_ERROR_INVALID_ID, inst)
  219|      2|           << "Default must be an OpLabel instruction";
  220|      2|  }
  221|       |
  222|       |  // target operands must be OpLabel
  223|  5.95k|  for (size_t i = 2; i < num_operands; i += 2) {
  ------------------
  |  Branch (223:22): [True: 3.73k, False: 2.22k]
  ------------------
  224|       |    // literal, id
  225|  3.73k|    const auto id = inst->GetOperandAs<uint32_t>(i + 1);
  226|  3.73k|    const auto target = _.FindDef(id);
  227|  3.73k|    if (!target || spv::Op::OpLabel != target->opcode()) {
  ------------------
  |  Branch (227:9): [True: 0, False: 3.73k]
  |  Branch (227:20): [True: 0, False: 3.73k]
  ------------------
  228|      0|      return _.diag(SPV_ERROR_INVALID_ID, inst)
  229|      0|             << "'Target Label' operands for OpSwitch must be IDs of an "
  230|      0|                "OpLabel instruction";
  231|      0|    }
  232|  3.73k|  }
  233|       |
  234|  2.22k|  return SPV_SUCCESS;
  235|  2.22k|}
validate_cfg.cpp:_ZN8spvtools3val12_GLOBAL__N_117ValidateLoopMergeERNS0_17ValidationState_tEPKNS0_11InstructionE:
  279|  3.58k|spv_result_t ValidateLoopMerge(ValidationState_t& _, const Instruction* inst) {
  280|  3.58k|  const auto merge_id = inst->GetOperandAs<uint32_t>(0);
  281|  3.58k|  const auto merge = _.FindDef(merge_id);
  282|  3.58k|  if (!merge || merge->opcode() != spv::Op::OpLabel) {
  ------------------
  |  Branch (282:7): [True: 0, False: 3.58k]
  |  Branch (282:17): [True: 5, False: 3.58k]
  ------------------
  283|      5|    return _.diag(SPV_ERROR_INVALID_ID, inst)
  284|      5|           << "Merge Block " << _.getIdName(merge_id) << " must be an OpLabel";
  285|      5|  }
  286|  3.58k|  if (merge_id == inst->block()->id()) {
  ------------------
  |  Branch (286:7): [True: 2, False: 3.58k]
  ------------------
  287|      2|    return _.diag(SPV_ERROR_INVALID_ID, inst)
  288|      2|           << "Merge Block may not be the block containing the OpLoopMerge\n";
  289|      2|  }
  290|       |
  291|  3.58k|  const auto continue_id = inst->GetOperandAs<uint32_t>(1);
  292|  3.58k|  const auto continue_target = _.FindDef(continue_id);
  293|  3.58k|  if (!continue_target || continue_target->opcode() != spv::Op::OpLabel) {
  ------------------
  |  Branch (293:7): [True: 0, False: 3.58k]
  |  Branch (293:27): [True: 2, False: 3.57k]
  ------------------
  294|      2|    return _.diag(SPV_ERROR_INVALID_ID, inst)
  295|      2|           << "Continue Target " << _.getIdName(continue_id)
  296|      2|           << " must be an OpLabel";
  297|      2|  }
  298|       |
  299|  3.57k|  if (merge_id == continue_id) {
  ------------------
  |  Branch (299:7): [True: 2, False: 3.57k]
  ------------------
  300|      2|    return _.diag(SPV_ERROR_INVALID_ID, inst)
  301|      2|           << "Merge Block and Continue Target must be different ids";
  302|      2|  }
  303|       |
  304|  3.57k|  const auto loop_control = inst->GetOperandAs<spv::LoopControlShift>(2);
  305|  3.57k|  if ((loop_control >> spv::LoopControlShift::Unroll) & 0x1 &&
  ------------------
  |  Branch (305:7): [True: 212, False: 3.36k]
  |  Branch (305:7): [True: 1, False: 3.57k]
  ------------------
  306|  3.57k|      (loop_control >> spv::LoopControlShift::DontUnroll) & 0x1) {
  ------------------
  |  Branch (306:7): [True: 1, False: 211]
  ------------------
  307|      1|    return _.diag(SPV_ERROR_INVALID_DATA, inst)
  308|      1|           << "Unroll and DontUnroll loop controls must not both be specified";
  309|      1|  }
  310|  3.57k|  if ((loop_control >> spv::LoopControlShift::DontUnroll) & 0x1 &&
  ------------------
  |  Branch (310:7): [True: 185, False: 3.39k]
  |  Branch (310:7): [True: 0, False: 3.57k]
  ------------------
  311|  3.57k|      (loop_control >> spv::LoopControlShift::PeelCount) & 0x1) {
  ------------------
  |  Branch (311:7): [True: 0, False: 185]
  ------------------
  312|      0|    return _.diag(SPV_ERROR_INVALID_DATA, inst) << "PeelCount and DontUnroll "
  313|      0|                                                   "loop controls must not "
  314|      0|                                                   "both be specified";
  315|      0|  }
  316|  3.57k|  if ((loop_control >> spv::LoopControlShift::DontUnroll) & 0x1 &&
  ------------------
  |  Branch (316:7): [True: 185, False: 3.39k]
  |  Branch (316:7): [True: 0, False: 3.57k]
  ------------------
  317|  3.57k|      (loop_control >> spv::LoopControlShift::PartialCount) & 0x1) {
  ------------------
  |  Branch (317:7): [True: 0, False: 185]
  ------------------
  318|      0|    return _.diag(SPV_ERROR_INVALID_DATA, inst) << "PartialCount and "
  319|      0|                                                   "DontUnroll loop controls "
  320|      0|                                                   "must not both be specified";
  321|      0|  }
  322|       |
  323|  3.57k|  uint32_t operand = 3;
  324|  3.57k|  if ((loop_control >> spv::LoopControlShift::DependencyLength) & 0x1) {
  ------------------
  |  Branch (324:7): [True: 0, False: 3.57k]
  ------------------
  325|      0|    ++operand;
  326|      0|  }
  327|  3.57k|  if ((loop_control >> spv::LoopControlShift::MinIterations) & 0x1) {
  ------------------
  |  Branch (327:7): [True: 0, False: 3.57k]
  ------------------
  328|      0|    ++operand;
  329|      0|  }
  330|  3.57k|  if ((loop_control >> spv::LoopControlShift::MaxIterations) & 0x1) {
  ------------------
  |  Branch (330:7): [True: 0, False: 3.57k]
  ------------------
  331|      0|    ++operand;
  332|      0|  }
  333|  3.57k|  if ((loop_control >> spv::LoopControlShift::IterationMultiple) & 0x1) {
  ------------------
  |  Branch (333:7): [True: 0, False: 3.57k]
  ------------------
  334|      0|    if (inst->operands().size() < operand ||
  ------------------
  |  Branch (334:9): [True: 0, False: 0]
  ------------------
  335|      0|        inst->GetOperandAs<uint32_t>(operand) == 0) {
  ------------------
  |  Branch (335:9): [True: 0, False: 0]
  ------------------
  336|      0|      return _.diag(SPV_ERROR_INVALID_DATA, inst) << "IterationMultiple loop "
  337|      0|                                                     "control operand must be "
  338|      0|                                                     "greater than zero";
  339|      0|    }
  340|      0|    ++operand;
  341|      0|  }
  342|  3.57k|  if ((loop_control >> spv::LoopControlShift::PeelCount) & 0x1) {
  ------------------
  |  Branch (342:7): [True: 0, False: 3.57k]
  ------------------
  343|      0|    ++operand;
  344|      0|  }
  345|  3.57k|  if ((loop_control >> spv::LoopControlShift::PartialCount) & 0x1) {
  ------------------
  |  Branch (345:7): [True: 0, False: 3.57k]
  ------------------
  346|      0|    ++operand;
  347|      0|  }
  348|       |
  349|       |  // That the right number of operands is present is checked by the parser. The
  350|       |  // above code tracks operands for expanded validation checking in the future.
  351|       |
  352|  3.57k|  return SPV_SUCCESS;
  353|  3.57k|}
validate_cfg.cpp:_ZN8spvtools3val12_GLOBAL__N_1rsERKN3spv16LoopControlShiftES5_:
  275|  32.7k|                    const spv::LoopControlShift& rhs) {
  276|  32.7k|  return uint32_t(lhs) >> uint32_t(rhs);
  277|  32.7k|}
validate_cfg.cpp:_ZZN8spvtools3val16PerformCfgChecksERNS0_17ValidationState_tEENK3$_1clEPKNS0_10BasicBlockE:
  906|   171k|    auto ignore_block = [](const BasicBlock*) {};
validate_cfg.cpp:_ZZN8spvtools3val16PerformCfgChecksERNS0_17ValidationState_tEENK3$_3clEPKNS0_10BasicBlockE:
  912|  27.7k|          ignore_block, [&](const BasicBlock* b) { postorder.push_back(b); },
validate_cfg.cpp:_ZZN8spvtools3val16PerformCfgChecksERNS0_17ValidationState_tEENK3$_2clEPKNS0_10BasicBlockE:
  907|   352k|    auto no_terminal_blocks = [](const BasicBlock*) { return false; };
validate_cfg.cpp:_ZZN8spvtools3val16PerformCfgChecksERNS0_17ValidationState_tEENK3$_4clEPKNS0_10BasicBlockE:
  963|  31.5k|            [&](const BasicBlock* b) { postorder.push_back(b); },
validate_cfg.cpp:_ZZN8spvtools3val16PerformCfgChecksERNS0_17ValidationState_tEENK3$_5clEPKNS0_10BasicBlockE:
  976|  37.4k|            [&](const BasicBlock* b) { postdom_postorder.push_back(b); },
validate_cfg.cpp:_ZZN8spvtools3val16PerformCfgChecksERNS0_17ValidationState_tEENK3$_6clEPKNS0_10BasicBlockES6_:
  989|  4.17k|            [&](const BasicBlock* from, const BasicBlock* to) {
  990|       |              // A back edge must be a real edge. Since the augmented successors
  991|       |              // contain structural edges, filter those from consideration.
  992|  8.79k|              for (const auto* succ : *(from->successors())) {
  ------------------
  |  Branch (992:37): [True: 8.79k, False: 4.17k]
  ------------------
  993|  8.79k|                if (succ == to) back_edges.emplace_back(from->id(), to->id());
  ------------------
  |  Branch (993:21): [True: 5.20k, False: 3.58k]
  ------------------
  994|  8.79k|              }
  995|  4.17k|            },

_ZN8spvtools3val14CompositesPassERNS0_17ValidationState_tEPKNS0_11InstructionE:
  589|   285k|spv_result_t CompositesPass(ValidationState_t& _, const Instruction* inst) {
  590|   285k|  switch (inst->opcode()) {
  591|      3|    case spv::Op::OpVectorExtractDynamic:
  ------------------
  |  Branch (591:5): [True: 3, False: 285k]
  ------------------
  592|      3|      return ValidateVectorExtractDynamic(_, inst);
  593|      2|    case spv::Op::OpVectorInsertDynamic:
  ------------------
  |  Branch (593:5): [True: 2, False: 285k]
  ------------------
  594|      2|      return ValidateVectorInsertDyanmic(_, inst);
  595|    525|    case spv::Op::OpVectorShuffle:
  ------------------
  |  Branch (595:5): [True: 525, False: 285k]
  ------------------
  596|    525|      return ValidateVectorShuffle(_, inst);
  597|  1.32k|    case spv::Op::OpCompositeConstruct:
  ------------------
  |  Branch (597:5): [True: 1.32k, False: 284k]
  ------------------
  598|  1.32k|      return ValidateCompositeConstruct(_, inst);
  599|  2.35k|    case spv::Op::OpCompositeExtract:
  ------------------
  |  Branch (599:5): [True: 2.35k, False: 283k]
  ------------------
  600|  2.35k|      return ValidateCompositeExtract(_, inst);
  601|    178|    case spv::Op::OpCompositeInsert:
  ------------------
  |  Branch (601:5): [True: 178, False: 285k]
  ------------------
  602|    178|      return ValidateCompositeInsert(_, inst);
  603|     80|    case spv::Op::OpCopyObject:
  ------------------
  |  Branch (603:5): [True: 80, False: 285k]
  ------------------
  604|     80|      return ValidateCopyObject(_, inst);
  605|     17|    case spv::Op::OpTranspose:
  ------------------
  |  Branch (605:5): [True: 17, False: 285k]
  ------------------
  606|     17|      return ValidateTranspose(_, inst);
  607|      0|    case spv::Op::OpCopyLogical:
  ------------------
  |  Branch (607:5): [True: 0, False: 285k]
  ------------------
  608|      0|      return ValidateCopyLogical(_, inst);
  609|   281k|    default:
  ------------------
  |  Branch (609:5): [True: 281k, False: 4.47k]
  ------------------
  610|   281k|      break;
  611|   285k|  }
  612|       |
  613|   281k|  return SPV_SUCCESS;
  614|   285k|}
validate_composites.cpp:_ZN8spvtools3val12_GLOBAL__N_128ValidateVectorExtractDynamicERNS0_17ValidationState_tEPKNS0_11InstructionE:
  142|      3|                                          const Instruction* inst) {
  143|      3|  const uint32_t result_type = inst->type_id();
  144|      3|  const spv::Op result_opcode = _.GetIdOpcode(result_type);
  145|      3|  if (!spvOpcodeIsScalarType(result_opcode)) {
  ------------------
  |  Branch (145:7): [True: 0, False: 3]
  ------------------
  146|      0|    return _.diag(SPV_ERROR_INVALID_DATA, inst)
  147|      0|           << "Expected Result Type to be a scalar type";
  148|      0|  }
  149|       |
  150|      3|  const uint32_t vector_type = _.GetOperandTypeId(inst, 2);
  151|      3|  const spv::Op vector_opcode = _.GetIdOpcode(vector_type);
  152|      3|  if (vector_opcode != spv::Op::OpTypeVector) {
  ------------------
  |  Branch (152:7): [True: 0, False: 3]
  ------------------
  153|      0|    return _.diag(SPV_ERROR_INVALID_DATA, inst)
  154|      0|           << "Expected Vector type to be OpTypeVector";
  155|      0|  }
  156|       |
  157|      3|  if (_.GetComponentType(vector_type) != result_type) {
  ------------------
  |  Branch (157:7): [True: 1, False: 2]
  ------------------
  158|      1|    return _.diag(SPV_ERROR_INVALID_DATA, inst)
  159|      1|           << "Expected Vector component type to be equal to Result Type";
  160|      1|  }
  161|       |
  162|      2|  const auto index = _.FindDef(inst->GetOperandAs<uint32_t>(3));
  163|      2|  if (!index || index->type_id() == 0 || !_.IsIntScalarType(index->type_id())) {
  ------------------
  |  Branch (163:7): [True: 0, False: 2]
  |  Branch (163:17): [True: 0, False: 2]
  |  Branch (163:42): [True: 1, False: 1]
  ------------------
  164|      1|    return _.diag(SPV_ERROR_INVALID_DATA, inst)
  165|      1|           << "Expected Index to be int scalar";
  166|      1|  }
  167|       |
  168|      1|  if (_.HasCapability(spv::Capability::Shader) &&
  ------------------
  |  Branch (168:7): [True: 1, False: 0]
  ------------------
  169|      1|      _.ContainsLimitedUseIntOrFloatType(inst->type_id())) {
  ------------------
  |  Branch (169:7): [True: 0, False: 1]
  ------------------
  170|      0|    return _.diag(SPV_ERROR_INVALID_DATA, inst)
  171|      0|           << "Cannot extract from a vector of 8- or 16-bit types";
  172|      0|  }
  173|      1|  return SPV_SUCCESS;
  174|      1|}
validate_composites.cpp:_ZN8spvtools3val12_GLOBAL__N_127ValidateVectorInsertDyanmicERNS0_17ValidationState_tEPKNS0_11InstructionE:
  177|      2|                                         const Instruction* inst) {
  178|      2|  const uint32_t result_type = inst->type_id();
  179|      2|  const spv::Op result_opcode = _.GetIdOpcode(result_type);
  180|      2|  if (result_opcode != spv::Op::OpTypeVector) {
  ------------------
  |  Branch (180:7): [True: 0, False: 2]
  ------------------
  181|      0|    return _.diag(SPV_ERROR_INVALID_DATA, inst)
  182|      0|           << "Expected Result Type to be OpTypeVector";
  183|      0|  }
  184|       |
  185|      2|  const uint32_t vector_type = _.GetOperandTypeId(inst, 2);
  186|      2|  if (vector_type != result_type) {
  ------------------
  |  Branch (186:7): [True: 1, False: 1]
  ------------------
  187|      1|    return _.diag(SPV_ERROR_INVALID_DATA, inst)
  188|      1|           << "Expected Vector type to be equal to Result Type";
  189|      1|  }
  190|       |
  191|      1|  const uint32_t component_type = _.GetOperandTypeId(inst, 3);
  192|      1|  if (_.GetComponentType(result_type) != component_type) {
  ------------------
  |  Branch (192:7): [True: 0, False: 1]
  ------------------
  193|      0|    return _.diag(SPV_ERROR_INVALID_DATA, inst)
  194|      0|           << "Expected Component type to be equal to Result Type "
  195|      0|           << "component type";
  196|      0|  }
  197|       |
  198|      1|  const uint32_t index_type = _.GetOperandTypeId(inst, 4);
  199|      1|  if (!_.IsIntScalarType(index_type)) {
  ------------------
  |  Branch (199:7): [True: 1, False: 0]
  ------------------
  200|      1|    return _.diag(SPV_ERROR_INVALID_DATA, inst)
  201|      1|           << "Expected Index to be int scalar";
  202|      1|  }
  203|       |
  204|      0|  if (_.HasCapability(spv::Capability::Shader) &&
  ------------------
  |  Branch (204:7): [True: 0, False: 0]
  ------------------
  205|      0|      _.ContainsLimitedUseIntOrFloatType(inst->type_id())) {
  ------------------
  |  Branch (205:7): [True: 0, False: 0]
  ------------------
  206|      0|    return _.diag(SPV_ERROR_INVALID_DATA, inst)
  207|      0|           << "Cannot insert into a vector of 8- or 16-bit types";
  208|      0|  }
  209|      0|  return SPV_SUCCESS;
  210|      0|}
validate_composites.cpp:_ZN8spvtools3val12_GLOBAL__N_121ValidateVectorShuffleERNS0_17ValidationState_tEPKNS0_11InstructionE:
  493|    525|                                   const Instruction* inst) {
  494|    525|  auto resultType = _.FindDef(inst->type_id());
  495|    525|  if (!resultType || resultType->opcode() != spv::Op::OpTypeVector) {
  ------------------
  |  Branch (495:7): [True: 0, False: 525]
  |  Branch (495:22): [True: 0, False: 525]
  ------------------
  496|      0|    return _.diag(SPV_ERROR_INVALID_ID, inst)
  497|      0|           << "The Result Type of OpVectorShuffle must be"
  498|      0|           << " OpTypeVector. Found Op"
  499|      0|           << spvOpcodeString(static_cast<spv::Op>(resultType->opcode()))
  500|      0|           << ".";
  501|      0|  }
  502|       |
  503|       |  // The number of components in Result Type must be the same as the number of
  504|       |  // Component operands.
  505|    525|  auto componentCount = inst->operands().size() - 4;
  506|    525|  auto resultVectorDimension = resultType->GetOperandAs<uint32_t>(2);
  507|    525|  if (componentCount != resultVectorDimension) {
  ------------------
  |  Branch (507:7): [True: 1, False: 524]
  ------------------
  508|      1|    return _.diag(SPV_ERROR_INVALID_ID, inst)
  509|      1|           << "OpVectorShuffle component literals count does not match "
  510|      1|              "Result Type <id> "
  511|      1|           << _.getIdName(resultType->id()) << "s vector component count.";
  512|      1|  }
  513|       |
  514|       |  // Vector 1 and Vector 2 must both have vector types, with the same Component
  515|       |  // Type as Result Type.
  516|    524|  auto vector1Object = _.FindDef(inst->GetOperandAs<uint32_t>(2));
  517|    524|  auto vector1Type = _.FindDef(vector1Object->type_id());
  518|    524|  auto vector2Object = _.FindDef(inst->GetOperandAs<uint32_t>(3));
  519|    524|  auto vector2Type = _.FindDef(vector2Object->type_id());
  520|    524|  if (!vector1Type || vector1Type->opcode() != spv::Op::OpTypeVector) {
  ------------------
  |  Branch (520:7): [True: 0, False: 524]
  |  Branch (520:23): [True: 1, False: 523]
  ------------------
  521|      1|    return _.diag(SPV_ERROR_INVALID_ID, inst)
  522|      1|           << "The type of Vector 1 must be OpTypeVector.";
  523|      1|  }
  524|    523|  if (!vector2Type || vector2Type->opcode() != spv::Op::OpTypeVector) {
  ------------------
  |  Branch (524:7): [True: 0, False: 523]
  |  Branch (524:23): [True: 0, False: 523]
  ------------------
  525|      0|    return _.diag(SPV_ERROR_INVALID_ID, inst)
  526|      0|           << "The type of Vector 2 must be OpTypeVector.";
  527|      0|  }
  528|       |
  529|    523|  auto resultComponentType = resultType->GetOperandAs<uint32_t>(1);
  530|    523|  if (vector1Type->GetOperandAs<uint32_t>(1) != resultComponentType) {
  ------------------
  |  Branch (530:7): [True: 1, False: 522]
  ------------------
  531|      1|    return _.diag(SPV_ERROR_INVALID_ID, inst)
  532|      1|           << "The Component Type of Vector 1 must be the same as ResultType.";
  533|      1|  }
  534|    522|  if (vector2Type->GetOperandAs<uint32_t>(1) != resultComponentType) {
  ------------------
  |  Branch (534:7): [True: 1, False: 521]
  ------------------
  535|      1|    return _.diag(SPV_ERROR_INVALID_ID, inst)
  536|      1|           << "The Component Type of Vector 2 must be the same as ResultType.";
  537|      1|  }
  538|       |
  539|       |  // All Component literals must either be FFFFFFFF or in [0, N - 1].
  540|    521|  auto vector1ComponentCount = vector1Type->GetOperandAs<uint32_t>(2);
  541|    521|  auto vector2ComponentCount = vector2Type->GetOperandAs<uint32_t>(2);
  542|    521|  auto N = vector1ComponentCount + vector2ComponentCount;
  543|    521|  auto firstLiteralIndex = 4;
  544|  1.59k|  for (size_t i = firstLiteralIndex; i < inst->operands().size(); ++i) {
  ------------------
  |  Branch (544:38): [True: 1.08k, False: 506]
  ------------------
  545|  1.08k|    auto literal = inst->GetOperandAs<uint32_t>(i);
  546|  1.08k|    if (literal != 0xFFFFFFFF && literal >= N) {
  ------------------
  |  Branch (546:9): [True: 1.03k, False: 53]
  |  Branch (546:34): [True: 15, False: 1.02k]
  ------------------
  547|     15|      return _.diag(SPV_ERROR_INVALID_ID, inst)
  548|     15|             << "Component index " << literal << " is out of bounds for "
  549|     15|             << "combined (Vector1 + Vector2) size of " << N << ".";
  550|     15|    }
  551|  1.08k|  }
  552|       |
  553|    506|  if (_.HasCapability(spv::Capability::Shader) &&
  ------------------
  |  Branch (553:7): [True: 506, False: 0]
  ------------------
  554|    506|      _.ContainsLimitedUseIntOrFloatType(inst->type_id())) {
  ------------------
  |  Branch (554:7): [True: 0, False: 506]
  ------------------
  555|      0|    return _.diag(SPV_ERROR_INVALID_DATA, inst)
  556|      0|           << "Cannot shuffle a vector of 8- or 16-bit types";
  557|      0|  }
  558|       |
  559|    506|  return SPV_SUCCESS;
  560|    506|}
validate_composites.cpp:_ZN8spvtools3val12_GLOBAL__N_126ValidateCompositeConstructERNS0_17ValidationState_tEPKNS0_11InstructionE:
  213|  1.32k|                                        const Instruction* inst) {
  214|  1.32k|  const uint32_t num_operands = static_cast<uint32_t>(inst->operands().size());
  215|  1.32k|  const uint32_t result_type = inst->type_id();
  216|  1.32k|  const spv::Op result_opcode = _.GetIdOpcode(result_type);
  217|  1.32k|  switch (result_opcode) {
  218|  1.26k|    case spv::Op::OpTypeVector: {
  ------------------
  |  Branch (218:5): [True: 1.26k, False: 59]
  ------------------
  219|  1.26k|      const uint32_t num_result_components = _.GetDimension(result_type);
  220|  1.26k|      const uint32_t result_component_type = _.GetComponentType(result_type);
  221|  1.26k|      uint32_t given_component_count = 0;
  222|       |
  223|  1.26k|      if (num_operands <= 3) {
  ------------------
  |  Branch (223:11): [True: 1, False: 1.26k]
  ------------------
  224|      1|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
  225|      1|               << "Expected number of constituents to be at least 2";
  226|      1|      }
  227|       |
  228|  4.95k|      for (uint32_t operand_index = 2; operand_index < num_operands;
  ------------------
  |  Branch (228:40): [True: 3.69k, False: 1.25k]
  ------------------
  229|  3.69k|           ++operand_index) {
  230|  3.69k|        const uint32_t operand_type = _.GetOperandTypeId(inst, operand_index);
  231|  3.69k|        if (operand_type == result_component_type) {
  ------------------
  |  Branch (231:13): [True: 3.69k, False: 8]
  ------------------
  232|  3.69k|          ++given_component_count;
  233|  3.69k|        } else {
  234|      8|          if (_.GetIdOpcode(operand_type) != spv::Op::OpTypeVector ||
  ------------------
  |  Branch (234:15): [True: 3, False: 5]
  ------------------
  235|      8|              _.GetComponentType(operand_type) != result_component_type) {
  ------------------
  |  Branch (235:15): [True: 0, False: 5]
  ------------------
  236|      3|            return _.diag(SPV_ERROR_INVALID_DATA, inst)
  237|      3|                   << "Expected Constituents to be scalars or vectors of"
  238|      3|                   << " the same type as Result Type components";
  239|      3|          }
  240|       |
  241|      5|          given_component_count += _.GetDimension(operand_type);
  242|      5|        }
  243|  3.69k|      }
  244|       |
  245|  1.25k|      if (num_result_components != given_component_count) {
  ------------------
  |  Branch (245:11): [True: 2, False: 1.25k]
  ------------------
  246|      2|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
  247|      2|               << "Expected total number of given components to be equal "
  248|      2|               << "to the size of Result Type vector";
  249|      2|      }
  250|       |
  251|  1.25k|      break;
  252|  1.25k|    }
  253|  1.25k|    case spv::Op::OpTypeMatrix: {
  ------------------
  |  Branch (253:5): [True: 41, False: 1.27k]
  ------------------
  254|     41|      uint32_t result_num_rows = 0;
  255|     41|      uint32_t result_num_cols = 0;
  256|     41|      uint32_t result_col_type = 0;
  257|     41|      uint32_t result_component_type = 0;
  258|     41|      if (!_.GetMatrixTypeInfo(result_type, &result_num_rows, &result_num_cols,
  ------------------
  |  Branch (258:11): [True: 0, False: 41]
  ------------------
  259|     41|                               &result_col_type, &result_component_type)) {
  260|      0|        assert(0);
  261|      0|      }
  262|       |
  263|     41|      if (result_num_cols + 2 != num_operands) {
  ------------------
  |  Branch (263:11): [True: 1, False: 40]
  ------------------
  264|      1|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
  265|      1|               << "Expected total number of Constituents to be equal "
  266|      1|               << "to the number of columns of Result Type matrix";
  267|      1|      }
  268|       |
  269|    147|      for (uint32_t operand_index = 2; operand_index < num_operands;
  ------------------
  |  Branch (269:40): [True: 109, False: 38]
  ------------------
  270|    109|           ++operand_index) {
  271|    109|        const uint32_t operand_type = _.GetOperandTypeId(inst, operand_index);
  272|    109|        if (operand_type != result_col_type) {
  ------------------
  |  Branch (272:13): [True: 2, False: 107]
  ------------------
  273|      2|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
  274|      2|                 << "Expected Constituent type to be equal to the column "
  275|      2|                 << "type Result Type matrix";
  276|      2|        }
  277|    109|      }
  278|       |
  279|     38|      break;
  280|     40|    }
  281|     38|    case spv::Op::OpTypeArray: {
  ------------------
  |  Branch (281:5): [True: 11, False: 1.30k]
  ------------------
  282|     11|      const Instruction* const array_inst = _.FindDef(result_type);
  283|     11|      assert(array_inst);
  284|      0|      assert(array_inst->opcode() == spv::Op::OpTypeArray);
  285|       |
  286|      0|      auto size = _.FindDef(array_inst->word(3));
  287|     11|      if (spvOpcodeIsSpecConstant(size->opcode())) {
  ------------------
  |  Branch (287:11): [True: 0, False: 11]
  ------------------
  288|       |        // Cannot verify against the size of this array.
  289|      0|        break;
  290|      0|      }
  291|       |
  292|     11|      uint64_t array_size = 0;
  293|     11|      if (!_.GetConstantValUint64(array_inst->word(3), &array_size)) {
  ------------------
  |  Branch (293:11): [True: 0, False: 11]
  ------------------
  294|      0|        assert(0 && "Array type definition is corrupt");
  295|      0|      }
  296|       |
  297|     11|      if (array_size + 2 != num_operands) {
  ------------------
  |  Branch (297:11): [True: 9, False: 2]
  ------------------
  298|      9|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
  299|      9|               << "Expected total number of Constituents to be equal "
  300|      9|               << "to the number of elements of Result Type array";
  301|      9|      }
  302|       |
  303|      2|      const uint32_t result_component_type = array_inst->word(2);
  304|      8|      for (uint32_t operand_index = 2; operand_index < num_operands;
  ------------------
  |  Branch (304:40): [True: 7, False: 1]
  ------------------
  305|      7|           ++operand_index) {
  306|      7|        const uint32_t operand_type = _.GetOperandTypeId(inst, operand_index);
  307|      7|        if (operand_type != result_component_type) {
  ------------------
  |  Branch (307:13): [True: 1, False: 6]
  ------------------
  308|      1|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
  309|      1|                 << "Expected Constituent type to be equal to the column "
  310|      1|                 << "type Result Type array";
  311|      1|        }
  312|      7|      }
  313|       |
  314|      1|      break;
  315|      2|    }
  316|      4|    case spv::Op::OpTypeStruct: {
  ------------------
  |  Branch (316:5): [True: 4, False: 1.31k]
  ------------------
  317|      4|      const Instruction* const struct_inst = _.FindDef(result_type);
  318|      4|      assert(struct_inst);
  319|      0|      assert(struct_inst->opcode() == spv::Op::OpTypeStruct);
  320|       |
  321|      4|      if (struct_inst->operands().size() + 1 != num_operands) {
  ------------------
  |  Branch (321:11): [True: 1, False: 3]
  ------------------
  322|      1|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
  323|      1|               << "Expected total number of Constituents to be equal "
  324|      1|               << "to the number of members of Result Type struct";
  325|      1|      }
  326|       |
  327|      5|      for (uint32_t operand_index = 2; operand_index < num_operands;
  ------------------
  |  Branch (327:40): [True: 2, False: 3]
  ------------------
  328|      3|           ++operand_index) {
  329|      2|        const uint32_t operand_type = _.GetOperandTypeId(inst, operand_index);
  330|      2|        const uint32_t member_type = struct_inst->word(operand_index);
  331|      2|        if (operand_type != member_type) {
  ------------------
  |  Branch (331:13): [True: 0, False: 2]
  ------------------
  332|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
  333|      0|                 << "Expected Constituent type to be equal to the "
  334|      0|                 << "corresponding member type of Result Type struct";
  335|      0|        }
  336|      2|      }
  337|       |
  338|      3|      break;
  339|      3|    }
  340|      3|    case spv::Op::OpTypeCooperativeMatrixNV: {
  ------------------
  |  Branch (340:5): [True: 0, False: 1.32k]
  ------------------
  341|      0|      const auto result_type_inst = _.FindDef(result_type);
  342|      0|      assert(result_type_inst);
  343|      0|      const auto component_type_id =
  344|      0|          result_type_inst->GetOperandAs<uint32_t>(1);
  345|       |
  346|      0|      if (3 != num_operands) {
  ------------------
  |  Branch (346:11): [True: 0, False: 0]
  ------------------
  347|      0|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
  348|      0|               << "Expected single constituent";
  349|      0|      }
  350|       |
  351|      0|      const uint32_t operand_type_id = _.GetOperandTypeId(inst, 2);
  352|       |
  353|      0|      if (operand_type_id != component_type_id) {
  ------------------
  |  Branch (353:11): [True: 0, False: 0]
  ------------------
  354|      0|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
  355|      0|               << "Expected Constituent type to be equal to the component type";
  356|      0|      }
  357|       |
  358|      0|      break;
  359|      0|    }
  360|      3|    default: {
  ------------------
  |  Branch (360:5): [True: 3, False: 1.31k]
  ------------------
  361|      3|      return _.diag(SPV_ERROR_INVALID_DATA, inst)
  362|      3|             << "Expected Result Type to be a composite type";
  363|      0|    }
  364|  1.32k|  }
  365|       |
  366|  1.29k|  if (_.HasCapability(spv::Capability::Shader) &&
  ------------------
  |  Branch (366:7): [True: 1.29k, False: 1]
  ------------------
  367|  1.29k|      _.ContainsLimitedUseIntOrFloatType(inst->type_id())) {
  ------------------
  |  Branch (367:7): [True: 0, False: 1.29k]
  ------------------
  368|      0|    return _.diag(SPV_ERROR_INVALID_DATA, inst)
  369|      0|           << "Cannot create a composite containing 8- or 16-bit types";
  370|      0|  }
  371|  1.29k|  return SPV_SUCCESS;
  372|  1.29k|}
validate_composites.cpp:_ZN8spvtools3val12_GLOBAL__N_124ValidateCompositeExtractERNS0_17ValidationState_tEPKNS0_11InstructionE:
  375|  2.35k|                                      const Instruction* inst) {
  376|  2.35k|  uint32_t member_type = 0;
  377|  2.35k|  if (spv_result_t error = GetExtractInsertValueType(_, inst, &member_type)) {
  ------------------
  |  Branch (377:20): [True: 46, False: 2.30k]
  ------------------
  378|     46|    return error;
  379|     46|  }
  380|       |
  381|  2.30k|  const uint32_t result_type = inst->type_id();
  382|  2.30k|  if (result_type != member_type) {
  ------------------
  |  Branch (382:7): [True: 2, False: 2.30k]
  ------------------
  383|      2|    return _.diag(SPV_ERROR_INVALID_DATA, inst)
  384|      2|           << "Result type (Op" << spvOpcodeString(_.GetIdOpcode(result_type))
  385|      2|           << ") does not match the type that results from indexing into "
  386|      2|              "the composite (Op"
  387|      2|           << spvOpcodeString(_.GetIdOpcode(member_type)) << ").";
  388|      2|  }
  389|       |
  390|  2.30k|  if (_.HasCapability(spv::Capability::Shader) &&
  ------------------
  |  Branch (390:7): [True: 2.30k, False: 0]
  ------------------
  391|  2.30k|      _.ContainsLimitedUseIntOrFloatType(inst->type_id())) {
  ------------------
  |  Branch (391:7): [True: 0, False: 2.30k]
  ------------------
  392|      0|    return _.diag(SPV_ERROR_INVALID_DATA, inst)
  393|      0|           << "Cannot extract from a composite of 8- or 16-bit types";
  394|      0|  }
  395|       |
  396|  2.30k|  return SPV_SUCCESS;
  397|  2.30k|}
validate_composites.cpp:_ZN8spvtools3val12_GLOBAL__N_125GetExtractInsertValueTypeERNS0_17ValidationState_tEPKNS0_11InstructionEPj:
   37|  2.52k|                                       uint32_t* member_type) {
   38|  2.52k|  const spv::Op opcode = inst->opcode();
   39|  2.52k|  assert(opcode == spv::Op::OpCompositeExtract ||
   40|  2.52k|         opcode == spv::Op::OpCompositeInsert);
   41|  2.52k|  uint32_t word_index = opcode == spv::Op::OpCompositeExtract ? 4 : 5;
  ------------------
  |  Branch (41:25): [True: 2.35k, False: 172]
  ------------------
   42|  2.52k|  const uint32_t num_words = static_cast<uint32_t>(inst->words().size());
   43|  2.52k|  const uint32_t composite_id_index = word_index - 1;
   44|  2.52k|  const uint32_t num_indices = num_words - word_index;
   45|  2.52k|  const uint32_t kCompositeExtractInsertMaxNumIndices = 255;
   46|       |
   47|  2.52k|  if (num_indices == 0) {
  ------------------
  |  Branch (47:7): [True: 2, False: 2.52k]
  ------------------
   48|      2|    return _.diag(SPV_ERROR_INVALID_DATA, inst)
   49|      2|           << "Expected at least one index to Op"
   50|      2|           << spvOpcodeString(inst->opcode()) << ", zero found";
   51|       |
   52|  2.52k|  } else if (num_indices > kCompositeExtractInsertMaxNumIndices) {
  ------------------
  |  Branch (52:14): [True: 0, False: 2.52k]
  ------------------
   53|      0|    return _.diag(SPV_ERROR_INVALID_DATA, inst)
   54|      0|           << "The number of indexes in Op" << spvOpcodeString(opcode)
   55|      0|           << " may not exceed " << kCompositeExtractInsertMaxNumIndices
   56|      0|           << ". Found " << num_indices << " indexes.";
   57|      0|  }
   58|       |
   59|  2.52k|  *member_type = _.GetTypeId(inst->word(composite_id_index));
   60|  2.52k|  if (*member_type == 0) {
  ------------------
  |  Branch (60:7): [True: 0, False: 2.52k]
  ------------------
   61|      0|    return _.diag(SPV_ERROR_INVALID_DATA, inst)
   62|      0|           << "Expected Composite to be an object of composite type";
   63|      0|  }
   64|       |
   65|  4.99k|  for (; word_index < num_words; ++word_index) {
  ------------------
  |  Branch (65:10): [True: 2.52k, False: 2.47k]
  ------------------
   66|  2.52k|    const uint32_t component_index = inst->word(word_index);
   67|  2.52k|    const Instruction* const type_inst = _.FindDef(*member_type);
   68|  2.52k|    assert(type_inst);
   69|      0|    switch (type_inst->opcode()) {
   70|  1.50k|      case spv::Op::OpTypeVector: {
  ------------------
  |  Branch (70:7): [True: 1.50k, False: 1.01k]
  ------------------
   71|  1.50k|        *member_type = type_inst->word(2);
   72|  1.50k|        const uint32_t vector_size = type_inst->word(3);
   73|  1.50k|        if (component_index >= vector_size) {
  ------------------
  |  Branch (73:13): [True: 17, False: 1.48k]
  ------------------
   74|     17|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
   75|     17|                 << "Vector access is out of bounds, vector size is "
   76|     17|                 << vector_size << ", but access index is " << component_index;
   77|     17|        }
   78|  1.48k|        break;
   79|  1.50k|      }
   80|  1.48k|      case spv::Op::OpTypeMatrix: {
  ------------------
  |  Branch (80:7): [True: 35, False: 2.48k]
  ------------------
   81|     35|        *member_type = type_inst->word(2);
   82|     35|        const uint32_t num_cols = type_inst->word(3);
   83|     35|        if (component_index >= num_cols) {
  ------------------
  |  Branch (83:13): [True: 11, False: 24]
  ------------------
   84|     11|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
   85|     11|                 << "Matrix access is out of bounds, matrix has " << num_cols
   86|     11|                 << " columns, but access index is " << component_index;
   87|     11|        }
   88|     24|        break;
   89|     35|      }
   90|     25|      case spv::Op::OpTypeArray: {
  ------------------
  |  Branch (90:7): [True: 25, False: 2.49k]
  ------------------
   91|     25|        uint64_t array_size = 0;
   92|     25|        auto size = _.FindDef(type_inst->word(3));
   93|     25|        *member_type = type_inst->word(2);
   94|     25|        if (spvOpcodeIsSpecConstant(size->opcode())) {
  ------------------
  |  Branch (94:13): [True: 1, False: 24]
  ------------------
   95|       |          // Cannot verify against the size of this array.
   96|      1|          break;
   97|      1|        }
   98|       |
   99|     24|        if (!_.GetConstantValUint64(type_inst->word(3), &array_size)) {
  ------------------
  |  Branch (99:13): [True: 0, False: 24]
  ------------------
  100|      0|          assert(0 && "Array type definition is corrupt");
  101|      0|        }
  102|     24|        if (component_index >= array_size) {
  ------------------
  |  Branch (102:13): [True: 12, False: 12]
  ------------------
  103|     12|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
  104|     12|                 << "Array access is out of bounds, array size is "
  105|     12|                 << array_size << ", but access index is " << component_index;
  106|     12|        }
  107|     12|        break;
  108|     24|      }
  109|     12|      case spv::Op::OpTypeRuntimeArray: {
  ------------------
  |  Branch (109:7): [True: 0, False: 2.52k]
  ------------------
  110|      0|        *member_type = type_inst->word(2);
  111|       |        // Array size is unknown.
  112|      0|        break;
  113|     24|      }
  114|    953|      case spv::Op::OpTypeStruct: {
  ------------------
  |  Branch (114:7): [True: 953, False: 1.57k]
  ------------------
  115|    953|        const size_t num_struct_members = type_inst->words().size() - 2;
  116|    953|        if (component_index >= num_struct_members) {
  ------------------
  |  Branch (116:13): [True: 6, False: 947]
  ------------------
  117|      6|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
  118|      6|                 << "Index is out of bounds, can not find index "
  119|      6|                 << component_index << " in the structure <id> '"
  120|      6|                 << type_inst->id() << "'. This structure has "
  121|      6|                 << num_struct_members << " members. Largest valid index is "
  122|      6|                 << num_struct_members - 1 << ".";
  123|      6|        }
  124|    947|        *member_type = type_inst->word(component_index + 2);
  125|    947|        break;
  126|    953|      }
  127|      0|      case spv::Op::OpTypeCooperativeMatrixNV: {
  ------------------
  |  Branch (127:7): [True: 0, False: 2.52k]
  ------------------
  128|      0|        *member_type = type_inst->word(2);
  129|      0|        break;
  130|    953|      }
  131|      4|      default:
  ------------------
  |  Branch (131:7): [True: 4, False: 2.51k]
  ------------------
  132|      4|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
  133|      4|               << "Reached non-composite type while indexes still remain to "
  134|      4|                  "be traversed.";
  135|  2.52k|    }
  136|  2.52k|  }
  137|       |
  138|  2.47k|  return SPV_SUCCESS;
  139|  2.52k|}
validate_composites.cpp:_ZN8spvtools3val12_GLOBAL__N_123ValidateCompositeInsertERNS0_17ValidationState_tEPKNS0_11InstructionE:
  400|    178|                                     const Instruction* inst) {
  401|    178|  const uint32_t object_type = _.GetOperandTypeId(inst, 2);
  402|    178|  const uint32_t composite_type = _.GetOperandTypeId(inst, 3);
  403|    178|  const uint32_t result_type = inst->type_id();
  404|    178|  if (result_type != composite_type) {
  ------------------
  |  Branch (404:7): [True: 6, False: 172]
  ------------------
  405|      6|    return _.diag(SPV_ERROR_INVALID_DATA, inst)
  406|      6|           << "The Result Type must be the same as Composite type in Op"
  407|      6|           << spvOpcodeString(inst->opcode()) << " yielding Result Id "
  408|      6|           << result_type << ".";
  409|      6|  }
  410|       |
  411|    172|  uint32_t member_type = 0;
  412|    172|  if (spv_result_t error = GetExtractInsertValueType(_, inst, &member_type)) {
  ------------------
  |  Branch (412:20): [True: 6, False: 166]
  ------------------
  413|      6|    return error;
  414|      6|  }
  415|       |
  416|    166|  if (object_type != member_type) {
  ------------------
  |  Branch (416:7): [True: 1, False: 165]
  ------------------
  417|      1|    return _.diag(SPV_ERROR_INVALID_DATA, inst)
  418|      1|           << "The Object type (Op"
  419|      1|           << spvOpcodeString(_.GetIdOpcode(object_type))
  420|      1|           << ") does not match the type that results from indexing into the "
  421|      1|              "Composite (Op"
  422|      1|           << spvOpcodeString(_.GetIdOpcode(member_type)) << ").";
  423|      1|  }
  424|       |
  425|    165|  if (_.HasCapability(spv::Capability::Shader) &&
  ------------------
  |  Branch (425:7): [True: 165, False: 0]
  ------------------
  426|    165|      _.ContainsLimitedUseIntOrFloatType(inst->type_id())) {
  ------------------
  |  Branch (426:7): [True: 0, False: 165]
  ------------------
  427|      0|    return _.diag(SPV_ERROR_INVALID_DATA, inst)
  428|      0|           << "Cannot insert into a composite of 8- or 16-bit types";
  429|      0|  }
  430|       |
  431|    165|  return SPV_SUCCESS;
  432|    165|}
validate_composites.cpp:_ZN8spvtools3val12_GLOBAL__N_118ValidateCopyObjectERNS0_17ValidationState_tEPKNS0_11InstructionE:
  434|     80|spv_result_t ValidateCopyObject(ValidationState_t& _, const Instruction* inst) {
  435|     80|  const uint32_t result_type = inst->type_id();
  436|     80|  const uint32_t operand_type = _.GetOperandTypeId(inst, 2);
  437|     80|  if (operand_type != result_type) {
  ------------------
  |  Branch (437:7): [True: 2, False: 78]
  ------------------
  438|      2|    return _.diag(SPV_ERROR_INVALID_DATA, inst)
  439|      2|           << "Expected Result Type and Operand type to be the same";
  440|      2|  }
  441|     78|  if (_.IsVoidType(result_type)) {
  ------------------
  |  Branch (441:7): [True: 0, False: 78]
  ------------------
  442|      0|    return _.diag(SPV_ERROR_INVALID_DATA, inst)
  443|      0|           << "OpCopyObject cannot have void result type";
  444|      0|  }
  445|     78|  return SPV_SUCCESS;
  446|     78|}
validate_composites.cpp:_ZN8spvtools3val12_GLOBAL__N_117ValidateTransposeERNS0_17ValidationState_tEPKNS0_11InstructionE:
  448|     17|spv_result_t ValidateTranspose(ValidationState_t& _, const Instruction* inst) {
  449|     17|  uint32_t result_num_rows = 0;
  450|     17|  uint32_t result_num_cols = 0;
  451|     17|  uint32_t result_col_type = 0;
  452|     17|  uint32_t result_component_type = 0;
  453|     17|  const uint32_t result_type = inst->type_id();
  454|     17|  if (!_.GetMatrixTypeInfo(result_type, &result_num_rows, &result_num_cols,
  ------------------
  |  Branch (454:7): [True: 5, False: 12]
  ------------------
  455|     17|                           &result_col_type, &result_component_type)) {
  456|      5|    return _.diag(SPV_ERROR_INVALID_DATA, inst)
  457|      5|           << "Expected Result Type to be a matrix type";
  458|      5|  }
  459|       |
  460|     12|  const uint32_t matrix_type = _.GetOperandTypeId(inst, 2);
  461|     12|  uint32_t matrix_num_rows = 0;
  462|     12|  uint32_t matrix_num_cols = 0;
  463|     12|  uint32_t matrix_col_type = 0;
  464|     12|  uint32_t matrix_component_type = 0;
  465|     12|  if (!_.GetMatrixTypeInfo(matrix_type, &matrix_num_rows, &matrix_num_cols,
  ------------------
  |  Branch (465:7): [True: 0, False: 12]
  ------------------
  466|     12|                           &matrix_col_type, &matrix_component_type)) {
  467|      0|    return _.diag(SPV_ERROR_INVALID_DATA, inst)
  468|      0|           << "Expected Matrix to be of type OpTypeMatrix";
  469|      0|  }
  470|       |
  471|     12|  if (result_component_type != matrix_component_type) {
  ------------------
  |  Branch (471:7): [True: 0, False: 12]
  ------------------
  472|      0|    return _.diag(SPV_ERROR_INVALID_DATA, inst)
  473|      0|           << "Expected component types of Matrix and Result Type to be "
  474|      0|           << "identical";
  475|      0|  }
  476|       |
  477|     12|  if (result_num_rows != matrix_num_cols ||
  ------------------
  |  Branch (477:7): [True: 2, False: 10]
  ------------------
  478|     12|      result_num_cols != matrix_num_rows) {
  ------------------
  |  Branch (478:7): [True: 0, False: 10]
  ------------------
  479|      2|    return _.diag(SPV_ERROR_INVALID_DATA, inst)
  480|      2|           << "Expected number of columns and the column size of Matrix "
  481|      2|           << "to be the reverse of those of Result Type";
  482|      2|  }
  483|       |
  484|     10|  if (_.HasCapability(spv::Capability::Shader) &&
  ------------------
  |  Branch (484:7): [True: 10, False: 0]
  ------------------
  485|     10|      _.ContainsLimitedUseIntOrFloatType(inst->type_id())) {
  ------------------
  |  Branch (485:7): [True: 0, False: 10]
  ------------------
  486|      0|    return _.diag(SPV_ERROR_INVALID_DATA, inst)
  487|      0|           << "Cannot transpose matrices of 16-bit floats";
  488|      0|  }
  489|     10|  return SPV_SUCCESS;
  490|     10|}

_ZN8spvtools3val12ConstantPassERNS0_17ValidationState_tEPKNS0_11InstructionE:
  426|   286k|spv_result_t ConstantPass(ValidationState_t& _, const Instruction* inst) {
  427|   286k|  switch (inst->opcode()) {
  428|    271|    case spv::Op::OpConstantTrue:
  ------------------
  |  Branch (428:5): [True: 271, False: 285k]
  ------------------
  429|    426|    case spv::Op::OpConstantFalse:
  ------------------
  |  Branch (429:5): [True: 155, False: 285k]
  ------------------
  430|    452|    case spv::Op::OpSpecConstantTrue:
  ------------------
  |  Branch (430:5): [True: 26, False: 286k]
  ------------------
  431|    465|    case spv::Op::OpSpecConstantFalse:
  ------------------
  |  Branch (431:5): [True: 13, False: 286k]
  ------------------
  432|    465|      if (auto error = ValidateConstantBool(_, inst)) return error;
  ------------------
  |  Branch (432:16): [True: 5, False: 460]
  ------------------
  433|    460|      break;
  434|  2.76k|    case spv::Op::OpConstantComposite:
  ------------------
  |  Branch (434:5): [True: 2.76k, False: 283k]
  ------------------
  435|  2.84k|    case spv::Op::OpSpecConstantComposite:
  ------------------
  |  Branch (435:5): [True: 80, False: 286k]
  ------------------
  436|  2.84k|      if (auto error = ValidateConstantComposite(_, inst)) return error;
  ------------------
  |  Branch (436:16): [True: 37, False: 2.80k]
  ------------------
  437|  2.80k|      break;
  438|  2.80k|    case spv::Op::OpConstantSampler:
  ------------------
  |  Branch (438:5): [True: 0, False: 286k]
  ------------------
  439|      0|      if (auto error = ValidateConstantSampler(_, inst)) return error;
  ------------------
  |  Branch (439:16): [True: 0, False: 0]
  ------------------
  440|      0|      break;
  441|    153|    case spv::Op::OpConstantNull:
  ------------------
  |  Branch (441:5): [True: 153, False: 285k]
  ------------------
  442|    153|      if (auto error = ValidateConstantNull(_, inst)) return error;
  ------------------
  |  Branch (442:16): [True: 1, False: 152]
  ------------------
  443|    152|      break;
  444|    255|    case spv::Op::OpSpecConstant:
  ------------------
  |  Branch (444:5): [True: 255, False: 285k]
  ------------------
  445|    255|      if (auto error = ValidateSpecConstant(_, inst)) return error;
  ------------------
  |  Branch (445:16): [True: 0, False: 255]
  ------------------
  446|    255|      break;
  447|    255|    case spv::Op::OpSpecConstantOp:
  ------------------
  |  Branch (447:5): [True: 19, False: 286k]
  ------------------
  448|     19|      if (auto error = ValidateSpecConstantOp(_, inst)) return error;
  ------------------
  |  Branch (448:16): [True: 8, False: 11]
  ------------------
  449|     11|      break;
  450|   282k|    default:
  ------------------
  |  Branch (450:5): [True: 282k, False: 3.73k]
  ------------------
  451|   282k|      break;
  452|   286k|  }
  453|       |
  454|       |  // Generally disallow creating 8- or 16-bit constants unless the full
  455|       |  // capabilities are present.
  456|   286k|  if (spvOpcodeIsConstant(inst->opcode()) &&
  ------------------
  |  Branch (456:7): [True: 16.6k, False: 269k]
  ------------------
  457|   286k|      _.HasCapability(spv::Capability::Shader) &&
  ------------------
  |  Branch (457:7): [True: 16.6k, False: 36]
  ------------------
  458|   286k|      !_.IsPointerType(inst->type_id()) &&
  ------------------
  |  Branch (458:7): [True: 16.6k, False: 6]
  ------------------
  459|   286k|      _.ContainsLimitedUseIntOrFloatType(inst->type_id())) {
  ------------------
  |  Branch (459:7): [True: 0, False: 16.6k]
  ------------------
  460|      0|    return _.diag(SPV_ERROR_INVALID_ID, inst)
  461|      0|           << "Cannot form constants of 8- or 16-bit types";
  462|      0|  }
  463|       |
  464|   286k|  return SPV_SUCCESS;
  465|   286k|}
validate_constants.cpp:_ZN8spvtools3val12_GLOBAL__N_120ValidateConstantBoolERNS0_17ValidationState_tEPKNS0_11InstructionE:
   25|    465|                                  const Instruction* inst) {
   26|    465|  auto type = _.FindDef(inst->type_id());
   27|    465|  if (!type || type->opcode() != spv::Op::OpTypeBool) {
  ------------------
  |  Branch (27:7): [True: 0, False: 465]
  |  Branch (27:16): [True: 5, False: 460]
  ------------------
   28|      5|    return _.diag(SPV_ERROR_INVALID_ID, inst)
   29|      5|           << "Op" << spvOpcodeString(inst->opcode()) << " Result Type <id> "
   30|      5|           << _.getIdName(inst->type_id()) << " is not a boolean type.";
   31|      5|  }
   32|       |
   33|    460|  return SPV_SUCCESS;
   34|    465|}
validate_constants.cpp:_ZN8spvtools3val12_GLOBAL__N_125ValidateConstantCompositeERNS0_17ValidationState_tEPKNS0_11InstructionE:
   37|  2.84k|                                       const Instruction* inst) {
   38|  2.84k|  std::string opcode_name = std::string("Op") + spvOpcodeString(inst->opcode());
   39|       |
   40|  2.84k|  const auto result_type = _.FindDef(inst->type_id());
   41|  2.84k|  if (!result_type || !spvOpcodeIsComposite(result_type->opcode())) {
  ------------------
  |  Branch (41:7): [True: 0, False: 2.84k]
  |  Branch (41:23): [True: 3, False: 2.84k]
  ------------------
   42|      3|    return _.diag(SPV_ERROR_INVALID_ID, inst)
   43|      3|           << opcode_name << " Result Type <id> "
   44|      3|           << _.getIdName(inst->type_id()) << " is not a composite type.";
   45|      3|  }
   46|       |
   47|  2.84k|  const auto constituent_count = inst->words().size() - 3;
   48|  2.84k|  switch (result_type->opcode()) {
   49|  1.19k|    case spv::Op::OpTypeVector: {
  ------------------
  |  Branch (49:5): [True: 1.19k, False: 1.64k]
  ------------------
   50|  1.19k|      const auto component_count = result_type->GetOperandAs<uint32_t>(2);
   51|  1.19k|      if (component_count != constituent_count) {
  ------------------
  |  Branch (51:11): [True: 3, False: 1.19k]
  ------------------
   52|       |        // TODO: Output ID's on diagnostic
   53|      3|        return _.diag(SPV_ERROR_INVALID_ID, inst)
   54|      3|               << opcode_name
   55|      3|               << " Constituent <id> count does not match "
   56|      3|                  "Result Type <id> "
   57|      3|               << _.getIdName(result_type->id()) << "s vector component count.";
   58|      3|      }
   59|  1.19k|      const auto component_type =
   60|  1.19k|          _.FindDef(result_type->GetOperandAs<uint32_t>(1));
   61|  1.19k|      if (!component_type) {
  ------------------
  |  Branch (61:11): [True: 0, False: 1.19k]
  ------------------
   62|      0|        return _.diag(SPV_ERROR_INVALID_ID, result_type)
   63|      0|               << "Component type is not defined.";
   64|      0|      }
   65|  1.19k|      for (size_t constituent_index = 2;
   66|  4.95k|           constituent_index < inst->operands().size(); constituent_index++) {
  ------------------
  |  Branch (66:12): [True: 3.76k, False: 1.18k]
  ------------------
   67|  3.76k|        const auto constituent_id =
   68|  3.76k|            inst->GetOperandAs<uint32_t>(constituent_index);
   69|  3.76k|        const auto constituent = _.FindDef(constituent_id);
   70|  3.76k|        if (!constituent ||
  ------------------
  |  Branch (70:13): [True: 0, False: 3.76k]
  ------------------
   71|  3.76k|            !spvOpcodeIsConstantOrUndef(constituent->opcode())) {
  ------------------
  |  Branch (71:13): [True: 0, False: 3.76k]
  ------------------
   72|      0|          return _.diag(SPV_ERROR_INVALID_ID, inst)
   73|      0|                 << opcode_name << " Constituent <id> "
   74|      0|                 << _.getIdName(constituent_id)
   75|      0|                 << " is not a constant or undef.";
   76|      0|        }
   77|  3.76k|        const auto constituent_result_type = _.FindDef(constituent->type_id());
   78|  3.76k|        if (!constituent_result_type ||
  ------------------
  |  Branch (78:13): [True: 0, False: 3.76k]
  ------------------
   79|  3.76k|            component_type->opcode() != constituent_result_type->opcode()) {
  ------------------
  |  Branch (79:13): [True: 3, False: 3.76k]
  ------------------
   80|      3|          return _.diag(SPV_ERROR_INVALID_ID, inst)
   81|      3|                 << opcode_name << " Constituent <id> "
   82|      3|                 << _.getIdName(constituent_id)
   83|      3|                 << "s type does not match Result Type <id> "
   84|      3|                 << _.getIdName(result_type->id()) << "s vector element type.";
   85|      3|        }
   86|  3.76k|      }
   87|  1.19k|    } break;
   88|  1.18k|    case spv::Op::OpTypeMatrix: {
  ------------------
  |  Branch (88:5): [True: 5, False: 2.83k]
  ------------------
   89|      5|      const auto column_count = result_type->GetOperandAs<uint32_t>(2);
   90|      5|      if (column_count != constituent_count) {
  ------------------
  |  Branch (90:11): [True: 2, False: 3]
  ------------------
   91|       |        // TODO: Output ID's on diagnostic
   92|      2|        return _.diag(SPV_ERROR_INVALID_ID, inst)
   93|      2|               << opcode_name
   94|      2|               << " Constituent <id> count does not match "
   95|      2|                  "Result Type <id> "
   96|      2|               << _.getIdName(result_type->id()) << "s matrix column count.";
   97|      2|      }
   98|       |
   99|      3|      const auto column_type = _.FindDef(result_type->words()[2]);
  100|      3|      if (!column_type) {
  ------------------
  |  Branch (100:11): [True: 0, False: 3]
  ------------------
  101|      0|        return _.diag(SPV_ERROR_INVALID_ID, result_type)
  102|      0|               << "Column type is not defined.";
  103|      0|      }
  104|      3|      const auto component_count = column_type->GetOperandAs<uint32_t>(2);
  105|      3|      const auto component_type =
  106|      3|          _.FindDef(column_type->GetOperandAs<uint32_t>(1));
  107|      3|      if (!component_type) {
  ------------------
  |  Branch (107:11): [True: 0, False: 3]
  ------------------
  108|      0|        return _.diag(SPV_ERROR_INVALID_ID, column_type)
  109|      0|               << "Component type is not defined.";
  110|      0|      }
  111|       |
  112|      3|      for (size_t constituent_index = 2;
  113|     10|           constituent_index < inst->operands().size(); constituent_index++) {
  ------------------
  |  Branch (113:12): [True: 9, False: 1]
  ------------------
  114|      9|        const auto constituent_id =
  115|      9|            inst->GetOperandAs<uint32_t>(constituent_index);
  116|      9|        const auto constituent = _.FindDef(constituent_id);
  117|      9|        if (!constituent ||
  ------------------
  |  Branch (117:13): [True: 0, False: 9]
  ------------------
  118|      9|            !spvOpcodeIsConstantOrUndef(constituent->opcode())) {
  ------------------
  |  Branch (118:13): [True: 0, False: 9]
  ------------------
  119|       |          // The message says "... or undef" because the spec does not say
  120|       |          // undef is a constant.
  121|      0|          return _.diag(SPV_ERROR_INVALID_ID, inst)
  122|      0|                 << opcode_name << " Constituent <id> "
  123|      0|                 << _.getIdName(constituent_id)
  124|      0|                 << " is not a constant or undef.";
  125|      0|        }
  126|      9|        const auto vector = _.FindDef(constituent->type_id());
  127|      9|        if (!vector) {
  ------------------
  |  Branch (127:13): [True: 0, False: 9]
  ------------------
  128|      0|          return _.diag(SPV_ERROR_INVALID_ID, constituent)
  129|      0|                 << "Result type is not defined.";
  130|      0|        }
  131|      9|        if (column_type->opcode() != vector->opcode()) {
  ------------------
  |  Branch (131:13): [True: 2, False: 7]
  ------------------
  132|      2|          return _.diag(SPV_ERROR_INVALID_ID, inst)
  133|      2|                 << opcode_name << " Constituent <id> "
  134|      2|                 << _.getIdName(constituent_id)
  135|      2|                 << " type does not match Result Type <id> "
  136|      2|                 << _.getIdName(result_type->id()) << "s matrix column type.";
  137|      2|        }
  138|      7|        const auto vector_component_type =
  139|      7|            _.FindDef(vector->GetOperandAs<uint32_t>(1));
  140|      7|        if (component_type->id() != vector_component_type->id()) {
  ------------------
  |  Branch (140:13): [True: 0, False: 7]
  ------------------
  141|      0|          return _.diag(SPV_ERROR_INVALID_ID, inst)
  142|      0|                 << opcode_name << " Constituent <id> "
  143|      0|                 << _.getIdName(constituent_id)
  144|      0|                 << " component type does not match Result Type <id> "
  145|      0|                 << _.getIdName(result_type->id())
  146|      0|                 << "s matrix column component type.";
  147|      0|        }
  148|      7|        if (component_count != vector->words()[3]) {
  ------------------
  |  Branch (148:13): [True: 0, False: 7]
  ------------------
  149|      0|          return _.diag(SPV_ERROR_INVALID_ID, inst)
  150|      0|                 << opcode_name << " Constituent <id> "
  151|      0|                 << _.getIdName(constituent_id)
  152|      0|                 << " vector component count does not match Result Type <id> "
  153|      0|                 << _.getIdName(result_type->id())
  154|      0|                 << "s vector component count.";
  155|      0|        }
  156|      7|      }
  157|      3|    } break;
  158|     88|    case spv::Op::OpTypeArray: {
  ------------------
  |  Branch (158:5): [True: 88, False: 2.75k]
  ------------------
  159|     88|      auto element_type = _.FindDef(result_type->GetOperandAs<uint32_t>(1));
  160|     88|      if (!element_type) {
  ------------------
  |  Branch (160:11): [True: 0, False: 88]
  ------------------
  161|      0|        return _.diag(SPV_ERROR_INVALID_ID, result_type)
  162|      0|               << "Element type is not defined.";
  163|      0|      }
  164|     88|      const auto length = _.FindDef(result_type->GetOperandAs<uint32_t>(2));
  165|     88|      if (!length) {
  ------------------
  |  Branch (165:11): [True: 0, False: 88]
  ------------------
  166|      0|        return _.diag(SPV_ERROR_INVALID_ID, result_type)
  167|      0|               << "Length is not defined.";
  168|      0|      }
  169|     88|      bool is_int32;
  170|     88|      bool is_const;
  171|     88|      uint32_t value;
  172|     88|      std::tie(is_int32, is_const, value) = _.EvalInt32IfConst(length->id());
  173|     88|      if (is_int32 && is_const && value != constituent_count) {
  ------------------
  |  Branch (173:11): [True: 88, False: 0]
  |  Branch (173:23): [True: 60, False: 28]
  |  Branch (173:35): [True: 15, False: 45]
  ------------------
  174|     15|        return _.diag(SPV_ERROR_INVALID_ID, inst)
  175|     15|               << opcode_name
  176|     15|               << " Constituent count does not match "
  177|     15|                  "Result Type <id> "
  178|     15|               << _.getIdName(result_type->id()) << "s array length.";
  179|     15|      }
  180|     73|      for (size_t constituent_index = 2;
  181|    801|           constituent_index < inst->operands().size(); constituent_index++) {
  ------------------
  |  Branch (181:12): [True: 731, False: 70]
  ------------------
  182|    731|        const auto constituent_id =
  183|    731|            inst->GetOperandAs<uint32_t>(constituent_index);
  184|    731|        const auto constituent = _.FindDef(constituent_id);
  185|    731|        if (!constituent ||
  ------------------
  |  Branch (185:13): [True: 0, False: 731]
  ------------------
  186|    731|            !spvOpcodeIsConstantOrUndef(constituent->opcode())) {
  ------------------
  |  Branch (186:13): [True: 1, False: 730]
  ------------------
  187|      1|          return _.diag(SPV_ERROR_INVALID_ID, inst)
  188|      1|                 << opcode_name << " Constituent <id> "
  189|      1|                 << _.getIdName(constituent_id)
  190|      1|                 << " is not a constant or undef.";
  191|      1|        }
  192|    730|        const auto constituent_type = _.FindDef(constituent->type_id());
  193|    730|        if (!constituent_type) {
  ------------------
  |  Branch (193:13): [True: 0, False: 730]
  ------------------
  194|      0|          return _.diag(SPV_ERROR_INVALID_ID, constituent)
  195|      0|                 << "Result type is not defined.";
  196|      0|        }
  197|    730|        if (element_type->id() != constituent_type->id()) {
  ------------------
  |  Branch (197:13): [True: 2, False: 728]
  ------------------
  198|      2|          return _.diag(SPV_ERROR_INVALID_ID, inst)
  199|      2|                 << opcode_name << " Constituent <id> "
  200|      2|                 << _.getIdName(constituent_id)
  201|      2|                 << "s type does not match Result Type <id> "
  202|      2|                 << _.getIdName(result_type->id()) << "s array element type.";
  203|      2|        }
  204|    730|      }
  205|     73|    } break;
  206|  1.55k|    case spv::Op::OpTypeStruct: {
  ------------------
  |  Branch (206:5): [True: 1.55k, False: 1.28k]
  ------------------
  207|  1.55k|      const auto member_count = result_type->words().size() - 2;
  208|  1.55k|      if (member_count != constituent_count) {
  ------------------
  |  Branch (208:11): [True: 1, False: 1.55k]
  ------------------
  209|      1|        return _.diag(SPV_ERROR_INVALID_ID, inst)
  210|      1|               << opcode_name << " Constituent <id> "
  211|      1|               << _.getIdName(inst->type_id())
  212|      1|               << " count does not match Result Type <id> "
  213|      1|               << _.getIdName(result_type->id()) << "s struct member count.";
  214|      1|      }
  215|  1.55k|      for (uint32_t constituent_index = 2, member_index = 1;
  216|  6.16k|           constituent_index < inst->operands().size();
  ------------------
  |  Branch (216:12): [True: 4.61k, False: 1.54k]
  ------------------
  217|  4.61k|           constituent_index++, member_index++) {
  218|  4.61k|        const auto constituent_id =
  219|  4.61k|            inst->GetOperandAs<uint32_t>(constituent_index);
  220|  4.61k|        const auto constituent = _.FindDef(constituent_id);
  221|  4.61k|        if (!constituent ||
  ------------------
  |  Branch (221:13): [True: 0, False: 4.61k]
  ------------------
  222|  4.61k|            !spvOpcodeIsConstantOrUndef(constituent->opcode())) {
  ------------------
  |  Branch (222:13): [True: 1, False: 4.61k]
  ------------------
  223|      1|          return _.diag(SPV_ERROR_INVALID_ID, inst)
  224|      1|                 << opcode_name << " Constituent <id> "
  225|      1|                 << _.getIdName(constituent_id)
  226|      1|                 << " is not a constant or undef.";
  227|      1|        }
  228|  4.61k|        const auto constituent_type = _.FindDef(constituent->type_id());
  229|  4.61k|        if (!constituent_type) {
  ------------------
  |  Branch (229:13): [True: 0, False: 4.61k]
  ------------------
  230|      0|          return _.diag(SPV_ERROR_INVALID_ID, constituent)
  231|      0|                 << "Result type is not defined.";
  232|      0|        }
  233|       |
  234|  4.61k|        const auto member_type_id =
  235|  4.61k|            result_type->GetOperandAs<uint32_t>(member_index);
  236|  4.61k|        const auto member_type = _.FindDef(member_type_id);
  237|  4.61k|        if (!member_type || member_type->id() != constituent_type->id()) {
  ------------------
  |  Branch (237:13): [True: 0, False: 4.61k]
  |  Branch (237:29): [True: 4, False: 4.60k]
  ------------------
  238|      4|          return _.diag(SPV_ERROR_INVALID_ID, inst)
  239|      4|                 << opcode_name << " Constituent <id> "
  240|      4|                 << _.getIdName(constituent_id)
  241|      4|                 << " type does not match the Result Type <id> "
  242|      4|                 << _.getIdName(result_type->id()) << "s member type.";
  243|      4|        }
  244|  4.61k|      }
  245|  1.55k|    } break;
  246|  1.54k|    case spv::Op::OpTypeCooperativeMatrixNV: {
  ------------------
  |  Branch (246:5): [True: 0, False: 2.84k]
  ------------------
  247|      0|      if (1 != constituent_count) {
  ------------------
  |  Branch (247:11): [True: 0, False: 0]
  ------------------
  248|      0|        return _.diag(SPV_ERROR_INVALID_ID, inst)
  249|      0|               << opcode_name << " Constituent <id> "
  250|      0|               << _.getIdName(inst->type_id()) << " count must be one.";
  251|      0|      }
  252|      0|      const auto constituent_id = inst->GetOperandAs<uint32_t>(2);
  253|      0|      const auto constituent = _.FindDef(constituent_id);
  254|      0|      if (!constituent || !spvOpcodeIsConstantOrUndef(constituent->opcode())) {
  ------------------
  |  Branch (254:11): [True: 0, False: 0]
  |  Branch (254:27): [True: 0, False: 0]
  ------------------
  255|      0|        return _.diag(SPV_ERROR_INVALID_ID, inst)
  256|      0|               << opcode_name << " Constituent <id> "
  257|      0|               << _.getIdName(constituent_id) << " is not a constant or undef.";
  258|      0|      }
  259|      0|      const auto constituent_type = _.FindDef(constituent->type_id());
  260|      0|      if (!constituent_type) {
  ------------------
  |  Branch (260:11): [True: 0, False: 0]
  ------------------
  261|      0|        return _.diag(SPV_ERROR_INVALID_ID, constituent)
  262|      0|               << "Result type is not defined.";
  263|      0|      }
  264|       |
  265|      0|      const auto component_type_id = result_type->GetOperandAs<uint32_t>(1);
  266|      0|      const auto component_type = _.FindDef(component_type_id);
  267|      0|      if (!component_type || component_type->id() != constituent_type->id()) {
  ------------------
  |  Branch (267:11): [True: 0, False: 0]
  |  Branch (267:30): [True: 0, False: 0]
  ------------------
  268|      0|        return _.diag(SPV_ERROR_INVALID_ID, inst)
  269|      0|               << opcode_name << " Constituent <id> "
  270|      0|               << _.getIdName(constituent_id)
  271|      0|               << " type does not match the Result Type <id> "
  272|      0|               << _.getIdName(result_type->id()) << "s component type.";
  273|      0|      }
  274|      0|    } break;
  275|      0|    default:
  ------------------
  |  Branch (275:5): [True: 0, False: 2.84k]
  ------------------
  276|      0|      break;
  277|  2.84k|  }
  278|  2.80k|  return SPV_SUCCESS;
  279|  2.84k|}
validate_constants.cpp:_ZN8spvtools3val12_GLOBAL__N_120ValidateConstantNullERNS0_17ValidationState_tEPKNS0_11InstructionE:
  337|    153|                                  const Instruction* inst) {
  338|    153|  const auto result_type = _.FindDef(inst->type_id());
  339|    153|  if (!result_type || !IsTypeNullable(result_type->words(), _)) {
  ------------------
  |  Branch (339:7): [True: 0, False: 153]
  |  Branch (339:23): [True: 1, False: 152]
  ------------------
  340|      1|    return _.diag(SPV_ERROR_INVALID_ID, inst)
  341|      1|           << "OpConstantNull Result Type <id> " << _.getIdName(inst->type_id())
  342|      1|           << " cannot have a null value.";
  343|      1|  }
  344|       |
  345|    152|  return SPV_SUCCESS;
  346|    153|}
validate_constants.cpp:_ZN8spvtools3val12_GLOBAL__N_114IsTypeNullableERKNSt3__16vectorIjNS2_9allocatorIjEEEERKNS0_17ValidationState_tE:
  297|    264|                    const ValidationState_t& _) {
  298|    264|  uint16_t opcode;
  299|    264|  uint16_t word_count;
  300|    264|  spvOpcodeSplit(instruction[0], &word_count, &opcode);
  301|    264|  switch (static_cast<spv::Op>(opcode)) {
  302|     67|    case spv::Op::OpTypeBool:
  ------------------
  |  Branch (302:5): [True: 67, False: 197]
  ------------------
  303|    167|    case spv::Op::OpTypeInt:
  ------------------
  |  Branch (303:5): [True: 100, False: 164]
  ------------------
  304|    196|    case spv::Op::OpTypeFloat:
  ------------------
  |  Branch (304:5): [True: 29, False: 235]
  ------------------
  305|    202|    case spv::Op::OpTypeEvent:
  ------------------
  |  Branch (305:5): [True: 6, False: 258]
  ------------------
  306|    202|    case spv::Op::OpTypeDeviceEvent:
  ------------------
  |  Branch (306:5): [True: 0, False: 264]
  ------------------
  307|    202|    case spv::Op::OpTypeReserveId:
  ------------------
  |  Branch (307:5): [True: 0, False: 264]
  ------------------
  308|    202|    case spv::Op::OpTypeQueue:
  ------------------
  |  Branch (308:5): [True: 0, False: 264]
  ------------------
  309|    202|      return true;
  310|      2|    case spv::Op::OpTypeArray:
  ------------------
  |  Branch (310:5): [True: 2, False: 262]
  ------------------
  311|      2|    case spv::Op::OpTypeMatrix:
  ------------------
  |  Branch (311:5): [True: 0, False: 264]
  ------------------
  312|      2|    case spv::Op::OpTypeCooperativeMatrixNV:
  ------------------
  |  Branch (312:5): [True: 0, False: 264]
  ------------------
  313|      6|    case spv::Op::OpTypeVector: {
  ------------------
  |  Branch (313:5): [True: 4, False: 260]
  ------------------
  314|      6|      auto base_type = _.FindDef(instruction[2]);
  315|      6|      return base_type && IsTypeNullable(base_type->words(), _);
  ------------------
  |  Branch (315:14): [True: 6, False: 0]
  |  Branch (315:27): [True: 6, False: 0]
  ------------------
  316|      2|    }
  317|     49|    case spv::Op::OpTypeStruct: {
  ------------------
  |  Branch (317:5): [True: 49, False: 215]
  ------------------
  318|    154|      for (size_t elementIndex = 2; elementIndex < instruction.size();
  ------------------
  |  Branch (318:37): [True: 105, False: 49]
  ------------------
  319|    105|           ++elementIndex) {
  320|    105|        auto element = _.FindDef(instruction[elementIndex]);
  321|    105|        if (!element || !IsTypeNullable(element->words(), _)) return false;
  ------------------
  |  Branch (321:13): [True: 0, False: 105]
  |  Branch (321:25): [True: 0, False: 105]
  ------------------
  322|    105|      }
  323|     49|      return true;
  324|     49|    }
  325|      6|    case spv::Op::OpTypePointer:
  ------------------
  |  Branch (325:5): [True: 6, False: 258]
  ------------------
  326|      6|      if (spv::StorageClass(instruction[2]) ==
  ------------------
  |  Branch (326:11): [True: 0, False: 6]
  ------------------
  327|      6|          spv::StorageClass::PhysicalStorageBuffer) {
  328|      0|        return false;
  329|      0|      }
  330|      6|      return true;
  331|      1|    default:
  ------------------
  |  Branch (331:5): [True: 1, False: 263]
  ------------------
  332|      1|      return false;
  333|    264|  }
  334|    264|}
validate_constants.cpp:_ZN8spvtools3val12_GLOBAL__N_120ValidateSpecConstantERNS0_17ValidationState_tEPKNS0_11InstructionE:
  350|    255|                                  const Instruction* inst) {
  351|       |  // Operand 0 is the <id> of the type that we're specializing to.
  352|    255|  auto type_id = inst->GetOperandAs<const uint32_t>(0);
  353|    255|  auto type_instruction = _.FindDef(type_id);
  354|    255|  auto type_opcode = type_instruction->opcode();
  355|    255|  if (type_opcode != spv::Op::OpTypeInt &&
  ------------------
  |  Branch (355:7): [True: 61, False: 194]
  ------------------
  356|    255|      type_opcode != spv::Op::OpTypeFloat) {
  ------------------
  |  Branch (356:7): [True: 0, False: 61]
  ------------------
  357|      0|    return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Specialization constant "
  358|      0|                                                   "must be an integer or "
  359|      0|                                                   "floating-point number.";
  360|      0|  }
  361|    255|  return SPV_SUCCESS;
  362|    255|}
validate_constants.cpp:_ZN8spvtools3val12_GLOBAL__N_122ValidateSpecConstantOpERNS0_17ValidationState_tEPKNS0_11InstructionE:
  365|     19|                                    const Instruction* inst) {
  366|     19|  const auto op = inst->GetOperandAs<spv::Op>(2);
  367|       |
  368|       |  // The binary parser already ensures that the op is valid for *some*
  369|       |  // environment.  Here we check restrictions.
  370|     19|  switch (op) {
  371|      0|    case spv::Op::OpQuantizeToF16:
  ------------------
  |  Branch (371:5): [True: 0, False: 19]
  ------------------
  372|      0|      if (!_.HasCapability(spv::Capability::Shader)) {
  ------------------
  |  Branch (372:11): [True: 0, False: 0]
  ------------------
  373|      0|        return _.diag(SPV_ERROR_INVALID_ID, inst)
  374|      0|               << "Specialization constant operation " << spvOpcodeString(op)
  375|      0|               << " requires Shader capability";
  376|      0|      }
  377|      0|      break;
  378|       |
  379|      2|    case spv::Op::OpUConvert:
  ------------------
  |  Branch (379:5): [True: 2, False: 17]
  ------------------
  380|      2|      if (!_.features().uconvert_spec_constant_op &&
  ------------------
  |  Branch (380:11): [True: 2, False: 0]
  ------------------
  381|      2|          !_.HasCapability(spv::Capability::Kernel)) {
  ------------------
  |  Branch (381:11): [True: 1, False: 1]
  ------------------
  382|      1|        return _.diag(SPV_ERROR_INVALID_ID, inst)
  383|      1|               << "Prior to SPIR-V 1.4, specialization constant operation "
  384|      1|                  "UConvert requires Kernel capability or extension "
  385|      1|                  "SPV_AMD_gpu_shader_int16";
  386|      1|      }
  387|      1|      break;
  388|       |
  389|      1|    case spv::Op::OpConvertFToS:
  ------------------
  |  Branch (389:5): [True: 0, False: 19]
  ------------------
  390|      1|    case spv::Op::OpConvertSToF:
  ------------------
  |  Branch (390:5): [True: 1, False: 18]
  ------------------
  391|      1|    case spv::Op::OpConvertFToU:
  ------------------
  |  Branch (391:5): [True: 0, False: 19]
  ------------------
  392|      1|    case spv::Op::OpConvertUToF:
  ------------------
  |  Branch (392:5): [True: 0, False: 19]
  ------------------
  393|      2|    case spv::Op::OpConvertPtrToU:
  ------------------
  |  Branch (393:5): [True: 1, False: 18]
  ------------------
  394|      2|    case spv::Op::OpConvertUToPtr:
  ------------------
  |  Branch (394:5): [True: 0, False: 19]
  ------------------
  395|      3|    case spv::Op::OpGenericCastToPtr:
  ------------------
  |  Branch (395:5): [True: 1, False: 18]
  ------------------
  396|      4|    case spv::Op::OpPtrCastToGeneric:
  ------------------
  |  Branch (396:5): [True: 1, False: 18]
  ------------------
  397|      4|    case spv::Op::OpBitcast:
  ------------------
  |  Branch (397:5): [True: 0, False: 19]
  ------------------
  398|      4|    case spv::Op::OpFNegate:
  ------------------
  |  Branch (398:5): [True: 0, False: 19]
  ------------------
  399|      4|    case spv::Op::OpFAdd:
  ------------------
  |  Branch (399:5): [True: 0, False: 19]
  ------------------
  400|      5|    case spv::Op::OpFSub:
  ------------------
  |  Branch (400:5): [True: 1, False: 18]
  ------------------
  401|      5|    case spv::Op::OpFMul:
  ------------------
  |  Branch (401:5): [True: 0, False: 19]
  ------------------
  402|      5|    case spv::Op::OpFDiv:
  ------------------
  |  Branch (402:5): [True: 0, False: 19]
  ------------------
  403|      5|    case spv::Op::OpFRem:
  ------------------
  |  Branch (403:5): [True: 0, False: 19]
  ------------------
  404|      6|    case spv::Op::OpFMod:
  ------------------
  |  Branch (404:5): [True: 1, False: 18]
  ------------------
  405|      7|    case spv::Op::OpAccessChain:
  ------------------
  |  Branch (405:5): [True: 1, False: 18]
  ------------------
  406|      7|    case spv::Op::OpInBoundsAccessChain:
  ------------------
  |  Branch (406:5): [True: 0, False: 19]
  ------------------
  407|      7|    case spv::Op::OpPtrAccessChain:
  ------------------
  |  Branch (407:5): [True: 0, False: 19]
  ------------------
  408|      8|    case spv::Op::OpInBoundsPtrAccessChain:
  ------------------
  |  Branch (408:5): [True: 1, False: 18]
  ------------------
  409|      8|      if (!_.HasCapability(spv::Capability::Kernel)) {
  ------------------
  |  Branch (409:11): [True: 7, False: 1]
  ------------------
  410|      7|        return _.diag(SPV_ERROR_INVALID_ID, inst)
  411|      7|               << "Specialization constant operation " << spvOpcodeString(op)
  412|      7|               << " requires Kernel capability";
  413|      7|      }
  414|      1|      break;
  415|       |
  416|      9|    default:
  ------------------
  |  Branch (416:5): [True: 9, False: 10]
  ------------------
  417|      9|      break;
  418|     19|  }
  419|       |
  420|       |  // TODO(dneto): Validate result type and arguments to the various operations.
  421|     11|  return SPV_SUCCESS;
  422|     19|}

_ZN8spvtools3val14ConversionPassERNS0_17ValidationState_tEPKNS0_11InstructionE:
   29|   285k|spv_result_t ConversionPass(ValidationState_t& _, const Instruction* inst) {
   30|   285k|  const spv::Op opcode = inst->opcode();
   31|   285k|  const uint32_t result_type = inst->type_id();
   32|       |
   33|   285k|  switch (opcode) {
   34|     10|    case spv::Op::OpConvertFToU: {
  ------------------
  |  Branch (34:5): [True: 10, False: 285k]
  ------------------
   35|     10|      if (!_.IsUnsignedIntScalarType(result_type) &&
  ------------------
  |  Branch (35:11): [True: 10, False: 0]
  ------------------
   36|     10|          !_.IsUnsignedIntVectorType(result_type) &&
  ------------------
  |  Branch (36:11): [True: 5, False: 5]
  ------------------
   37|     10|          !_.IsUnsignedIntCooperativeMatrixType(result_type))
  ------------------
  |  Branch (37:11): [True: 5, False: 0]
  ------------------
   38|      5|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
   39|      5|               << "Expected unsigned int scalar or vector type as Result Type: "
   40|      5|               << spvOpcodeString(opcode);
   41|       |
   42|      5|      const uint32_t input_type = _.GetOperandTypeId(inst, 2);
   43|      5|      if (!input_type || (!_.IsFloatScalarType(input_type) &&
  ------------------
  |  Branch (43:11): [True: 0, False: 5]
  |  Branch (43:27): [True: 5, False: 0]
  ------------------
   44|      5|                          !_.IsFloatVectorType(input_type) &&
  ------------------
  |  Branch (44:27): [True: 0, False: 5]
  ------------------
   45|      5|                          !_.IsFloatCooperativeMatrixType(input_type)))
  ------------------
  |  Branch (45:27): [True: 0, False: 0]
  ------------------
   46|      0|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
   47|      0|               << "Expected input to be float scalar or vector: "
   48|      0|               << spvOpcodeString(opcode);
   49|       |
   50|      5|      if (_.IsCooperativeMatrixType(result_type) ||
  ------------------
  |  Branch (50:11): [True: 0, False: 5]
  ------------------
   51|      5|          _.IsCooperativeMatrixType(input_type)) {
  ------------------
  |  Branch (51:11): [True: 0, False: 5]
  ------------------
   52|      0|        spv_result_t ret =
   53|      0|            _.CooperativeMatrixShapesMatch(inst, result_type, input_type);
   54|      0|        if (ret != SPV_SUCCESS) return ret;
  ------------------
  |  Branch (54:13): [True: 0, False: 0]
  ------------------
   55|      5|      } else {
   56|      5|        if (_.GetDimension(result_type) != _.GetDimension(input_type))
  ------------------
  |  Branch (56:13): [True: 0, False: 5]
  ------------------
   57|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
   58|      0|                 << "Expected input to have the same dimension as Result Type: "
   59|      0|                 << spvOpcodeString(opcode);
   60|      5|      }
   61|       |
   62|      5|      break;
   63|      5|    }
   64|       |
   65|    538|    case spv::Op::OpConvertFToS: {
  ------------------
  |  Branch (65:5): [True: 538, False: 285k]
  ------------------
   66|    538|      if (!_.IsIntScalarType(result_type) && !_.IsIntVectorType(result_type) &&
  ------------------
  |  Branch (66:11): [True: 26, False: 512]
  |  Branch (66:46): [True: 1, False: 25]
  ------------------
   67|    538|          !_.IsIntCooperativeMatrixType(result_type))
  ------------------
  |  Branch (67:11): [True: 1, False: 0]
  ------------------
   68|      1|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
   69|      1|               << "Expected int scalar or vector type as Result Type: "
   70|      1|               << spvOpcodeString(opcode);
   71|       |
   72|    537|      const uint32_t input_type = _.GetOperandTypeId(inst, 2);
   73|    537|      if (!input_type || (!_.IsFloatScalarType(input_type) &&
  ------------------
  |  Branch (73:11): [True: 0, False: 537]
  |  Branch (73:27): [True: 25, False: 512]
  ------------------
   74|    537|                          !_.IsFloatVectorType(input_type) &&
  ------------------
  |  Branch (74:27): [True: 0, False: 25]
  ------------------
   75|    537|                          !_.IsFloatCooperativeMatrixType(input_type)))
  ------------------
  |  Branch (75:27): [True: 0, False: 0]
  ------------------
   76|      0|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
   77|      0|               << "Expected input to be float scalar or vector: "
   78|      0|               << spvOpcodeString(opcode);
   79|       |
   80|    537|      if (_.IsCooperativeMatrixType(result_type) ||
  ------------------
  |  Branch (80:11): [True: 0, False: 537]
  ------------------
   81|    537|          _.IsCooperativeMatrixType(input_type)) {
  ------------------
  |  Branch (81:11): [True: 0, False: 537]
  ------------------
   82|      0|        spv_result_t ret =
   83|      0|            _.CooperativeMatrixShapesMatch(inst, result_type, input_type);
   84|      0|        if (ret != SPV_SUCCESS) return ret;
  ------------------
  |  Branch (84:13): [True: 0, False: 0]
  ------------------
   85|    537|      } else {
   86|    537|        if (_.GetDimension(result_type) != _.GetDimension(input_type))
  ------------------
  |  Branch (86:13): [True: 0, False: 537]
  ------------------
   87|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
   88|      0|                 << "Expected input to have the same dimension as Result Type: "
   89|      0|                 << spvOpcodeString(opcode);
   90|    537|      }
   91|       |
   92|    537|      break;
   93|    537|    }
   94|       |
   95|  1.00k|    case spv::Op::OpConvertSToF:
  ------------------
  |  Branch (95:5): [True: 1.00k, False: 284k]
  ------------------
   96|  1.01k|    case spv::Op::OpConvertUToF: {
  ------------------
  |  Branch (96:5): [True: 9, False: 285k]
  ------------------
   97|  1.01k|      if (!_.IsFloatScalarType(result_type) &&
  ------------------
  |  Branch (97:11): [True: 6, False: 1.01k]
  ------------------
   98|  1.01k|          !_.IsFloatVectorType(result_type) &&
  ------------------
  |  Branch (98:11): [True: 4, False: 2]
  ------------------
   99|  1.01k|          !_.IsFloatCooperativeMatrixType(result_type))
  ------------------
  |  Branch (99:11): [True: 4, False: 0]
  ------------------
  100|      4|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
  101|      4|               << "Expected float scalar or vector type as Result Type: "
  102|      4|               << spvOpcodeString(opcode);
  103|       |
  104|  1.01k|      const uint32_t input_type = _.GetOperandTypeId(inst, 2);
  105|  1.01k|      if (!input_type ||
  ------------------
  |  Branch (105:11): [True: 0, False: 1.01k]
  ------------------
  106|  1.01k|          (!_.IsIntScalarType(input_type) && !_.IsIntVectorType(input_type) &&
  ------------------
  |  Branch (106:12): [True: 1, False: 1.01k]
  |  Branch (106:46): [True: 1, False: 0]
  ------------------
  107|  1.01k|           !_.IsIntCooperativeMatrixType(input_type)))
  ------------------
  |  Branch (107:12): [True: 1, False: 0]
  ------------------
  108|      1|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
  109|      1|               << "Expected input to be int scalar or vector: "
  110|      1|               << spvOpcodeString(opcode);
  111|       |
  112|  1.01k|      if (_.IsCooperativeMatrixType(result_type) ||
  ------------------
  |  Branch (112:11): [True: 0, False: 1.01k]
  ------------------
  113|  1.01k|          _.IsCooperativeMatrixType(input_type)) {
  ------------------
  |  Branch (113:11): [True: 0, False: 1.01k]
  ------------------
  114|      0|        spv_result_t ret =
  115|      0|            _.CooperativeMatrixShapesMatch(inst, result_type, input_type);
  116|      0|        if (ret != SPV_SUCCESS) return ret;
  ------------------
  |  Branch (116:13): [True: 0, False: 0]
  ------------------
  117|  1.01k|      } else {
  118|  1.01k|        if (_.GetDimension(result_type) != _.GetDimension(input_type))
  ------------------
  |  Branch (118:13): [True: 1, False: 1.01k]
  ------------------
  119|      1|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
  120|      1|                 << "Expected input to have the same dimension as Result Type: "
  121|      1|                 << spvOpcodeString(opcode);
  122|  1.01k|      }
  123|       |
  124|  1.01k|      break;
  125|  1.01k|    }
  126|       |
  127|  1.01k|    case spv::Op::OpUConvert: {
  ------------------
  |  Branch (127:5): [True: 4, False: 285k]
  ------------------
  128|      4|      if (!_.IsUnsignedIntScalarType(result_type) &&
  ------------------
  |  Branch (128:11): [True: 3, False: 1]
  ------------------
  129|      4|          !_.IsUnsignedIntVectorType(result_type) &&
  ------------------
  |  Branch (129:11): [True: 3, False: 0]
  ------------------
  130|      4|          !_.IsUnsignedIntCooperativeMatrixType(result_type))
  ------------------
  |  Branch (130:11): [True: 3, False: 0]
  ------------------
  131|      3|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
  132|      3|               << "Expected unsigned int scalar or vector type as Result Type: "
  133|      3|               << spvOpcodeString(opcode);
  134|       |
  135|      1|      const uint32_t input_type = _.GetOperandTypeId(inst, 2);
  136|      1|      if (!input_type ||
  ------------------
  |  Branch (136:11): [True: 0, False: 1]
  ------------------
  137|      1|          (!_.IsIntScalarType(input_type) && !_.IsIntVectorType(input_type) &&
  ------------------
  |  Branch (137:12): [True: 0, False: 1]
  |  Branch (137:46): [True: 0, False: 0]
  ------------------
  138|      1|           !_.IsIntCooperativeMatrixType(input_type)))
  ------------------
  |  Branch (138:12): [True: 0, False: 0]
  ------------------
  139|      0|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
  140|      0|               << "Expected input to be int scalar or vector: "
  141|      0|               << spvOpcodeString(opcode);
  142|       |
  143|      1|      if (_.IsCooperativeMatrixType(result_type) ||
  ------------------
  |  Branch (143:11): [True: 0, False: 1]
  ------------------
  144|      1|          _.IsCooperativeMatrixType(input_type)) {
  ------------------
  |  Branch (144:11): [True: 0, False: 1]
  ------------------
  145|      0|        spv_result_t ret =
  146|      0|            _.CooperativeMatrixShapesMatch(inst, result_type, input_type);
  147|      0|        if (ret != SPV_SUCCESS) return ret;
  ------------------
  |  Branch (147:13): [True: 0, False: 0]
  ------------------
  148|      1|      } else {
  149|      1|        if (_.GetDimension(result_type) != _.GetDimension(input_type))
  ------------------
  |  Branch (149:13): [True: 0, False: 1]
  ------------------
  150|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
  151|      0|                 << "Expected input to have the same dimension as Result Type: "
  152|      0|                 << spvOpcodeString(opcode);
  153|      1|      }
  154|       |
  155|      1|      if (_.GetBitWidth(result_type) == _.GetBitWidth(input_type))
  ------------------
  |  Branch (155:11): [True: 1, False: 0]
  ------------------
  156|      1|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
  157|      1|               << "Expected input to have different bit width from Result "
  158|      1|                  "Type: "
  159|      1|               << spvOpcodeString(opcode);
  160|      0|      break;
  161|      1|    }
  162|       |
  163|      3|    case spv::Op::OpSConvert: {
  ------------------
  |  Branch (163:5): [True: 3, False: 285k]
  ------------------
  164|      3|      if (!_.IsIntScalarType(result_type) && !_.IsIntVectorType(result_type) &&
  ------------------
  |  Branch (164:11): [True: 2, False: 1]
  |  Branch (164:46): [True: 2, False: 0]
  ------------------
  165|      3|          !_.IsIntCooperativeMatrixType(result_type))
  ------------------
  |  Branch (165:11): [True: 2, False: 0]
  ------------------
  166|      2|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
  167|      2|               << "Expected int scalar or vector type as Result Type: "
  168|      2|               << spvOpcodeString(opcode);
  169|       |
  170|      1|      const uint32_t input_type = _.GetOperandTypeId(inst, 2);
  171|      1|      if (!input_type ||
  ------------------
  |  Branch (171:11): [True: 0, False: 1]
  ------------------
  172|      1|          (!_.IsIntScalarType(input_type) && !_.IsIntVectorType(input_type) &&
  ------------------
  |  Branch (172:12): [True: 1, False: 0]
  |  Branch (172:46): [True: 1, False: 0]
  ------------------
  173|      1|           !_.IsIntCooperativeMatrixType(input_type)))
  ------------------
  |  Branch (173:12): [True: 1, False: 0]
  ------------------
  174|      1|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
  175|      1|               << "Expected input to be int scalar or vector: "
  176|      1|               << spvOpcodeString(opcode);
  177|       |
  178|      0|      if (_.IsCooperativeMatrixType(result_type) ||
  ------------------
  |  Branch (178:11): [True: 0, False: 0]
  ------------------
  179|      0|          _.IsCooperativeMatrixType(input_type)) {
  ------------------
  |  Branch (179:11): [True: 0, False: 0]
  ------------------
  180|      0|        spv_result_t ret =
  181|      0|            _.CooperativeMatrixShapesMatch(inst, result_type, input_type);
  182|      0|        if (ret != SPV_SUCCESS) return ret;
  ------------------
  |  Branch (182:13): [True: 0, False: 0]
  ------------------
  183|      0|      } else {
  184|      0|        if (_.GetDimension(result_type) != _.GetDimension(input_type))
  ------------------
  |  Branch (184:13): [True: 0, False: 0]
  ------------------
  185|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
  186|      0|                 << "Expected input to have the same dimension as Result Type: "
  187|      0|                 << spvOpcodeString(opcode);
  188|      0|      }
  189|       |
  190|      0|      if (_.GetBitWidth(result_type) == _.GetBitWidth(input_type))
  ------------------
  |  Branch (190:11): [True: 0, False: 0]
  ------------------
  191|      0|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
  192|      0|               << "Expected input to have different bit width from Result "
  193|      0|                  "Type: "
  194|      0|               << spvOpcodeString(opcode);
  195|      0|      break;
  196|      0|    }
  197|       |
  198|      1|    case spv::Op::OpFConvert: {
  ------------------
  |  Branch (198:5): [True: 1, False: 285k]
  ------------------
  199|      1|      if (!_.IsFloatScalarType(result_type) &&
  ------------------
  |  Branch (199:11): [True: 1, False: 0]
  ------------------
  200|      1|          !_.IsFloatVectorType(result_type) &&
  ------------------
  |  Branch (200:11): [True: 0, False: 1]
  ------------------
  201|      1|          !_.IsFloatCooperativeMatrixType(result_type))
  ------------------
  |  Branch (201:11): [True: 0, False: 0]
  ------------------
  202|      0|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
  203|      0|               << "Expected float scalar or vector type as Result Type: "
  204|      0|               << spvOpcodeString(opcode);
  205|       |
  206|      1|      const uint32_t input_type = _.GetOperandTypeId(inst, 2);
  207|      1|      if (!input_type || (!_.IsFloatScalarType(input_type) &&
  ------------------
  |  Branch (207:11): [True: 0, False: 1]
  |  Branch (207:27): [True: 1, False: 0]
  ------------------
  208|      1|                          !_.IsFloatVectorType(input_type) &&
  ------------------
  |  Branch (208:27): [True: 0, False: 1]
  ------------------
  209|      1|                          !_.IsFloatCooperativeMatrixType(input_type)))
  ------------------
  |  Branch (209:27): [True: 0, False: 0]
  ------------------
  210|      0|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
  211|      0|               << "Expected input to be float scalar or vector: "
  212|      0|               << spvOpcodeString(opcode);
  213|       |
  214|      1|      if (_.IsCooperativeMatrixType(result_type) ||
  ------------------
  |  Branch (214:11): [True: 0, False: 1]
  ------------------
  215|      1|          _.IsCooperativeMatrixType(input_type)) {
  ------------------
  |  Branch (215:11): [True: 0, False: 1]
  ------------------
  216|      0|        spv_result_t ret =
  217|      0|            _.CooperativeMatrixShapesMatch(inst, result_type, input_type);
  218|      0|        if (ret != SPV_SUCCESS) return ret;
  ------------------
  |  Branch (218:13): [True: 0, False: 0]
  ------------------
  219|      1|      } else {
  220|      1|        if (_.GetDimension(result_type) != _.GetDimension(input_type))
  ------------------
  |  Branch (220:13): [True: 0, False: 1]
  ------------------
  221|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
  222|      0|                 << "Expected input to have the same dimension as Result Type: "
  223|      0|                 << spvOpcodeString(opcode);
  224|      1|      }
  225|       |
  226|      1|      if (_.GetBitWidth(result_type) == _.GetBitWidth(input_type))
  ------------------
  |  Branch (226:11): [True: 1, False: 0]
  ------------------
  227|      1|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
  228|      1|               << "Expected input to have different bit width from Result "
  229|      1|                  "Type: "
  230|      1|               << spvOpcodeString(opcode);
  231|      0|      break;
  232|      1|    }
  233|       |
  234|     10|    case spv::Op::OpQuantizeToF16: {
  ------------------
  |  Branch (234:5): [True: 10, False: 285k]
  ------------------
  235|     10|      if ((!_.IsFloatScalarType(result_type) &&
  ------------------
  |  Branch (235:12): [True: 3, False: 7]
  ------------------
  236|     10|           !_.IsFloatVectorType(result_type)) ||
  ------------------
  |  Branch (236:12): [True: 0, False: 3]
  ------------------
  237|     10|          _.GetBitWidth(result_type) != 32)
  ------------------
  |  Branch (237:11): [True: 1, False: 9]
  ------------------
  238|      1|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
  239|      1|               << "Expected 32-bit float scalar or vector type as Result Type: "
  240|      1|               << spvOpcodeString(opcode);
  241|       |
  242|      9|      const uint32_t input_type = _.GetOperandTypeId(inst, 2);
  243|      9|      if (input_type != result_type)
  ------------------
  |  Branch (243:11): [True: 5, False: 4]
  ------------------
  244|      5|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
  245|      5|               << "Expected input type to be equal to Result Type: "
  246|      5|               << spvOpcodeString(opcode);
  247|      4|      break;
  248|      9|    }
  249|       |
  250|      4|    case spv::Op::OpConvertPtrToU: {
  ------------------
  |  Branch (250:5): [True: 1, False: 285k]
  ------------------
  251|      1|      if (!_.IsUnsignedIntScalarType(result_type))
  ------------------
  |  Branch (251:11): [True: 1, False: 0]
  ------------------
  252|      1|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
  253|      1|               << "Expected unsigned int scalar type as Result Type: "
  254|      1|               << spvOpcodeString(opcode);
  255|       |
  256|      0|      const uint32_t input_type = _.GetOperandTypeId(inst, 2);
  257|      0|      if (!_.IsPointerType(input_type))
  ------------------
  |  Branch (257:11): [True: 0, False: 0]
  ------------------
  258|      0|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
  259|      0|               << "Expected input to be a pointer: " << spvOpcodeString(opcode);
  260|       |
  261|      0|      if (_.addressing_model() == spv::AddressingModel::Logical)
  ------------------
  |  Branch (261:11): [True: 0, False: 0]
  ------------------
  262|      0|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
  263|      0|               << "Logical addressing not supported: "
  264|      0|               << spvOpcodeString(opcode);
  265|       |
  266|      0|      if (_.addressing_model() ==
  ------------------
  |  Branch (266:11): [True: 0, False: 0]
  ------------------
  267|      0|          spv::AddressingModel::PhysicalStorageBuffer64) {
  268|      0|        spv::StorageClass input_storage_class;
  269|      0|        uint32_t input_data_type = 0;
  270|      0|        _.GetPointerTypeInfo(input_type, &input_data_type,
  271|      0|                             &input_storage_class);
  272|      0|        if (input_storage_class != spv::StorageClass::PhysicalStorageBuffer)
  ------------------
  |  Branch (272:13): [True: 0, False: 0]
  ------------------
  273|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
  274|      0|                 << "Pointer storage class must be PhysicalStorageBuffer: "
  275|      0|                 << spvOpcodeString(opcode);
  276|       |
  277|      0|        if (spvIsVulkanEnv(_.context()->target_env)) {
  ------------------
  |  Branch (277:13): [True: 0, False: 0]
  ------------------
  278|      0|          if (_.GetBitWidth(result_type) != 64) {
  ------------------
  |  Branch (278:15): [True: 0, False: 0]
  ------------------
  279|      0|            return _.diag(SPV_ERROR_INVALID_DATA, inst)
  280|      0|                   << _.VkErrorID(4710)
  281|      0|                   << "PhysicalStorageBuffer64 addressing mode requires the "
  282|      0|                      "result integer type to have a 64-bit width for Vulkan "
  283|      0|                      "environment.";
  284|      0|          }
  285|      0|        }
  286|      0|      }
  287|      0|      break;
  288|      0|    }
  289|       |
  290|      0|    case spv::Op::OpSatConvertSToU:
  ------------------
  |  Branch (290:5): [True: 0, False: 285k]
  ------------------
  291|      0|    case spv::Op::OpSatConvertUToS: {
  ------------------
  |  Branch (291:5): [True: 0, False: 285k]
  ------------------
  292|      0|      if (!_.IsIntScalarType(result_type) && !_.IsIntVectorType(result_type))
  ------------------
  |  Branch (292:11): [True: 0, False: 0]
  |  Branch (292:46): [True: 0, False: 0]
  ------------------
  293|      0|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
  294|      0|               << "Expected int scalar or vector type as Result Type: "
  295|      0|               << spvOpcodeString(opcode);
  296|       |
  297|      0|      const uint32_t input_type = _.GetOperandTypeId(inst, 2);
  298|      0|      if (!input_type ||
  ------------------
  |  Branch (298:11): [True: 0, False: 0]
  ------------------
  299|      0|          (!_.IsIntScalarType(input_type) && !_.IsIntVectorType(input_type)))
  ------------------
  |  Branch (299:12): [True: 0, False: 0]
  |  Branch (299:46): [True: 0, False: 0]
  ------------------
  300|      0|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
  301|      0|               << "Expected int scalar or vector as input: "
  302|      0|               << spvOpcodeString(opcode);
  303|       |
  304|      0|      if (_.GetDimension(result_type) != _.GetDimension(input_type))
  ------------------
  |  Branch (304:11): [True: 0, False: 0]
  ------------------
  305|      0|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
  306|      0|               << "Expected input to have the same dimension as Result Type: "
  307|      0|               << spvOpcodeString(opcode);
  308|      0|      break;
  309|      0|    }
  310|       |
  311|      1|    case spv::Op::OpConvertUToPtr: {
  ------------------
  |  Branch (311:5): [True: 1, False: 285k]
  ------------------
  312|      1|      if (!_.IsPointerType(result_type))
  ------------------
  |  Branch (312:11): [True: 1, False: 0]
  ------------------
  313|      1|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
  314|      1|               << "Expected Result Type to be a pointer: "
  315|      1|               << spvOpcodeString(opcode);
  316|       |
  317|      0|      const uint32_t input_type = _.GetOperandTypeId(inst, 2);
  318|      0|      if (!input_type || !_.IsIntScalarType(input_type))
  ------------------
  |  Branch (318:11): [True: 0, False: 0]
  |  Branch (318:26): [True: 0, False: 0]
  ------------------
  319|      0|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
  320|      0|               << "Expected int scalar as input: " << spvOpcodeString(opcode);
  321|       |
  322|      0|      if (_.addressing_model() == spv::AddressingModel::Logical)
  ------------------
  |  Branch (322:11): [True: 0, False: 0]
  ------------------
  323|      0|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
  324|      0|               << "Logical addressing not supported: "
  325|      0|               << spvOpcodeString(opcode);
  326|       |
  327|      0|      if (_.addressing_model() ==
  ------------------
  |  Branch (327:11): [True: 0, False: 0]
  ------------------
  328|      0|          spv::AddressingModel::PhysicalStorageBuffer64) {
  329|      0|        spv::StorageClass result_storage_class;
  330|      0|        uint32_t result_data_type = 0;
  331|      0|        _.GetPointerTypeInfo(result_type, &result_data_type,
  332|      0|                             &result_storage_class);
  333|      0|        if (result_storage_class != spv::StorageClass::PhysicalStorageBuffer)
  ------------------
  |  Branch (333:13): [True: 0, False: 0]
  ------------------
  334|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
  335|      0|                 << "Pointer storage class must be PhysicalStorageBuffer: "
  336|      0|                 << spvOpcodeString(opcode);
  337|       |
  338|      0|        if (spvIsVulkanEnv(_.context()->target_env)) {
  ------------------
  |  Branch (338:13): [True: 0, False: 0]
  ------------------
  339|      0|          if (_.GetBitWidth(input_type) != 64) {
  ------------------
  |  Branch (339:15): [True: 0, False: 0]
  ------------------
  340|      0|            return _.diag(SPV_ERROR_INVALID_DATA, inst)
  341|      0|                   << _.VkErrorID(4710)
  342|      0|                   << "PhysicalStorageBuffer64 addressing mode requires the "
  343|      0|                      "input integer to have a 64-bit width for Vulkan "
  344|      0|                      "environment.";
  345|      0|          }
  346|      0|        }
  347|      0|      }
  348|      0|      break;
  349|      0|    }
  350|       |
  351|      1|    case spv::Op::OpPtrCastToGeneric: {
  ------------------
  |  Branch (351:5): [True: 1, False: 285k]
  ------------------
  352|      1|      spv::StorageClass result_storage_class;
  353|      1|      uint32_t result_data_type = 0;
  354|      1|      if (!_.GetPointerTypeInfo(result_type, &result_data_type,
  ------------------
  |  Branch (354:11): [True: 1, False: 0]
  ------------------
  355|      1|                                &result_storage_class))
  356|      1|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
  357|      1|               << "Expected Result Type to be a pointer: "
  358|      1|               << spvOpcodeString(opcode);
  359|       |
  360|      0|      if (result_storage_class != spv::StorageClass::Generic)
  ------------------
  |  Branch (360:11): [True: 0, False: 0]
  ------------------
  361|      0|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
  362|      0|               << "Expected Result Type to have storage class Generic: "
  363|      0|               << spvOpcodeString(opcode);
  364|       |
  365|      0|      const uint32_t input_type = _.GetOperandTypeId(inst, 2);
  366|      0|      spv::StorageClass input_storage_class;
  367|      0|      uint32_t input_data_type = 0;
  368|      0|      if (!_.GetPointerTypeInfo(input_type, &input_data_type,
  ------------------
  |  Branch (368:11): [True: 0, False: 0]
  ------------------
  369|      0|                                &input_storage_class))
  370|      0|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
  371|      0|               << "Expected input to be a pointer: " << spvOpcodeString(opcode);
  372|       |
  373|      0|      if (input_storage_class != spv::StorageClass::Workgroup &&
  ------------------
  |  Branch (373:11): [True: 0, False: 0]
  ------------------
  374|      0|          input_storage_class != spv::StorageClass::CrossWorkgroup &&
  ------------------
  |  Branch (374:11): [True: 0, False: 0]
  ------------------
  375|      0|          input_storage_class != spv::StorageClass::Function)
  ------------------
  |  Branch (375:11): [True: 0, False: 0]
  ------------------
  376|      0|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
  377|      0|               << "Expected input to have storage class Workgroup, "
  378|      0|               << "CrossWorkgroup or Function: " << spvOpcodeString(opcode);
  379|       |
  380|      0|      if (result_data_type != input_data_type)
  ------------------
  |  Branch (380:11): [True: 0, False: 0]
  ------------------
  381|      0|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
  382|      0|               << "Expected input and Result Type to point to the same type: "
  383|      0|               << spvOpcodeString(opcode);
  384|      0|      break;
  385|      0|    }
  386|       |
  387|      1|    case spv::Op::OpGenericCastToPtr: {
  ------------------
  |  Branch (387:5): [True: 1, False: 285k]
  ------------------
  388|      1|      spv::StorageClass result_storage_class;
  389|      1|      uint32_t result_data_type = 0;
  390|      1|      if (!_.GetPointerTypeInfo(result_type, &result_data_type,
  ------------------
  |  Branch (390:11): [True: 0, False: 1]
  ------------------
  391|      1|                                &result_storage_class))
  392|      0|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
  393|      0|               << "Expected Result Type to be a pointer: "
  394|      0|               << spvOpcodeString(opcode);
  395|       |
  396|      1|      if (result_storage_class != spv::StorageClass::Workgroup &&
  ------------------
  |  Branch (396:11): [True: 1, False: 0]
  ------------------
  397|      1|          result_storage_class != spv::StorageClass::CrossWorkgroup &&
  ------------------
  |  Branch (397:11): [True: 1, False: 0]
  ------------------
  398|      1|          result_storage_class != spv::StorageClass::Function)
  ------------------
  |  Branch (398:11): [True: 1, False: 0]
  ------------------
  399|      1|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
  400|      1|               << "Expected Result Type to have storage class Workgroup, "
  401|      1|               << "CrossWorkgroup or Function: " << spvOpcodeString(opcode);
  402|       |
  403|      0|      const uint32_t input_type = _.GetOperandTypeId(inst, 2);
  404|      0|      spv::StorageClass input_storage_class;
  405|      0|      uint32_t input_data_type = 0;
  406|      0|      if (!_.GetPointerTypeInfo(input_type, &input_data_type,
  ------------------
  |  Branch (406:11): [True: 0, False: 0]
  ------------------
  407|      0|                                &input_storage_class))
  408|      0|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
  409|      0|               << "Expected input to be a pointer: " << spvOpcodeString(opcode);
  410|       |
  411|      0|      if (input_storage_class != spv::StorageClass::Generic)
  ------------------
  |  Branch (411:11): [True: 0, False: 0]
  ------------------
  412|      0|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
  413|      0|               << "Expected input to have storage class Generic: "
  414|      0|               << spvOpcodeString(opcode);
  415|       |
  416|      0|      if (result_data_type != input_data_type)
  ------------------
  |  Branch (416:11): [True: 0, False: 0]
  ------------------
  417|      0|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
  418|      0|               << "Expected input and Result Type to point to the same type: "
  419|      0|               << spvOpcodeString(opcode);
  420|      0|      break;
  421|      0|    }
  422|       |
  423|      0|    case spv::Op::OpGenericCastToPtrExplicit: {
  ------------------
  |  Branch (423:5): [True: 0, False: 285k]
  ------------------
  424|      0|      spv::StorageClass result_storage_class;
  425|      0|      uint32_t result_data_type = 0;
  426|      0|      if (!_.GetPointerTypeInfo(result_type, &result_data_type,
  ------------------
  |  Branch (426:11): [True: 0, False: 0]
  ------------------
  427|      0|                                &result_storage_class))
  428|      0|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
  429|      0|               << "Expected Result Type to be a pointer: "
  430|      0|               << spvOpcodeString(opcode);
  431|       |
  432|      0|      const auto target_storage_class =
  433|      0|          inst->GetOperandAs<spv::StorageClass>(3);
  434|      0|      if (result_storage_class != target_storage_class)
  ------------------
  |  Branch (434:11): [True: 0, False: 0]
  ------------------
  435|      0|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
  436|      0|               << "Expected Result Type to be of target storage class: "
  437|      0|               << spvOpcodeString(opcode);
  438|       |
  439|      0|      const uint32_t input_type = _.GetOperandTypeId(inst, 2);
  440|      0|      spv::StorageClass input_storage_class;
  441|      0|      uint32_t input_data_type = 0;
  442|      0|      if (!_.GetPointerTypeInfo(input_type, &input_data_type,
  ------------------
  |  Branch (442:11): [True: 0, False: 0]
  ------------------
  443|      0|                                &input_storage_class))
  444|      0|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
  445|      0|               << "Expected input to be a pointer: " << spvOpcodeString(opcode);
  446|       |
  447|      0|      if (input_storage_class != spv::StorageClass::Generic)
  ------------------
  |  Branch (447:11): [True: 0, False: 0]
  ------------------
  448|      0|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
  449|      0|               << "Expected input to have storage class Generic: "
  450|      0|               << spvOpcodeString(opcode);
  451|       |
  452|      0|      if (result_data_type != input_data_type)
  ------------------
  |  Branch (452:11): [True: 0, False: 0]
  ------------------
  453|      0|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
  454|      0|               << "Expected input and Result Type to point to the same type: "
  455|      0|               << spvOpcodeString(opcode);
  456|       |
  457|      0|      if (target_storage_class != spv::StorageClass::Workgroup &&
  ------------------
  |  Branch (457:11): [True: 0, False: 0]
  ------------------
  458|      0|          target_storage_class != spv::StorageClass::CrossWorkgroup &&
  ------------------
  |  Branch (458:11): [True: 0, False: 0]
  ------------------
  459|      0|          target_storage_class != spv::StorageClass::Function)
  ------------------
  |  Branch (459:11): [True: 0, False: 0]
  ------------------
  460|      0|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
  461|      0|               << "Expected target storage class to be Workgroup, "
  462|      0|               << "CrossWorkgroup or Function: " << spvOpcodeString(opcode);
  463|      0|      break;
  464|      0|    }
  465|       |
  466|     87|    case spv::Op::OpBitcast: {
  ------------------
  |  Branch (466:5): [True: 87, False: 285k]
  ------------------
  467|     87|      const uint32_t input_type = _.GetOperandTypeId(inst, 2);
  468|     87|      if (!input_type)
  ------------------
  |  Branch (468:11): [True: 0, False: 87]
  ------------------
  469|      0|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
  470|      0|               << "Expected input to have a type: " << spvOpcodeString(opcode);
  471|       |
  472|     87|      const bool result_is_pointer = _.IsPointerType(result_type);
  473|     87|      const bool result_is_int_scalar = _.IsIntScalarType(result_type);
  474|     87|      const bool input_is_pointer = _.IsPointerType(input_type);
  475|     87|      const bool input_is_int_scalar = _.IsIntScalarType(input_type);
  476|       |
  477|     87|      if (!result_is_pointer && !result_is_int_scalar &&
  ------------------
  |  Branch (477:11): [True: 77, False: 10]
  |  Branch (477:33): [True: 17, False: 60]
  ------------------
  478|     87|          !_.IsIntVectorType(result_type) &&
  ------------------
  |  Branch (478:11): [True: 15, False: 2]
  ------------------
  479|     87|          !_.IsFloatScalarType(result_type) &&
  ------------------
  |  Branch (479:11): [True: 9, False: 6]
  ------------------
  480|     87|          !_.IsFloatVectorType(result_type))
  ------------------
  |  Branch (480:11): [True: 2, False: 7]
  ------------------
  481|      2|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
  482|      2|               << "Expected Result Type to be a pointer or int or float vector "
  483|      2|               << "or scalar type: " << spvOpcodeString(opcode);
  484|       |
  485|     85|      if (!input_is_pointer && !input_is_int_scalar &&
  ------------------
  |  Branch (485:11): [True: 57, False: 28]
  |  Branch (485:32): [True: 27, False: 30]
  ------------------
  486|     85|          !_.IsIntVectorType(input_type) && !_.IsFloatScalarType(input_type) &&
  ------------------
  |  Branch (486:11): [True: 25, False: 2]
  |  Branch (486:45): [True: 6, False: 19]
  ------------------
  487|     85|          !_.IsFloatVectorType(input_type))
  ------------------
  |  Branch (487:11): [True: 0, False: 6]
  ------------------
  488|      0|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
  489|      0|               << "Expected input to be a pointer or int or float vector "
  490|      0|               << "or scalar: " << spvOpcodeString(opcode);
  491|       |
  492|     85|      if (_.version() >= SPV_SPIRV_VERSION_WORD(1, 5) ||
  ------------------
  |  |   26|    170|  ((uint32_t(uint8_t(MAJOR)) << 16) | (uint32_t(uint8_t(MINOR)) << 8))
  ------------------
  |  Branch (492:11): [True: 0, False: 85]
  ------------------
  493|     85|          _.HasExtension(kSPV_KHR_physical_storage_buffer)) {
  ------------------
  |  Branch (493:11): [True: 0, False: 85]
  ------------------
  494|      0|        const bool result_is_int_vector = _.IsIntVectorType(result_type);
  495|      0|        const bool result_has_int32 =
  496|      0|            _.ContainsSizedIntOrFloatType(result_type, spv::Op::OpTypeInt, 32);
  497|      0|        const bool input_is_int_vector = _.IsIntVectorType(input_type);
  498|      0|        const bool input_has_int32 =
  499|      0|            _.ContainsSizedIntOrFloatType(input_type, spv::Op::OpTypeInt, 32);
  500|      0|        if (result_is_pointer && !input_is_pointer && !input_is_int_scalar &&
  ------------------
  |  Branch (500:13): [True: 0, False: 0]
  |  Branch (500:34): [True: 0, False: 0]
  |  Branch (500:55): [True: 0, False: 0]
  ------------------
  501|      0|            !(input_is_int_vector && input_has_int32))
  ------------------
  |  Branch (501:15): [True: 0, False: 0]
  |  Branch (501:38): [True: 0, False: 0]
  ------------------
  502|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
  503|      0|                 << "Expected input to be a pointer, int scalar or 32-bit int "
  504|      0|                    "vector if Result Type is pointer: "
  505|      0|                 << spvOpcodeString(opcode);
  506|       |
  507|      0|        if (input_is_pointer && !result_is_pointer && !result_is_int_scalar &&
  ------------------
  |  Branch (507:13): [True: 0, False: 0]
  |  Branch (507:33): [True: 0, False: 0]
  |  Branch (507:55): [True: 0, False: 0]
  ------------------
  508|      0|            !(result_is_int_vector && result_has_int32))
  ------------------
  |  Branch (508:15): [True: 0, False: 0]
  |  Branch (508:39): [True: 0, False: 0]
  ------------------
  509|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
  510|      0|                 << "Pointer can only be converted to another pointer, int "
  511|      0|                    "scalar or 32-bit int vector: "
  512|      0|                 << spvOpcodeString(opcode);
  513|     85|      } else {
  514|     85|        if (result_is_pointer && !input_is_pointer && !input_is_int_scalar)
  ------------------
  |  Branch (514:13): [True: 10, False: 75]
  |  Branch (514:34): [True: 6, False: 4]
  |  Branch (514:55): [True: 1, False: 5]
  ------------------
  515|      1|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
  516|      1|                 << "Expected input to be a pointer or int scalar if Result "
  517|      1|                    "Type is pointer: "
  518|      1|                 << spvOpcodeString(opcode);
  519|       |
  520|     84|        if (input_is_pointer && !result_is_pointer && !result_is_int_scalar)
  ------------------
  |  Branch (520:13): [True: 28, False: 56]
  |  Branch (520:33): [True: 24, False: 4]
  |  Branch (520:55): [True: 0, False: 24]
  ------------------
  521|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
  522|      0|                 << "Pointer can only be converted to another pointer or int "
  523|      0|                    "scalar: "
  524|      0|                 << spvOpcodeString(opcode);
  525|     84|      }
  526|       |
  527|     84|      if (!result_is_pointer && !input_is_pointer) {
  ------------------
  |  Branch (527:11): [True: 75, False: 9]
  |  Branch (527:33): [True: 51, False: 24]
  ------------------
  528|     51|        const uint32_t result_size =
  529|     51|            _.GetBitWidth(result_type) * _.GetDimension(result_type);
  530|     51|        const uint32_t input_size =
  531|     51|            _.GetBitWidth(input_type) * _.GetDimension(input_type);
  532|     51|        if (result_size != input_size)
  ------------------
  |  Branch (532:13): [True: 1, False: 50]
  ------------------
  533|      1|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
  534|      1|                 << "Expected input to have the same total bit width as "
  535|      1|                 << "Result Type: " << spvOpcodeString(opcode);
  536|     51|      }
  537|     83|      break;
  538|     84|    }
  539|       |
  540|     83|    case spv::Op::OpConvertUToAccelerationStructureKHR: {
  ------------------
  |  Branch (540:5): [True: 0, False: 285k]
  ------------------
  541|      0|      if (!_.IsAccelerationStructureType(result_type)) {
  ------------------
  |  Branch (541:11): [True: 0, False: 0]
  ------------------
  542|      0|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
  543|      0|               << "Expected Result Type to be a Acceleration Structure: "
  544|      0|               << spvOpcodeString(opcode);
  545|      0|      }
  546|       |
  547|      0|      const uint32_t input_type = _.GetOperandTypeId(inst, 2);
  548|      0|      if (!input_type || !_.IsUnsigned64BitHandle(input_type)) {
  ------------------
  |  Branch (548:11): [True: 0, False: 0]
  |  Branch (548:26): [True: 0, False: 0]
  ------------------
  549|      0|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
  550|      0|               << "Expected 64-bit uint scalar or 2-component 32-bit uint "
  551|      0|                  "vector as input: "
  552|      0|               << spvOpcodeString(opcode);
  553|      0|      }
  554|       |
  555|      0|      break;
  556|      0|    }
  557|       |
  558|   284k|    default:
  ------------------
  |  Branch (558:5): [True: 284k, False: 1.67k]
  ------------------
  559|   284k|      break;
  560|   285k|  }
  561|       |
  562|   285k|  if (_.HasCapability(spv::Capability::Shader)) {
  ------------------
  |  Branch (562:7): [True: 284k, False: 1.40k]
  ------------------
  563|   284k|    switch (inst->opcode()) {
  564|      5|      case spv::Op::OpConvertFToU:
  ------------------
  |  Branch (564:7): [True: 5, False: 284k]
  ------------------
  565|    542|      case spv::Op::OpConvertFToS:
  ------------------
  |  Branch (565:7): [True: 537, False: 283k]
  ------------------
  566|  1.54k|      case spv::Op::OpConvertSToF:
  ------------------
  |  Branch (566:7): [True: 1.00k, False: 283k]
  ------------------
  567|  1.55k|      case spv::Op::OpConvertUToF:
  ------------------
  |  Branch (567:7): [True: 6, False: 284k]
  ------------------
  568|  1.63k|      case spv::Op::OpBitcast:
  ------------------
  |  Branch (568:7): [True: 83, False: 284k]
  ------------------
  569|  1.63k|        if (_.ContainsLimitedUseIntOrFloatType(inst->type_id()) ||
  ------------------
  |  Branch (569:13): [True: 0, False: 1.63k]
  ------------------
  570|  1.63k|            _.ContainsLimitedUseIntOrFloatType(_.GetOperandTypeId(inst, 2u))) {
  ------------------
  |  Branch (570:13): [True: 0, False: 1.63k]
  ------------------
  571|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
  572|      0|                 << "8- or 16-bit types can only be used with width-only "
  573|      0|                    "conversions";
  574|      0|        }
  575|  1.63k|        break;
  576|   282k|      default:
  ------------------
  |  Branch (576:7): [True: 282k, False: 1.63k]
  ------------------
  577|   282k|        break;
  578|   284k|    }
  579|   284k|  }
  580|       |
  581|   285k|  return SPV_SUCCESS;
  582|   285k|}

_ZN8spvtools3val9DebugPassERNS0_17ValidationState_tEPKNS0_11InstructionE:
   58|   286k|spv_result_t DebugPass(ValidationState_t& _, const Instruction* inst) {
   59|   286k|  switch (inst->opcode()) {
   60|    245|    case spv::Op::OpMemberName:
  ------------------
  |  Branch (60:5): [True: 245, False: 286k]
  ------------------
   61|    245|      if (auto error = ValidateMemberName(_, inst)) return error;
  ------------------
  |  Branch (61:16): [True: 6, False: 239]
  ------------------
   62|    239|      break;
   63|    239|    case spv::Op::OpLine:
  ------------------
  |  Branch (63:5): [True: 23, False: 286k]
  ------------------
   64|     23|      if (auto error = ValidateLine(_, inst)) return error;
  ------------------
  |  Branch (64:16): [True: 7, False: 16]
  ------------------
   65|     16|      break;
   66|   286k|    default:
  ------------------
  |  Branch (66:5): [True: 286k, False: 268]
  ------------------
   67|   286k|      break;
   68|   286k|  }
   69|       |
   70|   286k|  return SPV_SUCCESS;
   71|   286k|}
validate_debug.cpp:_ZN8spvtools3val12_GLOBAL__N_118ValidateMemberNameERNS0_17ValidationState_tEPKNS0_11InstructionE:
   26|    245|spv_result_t ValidateMemberName(ValidationState_t& _, const Instruction* inst) {
   27|    245|  const auto type_id = inst->GetOperandAs<uint32_t>(0);
   28|    245|  const auto type = _.FindDef(type_id);
   29|    245|  if (!type || spv::Op::OpTypeStruct != type->opcode()) {
  ------------------
  |  Branch (29:7): [True: 0, False: 245]
  |  Branch (29:16): [True: 4, False: 241]
  ------------------
   30|      4|    return _.diag(SPV_ERROR_INVALID_ID, inst)
   31|      4|           << "OpMemberName Type <id> " << _.getIdName(type_id)
   32|      4|           << " is not a struct type.";
   33|      4|  }
   34|    241|  const auto member_id = inst->GetOperandAs<uint32_t>(1);
   35|    241|  const auto member_count = (uint32_t)(type->words().size() - 2);
   36|    241|  if (member_count <= member_id) {
  ------------------
  |  Branch (36:7): [True: 2, False: 239]
  ------------------
   37|      2|    return _.diag(SPV_ERROR_INVALID_ID, inst)
   38|      2|           << "OpMemberName Member <id> " << _.getIdName(member_id)
   39|      2|           << " index is larger than Type <id> " << _.getIdName(type->id())
   40|      2|           << "s member count.";
   41|      2|  }
   42|    239|  return SPV_SUCCESS;
   43|    241|}
validate_debug.cpp:_ZN8spvtools3val12_GLOBAL__N_112ValidateLineERNS0_17ValidationState_tEPKNS0_11InstructionE:
   45|     23|spv_result_t ValidateLine(ValidationState_t& _, const Instruction* inst) {
   46|     23|  const auto file_id = inst->GetOperandAs<uint32_t>(0);
   47|     23|  const auto file = _.FindDef(file_id);
   48|     23|  if (!file || spv::Op::OpString != file->opcode()) {
  ------------------
  |  Branch (48:7): [True: 0, False: 23]
  |  Branch (48:16): [True: 7, False: 16]
  ------------------
   49|      7|    return _.diag(SPV_ERROR_INVALID_ID, inst)
   50|      7|           << "OpLine Target <id> " << _.getIdName(file_id)
   51|      7|           << " is not an OpString.";
   52|      7|  }
   53|     16|  return SPV_SUCCESS;
   54|     23|}

_ZN8spvtools3val19ValidateDecorationsERNS0_17ValidationState_tE:
 1864|  1.02k|spv_result_t ValidateDecorations(ValidationState_t& vstate) {
 1865|  1.02k|  if (auto error = CheckImportedVariableInitialization(vstate)) return error;
  ------------------
  |  Branch (1865:12): [True: 0, False: 1.02k]
  ------------------
 1866|  1.02k|  if (auto error = CheckDecorationsOfEntryPoints(vstate)) return error;
  ------------------
  |  Branch (1866:12): [True: 40, False: 983]
  ------------------
 1867|    983|  if (auto error = CheckDecorationsOfBuffers(vstate)) return error;
  ------------------
  |  Branch (1867:12): [True: 17, False: 966]
  ------------------
 1868|    966|  if (auto error = CheckDecorationsCompatibility(vstate)) return error;
  ------------------
  |  Branch (1868:12): [True: 35, False: 931]
  ------------------
 1869|    931|  if (auto error = CheckLinkageAttrOfFunctions(vstate)) return error;
  ------------------
  |  Branch (1869:12): [True: 201, False: 730]
  ------------------
 1870|    730|  if (auto error = CheckVulkanMemoryModelDeprecatedDecorations(vstate))
  ------------------
  |  Branch (1870:12): [True: 0, False: 730]
  ------------------
 1871|      0|    return error;
 1872|    730|  if (auto error = CheckDecorationsFromDecoration(vstate)) return error;
  ------------------
  |  Branch (1872:12): [True: 66, False: 664]
  ------------------
 1873|    664|  return SPV_SUCCESS;
 1874|    730|}
validate_decorations.cpp:_ZN8spvtools3val12_GLOBAL__N_135CheckImportedVariableInitializationERNS0_17ValidationState_tE:
  719|  1.02k|spv_result_t CheckImportedVariableInitialization(ValidationState_t& vstate) {
  720|       |  // According the SPIR-V Spec 2.16.1, it is illegal to initialize an imported
  721|       |  // variable. This means that a module-scope OpVariable with initialization
  722|       |  // value cannot be marked with the Import Linkage Type (import type id = 1).
  723|  1.02k|  for (auto global_var_id : vstate.global_vars()) {
  ------------------
  |  Branch (723:27): [True: 909, False: 1.02k]
  ------------------
  724|       |    // Initializer <id> is an optional argument for OpVariable. If initializer
  725|       |    // <id> is present, the instruction will have 5 words.
  726|    909|    auto variable_instr = vstate.FindDef(global_var_id);
  727|    909|    if (variable_instr->words().size() == 5u &&
  ------------------
  |  Branch (727:9): [True: 0, False: 909]
  ------------------
  728|    909|        hasImportLinkageAttribute(global_var_id, vstate)) {
  ------------------
  |  Branch (728:9): [True: 0, False: 0]
  ------------------
  729|      0|      return vstate.diag(SPV_ERROR_INVALID_ID, variable_instr)
  730|      0|             << "A module-scope OpVariable with initialization value "
  731|      0|                "cannot be marked with the Import Linkage Type.";
  732|      0|    }
  733|    909|  }
  734|  1.02k|  return SPV_SUCCESS;
  735|  1.02k|}
validate_decorations.cpp:_ZN8spvtools3val12_GLOBAL__N_125hasImportLinkageAttributeEjRNS0_17ValidationState_tE:
  112|  1.01k|bool hasImportLinkageAttribute(uint32_t id, ValidationState_t& vstate) {
  113|  1.01k|  const auto& decorations = vstate.id_decorations(id);
  114|  1.01k|  return std::any_of(
  115|  1.01k|      decorations.begin(), decorations.end(), [](const Decoration& d) {
  116|  1.01k|        return spv::Decoration::LinkageAttributes == d.dec_type() &&
  117|  1.01k|               d.params().size() >= 2u &&
  118|  1.01k|               spv::LinkageType(d.params().back()) == spv::LinkageType::Import;
  119|  1.01k|      });
  120|  1.01k|}
validate_decorations.cpp:_ZZN8spvtools3val12_GLOBAL__N_125hasImportLinkageAttributeEjRNS0_17ValidationState_tEENK3$_3clERKNS0_10DecorationE:
  115|  1.35k|      decorations.begin(), decorations.end(), [](const Decoration& d) {
  116|  1.35k|        return spv::Decoration::LinkageAttributes == d.dec_type() &&
  ------------------
  |  Branch (116:16): [True: 0, False: 1.35k]
  ------------------
  117|  1.35k|               d.params().size() >= 2u &&
  ------------------
  |  Branch (117:16): [True: 0, False: 0]
  ------------------
  118|  1.35k|               spv::LinkageType(d.params().back()) == spv::LinkageType::Import;
  ------------------
  |  Branch (118:16): [True: 0, False: 0]
  ------------------
  119|  1.35k|      });
validate_decorations.cpp:_ZN8spvtools3val12_GLOBAL__N_129CheckDecorationsOfEntryPointsERNS0_17ValidationState_tE:
  754|  1.02k|spv_result_t CheckDecorationsOfEntryPoints(ValidationState_t& vstate) {
  755|  1.02k|  for (uint32_t entry_point : vstate.entry_points()) {
  ------------------
  |  Branch (755:29): [True: 872, False: 983]
  ------------------
  756|    872|    const auto& descs = vstate.entry_point_descriptions(entry_point);
  757|    872|    int num_builtin_block_inputs = 0;
  758|    872|    int num_builtin_block_outputs = 0;
  759|    872|    int num_workgroup_variables = 0;
  760|    872|    int num_workgroup_variables_with_block = 0;
  761|    872|    int num_workgroup_variables_with_aliased = 0;
  762|  2.10k|    for (const auto& desc : descs) {
  ------------------
  |  Branch (762:27): [True: 2.10k, False: 832]
  ------------------
  763|  2.10k|      std::unordered_set<Instruction*> seen_vars;
  764|  2.10k|      for (auto interface : desc.interfaces) {
  ------------------
  |  Branch (764:27): [True: 590, False: 2.06k]
  ------------------
  765|    590|        Instruction* var_instr = vstate.FindDef(interface);
  766|    590|        if (!var_instr || spv::Op::OpVariable != var_instr->opcode()) {
  ------------------
  |  Branch (766:13): [True: 0, False: 590]
  |  Branch (766:27): [True: 26, False: 564]
  ------------------
  767|     26|          return vstate.diag(SPV_ERROR_INVALID_ID, var_instr)
  768|     26|                 << "Interfaces passed to OpEntryPoint must be of type "
  769|     26|                    "OpTypeVariable. Found Op"
  770|     26|                 << spvOpcodeString(var_instr->opcode()) << ".";
  771|     26|        }
  772|    564|        const spv::StorageClass storage_class =
  773|    564|            var_instr->GetOperandAs<spv::StorageClass>(2);
  774|    564|        if (vstate.version() >= SPV_SPIRV_VERSION_WORD(1, 4)) {
  ------------------
  |  |   26|    564|  ((uint32_t(uint8_t(MAJOR)) << 16) | (uint32_t(uint8_t(MINOR)) << 8))
  ------------------
  |  Branch (774:13): [True: 0, False: 564]
  ------------------
  775|       |          // Starting in 1.4, OpEntryPoint must list all global variables
  776|       |          // it statically uses and those interfaces must be unique.
  777|      0|          if (storage_class == spv::StorageClass::Function) {
  ------------------
  |  Branch (777:15): [True: 0, False: 0]
  ------------------
  778|      0|            return vstate.diag(SPV_ERROR_INVALID_ID, var_instr)
  779|      0|                   << "OpEntryPoint interfaces should only list global "
  780|      0|                      "variables";
  781|      0|          }
  782|       |
  783|      0|          if (!seen_vars.insert(var_instr).second) {
  ------------------
  |  Branch (783:15): [True: 0, False: 0]
  ------------------
  784|      0|            return vstate.diag(SPV_ERROR_INVALID_ID, var_instr)
  785|      0|                   << "Non-unique OpEntryPoint interface "
  786|      0|                   << vstate.getIdName(interface) << " is disallowed";
  787|      0|          }
  788|    564|        } else {
  789|    564|          if (storage_class != spv::StorageClass::Input &&
  ------------------
  |  Branch (789:15): [True: 263, False: 301]
  ------------------
  790|    564|              storage_class != spv::StorageClass::Output) {
  ------------------
  |  Branch (790:15): [True: 3, False: 260]
  ------------------
  791|      3|            return vstate.diag(SPV_ERROR_INVALID_ID, var_instr)
  792|      3|                   << "OpEntryPoint interfaces must be OpVariables with "
  793|      3|                      "Storage Class of Input(1) or Output(3). Found Storage "
  794|      3|                      "Class "
  795|      3|                   << uint32_t(storage_class) << " for Entry Point id "
  796|      3|                   << entry_point << ".";
  797|      3|          }
  798|    564|        }
  799|       |
  800|    561|        const uint32_t ptr_id = var_instr->word(1);
  801|    561|        Instruction* ptr_instr = vstate.FindDef(ptr_id);
  802|       |        // It is guaranteed (by validator ID checks) that ptr_instr is
  803|       |        // OpTypePointer. Word 3 of this instruction is the type being pointed
  804|       |        // to.
  805|    561|        const uint32_t type_id = ptr_instr->word(3);
  806|    561|        Instruction* type_instr = vstate.FindDef(type_id);
  807|    561|        if (type_instr && spv::Op::OpTypeStruct == type_instr->opcode() &&
  ------------------
  |  Branch (807:13): [True: 561, False: 0]
  |  Branch (807:27): [True: 110, False: 451]
  ------------------
  808|    561|            isBuiltInStruct(type_id, vstate)) {
  ------------------
  |  Branch (808:13): [True: 14, False: 96]
  ------------------
  809|     14|          if (!isBlock(type_id, vstate)) {
  ------------------
  |  Branch (809:15): [True: 10, False: 4]
  ------------------
  810|     10|            return vstate.diag(SPV_ERROR_INVALID_DATA, vstate.FindDef(type_id))
  811|     10|                   << vstate.VkErrorID(4919)
  812|     10|                   << "Interface struct has no Block decoration but has "
  813|     10|                      "BuiltIn members. "
  814|     10|                      "Location decorations must be used on each member of "
  815|     10|                      "OpVariable with a structure type that is a block not "
  816|     10|                      "decorated with Location.";
  817|     10|          }
  818|      4|          if (storage_class == spv::StorageClass::Input)
  ------------------
  |  Branch (818:15): [True: 0, False: 4]
  ------------------
  819|      0|            ++num_builtin_block_inputs;
  820|      4|          if (storage_class == spv::StorageClass::Output)
  ------------------
  |  Branch (820:15): [True: 4, False: 0]
  ------------------
  821|      4|            ++num_builtin_block_outputs;
  822|      4|          if (num_builtin_block_inputs > 1 || num_builtin_block_outputs > 1)
  ------------------
  |  Branch (822:15): [True: 0, False: 4]
  |  Branch (822:47): [True: 1, False: 3]
  ------------------
  823|      1|            break;
  824|      3|          if (auto error = CheckBuiltInVariable(interface, vstate))
  ------------------
  |  Branch (824:20): [True: 0, False: 3]
  ------------------
  825|      0|            return error;
  826|    547|        } else if (isBuiltInVar(interface, vstate)) {
  ------------------
  |  Branch (826:20): [True: 176, False: 371]
  ------------------
  827|    176|          if (auto error = CheckBuiltInVariable(interface, vstate))
  ------------------
  |  Branch (827:20): [True: 0, False: 176]
  ------------------
  828|      0|            return error;
  829|    176|        }
  830|       |
  831|    550|        if (storage_class == spv::StorageClass::Workgroup) {
  ------------------
  |  Branch (831:13): [True: 0, False: 550]
  ------------------
  832|      0|          ++num_workgroup_variables;
  833|      0|          if (type_instr && spv::Op::OpTypeStruct == type_instr->opcode()) {
  ------------------
  |  Branch (833:15): [True: 0, False: 0]
  |  Branch (833:29): [True: 0, False: 0]
  ------------------
  834|      0|            if (hasDecoration(type_id, spv::Decoration::Block, vstate))
  ------------------
  |  Branch (834:17): [True: 0, False: 0]
  ------------------
  835|      0|              ++num_workgroup_variables_with_block;
  836|      0|            if (hasDecoration(var_instr->id(), spv::Decoration::Aliased,
  ------------------
  |  Branch (836:17): [True: 0, False: 0]
  ------------------
  837|      0|                              vstate))
  838|      0|              ++num_workgroup_variables_with_aliased;
  839|      0|          }
  840|      0|        }
  841|       |
  842|    550|        if (spvIsVulkanEnv(vstate.context()->target_env)) {
  ------------------
  |  Branch (842:13): [True: 0, False: 550]
  ------------------
  843|      0|          const auto* models = vstate.GetExecutionModels(entry_point);
  844|      0|          const bool has_frag =
  845|      0|              models->find(spv::ExecutionModel::Fragment) != models->end();
  846|      0|          const bool has_vert =
  847|      0|              models->find(spv::ExecutionModel::Vertex) != models->end();
  848|      0|          for (const auto& decoration :
  ------------------
  |  Branch (848:39): [True: 0, False: 0]
  ------------------
  849|      0|               vstate.id_decorations(var_instr->id())) {
  850|      0|            if (decoration == spv::Decoration::Flat ||
  ------------------
  |  Branch (850:17): [True: 0, False: 0]
  |  Branch (850:17): [True: 0, False: 0]
  ------------------
  851|      0|                decoration == spv::Decoration::NoPerspective ||
  ------------------
  |  Branch (851:17): [True: 0, False: 0]
  ------------------
  852|      0|                decoration == spv::Decoration::Sample ||
  ------------------
  |  Branch (852:17): [True: 0, False: 0]
  ------------------
  853|      0|                decoration == spv::Decoration::Centroid) {
  ------------------
  |  Branch (853:17): [True: 0, False: 0]
  ------------------
  854|       |              // VUID 04670 already validates these decorations are input/output
  855|      0|              if (storage_class == spv::StorageClass::Input &&
  ------------------
  |  Branch (855:19): [True: 0, False: 0]
  ------------------
  856|      0|                  (models->size() > 1 || has_vert)) {
  ------------------
  |  Branch (856:20): [True: 0, False: 0]
  |  Branch (856:42): [True: 0, False: 0]
  ------------------
  857|      0|                return vstate.diag(SPV_ERROR_INVALID_ID, var_instr)
  858|      0|                       << vstate.VkErrorID(6202)
  859|      0|                       << vstate.SpvDecorationString(decoration.dec_type())
  860|      0|                       << " decorated variable must not be used in vertex "
  861|      0|                          "execution model as an Input storage class for Entry "
  862|      0|                          "Point id "
  863|      0|                       << entry_point << ".";
  864|      0|              } else if (storage_class == spv::StorageClass::Output &&
  ------------------
  |  Branch (864:26): [True: 0, False: 0]
  ------------------
  865|      0|                         (models->size() > 1 || has_frag)) {
  ------------------
  |  Branch (865:27): [True: 0, False: 0]
  |  Branch (865:49): [True: 0, False: 0]
  ------------------
  866|      0|                return vstate.diag(SPV_ERROR_INVALID_ID, var_instr)
  867|      0|                       << vstate.VkErrorID(6201)
  868|      0|                       << vstate.SpvDecorationString(decoration.dec_type())
  869|      0|                       << " decorated variable must not be used in fragment "
  870|      0|                          "execution model as an Output storage class for "
  871|      0|                          "Entry Point id "
  872|      0|                       << entry_point << ".";
  873|      0|              }
  874|      0|            }
  875|      0|          }
  876|       |
  877|      0|          const bool has_flat =
  878|      0|              hasDecoration(var_instr->id(), spv::Decoration::Flat, vstate);
  879|      0|          if (has_frag && storage_class == spv::StorageClass::Input &&
  ------------------
  |  Branch (879:15): [True: 0, False: 0]
  |  Branch (879:27): [True: 0, False: 0]
  ------------------
  880|      0|              !has_flat &&
  ------------------
  |  Branch (880:15): [True: 0, False: 0]
  ------------------
  881|      0|              ((vstate.IsFloatScalarType(type_id) &&
  ------------------
  |  Branch (881:17): [True: 0, False: 0]
  ------------------
  882|      0|                vstate.GetBitWidth(type_id) == 64) ||
  ------------------
  |  Branch (882:17): [True: 0, False: 0]
  ------------------
  883|      0|               vstate.IsIntScalarOrVectorType(type_id))) {
  ------------------
  |  Branch (883:16): [True: 0, False: 0]
  ------------------
  884|      0|            return vstate.diag(SPV_ERROR_INVALID_ID, var_instr)
  885|      0|                     << vstate.VkErrorID(4744)
  886|      0|                     << "Fragment OpEntryPoint operand "
  887|      0|                     << interface << " with Input interfaces with integer or "
  888|      0|                                     "float type must have a Flat decoration "
  889|      0|                                     "for Entry Point id "
  890|      0|                     << entry_point << ".";
  891|      0|          }
  892|      0|        }
  893|    550|      }
  894|  2.06k|      if (num_builtin_block_inputs > 1 || num_builtin_block_outputs > 1) {
  ------------------
  |  Branch (894:11): [True: 0, False: 2.06k]
  |  Branch (894:43): [True: 1, False: 2.06k]
  ------------------
  895|      1|        return vstate.diag(SPV_ERROR_INVALID_BINARY,
  896|      1|                           vstate.FindDef(entry_point))
  897|      1|               << "There must be at most one object per Storage Class that can "
  898|      1|                  "contain a structure type containing members decorated with "
  899|      1|                  "BuiltIn, consumed per entry-point. Entry Point id "
  900|      1|               << entry_point << " does not meet this requirement.";
  901|      1|      }
  902|       |      // The LinkageAttributes Decoration cannot be applied to functions
  903|       |      // targeted by an OpEntryPoint instruction
  904|  2.06k|      for (auto& decoration : vstate.id_decorations(entry_point)) {
  ------------------
  |  Branch (904:29): [True: 1.62k, False: 2.06k]
  ------------------
  905|  1.62k|        if (spv::Decoration::LinkageAttributes == decoration.dec_type()) {
  ------------------
  |  Branch (905:13): [True: 0, False: 1.62k]
  ------------------
  906|      0|          const std::string linkage_name =
  907|      0|              spvtools::utils::MakeString(decoration.params());
  908|      0|          return vstate.diag(SPV_ERROR_INVALID_BINARY,
  909|      0|                             vstate.FindDef(entry_point))
  910|      0|                 << "The LinkageAttributes Decoration (Linkage name: "
  911|      0|                 << linkage_name << ") cannot be applied to function id "
  912|      0|                 << entry_point
  913|      0|                 << " because it is targeted by an OpEntryPoint instruction.";
  914|      0|        }
  915|  1.62k|      }
  916|       |
  917|  2.06k|      if (vstate.HasCapability(
  ------------------
  |  Branch (917:11): [True: 0, False: 2.06k]
  ------------------
  918|  2.06k|              spv::Capability::WorkgroupMemoryExplicitLayoutKHR) &&
  919|  2.06k|          num_workgroup_variables > 0 &&
  ------------------
  |  Branch (919:11): [True: 0, False: 0]
  ------------------
  920|  2.06k|          num_workgroup_variables_with_block > 0) {
  ------------------
  |  Branch (920:11): [True: 0, False: 0]
  ------------------
  921|      0|        if (num_workgroup_variables != num_workgroup_variables_with_block) {
  ------------------
  |  Branch (921:13): [True: 0, False: 0]
  ------------------
  922|      0|          return vstate.diag(SPV_ERROR_INVALID_BINARY, vstate.FindDef(entry_point))
  923|      0|                 << "When declaring WorkgroupMemoryExplicitLayoutKHR, "
  924|      0|                    "either all or none of the Workgroup Storage Class variables "
  925|      0|                    "in the entry point interface must point to struct types "
  926|      0|                    "decorated with Block.  Entry point id "
  927|      0|                 << entry_point << " does not meet this requirement.";
  928|      0|        }
  929|      0|        if (num_workgroup_variables_with_block > 1 &&
  ------------------
  |  Branch (929:13): [True: 0, False: 0]
  ------------------
  930|      0|            num_workgroup_variables_with_block !=
  ------------------
  |  Branch (930:13): [True: 0, False: 0]
  ------------------
  931|      0|            num_workgroup_variables_with_aliased) {
  932|      0|          return vstate.diag(SPV_ERROR_INVALID_BINARY, vstate.FindDef(entry_point))
  933|      0|                 << "When declaring WorkgroupMemoryExplicitLayoutKHR, "
  934|      0|                    "if more than one Workgroup Storage Class variable in "
  935|      0|                    "the entry point interface point to a type decorated "
  936|      0|                    "with Block, all of them must be decorated with Aliased. "
  937|      0|                    "Entry point id "
  938|      0|                 << entry_point << " does not meet this requirement.";
  939|      0|        }
  940|      0|      }
  941|  2.06k|    }
  942|    872|  }
  943|    983|  return SPV_SUCCESS;
  944|  1.02k|}
validate_decorations.cpp:_ZN8spvtools3val12_GLOBAL__N_115isBuiltInStructEjRNS0_17ValidationState_tE:
   93|    110|bool isBuiltInStruct(uint32_t struct_id, ValidationState_t& vstate) {
   94|    110|  const auto& decorations = vstate.id_decorations(struct_id);
   95|    110|  return std::any_of(
   96|    110|      decorations.begin(), decorations.end(), [](const Decoration& d) {
   97|    110|        return spv::Decoration::BuiltIn == d.dec_type() &&
   98|    110|               Decoration::kInvalidMember != d.struct_member_index();
   99|    110|      });
  100|    110|}
validate_decorations.cpp:_ZZN8spvtools3val12_GLOBAL__N_115isBuiltInStructEjRNS0_17ValidationState_tEENK3$_1clERKNS0_10DecorationE:
   96|  2.26k|      decorations.begin(), decorations.end(), [](const Decoration& d) {
   97|  2.26k|        return spv::Decoration::BuiltIn == d.dec_type() &&
  ------------------
  |  Branch (97:16): [True: 40, False: 2.22k]
  ------------------
   98|  2.26k|               Decoration::kInvalidMember != d.struct_member_index();
  ------------------
  |  Branch (98:16): [True: 14, False: 26]
  ------------------
   99|  2.26k|      });
validate_decorations.cpp:_ZN8spvtools3val12_GLOBAL__N_17isBlockEjRNS0_17ValidationState_tE:
  103|     14|bool isBlock(uint32_t struct_id, ValidationState_t& vstate) {
  104|     14|  const auto& decorations = vstate.id_decorations(struct_id);
  105|     14|  return std::any_of(decorations.begin(), decorations.end(),
  106|     14|                     [](const Decoration& d) {
  107|     14|                       return spv::Decoration::Block == d.dec_type();
  108|     14|                     });
  109|     14|}
validate_decorations.cpp:_ZZN8spvtools3val12_GLOBAL__N_17isBlockEjRNS0_17ValidationState_tEENK3$_2clERKNS0_10DecorationE:
  106|    120|                     [](const Decoration& d) {
  107|    120|                       return spv::Decoration::Block == d.dec_type();
  108|    120|                     });
validate_decorations.cpp:_ZN8spvtools3val12_GLOBAL__N_120CheckBuiltInVariableEjRNS0_17ValidationState_tE:
  738|    179|spv_result_t CheckBuiltInVariable(uint32_t var_id, ValidationState_t& vstate) {
  739|    179|  const auto& decorations = vstate.id_decorations(var_id);
  740|    817|  for (const auto& d : decorations) {
  ------------------
  |  Branch (740:22): [True: 817, False: 179]
  ------------------
  741|    817|    if (spvIsVulkanEnv(vstate.context()->target_env)) {
  ------------------
  |  Branch (741:9): [True: 0, False: 817]
  ------------------
  742|      0|      if (d.dec_type() == spv::Decoration::Location ||
  ------------------
  |  Branch (742:11): [True: 0, False: 0]
  ------------------
  743|      0|          d.dec_type() == spv::Decoration::Component) {
  ------------------
  |  Branch (743:11): [True: 0, False: 0]
  ------------------
  744|      0|        return vstate.diag(SPV_ERROR_INVALID_ID, vstate.FindDef(var_id))
  745|      0|               << vstate.VkErrorID(4915) << "A BuiltIn variable (id " << var_id
  746|      0|               << ") cannot have any Location or Component decorations";
  747|      0|      }
  748|      0|    }
  749|    817|  }
  750|    179|  return SPV_SUCCESS;
  751|    179|}
validate_decorations.cpp:_ZN8spvtools3val12_GLOBAL__N_112isBuiltInVarEjRNS0_17ValidationState_tE:
   83|    547|bool isBuiltInVar(uint32_t var_id, ValidationState_t& vstate) {
   84|    547|  const auto& decorations = vstate.id_decorations(var_id);
   85|    547|  return std::any_of(decorations.begin(), decorations.end(),
   86|    547|                     [](const Decoration& d) {
   87|    547|                       return spv::Decoration::BuiltIn == d.dec_type();
   88|    547|                     });
   89|    547|}
validate_decorations.cpp:_ZZN8spvtools3val12_GLOBAL__N_112isBuiltInVarEjRNS0_17ValidationState_tEENK3$_0clERKNS0_10DecorationE:
   86|  2.46k|                     [](const Decoration& d) {
   87|  2.46k|                       return spv::Decoration::BuiltIn == d.dec_type();
   88|  2.46k|                     });
validate_decorations.cpp:_ZN8spvtools3val12_GLOBAL__N_113hasDecorationEjN3spv10DecorationERNS0_17ValidationState_tE:
  649|  4.61k|                   ValidationState_t& vstate) {
  650|  6.57k|  for (auto& dec : vstate.id_decorations(id)) {
  ------------------
  |  Branch (650:18): [True: 6.57k, False: 4.59k]
  ------------------
  651|  6.57k|    if (decoration == dec.dec_type()) return true;
  ------------------
  |  Branch (651:9): [True: 16, False: 6.55k]
  ------------------
  652|  6.57k|  }
  653|  4.59k|  if (spv::Op::OpTypeStruct != vstate.FindDef(id)->opcode()) {
  ------------------
  |  Branch (653:7): [True: 4.59k, False: 0]
  ------------------
  654|  4.59k|    return false;
  655|  4.59k|  }
  656|      0|  for (auto member_id : getStructMembers(id, spv::Op::OpTypeStruct, vstate)) {
  ------------------
  |  Branch (656:23): [True: 0, False: 0]
  ------------------
  657|      0|    if (hasDecoration(member_id, decoration, vstate)) {
  ------------------
  |  Branch (657:9): [True: 0, False: 0]
  ------------------
  658|      0|      return true;
  659|      0|    }
  660|      0|  }
  661|      0|  return false;
  662|      0|}
validate_decorations.cpp:_ZN8spvtools3val12_GLOBAL__N_116getStructMembersEjN3spv2OpERNS0_17ValidationState_tE:
  131|    483|                                       ValidationState_t& vstate) {
  132|    483|  std::vector<uint32_t> members;
  133|    483|  for (auto id : getStructMembers(struct_id, vstate)) {
  ------------------
  |  Branch (133:16): [True: 477, False: 483]
  ------------------
  134|    477|    if (type == vstate.FindDef(id)->opcode()) {
  ------------------
  |  Branch (134:9): [True: 8, False: 469]
  ------------------
  135|      8|      members.push_back(id);
  136|      8|    }
  137|    477|  }
  138|    483|  return members;
  139|    483|}
validate_decorations.cpp:_ZN8spvtools3val12_GLOBAL__N_116getStructMembersEjRNS0_17ValidationState_tE:
  124|  1.59k|                                       ValidationState_t& vstate) {
  125|  1.59k|  const auto inst = vstate.FindDef(struct_id);
  126|  1.59k|  return std::vector<uint32_t>(inst->words().begin() + 2, inst->words().end());
  127|  1.59k|}
validate_decorations.cpp:_ZN8spvtools3val12_GLOBAL__N_125CheckDecorationsOfBuffersERNS0_17ValidationState_tE:
 1029|    983|spv_result_t CheckDecorationsOfBuffers(ValidationState_t& vstate) {
 1030|       |  // Set of entry points that are known to use a push constant.
 1031|    983|  std::unordered_set<uint32_t> uses_push_constant;
 1032|  89.3k|  for (const auto& inst : vstate.ordered_instructions()) {
  ------------------
  |  Branch (1032:25): [True: 89.3k, False: 966]
  ------------------
 1033|  89.3k|    const auto& words = inst.words();
 1034|  89.3k|    if (spv::Op::OpVariable == inst.opcode()) {
  ------------------
  |  Branch (1034:9): [True: 2.30k, False: 87.0k]
  ------------------
 1035|  2.30k|      const auto var_id = inst.id();
 1036|       |      // For storage class / decoration combinations, see Vulkan 14.5.4 "Offset
 1037|       |      // and Stride Assignment".
 1038|  2.30k|      const auto storageClass = inst.GetOperandAs<spv::StorageClass>(2);
 1039|  2.30k|      const bool uniform = storageClass == spv::StorageClass::Uniform;
 1040|  2.30k|      const bool uniform_constant =
 1041|  2.30k|          storageClass == spv::StorageClass::UniformConstant;
 1042|  2.30k|      const bool push_constant =
 1043|  2.30k|          storageClass == spv::StorageClass::PushConstant;
 1044|  2.30k|      const bool storage_buffer =
 1045|  2.30k|          storageClass == spv::StorageClass::StorageBuffer;
 1046|       |
 1047|  2.30k|      if (spvIsVulkanEnv(vstate.context()->target_env)) {
  ------------------
  |  Branch (1047:11): [True: 0, False: 2.30k]
  ------------------
 1048|       |        // Vulkan: There must be no more than one PushConstant block per entry
 1049|       |        // point.
 1050|      0|        if (push_constant) {
  ------------------
  |  Branch (1050:13): [True: 0, False: 0]
  ------------------
 1051|      0|          auto entry_points = vstate.EntryPointReferences(var_id);
 1052|      0|          for (auto ep_id : entry_points) {
  ------------------
  |  Branch (1052:27): [True: 0, False: 0]
  ------------------
 1053|      0|            const bool already_used = !uses_push_constant.insert(ep_id).second;
 1054|      0|            if (already_used) {
  ------------------
  |  Branch (1054:17): [True: 0, False: 0]
  ------------------
 1055|      0|              return vstate.diag(SPV_ERROR_INVALID_ID, vstate.FindDef(var_id))
 1056|      0|                     << vstate.VkErrorID(6674) << "Entry point id '" << ep_id
 1057|      0|                     << "' uses more than one PushConstant interface.\n"
 1058|      0|                     << "From Vulkan spec:\n"
 1059|      0|                     << "There must be no more than one push constant block "
 1060|      0|                     << "statically used per shader entry point.";
 1061|      0|            }
 1062|      0|          }
 1063|      0|        }
 1064|       |        // Vulkan: Check DescriptorSet and Binding decoration for
 1065|       |        // UniformConstant which cannot be a struct.
 1066|      0|        if (uniform_constant) {
  ------------------
  |  Branch (1066:13): [True: 0, False: 0]
  ------------------
 1067|      0|          auto entry_points = vstate.EntryPointReferences(var_id);
 1068|      0|          if (!entry_points.empty() &&
  ------------------
  |  Branch (1068:15): [True: 0, False: 0]
  ------------------
 1069|      0|              !hasDecoration(var_id, spv::Decoration::DescriptorSet, vstate)) {
  ------------------
  |  Branch (1069:15): [True: 0, False: 0]
  ------------------
 1070|      0|            return vstate.diag(SPV_ERROR_INVALID_ID, vstate.FindDef(var_id))
 1071|      0|                   << vstate.VkErrorID(6677) << "UniformConstant id '" << var_id
 1072|      0|                   << "' is missing DescriptorSet decoration.\n"
 1073|      0|                   << "From Vulkan spec:\n"
 1074|      0|                   << "These variables must have DescriptorSet and Binding "
 1075|      0|                      "decorations specified";
 1076|      0|          }
 1077|      0|          if (!entry_points.empty() &&
  ------------------
  |  Branch (1077:15): [True: 0, False: 0]
  ------------------
 1078|      0|              !hasDecoration(var_id, spv::Decoration::Binding, vstate)) {
  ------------------
  |  Branch (1078:15): [True: 0, False: 0]
  ------------------
 1079|      0|            return vstate.diag(SPV_ERROR_INVALID_ID, vstate.FindDef(var_id))
 1080|      0|                   << vstate.VkErrorID(6677) << "UniformConstant id '" << var_id
 1081|      0|                   << "' is missing Binding decoration.\n"
 1082|      0|                   << "From Vulkan spec:\n"
 1083|      0|                   << "These variables must have DescriptorSet and Binding "
 1084|      0|                      "decorations specified";
 1085|      0|          }
 1086|      0|        }
 1087|      0|      }
 1088|       |
 1089|  2.30k|      if (spvIsOpenGLEnv(vstate.context()->target_env)) {
  ------------------
  |  Branch (1089:11): [True: 2.30k, False: 0]
  ------------------
 1090|  2.30k|        bool has_block = hasDecoration(var_id, spv::Decoration::Block, vstate);
 1091|  2.30k|        bool has_buffer_block =
 1092|  2.30k|            hasDecoration(var_id, spv::Decoration::BufferBlock, vstate);
 1093|  2.30k|        if ((uniform && (has_block || has_buffer_block)) ||
  ------------------
  |  Branch (1093:14): [True: 306, False: 2.00k]
  |  Branch (1093:26): [True: 6, False: 300]
  |  Branch (1093:39): [True: 6, False: 294]
  ------------------
 1094|  2.30k|            (storage_buffer && has_block)) {
  ------------------
  |  Branch (1094:14): [True: 0, False: 2.29k]
  |  Branch (1094:32): [True: 0, False: 0]
  ------------------
 1095|     12|          auto entry_points = vstate.EntryPointReferences(var_id);
 1096|     12|          if (!entry_points.empty() &&
  ------------------
  |  Branch (1096:15): [True: 0, False: 12]
  ------------------
 1097|     12|              !hasDecoration(var_id, spv::Decoration::Binding, vstate)) {
  ------------------
  |  Branch (1097:15): [True: 0, False: 0]
  ------------------
 1098|      0|            return vstate.diag(SPV_ERROR_INVALID_ID, vstate.FindDef(var_id))
 1099|      0|                   << (uniform ? "Uniform" : "Storage Buffer") << " id '"
  ------------------
  |  Branch (1099:24): [True: 0, False: 0]
  ------------------
 1100|      0|                   << var_id << "' is missing Binding decoration.\n"
 1101|      0|                   << "From ARB_gl_spirv extension:\n"
 1102|      0|                   << "Uniform and shader storage block variables must "
 1103|      0|                   << "also be decorated with a *Binding*.";
 1104|      0|          }
 1105|     12|        }
 1106|  2.30k|      }
 1107|       |
 1108|  2.30k|      const bool phys_storage_buffer =
 1109|  2.30k|          storageClass == spv::StorageClass::PhysicalStorageBuffer;
 1110|  2.30k|      const bool workgroup =
 1111|  2.30k|          storageClass == spv::StorageClass::Workgroup &&
  ------------------
  |  Branch (1111:11): [True: 1, False: 2.30k]
  ------------------
 1112|  2.30k|          vstate.HasCapability(
  ------------------
  |  Branch (1112:11): [True: 0, False: 1]
  ------------------
 1113|      1|              spv::Capability::WorkgroupMemoryExplicitLayoutKHR);
 1114|  2.30k|      if (uniform || push_constant || storage_buffer || phys_storage_buffer ||
  ------------------
  |  Branch (1114:11): [True: 306, False: 2.00k]
  |  Branch (1114:22): [True: 1, False: 1.99k]
  |  Branch (1114:39): [True: 0, False: 1.99k]
  |  Branch (1114:57): [True: 0, False: 1.99k]
  ------------------
 1115|  2.30k|          workgroup) {
  ------------------
  |  Branch (1115:11): [True: 0, False: 1.99k]
  ------------------
 1116|    307|        const auto ptrInst = vstate.FindDef(words[1]);
 1117|    307|        assert(spv::Op::OpTypePointer == ptrInst->opcode());
 1118|      0|        auto id = ptrInst->words()[3];
 1119|    307|        auto id_inst = vstate.FindDef(id);
 1120|       |        // Jump through one level of arraying.
 1121|    307|        if (!workgroup && (id_inst->opcode() == spv::Op::OpTypeArray ||
  ------------------
  |  Branch (1121:13): [True: 307, False: 0]
  |  Branch (1121:28): [True: 2, False: 305]
  ------------------
 1122|    307|                           id_inst->opcode() == spv::Op::OpTypeRuntimeArray)) {
  ------------------
  |  Branch (1122:28): [True: 8, False: 297]
  ------------------
 1123|     10|          id = id_inst->GetOperandAs<uint32_t>(1u);
 1124|     10|          id_inst = vstate.FindDef(id);
 1125|     10|        }
 1126|       |        // Struct requirement is checked on variables so just move on here.
 1127|    307|        if (spv::Op::OpTypeStruct != id_inst->opcode()) continue;
  ------------------
  |  Branch (1127:13): [True: 12, False: 295]
  ------------------
 1128|    295|        MemberConstraints constraints;
 1129|    295|        ComputeMemberConstraintsForStruct(&constraints, id, LayoutConstraints(),
 1130|    295|                                          vstate);
 1131|       |        // Prepare for messages
 1132|    295|        const char* sc_str =
 1133|    295|            uniform ? "Uniform"
  ------------------
  |  Branch (1133:13): [True: 295, False: 0]
  ------------------
 1134|    295|                    : (push_constant ? "PushConstant"
  ------------------
  |  Branch (1134:24): [True: 0, False: 0]
  ------------------
 1135|      0|                                     : (workgroup ? "Workgroup"
  ------------------
  |  Branch (1135:41): [True: 0, False: 0]
  ------------------
 1136|      0|                                                  : "StorageBuffer"));
 1137|       |
 1138|    295|        if (spvIsVulkanEnv(vstate.context()->target_env)) {
  ------------------
  |  Branch (1138:13): [True: 0, False: 295]
  ------------------
 1139|      0|          const bool block = hasDecoration(id, spv::Decoration::Block, vstate);
 1140|      0|          const bool buffer_block =
 1141|      0|              hasDecoration(id, spv::Decoration::BufferBlock, vstate);
 1142|      0|          if (storage_buffer && buffer_block) {
  ------------------
  |  Branch (1142:15): [True: 0, False: 0]
  |  Branch (1142:33): [True: 0, False: 0]
  ------------------
 1143|      0|            return vstate.diag(SPV_ERROR_INVALID_ID, vstate.FindDef(var_id))
 1144|      0|                   << vstate.VkErrorID(6675) << "Storage buffer id '" << var_id
 1145|      0|                   << " In Vulkan, BufferBlock is disallowed on variables in "
 1146|      0|                      "the StorageBuffer storage class";
 1147|      0|          }
 1148|       |          // Vulkan: Check Block decoration for PushConstant, Uniform
 1149|       |          // and StorageBuffer variables. Uniform can also use BufferBlock.
 1150|      0|          if (push_constant && !block) {
  ------------------
  |  Branch (1150:15): [True: 0, False: 0]
  |  Branch (1150:32): [True: 0, False: 0]
  ------------------
 1151|      0|            return vstate.diag(SPV_ERROR_INVALID_ID, vstate.FindDef(id))
 1152|      0|                   << vstate.VkErrorID(6675) << "PushConstant id '" << id
 1153|      0|                   << "' is missing Block decoration.\n"
 1154|      0|                   << "From Vulkan spec:\n"
 1155|      0|                   << "Such variables must be identified with a Block "
 1156|      0|                      "decoration";
 1157|      0|          }
 1158|      0|          if (storage_buffer && !block) {
  ------------------
  |  Branch (1158:15): [True: 0, False: 0]
  |  Branch (1158:33): [True: 0, False: 0]
  ------------------
 1159|      0|            return vstate.diag(SPV_ERROR_INVALID_ID, vstate.FindDef(id))
 1160|      0|                   << vstate.VkErrorID(6675) << "StorageBuffer id '" << id
 1161|      0|                   << "' is missing Block decoration.\n"
 1162|      0|                   << "From Vulkan spec:\n"
 1163|      0|                   << "Such variables must be identified with a Block "
 1164|      0|                      "decoration";
 1165|      0|          }
 1166|      0|          if (uniform && !block && !buffer_block) {
  ------------------
  |  Branch (1166:15): [True: 0, False: 0]
  |  Branch (1166:26): [True: 0, False: 0]
  |  Branch (1166:36): [True: 0, False: 0]
  ------------------
 1167|      0|            return vstate.diag(SPV_ERROR_INVALID_ID, vstate.FindDef(id))
 1168|      0|                   << vstate.VkErrorID(6676) << "Uniform id '" << id
 1169|      0|                   << "' is missing Block or BufferBlock decoration.\n"
 1170|      0|                   << "From Vulkan spec:\n"
 1171|      0|                   << "Such variables must be identified with a Block or "
 1172|      0|                      "BufferBlock decoration";
 1173|      0|          }
 1174|       |          // Vulkan: Check DescriptorSet and Binding decoration for
 1175|       |          // Uniform and StorageBuffer variables.
 1176|      0|          if (uniform || storage_buffer) {
  ------------------
  |  Branch (1176:15): [True: 0, False: 0]
  |  Branch (1176:26): [True: 0, False: 0]
  ------------------
 1177|      0|            auto entry_points = vstate.EntryPointReferences(var_id);
 1178|      0|            if (!entry_points.empty() &&
  ------------------
  |  Branch (1178:17): [True: 0, False: 0]
  ------------------
 1179|      0|                !hasDecoration(var_id, spv::Decoration::DescriptorSet,
  ------------------
  |  Branch (1179:17): [True: 0, False: 0]
  ------------------
 1180|      0|                               vstate)) {
 1181|      0|              return vstate.diag(SPV_ERROR_INVALID_ID, vstate.FindDef(var_id))
 1182|      0|                     << vstate.VkErrorID(6677) << sc_str << " id '" << var_id
 1183|      0|                     << "' is missing DescriptorSet decoration.\n"
 1184|      0|                     << "From Vulkan spec:\n"
 1185|      0|                     << "These variables must have DescriptorSet and Binding "
 1186|      0|                        "decorations specified";
 1187|      0|            }
 1188|      0|            if (!entry_points.empty() &&
  ------------------
  |  Branch (1188:17): [True: 0, False: 0]
  ------------------
 1189|      0|                !hasDecoration(var_id, spv::Decoration::Binding, vstate)) {
  ------------------
  |  Branch (1189:17): [True: 0, False: 0]
  ------------------
 1190|      0|              return vstate.diag(SPV_ERROR_INVALID_ID, vstate.FindDef(var_id))
 1191|      0|                     << vstate.VkErrorID(6677) << sc_str << " id '" << var_id
 1192|      0|                     << "' is missing Binding decoration.\n"
 1193|      0|                     << "From Vulkan spec:\n"
 1194|      0|                     << "These variables must have DescriptorSet and Binding "
 1195|      0|                        "decorations specified";
 1196|      0|            }
 1197|      0|          }
 1198|      0|        }
 1199|       |
 1200|  1.60k|        for (const auto& dec : vstate.id_decorations(id)) {
  ------------------
  |  Branch (1200:30): [True: 1.60k, False: 278]
  ------------------
 1201|  1.60k|          const bool blockDeco = spv::Decoration::Block == dec.dec_type();
 1202|  1.60k|          const bool bufferDeco =
 1203|  1.60k|              spv::Decoration::BufferBlock == dec.dec_type();
 1204|  1.60k|          const bool blockRules = uniform && blockDeco;
  ------------------
  |  Branch (1204:35): [True: 1.60k, False: 0]
  |  Branch (1204:46): [True: 124, False: 1.48k]
  ------------------
 1205|  1.60k|          const bool bufferRules =
 1206|  1.60k|              (uniform && bufferDeco) ||
  ------------------
  |  Branch (1206:16): [True: 1.60k, False: 0]
  |  Branch (1206:27): [True: 51, False: 1.55k]
  ------------------
 1207|  1.60k|              ((push_constant || storage_buffer ||
  ------------------
  |  Branch (1207:17): [True: 0, False: 1.55k]
  |  Branch (1207:34): [True: 0, False: 1.55k]
  ------------------
 1208|  1.55k|                phys_storage_buffer || workgroup) && blockDeco);
  ------------------
  |  Branch (1208:17): [True: 0, False: 1.55k]
  |  Branch (1208:40): [True: 0, False: 1.55k]
  |  Branch (1208:54): [True: 0, False: 0]
  ------------------
 1209|  1.60k|          if (uniform && blockDeco) {
  ------------------
  |  Branch (1209:15): [True: 1.60k, False: 0]
  |  Branch (1209:26): [True: 124, False: 1.48k]
  ------------------
 1210|    124|            vstate.RegisterPointerToUniformBlock(ptrInst->id());
 1211|    124|            vstate.RegisterStructForUniformBlock(id);
 1212|    124|          }
 1213|  1.60k|          if ((uniform && bufferDeco) ||
  ------------------
  |  Branch (1213:16): [True: 1.60k, False: 0]
  |  Branch (1213:27): [True: 51, False: 1.55k]
  ------------------
 1214|  1.60k|              ((storage_buffer || phys_storage_buffer) && blockDeco)) {
  ------------------
  |  Branch (1214:17): [True: 0, False: 1.55k]
  |  Branch (1214:35): [True: 0, False: 1.55k]
  |  Branch (1214:59): [True: 0, False: 0]
  ------------------
 1215|     51|            vstate.RegisterPointerToStorageBuffer(ptrInst->id());
 1216|     51|            vstate.RegisterStructForStorageBuffer(id);
 1217|     51|          }
 1218|       |
 1219|  1.60k|          if (blockRules || bufferRules) {
  ------------------
  |  Branch (1219:15): [True: 124, False: 1.48k]
  |  Branch (1219:29): [True: 51, False: 1.43k]
  ------------------
 1220|    175|            const char* deco_str = blockDeco ? "Block" : "BufferBlock";
  ------------------
  |  Branch (1220:36): [True: 124, False: 51]
  ------------------
 1221|    175|            spv_result_t recursive_status = SPV_SUCCESS;
 1222|    175|            const bool scalar_block_layout = workgroup ?
  ------------------
  |  Branch (1222:46): [True: 0, False: 175]
  ------------------
 1223|      0|                vstate.options()->workgroup_scalar_block_layout :
 1224|    175|                vstate.options()->scalar_block_layout;
 1225|       |
 1226|    175|            if (isMissingOffsetInStruct(id, vstate)) {
  ------------------
  |  Branch (1226:17): [True: 13, False: 162]
  ------------------
 1227|     13|              return vstate.diag(SPV_ERROR_INVALID_ID, vstate.FindDef(id))
 1228|     13|                     << "Structure id " << id << " decorated as " << deco_str
 1229|     13|                     << " must be explicitly laid out with Offset "
 1230|     13|                        "decorations.";
 1231|     13|            }
 1232|       |
 1233|    162|            if (!checkForRequiredDecoration(
  ------------------
  |  Branch (1233:17): [True: 3, False: 159]
  ------------------
 1234|    162|                    id,
 1235|    162|                    [](spv::Decoration d) {
 1236|    162|                      return d == spv::Decoration::ArrayStride;
 1237|    162|                    },
 1238|    162|                    spv::Op::OpTypeArray, vstate)) {
 1239|      3|              return vstate.diag(SPV_ERROR_INVALID_ID, vstate.FindDef(id))
 1240|      3|                     << "Structure id " << id << " decorated as " << deco_str
 1241|      3|                     << " must be explicitly laid out with ArrayStride "
 1242|      3|                        "decorations.";
 1243|      3|            }
 1244|       |
 1245|    159|            if (!checkForRequiredDecoration(
  ------------------
  |  Branch (1245:17): [True: 1, False: 158]
  ------------------
 1246|    159|                    id,
 1247|    159|                    [](spv::Decoration d) {
 1248|    159|                      return d == spv::Decoration::MatrixStride;
 1249|    159|                    },
 1250|    159|                    spv::Op::OpTypeMatrix, vstate)) {
 1251|      1|              return vstate.diag(SPV_ERROR_INVALID_ID, vstate.FindDef(id))
 1252|      1|                     << "Structure id " << id << " decorated as " << deco_str
 1253|      1|                     << " must be explicitly laid out with MatrixStride "
 1254|      1|                        "decorations.";
 1255|      1|            }
 1256|       |
 1257|    158|            if (!checkForRequiredDecoration(
  ------------------
  |  Branch (1257:17): [True: 0, False: 158]
  ------------------
 1258|    158|                    id,
 1259|    158|                    [](spv::Decoration d) {
 1260|    158|                      return d == spv::Decoration::RowMajor ||
 1261|    158|                             d == spv::Decoration::ColMajor;
 1262|    158|                    },
 1263|    158|                    spv::Op::OpTypeMatrix, vstate)) {
 1264|      0|              return vstate.diag(SPV_ERROR_INVALID_ID, vstate.FindDef(id))
 1265|      0|                     << "Structure id " << id << " decorated as " << deco_str
 1266|      0|                     << " must be explicitly laid out with RowMajor or "
 1267|      0|                        "ColMajor decorations.";
 1268|      0|            }
 1269|       |
 1270|    158|            if (spvIsVulkanEnv(vstate.context()->target_env)) {
  ------------------
  |  Branch (1270:17): [True: 0, False: 158]
  ------------------
 1271|      0|              if (blockRules && (SPV_SUCCESS != (recursive_status = checkLayout(
  ------------------
  |  Branch (1271:19): [True: 0, False: 0]
  |  Branch (1271:33): [True: 0, False: 0]
  ------------------
 1272|      0|                                                     id, sc_str, deco_str, true,
 1273|      0|                                                     scalar_block_layout, 0,
 1274|      0|                                                     constraints, vstate)))) {
 1275|      0|                return recursive_status;
 1276|      0|              } else if (bufferRules &&
  ------------------
  |  Branch (1276:26): [True: 0, False: 0]
  ------------------
 1277|      0|                         (SPV_SUCCESS !=
  ------------------
  |  Branch (1277:26): [True: 0, False: 0]
  ------------------
 1278|      0|                          (recursive_status = checkLayout(
 1279|      0|                               id, sc_str, deco_str, false, scalar_block_layout,
 1280|      0|                               0, constraints, vstate)))) {
 1281|      0|                return recursive_status;
 1282|      0|              }
 1283|      0|            }
 1284|    158|          }
 1285|  1.60k|        }
 1286|    295|      }
 1287|  2.30k|    }
 1288|  89.3k|  }
 1289|    966|  return SPV_SUCCESS;
 1290|    983|}
validate_decorations.cpp:_ZN8spvtools3val12_GLOBAL__N_133ComputeMemberConstraintsForStructEPNSt3__113unordered_mapINS2_4pairIjjEENS1_17LayoutConstraintsENS1_8PairHashENS2_8equal_toIS5_EENS2_9allocatorINS4_IKS5_S6_EEEEEEjRKS6_RNS0_17ValidationState_tE:
  958|    436|                                       ValidationState_t& vstate) {
  959|    436|  assert(constraints);
  960|      0|  const auto& members = getStructMembers(struct_id, vstate);
  961|    436|  for (uint32_t memberIdx = 0, numMembers = uint32_t(members.size());
  962|    903|       memberIdx < numMembers; memberIdx++) {
  ------------------
  |  Branch (962:8): [True: 467, False: 436]
  ------------------
  963|    467|    LayoutConstraints& constraint =
  964|    467|        (*constraints)[std::make_pair(struct_id, memberIdx)];
  965|    467|    constraint = inherited;
  966|    467|    auto member_decorations =
  967|    467|        vstate.id_member_decorations(struct_id, memberIdx);
  968|    467|    for (auto decoration = member_decorations.begin;
  969|    794|         decoration != member_decorations.end; ++decoration) {
  ------------------
  |  Branch (969:10): [True: 327, False: 467]
  ------------------
  970|    327|      assert(decoration->struct_member_index() == (int)memberIdx);
  971|      0|      switch (decoration->dec_type()) {
  972|      2|        case spv::Decoration::RowMajor:
  ------------------
  |  Branch (972:9): [True: 2, False: 325]
  ------------------
  973|      2|          constraint.majorness = kRowMajor;
  974|      2|          break;
  975|      7|        case spv::Decoration::ColMajor:
  ------------------
  |  Branch (975:9): [True: 7, False: 320]
  ------------------
  976|      7|          constraint.majorness = kColumnMajor;
  977|      7|          break;
  978|     14|        case spv::Decoration::MatrixStride:
  ------------------
  |  Branch (978:9): [True: 14, False: 313]
  ------------------
  979|     14|          constraint.matrix_stride = decoration->params()[0];
  980|     14|          break;
  981|    304|        default:
  ------------------
  |  Branch (981:9): [True: 304, False: 23]
  ------------------
  982|    304|          break;
  983|    327|      }
  984|    327|    }
  985|       |
  986|       |    // Now recurse
  987|    467|    auto member_type_id = members[memberIdx];
  988|    467|    const auto member_type_inst = vstate.FindDef(member_type_id);
  989|    467|    const auto opcode = member_type_inst->opcode();
  990|    467|    switch (opcode) {
  991|     79|      case spv::Op::OpTypeArray:
  ------------------
  |  Branch (991:7): [True: 79, False: 388]
  ------------------
  992|    112|      case spv::Op::OpTypeRuntimeArray:
  ------------------
  |  Branch (992:7): [True: 33, False: 434]
  ------------------
  993|    112|        ComputeMemberConstraintsForArray(constraints, member_type_id, inherited,
  994|    112|                                         vstate);
  995|    112|        break;
  996|    114|      case spv::Op::OpTypeStruct:
  ------------------
  |  Branch (996:7): [True: 114, False: 353]
  ------------------
  997|    114|        ComputeMemberConstraintsForStruct(constraints, member_type_id,
  998|    114|                                          inherited, vstate);
  999|    114|        break;
 1000|    241|      default:
  ------------------
  |  Branch (1000:7): [True: 241, False: 226]
  ------------------
 1001|    241|        break;
 1002|    467|    }
 1003|    467|  }
 1004|    436|}
validate_decorations.cpp:_ZNK8spvtools3val12_GLOBAL__N_18PairHashclENSt3__14pairIjjEE:
   43|    467|  std::size_t operator()(const std::pair<uint32_t, uint32_t> pair) const {
   44|    467|    const uint32_t a = pair.first;
   45|    467|    const uint32_t b = pair.second;
   46|    467|    const uint32_t rotated_b = (b >> 2) | ((b & 3) << 30);
   47|    467|    return a ^ rotated_b;
   48|    467|  }
validate_decorations.cpp:_ZN8spvtools3val12_GLOBAL__N_132ComputeMemberConstraintsForArrayEPNSt3__113unordered_mapINS2_4pairIjjEENS1_17LayoutConstraintsENS1_8PairHashENS2_8equal_toIS5_EENS2_9allocatorINS4_IKS5_S6_EEEEEEjRKS6_RNS0_17ValidationState_tE:
 1009|    118|                                      ValidationState_t& vstate) {
 1010|    118|  assert(constraints);
 1011|      0|  auto elem_type_id = vstate.FindDef(array_id)->words()[2];
 1012|    118|  const auto elem_type_inst = vstate.FindDef(elem_type_id);
 1013|    118|  const auto opcode = elem_type_inst->opcode();
 1014|    118|  switch (opcode) {
 1015|      0|    case spv::Op::OpTypeArray:
  ------------------
  |  Branch (1015:5): [True: 0, False: 118]
  ------------------
 1016|      6|    case spv::Op::OpTypeRuntimeArray:
  ------------------
  |  Branch (1016:5): [True: 6, False: 112]
  ------------------
 1017|      6|      ComputeMemberConstraintsForArray(constraints, elem_type_id, inherited,
 1018|      6|                                       vstate);
 1019|      6|      break;
 1020|     27|    case spv::Op::OpTypeStruct:
  ------------------
  |  Branch (1020:5): [True: 27, False: 91]
  ------------------
 1021|     27|      ComputeMemberConstraintsForStruct(constraints, elem_type_id, inherited,
 1022|     27|                                        vstate);
 1023|     27|      break;
 1024|     85|    default:
  ------------------
  |  Branch (1024:5): [True: 85, False: 33]
  ------------------
 1025|     85|      break;
 1026|    118|  }
 1027|    118|}
validate_decorations.cpp:_ZN8spvtools3val12_GLOBAL__N_117LayoutConstraintsC2ENS1_12MatrixLayoutEj:
   63|    745|      : majorness(the_majorness), matrix_stride(stride) {}
validate_decorations.cpp:_ZN8spvtools3val12_GLOBAL__N_123isMissingOffsetInStructEjRNS0_17ValidationState_tE:
  143|    436|bool isMissingOffsetInStruct(uint32_t struct_id, ValidationState_t& vstate) {
  144|    436|  const auto* inst = vstate.FindDef(struct_id);
  145|    436|  std::vector<bool> hasOffset;
  146|    436|  std::vector<uint32_t> struct_members;
  147|    436|  if (inst->opcode() == spv::Op::OpTypeStruct) {
  ------------------
  |  Branch (147:7): [True: 192, False: 244]
  ------------------
  148|       |    // Check offsets of member decorations.
  149|    192|    struct_members = getStructMembers(struct_id, vstate);
  150|    192|    hasOffset.resize(struct_members.size(), false);
  151|       |
  152|  1.32k|    for (auto& decoration : vstate.id_decorations(struct_id)) {
  ------------------
  |  Branch (152:27): [True: 1.32k, False: 189]
  ------------------
  153|  1.32k|      if (spv::Decoration::Offset == decoration.dec_type() &&
  ------------------
  |  Branch (153:11): [True: 236, False: 1.08k]
  ------------------
  154|  1.32k|          Decoration::kInvalidMember != decoration.struct_member_index()) {
  ------------------
  |  Branch (154:11): [True: 212, False: 24]
  ------------------
  155|       |        // Offset 0xffffffff is not valid so ignore it for simplicity's sake.
  156|    212|        if (decoration.params()[0] == 0xffffffff) return true;
  ------------------
  |  Branch (156:13): [True: 3, False: 209]
  ------------------
  157|    209|        hasOffset[decoration.struct_member_index()] = true;
  158|    209|      }
  159|  1.32k|    }
  160|    244|  } else if (inst->opcode() == spv::Op::OpTypeArray ||
  ------------------
  |  Branch (160:14): [True: 73, False: 171]
  ------------------
  161|    244|             inst->opcode() == spv::Op::OpTypeRuntimeArray) {
  ------------------
  |  Branch (161:14): [True: 1, False: 170]
  ------------------
  162|     74|    hasOffset.resize(1, true);
  163|     74|    struct_members.push_back(inst->GetOperandAs<uint32_t>(1u));
  164|     74|  }
  165|       |  // Look through nested structs (which may be in an array).
  166|    433|  bool nestedStructsMissingOffset = false;
  167|    433|  for (auto id : struct_members) {
  ------------------
  |  Branch (167:16): [True: 261, False: 422]
  ------------------
  168|    261|    if (isMissingOffsetInStruct(id, vstate)) {
  ------------------
  |  Branch (168:9): [True: 11, False: 250]
  ------------------
  169|     11|      nestedStructsMissingOffset = true;
  170|     11|      break;
  171|     11|    }
  172|    261|  }
  173|    433|  return nestedStructsMissingOffset ||
  ------------------
  |  Branch (173:10): [True: 11, False: 422]
  ------------------
  174|    433|         !std::all_of(hasOffset.begin(), hasOffset.end(),
  ------------------
  |  Branch (174:10): [True: 10, False: 412]
  ------------------
  175|    422|                      [](const bool b) { return b; });
  176|    436|}
validate_decorations.cpp:_ZZN8spvtools3val12_GLOBAL__N_123isMissingOffsetInStructEjRNS0_17ValidationState_tEENK3$_4clEb:
  175|    250|                      [](const bool b) { return b; });
validate_decorations.cpp:_ZN8spvtools3val12_GLOBAL__N_126checkForRequiredDecorationEjNSt3__18functionIFbN3spv10DecorationEEEENS4_2OpERNS0_17ValidationState_tE:
  667|    487|                                spv::Op type, ValidationState_t& vstate) {
  668|    487|  const auto& members = getStructMembers(struct_id, vstate);
  669|    964|  for (size_t memberIdx = 0; memberIdx < members.size(); memberIdx++) {
  ------------------
  |  Branch (669:30): [True: 481, False: 483]
  ------------------
  670|    481|    const auto id = members[memberIdx];
  671|    481|    if (type != vstate.FindDef(id)->opcode()) continue;
  ------------------
  |  Branch (671:9): [True: 411, False: 70]
  ------------------
  672|     70|    bool found = false;
  673|    530|    for (auto& dec : vstate.id_decorations(id)) {
  ------------------
  |  Branch (673:20): [True: 530, False: 70]
  ------------------
  674|    530|      if (checker(dec.dec_type())) found = true;
  ------------------
  |  Branch (674:11): [True: 76, False: 454]
  ------------------
  675|    530|    }
  676|  1.01k|    for (auto& dec : vstate.id_decorations(struct_id)) {
  ------------------
  |  Branch (676:20): [True: 1.01k, False: 70]
  ------------------
  677|  1.01k|      if (checker(dec.dec_type()) &&
  ------------------
  |  Branch (677:11): [True: 141, False: 876]
  ------------------
  678|  1.01k|          (int)memberIdx == dec.struct_member_index()) {
  ------------------
  |  Branch (678:11): [True: 68, False: 73]
  ------------------
  679|     68|        found = true;
  680|     68|      }
  681|  1.01k|    }
  682|     70|    if (!found) {
  ------------------
  |  Branch (682:9): [True: 4, False: 66]
  ------------------
  683|      4|      return false;
  684|      4|    }
  685|     70|  }
  686|    483|  for (auto id : getStructMembers(struct_id, spv::Op::OpTypeStruct, vstate)) {
  ------------------
  |  Branch (686:16): [True: 8, False: 481]
  ------------------
  687|      8|    if (!checkForRequiredDecoration(id, checker, type, vstate)) {
  ------------------
  |  Branch (687:9): [True: 2, False: 6]
  ------------------
  688|      2|      return false;
  689|      2|    }
  690|      8|  }
  691|    481|  return true;
  692|    483|}
validate_decorations.cpp:_ZZN8spvtools3val12_GLOBAL__N_125CheckDecorationsOfBuffersERNS0_17ValidationState_tEENK3$_6clEN3spv10DecorationE:
 1235|  1.51k|                    [](spv::Decoration d) {
 1236|  1.51k|                      return d == spv::Decoration::ArrayStride;
 1237|  1.51k|                    },
validate_decorations.cpp:_ZZN8spvtools3val12_GLOBAL__N_125CheckDecorationsOfBuffersERNS0_17ValidationState_tEENK3$_7clEN3spv10DecorationE:
 1247|     15|                    [](spv::Decoration d) {
 1248|     15|                      return d == spv::Decoration::MatrixStride;
 1249|     15|                    },
validate_decorations.cpp:_ZZN8spvtools3val12_GLOBAL__N_125CheckDecorationsOfBuffersERNS0_17ValidationState_tEENK3$_8clEN3spv10DecorationE:
 1259|     13|                    [](spv::Decoration d) {
 1260|     13|                      return d == spv::Decoration::RowMajor ||
  ------------------
  |  Branch (1260:30): [True: 0, False: 13]
  ------------------
 1261|     13|                             d == spv::Decoration::ColMajor;
  ------------------
  |  Branch (1261:30): [True: 3, False: 10]
  ------------------
 1262|     13|                    },
validate_decorations.cpp:_ZN8spvtools3val12_GLOBAL__N_129CheckDecorationsCompatibilityERNS0_17ValidationState_tE:
 1311|    966|spv_result_t CheckDecorationsCompatibility(ValidationState_t& vstate) {
 1312|    966|  using PerIDKey = std::tuple<spv::Decoration, uint32_t>;
 1313|    966|  using PerMemberKey = std::tuple<spv::Decoration, uint32_t, uint32_t>;
 1314|       |
 1315|       |  // An Array of pairs where the decorations in the pair cannot both be applied
 1316|       |  // to the same id.
 1317|    966|  static const spv::Decoration mutually_exclusive_per_id[][2] = {
 1318|    966|      {spv::Decoration::Block, spv::Decoration::BufferBlock},
 1319|    966|      {spv::Decoration::Restrict, spv::Decoration::Aliased}};
 1320|    966|  static const auto num_mutually_exclusive_per_id_pairs =
 1321|    966|      sizeof(mutually_exclusive_per_id) / (2 * sizeof(spv::Decoration));
 1322|       |
 1323|       |  // An Array of pairs where the decorations in the pair cannot both be applied
 1324|       |  // to the same member.
 1325|    966|  static const spv::Decoration mutually_exclusive_per_member[][2] = {
 1326|    966|      {spv::Decoration::RowMajor, spv::Decoration::ColMajor}};
 1327|    966|  static const auto num_mutually_exclusive_per_mem_pairs =
 1328|    966|      sizeof(mutually_exclusive_per_member) / (2 * sizeof(spv::Decoration));
 1329|       |
 1330|    966|  std::set<PerIDKey> seen_per_id;
 1331|    966|  std::set<PerMemberKey> seen_per_member;
 1332|       |
 1333|  86.9k|  for (const auto& inst : vstate.ordered_instructions()) {
  ------------------
  |  Branch (1333:25): [True: 86.9k, False: 931]
  ------------------
 1334|  86.9k|    const auto& words = inst.words();
 1335|  86.9k|    if (spv::Op::OpDecorate == inst.opcode()) {
  ------------------
  |  Branch (1335:9): [True: 7.78k, False: 79.1k]
  ------------------
 1336|  7.78k|      const auto id = words[1];
 1337|  7.78k|      const auto dec_type = static_cast<spv::Decoration>(words[2]);
 1338|  7.78k|      const auto k = PerIDKey(dec_type, id);
 1339|  7.78k|      const auto already_used = !seen_per_id.insert(k).second;
 1340|  7.78k|      if (already_used && AtMostOncePerId(dec_type)) {
  ------------------
  |  Branch (1340:11): [True: 4.10k, False: 3.67k]
  |  Branch (1340:27): [True: 5, False: 4.10k]
  ------------------
 1341|      5|        return vstate.diag(SPV_ERROR_INVALID_ID, vstate.FindDef(id))
 1342|      5|               << "ID '" << id << "' decorated with "
 1343|      5|               << vstate.SpvDecorationString(dec_type)
 1344|      5|               << " multiple times is not allowed.";
 1345|      5|      }
 1346|       |      // Verify certain mutually exclusive decorations are not both applied on
 1347|       |      // an ID.
 1348|  7.77k|      for (uint32_t pair_idx = 0;
 1349|  23.3k|           pair_idx < num_mutually_exclusive_per_id_pairs; ++pair_idx) {
  ------------------
  |  Branch (1349:12): [True: 15.5k, False: 7.76k]
  ------------------
 1350|  15.5k|        spv::Decoration excl_dec_type = spv::Decoration::Max;
 1351|  15.5k|        if (mutually_exclusive_per_id[pair_idx][0] == dec_type) {
  ------------------
  |  Branch (1351:13): [True: 378, False: 15.1k]
  ------------------
 1352|    378|          excl_dec_type = mutually_exclusive_per_id[pair_idx][1];
 1353|  15.1k|        } else if (mutually_exclusive_per_id[pair_idx][1] == dec_type) {
  ------------------
  |  Branch (1353:20): [True: 879, False: 14.2k]
  ------------------
 1354|    879|          excl_dec_type = mutually_exclusive_per_id[pair_idx][0];
 1355|  14.2k|        } else {
 1356|  14.2k|          continue;
 1357|  14.2k|        }
 1358|       |
 1359|  1.25k|        const auto excl_k = PerIDKey(excl_dec_type, id);
 1360|  1.25k|        if (seen_per_id.find(excl_k) != seen_per_id.end()) {
  ------------------
  |  Branch (1360:13): [True: 17, False: 1.24k]
  ------------------
 1361|     17|          return vstate.diag(SPV_ERROR_INVALID_ID, vstate.FindDef(id))
 1362|     17|                 << "ID '" << id << "' decorated with both "
 1363|     17|                 << vstate.SpvDecorationString(dec_type) << " and "
 1364|     17|                 << vstate.SpvDecorationString(excl_dec_type)
 1365|     17|                 << " is not allowed.";
 1366|     17|        }
 1367|  1.25k|      }
 1368|  79.1k|    } else if (spv::Op::OpMemberDecorate == inst.opcode()) {
  ------------------
  |  Branch (1368:16): [True: 614, False: 78.5k]
  ------------------
 1369|    614|      const auto id = words[1];
 1370|    614|      const auto member_id = words[2];
 1371|    614|      const auto dec_type = static_cast<spv::Decoration>(words[3]);
 1372|    614|      const auto k = PerMemberKey(dec_type, id, member_id);
 1373|    614|      const auto already_used = !seen_per_member.insert(k).second;
 1374|    614|      if (already_used && AtMostOncePerMember(dec_type)) {
  ------------------
  |  Branch (1374:11): [True: 339, False: 275]
  |  Branch (1374:27): [True: 11, False: 328]
  ------------------
 1375|     11|        return vstate.diag(SPV_ERROR_INVALID_ID, vstate.FindDef(id))
 1376|     11|               << "ID '" << id << "', member '" << member_id
 1377|     11|               << "' decorated with " << vstate.SpvDecorationString(dec_type)
 1378|     11|               << " multiple times is not allowed.";
 1379|     11|      }
 1380|       |      // Verify certain mutually exclusive decorations are not both applied on
 1381|       |      // a (ID, member) tuple.
 1382|    603|      for (uint32_t pair_idx = 0;
 1383|  1.20k|           pair_idx < num_mutually_exclusive_per_mem_pairs; ++pair_idx) {
  ------------------
  |  Branch (1383:12): [True: 603, False: 601]
  ------------------
 1384|    603|        spv::Decoration excl_dec_type = spv::Decoration::Max;
 1385|    603|        if (mutually_exclusive_per_member[pair_idx][0] == dec_type) {
  ------------------
  |  Branch (1385:13): [True: 15, False: 588]
  ------------------
 1386|     15|          excl_dec_type = mutually_exclusive_per_member[pair_idx][1];
 1387|    588|        } else if (mutually_exclusive_per_member[pair_idx][1] == dec_type) {
  ------------------
  |  Branch (1387:20): [True: 17, False: 571]
  ------------------
 1388|     17|          excl_dec_type = mutually_exclusive_per_member[pair_idx][0];
 1389|    571|        } else {
 1390|    571|          continue;
 1391|    571|        }
 1392|       |
 1393|     32|        const auto excl_k = PerMemberKey(excl_dec_type, id, member_id);
 1394|     32|        if (seen_per_member.find(excl_k) != seen_per_member.end()) {
  ------------------
  |  Branch (1394:13): [True: 2, False: 30]
  ------------------
 1395|      2|          return vstate.diag(SPV_ERROR_INVALID_ID, vstate.FindDef(id))
 1396|      2|                 << "ID '" << id << "', member '" << member_id
 1397|      2|                 << "' decorated with both "
 1398|      2|                 << vstate.SpvDecorationString(dec_type) << " and "
 1399|      2|                 << vstate.SpvDecorationString(excl_dec_type)
 1400|      2|                 << " is not allowed.";
 1401|      2|        }
 1402|     32|      }
 1403|    603|    }
 1404|  86.9k|  }
 1405|    931|  return SPV_SUCCESS;
 1406|    966|}
validate_decorations.cpp:_ZN8spvtools3val12_GLOBAL__N_115AtMostOncePerIdEN3spv10DecorationE:
 1293|  4.10k|bool AtMostOncePerId(spv::Decoration decoration) {
 1294|  4.10k|  return decoration == spv::Decoration::ArrayStride;
 1295|  4.10k|}
validate_decorations.cpp:_ZN8spvtools3val12_GLOBAL__N_119AtMostOncePerMemberEN3spv10DecorationE:
 1299|    339|bool AtMostOncePerMember(spv::Decoration decoration) {
 1300|    339|  switch (decoration) {
 1301|      9|    case spv::Decoration::Offset:
  ------------------
  |  Branch (1301:5): [True: 9, False: 330]
  ------------------
 1302|     11|    case spv::Decoration::MatrixStride:
  ------------------
  |  Branch (1302:5): [True: 2, False: 337]
  ------------------
 1303|     11|    case spv::Decoration::RowMajor:
  ------------------
  |  Branch (1303:5): [True: 0, False: 339]
  ------------------
 1304|     11|    case spv::Decoration::ColMajor:
  ------------------
  |  Branch (1304:5): [True: 0, False: 339]
  ------------------
 1305|     11|      return true;
 1306|    328|    default:
  ------------------
  |  Branch (1306:5): [True: 328, False: 11]
  ------------------
 1307|    328|      return false;
 1308|    339|  }
 1309|    339|}
validate_decorations.cpp:_ZN8spvtools3val12_GLOBAL__N_127CheckLinkageAttrOfFunctionsERNS0_17ValidationState_tE:
  694|    931|spv_result_t CheckLinkageAttrOfFunctions(ValidationState_t& vstate) {
  695|  1.01k|  for (const auto& function : vstate.functions()) {
  ------------------
  |  Branch (695:29): [True: 1.01k, False: 730]
  ------------------
  696|  1.01k|    if (function.block_count() == 0u) {
  ------------------
  |  Branch (696:9): [True: 201, False: 817]
  ------------------
  697|       |      // A function declaration (an OpFunction with no basic blocks), must have
  698|       |      // a Linkage Attributes Decoration with the Import Linkage Type.
  699|    201|      if (!hasImportLinkageAttribute(function.id(), vstate)) {
  ------------------
  |  Branch (699:11): [True: 201, False: 0]
  ------------------
  700|    201|        return vstate.diag(SPV_ERROR_INVALID_BINARY,
  701|    201|                           vstate.FindDef(function.id()))
  702|    201|               << "Function declaration (id " << function.id()
  703|    201|               << ") must have a LinkageAttributes decoration with the Import "
  704|    201|                  "Linkage type.";
  705|    201|      }
  706|    817|    } else {
  707|    817|      if (hasImportLinkageAttribute(function.id(), vstate)) {
  ------------------
  |  Branch (707:11): [True: 0, False: 817]
  ------------------
  708|      0|        return vstate.diag(SPV_ERROR_INVALID_BINARY,
  709|      0|                           vstate.FindDef(function.id()))
  710|      0|               << "Function definition (id " << function.id()
  711|      0|               << ") may not be decorated with Import Linkage type.";
  712|      0|      }
  713|    817|    }
  714|  1.01k|  }
  715|    730|  return SPV_SUCCESS;
  716|    931|}
validate_decorations.cpp:_ZN8spvtools3val12_GLOBAL__N_143CheckVulkanMemoryModelDeprecatedDecorationsERNS0_17ValidationState_tE:
 1409|    730|    ValidationState_t& vstate) {
 1410|    730|  if (vstate.memory_model() != spv::MemoryModel::VulkanKHR) return SPV_SUCCESS;
  ------------------
  |  Branch (1410:7): [True: 711, False: 19]
  ------------------
 1411|       |
 1412|     19|  std::string msg;
 1413|     19|  std::ostringstream str(msg);
 1414|    180|  for (const auto& def : vstate.all_definitions()) {
  ------------------
  |  Branch (1414:24): [True: 180, False: 19]
  ------------------
 1415|    180|    const auto inst = def.second;
 1416|    180|    const auto id = inst->id();
 1417|    180|    for (const auto& dec : vstate.id_decorations(id)) {
  ------------------
  |  Branch (1417:26): [True: 0, False: 180]
  ------------------
 1418|      0|      const auto member = dec.struct_member_index();
 1419|      0|      if (dec.dec_type() == spv::Decoration::Coherent ||
  ------------------
  |  Branch (1419:11): [True: 0, False: 0]
  ------------------
 1420|      0|          dec.dec_type() == spv::Decoration::Volatile) {
  ------------------
  |  Branch (1420:11): [True: 0, False: 0]
  ------------------
 1421|      0|        str << (dec.dec_type() == spv::Decoration::Coherent ? "Coherent"
  ------------------
  |  Branch (1421:17): [True: 0, False: 0]
  ------------------
 1422|      0|                                                            : "Volatile");
 1423|      0|        str << " decoration targeting " << vstate.getIdName(id);
 1424|      0|        if (member != Decoration::kInvalidMember) {
  ------------------
  |  Branch (1424:13): [True: 0, False: 0]
  ------------------
 1425|      0|          str << " (member index " << member << ")";
 1426|      0|        }
 1427|      0|        str << " is banned when using the Vulkan memory model.";
 1428|      0|        return vstate.diag(SPV_ERROR_INVALID_ID, inst) << str.str();
 1429|      0|      }
 1430|      0|    }
 1431|    180|  }
 1432|     19|  return SPV_SUCCESS;
 1433|     19|}
validate_decorations.cpp:_ZN8spvtools3val12_GLOBAL__N_130CheckDecorationsFromDecorationERNS0_17ValidationState_tE:
 1806|    730|spv_result_t CheckDecorationsFromDecoration(ValidationState_t& vstate) {
 1807|       |  // Some rules are only checked for shaders.
 1808|    730|  const bool is_shader = vstate.HasCapability(spv::Capability::Shader);
 1809|       |
 1810|  5.72k|  for (const auto& kv : vstate.id_decorations()) {
  ------------------
  |  Branch (1810:23): [True: 5.72k, False: 664]
  ------------------
 1811|  5.72k|    const uint32_t id = kv.first;
 1812|  5.72k|    const auto& decorations = kv.second;
 1813|  5.72k|    if (decorations.empty()) continue;
  ------------------
  |  Branch (1813:9): [True: 3.04k, False: 2.68k]
  ------------------
 1814|       |
 1815|  2.68k|    const Instruction* inst = vstate.FindDef(id);
 1816|  2.68k|    assert(inst);
 1817|       |
 1818|       |    // We assume the decorations applied to a decoration group have already
 1819|       |    // been propagated down to the group members.
 1820|  2.68k|    if (inst->opcode() == spv::Op::OpDecorationGroup) continue;
  ------------------
  |  Branch (1820:9): [True: 64, False: 2.61k]
  ------------------
 1821|       |
 1822|  3.37k|    for (const auto& decoration : decorations) {
  ------------------
  |  Branch (1822:33): [True: 3.37k, False: 2.55k]
  ------------------
 1823|  3.37k|      switch (decoration.dec_type()) {
 1824|    133|        case spv::Decoration::Component:
  ------------------
  |  Branch (1824:9): [True: 133, False: 3.24k]
  ------------------
 1825|    133|          PASS_OR_BAIL(CheckComponentDecoration(vstate, *inst, decoration));
  ------------------
  |  | 1801|    133|#define PASS_OR_BAIL(X) PASS_OR_BAIL_AT_LINE(X, __LINE__)
  |  |  ------------------
  |  |  |  | 1797|    133|  {                                             \
  |  |  |  | 1798|    133|    spv_result_t e##LINE = (X);                 \
  |  |  |  | 1799|    133|    if (e##LINE != SPV_SUCCESS) return e##LINE; \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (1799:9): [True: 6, False: 127]
  |  |  |  |  ------------------
  |  |  |  | 1800|    133|  } static_assert(true, "require extra semicolon")
  |  |  ------------------
  ------------------
 1826|    127|          break;
 1827|      1|        case spv::Decoration::FPRoundingMode:
  ------------------
  |  Branch (1827:9): [True: 1, False: 3.37k]
  ------------------
 1828|      1|          if (is_shader)
  ------------------
  |  Branch (1828:15): [True: 1, False: 0]
  ------------------
 1829|      1|            PASS_OR_BAIL(
  ------------------
  |  | 1801|      1|#define PASS_OR_BAIL(X) PASS_OR_BAIL_AT_LINE(X, __LINE__)
  |  |  ------------------
  |  |  |  | 1797|      1|  {                                             \
  |  |  |  | 1798|      1|    spv_result_t e##LINE = (X);                 \
  |  |  |  | 1799|      1|    if (e##LINE != SPV_SUCCESS) return e##LINE; \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (1799:9): [True: 1, False: 0]
  |  |  |  |  ------------------
  |  |  |  | 1800|      1|  } static_assert(true, "require extra semicolon")
  |  |  ------------------
  ------------------
 1830|      0|                CheckFPRoundingModeForShaders(vstate, *inst, decoration));
 1831|      0|          break;
 1832|     22|        case spv::Decoration::NonWritable:
  ------------------
  |  Branch (1832:9): [True: 22, False: 3.35k]
  ------------------
 1833|     22|          PASS_OR_BAIL(CheckNonWritableDecoration(vstate, *inst, decoration));
  ------------------
  |  | 1801|     22|#define PASS_OR_BAIL(X) PASS_OR_BAIL_AT_LINE(X, __LINE__)
  |  |  ------------------
  |  |  |  | 1797|     22|  {                                             \
  |  |  |  | 1798|     22|    spv_result_t e##LINE = (X);                 \
  |  |  |  | 1799|     22|    if (e##LINE != SPV_SUCCESS) return e##LINE; \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (1799:9): [True: 21, False: 1]
  |  |  |  |  ------------------
  |  |  |  | 1800|     22|  } static_assert(true, "require extra semicolon")
  |  |  ------------------
  ------------------
 1834|      1|          break;
 1835|     15|        case spv::Decoration::Uniform:
  ------------------
  |  Branch (1835:9): [True: 15, False: 3.35k]
  ------------------
 1836|     15|        case spv::Decoration::UniformId:
  ------------------
  |  Branch (1836:9): [True: 0, False: 3.37k]
  ------------------
 1837|     15|          PASS_OR_BAIL(CheckUniformDecoration(vstate, *inst, decoration));
  ------------------
  |  | 1801|     15|#define PASS_OR_BAIL(X) PASS_OR_BAIL_AT_LINE(X, __LINE__)
  |  |  ------------------
  |  |  |  | 1797|     15|  {                                             \
  |  |  |  | 1798|     15|    spv_result_t e##LINE = (X);                 \
  |  |  |  | 1799|     15|    if (e##LINE != SPV_SUCCESS) return e##LINE; \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (1799:9): [True: 7, False: 8]
  |  |  |  |  ------------------
  |  |  |  | 1800|     15|  } static_assert(true, "require extra semicolon")
  |  |  ------------------
  ------------------
 1838|      8|          break;
 1839|      0|        case spv::Decoration::NoSignedWrap:
  ------------------
  |  Branch (1839:9): [True: 0, False: 3.37k]
  ------------------
 1840|      0|        case spv::Decoration::NoUnsignedWrap:
  ------------------
  |  Branch (1840:9): [True: 0, False: 3.37k]
  ------------------
 1841|      0|          PASS_OR_BAIL(CheckIntegerWrapDecoration(vstate, *inst, decoration));
  ------------------
  |  | 1801|      0|#define PASS_OR_BAIL(X) PASS_OR_BAIL_AT_LINE(X, __LINE__)
  |  |  ------------------
  |  |  |  | 1797|      0|  {                                             \
  |  |  |  | 1798|      0|    spv_result_t e##LINE = (X);                 \
  |  |  |  | 1799|      0|    if (e##LINE != SPV_SUCCESS) return e##LINE; \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (1799:9): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  | 1800|      0|  } static_assert(true, "require extra semicolon")
  |  |  ------------------
  ------------------
 1842|      0|          break;
 1843|     97|        case spv::Decoration::Block:
  ------------------
  |  Branch (1843:9): [True: 97, False: 3.27k]
  ------------------
 1844|    106|        case spv::Decoration::BufferBlock:
  ------------------
  |  Branch (1844:9): [True: 9, False: 3.36k]
  ------------------
 1845|    106|          PASS_OR_BAIL(CheckBlockDecoration(vstate, *inst, decoration));
  ------------------
  |  | 1801|    106|#define PASS_OR_BAIL(X) PASS_OR_BAIL_AT_LINE(X, __LINE__)
  |  |  ------------------
  |  |  |  | 1797|    106|  {                                             \
  |  |  |  | 1798|    106|    spv_result_t e##LINE = (X);                 \
  |  |  |  | 1799|    106|    if (e##LINE != SPV_SUCCESS) return e##LINE; \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (1799:9): [True: 12, False: 94]
  |  |  |  |  ------------------
  |  |  |  | 1800|    106|  } static_assert(true, "require extra semicolon")
  |  |  ------------------
  ------------------
 1846|     94|          break;
 1847|    133|        case spv::Decoration::Location:
  ------------------
  |  Branch (1847:9): [True: 133, False: 3.24k]
  ------------------
 1848|    133|          PASS_OR_BAIL(CheckLocationDecoration(vstate, *inst, decoration));
  ------------------
  |  | 1801|    133|#define PASS_OR_BAIL(X) PASS_OR_BAIL_AT_LINE(X, __LINE__)
  |  |  ------------------
  |  |  |  | 1797|    133|  {                                             \
  |  |  |  | 1798|    133|    spv_result_t e##LINE = (X);                 \
  |  |  |  | 1799|    133|    if (e##LINE != SPV_SUCCESS) return e##LINE; \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (1799:9): [True: 8, False: 125]
  |  |  |  |  ------------------
  |  |  |  | 1800|    133|  } static_assert(true, "require extra semicolon")
  |  |  ------------------
  ------------------
 1849|    125|          break;
 1850|  2.15k|        case spv::Decoration::RelaxedPrecision:
  ------------------
  |  Branch (1850:9): [True: 2.15k, False: 1.22k]
  ------------------
 1851|  2.15k|          PASS_OR_BAIL(
  ------------------
  |  | 1801|  2.15k|#define PASS_OR_BAIL(X) PASS_OR_BAIL_AT_LINE(X, __LINE__)
  |  |  ------------------
  |  |  |  | 1797|  2.15k|  {                                             \
  |  |  |  | 1798|  2.15k|    spv_result_t e##LINE = (X);                 \
  |  |  |  | 1799|  2.15k|    if (e##LINE != SPV_SUCCESS) return e##LINE; \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (1799:9): [True: 11, False: 2.14k]
  |  |  |  |  ------------------
  |  |  |  | 1800|  2.15k|  } static_assert(true, "require extra semicolon")
  |  |  ------------------
  ------------------
 1852|  2.14k|              CheckRelaxPrecisionDecoration(vstate, *inst, decoration));
 1853|  2.14k|          break;
 1854|    812|        default:
  ------------------
  |  Branch (1854:9): [True: 812, False: 2.56k]
  ------------------
 1855|    812|          break;
 1856|  3.37k|      }
 1857|  3.37k|    }
 1858|  2.61k|  }
 1859|    664|  return SPV_SUCCESS;
 1860|    730|}
validate_decorations.cpp:_ZN8spvtools3val12_GLOBAL__N_124CheckComponentDecorationERNS0_17ValidationState_tERKNS0_11InstructionERKNS0_10DecorationE:
 1642|    133|                                      const Decoration& decoration) {
 1643|    133|  assert(inst.id() && "Parser ensures the target of the decoration has an ID");
 1644|      0|  assert(decoration.params().size() == 1 &&
 1645|    133|         "Grammar ensures Component has one parameter");
 1646|       |
 1647|      0|  uint32_t type_id;
 1648|    133|  if (decoration.struct_member_index() == Decoration::kInvalidMember) {
  ------------------
  |  Branch (1648:7): [True: 125, False: 8]
  ------------------
 1649|       |    // The target must be a memory object declaration.
 1650|    125|    const auto opcode = inst.opcode();
 1651|    125|    if (opcode != spv::Op::OpVariable &&
  ------------------
  |  Branch (1651:9): [True: 7, False: 118]
  ------------------
 1652|    125|        opcode != spv::Op::OpFunctionParameter) {
  ------------------
  |  Branch (1652:9): [True: 5, False: 2]
  ------------------
 1653|      5|      return vstate.diag(SPV_ERROR_INVALID_ID, &inst)
 1654|      5|             << "Target of Component decoration must be a memory object "
 1655|      5|                "declaration (a variable or a function parameter)";
 1656|      5|    }
 1657|       |
 1658|       |    // Only valid for the Input and Output Storage Classes.
 1659|    120|    const auto storage_class = opcode == spv::Op::OpVariable
  ------------------
  |  Branch (1659:32): [True: 118, False: 2]
  ------------------
 1660|    120|                                   ? inst.GetOperandAs<spv::StorageClass>(2)
 1661|    120|                                   : spv::StorageClass::Max;
 1662|    120|    if (storage_class != spv::StorageClass::Input &&
  ------------------
  |  Branch (1662:9): [True: 65, False: 55]
  ------------------
 1663|    120|        storage_class != spv::StorageClass::Output &&
  ------------------
  |  Branch (1663:9): [True: 3, False: 62]
  ------------------
 1664|    120|        storage_class != spv::StorageClass::Max) {
  ------------------
  |  Branch (1664:9): [True: 1, False: 2]
  ------------------
 1665|      1|      return vstate.diag(SPV_ERROR_INVALID_ID, &inst)
 1666|      1|             << "Target of Component decoration is invalid: must point to a "
 1667|      1|                "Storage Class of Input(1) or Output(3). Found Storage "
 1668|      1|                "Class "
 1669|      1|             << uint32_t(storage_class);
 1670|      1|    }
 1671|       |
 1672|    119|    type_id = inst.type_id();
 1673|    119|    if (vstate.IsPointerType(type_id)) {
  ------------------
  |  Branch (1673:9): [True: 119, False: 0]
  ------------------
 1674|    119|      const auto pointer = vstate.FindDef(type_id);
 1675|    119|      type_id = pointer->GetOperandAs<uint32_t>(2);
 1676|    119|    }
 1677|    119|  } else {
 1678|      8|    if (inst.opcode() != spv::Op::OpTypeStruct) {
  ------------------
  |  Branch (1678:9): [True: 0, False: 8]
  ------------------
 1679|      0|      return vstate.diag(SPV_ERROR_INVALID_DATA, &inst)
 1680|      0|             << "Attempted to get underlying data type via member index for "
 1681|      0|                "non-struct type.";
 1682|      0|    }
 1683|      8|    type_id = inst.word(decoration.struct_member_index() + 2);
 1684|      8|  }
 1685|       |
 1686|    127|  if (spvIsVulkanEnv(vstate.context()->target_env)) {
  ------------------
  |  Branch (1686:7): [True: 0, False: 127]
  ------------------
 1687|       |    // Strip the array, if present.
 1688|      0|    if (vstate.GetIdOpcode(type_id) == spv::Op::OpTypeArray) {
  ------------------
  |  Branch (1688:9): [True: 0, False: 0]
  ------------------
 1689|      0|      type_id = vstate.FindDef(type_id)->word(2u);
 1690|      0|    }
 1691|       |
 1692|      0|    if (!vstate.IsIntScalarOrVectorType(type_id) &&
  ------------------
  |  Branch (1692:9): [True: 0, False: 0]
  ------------------
 1693|      0|        !vstate.IsFloatScalarOrVectorType(type_id)) {
  ------------------
  |  Branch (1693:9): [True: 0, False: 0]
  ------------------
 1694|      0|      return vstate.diag(SPV_ERROR_INVALID_ID, &inst)
 1695|      0|             << vstate.VkErrorID(4924)
 1696|      0|             << "Component decoration specified for type "
 1697|      0|             << vstate.getIdName(type_id) << " that is not a scalar or vector";
 1698|      0|    }
 1699|       |
 1700|      0|    const auto component = decoration.params()[0];
 1701|      0|    if (component > 3) {
  ------------------
  |  Branch (1701:9): [True: 0, False: 0]
  ------------------
 1702|      0|      return vstate.diag(SPV_ERROR_INVALID_ID, &inst)
 1703|      0|             << vstate.VkErrorID(4920)
 1704|      0|             << "Component decoration value must not be greater than 3";
 1705|      0|    }
 1706|       |
 1707|      0|    const auto dimension = vstate.GetDimension(type_id);
 1708|      0|    const auto bit_width = vstate.GetBitWidth(type_id);
 1709|      0|    if (bit_width == 16 || bit_width == 32) {
  ------------------
  |  Branch (1709:9): [True: 0, False: 0]
  |  Branch (1709:28): [True: 0, False: 0]
  ------------------
 1710|      0|      const auto sum_component = component + dimension;
 1711|      0|      if (sum_component > 4) {
  ------------------
  |  Branch (1711:11): [True: 0, False: 0]
  ------------------
 1712|      0|        return vstate.diag(SPV_ERROR_INVALID_ID, &inst)
 1713|      0|               << vstate.VkErrorID(4921)
 1714|      0|               << "Sequence of components starting with " << component
 1715|      0|               << " and ending with " << (sum_component - 1)
 1716|      0|               << " gets larger than 3";
 1717|      0|      }
 1718|      0|    } else if (bit_width == 64) {
  ------------------
  |  Branch (1718:16): [True: 0, False: 0]
  ------------------
 1719|      0|      if (dimension > 2) {
  ------------------
  |  Branch (1719:11): [True: 0, False: 0]
  ------------------
 1720|      0|        return vstate.diag(SPV_ERROR_INVALID_ID, &inst)
 1721|      0|               << vstate.VkErrorID(7703)
 1722|      0|               << "Component decoration only allowed on 64-bit scalar and "
 1723|      0|                  "2-component vector";
 1724|      0|      }
 1725|      0|      if (component == 1 || component == 3) {
  ------------------
  |  Branch (1725:11): [True: 0, False: 0]
  |  Branch (1725:29): [True: 0, False: 0]
  ------------------
 1726|      0|        return vstate.diag(SPV_ERROR_INVALID_ID, &inst)
 1727|      0|               << vstate.VkErrorID(4923)
 1728|      0|               << "Component decoration value must not be 1 or 3 for 64-bit "
 1729|      0|                  "data types";
 1730|      0|      }
 1731|       |      // 64-bit is double per component dimension
 1732|      0|      const auto sum_component = component + (2 * dimension);
 1733|      0|      if (sum_component > 4) {
  ------------------
  |  Branch (1733:11): [True: 0, False: 0]
  ------------------
 1734|      0|        return vstate.diag(SPV_ERROR_INVALID_ID, &inst)
 1735|      0|               << vstate.VkErrorID(4922)
 1736|      0|               << "Sequence of components starting with " << component
 1737|      0|               << " and ending with " << (sum_component - 1)
 1738|      0|               << " gets larger than 3";
 1739|      0|      }
 1740|      0|    }
 1741|      0|  }
 1742|       |
 1743|    127|  return SPV_SUCCESS;
 1744|    127|}
validate_decorations.cpp:_ZN8spvtools3val12_GLOBAL__N_129CheckFPRoundingModeForShadersERNS0_17ValidationState_tERKNS0_11InstructionERKNS0_10DecorationE:
 1440|      1|                                           const Decoration& decoration) {
 1441|       |  // Validates width-only conversion instruction for floating-point object
 1442|       |  // i.e., OpFConvert
 1443|      1|  if (inst.opcode() != spv::Op::OpFConvert) {
  ------------------
  |  Branch (1443:7): [True: 1, False: 0]
  ------------------
 1444|      1|    return vstate.diag(SPV_ERROR_INVALID_ID, &inst)
 1445|      1|           << "FPRoundingMode decoration can be applied only to a "
 1446|      1|              "width-only conversion instruction for floating-point "
 1447|      1|              "object.";
 1448|      1|  }
 1449|       |
 1450|      0|  if (spvIsVulkanEnv(vstate.context()->target_env)) {
  ------------------
  |  Branch (1450:7): [True: 0, False: 0]
  ------------------
 1451|      0|    const auto mode = spv::FPRoundingMode(decoration.params()[0]);
 1452|      0|    if ((mode != spv::FPRoundingMode::RTE) &&
  ------------------
  |  Branch (1452:9): [True: 0, False: 0]
  ------------------
 1453|      0|        (mode != spv::FPRoundingMode::RTZ)) {
  ------------------
  |  Branch (1453:9): [True: 0, False: 0]
  ------------------
 1454|      0|      return vstate.diag(SPV_ERROR_INVALID_ID, &inst)
 1455|      0|             << vstate.VkErrorID(4675)
 1456|      0|             << "In Vulkan, the FPRoundingMode mode must only by RTE or RTZ.";
 1457|      0|    }
 1458|      0|  }
 1459|       |
 1460|       |  // Validates Object operand of an OpStore
 1461|      0|  for (const auto& use : inst.uses()) {
  ------------------
  |  Branch (1461:24): [True: 0, False: 0]
  ------------------
 1462|      0|    const auto store = use.first;
 1463|      0|    if (store->opcode() == spv::Op::OpFConvert) continue;
  ------------------
  |  Branch (1463:9): [True: 0, False: 0]
  ------------------
 1464|      0|    if (spvOpcodeIsDebug(store->opcode())) continue;
  ------------------
  |  Branch (1464:9): [True: 0, False: 0]
  ------------------
 1465|      0|    if (store->IsNonSemantic()) continue;
  ------------------
  |  Branch (1465:9): [True: 0, False: 0]
  ------------------
 1466|      0|    if (spvOpcodeIsDecoration(store->opcode())) continue;
  ------------------
  |  Branch (1466:9): [True: 0, False: 0]
  ------------------
 1467|      0|    if (store->opcode() != spv::Op::OpStore) {
  ------------------
  |  Branch (1467:9): [True: 0, False: 0]
  ------------------
 1468|      0|      return vstate.diag(SPV_ERROR_INVALID_ID, &inst)
 1469|      0|             << "FPRoundingMode decoration can be applied only to the "
 1470|      0|                "Object operand of an OpStore.";
 1471|      0|    }
 1472|       |
 1473|      0|    if (use.second != 2) {
  ------------------
  |  Branch (1473:9): [True: 0, False: 0]
  ------------------
 1474|      0|      return vstate.diag(SPV_ERROR_INVALID_ID, &inst)
 1475|      0|             << "FPRoundingMode decoration can be applied only to the "
 1476|      0|                "Object operand of an OpStore.";
 1477|      0|    }
 1478|       |
 1479|      0|    const auto ptr_inst = vstate.FindDef(store->GetOperandAs<uint32_t>(0));
 1480|      0|    const auto ptr_type = vstate.FindDef(ptr_inst->GetOperandAs<uint32_t>(0));
 1481|       |
 1482|      0|    const auto half_float_id = ptr_type->GetOperandAs<uint32_t>(2);
 1483|      0|    if (!vstate.IsFloatScalarOrVectorType(half_float_id) ||
  ------------------
  |  Branch (1483:9): [True: 0, False: 0]
  ------------------
 1484|      0|        vstate.GetBitWidth(half_float_id) != 16) {
  ------------------
  |  Branch (1484:9): [True: 0, False: 0]
  ------------------
 1485|      0|      return vstate.diag(SPV_ERROR_INVALID_ID, &inst)
 1486|      0|             << "FPRoundingMode decoration can be applied only to the "
 1487|      0|                "Object operand of an OpStore storing through a pointer "
 1488|      0|                "to "
 1489|      0|                "a 16-bit floating-point scalar or vector object.";
 1490|      0|    }
 1491|       |
 1492|       |    // Validates storage class of the pointer to the OpStore
 1493|      0|    const auto storage = ptr_type->GetOperandAs<spv::StorageClass>(1);
 1494|      0|    if (storage != spv::StorageClass::StorageBuffer &&
  ------------------
  |  Branch (1494:9): [True: 0, False: 0]
  ------------------
 1495|      0|        storage != spv::StorageClass::Uniform &&
  ------------------
  |  Branch (1495:9): [True: 0, False: 0]
  ------------------
 1496|      0|        storage != spv::StorageClass::PushConstant &&
  ------------------
  |  Branch (1496:9): [True: 0, False: 0]
  ------------------
 1497|      0|        storage != spv::StorageClass::Input &&
  ------------------
  |  Branch (1497:9): [True: 0, False: 0]
  ------------------
 1498|      0|        storage != spv::StorageClass::Output &&
  ------------------
  |  Branch (1498:9): [True: 0, False: 0]
  ------------------
 1499|      0|        storage != spv::StorageClass::PhysicalStorageBuffer) {
  ------------------
  |  Branch (1499:9): [True: 0, False: 0]
  ------------------
 1500|      0|      return vstate.diag(SPV_ERROR_INVALID_ID, &inst)
 1501|      0|             << "FPRoundingMode decoration can be applied only to the "
 1502|      0|                "Object operand of an OpStore in the StorageBuffer, "
 1503|      0|                "PhysicalStorageBuffer, Uniform, PushConstant, Input, or "
 1504|      0|                "Output Storage Classes.";
 1505|      0|    }
 1506|      0|  }
 1507|      0|  return SPV_SUCCESS;
 1508|      0|}
validate_decorations.cpp:_ZN8spvtools3val12_GLOBAL__N_126CheckNonWritableDecorationERNS0_17ValidationState_tERKNS0_11InstructionERKNS0_10DecorationE:
 1516|     22|                                        const Decoration& decoration) {
 1517|     22|  assert(inst.id() && "Parser ensures the target of the decoration has an ID");
 1518|       |
 1519|     22|  if (decoration.struct_member_index() == Decoration::kInvalidMember) {
  ------------------
  |  Branch (1519:7): [True: 21, False: 1]
  ------------------
 1520|       |    // The target must be a memory object declaration.
 1521|       |    // First, it must be a variable or function parameter.
 1522|     21|    const auto opcode = inst.opcode();
 1523|     21|    const auto type_id = inst.type_id();
 1524|     21|    if (opcode != spv::Op::OpVariable &&
  ------------------
  |  Branch (1524:9): [True: 12, False: 9]
  ------------------
 1525|     21|        opcode != spv::Op::OpFunctionParameter) {
  ------------------
  |  Branch (1525:9): [True: 11, False: 1]
  ------------------
 1526|     11|      return vstate.diag(SPV_ERROR_INVALID_ID, &inst)
 1527|     11|             << "Target of NonWritable decoration must be a memory object "
 1528|     11|                "declaration (a variable or a function parameter)";
 1529|     11|    }
 1530|     10|    const auto var_storage_class = opcode == spv::Op::OpVariable
  ------------------
  |  Branch (1530:36): [True: 9, False: 1]
  ------------------
 1531|     10|                                       ? inst.GetOperandAs<spv::StorageClass>(2)
 1532|     10|                                       : spv::StorageClass::Max;
 1533|     10|    if ((var_storage_class == spv::StorageClass::Function ||
  ------------------
  |  Branch (1533:10): [True: 0, False: 10]
  ------------------
 1534|     10|         var_storage_class == spv::StorageClass::Private) &&
  ------------------
  |  Branch (1534:10): [True: 1, False: 9]
  ------------------
 1535|     10|        vstate.features().nonwritable_var_in_function_or_private) {
  ------------------
  |  Branch (1535:9): [True: 0, False: 1]
  ------------------
 1536|       |      // New permitted feature in SPIR-V 1.4.
 1537|     10|    } else if (
 1538|       |        // It may point to a UBO, SSBO, or storage image.
 1539|     10|        vstate.IsPointerToUniformBlock(type_id) ||
  ------------------
  |  Branch (1539:9): [True: 0, False: 10]
  ------------------
 1540|     10|        vstate.IsPointerToStorageBuffer(type_id) ||
  ------------------
  |  Branch (1540:9): [True: 0, False: 10]
  ------------------
 1541|     10|        vstate.IsPointerToStorageImage(type_id)) {
  ------------------
  |  Branch (1541:9): [True: 0, False: 10]
  ------------------
 1542|     10|    } else {
 1543|     10|      return vstate.diag(SPV_ERROR_INVALID_ID, &inst)
 1544|     10|             << "Target of NonWritable decoration is invalid: must point to a "
 1545|     10|                "storage image, uniform block, "
 1546|     10|             << (vstate.features().nonwritable_var_in_function_or_private
  ------------------
  |  Branch (1546:18): [True: 0, False: 10]
  ------------------
 1547|     10|                     ? "storage buffer, or variable in Private or Function "
 1548|      0|                       "storage class"
 1549|     10|                     : "or storage buffer");
 1550|     10|    }
 1551|     10|  }
 1552|       |
 1553|      1|  return SPV_SUCCESS;
 1554|     22|}
validate_decorations.cpp:_ZN8spvtools3val12_GLOBAL__N_122CheckUniformDecorationERNS0_17ValidationState_tERKNS0_11InstructionERKNS0_10DecorationE:
 1563|     15|                                    const Decoration& decoration) {
 1564|     15|  const char* const dec_name = decoration.dec_type() == spv::Decoration::Uniform
  ------------------
  |  Branch (1564:32): [True: 15, False: 0]
  ------------------
 1565|     15|                                   ? "Uniform"
 1566|     15|                                   : "UniformId";
 1567|       |
 1568|       |  // Uniform or UniformId must decorate an "object"
 1569|       |  //  - has a result ID
 1570|       |  //  - is an instantiation of a non-void type.  So it has a type ID, and that
 1571|       |  //  type is not void.
 1572|       |
 1573|       |  // We already know the result ID is non-zero.
 1574|       |
 1575|     15|  if (inst.type_id() == 0) {
  ------------------
  |  Branch (1575:7): [True: 2, False: 13]
  ------------------
 1576|      2|    return vstate.diag(SPV_ERROR_INVALID_ID, &inst)
 1577|      2|           << dec_name << " decoration applied to a non-object";
 1578|      2|  }
 1579|     13|  if (Instruction* type_inst = vstate.FindDef(inst.type_id())) {
  ------------------
  |  Branch (1579:20): [True: 13, False: 0]
  ------------------
 1580|     13|    if (type_inst->opcode() == spv::Op::OpTypeVoid) {
  ------------------
  |  Branch (1580:9): [True: 5, False: 8]
  ------------------
 1581|      5|      return vstate.diag(SPV_ERROR_INVALID_ID, &inst)
 1582|      5|             << dec_name << " decoration applied to a value with void type";
 1583|      5|    }
 1584|     13|  } else {
 1585|       |    // We might never get here because this would have been rejected earlier in
 1586|       |    // the flow.
 1587|      0|    return vstate.diag(SPV_ERROR_INVALID_ID, &inst)
 1588|      0|           << dec_name << " decoration applied to an object with invalid type";
 1589|      0|  }
 1590|       |
 1591|       |  // Use of Uniform with OpDecorate is checked elsewhere.
 1592|       |  // Use of UniformId with OpDecorateId is checked elsewhere.
 1593|       |
 1594|      8|  if (decoration.dec_type() == spv::Decoration::UniformId) {
  ------------------
  |  Branch (1594:7): [True: 0, False: 8]
  ------------------
 1595|      0|    assert(decoration.params().size() == 1 &&
 1596|      0|           "Grammar ensures UniformId has one parameter");
 1597|       |
 1598|       |    // The scope id is an execution scope.
 1599|      0|    if (auto error =
  ------------------
  |  Branch (1599:14): [True: 0, False: 0]
  ------------------
 1600|      0|            ValidateExecutionScope(vstate, &inst, decoration.params()[0]))
 1601|      0|      return error;
 1602|      0|  }
 1603|       |
 1604|      8|  return SPV_SUCCESS;
 1605|      8|}
validate_decorations.cpp:_ZN8spvtools3val12_GLOBAL__N_120CheckBlockDecorationERNS0_17ValidationState_tERKNS0_11InstructionERKNS0_10DecorationE:
 1751|    106|                                  const Decoration& decoration) {
 1752|    106|  assert(inst.id() && "Parser ensures the target of the decoration has an ID");
 1753|    106|  if (inst.opcode() != spv::Op::OpTypeStruct) {
  ------------------
  |  Branch (1753:7): [True: 12, False: 94]
  ------------------
 1754|     12|    const char* const dec_name = decoration.dec_type() == spv::Decoration::Block
  ------------------
  |  Branch (1754:34): [True: 9, False: 3]
  ------------------
 1755|     12|                                     ? "Block"
 1756|     12|                                     : "BufferBlock";
 1757|     12|    return vstate.diag(SPV_ERROR_INVALID_ID, &inst)
 1758|     12|           << dec_name << " decoration on a non-struct type.";
 1759|     12|  }
 1760|     94|  return SPV_SUCCESS;
 1761|    106|}
validate_decorations.cpp:_ZN8spvtools3val12_GLOBAL__N_123CheckLocationDecorationERNS0_17ValidationState_tERKNS0_11InstructionERKNS0_10DecorationE:
 1765|    133|                                     const Decoration& decoration) {
 1766|    133|  if (inst.opcode() == spv::Op::OpVariable) return SPV_SUCCESS;
  ------------------
  |  Branch (1766:7): [True: 121, False: 12]
  ------------------
 1767|       |
 1768|     12|  if (decoration.struct_member_index() != Decoration::kInvalidMember &&
  ------------------
  |  Branch (1768:7): [True: 4, False: 8]
  ------------------
 1769|     12|      inst.opcode() == spv::Op::OpTypeStruct) {
  ------------------
  |  Branch (1769:7): [True: 4, False: 0]
  ------------------
 1770|      4|    return SPV_SUCCESS;
 1771|      4|  }
 1772|       |
 1773|      8|  return vstate.diag(SPV_ERROR_INVALID_ID, &inst)
 1774|      8|         << "Location decoration can only be applied to a variable or member "
 1775|      8|            "of a structure type";
 1776|     12|}
validate_decorations.cpp:_ZN8spvtools3val12_GLOBAL__N_129CheckRelaxPrecisionDecorationERNS0_17ValidationState_tERKNS0_11InstructionERKNS0_10DecorationE:
 1780|  2.15k|                                           const Decoration& decoration) {
 1781|       |  // This is not the most precise check, but the rules for RelaxPrecision are
 1782|       |  // very general, and it will be difficult to implement precisely.  For now,
 1783|       |  // I will only check for the cases that cause problems for the optimizer.
 1784|  2.15k|  if (!spvOpcodeGeneratesType(inst.opcode())) {
  ------------------
  |  Branch (1784:7): [True: 2.12k, False: 23]
  ------------------
 1785|  2.12k|    return SPV_SUCCESS;
 1786|  2.12k|  }
 1787|       |
 1788|     23|  if (decoration.struct_member_index() != Decoration::kInvalidMember &&
  ------------------
  |  Branch (1788:7): [True: 12, False: 11]
  ------------------
 1789|     23|      inst.opcode() == spv::Op::OpTypeStruct) {
  ------------------
  |  Branch (1789:7): [True: 12, False: 0]
  ------------------
 1790|     12|    return SPV_SUCCESS;
 1791|     12|  }
 1792|     11|  return vstate.diag(SPV_ERROR_INVALID_ID, &inst)
 1793|     11|         << "RelaxPrecision decoration cannot be applied to a type";
 1794|     23|}

_ZN8spvtools3val15DerivativesPassERNS0_17ValidationState_tEPKNS0_11InstructionE:
   30|   285k|spv_result_t DerivativesPass(ValidationState_t& _, const Instruction* inst) {
   31|   285k|  const spv::Op opcode = inst->opcode();
   32|   285k|  const uint32_t result_type = inst->type_id();
   33|       |
   34|   285k|  switch (opcode) {
   35|     28|    case spv::Op::OpDPdx:
  ------------------
  |  Branch (35:5): [True: 28, False: 285k]
  ------------------
   36|     81|    case spv::Op::OpDPdy:
  ------------------
  |  Branch (36:5): [True: 53, False: 285k]
  ------------------
   37|     98|    case spv::Op::OpFwidth:
  ------------------
  |  Branch (37:5): [True: 17, False: 285k]
  ------------------
   38|     98|    case spv::Op::OpDPdxFine:
  ------------------
  |  Branch (38:5): [True: 0, False: 285k]
  ------------------
   39|    128|    case spv::Op::OpDPdyFine:
  ------------------
  |  Branch (39:5): [True: 30, False: 285k]
  ------------------
   40|    128|    case spv::Op::OpFwidthFine:
  ------------------
  |  Branch (40:5): [True: 0, False: 285k]
  ------------------
   41|    128|    case spv::Op::OpDPdxCoarse:
  ------------------
  |  Branch (41:5): [True: 0, False: 285k]
  ------------------
   42|    128|    case spv::Op::OpDPdyCoarse:
  ------------------
  |  Branch (42:5): [True: 0, False: 285k]
  ------------------
   43|    141|    case spv::Op::OpFwidthCoarse: {
  ------------------
  |  Branch (43:5): [True: 13, False: 285k]
  ------------------
   44|    141|      if (!_.IsFloatScalarOrVectorType(result_type)) {
  ------------------
  |  Branch (44:11): [True: 1, False: 140]
  ------------------
   45|      1|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
   46|      1|               << "Expected Result Type to be float scalar or vector type: "
   47|      1|               << spvOpcodeString(opcode);
   48|      1|      }
   49|    140|      if (!_.ContainsSizedIntOrFloatType(result_type, spv::Op::OpTypeFloat,
  ------------------
  |  Branch (49:11): [True: 0, False: 140]
  ------------------
   50|    140|                                         32)) {
   51|      0|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
   52|      0|               << "Result type component width must be 32 bits";
   53|      0|      }
   54|       |
   55|    140|      const uint32_t p_type = _.GetOperandTypeId(inst, 2);
   56|    140|      if (p_type != result_type) {
  ------------------
  |  Branch (56:11): [True: 1, False: 139]
  ------------------
   57|      1|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
   58|      1|               << "Expected P type and Result Type to be the same: "
   59|      1|               << spvOpcodeString(opcode);
   60|      1|      }
   61|    139|      _.function(inst->function()->id())
   62|    139|          ->RegisterExecutionModelLimitation([opcode](spv::ExecutionModel model,
   63|    139|                                                      std::string* message) {
   64|    139|            if (model != spv::ExecutionModel::Fragment &&
   65|    139|                model != spv::ExecutionModel::GLCompute) {
   66|    139|              if (message) {
   67|    139|                *message =
   68|    139|                    std::string(
   69|    139|                        "Derivative instructions require Fragment or GLCompute "
   70|    139|                        "execution model: ") +
   71|    139|                    spvOpcodeString(opcode);
   72|    139|              }
   73|    139|              return false;
   74|    139|            }
   75|    139|            return true;
   76|    139|          });
   77|    139|      _.function(inst->function()->id())
   78|    139|          ->RegisterLimitation([opcode](const ValidationState_t& state,
   79|    139|                                        const Function* entry_point,
   80|    139|                                        std::string* message) {
   81|    139|            const auto* models = state.GetExecutionModels(entry_point->id());
   82|    139|            const auto* modes = state.GetExecutionModes(entry_point->id());
   83|    139|            if (models &&
   84|    139|                models->find(spv::ExecutionModel::GLCompute) != models->end() &&
   85|    139|                (!modes ||
   86|    139|                 (modes->find(spv::ExecutionMode::DerivativeGroupLinearNV) ==
   87|    139|                      modes->end() &&
   88|    139|                  modes->find(spv::ExecutionMode::DerivativeGroupQuadsNV) ==
   89|    139|                      modes->end()))) {
   90|    139|              if (message) {
   91|    139|                *message = std::string(
   92|    139|                               "Derivative instructions require "
   93|    139|                               "DerivativeGroupQuadsNV "
   94|    139|                               "or DerivativeGroupLinearNV execution mode for "
   95|    139|                               "GLCompute execution model: ") +
   96|    139|                           spvOpcodeString(opcode);
   97|    139|              }
   98|    139|              return false;
   99|    139|            }
  100|    139|            return true;
  101|    139|          });
  102|    139|      break;
  103|    140|    }
  104|       |
  105|   285k|    default:
  ------------------
  |  Branch (105:5): [True: 285k, False: 141]
  ------------------
  106|   285k|      break;
  107|   285k|  }
  108|       |
  109|   285k|  return SPV_SUCCESS;
  110|   285k|}
validate_derivatives.cpp:_ZZN8spvtools3val15DerivativesPassERNS0_17ValidationState_tEPKNS0_11InstructionEENK3$_0clEN3spv14ExecutionModelEPNSt3__112basic_stringIcNS9_11char_traitsIcEENS9_9allocatorIcEEEE:
   63|     37|                                                      std::string* message) {
   64|     37|            if (model != spv::ExecutionModel::Fragment &&
  ------------------
  |  Branch (64:17): [True: 6, False: 31]
  ------------------
   65|     37|                model != spv::ExecutionModel::GLCompute) {
  ------------------
  |  Branch (65:17): [True: 3, False: 3]
  ------------------
   66|      3|              if (message) {
  ------------------
  |  Branch (66:19): [True: 3, False: 0]
  ------------------
   67|      3|                *message =
   68|      3|                    std::string(
   69|      3|                        "Derivative instructions require Fragment or GLCompute "
   70|      3|                        "execution model: ") +
   71|      3|                    spvOpcodeString(opcode);
   72|      3|              }
   73|      3|              return false;
   74|      3|            }
   75|     34|            return true;
   76|     37|          });
validate_derivatives.cpp:_ZZN8spvtools3val15DerivativesPassERNS0_17ValidationState_tEPKNS0_11InstructionEENK3$_1clERKS1_PKNS0_8FunctionEPNSt3__112basic_stringIcNSC_11char_traitsIcEENSC_9allocatorIcEEEE:
   80|     34|                                        std::string* message) {
   81|     34|            const auto* models = state.GetExecutionModels(entry_point->id());
   82|     34|            const auto* modes = state.GetExecutionModes(entry_point->id());
   83|     34|            if (models &&
  ------------------
  |  Branch (83:17): [True: 34, False: 0]
  |  Branch (83:17): [True: 3, False: 31]
  ------------------
   84|     34|                models->find(spv::ExecutionModel::GLCompute) != models->end() &&
  ------------------
  |  Branch (84:17): [True: 3, False: 31]
  ------------------
   85|     34|                (!modes ||
  ------------------
  |  Branch (85:18): [True: 2, False: 1]
  ------------------
   86|      3|                 (modes->find(spv::ExecutionMode::DerivativeGroupLinearNV) ==
  ------------------
  |  Branch (86:19): [True: 1, False: 0]
  ------------------
   87|      1|                      modes->end() &&
   88|      1|                  modes->find(spv::ExecutionMode::DerivativeGroupQuadsNV) ==
  ------------------
  |  Branch (88:19): [True: 1, False: 0]
  ------------------
   89|      3|                      modes->end()))) {
   90|      3|              if (message) {
  ------------------
  |  Branch (90:19): [True: 3, False: 0]
  ------------------
   91|      3|                *message = std::string(
   92|      3|                               "Derivative instructions require "
   93|      3|                               "DerivativeGroupQuadsNV "
   94|      3|                               "or DerivativeGroupLinearNV execution mode for "
   95|      3|                               "GLCompute execution model: ") +
   96|      3|                           spvOpcodeString(opcode);
   97|      3|              }
   98|      3|              return false;
   99|      3|            }
  100|     31|            return true;
  101|     34|          });

_ZN8spvtools3val28ValidateExecutionLimitationsERNS0_17ValidationState_tEPKNS0_11InstructionE:
   24|  69.9k|                                          const Instruction* inst) {
   25|  69.9k|  if (inst->opcode() != spv::Op::OpFunction) {
  ------------------
  |  Branch (25:7): [True: 69.2k, False: 686]
  ------------------
   26|  69.2k|    return SPV_SUCCESS;
   27|  69.2k|  }
   28|       |
   29|    686|  const auto func = _.function(inst->id());
   30|    686|  if (!func) {
  ------------------
  |  Branch (30:7): [True: 0, False: 686]
  ------------------
   31|      0|    return _.diag(SPV_ERROR_INTERNAL, inst)
   32|      0|           << "Internal error: missing function id " << inst->id() << ".";
   33|      0|  }
   34|       |
   35|    686|  for (uint32_t entry_id : _.FunctionEntryPoints(inst->id())) {
  ------------------
  |  Branch (35:26): [True: 481, False: 589]
  ------------------
   36|    481|    const auto* models = _.GetExecutionModels(entry_id);
   37|    481|    if (models) {
  ------------------
  |  Branch (37:9): [True: 481, False: 0]
  ------------------
   38|    481|      if (models->empty()) {
  ------------------
  |  Branch (38:11): [True: 0, False: 481]
  ------------------
   39|      0|        return _.diag(SPV_ERROR_INTERNAL, inst)
   40|      0|               << "Internal error: empty execution models for function id "
   41|      0|               << entry_id << ".";
   42|      0|      }
   43|    582|      for (const auto model : *models) {
  ------------------
  |  Branch (43:29): [True: 582, False: 388]
  ------------------
   44|    582|        std::string reason;
   45|    582|        if (!func->IsCompatibleWithExecutionModel(model, &reason)) {
  ------------------
  |  Branch (45:13): [True: 93, False: 489]
  ------------------
   46|     93|          return _.diag(SPV_ERROR_INVALID_ID, inst)
   47|     93|                 << "OpEntryPoint Entry Point <id> " << _.getIdName(entry_id)
   48|     93|                 << "s callgraph contains function <id> "
   49|     93|                 << _.getIdName(inst->id())
   50|     93|                 << ", which cannot be used with the current execution "
   51|     93|                    "model:\n"
   52|     93|                 << reason;
   53|     93|        }
   54|    582|      }
   55|    481|    }
   56|       |
   57|    388|    std::string reason;
   58|    388|    if (!func->CheckLimitations(_, _.function(entry_id), &reason)) {
  ------------------
  |  Branch (58:9): [True: 4, False: 384]
  ------------------
   59|      4|      return _.diag(SPV_ERROR_INVALID_ID, inst)
   60|      4|             << "OpEntryPoint Entry Point <id> " << _.getIdName(entry_id)
   61|      4|             << "s callgraph contains function <id> " << _.getIdName(inst->id())
   62|      4|             << ", which cannot be used with the current execution "
   63|      4|                "modes:\n"
   64|      4|             << reason;
   65|      4|    }
   66|    388|  }
   67|    589|  return SPV_SUCCESS;
   68|    686|}

_ZN8spvtools3val17ValidateExtensionERNS0_17ValidationState_tEPKNS0_11InstructionE:
 1058|    518|spv_result_t ValidateExtension(ValidationState_t& _, const Instruction* inst) {
 1059|    518|  if (_.version() < SPV_SPIRV_VERSION_WORD(1, 4)) {
  ------------------
  |  |   26|    518|  ((uint32_t(uint8_t(MAJOR)) << 16) | (uint32_t(uint8_t(MINOR)) << 8))
  ------------------
  |  Branch (1059:7): [True: 518, False: 0]
  ------------------
 1060|    518|    std::string extension = GetExtensionString(&(inst->c_inst()));
 1061|    518|    if (extension ==
  ------------------
  |  Branch (1061:9): [True: 0, False: 518]
  ------------------
 1062|    518|            ExtensionToString(kSPV_KHR_workgroup_memory_explicit_layout) ||
 1063|    518|        extension == ExtensionToString(kSPV_EXT_mesh_shader) ||
  ------------------
  |  Branch (1063:9): [True: 1, False: 517]
  ------------------
 1064|    518|        extension == ExtensionToString(kSPV_NV_shader_invocation_reorder)) {
  ------------------
  |  Branch (1064:9): [True: 0, False: 517]
  ------------------
 1065|      1|      return _.diag(SPV_ERROR_WRONG_VERSION, inst)
 1066|      1|             << extension << " extension requires SPIR-V version 1.4 or later.";
 1067|      1|    }
 1068|    518|  }
 1069|       |
 1070|    517|  return SPV_SUCCESS;
 1071|    518|}
_ZN8spvtools3val21ValidateExtInstImportERNS0_17ValidationState_tEPKNS0_11InstructionE:
 1074|    775|                                   const Instruction* inst) {
 1075|    775|  const auto name_id = 1;
 1076|    775|  if (_.version() <= SPV_SPIRV_VERSION_WORD(1, 5) &&
  ------------------
  |  |   26|  1.55k|  ((uint32_t(uint8_t(MAJOR)) << 16) | (uint32_t(uint8_t(MINOR)) << 8))
  ------------------
  |  Branch (1076:7): [True: 775, False: 0]
  ------------------
 1077|    775|      !_.HasExtension(kSPV_KHR_non_semantic_info)) {
  ------------------
  |  Branch (1077:7): [True: 774, False: 1]
  ------------------
 1078|    774|    const std::string name = inst->GetOperandAs<std::string>(name_id);
 1079|    774|    if (name.find("NonSemantic.") == 0) {
  ------------------
  |  Branch (1079:9): [True: 6, False: 768]
  ------------------
 1080|      6|      return _.diag(SPV_ERROR_INVALID_DATA, inst)
 1081|      6|             << "NonSemantic extended instruction sets cannot be declared "
 1082|      6|                "without SPV_KHR_non_semantic_info.";
 1083|      6|    }
 1084|    774|  }
 1085|       |
 1086|    769|  return SPV_SUCCESS;
 1087|    775|}
_ZN8spvtools3val15ValidateExtInstERNS0_17ValidationState_tEPKNS0_11InstructionE:
 1089|  2.42k|spv_result_t ValidateExtInst(ValidationState_t& _, const Instruction* inst) {
 1090|  2.42k|  const uint32_t result_type = inst->type_id();
 1091|  2.42k|  const uint32_t num_operands = static_cast<uint32_t>(inst->operands().size());
 1092|       |
 1093|  2.42k|  const uint32_t ext_inst_set = inst->word(3);
 1094|  2.42k|  const uint32_t ext_inst_index = inst->word(4);
 1095|  2.42k|  const spv_ext_inst_type_t ext_inst_type =
 1096|  2.42k|      spv_ext_inst_type_t(inst->ext_inst_type());
 1097|       |
 1098|  2.42k|  auto ext_inst_name = [&_, ext_inst_set, ext_inst_type, ext_inst_index]() {
 1099|  2.42k|    spv_ext_inst_desc desc = nullptr;
 1100|  2.42k|    if (_.grammar().lookupExtInst(ext_inst_type, ext_inst_index, &desc) !=
 1101|  2.42k|            SPV_SUCCESS ||
 1102|  2.42k|        !desc) {
 1103|  2.42k|      return std::string("Unknown ExtInst");
 1104|  2.42k|    }
 1105|       |
 1106|  2.42k|    auto* import_inst = _.FindDef(ext_inst_set);
 1107|  2.42k|    assert(import_inst);
 1108|       |
 1109|  2.42k|    std::ostringstream ss;
 1110|  2.42k|    ss << import_inst->GetOperandAs<std::string>(1);
 1111|  2.42k|    ss << " ";
 1112|  2.42k|    ss << desc->name;
 1113|       |
 1114|  2.42k|    return ss.str();
 1115|  2.42k|  };
 1116|       |
 1117|  2.42k|  if (ext_inst_type == SPV_EXT_INST_TYPE_GLSL_STD_450) {
  ------------------
  |  Branch (1117:7): [True: 2.42k, False: 0]
  ------------------
 1118|  2.42k|    const GLSLstd450 ext_inst_key = GLSLstd450(ext_inst_index);
 1119|  2.42k|    switch (ext_inst_key) {
  ------------------
  |  Branch (1119:13): [True: 0, False: 2.42k]
  ------------------
 1120|     13|      case GLSLstd450Round:
  ------------------
  |  Branch (1120:7): [True: 13, False: 2.41k]
  ------------------
 1121|     40|      case GLSLstd450RoundEven:
  ------------------
  |  Branch (1121:7): [True: 27, False: 2.39k]
  ------------------
 1122|    259|      case GLSLstd450FAbs:
  ------------------
  |  Branch (1122:7): [True: 219, False: 2.20k]
  ------------------
 1123|    394|      case GLSLstd450Trunc:
  ------------------
  |  Branch (1123:7): [True: 135, False: 2.29k]
  ------------------
 1124|    406|      case GLSLstd450FSign:
  ------------------
  |  Branch (1124:7): [True: 12, False: 2.41k]
  ------------------
 1125|    452|      case GLSLstd450Floor:
  ------------------
  |  Branch (1125:7): [True: 46, False: 2.38k]
  ------------------
 1126|    455|      case GLSLstd450Ceil:
  ------------------
  |  Branch (1126:7): [True: 3, False: 2.42k]
  ------------------
 1127|    735|      case GLSLstd450Fract:
  ------------------
  |  Branch (1127:7): [True: 280, False: 2.14k]
  ------------------
 1128|    759|      case GLSLstd450Sqrt:
  ------------------
  |  Branch (1128:7): [True: 24, False: 2.40k]
  ------------------
 1129|    774|      case GLSLstd450InverseSqrt:
  ------------------
  |  Branch (1129:7): [True: 15, False: 2.41k]
  ------------------
 1130|    785|      case GLSLstd450FMin:
  ------------------
  |  Branch (1130:7): [True: 11, False: 2.41k]
  ------------------
 1131|    790|      case GLSLstd450FMax:
  ------------------
  |  Branch (1131:7): [True: 5, False: 2.42k]
  ------------------
 1132|    913|      case GLSLstd450FClamp:
  ------------------
  |  Branch (1132:7): [True: 123, False: 2.30k]
  ------------------
 1133|  1.03k|      case GLSLstd450FMix:
  ------------------
  |  Branch (1133:7): [True: 117, False: 2.30k]
  ------------------
 1134|  1.08k|      case GLSLstd450Step:
  ------------------
  |  Branch (1134:7): [True: 58, False: 2.36k]
  ------------------
 1135|  1.13k|      case GLSLstd450SmoothStep:
  ------------------
  |  Branch (1135:7): [True: 47, False: 2.37k]
  ------------------
 1136|  1.16k|      case GLSLstd450Fma:
  ------------------
  |  Branch (1136:7): [True: 31, False: 2.39k]
  ------------------
 1137|  1.21k|      case GLSLstd450Normalize:
  ------------------
  |  Branch (1137:7): [True: 46, False: 2.38k]
  ------------------
 1138|  1.22k|      case GLSLstd450FaceForward:
  ------------------
  |  Branch (1138:7): [True: 13, False: 2.41k]
  ------------------
 1139|  1.22k|      case GLSLstd450Reflect:
  ------------------
  |  Branch (1139:7): [True: 0, False: 2.42k]
  ------------------
 1140|  1.22k|      case GLSLstd450NMin:
  ------------------
  |  Branch (1140:7): [True: 1, False: 2.42k]
  ------------------
 1141|  1.22k|      case GLSLstd450NMax:
  ------------------
  |  Branch (1141:7): [True: 1, False: 2.42k]
  ------------------
 1142|  1.22k|      case GLSLstd450NClamp: {
  ------------------
  |  Branch (1142:7): [True: 0, False: 2.42k]
  ------------------
 1143|  1.22k|        if (!_.IsFloatScalarOrVectorType(result_type)) {
  ------------------
  |  Branch (1143:13): [True: 10, False: 1.21k]
  ------------------
 1144|     10|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
 1145|     10|                 << ext_inst_name() << ": "
 1146|     10|                 << "expected Result Type to be a float scalar or vector type";
 1147|     10|        }
 1148|       |
 1149|  3.16k|        for (uint32_t operand_index = 4; operand_index < num_operands;
  ------------------
  |  Branch (1149:42): [True: 1.94k, False: 1.21k]
  ------------------
 1150|  1.94k|             ++operand_index) {
 1151|  1.94k|          const uint32_t operand_type = _.GetOperandTypeId(inst, operand_index);
 1152|  1.94k|          if (result_type != operand_type) {
  ------------------
  |  Branch (1152:15): [True: 4, False: 1.94k]
  ------------------
 1153|      4|            return _.diag(SPV_ERROR_INVALID_DATA, inst)
 1154|      4|                   << ext_inst_name() << ": "
 1155|      4|                   << "expected types of all operands to be equal to Result "
 1156|      4|                      "Type";
 1157|      4|          }
 1158|  1.94k|        }
 1159|  1.21k|        break;
 1160|  1.21k|      }
 1161|       |
 1162|  1.21k|      case GLSLstd450SAbs:
  ------------------
  |  Branch (1162:7): [True: 2, False: 2.42k]
  ------------------
 1163|      4|      case GLSLstd450SSign:
  ------------------
  |  Branch (1163:7): [True: 2, False: 2.42k]
  ------------------
 1164|      5|      case GLSLstd450UMin:
  ------------------
  |  Branch (1164:7): [True: 1, False: 2.42k]
  ------------------
 1165|     30|      case GLSLstd450SMin:
  ------------------
  |  Branch (1165:7): [True: 25, False: 2.40k]
  ------------------
 1166|     32|      case GLSLstd450UMax:
  ------------------
  |  Branch (1166:7): [True: 2, False: 2.42k]
  ------------------
 1167|     32|      case GLSLstd450SMax:
  ------------------
  |  Branch (1167:7): [True: 0, False: 2.42k]
  ------------------
 1168|     33|      case GLSLstd450UClamp:
  ------------------
  |  Branch (1168:7): [True: 1, False: 2.42k]
  ------------------
 1169|     35|      case GLSLstd450SClamp:
  ------------------
  |  Branch (1169:7): [True: 2, False: 2.42k]
  ------------------
 1170|    109|      case GLSLstd450FindILsb:
  ------------------
  |  Branch (1170:7): [True: 74, False: 2.35k]
  ------------------
 1171|    125|      case GLSLstd450FindUMsb:
  ------------------
  |  Branch (1171:7): [True: 16, False: 2.41k]
  ------------------
 1172|    268|      case GLSLstd450FindSMsb: {
  ------------------
  |  Branch (1172:7): [True: 143, False: 2.28k]
  ------------------
 1173|    268|        if (!_.IsIntScalarOrVectorType(result_type)) {
  ------------------
  |  Branch (1173:13): [True: 14, False: 254]
  ------------------
 1174|     14|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
 1175|     14|                 << ext_inst_name() << ": "
 1176|     14|                 << "expected Result Type to be an int scalar or vector type";
 1177|     14|        }
 1178|       |
 1179|    254|        const uint32_t result_type_bit_width = _.GetBitWidth(result_type);
 1180|    254|        const uint32_t result_type_dimension = _.GetDimension(result_type);
 1181|       |
 1182|    534|        for (uint32_t operand_index = 4; operand_index < num_operands;
  ------------------
  |  Branch (1182:42): [True: 281, False: 253]
  ------------------
 1183|    281|             ++operand_index) {
 1184|    281|          const uint32_t operand_type = _.GetOperandTypeId(inst, operand_index);
 1185|    281|          if (!operand_type || !_.IsIntScalarOrVectorType(operand_type)) {
  ------------------
  |  Branch (1185:15): [True: 1, False: 280]
  |  Branch (1185:32): [True: 0, False: 280]
  ------------------
 1186|      1|            return _.diag(SPV_ERROR_INVALID_DATA, inst)
 1187|      1|                   << ext_inst_name() << ": "
 1188|      1|                   << "expected all operands to be int scalars or vectors";
 1189|      1|          }
 1190|       |
 1191|    280|          if (result_type_dimension != _.GetDimension(operand_type)) {
  ------------------
  |  Branch (1191:15): [True: 0, False: 280]
  ------------------
 1192|      0|            return _.diag(SPV_ERROR_INVALID_DATA, inst)
 1193|      0|                   << ext_inst_name() << ": "
 1194|      0|                   << "expected all operands to have the same dimension as "
 1195|      0|                   << "Result Type";
 1196|      0|          }
 1197|       |
 1198|    280|          if (result_type_bit_width != _.GetBitWidth(operand_type)) {
  ------------------
  |  Branch (1198:15): [True: 0, False: 280]
  ------------------
 1199|      0|            return _.diag(SPV_ERROR_INVALID_DATA, inst)
 1200|      0|                   << ext_inst_name() << ": "
 1201|      0|                   << "expected all operands to have the same bit width as "
 1202|      0|                   << "Result Type";
 1203|      0|          }
 1204|       |
 1205|    280|          if (ext_inst_key == GLSLstd450FindUMsb ||
  ------------------
  |  Branch (1205:15): [True: 15, False: 265]
  ------------------
 1206|    280|              ext_inst_key == GLSLstd450FindSMsb) {
  ------------------
  |  Branch (1206:15): [True: 142, False: 123]
  ------------------
 1207|    157|            if (result_type_bit_width != 32) {
  ------------------
  |  Branch (1207:17): [True: 0, False: 157]
  ------------------
 1208|      0|              return _.diag(SPV_ERROR_INVALID_DATA, inst)
 1209|      0|                     << ext_inst_name() << ": "
 1210|      0|                     << "this instruction is currently limited to 32-bit width "
 1211|      0|                     << "components";
 1212|      0|            }
 1213|    157|          }
 1214|    280|        }
 1215|    253|        break;
 1216|    254|      }
 1217|       |
 1218|    253|      case GLSLstd450Radians:
  ------------------
  |  Branch (1218:7): [True: 9, False: 2.41k]
  ------------------
 1219|     45|      case GLSLstd450Degrees:
  ------------------
  |  Branch (1219:7): [True: 36, False: 2.39k]
  ------------------
 1220|    209|      case GLSLstd450Sin:
  ------------------
  |  Branch (1220:7): [True: 164, False: 2.26k]
  ------------------
 1221|    276|      case GLSLstd450Cos:
  ------------------
  |  Branch (1221:7): [True: 67, False: 2.35k]
  ------------------
 1222|    324|      case GLSLstd450Tan:
  ------------------
  |  Branch (1222:7): [True: 48, False: 2.37k]
  ------------------
 1223|    327|      case GLSLstd450Asin:
  ------------------
  |  Branch (1223:7): [True: 3, False: 2.42k]
  ------------------
 1224|    329|      case GLSLstd450Acos:
  ------------------
  |  Branch (1224:7): [True: 2, False: 2.42k]
  ------------------
 1225|    344|      case GLSLstd450Atan:
  ------------------
  |  Branch (1225:7): [True: 15, False: 2.41k]
  ------------------
 1226|    357|      case GLSLstd450Sinh:
  ------------------
  |  Branch (1226:7): [True: 13, False: 2.41k]
  ------------------
 1227|    421|      case GLSLstd450Cosh:
  ------------------
  |  Branch (1227:7): [True: 64, False: 2.36k]
  ------------------
 1228|    509|      case GLSLstd450Tanh:
  ------------------
  |  Branch (1228:7): [True: 88, False: 2.33k]
  ------------------
 1229|    543|      case GLSLstd450Asinh:
  ------------------
  |  Branch (1229:7): [True: 34, False: 2.39k]
  ------------------
 1230|    574|      case GLSLstd450Acosh:
  ------------------
  |  Branch (1230:7): [True: 31, False: 2.39k]
  ------------------
 1231|    599|      case GLSLstd450Atanh:
  ------------------
  |  Branch (1231:7): [True: 25, False: 2.40k]
  ------------------
 1232|    611|      case GLSLstd450Exp:
  ------------------
  |  Branch (1232:7): [True: 12, False: 2.41k]
  ------------------
 1233|    633|      case GLSLstd450Exp2:
  ------------------
  |  Branch (1233:7): [True: 22, False: 2.40k]
  ------------------
 1234|    636|      case GLSLstd450Log:
  ------------------
  |  Branch (1234:7): [True: 3, False: 2.42k]
  ------------------
 1235|    677|      case GLSLstd450Log2:
  ------------------
  |  Branch (1235:7): [True: 41, False: 2.38k]
  ------------------
 1236|    679|      case GLSLstd450Atan2:
  ------------------
  |  Branch (1236:7): [True: 2, False: 2.42k]
  ------------------
 1237|    754|      case GLSLstd450Pow: {
  ------------------
  |  Branch (1237:7): [True: 75, False: 2.35k]
  ------------------
 1238|    754|        if (!_.IsFloatScalarOrVectorType(result_type)) {
  ------------------
  |  Branch (1238:13): [True: 9, False: 745]
  ------------------
 1239|      9|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
 1240|      9|                 << ext_inst_name() << ": "
 1241|      9|                 << "expected Result Type to be a 16 or 32-bit scalar or "
 1242|      9|                    "vector float type";
 1243|      9|        }
 1244|       |
 1245|    745|        const uint32_t result_type_bit_width = _.GetBitWidth(result_type);
 1246|    745|        if (result_type_bit_width != 16 && result_type_bit_width != 32) {
  ------------------
  |  Branch (1246:13): [True: 745, False: 0]
  |  Branch (1246:44): [True: 0, False: 745]
  ------------------
 1247|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
 1248|      0|                 << ext_inst_name() << ": "
 1249|      0|                 << "expected Result Type to be a 16 or 32-bit scalar or "
 1250|      0|                    "vector float type";
 1251|      0|        }
 1252|       |
 1253|  1.56k|        for (uint32_t operand_index = 4; operand_index < num_operands;
  ------------------
  |  Branch (1253:42): [True: 822, False: 743]
  ------------------
 1254|    822|             ++operand_index) {
 1255|    822|          const uint32_t operand_type = _.GetOperandTypeId(inst, operand_index);
 1256|    822|          if (result_type != operand_type) {
  ------------------
  |  Branch (1256:15): [True: 2, False: 820]
  ------------------
 1257|      2|            return _.diag(SPV_ERROR_INVALID_DATA, inst)
 1258|      2|                   << ext_inst_name() << ": "
 1259|      2|                   << "expected types of all operands to be equal to Result "
 1260|      2|                      "Type";
 1261|      2|          }
 1262|    822|        }
 1263|    743|        break;
 1264|    745|      }
 1265|       |
 1266|    743|      case GLSLstd450Determinant: {
  ------------------
  |  Branch (1266:7): [True: 3, False: 2.42k]
  ------------------
 1267|      3|        const uint32_t x_type = _.GetOperandTypeId(inst, 4);
 1268|      3|        uint32_t num_rows = 0;
 1269|      3|        uint32_t num_cols = 0;
 1270|      3|        uint32_t col_type = 0;
 1271|      3|        uint32_t component_type = 0;
 1272|      3|        if (!_.GetMatrixTypeInfo(x_type, &num_rows, &num_cols, &col_type,
  ------------------
  |  Branch (1272:13): [True: 2, False: 1]
  ------------------
 1273|      3|                                 &component_type) ||
 1274|      3|            num_rows != num_cols) {
  ------------------
  |  Branch (1274:13): [True: 0, False: 1]
  ------------------
 1275|      2|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
 1276|      2|                 << ext_inst_name() << ": "
 1277|      2|                 << "expected operand X to be a square matrix";
 1278|      2|        }
 1279|       |
 1280|      1|        if (result_type != component_type) {
  ------------------
  |  Branch (1280:13): [True: 1, False: 0]
  ------------------
 1281|      1|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
 1282|      1|                 << ext_inst_name() << ": "
 1283|      1|                 << "expected operand X component type to be equal to "
 1284|      1|                 << "Result Type";
 1285|      1|        }
 1286|      0|        break;
 1287|      1|      }
 1288|       |
 1289|      2|      case GLSLstd450MatrixInverse: {
  ------------------
  |  Branch (1289:7): [True: 2, False: 2.42k]
  ------------------
 1290|      2|        uint32_t num_rows = 0;
 1291|      2|        uint32_t num_cols = 0;
 1292|      2|        uint32_t col_type = 0;
 1293|      2|        uint32_t component_type = 0;
 1294|      2|        if (!_.GetMatrixTypeInfo(result_type, &num_rows, &num_cols, &col_type,
  ------------------
  |  Branch (1294:13): [True: 1, False: 1]
  ------------------
 1295|      2|                                 &component_type) ||
 1296|      2|            num_rows != num_cols) {
  ------------------
  |  Branch (1296:13): [True: 0, False: 1]
  ------------------
 1297|      1|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
 1298|      1|                 << ext_inst_name() << ": "
 1299|      1|                 << "expected Result Type to be a square matrix";
 1300|      1|        }
 1301|       |
 1302|      1|        const uint32_t x_type = _.GetOperandTypeId(inst, 4);
 1303|      1|        if (result_type != x_type) {
  ------------------
  |  Branch (1303:13): [True: 1, False: 0]
  ------------------
 1304|      1|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
 1305|      1|                 << ext_inst_name() << ": "
 1306|      1|                 << "expected operand X type to be equal to Result Type";
 1307|      1|        }
 1308|      0|        break;
 1309|      1|      }
 1310|       |
 1311|      3|      case GLSLstd450Modf: {
  ------------------
  |  Branch (1311:7): [True: 3, False: 2.42k]
  ------------------
 1312|      3|        if (!_.IsFloatScalarOrVectorType(result_type)) {
  ------------------
  |  Branch (1312:13): [True: 0, False: 3]
  ------------------
 1313|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
 1314|      0|                 << ext_inst_name() << ": "
 1315|      0|                 << "expected Result Type to be a scalar or vector float type";
 1316|      0|        }
 1317|       |
 1318|      3|        const uint32_t x_type = _.GetOperandTypeId(inst, 4);
 1319|      3|        const uint32_t i_type = _.GetOperandTypeId(inst, 5);
 1320|       |
 1321|      3|        if (x_type != result_type) {
  ------------------
  |  Branch (1321:13): [True: 0, False: 3]
  ------------------
 1322|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
 1323|      0|                 << ext_inst_name() << ": "
 1324|      0|                 << "expected operand X type to be equal to Result Type";
 1325|      0|        }
 1326|       |
 1327|      3|        spv::StorageClass i_storage_class;
 1328|      3|        uint32_t i_data_type = 0;
 1329|      3|        if (!_.GetPointerTypeInfo(i_type, &i_data_type, &i_storage_class)) {
  ------------------
  |  Branch (1329:13): [True: 2, False: 1]
  ------------------
 1330|      2|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
 1331|      2|                 << ext_inst_name() << ": "
 1332|      2|                 << "expected operand I to be a pointer";
 1333|      2|        }
 1334|       |
 1335|      1|        if (i_data_type != result_type) {
  ------------------
  |  Branch (1335:13): [True: 0, False: 1]
  ------------------
 1336|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
 1337|      0|                 << ext_inst_name() << ": "
 1338|      0|                 << "expected operand I data type to be equal to Result Type";
 1339|      0|        }
 1340|       |
 1341|      1|        break;
 1342|      1|      }
 1343|       |
 1344|      1|      case GLSLstd450ModfStruct: {
  ------------------
  |  Branch (1344:7): [True: 0, False: 2.42k]
  ------------------
 1345|      0|        std::vector<uint32_t> result_types;
 1346|      0|        if (!_.GetStructMemberTypes(result_type, &result_types) ||
  ------------------
  |  Branch (1346:13): [True: 0, False: 0]
  ------------------
 1347|      0|            result_types.size() != 2 ||
  ------------------
  |  Branch (1347:13): [True: 0, False: 0]
  ------------------
 1348|      0|            !_.IsFloatScalarOrVectorType(result_types[0]) ||
  ------------------
  |  Branch (1348:13): [True: 0, False: 0]
  ------------------
 1349|      0|            result_types[1] != result_types[0]) {
  ------------------
  |  Branch (1349:13): [True: 0, False: 0]
  ------------------
 1350|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
 1351|      0|                 << ext_inst_name() << ": "
 1352|      0|                 << "expected Result Type to be a struct with two identical "
 1353|      0|                 << "scalar or vector float type members";
 1354|      0|        }
 1355|       |
 1356|      0|        const uint32_t x_type = _.GetOperandTypeId(inst, 4);
 1357|      0|        if (x_type != result_types[0]) {
  ------------------
  |  Branch (1357:13): [True: 0, False: 0]
  ------------------
 1358|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
 1359|      0|                 << ext_inst_name() << ": "
 1360|      0|                 << "expected operand X type to be equal to members of "
 1361|      0|                 << "Result Type struct";
 1362|      0|        }
 1363|      0|        break;
 1364|      0|      }
 1365|       |
 1366|      0|      case GLSLstd450Frexp: {
  ------------------
  |  Branch (1366:7): [True: 0, False: 2.42k]
  ------------------
 1367|      0|        if (!_.IsFloatScalarOrVectorType(result_type)) {
  ------------------
  |  Branch (1367:13): [True: 0, False: 0]
  ------------------
 1368|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
 1369|      0|                 << ext_inst_name() << ": "
 1370|      0|                 << "expected Result Type to be a scalar or vector float type";
 1371|      0|        }
 1372|       |
 1373|      0|        const uint32_t x_type = _.GetOperandTypeId(inst, 4);
 1374|      0|        const uint32_t exp_type = _.GetOperandTypeId(inst, 5);
 1375|       |
 1376|      0|        if (x_type != result_type) {
  ------------------
  |  Branch (1376:13): [True: 0, False: 0]
  ------------------
 1377|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
 1378|      0|                 << ext_inst_name() << ": "
 1379|      0|                 << "expected operand X type to be equal to Result Type";
 1380|      0|        }
 1381|       |
 1382|      0|        spv::StorageClass exp_storage_class;
 1383|      0|        uint32_t exp_data_type = 0;
 1384|      0|        if (!_.GetPointerTypeInfo(exp_type, &exp_data_type,
  ------------------
  |  Branch (1384:13): [True: 0, False: 0]
  ------------------
 1385|      0|                                  &exp_storage_class)) {
 1386|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
 1387|      0|                 << ext_inst_name() << ": "
 1388|      0|                 << "expected operand Exp to be a pointer";
 1389|      0|        }
 1390|       |
 1391|      0|        if (!_.IsIntScalarOrVectorType(exp_data_type) ||
  ------------------
  |  Branch (1391:13): [True: 0, False: 0]
  ------------------
 1392|      0|            (!_.HasExtension(kSPV_AMD_gpu_shader_int16) &&
  ------------------
  |  Branch (1392:14): [True: 0, False: 0]
  ------------------
 1393|      0|             _.GetBitWidth(exp_data_type) != 32) ||
  ------------------
  |  Branch (1393:14): [True: 0, False: 0]
  ------------------
 1394|      0|            (_.HasExtension(kSPV_AMD_gpu_shader_int16) &&
  ------------------
  |  Branch (1394:14): [True: 0, False: 0]
  ------------------
 1395|      0|             _.GetBitWidth(exp_data_type) != 16 &&
  ------------------
  |  Branch (1395:14): [True: 0, False: 0]
  ------------------
 1396|      0|             _.GetBitWidth(exp_data_type) != 32)) {
  ------------------
  |  Branch (1396:14): [True: 0, False: 0]
  ------------------
 1397|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
 1398|      0|                 << ext_inst_name() << ": "
 1399|      0|                 << "expected operand Exp data type to be a "
 1400|      0|                 << (_.HasExtension(kSPV_AMD_gpu_shader_int16)
  ------------------
  |  Branch (1400:22): [True: 0, False: 0]
  ------------------
 1401|      0|                         ? "16-bit or 32-bit "
 1402|      0|                         : "32-bit ")
 1403|      0|                 << "int scalar or vector type";
 1404|      0|        }
 1405|       |
 1406|      0|        if (_.GetDimension(result_type) != _.GetDimension(exp_data_type)) {
  ------------------
  |  Branch (1406:13): [True: 0, False: 0]
  ------------------
 1407|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
 1408|      0|                 << ext_inst_name() << ": "
 1409|      0|                 << "expected operand Exp data type to have the same component "
 1410|      0|                 << "number as Result Type";
 1411|      0|        }
 1412|       |
 1413|      0|        break;
 1414|      0|      }
 1415|       |
 1416|    116|      case GLSLstd450Ldexp: {
  ------------------
  |  Branch (1416:7): [True: 116, False: 2.31k]
  ------------------
 1417|    116|        if (!_.IsFloatScalarOrVectorType(result_type)) {
  ------------------
  |  Branch (1417:13): [True: 0, False: 116]
  ------------------
 1418|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
 1419|      0|                 << ext_inst_name() << ": "
 1420|      0|                 << "expected Result Type to be a scalar or vector float type";
 1421|      0|        }
 1422|       |
 1423|    116|        const uint32_t x_type = _.GetOperandTypeId(inst, 4);
 1424|    116|        const uint32_t exp_type = _.GetOperandTypeId(inst, 5);
 1425|       |
 1426|    116|        if (x_type != result_type) {
  ------------------
  |  Branch (1426:13): [True: 1, False: 115]
  ------------------
 1427|      1|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
 1428|      1|                 << ext_inst_name() << ": "
 1429|      1|                 << "expected operand X type to be equal to Result Type";
 1430|      1|        }
 1431|       |
 1432|    115|        if (!_.IsIntScalarOrVectorType(exp_type)) {
  ------------------
  |  Branch (1432:13): [True: 2, False: 113]
  ------------------
 1433|      2|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
 1434|      2|                 << ext_inst_name() << ": "
 1435|      2|                 << "expected operand Exp to be a 32-bit int scalar "
 1436|      2|                 << "or vector type";
 1437|      2|        }
 1438|       |
 1439|    113|        if (_.GetDimension(result_type) != _.GetDimension(exp_type)) {
  ------------------
  |  Branch (1439:13): [True: 0, False: 113]
  ------------------
 1440|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
 1441|      0|                 << ext_inst_name() << ": "
 1442|      0|                 << "expected operand Exp to have the same component "
 1443|      0|                 << "number as Result Type";
 1444|      0|        }
 1445|       |
 1446|    113|        break;
 1447|    113|      }
 1448|       |
 1449|    113|      case GLSLstd450FrexpStruct: {
  ------------------
  |  Branch (1449:7): [True: 6, False: 2.42k]
  ------------------
 1450|      6|        std::vector<uint32_t> result_types;
 1451|      6|        if (!_.GetStructMemberTypes(result_type, &result_types) ||
  ------------------
  |  Branch (1451:13): [True: 4, False: 2]
  ------------------
 1452|      6|            result_types.size() != 2 ||
  ------------------
  |  Branch (1452:13): [True: 2, False: 0]
  ------------------
 1453|      6|            !_.IsFloatScalarOrVectorType(result_types[0]) ||
  ------------------
  |  Branch (1453:13): [True: 0, False: 0]
  ------------------
 1454|      6|            !_.IsIntScalarOrVectorType(result_types[1]) ||
  ------------------
  |  Branch (1454:13): [True: 0, False: 0]
  ------------------
 1455|      6|            (!_.HasExtension(kSPV_AMD_gpu_shader_int16) &&
  ------------------
  |  Branch (1455:14): [True: 0, False: 0]
  ------------------
 1456|      0|             _.GetBitWidth(result_types[1]) != 32) ||
  ------------------
  |  Branch (1456:14): [True: 0, False: 0]
  ------------------
 1457|      6|            (_.HasExtension(kSPV_AMD_gpu_shader_int16) &&
  ------------------
  |  Branch (1457:14): [True: 0, False: 0]
  ------------------
 1458|      0|             _.GetBitWidth(result_types[1]) != 16 &&
  ------------------
  |  Branch (1458:14): [True: 0, False: 0]
  ------------------
 1459|      0|             _.GetBitWidth(result_types[1]) != 32) ||
  ------------------
  |  Branch (1459:14): [True: 0, False: 0]
  ------------------
 1460|      6|            _.GetDimension(result_types[0]) !=
  ------------------
  |  Branch (1460:13): [True: 0, False: 0]
  ------------------
 1461|      6|                _.GetDimension(result_types[1])) {
 1462|      6|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
 1463|      6|                 << ext_inst_name() << ": "
 1464|      6|                 << "expected Result Type to be a struct with two members, "
 1465|      6|                 << "first member a float scalar or vector, second member a "
 1466|      6|                 << (_.HasExtension(kSPV_AMD_gpu_shader_int16)
  ------------------
  |  Branch (1466:22): [True: 0, False: 6]
  ------------------
 1467|      6|                         ? "16-bit or 32-bit "
 1468|      6|                         : "32-bit ")
 1469|      6|                 << "int scalar or vector with the same number of "
 1470|      6|                 << "components as the first member";
 1471|      6|        }
 1472|       |
 1473|      0|        const uint32_t x_type = _.GetOperandTypeId(inst, 4);
 1474|      0|        if (x_type != result_types[0]) {
  ------------------
  |  Branch (1474:13): [True: 0, False: 0]
  ------------------
 1475|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
 1476|      0|                 << ext_inst_name() << ": "
 1477|      0|                 << "expected operand X type to be equal to the first member "
 1478|      0|                 << "of Result Type struct";
 1479|      0|        }
 1480|      0|        break;
 1481|      0|      }
 1482|       |
 1483|      2|      case GLSLstd450PackSnorm4x8:
  ------------------
  |  Branch (1483:7): [True: 2, False: 2.42k]
  ------------------
 1484|      4|      case GLSLstd450PackUnorm4x8: {
  ------------------
  |  Branch (1484:7): [True: 2, False: 2.42k]
  ------------------
 1485|      4|        if (!_.IsIntScalarType(result_type) ||
  ------------------
  |  Branch (1485:13): [True: 2, False: 2]
  ------------------
 1486|      4|            _.GetBitWidth(result_type) != 32) {
  ------------------
  |  Branch (1486:13): [True: 0, False: 2]
  ------------------
 1487|      2|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
 1488|      2|                 << ext_inst_name() << ": "
 1489|      2|                 << "expected Result Type to be 32-bit int scalar type";
 1490|      2|        }
 1491|       |
 1492|      2|        const uint32_t v_type = _.GetOperandTypeId(inst, 4);
 1493|      2|        if (!_.IsFloatVectorType(v_type) || _.GetDimension(v_type) != 4 ||
  ------------------
  |  Branch (1493:13): [True: 1, False: 1]
  |  Branch (1493:45): [True: 1, False: 0]
  ------------------
 1494|      2|            _.GetBitWidth(v_type) != 32) {
  ------------------
  |  Branch (1494:13): [True: 0, False: 0]
  ------------------
 1495|      2|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
 1496|      2|                 << ext_inst_name() << ": "
 1497|      2|                 << "expected operand V to be a 32-bit float vector of size 4";
 1498|      2|        }
 1499|      0|        break;
 1500|      2|      }
 1501|       |
 1502|      2|      case GLSLstd450PackSnorm2x16:
  ------------------
  |  Branch (1502:7): [True: 2, False: 2.42k]
  ------------------
 1503|      3|      case GLSLstd450PackUnorm2x16:
  ------------------
  |  Branch (1503:7): [True: 1, False: 2.42k]
  ------------------
 1504|      4|      case GLSLstd450PackHalf2x16: {
  ------------------
  |  Branch (1504:7): [True: 1, False: 2.42k]
  ------------------
 1505|      4|        if (!_.IsIntScalarType(result_type) ||
  ------------------
  |  Branch (1505:13): [True: 1, False: 3]
  ------------------
 1506|      4|            _.GetBitWidth(result_type) != 32) {
  ------------------
  |  Branch (1506:13): [True: 0, False: 3]
  ------------------
 1507|      1|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
 1508|      1|                 << ext_inst_name() << ": "
 1509|      1|                 << "expected Result Type to be 32-bit int scalar type";
 1510|      1|        }
 1511|       |
 1512|      3|        const uint32_t v_type = _.GetOperandTypeId(inst, 4);
 1513|      3|        if (!_.IsFloatVectorType(v_type) || _.GetDimension(v_type) != 2 ||
  ------------------
  |  Branch (1513:13): [True: 1, False: 2]
  |  Branch (1513:45): [True: 0, False: 2]
  ------------------
 1514|      3|            _.GetBitWidth(v_type) != 32) {
  ------------------
  |  Branch (1514:13): [True: 0, False: 2]
  ------------------
 1515|      1|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
 1516|      1|                 << ext_inst_name() << ": "
 1517|      1|                 << "expected operand V to be a 32-bit float vector of size 2";
 1518|      1|        }
 1519|      2|        break;
 1520|      3|      }
 1521|       |
 1522|      2|      case GLSLstd450PackDouble2x32: {
  ------------------
  |  Branch (1522:7): [True: 0, False: 2.42k]
  ------------------
 1523|      0|        if (!_.IsFloatScalarType(result_type) ||
  ------------------
  |  Branch (1523:13): [True: 0, False: 0]
  ------------------
 1524|      0|            _.GetBitWidth(result_type) != 64) {
  ------------------
  |  Branch (1524:13): [True: 0, False: 0]
  ------------------
 1525|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
 1526|      0|                 << ext_inst_name() << ": "
 1527|      0|                 << "expected Result Type to be 64-bit float scalar type";
 1528|      0|        }
 1529|       |
 1530|      0|        const uint32_t v_type = _.GetOperandTypeId(inst, 4);
 1531|      0|        if (!_.IsIntVectorType(v_type) || _.GetDimension(v_type) != 2 ||
  ------------------
  |  Branch (1531:13): [True: 0, False: 0]
  |  Branch (1531:43): [True: 0, False: 0]
  ------------------
 1532|      0|            _.GetBitWidth(v_type) != 32) {
  ------------------
  |  Branch (1532:13): [True: 0, False: 0]
  ------------------
 1533|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
 1534|      0|                 << ext_inst_name() << ": "
 1535|      0|                 << "expected operand V to be a 32-bit int vector of size 2";
 1536|      0|        }
 1537|      0|        break;
 1538|      0|      }
 1539|       |
 1540|      1|      case GLSLstd450UnpackSnorm4x8:
  ------------------
  |  Branch (1540:7): [True: 1, False: 2.42k]
  ------------------
 1541|      2|      case GLSLstd450UnpackUnorm4x8: {
  ------------------
  |  Branch (1541:7): [True: 1, False: 2.42k]
  ------------------
 1542|      2|        if (!_.IsFloatVectorType(result_type) ||
  ------------------
  |  Branch (1542:13): [True: 2, False: 0]
  ------------------
 1543|      2|            _.GetDimension(result_type) != 4 ||
  ------------------
  |  Branch (1543:13): [True: 0, False: 0]
  ------------------
 1544|      2|            _.GetBitWidth(result_type) != 32) {
  ------------------
  |  Branch (1544:13): [True: 0, False: 0]
  ------------------
 1545|      2|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
 1546|      2|                 << ext_inst_name() << ": "
 1547|      2|                 << "expected Result Type to be a 32-bit float vector of size "
 1548|      2|                    "4";
 1549|      2|        }
 1550|       |
 1551|      0|        const uint32_t v_type = _.GetOperandTypeId(inst, 4);
 1552|      0|        if (!_.IsIntScalarType(v_type) || _.GetBitWidth(v_type) != 32) {
  ------------------
  |  Branch (1552:13): [True: 0, False: 0]
  |  Branch (1552:43): [True: 0, False: 0]
  ------------------
 1553|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
 1554|      0|                 << ext_inst_name() << ": "
 1555|      0|                 << "expected operand P to be a 32-bit int scalar";
 1556|      0|        }
 1557|      0|        break;
 1558|      0|      }
 1559|       |
 1560|      1|      case GLSLstd450UnpackSnorm2x16:
  ------------------
  |  Branch (1560:7): [True: 1, False: 2.42k]
  ------------------
 1561|      1|      case GLSLstd450UnpackUnorm2x16:
  ------------------
  |  Branch (1561:7): [True: 0, False: 2.42k]
  ------------------
 1562|      1|      case GLSLstd450UnpackHalf2x16: {
  ------------------
  |  Branch (1562:7): [True: 0, False: 2.42k]
  ------------------
 1563|      1|        if (!_.IsFloatVectorType(result_type) ||
  ------------------
  |  Branch (1563:13): [True: 0, False: 1]
  ------------------
 1564|      1|            _.GetDimension(result_type) != 2 ||
  ------------------
  |  Branch (1564:13): [True: 1, False: 0]
  ------------------
 1565|      1|            _.GetBitWidth(result_type) != 32) {
  ------------------
  |  Branch (1565:13): [True: 0, False: 0]
  ------------------
 1566|      1|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
 1567|      1|                 << ext_inst_name() << ": "
 1568|      1|                 << "expected Result Type to be a 32-bit float vector of size "
 1569|      1|                    "2";
 1570|      1|        }
 1571|       |
 1572|      0|        const uint32_t v_type = _.GetOperandTypeId(inst, 4);
 1573|      0|        if (!_.IsIntScalarType(v_type) || _.GetBitWidth(v_type) != 32) {
  ------------------
  |  Branch (1573:13): [True: 0, False: 0]
  |  Branch (1573:43): [True: 0, False: 0]
  ------------------
 1574|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
 1575|      0|                 << ext_inst_name() << ": "
 1576|      0|                 << "expected operand P to be a 32-bit int scalar";
 1577|      0|        }
 1578|      0|        break;
 1579|      0|      }
 1580|       |
 1581|      1|      case GLSLstd450UnpackDouble2x32: {
  ------------------
  |  Branch (1581:7): [True: 1, False: 2.42k]
  ------------------
 1582|      1|        if (!_.IsIntVectorType(result_type) ||
  ------------------
  |  Branch (1582:13): [True: 1, False: 0]
  ------------------
 1583|      1|            _.GetDimension(result_type) != 2 ||
  ------------------
  |  Branch (1583:13): [True: 0, False: 0]
  ------------------
 1584|      1|            _.GetBitWidth(result_type) != 32) {
  ------------------
  |  Branch (1584:13): [True: 0, False: 0]
  ------------------
 1585|      1|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
 1586|      1|                 << ext_inst_name() << ": "
 1587|      1|                 << "expected Result Type to be a 32-bit int vector of size "
 1588|      1|                    "2";
 1589|      1|        }
 1590|       |
 1591|      0|        const uint32_t v_type = _.GetOperandTypeId(inst, 4);
 1592|      0|        if (!_.IsFloatScalarType(v_type) || _.GetBitWidth(v_type) != 64) {
  ------------------
  |  Branch (1592:13): [True: 0, False: 0]
  |  Branch (1592:45): [True: 0, False: 0]
  ------------------
 1593|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
 1594|      0|                 << ext_inst_name() << ": "
 1595|      0|                 << "expected operand V to be a 64-bit float scalar";
 1596|      0|        }
 1597|      0|        break;
 1598|      0|      }
 1599|       |
 1600|     30|      case GLSLstd450Length: {
  ------------------
  |  Branch (1600:7): [True: 30, False: 2.39k]
  ------------------
 1601|     30|        if (!_.IsFloatScalarType(result_type)) {
  ------------------
  |  Branch (1601:13): [True: 1, False: 29]
  ------------------
 1602|      1|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
 1603|      1|                 << ext_inst_name() << ": "
 1604|      1|                 << "expected Result Type to be a float scalar type";
 1605|      1|        }
 1606|       |
 1607|     29|        const uint32_t x_type = _.GetOperandTypeId(inst, 4);
 1608|     29|        if (!_.IsFloatScalarOrVectorType(x_type)) {
  ------------------
  |  Branch (1608:13): [True: 0, False: 29]
  ------------------
 1609|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
 1610|      0|                 << ext_inst_name() << ": "
 1611|      0|                 << "expected operand X to be of float scalar or vector type";
 1612|      0|        }
 1613|       |
 1614|     29|        if (result_type != _.GetComponentType(x_type)) {
  ------------------
  |  Branch (1614:13): [True: 0, False: 29]
  ------------------
 1615|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
 1616|      0|                 << ext_inst_name() << ": "
 1617|      0|                 << "expected operand X component type to be equal to Result "
 1618|      0|                    "Type";
 1619|      0|        }
 1620|     29|        break;
 1621|     29|      }
 1622|       |
 1623|     29|      case GLSLstd450Distance: {
  ------------------
  |  Branch (1623:7): [True: 2, False: 2.42k]
  ------------------
 1624|      2|        if (!_.IsFloatScalarType(result_type)) {
  ------------------
  |  Branch (1624:13): [True: 0, False: 2]
  ------------------
 1625|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
 1626|      0|                 << ext_inst_name() << ": "
 1627|      0|                 << "expected Result Type to be a float scalar type";
 1628|      0|        }
 1629|       |
 1630|      2|        const uint32_t p0_type = _.GetOperandTypeId(inst, 4);
 1631|      2|        if (!_.IsFloatScalarOrVectorType(p0_type)) {
  ------------------
  |  Branch (1631:13): [True: 1, False: 1]
  ------------------
 1632|      1|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
 1633|      1|                 << ext_inst_name() << ": "
 1634|      1|                 << "expected operand P0 to be of float scalar or vector type";
 1635|      1|        }
 1636|       |
 1637|      1|        if (result_type != _.GetComponentType(p0_type)) {
  ------------------
  |  Branch (1637:13): [True: 0, False: 1]
  ------------------
 1638|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
 1639|      0|                 << ext_inst_name() << ": "
 1640|      0|                 << "expected operand P0 component type to be equal to "
 1641|      0|                 << "Result Type";
 1642|      0|        }
 1643|       |
 1644|      1|        const uint32_t p1_type = _.GetOperandTypeId(inst, 5);
 1645|      1|        if (!_.IsFloatScalarOrVectorType(p1_type)) {
  ------------------
  |  Branch (1645:13): [True: 0, False: 1]
  ------------------
 1646|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
 1647|      0|                 << ext_inst_name() << ": "
 1648|      0|                 << "expected operand P1 to be of float scalar or vector type";
 1649|      0|        }
 1650|       |
 1651|      1|        if (result_type != _.GetComponentType(p1_type)) {
  ------------------
  |  Branch (1651:13): [True: 0, False: 1]
  ------------------
 1652|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
 1653|      0|                 << ext_inst_name() << ": "
 1654|      0|                 << "expected operand P1 component type to be equal to "
 1655|      0|                 << "Result Type";
 1656|      0|        }
 1657|       |
 1658|      1|        if (_.GetDimension(p0_type) != _.GetDimension(p1_type)) {
  ------------------
  |  Branch (1658:13): [True: 0, False: 1]
  ------------------
 1659|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
 1660|      0|                 << ext_inst_name() << ": "
 1661|      0|                 << "expected operands P0 and P1 to have the same number of "
 1662|      0|                 << "components";
 1663|      0|        }
 1664|      1|        break;
 1665|      1|      }
 1666|       |
 1667|      1|      case GLSLstd450Cross: {
  ------------------
  |  Branch (1667:7): [True: 1, False: 2.42k]
  ------------------
 1668|      1|        if (!_.IsFloatVectorType(result_type)) {
  ------------------
  |  Branch (1668:13): [True: 1, False: 0]
  ------------------
 1669|      1|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
 1670|      1|                 << ext_inst_name() << ": "
 1671|      1|                 << "expected Result Type to be a float vector type";
 1672|      1|        }
 1673|       |
 1674|      0|        if (_.GetDimension(result_type) != 3) {
  ------------------
  |  Branch (1674:13): [True: 0, False: 0]
  ------------------
 1675|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
 1676|      0|                 << ext_inst_name() << ": "
 1677|      0|                 << "expected Result Type to have 3 components";
 1678|      0|        }
 1679|       |
 1680|      0|        const uint32_t x_type = _.GetOperandTypeId(inst, 4);
 1681|      0|        const uint32_t y_type = _.GetOperandTypeId(inst, 5);
 1682|       |
 1683|      0|        if (x_type != result_type) {
  ------------------
  |  Branch (1683:13): [True: 0, False: 0]
  ------------------
 1684|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
 1685|      0|                 << ext_inst_name() << ": "
 1686|      0|                 << "expected operand X type to be equal to Result Type";
 1687|      0|        }
 1688|       |
 1689|      0|        if (y_type != result_type) {
  ------------------
  |  Branch (1689:13): [True: 0, False: 0]
  ------------------
 1690|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
 1691|      0|                 << ext_inst_name() << ": "
 1692|      0|                 << "expected operand Y type to be equal to Result Type";
 1693|      0|        }
 1694|      0|        break;
 1695|      0|      }
 1696|       |
 1697|      1|      case GLSLstd450Refract: {
  ------------------
  |  Branch (1697:7): [True: 1, False: 2.42k]
  ------------------
 1698|      1|        if (!_.IsFloatScalarOrVectorType(result_type)) {
  ------------------
  |  Branch (1698:13): [True: 0, False: 1]
  ------------------
 1699|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
 1700|      0|                 << ext_inst_name() << ": "
 1701|      0|                 << "expected Result Type to be a float scalar or vector type";
 1702|      0|        }
 1703|       |
 1704|      1|        const uint32_t i_type = _.GetOperandTypeId(inst, 4);
 1705|      1|        const uint32_t n_type = _.GetOperandTypeId(inst, 5);
 1706|      1|        const uint32_t eta_type = _.GetOperandTypeId(inst, 6);
 1707|       |
 1708|      1|        if (result_type != i_type) {
  ------------------
  |  Branch (1708:13): [True: 0, False: 1]
  ------------------
 1709|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
 1710|      0|                 << ext_inst_name() << ": "
 1711|      0|                 << "expected operand I to be of type equal to Result Type";
 1712|      0|        }
 1713|       |
 1714|      1|        if (result_type != n_type) {
  ------------------
  |  Branch (1714:13): [True: 0, False: 1]
  ------------------
 1715|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
 1716|      0|                 << ext_inst_name() << ": "
 1717|      0|                 << "expected operand N to be of type equal to Result Type";
 1718|      0|        }
 1719|       |
 1720|      1|        if (!_.IsFloatScalarType(eta_type)) {
  ------------------
  |  Branch (1720:13): [True: 1, False: 0]
  ------------------
 1721|      1|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
 1722|      1|                 << ext_inst_name() << ": "
 1723|      1|                 << "expected operand Eta to be a float scalar";
 1724|      1|        }
 1725|      0|        break;
 1726|      1|      }
 1727|       |
 1728|      0|      case GLSLstd450InterpolateAtCentroid:
  ------------------
  |  Branch (1728:7): [True: 0, False: 2.42k]
  ------------------
 1729|      0|      case GLSLstd450InterpolateAtSample:
  ------------------
  |  Branch (1729:7): [True: 0, False: 2.42k]
  ------------------
 1730|      1|      case GLSLstd450InterpolateAtOffset: {
  ------------------
  |  Branch (1730:7): [True: 1, False: 2.42k]
  ------------------
 1731|      1|        if (!_.HasCapability(spv::Capability::InterpolationFunction)) {
  ------------------
  |  Branch (1731:13): [True: 0, False: 1]
  ------------------
 1732|      0|          return _.diag(SPV_ERROR_INVALID_CAPABILITY, inst)
 1733|      0|                 << ext_inst_name()
 1734|      0|                 << " requires capability InterpolationFunction";
 1735|      0|        }
 1736|       |
 1737|      1|        if (!_.IsFloatScalarOrVectorType(result_type) ||
  ------------------
  |  Branch (1737:13): [True: 0, False: 1]
  ------------------
 1738|      1|            _.GetBitWidth(result_type) != 32) {
  ------------------
  |  Branch (1738:13): [True: 0, False: 1]
  ------------------
 1739|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
 1740|      0|                 << ext_inst_name() << ": "
 1741|      0|                 << "expected Result Type to be a 32-bit float scalar "
 1742|      0|                 << "or vector type";
 1743|      0|        }
 1744|       |
 1745|       |        // If HLSL legalization and first operand is an OpLoad, use load
 1746|       |        // pointer as the interpolant lvalue. Else use interpolate first
 1747|       |        // operand.
 1748|      1|        uint32_t interp_id = inst->GetOperandAs<uint32_t>(4);
 1749|      1|        auto* interp_inst = _.FindDef(interp_id);
 1750|      1|        uint32_t interpolant_type = (_.options()->before_hlsl_legalization &&
  ------------------
  |  Branch (1750:38): [True: 0, False: 1]
  ------------------
 1751|      1|                                     interp_inst->opcode() == spv::Op::OpLoad)
  ------------------
  |  Branch (1751:38): [True: 0, False: 0]
  ------------------
 1752|      1|                                        ? _.GetOperandTypeId(interp_inst, 2)
 1753|      1|                                        : _.GetOperandTypeId(inst, 4);
 1754|       |
 1755|      1|        spv::StorageClass interpolant_storage_class;
 1756|      1|        uint32_t interpolant_data_type = 0;
 1757|      1|        if (!_.GetPointerTypeInfo(interpolant_type, &interpolant_data_type,
  ------------------
  |  Branch (1757:13): [True: 1, False: 0]
  ------------------
 1758|      1|                                  &interpolant_storage_class)) {
 1759|      1|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
 1760|      1|                 << ext_inst_name() << ": "
 1761|      1|                 << "expected Interpolant to be a pointer";
 1762|      1|        }
 1763|       |
 1764|      0|        if (result_type != interpolant_data_type) {
  ------------------
  |  Branch (1764:13): [True: 0, False: 0]
  ------------------
 1765|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
 1766|      0|                 << ext_inst_name() << ": "
 1767|      0|                 << "expected Interpolant data type to be equal to Result Type";
 1768|      0|        }
 1769|       |
 1770|      0|        if (interpolant_storage_class != spv::StorageClass::Input) {
  ------------------
  |  Branch (1770:13): [True: 0, False: 0]
  ------------------
 1771|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
 1772|      0|                 << ext_inst_name() << ": "
 1773|      0|                 << "expected Interpolant storage class to be Input";
 1774|      0|        }
 1775|       |
 1776|      0|        if (ext_inst_key == GLSLstd450InterpolateAtSample) {
  ------------------
  |  Branch (1776:13): [True: 0, False: 0]
  ------------------
 1777|      0|          const uint32_t sample_type = _.GetOperandTypeId(inst, 5);
 1778|      0|          if (!_.IsIntScalarType(sample_type) ||
  ------------------
  |  Branch (1778:15): [True: 0, False: 0]
  ------------------
 1779|      0|              _.GetBitWidth(sample_type) != 32) {
  ------------------
  |  Branch (1779:15): [True: 0, False: 0]
  ------------------
 1780|      0|            return _.diag(SPV_ERROR_INVALID_DATA, inst)
 1781|      0|                   << ext_inst_name() << ": "
 1782|      0|                   << "expected Sample to be 32-bit integer";
 1783|      0|          }
 1784|      0|        }
 1785|       |
 1786|      0|        if (ext_inst_key == GLSLstd450InterpolateAtOffset) {
  ------------------
  |  Branch (1786:13): [True: 0, False: 0]
  ------------------
 1787|      0|          const uint32_t offset_type = _.GetOperandTypeId(inst, 5);
 1788|      0|          if (!_.IsFloatVectorType(offset_type) ||
  ------------------
  |  Branch (1788:15): [True: 0, False: 0]
  ------------------
 1789|      0|              _.GetDimension(offset_type) != 2 ||
  ------------------
  |  Branch (1789:15): [True: 0, False: 0]
  ------------------
 1790|      0|              _.GetBitWidth(offset_type) != 32) {
  ------------------
  |  Branch (1790:15): [True: 0, False: 0]
  ------------------
 1791|      0|            return _.diag(SPV_ERROR_INVALID_DATA, inst)
 1792|      0|                   << ext_inst_name() << ": "
 1793|      0|                   << "expected Offset to be a vector of 2 32-bit floats";
 1794|      0|          }
 1795|      0|        }
 1796|       |
 1797|      0|        _.function(inst->function()->id())
 1798|      0|            ->RegisterExecutionModelLimitation(
 1799|      0|                spv::ExecutionModel::Fragment,
 1800|      0|                ext_inst_name() +
 1801|      0|                    std::string(" requires Fragment execution model"));
 1802|      0|        break;
 1803|      0|      }
 1804|       |
 1805|      0|      case GLSLstd450IMix: {
  ------------------
  |  Branch (1805:7): [True: 0, False: 2.42k]
  ------------------
 1806|      0|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
 1807|      0|               << "Extended instruction GLSLstd450IMix is not supported";
 1808|      0|      }
 1809|       |
 1810|      0|      case GLSLstd450Bad: {
  ------------------
  |  Branch (1810:7): [True: 0, False: 2.42k]
  ------------------
 1811|      0|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
 1812|      0|               << "Encountered extended instruction GLSLstd450Bad";
 1813|      0|      }
 1814|       |
 1815|      0|      case GLSLstd450Count: {
  ------------------
  |  Branch (1815:7): [True: 0, False: 2.42k]
  ------------------
 1816|      0|        assert(0);
 1817|      0|        break;
 1818|      0|      }
 1819|  2.42k|    }
 1820|  2.42k|  } else if (ext_inst_type == SPV_EXT_INST_TYPE_OPENCL_STD) {
  ------------------
  |  Branch (1820:14): [True: 0, False: 0]
  ------------------
 1821|      0|    const OpenCLLIB::Entrypoints ext_inst_key =
 1822|      0|        OpenCLLIB::Entrypoints(ext_inst_index);
 1823|      0|    switch (ext_inst_key) {
  ------------------
  |  Branch (1823:13): [True: 0, False: 0]
  ------------------
 1824|      0|      case OpenCLLIB::Acos:
  ------------------
  |  Branch (1824:7): [True: 0, False: 0]
  ------------------
 1825|      0|      case OpenCLLIB::Acosh:
  ------------------
  |  Branch (1825:7): [True: 0, False: 0]
  ------------------
 1826|      0|      case OpenCLLIB::Acospi:
  ------------------
  |  Branch (1826:7): [True: 0, False: 0]
  ------------------
 1827|      0|      case OpenCLLIB::Asin:
  ------------------
  |  Branch (1827:7): [True: 0, False: 0]
  ------------------
 1828|      0|      case OpenCLLIB::Asinh:
  ------------------
  |  Branch (1828:7): [True: 0, False: 0]
  ------------------
 1829|      0|      case OpenCLLIB::Asinpi:
  ------------------
  |  Branch (1829:7): [True: 0, False: 0]
  ------------------
 1830|      0|      case OpenCLLIB::Atan:
  ------------------
  |  Branch (1830:7): [True: 0, False: 0]
  ------------------
 1831|      0|      case OpenCLLIB::Atan2:
  ------------------
  |  Branch (1831:7): [True: 0, False: 0]
  ------------------
 1832|      0|      case OpenCLLIB::Atanh:
  ------------------
  |  Branch (1832:7): [True: 0, False: 0]
  ------------------
 1833|      0|      case OpenCLLIB::Atanpi:
  ------------------
  |  Branch (1833:7): [True: 0, False: 0]
  ------------------
 1834|      0|      case OpenCLLIB::Atan2pi:
  ------------------
  |  Branch (1834:7): [True: 0, False: 0]
  ------------------
 1835|      0|      case OpenCLLIB::Cbrt:
  ------------------
  |  Branch (1835:7): [True: 0, False: 0]
  ------------------
 1836|      0|      case OpenCLLIB::Ceil:
  ------------------
  |  Branch (1836:7): [True: 0, False: 0]
  ------------------
 1837|      0|      case OpenCLLIB::Copysign:
  ------------------
  |  Branch (1837:7): [True: 0, False: 0]
  ------------------
 1838|      0|      case OpenCLLIB::Cos:
  ------------------
  |  Branch (1838:7): [True: 0, False: 0]
  ------------------
 1839|      0|      case OpenCLLIB::Cosh:
  ------------------
  |  Branch (1839:7): [True: 0, False: 0]
  ------------------
 1840|      0|      case OpenCLLIB::Cospi:
  ------------------
  |  Branch (1840:7): [True: 0, False: 0]
  ------------------
 1841|      0|      case OpenCLLIB::Erfc:
  ------------------
  |  Branch (1841:7): [True: 0, False: 0]
  ------------------
 1842|      0|      case OpenCLLIB::Erf:
  ------------------
  |  Branch (1842:7): [True: 0, False: 0]
  ------------------
 1843|      0|      case OpenCLLIB::Exp:
  ------------------
  |  Branch (1843:7): [True: 0, False: 0]
  ------------------
 1844|      0|      case OpenCLLIB::Exp2:
  ------------------
  |  Branch (1844:7): [True: 0, False: 0]
  ------------------
 1845|      0|      case OpenCLLIB::Exp10:
  ------------------
  |  Branch (1845:7): [True: 0, False: 0]
  ------------------
 1846|      0|      case OpenCLLIB::Expm1:
  ------------------
  |  Branch (1846:7): [True: 0, False: 0]
  ------------------
 1847|      0|      case OpenCLLIB::Fabs:
  ------------------
  |  Branch (1847:7): [True: 0, False: 0]
  ------------------
 1848|      0|      case OpenCLLIB::Fdim:
  ------------------
  |  Branch (1848:7): [True: 0, False: 0]
  ------------------
 1849|      0|      case OpenCLLIB::Floor:
  ------------------
  |  Branch (1849:7): [True: 0, False: 0]
  ------------------
 1850|      0|      case OpenCLLIB::Fma:
  ------------------
  |  Branch (1850:7): [True: 0, False: 0]
  ------------------
 1851|      0|      case OpenCLLIB::Fmax:
  ------------------
  |  Branch (1851:7): [True: 0, False: 0]
  ------------------
 1852|      0|      case OpenCLLIB::Fmin:
  ------------------
  |  Branch (1852:7): [True: 0, False: 0]
  ------------------
 1853|      0|      case OpenCLLIB::Fmod:
  ------------------
  |  Branch (1853:7): [True: 0, False: 0]
  ------------------
 1854|      0|      case OpenCLLIB::Hypot:
  ------------------
  |  Branch (1854:7): [True: 0, False: 0]
  ------------------
 1855|      0|      case OpenCLLIB::Lgamma:
  ------------------
  |  Branch (1855:7): [True: 0, False: 0]
  ------------------
 1856|      0|      case OpenCLLIB::Log:
  ------------------
  |  Branch (1856:7): [True: 0, False: 0]
  ------------------
 1857|      0|      case OpenCLLIB::Log2:
  ------------------
  |  Branch (1857:7): [True: 0, False: 0]
  ------------------
 1858|      0|      case OpenCLLIB::Log10:
  ------------------
  |  Branch (1858:7): [True: 0, False: 0]
  ------------------
 1859|      0|      case OpenCLLIB::Log1p:
  ------------------
  |  Branch (1859:7): [True: 0, False: 0]
  ------------------
 1860|      0|      case OpenCLLIB::Logb:
  ------------------
  |  Branch (1860:7): [True: 0, False: 0]
  ------------------
 1861|      0|      case OpenCLLIB::Mad:
  ------------------
  |  Branch (1861:7): [True: 0, False: 0]
  ------------------
 1862|      0|      case OpenCLLIB::Maxmag:
  ------------------
  |  Branch (1862:7): [True: 0, False: 0]
  ------------------
 1863|      0|      case OpenCLLIB::Minmag:
  ------------------
  |  Branch (1863:7): [True: 0, False: 0]
  ------------------
 1864|      0|      case OpenCLLIB::Nextafter:
  ------------------
  |  Branch (1864:7): [True: 0, False: 0]
  ------------------
 1865|      0|      case OpenCLLIB::Pow:
  ------------------
  |  Branch (1865:7): [True: 0, False: 0]
  ------------------
 1866|      0|      case OpenCLLIB::Powr:
  ------------------
  |  Branch (1866:7): [True: 0, False: 0]
  ------------------
 1867|      0|      case OpenCLLIB::Remainder:
  ------------------
  |  Branch (1867:7): [True: 0, False: 0]
  ------------------
 1868|      0|      case OpenCLLIB::Rint:
  ------------------
  |  Branch (1868:7): [True: 0, False: 0]
  ------------------
 1869|      0|      case OpenCLLIB::Round:
  ------------------
  |  Branch (1869:7): [True: 0, False: 0]
  ------------------
 1870|      0|      case OpenCLLIB::Rsqrt:
  ------------------
  |  Branch (1870:7): [True: 0, False: 0]
  ------------------
 1871|      0|      case OpenCLLIB::Sin:
  ------------------
  |  Branch (1871:7): [True: 0, False: 0]
  ------------------
 1872|      0|      case OpenCLLIB::Sinh:
  ------------------
  |  Branch (1872:7): [True: 0, False: 0]
  ------------------
 1873|      0|      case OpenCLLIB::Sinpi:
  ------------------
  |  Branch (1873:7): [True: 0, False: 0]
  ------------------
 1874|      0|      case OpenCLLIB::Sqrt:
  ------------------
  |  Branch (1874:7): [True: 0, False: 0]
  ------------------
 1875|      0|      case OpenCLLIB::Tan:
  ------------------
  |  Branch (1875:7): [True: 0, False: 0]
  ------------------
 1876|      0|      case OpenCLLIB::Tanh:
  ------------------
  |  Branch (1876:7): [True: 0, False: 0]
  ------------------
 1877|      0|      case OpenCLLIB::Tanpi:
  ------------------
  |  Branch (1877:7): [True: 0, False: 0]
  ------------------
 1878|      0|      case OpenCLLIB::Tgamma:
  ------------------
  |  Branch (1878:7): [True: 0, False: 0]
  ------------------
 1879|      0|      case OpenCLLIB::Trunc:
  ------------------
  |  Branch (1879:7): [True: 0, False: 0]
  ------------------
 1880|      0|      case OpenCLLIB::Half_cos:
  ------------------
  |  Branch (1880:7): [True: 0, False: 0]
  ------------------
 1881|      0|      case OpenCLLIB::Half_divide:
  ------------------
  |  Branch (1881:7): [True: 0, False: 0]
  ------------------
 1882|      0|      case OpenCLLIB::Half_exp:
  ------------------
  |  Branch (1882:7): [True: 0, False: 0]
  ------------------
 1883|      0|      case OpenCLLIB::Half_exp2:
  ------------------
  |  Branch (1883:7): [True: 0, False: 0]
  ------------------
 1884|      0|      case OpenCLLIB::Half_exp10:
  ------------------
  |  Branch (1884:7): [True: 0, False: 0]
  ------------------
 1885|      0|      case OpenCLLIB::Half_log:
  ------------------
  |  Branch (1885:7): [True: 0, False: 0]
  ------------------
 1886|      0|      case OpenCLLIB::Half_log2:
  ------------------
  |  Branch (1886:7): [True: 0, False: 0]
  ------------------
 1887|      0|      case OpenCLLIB::Half_log10:
  ------------------
  |  Branch (1887:7): [True: 0, False: 0]
  ------------------
 1888|      0|      case OpenCLLIB::Half_powr:
  ------------------
  |  Branch (1888:7): [True: 0, False: 0]
  ------------------
 1889|      0|      case OpenCLLIB::Half_recip:
  ------------------
  |  Branch (1889:7): [True: 0, False: 0]
  ------------------
 1890|      0|      case OpenCLLIB::Half_rsqrt:
  ------------------
  |  Branch (1890:7): [True: 0, False: 0]
  ------------------
 1891|      0|      case OpenCLLIB::Half_sin:
  ------------------
  |  Branch (1891:7): [True: 0, False: 0]
  ------------------
 1892|      0|      case OpenCLLIB::Half_sqrt:
  ------------------
  |  Branch (1892:7): [True: 0, False: 0]
  ------------------
 1893|      0|      case OpenCLLIB::Half_tan:
  ------------------
  |  Branch (1893:7): [True: 0, False: 0]
  ------------------
 1894|      0|      case OpenCLLIB::Native_cos:
  ------------------
  |  Branch (1894:7): [True: 0, False: 0]
  ------------------
 1895|      0|      case OpenCLLIB::Native_divide:
  ------------------
  |  Branch (1895:7): [True: 0, False: 0]
  ------------------
 1896|      0|      case OpenCLLIB::Native_exp:
  ------------------
  |  Branch (1896:7): [True: 0, False: 0]
  ------------------
 1897|      0|      case OpenCLLIB::Native_exp2:
  ------------------
  |  Branch (1897:7): [True: 0, False: 0]
  ------------------
 1898|      0|      case OpenCLLIB::Native_exp10:
  ------------------
  |  Branch (1898:7): [True: 0, False: 0]
  ------------------
 1899|      0|      case OpenCLLIB::Native_log:
  ------------------
  |  Branch (1899:7): [True: 0, False: 0]
  ------------------
 1900|      0|      case OpenCLLIB::Native_log2:
  ------------------
  |  Branch (1900:7): [True: 0, False: 0]
  ------------------
 1901|      0|      case OpenCLLIB::Native_log10:
  ------------------
  |  Branch (1901:7): [True: 0, False: 0]
  ------------------
 1902|      0|      case OpenCLLIB::Native_powr:
  ------------------
  |  Branch (1902:7): [True: 0, False: 0]
  ------------------
 1903|      0|      case OpenCLLIB::Native_recip:
  ------------------
  |  Branch (1903:7): [True: 0, False: 0]
  ------------------
 1904|      0|      case OpenCLLIB::Native_rsqrt:
  ------------------
  |  Branch (1904:7): [True: 0, False: 0]
  ------------------
 1905|      0|      case OpenCLLIB::Native_sin:
  ------------------
  |  Branch (1905:7): [True: 0, False: 0]
  ------------------
 1906|      0|      case OpenCLLIB::Native_sqrt:
  ------------------
  |  Branch (1906:7): [True: 0, False: 0]
  ------------------
 1907|      0|      case OpenCLLIB::Native_tan:
  ------------------
  |  Branch (1907:7): [True: 0, False: 0]
  ------------------
 1908|      0|      case OpenCLLIB::FClamp:
  ------------------
  |  Branch (1908:7): [True: 0, False: 0]
  ------------------
 1909|      0|      case OpenCLLIB::Degrees:
  ------------------
  |  Branch (1909:7): [True: 0, False: 0]
  ------------------
 1910|      0|      case OpenCLLIB::FMax_common:
  ------------------
  |  Branch (1910:7): [True: 0, False: 0]
  ------------------
 1911|      0|      case OpenCLLIB::FMin_common:
  ------------------
  |  Branch (1911:7): [True: 0, False: 0]
  ------------------
 1912|      0|      case OpenCLLIB::Mix:
  ------------------
  |  Branch (1912:7): [True: 0, False: 0]
  ------------------
 1913|      0|      case OpenCLLIB::Radians:
  ------------------
  |  Branch (1913:7): [True: 0, False: 0]
  ------------------
 1914|      0|      case OpenCLLIB::Step:
  ------------------
  |  Branch (1914:7): [True: 0, False: 0]
  ------------------
 1915|      0|      case OpenCLLIB::Smoothstep:
  ------------------
  |  Branch (1915:7): [True: 0, False: 0]
  ------------------
 1916|      0|      case OpenCLLIB::Sign: {
  ------------------
  |  Branch (1916:7): [True: 0, False: 0]
  ------------------
 1917|      0|        if (!_.IsFloatScalarOrVectorType(result_type)) {
  ------------------
  |  Branch (1917:13): [True: 0, False: 0]
  ------------------
 1918|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
 1919|      0|                 << ext_inst_name() << ": "
 1920|      0|                 << "expected Result Type to be a float scalar or vector type";
 1921|      0|        }
 1922|       |
 1923|      0|        const uint32_t num_components = _.GetDimension(result_type);
 1924|      0|        if (num_components > 4 && num_components != 8 && num_components != 16) {
  ------------------
  |  Branch (1924:13): [True: 0, False: 0]
  |  Branch (1924:35): [True: 0, False: 0]
  |  Branch (1924:58): [True: 0, False: 0]
  ------------------
 1925|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
 1926|      0|                 << ext_inst_name() << ": "
 1927|      0|                 << "expected Result Type to be a scalar or a vector with 2, "
 1928|      0|                    "3, 4, 8 or 16 components";
 1929|      0|        }
 1930|       |
 1931|      0|        for (uint32_t operand_index = 4; operand_index < num_operands;
  ------------------
  |  Branch (1931:42): [True: 0, False: 0]
  ------------------
 1932|      0|             ++operand_index) {
 1933|      0|          const uint32_t operand_type = _.GetOperandTypeId(inst, operand_index);
 1934|      0|          if (result_type != operand_type) {
  ------------------
  |  Branch (1934:15): [True: 0, False: 0]
  ------------------
 1935|      0|            return _.diag(SPV_ERROR_INVALID_DATA, inst)
 1936|      0|                   << ext_inst_name() << ": "
 1937|      0|                   << "expected types of all operands to be equal to Result "
 1938|      0|                      "Type";
 1939|      0|          }
 1940|      0|        }
 1941|      0|        break;
 1942|      0|      }
 1943|       |
 1944|      0|      case OpenCLLIB::Fract:
  ------------------
  |  Branch (1944:7): [True: 0, False: 0]
  ------------------
 1945|      0|      case OpenCLLIB::Modf:
  ------------------
  |  Branch (1945:7): [True: 0, False: 0]
  ------------------
 1946|      0|      case OpenCLLIB::Sincos: {
  ------------------
  |  Branch (1946:7): [True: 0, False: 0]
  ------------------
 1947|      0|        if (!_.IsFloatScalarOrVectorType(result_type)) {
  ------------------
  |  Branch (1947:13): [True: 0, False: 0]
  ------------------
 1948|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
 1949|      0|                 << ext_inst_name() << ": "
 1950|      0|                 << "expected Result Type to be a float scalar or vector type";
 1951|      0|        }
 1952|       |
 1953|      0|        const uint32_t num_components = _.GetDimension(result_type);
 1954|      0|        if (num_components > 4 && num_components != 8 && num_components != 16) {
  ------------------
  |  Branch (1954:13): [True: 0, False: 0]
  |  Branch (1954:35): [True: 0, False: 0]
  |  Branch (1954:58): [True: 0, False: 0]
  ------------------
 1955|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
 1956|      0|                 << ext_inst_name() << ": "
 1957|      0|                 << "expected Result Type to be a scalar or a vector with 2, "
 1958|      0|                    "3, 4, 8 or 16 components";
 1959|      0|        }
 1960|       |
 1961|      0|        const uint32_t x_type = _.GetOperandTypeId(inst, 4);
 1962|      0|        if (result_type != x_type) {
  ------------------
  |  Branch (1962:13): [True: 0, False: 0]
  ------------------
 1963|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
 1964|      0|                 << ext_inst_name() << ": "
 1965|      0|                 << "expected type of operand X to be equal to Result Type";
 1966|      0|        }
 1967|       |
 1968|      0|        const uint32_t p_type = _.GetOperandTypeId(inst, 5);
 1969|      0|        spv::StorageClass p_storage_class;
 1970|      0|        uint32_t p_data_type = 0;
 1971|      0|        if (!_.GetPointerTypeInfo(p_type, &p_data_type, &p_storage_class)) {
  ------------------
  |  Branch (1971:13): [True: 0, False: 0]
  ------------------
 1972|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
 1973|      0|                 << ext_inst_name() << ": "
 1974|      0|                 << "expected the last operand to be a pointer";
 1975|      0|        }
 1976|       |
 1977|      0|        if (p_storage_class != spv::StorageClass::Generic &&
  ------------------
  |  Branch (1977:13): [True: 0, False: 0]
  ------------------
 1978|      0|            p_storage_class != spv::StorageClass::CrossWorkgroup &&
  ------------------
  |  Branch (1978:13): [True: 0, False: 0]
  ------------------
 1979|      0|            p_storage_class != spv::StorageClass::Workgroup &&
  ------------------
  |  Branch (1979:13): [True: 0, False: 0]
  ------------------
 1980|      0|            p_storage_class != spv::StorageClass::Function) {
  ------------------
  |  Branch (1980:13): [True: 0, False: 0]
  ------------------
 1981|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
 1982|      0|                 << ext_inst_name() << ": "
 1983|      0|                 << "expected storage class of the pointer to be Generic, "
 1984|      0|                    "CrossWorkgroup, Workgroup or Function";
 1985|      0|        }
 1986|       |
 1987|      0|        if (result_type != p_data_type) {
  ------------------
  |  Branch (1987:13): [True: 0, False: 0]
  ------------------
 1988|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
 1989|      0|                 << ext_inst_name() << ": "
 1990|      0|                 << "expected data type of the pointer to be equal to Result "
 1991|      0|                    "Type";
 1992|      0|        }
 1993|      0|        break;
 1994|      0|      }
 1995|       |
 1996|      0|      case OpenCLLIB::Frexp:
  ------------------
  |  Branch (1996:7): [True: 0, False: 0]
  ------------------
 1997|      0|      case OpenCLLIB::Lgamma_r:
  ------------------
  |  Branch (1997:7): [True: 0, False: 0]
  ------------------
 1998|      0|      case OpenCLLIB::Remquo: {
  ------------------
  |  Branch (1998:7): [True: 0, False: 0]
  ------------------
 1999|      0|        if (!_.IsFloatScalarOrVectorType(result_type)) {
  ------------------
  |  Branch (1999:13): [True: 0, False: 0]
  ------------------
 2000|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
 2001|      0|                 << ext_inst_name() << ": "
 2002|      0|                 << "expected Result Type to be a float scalar or vector type";
 2003|      0|        }
 2004|       |
 2005|      0|        const uint32_t num_components = _.GetDimension(result_type);
 2006|      0|        if (num_components > 4 && num_components != 8 && num_components != 16) {
  ------------------
  |  Branch (2006:13): [True: 0, False: 0]
  |  Branch (2006:35): [True: 0, False: 0]
  |  Branch (2006:58): [True: 0, False: 0]
  ------------------
 2007|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
 2008|      0|                 << ext_inst_name() << ": "
 2009|      0|                 << "expected Result Type to be a scalar or a vector with 2, "
 2010|      0|                    "3, 4, 8 or 16 components";
 2011|      0|        }
 2012|       |
 2013|      0|        uint32_t operand_index = 4;
 2014|      0|        const uint32_t x_type = _.GetOperandTypeId(inst, operand_index++);
 2015|      0|        if (result_type != x_type) {
  ------------------
  |  Branch (2015:13): [True: 0, False: 0]
  ------------------
 2016|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
 2017|      0|                 << ext_inst_name() << ": "
 2018|      0|                 << "expected type of operand X to be equal to Result Type";
 2019|      0|        }
 2020|       |
 2021|      0|        if (ext_inst_key == OpenCLLIB::Remquo) {
  ------------------
  |  Branch (2021:13): [True: 0, False: 0]
  ------------------
 2022|      0|          const uint32_t y_type = _.GetOperandTypeId(inst, operand_index++);
 2023|      0|          if (result_type != y_type) {
  ------------------
  |  Branch (2023:15): [True: 0, False: 0]
  ------------------
 2024|      0|            return _.diag(SPV_ERROR_INVALID_DATA, inst)
 2025|      0|                   << ext_inst_name() << ": "
 2026|      0|                   << "expected type of operand Y to be equal to Result Type";
 2027|      0|          }
 2028|      0|        }
 2029|       |
 2030|      0|        const uint32_t p_type = _.GetOperandTypeId(inst, operand_index++);
 2031|      0|        spv::StorageClass p_storage_class;
 2032|      0|        uint32_t p_data_type = 0;
 2033|      0|        if (!_.GetPointerTypeInfo(p_type, &p_data_type, &p_storage_class)) {
  ------------------
  |  Branch (2033:13): [True: 0, False: 0]
  ------------------
 2034|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
 2035|      0|                 << ext_inst_name() << ": "
 2036|      0|                 << "expected the last operand to be a pointer";
 2037|      0|        }
 2038|       |
 2039|      0|        if (p_storage_class != spv::StorageClass::Generic &&
  ------------------
  |  Branch (2039:13): [True: 0, False: 0]
  ------------------
 2040|      0|            p_storage_class != spv::StorageClass::CrossWorkgroup &&
  ------------------
  |  Branch (2040:13): [True: 0, False: 0]
  ------------------
 2041|      0|            p_storage_class != spv::StorageClass::Workgroup &&
  ------------------
  |  Branch (2041:13): [True: 0, False: 0]
  ------------------
 2042|      0|            p_storage_class != spv::StorageClass::Function) {
  ------------------
  |  Branch (2042:13): [True: 0, False: 0]
  ------------------
 2043|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
 2044|      0|                 << ext_inst_name() << ": "
 2045|      0|                 << "expected storage class of the pointer to be Generic, "
 2046|      0|                    "CrossWorkgroup, Workgroup or Function";
 2047|      0|        }
 2048|       |
 2049|      0|        if (!_.IsIntScalarOrVectorType(p_data_type) ||
  ------------------
  |  Branch (2049:13): [True: 0, False: 0]
  ------------------
 2050|      0|            _.GetBitWidth(p_data_type) != 32) {
  ------------------
  |  Branch (2050:13): [True: 0, False: 0]
  ------------------
 2051|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
 2052|      0|                 << ext_inst_name() << ": "
 2053|      0|                 << "expected data type of the pointer to be a 32-bit int "
 2054|      0|                    "scalar or vector type";
 2055|      0|        }
 2056|       |
 2057|      0|        if (_.GetDimension(p_data_type) != num_components) {
  ------------------
  |  Branch (2057:13): [True: 0, False: 0]
  ------------------
 2058|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
 2059|      0|                 << ext_inst_name() << ": "
 2060|      0|                 << "expected data type of the pointer to have the same number "
 2061|      0|                    "of components as Result Type";
 2062|      0|        }
 2063|      0|        break;
 2064|      0|      }
 2065|       |
 2066|      0|      case OpenCLLIB::Ilogb: {
  ------------------
  |  Branch (2066:7): [True: 0, False: 0]
  ------------------
 2067|      0|        if (!_.IsIntScalarOrVectorType(result_type) ||
  ------------------
  |  Branch (2067:13): [True: 0, False: 0]
  ------------------
 2068|      0|            _.GetBitWidth(result_type) != 32) {
  ------------------
  |  Branch (2068:13): [True: 0, False: 0]
  ------------------
 2069|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
 2070|      0|                 << ext_inst_name() << ": "
 2071|      0|                 << "expected Result Type to be a 32-bit int scalar or vector "
 2072|      0|                    "type";
 2073|      0|        }
 2074|       |
 2075|      0|        const uint32_t num_components = _.GetDimension(result_type);
 2076|      0|        if (num_components > 4 && num_components != 8 && num_components != 16) {
  ------------------
  |  Branch (2076:13): [True: 0, False: 0]
  |  Branch (2076:35): [True: 0, False: 0]
  |  Branch (2076:58): [True: 0, False: 0]
  ------------------
 2077|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
 2078|      0|                 << ext_inst_name() << ": "
 2079|      0|                 << "expected Result Type to be a scalar or a vector with 2, "
 2080|      0|                    "3, 4, 8 or 16 components";
 2081|      0|        }
 2082|       |
 2083|      0|        const uint32_t x_type = _.GetOperandTypeId(inst, 4);
 2084|      0|        if (!_.IsFloatScalarOrVectorType(x_type)) {
  ------------------
  |  Branch (2084:13): [True: 0, False: 0]
  ------------------
 2085|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
 2086|      0|                 << ext_inst_name() << ": "
 2087|      0|                 << "expected operand X to be a float scalar or vector";
 2088|      0|        }
 2089|       |
 2090|      0|        if (_.GetDimension(x_type) != num_components) {
  ------------------
  |  Branch (2090:13): [True: 0, False: 0]
  ------------------
 2091|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
 2092|      0|                 << ext_inst_name() << ": "
 2093|      0|                 << "expected operand X to have the same number of components "
 2094|      0|                    "as Result Type";
 2095|      0|        }
 2096|      0|        break;
 2097|      0|      }
 2098|       |
 2099|      0|      case OpenCLLIB::Ldexp:
  ------------------
  |  Branch (2099:7): [True: 0, False: 0]
  ------------------
 2100|      0|      case OpenCLLIB::Pown:
  ------------------
  |  Branch (2100:7): [True: 0, False: 0]
  ------------------
 2101|      0|      case OpenCLLIB::Rootn: {
  ------------------
  |  Branch (2101:7): [True: 0, False: 0]
  ------------------
 2102|      0|        if (!_.IsFloatScalarOrVectorType(result_type)) {
  ------------------
  |  Branch (2102:13): [True: 0, False: 0]
  ------------------
 2103|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
 2104|      0|                 << ext_inst_name() << ": "
 2105|      0|                 << "expected Result Type to be a float scalar or vector type";
 2106|      0|        }
 2107|       |
 2108|      0|        const uint32_t num_components = _.GetDimension(result_type);
 2109|      0|        if (num_components > 4 && num_components != 8 && num_components != 16) {
  ------------------
  |  Branch (2109:13): [True: 0, False: 0]
  |  Branch (2109:35): [True: 0, False: 0]
  |  Branch (2109:58): [True: 0, False: 0]
  ------------------
 2110|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
 2111|      0|                 << ext_inst_name() << ": "
 2112|      0|                 << "expected Result Type to be a scalar or a vector with 2, "
 2113|      0|                    "3, 4, 8 or 16 components";
 2114|      0|        }
 2115|       |
 2116|      0|        const uint32_t x_type = _.GetOperandTypeId(inst, 4);
 2117|      0|        if (result_type != x_type) {
  ------------------
  |  Branch (2117:13): [True: 0, False: 0]
  ------------------
 2118|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
 2119|      0|                 << ext_inst_name() << ": "
 2120|      0|                 << "expected type of operand X to be equal to Result Type";
 2121|      0|        }
 2122|       |
 2123|      0|        const uint32_t exp_type = _.GetOperandTypeId(inst, 5);
 2124|      0|        if (!_.IsIntScalarOrVectorType(exp_type) ||
  ------------------
  |  Branch (2124:13): [True: 0, False: 0]
  ------------------
 2125|      0|            _.GetBitWidth(exp_type) != 32) {
  ------------------
  |  Branch (2125:13): [True: 0, False: 0]
  ------------------
 2126|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
 2127|      0|                 << ext_inst_name() << ": "
 2128|      0|                 << "expected the exponent to be a 32-bit int scalar or vector";
 2129|      0|        }
 2130|       |
 2131|      0|        if (_.GetDimension(exp_type) != num_components) {
  ------------------
  |  Branch (2131:13): [True: 0, False: 0]
  ------------------
 2132|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
 2133|      0|                 << ext_inst_name() << ": "
 2134|      0|                 << "expected the exponent to have the same number of "
 2135|      0|                    "components as Result Type";
 2136|      0|        }
 2137|      0|        break;
 2138|      0|      }
 2139|       |
 2140|      0|      case OpenCLLIB::Nan: {
  ------------------
  |  Branch (2140:7): [True: 0, False: 0]
  ------------------
 2141|      0|        if (!_.IsFloatScalarOrVectorType(result_type)) {
  ------------------
  |  Branch (2141:13): [True: 0, False: 0]
  ------------------
 2142|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
 2143|      0|                 << ext_inst_name() << ": "
 2144|      0|                 << "expected Result Type to be a float scalar or vector type";
 2145|      0|        }
 2146|       |
 2147|      0|        const uint32_t num_components = _.GetDimension(result_type);
 2148|      0|        if (num_components > 4 && num_components != 8 && num_components != 16) {
  ------------------
  |  Branch (2148:13): [True: 0, False: 0]
  |  Branch (2148:35): [True: 0, False: 0]
  |  Branch (2148:58): [True: 0, False: 0]
  ------------------
 2149|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
 2150|      0|                 << ext_inst_name() << ": "
 2151|      0|                 << "expected Result Type to be a scalar or a vector with 2, "
 2152|      0|                    "3, 4, 8 or 16 components";
 2153|      0|        }
 2154|       |
 2155|      0|        const uint32_t nancode_type = _.GetOperandTypeId(inst, 4);
 2156|      0|        if (!_.IsIntScalarOrVectorType(nancode_type)) {
  ------------------
  |  Branch (2156:13): [True: 0, False: 0]
  ------------------
 2157|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
 2158|      0|                 << ext_inst_name() << ": "
 2159|      0|                 << "expected Nancode to be an int scalar or vector type";
 2160|      0|        }
 2161|       |
 2162|      0|        if (_.GetDimension(nancode_type) != num_components) {
  ------------------
  |  Branch (2162:13): [True: 0, False: 0]
  ------------------
 2163|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
 2164|      0|                 << ext_inst_name() << ": "
 2165|      0|                 << "expected Nancode to have the same number of components as "
 2166|      0|                    "Result Type";
 2167|      0|        }
 2168|       |
 2169|      0|        if (_.GetBitWidth(result_type) != _.GetBitWidth(nancode_type)) {
  ------------------
  |  Branch (2169:13): [True: 0, False: 0]
  ------------------
 2170|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
 2171|      0|                 << ext_inst_name() << ": "
 2172|      0|                 << "expected Nancode to have the same bit width as Result "
 2173|      0|                    "Type";
 2174|      0|        }
 2175|      0|        break;
 2176|      0|      }
 2177|       |
 2178|      0|      case OpenCLLIB::SAbs:
  ------------------
  |  Branch (2178:7): [True: 0, False: 0]
  ------------------
 2179|      0|      case OpenCLLIB::SAbs_diff:
  ------------------
  |  Branch (2179:7): [True: 0, False: 0]
  ------------------
 2180|      0|      case OpenCLLIB::SAdd_sat:
  ------------------
  |  Branch (2180:7): [True: 0, False: 0]
  ------------------
 2181|      0|      case OpenCLLIB::UAdd_sat:
  ------------------
  |  Branch (2181:7): [True: 0, False: 0]
  ------------------
 2182|      0|      case OpenCLLIB::SHadd:
  ------------------
  |  Branch (2182:7): [True: 0, False: 0]
  ------------------
 2183|      0|      case OpenCLLIB::UHadd:
  ------------------
  |  Branch (2183:7): [True: 0, False: 0]
  ------------------
 2184|      0|      case OpenCLLIB::SRhadd:
  ------------------
  |  Branch (2184:7): [True: 0, False: 0]
  ------------------
 2185|      0|      case OpenCLLIB::URhadd:
  ------------------
  |  Branch (2185:7): [True: 0, False: 0]
  ------------------
 2186|      0|      case OpenCLLIB::SClamp:
  ------------------
  |  Branch (2186:7): [True: 0, False: 0]
  ------------------
 2187|      0|      case OpenCLLIB::UClamp:
  ------------------
  |  Branch (2187:7): [True: 0, False: 0]
  ------------------
 2188|      0|      case OpenCLLIB::Clz:
  ------------------
  |  Branch (2188:7): [True: 0, False: 0]
  ------------------
 2189|      0|      case OpenCLLIB::Ctz:
  ------------------
  |  Branch (2189:7): [True: 0, False: 0]
  ------------------
 2190|      0|      case OpenCLLIB::SMad_hi:
  ------------------
  |  Branch (2190:7): [True: 0, False: 0]
  ------------------
 2191|      0|      case OpenCLLIB::UMad_sat:
  ------------------
  |  Branch (2191:7): [True: 0, False: 0]
  ------------------
 2192|      0|      case OpenCLLIB::SMad_sat:
  ------------------
  |  Branch (2192:7): [True: 0, False: 0]
  ------------------
 2193|      0|      case OpenCLLIB::SMax:
  ------------------
  |  Branch (2193:7): [True: 0, False: 0]
  ------------------
 2194|      0|      case OpenCLLIB::UMax:
  ------------------
  |  Branch (2194:7): [True: 0, False: 0]
  ------------------
 2195|      0|      case OpenCLLIB::SMin:
  ------------------
  |  Branch (2195:7): [True: 0, False: 0]
  ------------------
 2196|      0|      case OpenCLLIB::UMin:
  ------------------
  |  Branch (2196:7): [True: 0, False: 0]
  ------------------
 2197|      0|      case OpenCLLIB::SMul_hi:
  ------------------
  |  Branch (2197:7): [True: 0, False: 0]
  ------------------
 2198|      0|      case OpenCLLIB::Rotate:
  ------------------
  |  Branch (2198:7): [True: 0, False: 0]
  ------------------
 2199|      0|      case OpenCLLIB::SSub_sat:
  ------------------
  |  Branch (2199:7): [True: 0, False: 0]
  ------------------
 2200|      0|      case OpenCLLIB::USub_sat:
  ------------------
  |  Branch (2200:7): [True: 0, False: 0]
  ------------------
 2201|      0|      case OpenCLLIB::Popcount:
  ------------------
  |  Branch (2201:7): [True: 0, False: 0]
  ------------------
 2202|      0|      case OpenCLLIB::UAbs:
  ------------------
  |  Branch (2202:7): [True: 0, False: 0]
  ------------------
 2203|      0|      case OpenCLLIB::UAbs_diff:
  ------------------
  |  Branch (2203:7): [True: 0, False: 0]
  ------------------
 2204|      0|      case OpenCLLIB::UMul_hi:
  ------------------
  |  Branch (2204:7): [True: 0, False: 0]
  ------------------
 2205|      0|      case OpenCLLIB::UMad_hi: {
  ------------------
  |  Branch (2205:7): [True: 0, False: 0]
  ------------------
 2206|      0|        if (!_.IsIntScalarOrVectorType(result_type)) {
  ------------------
  |  Branch (2206:13): [True: 0, False: 0]
  ------------------
 2207|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
 2208|      0|                 << ext_inst_name() << ": "
 2209|      0|                 << "expected Result Type to be an int scalar or vector type";
 2210|      0|        }
 2211|       |
 2212|      0|        const uint32_t num_components = _.GetDimension(result_type);
 2213|      0|        if (num_components > 4 && num_components != 8 && num_components != 16) {
  ------------------
  |  Branch (2213:13): [True: 0, False: 0]
  |  Branch (2213:35): [True: 0, False: 0]
  |  Branch (2213:58): [True: 0, False: 0]
  ------------------
 2214|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
 2215|      0|                 << ext_inst_name() << ": "
 2216|      0|                 << "expected Result Type to be a scalar or a vector with 2, "
 2217|      0|                    "3, 4, 8 or 16 components";
 2218|      0|        }
 2219|       |
 2220|      0|        for (uint32_t operand_index = 4; operand_index < num_operands;
  ------------------
  |  Branch (2220:42): [True: 0, False: 0]
  ------------------
 2221|      0|             ++operand_index) {
 2222|      0|          const uint32_t operand_type = _.GetOperandTypeId(inst, operand_index);
 2223|      0|          if (result_type != operand_type) {
  ------------------
  |  Branch (2223:15): [True: 0, False: 0]
  ------------------
 2224|      0|            return _.diag(SPV_ERROR_INVALID_DATA, inst)
 2225|      0|                   << ext_inst_name() << ": "
 2226|      0|                   << "expected types of all operands to be equal to Result "
 2227|      0|                      "Type";
 2228|      0|          }
 2229|      0|        }
 2230|      0|        break;
 2231|      0|      }
 2232|       |
 2233|      0|      case OpenCLLIB::U_Upsample:
  ------------------
  |  Branch (2233:7): [True: 0, False: 0]
  ------------------
 2234|      0|      case OpenCLLIB::S_Upsample: {
  ------------------
  |  Branch (2234:7): [True: 0, False: 0]
  ------------------
 2235|      0|        if (!_.IsIntScalarOrVectorType(result_type)) {
  ------------------
  |  Branch (2235:13): [True: 0, False: 0]
  ------------------
 2236|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
 2237|      0|                 << ext_inst_name() << ": "
 2238|      0|                 << "expected Result Type to be an int scalar or vector "
 2239|      0|                    "type";
 2240|      0|        }
 2241|       |
 2242|      0|        const uint32_t result_num_components = _.GetDimension(result_type);
 2243|      0|        if (result_num_components > 4 && result_num_components != 8 &&
  ------------------
  |  Branch (2243:13): [True: 0, False: 0]
  |  Branch (2243:42): [True: 0, False: 0]
  ------------------
 2244|      0|            result_num_components != 16) {
  ------------------
  |  Branch (2244:13): [True: 0, False: 0]
  ------------------
 2245|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
 2246|      0|                 << ext_inst_name() << ": "
 2247|      0|                 << "expected Result Type to be a scalar or a vector with 2, "
 2248|      0|                    "3, 4, 8 or 16 components";
 2249|      0|        }
 2250|       |
 2251|      0|        const uint32_t result_bit_width = _.GetBitWidth(result_type);
 2252|      0|        if (result_bit_width != 16 && result_bit_width != 32 &&
  ------------------
  |  Branch (2252:13): [True: 0, False: 0]
  |  Branch (2252:39): [True: 0, False: 0]
  ------------------
 2253|      0|            result_bit_width != 64) {
  ------------------
  |  Branch (2253:13): [True: 0, False: 0]
  ------------------
 2254|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
 2255|      0|                 << ext_inst_name() << ": "
 2256|      0|                 << "expected bit width of Result Type components to be 16, 32 "
 2257|      0|                    "or 64";
 2258|      0|        }
 2259|       |
 2260|      0|        const uint32_t hi_type = _.GetOperandTypeId(inst, 4);
 2261|      0|        const uint32_t lo_type = _.GetOperandTypeId(inst, 5);
 2262|       |
 2263|      0|        if (hi_type != lo_type) {
  ------------------
  |  Branch (2263:13): [True: 0, False: 0]
  ------------------
 2264|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
 2265|      0|                 << ext_inst_name() << ": "
 2266|      0|                 << "expected Hi and Lo operands to have the same type";
 2267|      0|        }
 2268|       |
 2269|      0|        if (result_num_components != _.GetDimension(hi_type)) {
  ------------------
  |  Branch (2269:13): [True: 0, False: 0]
  ------------------
 2270|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
 2271|      0|                 << ext_inst_name() << ": "
 2272|      0|                 << "expected Hi and Lo operands to have the same number of "
 2273|      0|                    "components as Result Type";
 2274|      0|        }
 2275|       |
 2276|      0|        if (result_bit_width != 2 * _.GetBitWidth(hi_type)) {
  ------------------
  |  Branch (2276:13): [True: 0, False: 0]
  ------------------
 2277|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
 2278|      0|                 << ext_inst_name() << ": "
 2279|      0|                 << "expected bit width of components of Hi and Lo operands to "
 2280|      0|                    "be half of the bit width of components of Result Type";
 2281|      0|        }
 2282|      0|        break;
 2283|      0|      }
 2284|       |
 2285|      0|      case OpenCLLIB::SMad24:
  ------------------
  |  Branch (2285:7): [True: 0, False: 0]
  ------------------
 2286|      0|      case OpenCLLIB::UMad24:
  ------------------
  |  Branch (2286:7): [True: 0, False: 0]
  ------------------
 2287|      0|      case OpenCLLIB::SMul24:
  ------------------
  |  Branch (2287:7): [True: 0, False: 0]
  ------------------
 2288|      0|      case OpenCLLIB::UMul24: {
  ------------------
  |  Branch (2288:7): [True: 0, False: 0]
  ------------------
 2289|      0|        if (!_.IsIntScalarOrVectorType(result_type) ||
  ------------------
  |  Branch (2289:13): [True: 0, False: 0]
  ------------------
 2290|      0|            _.GetBitWidth(result_type) != 32) {
  ------------------
  |  Branch (2290:13): [True: 0, False: 0]
  ------------------
 2291|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
 2292|      0|                 << ext_inst_name() << ": "
 2293|      0|                 << "expected Result Type to be a 32-bit int scalar or vector "
 2294|      0|                    "type";
 2295|      0|        }
 2296|       |
 2297|      0|        const uint32_t num_components = _.GetDimension(result_type);
 2298|      0|        if (num_components > 4 && num_components != 8 && num_components != 16) {
  ------------------
  |  Branch (2298:13): [True: 0, False: 0]
  |  Branch (2298:35): [True: 0, False: 0]
  |  Branch (2298:58): [True: 0, False: 0]
  ------------------
 2299|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
 2300|      0|                 << ext_inst_name() << ": "
 2301|      0|                 << "expected Result Type to be a scalar or a vector with 2, "
 2302|      0|                    "3, 4, 8 or 16 components";
 2303|      0|        }
 2304|       |
 2305|      0|        for (uint32_t operand_index = 4; operand_index < num_operands;
  ------------------
  |  Branch (2305:42): [True: 0, False: 0]
  ------------------
 2306|      0|             ++operand_index) {
 2307|      0|          const uint32_t operand_type = _.GetOperandTypeId(inst, operand_index);
 2308|      0|          if (result_type != operand_type) {
  ------------------
  |  Branch (2308:15): [True: 0, False: 0]
  ------------------
 2309|      0|            return _.diag(SPV_ERROR_INVALID_DATA, inst)
 2310|      0|                   << ext_inst_name() << ": "
 2311|      0|                   << "expected types of all operands to be equal to Result "
 2312|      0|                      "Type";
 2313|      0|          }
 2314|      0|        }
 2315|      0|        break;
 2316|      0|      }
 2317|       |
 2318|      0|      case OpenCLLIB::Cross: {
  ------------------
  |  Branch (2318:7): [True: 0, False: 0]
  ------------------
 2319|      0|        if (!_.IsFloatVectorType(result_type)) {
  ------------------
  |  Branch (2319:13): [True: 0, False: 0]
  ------------------
 2320|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
 2321|      0|                 << ext_inst_name() << ": "
 2322|      0|                 << "expected Result Type to be a float vector type";
 2323|      0|        }
 2324|       |
 2325|      0|        const uint32_t num_components = _.GetDimension(result_type);
 2326|      0|        if (num_components != 3 && num_components != 4) {
  ------------------
  |  Branch (2326:13): [True: 0, False: 0]
  |  Branch (2326:36): [True: 0, False: 0]
  ------------------
 2327|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
 2328|      0|                 << ext_inst_name() << ": "
 2329|      0|                 << "expected Result Type to have 3 or 4 components";
 2330|      0|        }
 2331|       |
 2332|      0|        const uint32_t x_type = _.GetOperandTypeId(inst, 4);
 2333|      0|        const uint32_t y_type = _.GetOperandTypeId(inst, 5);
 2334|       |
 2335|      0|        if (x_type != result_type) {
  ------------------
  |  Branch (2335:13): [True: 0, False: 0]
  ------------------
 2336|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
 2337|      0|                 << ext_inst_name() << ": "
 2338|      0|                 << "expected operand X type to be equal to Result Type";
 2339|      0|        }
 2340|       |
 2341|      0|        if (y_type != result_type) {
  ------------------
  |  Branch (2341:13): [True: 0, False: 0]
  ------------------
 2342|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
 2343|      0|                 << ext_inst_name() << ": "
 2344|      0|                 << "expected operand Y type to be equal to Result Type";
 2345|      0|        }
 2346|      0|        break;
 2347|      0|      }
 2348|       |
 2349|      0|      case OpenCLLIB::Distance:
  ------------------
  |  Branch (2349:7): [True: 0, False: 0]
  ------------------
 2350|      0|      case OpenCLLIB::Fast_distance: {
  ------------------
  |  Branch (2350:7): [True: 0, False: 0]
  ------------------
 2351|      0|        if (!_.IsFloatScalarType(result_type)) {
  ------------------
  |  Branch (2351:13): [True: 0, False: 0]
  ------------------
 2352|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
 2353|      0|                 << ext_inst_name() << ": "
 2354|      0|                 << "expected Result Type to be a float scalar type";
 2355|      0|        }
 2356|       |
 2357|      0|        const uint32_t p0_type = _.GetOperandTypeId(inst, 4);
 2358|      0|        if (!_.IsFloatScalarOrVectorType(p0_type)) {
  ------------------
  |  Branch (2358:13): [True: 0, False: 0]
  ------------------
 2359|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
 2360|      0|                 << ext_inst_name() << ": "
 2361|      0|                 << "expected operand P0 to be of float scalar or vector type";
 2362|      0|        }
 2363|       |
 2364|      0|        const uint32_t num_components = _.GetDimension(p0_type);
 2365|      0|        if (num_components > 4) {
  ------------------
  |  Branch (2365:13): [True: 0, False: 0]
  ------------------
 2366|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
 2367|      0|                 << ext_inst_name() << ": "
 2368|      0|                 << "expected operand P0 to have no more than 4 components";
 2369|      0|        }
 2370|       |
 2371|      0|        if (result_type != _.GetComponentType(p0_type)) {
  ------------------
  |  Branch (2371:13): [True: 0, False: 0]
  ------------------
 2372|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
 2373|      0|                 << ext_inst_name() << ": "
 2374|      0|                 << "expected operand P0 component type to be equal to "
 2375|      0|                 << "Result Type";
 2376|      0|        }
 2377|       |
 2378|      0|        const uint32_t p1_type = _.GetOperandTypeId(inst, 5);
 2379|      0|        if (p0_type != p1_type) {
  ------------------
  |  Branch (2379:13): [True: 0, False: 0]
  ------------------
 2380|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
 2381|      0|                 << ext_inst_name() << ": "
 2382|      0|                 << "expected operands P0 and P1 to be of the same type";
 2383|      0|        }
 2384|      0|        break;
 2385|      0|      }
 2386|       |
 2387|      0|      case OpenCLLIB::Length:
  ------------------
  |  Branch (2387:7): [True: 0, False: 0]
  ------------------
 2388|      0|      case OpenCLLIB::Fast_length: {
  ------------------
  |  Branch (2388:7): [True: 0, False: 0]
  ------------------
 2389|      0|        if (!_.IsFloatScalarType(result_type)) {
  ------------------
  |  Branch (2389:13): [True: 0, False: 0]
  ------------------
 2390|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
 2391|      0|                 << ext_inst_name() << ": "
 2392|      0|                 << "expected Result Type to be a float scalar type";
 2393|      0|        }
 2394|       |
 2395|      0|        const uint32_t p_type = _.GetOperandTypeId(inst, 4);
 2396|      0|        if (!_.IsFloatScalarOrVectorType(p_type)) {
  ------------------
  |  Branch (2396:13): [True: 0, False: 0]
  ------------------
 2397|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
 2398|      0|                 << ext_inst_name() << ": "
 2399|      0|                 << "expected operand P to be a float scalar or vector";
 2400|      0|        }
 2401|       |
 2402|      0|        const uint32_t num_components = _.GetDimension(p_type);
 2403|      0|        if (num_components > 4) {
  ------------------
  |  Branch (2403:13): [True: 0, False: 0]
  ------------------
 2404|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
 2405|      0|                 << ext_inst_name() << ": "
 2406|      0|                 << "expected operand P to have no more than 4 components";
 2407|      0|        }
 2408|       |
 2409|      0|        if (result_type != _.GetComponentType(p_type)) {
  ------------------
  |  Branch (2409:13): [True: 0, False: 0]
  ------------------
 2410|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
 2411|      0|                 << ext_inst_name() << ": "
 2412|      0|                 << "expected operand P component type to be equal to Result "
 2413|      0|                    "Type";
 2414|      0|        }
 2415|      0|        break;
 2416|      0|      }
 2417|       |
 2418|      0|      case OpenCLLIB::Normalize:
  ------------------
  |  Branch (2418:7): [True: 0, False: 0]
  ------------------
 2419|      0|      case OpenCLLIB::Fast_normalize: {
  ------------------
  |  Branch (2419:7): [True: 0, False: 0]
  ------------------
 2420|      0|        if (!_.IsFloatScalarOrVectorType(result_type)) {
  ------------------
  |  Branch (2420:13): [True: 0, False: 0]
  ------------------
 2421|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
 2422|      0|                 << ext_inst_name() << ": "
 2423|      0|                 << "expected Result Type to be a float scalar or vector type";
 2424|      0|        }
 2425|       |
 2426|      0|        const uint32_t num_components = _.GetDimension(result_type);
 2427|      0|        if (num_components > 4) {
  ------------------
  |  Branch (2427:13): [True: 0, False: 0]
  ------------------
 2428|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
 2429|      0|                 << ext_inst_name() << ": "
 2430|      0|                 << "expected Result Type to have no more than 4 components";
 2431|      0|        }
 2432|       |
 2433|      0|        const uint32_t p_type = _.GetOperandTypeId(inst, 4);
 2434|      0|        if (p_type != result_type) {
  ------------------
  |  Branch (2434:13): [True: 0, False: 0]
  ------------------
 2435|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
 2436|      0|                 << ext_inst_name() << ": "
 2437|      0|                 << "expected operand P type to be equal to Result Type";
 2438|      0|        }
 2439|      0|        break;
 2440|      0|      }
 2441|       |
 2442|      0|      case OpenCLLIB::Bitselect: {
  ------------------
  |  Branch (2442:7): [True: 0, False: 0]
  ------------------
 2443|      0|        if (!_.IsFloatScalarOrVectorType(result_type) &&
  ------------------
  |  Branch (2443:13): [True: 0, False: 0]
  ------------------
 2444|      0|            !_.IsIntScalarOrVectorType(result_type)) {
  ------------------
  |  Branch (2444:13): [True: 0, False: 0]
  ------------------
 2445|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
 2446|      0|                 << ext_inst_name() << ": "
 2447|      0|                 << "expected Result Type to be an int or float scalar or "
 2448|      0|                    "vector type";
 2449|      0|        }
 2450|       |
 2451|      0|        const uint32_t num_components = _.GetDimension(result_type);
 2452|      0|        if (num_components > 4 && num_components != 8 && num_components != 16) {
  ------------------
  |  Branch (2452:13): [True: 0, False: 0]
  |  Branch (2452:35): [True: 0, False: 0]
  |  Branch (2452:58): [True: 0, False: 0]
  ------------------
 2453|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
 2454|      0|                 << ext_inst_name() << ": "
 2455|      0|                 << "expected Result Type to be a scalar or a vector with 2, "
 2456|      0|                    "3, 4, 8 or 16 components";
 2457|      0|        }
 2458|       |
 2459|      0|        for (uint32_t operand_index = 4; operand_index < num_operands;
  ------------------
  |  Branch (2459:42): [True: 0, False: 0]
  ------------------
 2460|      0|             ++operand_index) {
 2461|      0|          const uint32_t operand_type = _.GetOperandTypeId(inst, operand_index);
 2462|      0|          if (result_type != operand_type) {
  ------------------
  |  Branch (2462:15): [True: 0, False: 0]
  ------------------
 2463|      0|            return _.diag(SPV_ERROR_INVALID_DATA, inst)
 2464|      0|                   << ext_inst_name() << ": "
 2465|      0|                   << "expected types of all operands to be equal to Result "
 2466|      0|                      "Type";
 2467|      0|          }
 2468|      0|        }
 2469|      0|        break;
 2470|      0|      }
 2471|       |
 2472|      0|      case OpenCLLIB::Select: {
  ------------------
  |  Branch (2472:7): [True: 0, False: 0]
  ------------------
 2473|      0|        if (!_.IsFloatScalarOrVectorType(result_type) &&
  ------------------
  |  Branch (2473:13): [True: 0, False: 0]
  ------------------
 2474|      0|            !_.IsIntScalarOrVectorType(result_type)) {
  ------------------
  |  Branch (2474:13): [True: 0, False: 0]
  ------------------
 2475|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
 2476|      0|                 << ext_inst_name() << ": "
 2477|      0|                 << "expected Result Type to be an int or float scalar or "
 2478|      0|                    "vector type";
 2479|      0|        }
 2480|       |
 2481|      0|        const uint32_t num_components = _.GetDimension(result_type);
 2482|      0|        if (num_components > 4 && num_components != 8 && num_components != 16) {
  ------------------
  |  Branch (2482:13): [True: 0, False: 0]
  |  Branch (2482:35): [True: 0, False: 0]
  |  Branch (2482:58): [True: 0, False: 0]
  ------------------
 2483|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
 2484|      0|                 << ext_inst_name() << ": "
 2485|      0|                 << "expected Result Type to be a scalar or a vector with 2, "
 2486|      0|                    "3, 4, 8 or 16 components";
 2487|      0|        }
 2488|       |
 2489|      0|        const uint32_t a_type = _.GetOperandTypeId(inst, 4);
 2490|      0|        const uint32_t b_type = _.GetOperandTypeId(inst, 5);
 2491|      0|        const uint32_t c_type = _.GetOperandTypeId(inst, 6);
 2492|       |
 2493|      0|        if (result_type != a_type) {
  ------------------
  |  Branch (2493:13): [True: 0, False: 0]
  ------------------
 2494|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
 2495|      0|                 << ext_inst_name() << ": "
 2496|      0|                 << "expected operand A type to be equal to Result Type";
 2497|      0|        }
 2498|       |
 2499|      0|        if (result_type != b_type) {
  ------------------
  |  Branch (2499:13): [True: 0, False: 0]
  ------------------
 2500|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
 2501|      0|                 << ext_inst_name() << ": "
 2502|      0|                 << "expected operand B type to be equal to Result Type";
 2503|      0|        }
 2504|       |
 2505|      0|        if (!_.IsIntScalarOrVectorType(c_type)) {
  ------------------
  |  Branch (2505:13): [True: 0, False: 0]
  ------------------
 2506|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
 2507|      0|                 << ext_inst_name() << ": "
 2508|      0|                 << "expected operand C to be an int scalar or vector";
 2509|      0|        }
 2510|       |
 2511|      0|        if (num_components != _.GetDimension(c_type)) {
  ------------------
  |  Branch (2511:13): [True: 0, False: 0]
  ------------------
 2512|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
 2513|      0|                 << ext_inst_name() << ": "
 2514|      0|                 << "expected operand C to have the same number of components "
 2515|      0|                    "as Result Type";
 2516|      0|        }
 2517|       |
 2518|      0|        if (_.GetBitWidth(result_type) != _.GetBitWidth(c_type)) {
  ------------------
  |  Branch (2518:13): [True: 0, False: 0]
  ------------------
 2519|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
 2520|      0|                 << ext_inst_name() << ": "
 2521|      0|                 << "expected operand C to have the same bit width as Result "
 2522|      0|                    "Type";
 2523|      0|        }
 2524|      0|        break;
 2525|      0|      }
 2526|       |
 2527|      0|      case OpenCLLIB::Vloadn: {
  ------------------
  |  Branch (2527:7): [True: 0, False: 0]
  ------------------
 2528|      0|        if (!_.IsFloatVectorType(result_type) &&
  ------------------
  |  Branch (2528:13): [True: 0, False: 0]
  ------------------
 2529|      0|            !_.IsIntVectorType(result_type)) {
  ------------------
  |  Branch (2529:13): [True: 0, False: 0]
  ------------------
 2530|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
 2531|      0|                 << ext_inst_name() << ": "
 2532|      0|                 << "expected Result Type to be an int or float vector type";
 2533|      0|        }
 2534|       |
 2535|      0|        const uint32_t num_components = _.GetDimension(result_type);
 2536|      0|        if (num_components > 4 && num_components != 8 && num_components != 16) {
  ------------------
  |  Branch (2536:13): [True: 0, False: 0]
  |  Branch (2536:35): [True: 0, False: 0]
  |  Branch (2536:58): [True: 0, False: 0]
  ------------------
 2537|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
 2538|      0|                 << ext_inst_name() << ": "
 2539|      0|                 << "expected Result Type to have 2, 3, 4, 8 or 16 components";
 2540|      0|        }
 2541|       |
 2542|      0|        const uint32_t offset_type = _.GetOperandTypeId(inst, 4);
 2543|      0|        const uint32_t p_type = _.GetOperandTypeId(inst, 5);
 2544|       |
 2545|      0|        const uint32_t size_t_bit_width = GetSizeTBitWidth(_);
 2546|      0|        if (!size_t_bit_width) {
  ------------------
  |  Branch (2546:13): [True: 0, False: 0]
  ------------------
 2547|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
 2548|      0|                 << ext_inst_name()
 2549|      0|                 << " can only be used with physical addressing models";
 2550|      0|        }
 2551|       |
 2552|      0|        if (!_.IsIntScalarType(offset_type) ||
  ------------------
  |  Branch (2552:13): [True: 0, False: 0]
  ------------------
 2553|      0|            _.GetBitWidth(offset_type) != size_t_bit_width) {
  ------------------
  |  Branch (2553:13): [True: 0, False: 0]
  ------------------
 2554|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
 2555|      0|                 << ext_inst_name() << ": "
 2556|      0|                 << "expected operand Offset to be of type size_t ("
 2557|      0|                 << size_t_bit_width
 2558|      0|                 << "-bit integer for the addressing model used in the module)";
 2559|      0|        }
 2560|       |
 2561|      0|        spv::StorageClass p_storage_class;
 2562|      0|        uint32_t p_data_type = 0;
 2563|      0|        if (!_.GetPointerTypeInfo(p_type, &p_data_type, &p_storage_class)) {
  ------------------
  |  Branch (2563:13): [True: 0, False: 0]
  ------------------
 2564|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
 2565|      0|                 << ext_inst_name() << ": "
 2566|      0|                 << "expected operand P to be a pointer";
 2567|      0|        }
 2568|       |
 2569|      0|        if (p_storage_class != spv::StorageClass::UniformConstant &&
  ------------------
  |  Branch (2569:13): [True: 0, False: 0]
  ------------------
 2570|      0|            p_storage_class != spv::StorageClass::Generic &&
  ------------------
  |  Branch (2570:13): [True: 0, False: 0]
  ------------------
 2571|      0|            p_storage_class != spv::StorageClass::CrossWorkgroup &&
  ------------------
  |  Branch (2571:13): [True: 0, False: 0]
  ------------------
 2572|      0|            p_storage_class != spv::StorageClass::Workgroup &&
  ------------------
  |  Branch (2572:13): [True: 0, False: 0]
  ------------------
 2573|      0|            p_storage_class != spv::StorageClass::Function) {
  ------------------
  |  Branch (2573:13): [True: 0, False: 0]
  ------------------
 2574|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
 2575|      0|                 << ext_inst_name() << ": "
 2576|      0|                 << "expected operand P storage class to be UniformConstant, "
 2577|      0|                    "Generic, CrossWorkgroup, Workgroup or Function";
 2578|      0|        }
 2579|       |
 2580|      0|        if (_.GetComponentType(result_type) != p_data_type) {
  ------------------
  |  Branch (2580:13): [True: 0, False: 0]
  ------------------
 2581|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
 2582|      0|                 << ext_inst_name() << ": "
 2583|      0|                 << "expected operand P data type to be equal to component "
 2584|      0|                    "type of Result Type";
 2585|      0|        }
 2586|       |
 2587|      0|        const uint32_t n_value = inst->word(7);
 2588|      0|        if (num_components != n_value) {
  ------------------
  |  Branch (2588:13): [True: 0, False: 0]
  ------------------
 2589|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
 2590|      0|                 << ext_inst_name() << ": "
 2591|      0|                 << "expected literal N to be equal to the number of "
 2592|      0|                    "components of Result Type";
 2593|      0|        }
 2594|      0|        break;
 2595|      0|      }
 2596|       |
 2597|      0|      case OpenCLLIB::Vstoren: {
  ------------------
  |  Branch (2597:7): [True: 0, False: 0]
  ------------------
 2598|      0|        if (_.GetIdOpcode(result_type) != spv::Op::OpTypeVoid) {
  ------------------
  |  Branch (2598:13): [True: 0, False: 0]
  ------------------
 2599|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
 2600|      0|                 << ext_inst_name() << ": expected Result Type to be void";
 2601|      0|        }
 2602|       |
 2603|      0|        const uint32_t data_type = _.GetOperandTypeId(inst, 4);
 2604|      0|        const uint32_t offset_type = _.GetOperandTypeId(inst, 5);
 2605|      0|        const uint32_t p_type = _.GetOperandTypeId(inst, 6);
 2606|       |
 2607|      0|        if (!_.IsFloatVectorType(data_type) && !_.IsIntVectorType(data_type)) {
  ------------------
  |  Branch (2607:13): [True: 0, False: 0]
  |  Branch (2607:48): [True: 0, False: 0]
  ------------------
 2608|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
 2609|      0|                 << ext_inst_name() << ": "
 2610|      0|                 << "expected Data to be an int or float vector";
 2611|      0|        }
 2612|       |
 2613|      0|        const uint32_t num_components = _.GetDimension(data_type);
 2614|      0|        if (num_components > 4 && num_components != 8 && num_components != 16) {
  ------------------
  |  Branch (2614:13): [True: 0, False: 0]
  |  Branch (2614:35): [True: 0, False: 0]
  |  Branch (2614:58): [True: 0, False: 0]
  ------------------
 2615|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
 2616|      0|                 << ext_inst_name() << ": "
 2617|      0|                 << "expected Data to have 2, 3, 4, 8 or 16 components";
 2618|      0|        }
 2619|       |
 2620|      0|        const uint32_t size_t_bit_width = GetSizeTBitWidth(_);
 2621|      0|        if (!size_t_bit_width) {
  ------------------
  |  Branch (2621:13): [True: 0, False: 0]
  ------------------
 2622|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
 2623|      0|                 << ext_inst_name()
 2624|      0|                 << " can only be used with physical addressing models";
 2625|      0|        }
 2626|       |
 2627|      0|        if (!_.IsIntScalarType(offset_type) ||
  ------------------
  |  Branch (2627:13): [True: 0, False: 0]
  ------------------
 2628|      0|            _.GetBitWidth(offset_type) != size_t_bit_width) {
  ------------------
  |  Branch (2628:13): [True: 0, False: 0]
  ------------------
 2629|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
 2630|      0|                 << ext_inst_name() << ": "
 2631|      0|                 << "expected operand Offset to be of type size_t ("
 2632|      0|                 << size_t_bit_width
 2633|      0|                 << "-bit integer for the addressing model used in the module)";
 2634|      0|        }
 2635|       |
 2636|      0|        spv::StorageClass p_storage_class;
 2637|      0|        uint32_t p_data_type = 0;
 2638|      0|        if (!_.GetPointerTypeInfo(p_type, &p_data_type, &p_storage_class)) {
  ------------------
  |  Branch (2638:13): [True: 0, False: 0]
  ------------------
 2639|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
 2640|      0|                 << ext_inst_name() << ": "
 2641|      0|                 << "expected operand P to be a pointer";
 2642|      0|        }
 2643|       |
 2644|      0|        if (p_storage_class != spv::StorageClass::Generic &&
  ------------------
  |  Branch (2644:13): [True: 0, False: 0]
  ------------------
 2645|      0|            p_storage_class != spv::StorageClass::CrossWorkgroup &&
  ------------------
  |  Branch (2645:13): [True: 0, False: 0]
  ------------------
 2646|      0|            p_storage_class != spv::StorageClass::Workgroup &&
  ------------------
  |  Branch (2646:13): [True: 0, False: 0]
  ------------------
 2647|      0|            p_storage_class != spv::StorageClass::Function) {
  ------------------
  |  Branch (2647:13): [True: 0, False: 0]
  ------------------
 2648|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
 2649|      0|                 << ext_inst_name() << ": "
 2650|      0|                 << "expected operand P storage class to be Generic, "
 2651|      0|                    "CrossWorkgroup, Workgroup or Function";
 2652|      0|        }
 2653|       |
 2654|      0|        if (_.GetComponentType(data_type) != p_data_type) {
  ------------------
  |  Branch (2654:13): [True: 0, False: 0]
  ------------------
 2655|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
 2656|      0|                 << ext_inst_name() << ": "
 2657|      0|                 << "expected operand P data type to be equal to the type of "
 2658|      0|                    "operand Data components";
 2659|      0|        }
 2660|      0|        break;
 2661|      0|      }
 2662|       |
 2663|      0|      case OpenCLLIB::Vload_half: {
  ------------------
  |  Branch (2663:7): [True: 0, False: 0]
  ------------------
 2664|      0|        if (!_.IsFloatScalarType(result_type)) {
  ------------------
  |  Branch (2664:13): [True: 0, False: 0]
  ------------------
 2665|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
 2666|      0|                 << ext_inst_name() << ": "
 2667|      0|                 << "expected Result Type to be a float scalar type";
 2668|      0|        }
 2669|       |
 2670|      0|        const uint32_t offset_type = _.GetOperandTypeId(inst, 4);
 2671|      0|        const uint32_t p_type = _.GetOperandTypeId(inst, 5);
 2672|       |
 2673|      0|        const uint32_t size_t_bit_width = GetSizeTBitWidth(_);
 2674|      0|        if (!size_t_bit_width) {
  ------------------
  |  Branch (2674:13): [True: 0, False: 0]
  ------------------
 2675|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
 2676|      0|                 << ext_inst_name()
 2677|      0|                 << " can only be used with physical addressing models";
 2678|      0|        }
 2679|       |
 2680|      0|        if (!_.IsIntScalarType(offset_type) ||
  ------------------
  |  Branch (2680:13): [True: 0, False: 0]
  ------------------
 2681|      0|            _.GetBitWidth(offset_type) != size_t_bit_width) {
  ------------------
  |  Branch (2681:13): [True: 0, False: 0]
  ------------------
 2682|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
 2683|      0|                 << ext_inst_name() << ": "
 2684|      0|                 << "expected operand Offset to be of type size_t ("
 2685|      0|                 << size_t_bit_width
 2686|      0|                 << "-bit integer for the addressing model used in the module)";
 2687|      0|        }
 2688|       |
 2689|      0|        spv::StorageClass p_storage_class;
 2690|      0|        uint32_t p_data_type = 0;
 2691|      0|        if (!_.GetPointerTypeInfo(p_type, &p_data_type, &p_storage_class)) {
  ------------------
  |  Branch (2691:13): [True: 0, False: 0]
  ------------------
 2692|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
 2693|      0|                 << ext_inst_name() << ": "
 2694|      0|                 << "expected operand P to be a pointer";
 2695|      0|        }
 2696|       |
 2697|      0|        if (p_storage_class != spv::StorageClass::UniformConstant &&
  ------------------
  |  Branch (2697:13): [True: 0, False: 0]
  ------------------
 2698|      0|            p_storage_class != spv::StorageClass::Generic &&
  ------------------
  |  Branch (2698:13): [True: 0, False: 0]
  ------------------
 2699|      0|            p_storage_class != spv::StorageClass::CrossWorkgroup &&
  ------------------
  |  Branch (2699:13): [True: 0, False: 0]
  ------------------
 2700|      0|            p_storage_class != spv::StorageClass::Workgroup &&
  ------------------
  |  Branch (2700:13): [True: 0, False: 0]
  ------------------
 2701|      0|            p_storage_class != spv::StorageClass::Function) {
  ------------------
  |  Branch (2701:13): [True: 0, False: 0]
  ------------------
 2702|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
 2703|      0|                 << ext_inst_name() << ": "
 2704|      0|                 << "expected operand P storage class to be UniformConstant, "
 2705|      0|                    "Generic, CrossWorkgroup, Workgroup or Function";
 2706|      0|        }
 2707|       |
 2708|      0|        if (!_.IsFloatScalarType(p_data_type) ||
  ------------------
  |  Branch (2708:13): [True: 0, False: 0]
  ------------------
 2709|      0|            _.GetBitWidth(p_data_type) != 16) {
  ------------------
  |  Branch (2709:13): [True: 0, False: 0]
  ------------------
 2710|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
 2711|      0|                 << ext_inst_name() << ": "
 2712|      0|                 << "expected operand P data type to be 16-bit float scalar";
 2713|      0|        }
 2714|      0|        break;
 2715|      0|      }
 2716|       |
 2717|      0|      case OpenCLLIB::Vload_halfn:
  ------------------
  |  Branch (2717:7): [True: 0, False: 0]
  ------------------
 2718|      0|      case OpenCLLIB::Vloada_halfn: {
  ------------------
  |  Branch (2718:7): [True: 0, False: 0]
  ------------------
 2719|      0|        if (!_.IsFloatVectorType(result_type)) {
  ------------------
  |  Branch (2719:13): [True: 0, False: 0]
  ------------------
 2720|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
 2721|      0|                 << ext_inst_name() << ": "
 2722|      0|                 << "expected Result Type to be a float vector type";
 2723|      0|        }
 2724|       |
 2725|      0|        const uint32_t num_components = _.GetDimension(result_type);
 2726|      0|        if (num_components > 4 && num_components != 8 && num_components != 16) {
  ------------------
  |  Branch (2726:13): [True: 0, False: 0]
  |  Branch (2726:35): [True: 0, False: 0]
  |  Branch (2726:58): [True: 0, False: 0]
  ------------------
 2727|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
 2728|      0|                 << ext_inst_name() << ": "
 2729|      0|                 << "expected Result Type to have 2, 3, 4, 8 or 16 components";
 2730|      0|        }
 2731|       |
 2732|      0|        const uint32_t offset_type = _.GetOperandTypeId(inst, 4);
 2733|      0|        const uint32_t p_type = _.GetOperandTypeId(inst, 5);
 2734|       |
 2735|      0|        const uint32_t size_t_bit_width = GetSizeTBitWidth(_);
 2736|      0|        if (!size_t_bit_width) {
  ------------------
  |  Branch (2736:13): [True: 0, False: 0]
  ------------------
 2737|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
 2738|      0|                 << ext_inst_name()
 2739|      0|                 << " can only be used with physical addressing models";
 2740|      0|        }
 2741|       |
 2742|      0|        if (!_.IsIntScalarType(offset_type) ||
  ------------------
  |  Branch (2742:13): [True: 0, False: 0]
  ------------------
 2743|      0|            _.GetBitWidth(offset_type) != size_t_bit_width) {
  ------------------
  |  Branch (2743:13): [True: 0, False: 0]
  ------------------
 2744|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
 2745|      0|                 << ext_inst_name() << ": "
 2746|      0|                 << "expected operand Offset to be of type size_t ("
 2747|      0|                 << size_t_bit_width
 2748|      0|                 << "-bit integer for the addressing model used in the module)";
 2749|      0|        }
 2750|       |
 2751|      0|        spv::StorageClass p_storage_class;
 2752|      0|        uint32_t p_data_type = 0;
 2753|      0|        if (!_.GetPointerTypeInfo(p_type, &p_data_type, &p_storage_class)) {
  ------------------
  |  Branch (2753:13): [True: 0, False: 0]
  ------------------
 2754|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
 2755|      0|                 << ext_inst_name() << ": "
 2756|      0|                 << "expected operand P to be a pointer";
 2757|      0|        }
 2758|       |
 2759|      0|        if (p_storage_class != spv::StorageClass::UniformConstant &&
  ------------------
  |  Branch (2759:13): [True: 0, False: 0]
  ------------------
 2760|      0|            p_storage_class != spv::StorageClass::Generic &&
  ------------------
  |  Branch (2760:13): [True: 0, False: 0]
  ------------------
 2761|      0|            p_storage_class != spv::StorageClass::CrossWorkgroup &&
  ------------------
  |  Branch (2761:13): [True: 0, False: 0]
  ------------------
 2762|      0|            p_storage_class != spv::StorageClass::Workgroup &&
  ------------------
  |  Branch (2762:13): [True: 0, False: 0]
  ------------------
 2763|      0|            p_storage_class != spv::StorageClass::Function) {
  ------------------
  |  Branch (2763:13): [True: 0, False: 0]
  ------------------
 2764|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
 2765|      0|                 << ext_inst_name() << ": "
 2766|      0|                 << "expected operand P storage class to be UniformConstant, "
 2767|      0|                    "Generic, CrossWorkgroup, Workgroup or Function";
 2768|      0|        }
 2769|       |
 2770|      0|        if (!_.IsFloatScalarType(p_data_type) ||
  ------------------
  |  Branch (2770:13): [True: 0, False: 0]
  ------------------
 2771|      0|            _.GetBitWidth(p_data_type) != 16) {
  ------------------
  |  Branch (2771:13): [True: 0, False: 0]
  ------------------
 2772|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
 2773|      0|                 << ext_inst_name() << ": "
 2774|      0|                 << "expected operand P data type to be 16-bit float scalar";
 2775|      0|        }
 2776|       |
 2777|      0|        const uint32_t n_value = inst->word(7);
 2778|      0|        if (num_components != n_value) {
  ------------------
  |  Branch (2778:13): [True: 0, False: 0]
  ------------------
 2779|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
 2780|      0|                 << ext_inst_name() << ": "
 2781|      0|                 << "expected literal N to be equal to the number of "
 2782|      0|                    "components of Result Type";
 2783|      0|        }
 2784|      0|        break;
 2785|      0|      }
 2786|       |
 2787|      0|      case OpenCLLIB::Vstore_half:
  ------------------
  |  Branch (2787:7): [True: 0, False: 0]
  ------------------
 2788|      0|      case OpenCLLIB::Vstore_half_r:
  ------------------
  |  Branch (2788:7): [True: 0, False: 0]
  ------------------
 2789|      0|      case OpenCLLIB::Vstore_halfn:
  ------------------
  |  Branch (2789:7): [True: 0, False: 0]
  ------------------
 2790|      0|      case OpenCLLIB::Vstore_halfn_r:
  ------------------
  |  Branch (2790:7): [True: 0, False: 0]
  ------------------
 2791|      0|      case OpenCLLIB::Vstorea_halfn:
  ------------------
  |  Branch (2791:7): [True: 0, False: 0]
  ------------------
 2792|      0|      case OpenCLLIB::Vstorea_halfn_r: {
  ------------------
  |  Branch (2792:7): [True: 0, False: 0]
  ------------------
 2793|      0|        if (_.GetIdOpcode(result_type) != spv::Op::OpTypeVoid) {
  ------------------
  |  Branch (2793:13): [True: 0, False: 0]
  ------------------
 2794|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
 2795|      0|                 << ext_inst_name() << ": expected Result Type to be void";
 2796|      0|        }
 2797|       |
 2798|      0|        const uint32_t data_type = _.GetOperandTypeId(inst, 4);
 2799|      0|        const uint32_t offset_type = _.GetOperandTypeId(inst, 5);
 2800|      0|        const uint32_t p_type = _.GetOperandTypeId(inst, 6);
 2801|      0|        const uint32_t data_type_bit_width = _.GetBitWidth(data_type);
 2802|       |
 2803|      0|        if (ext_inst_key == OpenCLLIB::Vstore_half ||
  ------------------
  |  Branch (2803:13): [True: 0, False: 0]
  ------------------
 2804|      0|            ext_inst_key == OpenCLLIB::Vstore_half_r) {
  ------------------
  |  Branch (2804:13): [True: 0, False: 0]
  ------------------
 2805|      0|          if (!_.IsFloatScalarType(data_type) ||
  ------------------
  |  Branch (2805:15): [True: 0, False: 0]
  ------------------
 2806|      0|              (data_type_bit_width != 32 && data_type_bit_width != 64)) {
  ------------------
  |  Branch (2806:16): [True: 0, False: 0]
  |  Branch (2806:45): [True: 0, False: 0]
  ------------------
 2807|      0|            return _.diag(SPV_ERROR_INVALID_DATA, inst)
 2808|      0|                   << ext_inst_name() << ": "
 2809|      0|                   << "expected Data to be a 32 or 64-bit float scalar";
 2810|      0|          }
 2811|      0|        } else {
 2812|      0|          if (!_.IsFloatVectorType(data_type) ||
  ------------------
  |  Branch (2812:15): [True: 0, False: 0]
  ------------------
 2813|      0|              (data_type_bit_width != 32 && data_type_bit_width != 64)) {
  ------------------
  |  Branch (2813:16): [True: 0, False: 0]
  |  Branch (2813:45): [True: 0, False: 0]
  ------------------
 2814|      0|            return _.diag(SPV_ERROR_INVALID_DATA, inst)
 2815|      0|                   << ext_inst_name() << ": "
 2816|      0|                   << "expected Data to be a 32 or 64-bit float vector";
 2817|      0|          }
 2818|       |
 2819|      0|          const uint32_t num_components = _.GetDimension(data_type);
 2820|      0|          if (num_components > 4 && num_components != 8 &&
  ------------------
  |  Branch (2820:15): [True: 0, False: 0]
  |  Branch (2820:37): [True: 0, False: 0]
  ------------------
 2821|      0|              num_components != 16) {
  ------------------
  |  Branch (2821:15): [True: 0, False: 0]
  ------------------
 2822|      0|            return _.diag(SPV_ERROR_INVALID_DATA, inst)
 2823|      0|                   << ext_inst_name() << ": "
 2824|      0|                   << "expected Data to have 2, 3, 4, 8 or 16 components";
 2825|      0|          }
 2826|      0|        }
 2827|       |
 2828|      0|        const uint32_t size_t_bit_width = GetSizeTBitWidth(_);
 2829|      0|        if (!size_t_bit_width) {
  ------------------
  |  Branch (2829:13): [True: 0, False: 0]
  ------------------
 2830|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
 2831|      0|                 << ext_inst_name()
 2832|      0|                 << " can only be used with physical addressing models";
 2833|      0|        }
 2834|       |
 2835|      0|        if (!_.IsIntScalarType(offset_type) ||
  ------------------
  |  Branch (2835:13): [True: 0, False: 0]
  ------------------
 2836|      0|            _.GetBitWidth(offset_type) != size_t_bit_width) {
  ------------------
  |  Branch (2836:13): [True: 0, False: 0]
  ------------------
 2837|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
 2838|      0|                 << ext_inst_name() << ": "
 2839|      0|                 << "expected operand Offset to be of type size_t ("
 2840|      0|                 << size_t_bit_width
 2841|      0|                 << "-bit integer for the addressing model used in the module)";
 2842|      0|        }
 2843|       |
 2844|      0|        spv::StorageClass p_storage_class;
 2845|      0|        uint32_t p_data_type = 0;
 2846|      0|        if (!_.GetPointerTypeInfo(p_type, &p_data_type, &p_storage_class)) {
  ------------------
  |  Branch (2846:13): [True: 0, False: 0]
  ------------------
 2847|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
 2848|      0|                 << ext_inst_name() << ": "
 2849|      0|                 << "expected operand P to be a pointer";
 2850|      0|        }
 2851|       |
 2852|      0|        if (p_storage_class != spv::StorageClass::Generic &&
  ------------------
  |  Branch (2852:13): [True: 0, False: 0]
  ------------------
 2853|      0|            p_storage_class != spv::StorageClass::CrossWorkgroup &&
  ------------------
  |  Branch (2853:13): [True: 0, False: 0]
  ------------------
 2854|      0|            p_storage_class != spv::StorageClass::Workgroup &&
  ------------------
  |  Branch (2854:13): [True: 0, False: 0]
  ------------------
 2855|      0|            p_storage_class != spv::StorageClass::Function) {
  ------------------
  |  Branch (2855:13): [True: 0, False: 0]
  ------------------
 2856|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
 2857|      0|                 << ext_inst_name() << ": "
 2858|      0|                 << "expected operand P storage class to be Generic, "
 2859|      0|                    "CrossWorkgroup, Workgroup or Function";
 2860|      0|        }
 2861|       |
 2862|      0|        if (!_.IsFloatScalarType(p_data_type) ||
  ------------------
  |  Branch (2862:13): [True: 0, False: 0]
  ------------------
 2863|      0|            _.GetBitWidth(p_data_type) != 16) {
  ------------------
  |  Branch (2863:13): [True: 0, False: 0]
  ------------------
 2864|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
 2865|      0|                 << ext_inst_name() << ": "
 2866|      0|                 << "expected operand P data type to be 16-bit float scalar";
 2867|      0|        }
 2868|       |
 2869|       |        // Rounding mode enum is checked by assembler.
 2870|      0|        break;
 2871|      0|      }
 2872|       |
 2873|      0|      case OpenCLLIB::Shuffle:
  ------------------
  |  Branch (2873:7): [True: 0, False: 0]
  ------------------
 2874|      0|      case OpenCLLIB::Shuffle2: {
  ------------------
  |  Branch (2874:7): [True: 0, False: 0]
  ------------------
 2875|      0|        if (!_.IsFloatVectorType(result_type) &&
  ------------------
  |  Branch (2875:13): [True: 0, False: 0]
  ------------------
 2876|      0|            !_.IsIntVectorType(result_type)) {
  ------------------
  |  Branch (2876:13): [True: 0, False: 0]
  ------------------
 2877|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
 2878|      0|                 << ext_inst_name() << ": "
 2879|      0|                 << "expected Result Type to be an int or float vector type";
 2880|      0|        }
 2881|       |
 2882|      0|        const uint32_t result_num_components = _.GetDimension(result_type);
 2883|      0|        if (result_num_components != 2 && result_num_components != 4 &&
  ------------------
  |  Branch (2883:13): [True: 0, False: 0]
  |  Branch (2883:43): [True: 0, False: 0]
  ------------------
 2884|      0|            result_num_components != 8 && result_num_components != 16) {
  ------------------
  |  Branch (2884:13): [True: 0, False: 0]
  |  Branch (2884:43): [True: 0, False: 0]
  ------------------
 2885|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
 2886|      0|                 << ext_inst_name() << ": "
 2887|      0|                 << "expected Result Type to have 2, 4, 8 or 16 components";
 2888|      0|        }
 2889|       |
 2890|      0|        uint32_t operand_index = 4;
 2891|      0|        const uint32_t x_type = _.GetOperandTypeId(inst, operand_index++);
 2892|       |
 2893|      0|        if (ext_inst_key == OpenCLLIB::Shuffle2) {
  ------------------
  |  Branch (2893:13): [True: 0, False: 0]
  ------------------
 2894|      0|          const uint32_t y_type = _.GetOperandTypeId(inst, operand_index++);
 2895|      0|          if (x_type != y_type) {
  ------------------
  |  Branch (2895:15): [True: 0, False: 0]
  ------------------
 2896|      0|            return _.diag(SPV_ERROR_INVALID_DATA, inst)
 2897|      0|                   << ext_inst_name() << ": "
 2898|      0|                   << "expected operands X and Y to be of the same type";
 2899|      0|          }
 2900|      0|        }
 2901|       |
 2902|      0|        const uint32_t shuffle_mask_type =
 2903|      0|            _.GetOperandTypeId(inst, operand_index++);
 2904|       |
 2905|      0|        if (!_.IsFloatVectorType(x_type) && !_.IsIntVectorType(x_type)) {
  ------------------
  |  Branch (2905:13): [True: 0, False: 0]
  |  Branch (2905:45): [True: 0, False: 0]
  ------------------
 2906|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
 2907|      0|                 << ext_inst_name() << ": "
 2908|      0|                 << "expected operand X to be an int or float vector";
 2909|      0|        }
 2910|       |
 2911|      0|        const uint32_t x_num_components = _.GetDimension(x_type);
 2912|      0|        if (x_num_components != 2 && x_num_components != 4 &&
  ------------------
  |  Branch (2912:13): [True: 0, False: 0]
  |  Branch (2912:38): [True: 0, False: 0]
  ------------------
 2913|      0|            x_num_components != 8 && x_num_components != 16) {
  ------------------
  |  Branch (2913:13): [True: 0, False: 0]
  |  Branch (2913:38): [True: 0, False: 0]
  ------------------
 2914|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
 2915|      0|                 << ext_inst_name() << ": "
 2916|      0|                 << "expected operand X to have 2, 4, 8 or 16 components";
 2917|      0|        }
 2918|       |
 2919|      0|        const uint32_t result_component_type = _.GetComponentType(result_type);
 2920|       |
 2921|      0|        if (result_component_type != _.GetComponentType(x_type)) {
  ------------------
  |  Branch (2921:13): [True: 0, False: 0]
  ------------------
 2922|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
 2923|      0|                 << ext_inst_name() << ": "
 2924|      0|                 << "expected operand X and Result Type to have equal "
 2925|      0|                    "component types";
 2926|      0|        }
 2927|       |
 2928|      0|        if (!_.IsIntVectorType(shuffle_mask_type)) {
  ------------------
  |  Branch (2928:13): [True: 0, False: 0]
  ------------------
 2929|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
 2930|      0|                 << ext_inst_name() << ": "
 2931|      0|                 << "expected operand Shuffle Mask to be an int vector";
 2932|      0|        }
 2933|       |
 2934|      0|        if (result_num_components != _.GetDimension(shuffle_mask_type)) {
  ------------------
  |  Branch (2934:13): [True: 0, False: 0]
  ------------------
 2935|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
 2936|      0|                 << ext_inst_name() << ": "
 2937|      0|                 << "expected operand Shuffle Mask to have the same number of "
 2938|      0|                    "components as Result Type";
 2939|      0|        }
 2940|       |
 2941|      0|        if (_.GetBitWidth(result_component_type) !=
  ------------------
  |  Branch (2941:13): [True: 0, False: 0]
  ------------------
 2942|      0|            _.GetBitWidth(shuffle_mask_type)) {
 2943|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
 2944|      0|                 << ext_inst_name() << ": "
 2945|      0|                 << "expected operand Shuffle Mask components to have the same "
 2946|      0|                    "bit width as Result Type components";
 2947|      0|        }
 2948|      0|        break;
 2949|      0|      }
 2950|       |
 2951|      0|      case OpenCLLIB::Printf: {
  ------------------
  |  Branch (2951:7): [True: 0, False: 0]
  ------------------
 2952|      0|        if (!_.IsIntScalarType(result_type) ||
  ------------------
  |  Branch (2952:13): [True: 0, False: 0]
  ------------------
 2953|      0|            _.GetBitWidth(result_type) != 32) {
  ------------------
  |  Branch (2953:13): [True: 0, False: 0]
  ------------------
 2954|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
 2955|      0|                 << ext_inst_name() << ": "
 2956|      0|                 << "expected Result Type to be a 32-bit int type";
 2957|      0|        }
 2958|       |
 2959|      0|        const uint32_t format_type = _.GetOperandTypeId(inst, 4);
 2960|      0|        spv::StorageClass format_storage_class;
 2961|      0|        uint32_t format_data_type = 0;
 2962|      0|        if (!_.GetPointerTypeInfo(format_type, &format_data_type,
  ------------------
  |  Branch (2962:13): [True: 0, False: 0]
  ------------------
 2963|      0|                                  &format_storage_class)) {
 2964|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
 2965|      0|                 << ext_inst_name() << ": "
 2966|      0|                 << "expected operand Format to be a pointer";
 2967|      0|        }
 2968|       |
 2969|      0|        if (format_storage_class != spv::StorageClass::UniformConstant) {
  ------------------
  |  Branch (2969:13): [True: 0, False: 0]
  ------------------
 2970|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
 2971|      0|                 << ext_inst_name() << ": "
 2972|      0|                 << "expected Format storage class to be UniformConstant";
 2973|      0|        }
 2974|       |
 2975|      0|        if (!_.IsIntScalarType(format_data_type) ||
  ------------------
  |  Branch (2975:13): [True: 0, False: 0]
  ------------------
 2976|      0|            _.GetBitWidth(format_data_type) != 8) {
  ------------------
  |  Branch (2976:13): [True: 0, False: 0]
  ------------------
 2977|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
 2978|      0|                 << ext_inst_name() << ": "
 2979|      0|                 << "expected Format data type to be 8-bit int";
 2980|      0|        }
 2981|      0|        break;
 2982|      0|      }
 2983|       |
 2984|      0|      case OpenCLLIB::Prefetch: {
  ------------------
  |  Branch (2984:7): [True: 0, False: 0]
  ------------------
 2985|      0|        if (_.GetIdOpcode(result_type) != spv::Op::OpTypeVoid) {
  ------------------
  |  Branch (2985:13): [True: 0, False: 0]
  ------------------
 2986|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
 2987|      0|                 << ext_inst_name() << ": expected Result Type to be void";
 2988|      0|        }
 2989|       |
 2990|      0|        const uint32_t p_type = _.GetOperandTypeId(inst, 4);
 2991|      0|        const uint32_t num_elements_type = _.GetOperandTypeId(inst, 5);
 2992|       |
 2993|      0|        spv::StorageClass p_storage_class;
 2994|      0|        uint32_t p_data_type = 0;
 2995|      0|        if (!_.GetPointerTypeInfo(p_type, &p_data_type, &p_storage_class)) {
  ------------------
  |  Branch (2995:13): [True: 0, False: 0]
  ------------------
 2996|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
 2997|      0|                 << ext_inst_name() << ": "
 2998|      0|                 << "expected operand Ptr to be a pointer";
 2999|      0|        }
 3000|       |
 3001|      0|        if (p_storage_class != spv::StorageClass::CrossWorkgroup) {
  ------------------
  |  Branch (3001:13): [True: 0, False: 0]
  ------------------
 3002|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
 3003|      0|                 << ext_inst_name() << ": "
 3004|      0|                 << "expected operand Ptr storage class to be CrossWorkgroup";
 3005|      0|        }
 3006|       |
 3007|      0|        if (!_.IsFloatScalarOrVectorType(p_data_type) &&
  ------------------
  |  Branch (3007:13): [True: 0, False: 0]
  ------------------
 3008|      0|            !_.IsIntScalarOrVectorType(p_data_type)) {
  ------------------
  |  Branch (3008:13): [True: 0, False: 0]
  ------------------
 3009|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
 3010|      0|                 << ext_inst_name() << ": "
 3011|      0|                 << "expected Ptr data type to be int or float scalar or "
 3012|      0|                    "vector";
 3013|      0|        }
 3014|       |
 3015|      0|        const uint32_t num_components = _.GetDimension(p_data_type);
 3016|      0|        if (num_components > 4 && num_components != 8 && num_components != 16) {
  ------------------
  |  Branch (3016:13): [True: 0, False: 0]
  |  Branch (3016:35): [True: 0, False: 0]
  |  Branch (3016:58): [True: 0, False: 0]
  ------------------
 3017|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
 3018|      0|                 << ext_inst_name() << ": "
 3019|      0|                 << "expected Result Type to be a scalar or a vector with 2, "
 3020|      0|                    "3, 4, 8 or 16 components";
 3021|      0|        }
 3022|       |
 3023|      0|        const uint32_t size_t_bit_width = GetSizeTBitWidth(_);
 3024|      0|        if (!size_t_bit_width) {
  ------------------
  |  Branch (3024:13): [True: 0, False: 0]
  ------------------
 3025|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
 3026|      0|                 << ext_inst_name()
 3027|      0|                 << " can only be used with physical addressing models";
 3028|      0|        }
 3029|       |
 3030|      0|        if (!_.IsIntScalarType(num_elements_type) ||
  ------------------
  |  Branch (3030:13): [True: 0, False: 0]
  ------------------
 3031|      0|            _.GetBitWidth(num_elements_type) != size_t_bit_width) {
  ------------------
  |  Branch (3031:13): [True: 0, False: 0]
  ------------------
 3032|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
 3033|      0|                 << ext_inst_name() << ": "
 3034|      0|                 << "expected operand Num Elements to be of type size_t ("
 3035|      0|                 << size_t_bit_width
 3036|      0|                 << "-bit integer for the addressing model used in the module)";
 3037|      0|        }
 3038|      0|        break;
 3039|      0|      }
 3040|      0|    }
 3041|      0|  } else if (ext_inst_type == SPV_EXT_INST_TYPE_OPENCL_DEBUGINFO_100 ||
  ------------------
  |  Branch (3041:14): [True: 0, False: 0]
  ------------------
 3042|      0|             ext_inst_type ==
  ------------------
  |  Branch (3042:14): [True: 0, False: 0]
  ------------------
 3043|      0|                 SPV_EXT_INST_TYPE_NONSEMANTIC_SHADER_DEBUGINFO_100) {
 3044|      0|    if (!_.IsVoidType(result_type)) {
  ------------------
  |  Branch (3044:9): [True: 0, False: 0]
  ------------------
 3045|      0|      return _.diag(SPV_ERROR_INVALID_DATA, inst)
 3046|      0|             << ext_inst_name() << ": "
 3047|      0|             << "expected result type must be a result id of "
 3048|      0|             << "OpTypeVoid";
 3049|      0|    }
 3050|       |
 3051|      0|    const bool vulkanDebugInfo =
 3052|      0|        ext_inst_type == SPV_EXT_INST_TYPE_NONSEMANTIC_SHADER_DEBUGINFO_100;
 3053|       |
 3054|      0|    auto num_words = inst->words().size();
 3055|       |
 3056|       |    // Handle any non-common NonSemanticShaderDebugInfo instructions.
 3057|      0|    if (vulkanDebugInfo) {
  ------------------
  |  Branch (3057:9): [True: 0, False: 0]
  ------------------
 3058|      0|      const NonSemanticShaderDebugInfo100Instructions ext_inst_key =
 3059|      0|          NonSemanticShaderDebugInfo100Instructions(ext_inst_index);
 3060|      0|      switch (ext_inst_key) {
  ------------------
  |  Branch (3060:15): [True: 0, False: 0]
  ------------------
 3061|       |        // The following block of instructions will be handled by the common
 3062|       |        // validation.
 3063|      0|        case NonSemanticShaderDebugInfo100DebugInfoNone:
  ------------------
  |  Branch (3063:9): [True: 0, False: 0]
  ------------------
 3064|      0|        case NonSemanticShaderDebugInfo100DebugCompilationUnit:
  ------------------
  |  Branch (3064:9): [True: 0, False: 0]
  ------------------
 3065|      0|        case NonSemanticShaderDebugInfo100DebugTypeBasic:
  ------------------
  |  Branch (3065:9): [True: 0, False: 0]
  ------------------
 3066|      0|        case NonSemanticShaderDebugInfo100DebugTypePointer:
  ------------------
  |  Branch (3066:9): [True: 0, False: 0]
  ------------------
 3067|      0|        case NonSemanticShaderDebugInfo100DebugTypeQualifier:
  ------------------
  |  Branch (3067:9): [True: 0, False: 0]
  ------------------
 3068|      0|        case NonSemanticShaderDebugInfo100DebugTypeArray:
  ------------------
  |  Branch (3068:9): [True: 0, False: 0]
  ------------------
 3069|      0|        case NonSemanticShaderDebugInfo100DebugTypeVector:
  ------------------
  |  Branch (3069:9): [True: 0, False: 0]
  ------------------
 3070|      0|        case NonSemanticShaderDebugInfo100DebugTypedef:
  ------------------
  |  Branch (3070:9): [True: 0, False: 0]
  ------------------
 3071|      0|        case NonSemanticShaderDebugInfo100DebugTypeFunction:
  ------------------
  |  Branch (3071:9): [True: 0, False: 0]
  ------------------
 3072|      0|        case NonSemanticShaderDebugInfo100DebugTypeEnum:
  ------------------
  |  Branch (3072:9): [True: 0, False: 0]
  ------------------
 3073|      0|        case NonSemanticShaderDebugInfo100DebugTypeComposite:
  ------------------
  |  Branch (3073:9): [True: 0, False: 0]
  ------------------
 3074|      0|        case NonSemanticShaderDebugInfo100DebugTypeMember:
  ------------------
  |  Branch (3074:9): [True: 0, False: 0]
  ------------------
 3075|      0|        case NonSemanticShaderDebugInfo100DebugTypeInheritance:
  ------------------
  |  Branch (3075:9): [True: 0, False: 0]
  ------------------
 3076|      0|        case NonSemanticShaderDebugInfo100DebugTypePtrToMember:
  ------------------
  |  Branch (3076:9): [True: 0, False: 0]
  ------------------
 3077|      0|        case NonSemanticShaderDebugInfo100DebugTypeTemplate:
  ------------------
  |  Branch (3077:9): [True: 0, False: 0]
  ------------------
 3078|      0|        case NonSemanticShaderDebugInfo100DebugTypeTemplateParameter:
  ------------------
  |  Branch (3078:9): [True: 0, False: 0]
  ------------------
 3079|      0|        case NonSemanticShaderDebugInfo100DebugTypeTemplateTemplateParameter:
  ------------------
  |  Branch (3079:9): [True: 0, False: 0]
  ------------------
 3080|      0|        case NonSemanticShaderDebugInfo100DebugTypeTemplateParameterPack:
  ------------------
  |  Branch (3080:9): [True: 0, False: 0]
  ------------------
 3081|      0|        case NonSemanticShaderDebugInfo100DebugGlobalVariable:
  ------------------
  |  Branch (3081:9): [True: 0, False: 0]
  ------------------
 3082|      0|        case NonSemanticShaderDebugInfo100DebugFunctionDeclaration:
  ------------------
  |  Branch (3082:9): [True: 0, False: 0]
  ------------------
 3083|      0|        case NonSemanticShaderDebugInfo100DebugFunction:
  ------------------
  |  Branch (3083:9): [True: 0, False: 0]
  ------------------
 3084|      0|        case NonSemanticShaderDebugInfo100DebugLexicalBlock:
  ------------------
  |  Branch (3084:9): [True: 0, False: 0]
  ------------------
 3085|      0|        case NonSemanticShaderDebugInfo100DebugLexicalBlockDiscriminator:
  ------------------
  |  Branch (3085:9): [True: 0, False: 0]
  ------------------
 3086|      0|        case NonSemanticShaderDebugInfo100DebugScope:
  ------------------
  |  Branch (3086:9): [True: 0, False: 0]
  ------------------
 3087|      0|        case NonSemanticShaderDebugInfo100DebugNoScope:
  ------------------
  |  Branch (3087:9): [True: 0, False: 0]
  ------------------
 3088|      0|        case NonSemanticShaderDebugInfo100DebugInlinedAt:
  ------------------
  |  Branch (3088:9): [True: 0, False: 0]
  ------------------
 3089|      0|        case NonSemanticShaderDebugInfo100DebugLocalVariable:
  ------------------
  |  Branch (3089:9): [True: 0, False: 0]
  ------------------
 3090|      0|        case NonSemanticShaderDebugInfo100DebugInlinedVariable:
  ------------------
  |  Branch (3090:9): [True: 0, False: 0]
  ------------------
 3091|      0|        case NonSemanticShaderDebugInfo100DebugDeclare:
  ------------------
  |  Branch (3091:9): [True: 0, False: 0]
  ------------------
 3092|      0|        case NonSemanticShaderDebugInfo100DebugValue:
  ------------------
  |  Branch (3092:9): [True: 0, False: 0]
  ------------------
 3093|      0|        case NonSemanticShaderDebugInfo100DebugOperation:
  ------------------
  |  Branch (3093:9): [True: 0, False: 0]
  ------------------
 3094|      0|        case NonSemanticShaderDebugInfo100DebugExpression:
  ------------------
  |  Branch (3094:9): [True: 0, False: 0]
  ------------------
 3095|      0|        case NonSemanticShaderDebugInfo100DebugMacroDef:
  ------------------
  |  Branch (3095:9): [True: 0, False: 0]
  ------------------
 3096|      0|        case NonSemanticShaderDebugInfo100DebugMacroUndef:
  ------------------
  |  Branch (3096:9): [True: 0, False: 0]
  ------------------
 3097|      0|        case NonSemanticShaderDebugInfo100DebugImportedEntity:
  ------------------
  |  Branch (3097:9): [True: 0, False: 0]
  ------------------
 3098|      0|        case NonSemanticShaderDebugInfo100DebugSource:
  ------------------
  |  Branch (3098:9): [True: 0, False: 0]
  ------------------
 3099|      0|          break;
 3100|      0|        case NonSemanticShaderDebugInfo100DebugTypeMatrix: {
  ------------------
  |  Branch (3100:9): [True: 0, False: 0]
  ------------------
 3101|      0|          CHECK_DEBUG_OPERAND("Vector Type", CommonDebugInfoDebugTypeVector, 5);
  ------------------
  |  |  211|      0|  do {                                                                         \
  |  |  212|      0|    auto result = ValidateDebugInfoOperand(_, NAME, debug_opcode, inst, index, \
  |  |  213|      0|                                           ext_inst_name);                     \
  |  |  214|      0|    if (result != SPV_SUCCESS) return result;                                  \
  |  |  ------------------
  |  |  |  Branch (214:9): [True: 0, False: 0]
  |  |  ------------------
  |  |  215|      0|  } while (0)
  |  |  ------------------
  |  |  |  Branch (215:12): [Folded - Ignored]
  |  |  ------------------
  ------------------
 3102|       |
 3103|      0|          CHECK_CONST_UINT_OPERAND("Vector Count", 6);
  ------------------
  |  |  139|      0|  if (vulkanDebugInfo) {                                     \
  |  |  ------------------
  |  |  |  Branch (139:7): [True: 0, False: 0]
  |  |  ------------------
  |  |  140|      0|    auto result = ValidateUint32ConstantOperandForDebugInfo( \
  |  |  141|      0|        _, NAME, inst, index, ext_inst_name);                \
  |  |  142|      0|    if (result != SPV_SUCCESS) return result;                \
  |  |  ------------------
  |  |  |  Branch (142:9): [True: 0, False: 0]
  |  |  ------------------
  |  |  143|      0|  }
  ------------------
 3104|       |
 3105|      0|          uint32_t vector_count = inst->word(6);
 3106|      0|          uint64_t const_val;
 3107|      0|          if (!_.GetConstantValUint64(vector_count, &const_val)) {
  ------------------
  |  Branch (3107:15): [True: 0, False: 0]
  ------------------
 3108|      0|            return _.diag(SPV_ERROR_INVALID_DATA, inst)
 3109|      0|                   << ext_inst_name()
 3110|      0|                   << ": Vector Count must be 32-bit integer OpConstant";
 3111|      0|          }
 3112|       |
 3113|      0|          vector_count = const_val & 0xffffffff;
 3114|      0|          if (!vector_count || vector_count > 4) {
  ------------------
  |  Branch (3114:15): [True: 0, False: 0]
  |  Branch (3114:32): [True: 0, False: 0]
  ------------------
 3115|      0|            return _.diag(SPV_ERROR_INVALID_DATA, inst)
 3116|      0|                   << ext_inst_name() << ": Vector Count must be positive "
 3117|      0|                   << "integer less than or equal to 4";
 3118|      0|          }
 3119|      0|          break;
 3120|      0|        }
 3121|       |        // TODO: Add validation rules for remaining cases as well.
 3122|      0|        case NonSemanticShaderDebugInfo100DebugFunctionDefinition:
  ------------------
  |  Branch (3122:9): [True: 0, False: 0]
  ------------------
 3123|      0|        case NonSemanticShaderDebugInfo100DebugSourceContinued:
  ------------------
  |  Branch (3123:9): [True: 0, False: 0]
  ------------------
 3124|      0|        case NonSemanticShaderDebugInfo100DebugLine:
  ------------------
  |  Branch (3124:9): [True: 0, False: 0]
  ------------------
 3125|      0|        case NonSemanticShaderDebugInfo100DebugNoLine:
  ------------------
  |  Branch (3125:9): [True: 0, False: 0]
  ------------------
 3126|      0|        case NonSemanticShaderDebugInfo100DebugBuildIdentifier:
  ------------------
  |  Branch (3126:9): [True: 0, False: 0]
  ------------------
 3127|      0|        case NonSemanticShaderDebugInfo100DebugStoragePath:
  ------------------
  |  Branch (3127:9): [True: 0, False: 0]
  ------------------
 3128|      0|        case NonSemanticShaderDebugInfo100DebugEntryPoint:
  ------------------
  |  Branch (3128:9): [True: 0, False: 0]
  ------------------
 3129|      0|          break;
 3130|      0|        case NonSemanticShaderDebugInfo100InstructionsMax:
  ------------------
  |  Branch (3130:9): [True: 0, False: 0]
  ------------------
 3131|      0|          assert(0);
 3132|      0|          break;
 3133|      0|      }
 3134|      0|    }
 3135|       |
 3136|       |    // Handle any non-common OpenCL insts, then common
 3137|      0|    if (ext_inst_type != SPV_EXT_INST_TYPE_OPENCL_DEBUGINFO_100 ||
  ------------------
  |  Branch (3137:9): [True: 0, False: 0]
  ------------------
 3138|      0|        OpenCLDebugInfo100Instructions(ext_inst_index) !=
  ------------------
  |  Branch (3138:9): [True: 0, False: 0]
  ------------------
 3139|      0|            OpenCLDebugInfo100DebugModuleINTEL) {
 3140|      0|      const CommonDebugInfoInstructions ext_inst_key =
 3141|      0|          CommonDebugInfoInstructions(ext_inst_index);
 3142|      0|      switch (ext_inst_key) {
  ------------------
  |  Branch (3142:15): [True: 0, False: 0]
  ------------------
 3143|      0|        case CommonDebugInfoDebugInfoNone:
  ------------------
  |  Branch (3143:9): [True: 0, False: 0]
  ------------------
 3144|      0|        case CommonDebugInfoDebugNoScope:
  ------------------
  |  Branch (3144:9): [True: 0, False: 0]
  ------------------
 3145|      0|          break;
 3146|       |          // The binary parser validates the opcode for DebugInfoNone,
 3147|       |          // DebugNoScope, DebugOperation. We just check the parameters to
 3148|       |          // DebugOperation are properly constants for vulkan debug info.
 3149|      0|        case CommonDebugInfoDebugOperation: {
  ------------------
  |  Branch (3149:9): [True: 0, False: 0]
  ------------------
 3150|      0|          CHECK_CONST_UINT_OPERAND("Operation", 5);
  ------------------
  |  |  139|      0|  if (vulkanDebugInfo) {                                     \
  |  |  ------------------
  |  |  |  Branch (139:7): [True: 0, False: 0]
  |  |  ------------------
  |  |  140|      0|    auto result = ValidateUint32ConstantOperandForDebugInfo( \
  |  |  141|      0|        _, NAME, inst, index, ext_inst_name);                \
  |  |  142|      0|    if (result != SPV_SUCCESS) return result;                \
  |  |  ------------------
  |  |  |  Branch (142:9): [True: 0, False: 0]
  |  |  ------------------
  |  |  143|      0|  }
  ------------------
 3151|      0|          for (uint32_t i = 6; i < num_words; ++i) {
  ------------------
  |  Branch (3151:32): [True: 0, False: 0]
  ------------------
 3152|      0|            CHECK_CONST_UINT_OPERAND("Operand", i);
  ------------------
  |  |  139|      0|  if (vulkanDebugInfo) {                                     \
  |  |  ------------------
  |  |  |  Branch (139:7): [True: 0, False: 0]
  |  |  ------------------
  |  |  140|      0|    auto result = ValidateUint32ConstantOperandForDebugInfo( \
  |  |  141|      0|        _, NAME, inst, index, ext_inst_name);                \
  |  |  142|      0|    if (result != SPV_SUCCESS) return result;                \
  |  |  ------------------
  |  |  |  Branch (142:9): [True: 0, False: 0]
  |  |  ------------------
  |  |  143|      0|  }
  ------------------
 3153|      0|          }
 3154|      0|          break;
 3155|      0|        }
 3156|      0|        case CommonDebugInfoDebugCompilationUnit: {
  ------------------
  |  Branch (3156:9): [True: 0, False: 0]
  ------------------
 3157|      0|          CHECK_CONST_UINT_OPERAND("Version", 5);
  ------------------
  |  |  139|      0|  if (vulkanDebugInfo) {                                     \
  |  |  ------------------
  |  |  |  Branch (139:7): [True: 0, False: 0]
  |  |  ------------------
  |  |  140|      0|    auto result = ValidateUint32ConstantOperandForDebugInfo( \
  |  |  141|      0|        _, NAME, inst, index, ext_inst_name);                \
  |  |  142|      0|    if (result != SPV_SUCCESS) return result;                \
  |  |  ------------------
  |  |  |  Branch (142:9): [True: 0, False: 0]
  |  |  ------------------
  |  |  143|      0|  }
  ------------------
 3158|      0|          CHECK_CONST_UINT_OPERAND("DWARF Version", 6);
  ------------------
  |  |  139|      0|  if (vulkanDebugInfo) {                                     \
  |  |  ------------------
  |  |  |  Branch (139:7): [True: 0, False: 0]
  |  |  ------------------
  |  |  140|      0|    auto result = ValidateUint32ConstantOperandForDebugInfo( \
  |  |  141|      0|        _, NAME, inst, index, ext_inst_name);                \
  |  |  142|      0|    if (result != SPV_SUCCESS) return result;                \
  |  |  ------------------
  |  |  |  Branch (142:9): [True: 0, False: 0]
  |  |  ------------------
  |  |  143|      0|  }
  ------------------
 3159|      0|          CHECK_DEBUG_OPERAND("Source", CommonDebugInfoDebugSource, 7);
  ------------------
  |  |  211|      0|  do {                                                                         \
  |  |  212|      0|    auto result = ValidateDebugInfoOperand(_, NAME, debug_opcode, inst, index, \
  |  |  213|      0|                                           ext_inst_name);                     \
  |  |  214|      0|    if (result != SPV_SUCCESS) return result;                                  \
  |  |  ------------------
  |  |  |  Branch (214:9): [True: 0, False: 0]
  |  |  ------------------
  |  |  215|      0|  } while (0)
  |  |  ------------------
  |  |  |  Branch (215:12): [Folded - Ignored]
  |  |  ------------------
  ------------------
 3160|      0|          CHECK_CONST_UINT_OPERAND("Language", 8);
  ------------------
  |  |  139|      0|  if (vulkanDebugInfo) {                                     \
  |  |  ------------------
  |  |  |  Branch (139:7): [True: 0, False: 0]
  |  |  ------------------
  |  |  140|      0|    auto result = ValidateUint32ConstantOperandForDebugInfo( \
  |  |  141|      0|        _, NAME, inst, index, ext_inst_name);                \
  |  |  142|      0|    if (result != SPV_SUCCESS) return result;                \
  |  |  ------------------
  |  |  |  Branch (142:9): [True: 0, False: 0]
  |  |  ------------------
  |  |  143|      0|  }
  ------------------
 3161|      0|          break;
 3162|      0|        }
 3163|      0|        case CommonDebugInfoDebugSource: {
  ------------------
  |  Branch (3163:9): [True: 0, False: 0]
  ------------------
 3164|      0|          CHECK_OPERAND("File", spv::Op::OpString, 5);
  ------------------
  |  |  132|      0|  do {                                                                      \
  |  |  133|      0|    auto result = ValidateOperandForDebugInfo(_, NAME, opcode, inst, index, \
  |  |  134|      0|                                              ext_inst_name);               \
  |  |  135|      0|    if (result != SPV_SUCCESS) return result;                               \
  |  |  ------------------
  |  |  |  Branch (135:9): [True: 0, False: 0]
  |  |  ------------------
  |  |  136|      0|  } while (0)
  |  |  ------------------
  |  |  |  Branch (136:12): [Folded - Ignored]
  |  |  ------------------
  ------------------
 3165|      0|          if (num_words == 7) CHECK_OPERAND("Text", spv::Op::OpString, 6);
  ------------------
  |  |  132|      0|  do {                                                                      \
  |  |  133|      0|    auto result = ValidateOperandForDebugInfo(_, NAME, opcode, inst, index, \
  |  |  134|      0|                                              ext_inst_name);               \
  |  |  135|      0|    if (result != SPV_SUCCESS) return result;                               \
  |  |  ------------------
  |  |  |  Branch (135:9): [True: 0, False: 0]
  |  |  ------------------
  |  |  136|      0|  } while (0)
  |  |  ------------------
  |  |  |  Branch (136:12): [Folded - Ignored]
  |  |  ------------------
  ------------------
  |  Branch (3165:15): [True: 0, False: 0]
  ------------------
 3166|      0|          break;
 3167|      0|        }
 3168|      0|        case CommonDebugInfoDebugTypeBasic: {
  ------------------
  |  Branch (3168:9): [True: 0, False: 0]
  ------------------
 3169|      0|          CHECK_OPERAND("Name", spv::Op::OpString, 5);
  ------------------
  |  |  132|      0|  do {                                                                      \
  |  |  133|      0|    auto result = ValidateOperandForDebugInfo(_, NAME, opcode, inst, index, \
  |  |  134|      0|                                              ext_inst_name);               \
  |  |  135|      0|    if (result != SPV_SUCCESS) return result;                               \
  |  |  ------------------
  |  |  |  Branch (135:9): [True: 0, False: 0]
  |  |  ------------------
  |  |  136|      0|  } while (0)
  |  |  ------------------
  |  |  |  Branch (136:12): [Folded - Ignored]
  |  |  ------------------
  ------------------
 3170|      0|          CHECK_OPERAND("Size", spv::Op::OpConstant, 6);
  ------------------
  |  |  132|      0|  do {                                                                      \
  |  |  133|      0|    auto result = ValidateOperandForDebugInfo(_, NAME, opcode, inst, index, \
  |  |  134|      0|                                              ext_inst_name);               \
  |  |  135|      0|    if (result != SPV_SUCCESS) return result;                               \
  |  |  ------------------
  |  |  |  Branch (135:9): [True: 0, False: 0]
  |  |  ------------------
  |  |  136|      0|  } while (0)
  |  |  ------------------
  |  |  |  Branch (136:12): [Folded - Ignored]
  |  |  ------------------
  ------------------
 3171|      0|          CHECK_CONST_UINT_OPERAND("Encoding", 7);
  ------------------
  |  |  139|      0|  if (vulkanDebugInfo) {                                     \
  |  |  ------------------
  |  |  |  Branch (139:7): [True: 0, False: 0]
  |  |  ------------------
  |  |  140|      0|    auto result = ValidateUint32ConstantOperandForDebugInfo( \
  |  |  141|      0|        _, NAME, inst, index, ext_inst_name);                \
  |  |  142|      0|    if (result != SPV_SUCCESS) return result;                \
  |  |  ------------------
  |  |  |  Branch (142:9): [True: 0, False: 0]
  |  |  ------------------
  |  |  143|      0|  }
  ------------------
 3172|      0|          break;
 3173|      0|        }
 3174|      0|        case CommonDebugInfoDebugTypePointer: {
  ------------------
  |  Branch (3174:9): [True: 0, False: 0]
  ------------------
 3175|      0|          auto validate_base_type =
 3176|      0|              ValidateOperandBaseType(_, inst, 5, ext_inst_name);
 3177|      0|          if (validate_base_type != SPV_SUCCESS) return validate_base_type;
  ------------------
  |  Branch (3177:15): [True: 0, False: 0]
  ------------------
 3178|      0|          CHECK_CONST_UINT_OPERAND("Storage Class", 6);
  ------------------
  |  |  139|      0|  if (vulkanDebugInfo) {                                     \
  |  |  ------------------
  |  |  |  Branch (139:7): [True: 0, False: 0]
  |  |  ------------------
  |  |  140|      0|    auto result = ValidateUint32ConstantOperandForDebugInfo( \
  |  |  141|      0|        _, NAME, inst, index, ext_inst_name);                \
  |  |  142|      0|    if (result != SPV_SUCCESS) return result;                \
  |  |  ------------------
  |  |  |  Branch (142:9): [True: 0, False: 0]
  |  |  ------------------
  |  |  143|      0|  }
  ------------------
 3179|      0|          CHECK_CONST_UINT_OPERAND("Flags", 7);
  ------------------
  |  |  139|      0|  if (vulkanDebugInfo) {                                     \
  |  |  ------------------
  |  |  |  Branch (139:7): [True: 0, False: 0]
  |  |  ------------------
  |  |  140|      0|    auto result = ValidateUint32ConstantOperandForDebugInfo( \
  |  |  141|      0|        _, NAME, inst, index, ext_inst_name);                \
  |  |  142|      0|    if (result != SPV_SUCCESS) return result;                \
  |  |  ------------------
  |  |  |  Branch (142:9): [True: 0, False: 0]
  |  |  ------------------
  |  |  143|      0|  }
  ------------------
 3180|      0|          break;
 3181|      0|        }
 3182|      0|        case CommonDebugInfoDebugTypeQualifier: {
  ------------------
  |  Branch (3182:9): [True: 0, False: 0]
  ------------------
 3183|      0|          auto validate_base_type =
 3184|      0|              ValidateOperandBaseType(_, inst, 5, ext_inst_name);
 3185|      0|          if (validate_base_type != SPV_SUCCESS) return validate_base_type;
  ------------------
  |  Branch (3185:15): [True: 0, False: 0]
  ------------------
 3186|      0|          CHECK_CONST_UINT_OPERAND("Type Qualifier", 6);
  ------------------
  |  |  139|      0|  if (vulkanDebugInfo) {                                     \
  |  |  ------------------
  |  |  |  Branch (139:7): [True: 0, False: 0]
  |  |  ------------------
  |  |  140|      0|    auto result = ValidateUint32ConstantOperandForDebugInfo( \
  |  |  141|      0|        _, NAME, inst, index, ext_inst_name);                \
  |  |  142|      0|    if (result != SPV_SUCCESS) return result;                \
  |  |  ------------------
  |  |  |  Branch (142:9): [True: 0, False: 0]
  |  |  ------------------
  |  |  143|      0|  }
  ------------------
 3187|      0|          break;
 3188|      0|        }
 3189|      0|        case CommonDebugInfoDebugTypeVector: {
  ------------------
  |  Branch (3189:9): [True: 0, False: 0]
  ------------------
 3190|      0|          auto validate_base_type =
 3191|      0|              ValidateOperandBaseType(_, inst, 5, ext_inst_name);
 3192|      0|          if (validate_base_type != SPV_SUCCESS) return validate_base_type;
  ------------------
  |  Branch (3192:15): [True: 0, False: 0]
  ------------------
 3193|       |
 3194|      0|          CHECK_CONST_UINT_OPERAND("Component Count", 6);
  ------------------
  |  |  139|      0|  if (vulkanDebugInfo) {                                     \
  |  |  ------------------
  |  |  |  Branch (139:7): [True: 0, False: 0]
  |  |  ------------------
  |  |  140|      0|    auto result = ValidateUint32ConstantOperandForDebugInfo( \
  |  |  141|      0|        _, NAME, inst, index, ext_inst_name);                \
  |  |  142|      0|    if (result != SPV_SUCCESS) return result;                \
  |  |  ------------------
  |  |  |  Branch (142:9): [True: 0, False: 0]
  |  |  ------------------
  |  |  143|      0|  }
  ------------------
 3195|      0|          uint32_t component_count = inst->word(6);
 3196|      0|          if (vulkanDebugInfo) {
  ------------------
  |  Branch (3196:15): [True: 0, False: 0]
  ------------------
 3197|      0|            uint64_t const_val;
 3198|      0|            if (!_.GetConstantValUint64(component_count, &const_val)) {
  ------------------
  |  Branch (3198:17): [True: 0, False: 0]
  ------------------
 3199|      0|              return _.diag(SPV_ERROR_INVALID_DATA, inst)
 3200|      0|                     << ext_inst_name()
 3201|      0|                     << ": Component Count must be 32-bit integer OpConstant";
 3202|      0|            }
 3203|      0|            component_count = const_val & 0xffffffff;
 3204|      0|          }
 3205|       |
 3206|      0|          if (!component_count || component_count > 4) {
  ------------------
  |  Branch (3206:15): [True: 0, False: 0]
  |  Branch (3206:35): [True: 0, False: 0]
  ------------------
 3207|      0|            return _.diag(SPV_ERROR_INVALID_DATA, inst)
 3208|      0|                   << ext_inst_name() << ": Component Count must be positive "
 3209|      0|                   << "integer less than or equal to 4";
 3210|      0|          }
 3211|      0|          break;
 3212|      0|        }
 3213|      0|        case CommonDebugInfoDebugTypeArray: {
  ------------------
  |  Branch (3213:9): [True: 0, False: 0]
  ------------------
 3214|      0|          auto validate_base_type = ValidateOperandDebugType(
 3215|      0|              _, "Base Type", inst, 5, ext_inst_name, false);
 3216|      0|          if (validate_base_type != SPV_SUCCESS) return validate_base_type;
  ------------------
  |  Branch (3216:15): [True: 0, False: 0]
  ------------------
 3217|      0|          for (uint32_t i = 6; i < num_words; ++i) {
  ------------------
  |  Branch (3217:32): [True: 0, False: 0]
  ------------------
 3218|      0|            bool invalid = false;
 3219|      0|            auto* component_count = _.FindDef(inst->word(i));
 3220|      0|            if (IsConstIntScalarTypeWith32Or64Bits(_, component_count)) {
  ------------------
  |  Branch (3220:17): [True: 0, False: 0]
  ------------------
 3221|       |              // TODO: We need a spec discussion for the runtime array for
 3222|       |              // OpenCL.
 3223|      0|              if (!vulkanDebugInfo && !component_count->word(3)) {
  ------------------
  |  Branch (3223:19): [True: 0, False: 0]
  |  Branch (3223:39): [True: 0, False: 0]
  ------------------
 3224|      0|                invalid = true;
 3225|      0|              }
 3226|      0|            } else if (component_count->words().size() > 6 &&
  ------------------
  |  Branch (3226:24): [True: 0, False: 0]
  ------------------
 3227|      0|                       (CommonDebugInfoInstructions(component_count->word(4)) ==
  ------------------
  |  Branch (3227:25): [True: 0, False: 0]
  ------------------
 3228|      0|                            CommonDebugInfoDebugLocalVariable ||
 3229|      0|                        CommonDebugInfoInstructions(component_count->word(4)) ==
  ------------------
  |  Branch (3229:25): [True: 0, False: 0]
  ------------------
 3230|      0|                            CommonDebugInfoDebugGlobalVariable)) {
 3231|      0|              auto* component_count_type = _.FindDef(component_count->word(6));
 3232|      0|              if (component_count_type->words().size() > 7) {
  ------------------
  |  Branch (3232:19): [True: 0, False: 0]
  ------------------
 3233|      0|                uint32_t encoding = component_count_type->word(7);
 3234|      0|                if (CommonDebugInfoInstructions(component_count_type->word(
  ------------------
  |  Branch (3234:21): [True: 0, False: 0]
  ------------------
 3235|      0|                        4)) != CommonDebugInfoDebugTypeBasic ||
 3236|      0|                    (vulkanDebugInfo && !IsUint32Constant(_, encoding)) ||
  ------------------
  |  Branch (3236:22): [True: 0, False: 0]
  |  Branch (3236:41): [True: 0, False: 0]
  ------------------
 3237|      0|                    OpenCLDebugInfo100DebugBaseTypeAttributeEncoding(
  ------------------
  |  Branch (3237:21): [True: 0, False: 0]
  ------------------
 3238|      0|                        vulkanDebugInfo
  ------------------
  |  Branch (3238:25): [True: 0, False: 0]
  ------------------
 3239|      0|                            ? GetUint32Constant(_, encoding)
 3240|      0|                            : encoding) != OpenCLDebugInfo100Unsigned) {
 3241|      0|                  invalid = true;
 3242|      0|                } else {
 3243|       |                  // DebugTypeBasic for DebugLocalVariable/DebugGlobalVariable
 3244|       |                  // must have Unsigned encoding and 32 or 64 as its size in
 3245|       |                  // bits.
 3246|      0|                  Instruction* size_in_bits =
 3247|      0|                      _.FindDef(component_count_type->word(6));
 3248|      0|                  if (!_.IsIntScalarType(size_in_bits->type_id()) ||
  ------------------
  |  Branch (3248:23): [True: 0, False: 0]
  ------------------
 3249|      0|                      (size_in_bits->word(3) != 32 &&
  ------------------
  |  Branch (3249:24): [True: 0, False: 0]
  ------------------
 3250|      0|                       size_in_bits->word(3) != 64)) {
  ------------------
  |  Branch (3250:24): [True: 0, False: 0]
  ------------------
 3251|      0|                    invalid = true;
 3252|      0|                  }
 3253|      0|                }
 3254|      0|              } else {
 3255|      0|                invalid = true;
 3256|      0|              }
 3257|      0|            } else {
 3258|      0|              invalid = true;
 3259|      0|            }
 3260|      0|            if (invalid) {
  ------------------
  |  Branch (3260:17): [True: 0, False: 0]
  ------------------
 3261|      0|              return _.diag(SPV_ERROR_INVALID_DATA, inst)
 3262|      0|                     << ext_inst_name() << ": Component Count must be "
 3263|      0|                     << "OpConstant with a 32- or 64-bits integer scalar type "
 3264|      0|                        "or "
 3265|      0|                     << "DebugGlobalVariable or DebugLocalVariable with a 32- "
 3266|      0|                        "or "
 3267|      0|                     << "64-bits unsigned integer scalar type";
 3268|      0|            }
 3269|      0|          }
 3270|      0|          break;
 3271|      0|        }
 3272|      0|        case CommonDebugInfoDebugTypedef: {
  ------------------
  |  Branch (3272:9): [True: 0, False: 0]
  ------------------
 3273|      0|          CHECK_OPERAND("Name", spv::Op::OpString, 5);
  ------------------
  |  |  132|      0|  do {                                                                      \
  |  |  133|      0|    auto result = ValidateOperandForDebugInfo(_, NAME, opcode, inst, index, \
  |  |  134|      0|                                              ext_inst_name);               \
  |  |  135|      0|    if (result != SPV_SUCCESS) return result;                               \
  |  |  ------------------
  |  |  |  Branch (135:9): [True: 0, False: 0]
  |  |  ------------------
  |  |  136|      0|  } while (0)
  |  |  ------------------
  |  |  |  Branch (136:12): [Folded - Ignored]
  |  |  ------------------
  ------------------
 3274|      0|          auto validate_base_type =
 3275|      0|              ValidateOperandBaseType(_, inst, 6, ext_inst_name);
 3276|      0|          if (validate_base_type != SPV_SUCCESS) return validate_base_type;
  ------------------
  |  Branch (3276:15): [True: 0, False: 0]
  ------------------
 3277|      0|          CHECK_DEBUG_OPERAND("Source", CommonDebugInfoDebugSource, 7);
  ------------------
  |  |  211|      0|  do {                                                                         \
  |  |  212|      0|    auto result = ValidateDebugInfoOperand(_, NAME, debug_opcode, inst, index, \
  |  |  213|      0|                                           ext_inst_name);                     \
  |  |  214|      0|    if (result != SPV_SUCCESS) return result;                                  \
  |  |  ------------------
  |  |  |  Branch (214:9): [True: 0, False: 0]
  |  |  ------------------
  |  |  215|      0|  } while (0)
  |  |  ------------------
  |  |  |  Branch (215:12): [Folded - Ignored]
  |  |  ------------------
  ------------------
 3278|      0|          CHECK_CONST_UINT_OPERAND("Line", 8);
  ------------------
  |  |  139|      0|  if (vulkanDebugInfo) {                                     \
  |  |  ------------------
  |  |  |  Branch (139:7): [True: 0, False: 0]
  |  |  ------------------
  |  |  140|      0|    auto result = ValidateUint32ConstantOperandForDebugInfo( \
  |  |  141|      0|        _, NAME, inst, index, ext_inst_name);                \
  |  |  142|      0|    if (result != SPV_SUCCESS) return result;                \
  |  |  ------------------
  |  |  |  Branch (142:9): [True: 0, False: 0]
  |  |  ------------------
  |  |  143|      0|  }
  ------------------
 3279|      0|          CHECK_CONST_UINT_OPERAND("Column", 9);
  ------------------
  |  |  139|      0|  if (vulkanDebugInfo) {                                     \
  |  |  ------------------
  |  |  |  Branch (139:7): [True: 0, False: 0]
  |  |  ------------------
  |  |  140|      0|    auto result = ValidateUint32ConstantOperandForDebugInfo( \
  |  |  141|      0|        _, NAME, inst, index, ext_inst_name);                \
  |  |  142|      0|    if (result != SPV_SUCCESS) return result;                \
  |  |  ------------------
  |  |  |  Branch (142:9): [True: 0, False: 0]
  |  |  ------------------
  |  |  143|      0|  }
  ------------------
 3280|      0|          auto validate_parent =
 3281|      0|              ValidateOperandLexicalScope(_, "Parent", inst, 10, ext_inst_name);
 3282|      0|          if (validate_parent != SPV_SUCCESS) return validate_parent;
  ------------------
  |  Branch (3282:15): [True: 0, False: 0]
  ------------------
 3283|      0|          break;
 3284|      0|        }
 3285|      0|        case CommonDebugInfoDebugTypeFunction: {
  ------------------
  |  Branch (3285:9): [True: 0, False: 0]
  ------------------
 3286|      0|          CHECK_CONST_UINT_OPERAND("Flags", 5);
  ------------------
  |  |  139|      0|  if (vulkanDebugInfo) {                                     \
  |  |  ------------------
  |  |  |  Branch (139:7): [True: 0, False: 0]
  |  |  ------------------
  |  |  140|      0|    auto result = ValidateUint32ConstantOperandForDebugInfo( \
  |  |  141|      0|        _, NAME, inst, index, ext_inst_name);                \
  |  |  142|      0|    if (result != SPV_SUCCESS) return result;                \
  |  |  ------------------
  |  |  |  Branch (142:9): [True: 0, False: 0]
  |  |  ------------------
  |  |  143|      0|  }
  ------------------
 3287|      0|          auto* return_type = _.FindDef(inst->word(6));
 3288|       |          // TODO: We need a spec discussion that we have to allow return and
 3289|       |          // parameter types of a DebugTypeFunction to have template parameter.
 3290|      0|          if (return_type->opcode() != spv::Op::OpTypeVoid) {
  ------------------
  |  Branch (3290:15): [True: 0, False: 0]
  ------------------
 3291|      0|            auto validate_return = ValidateOperandDebugType(
 3292|      0|                _, "Return Type", inst, 6, ext_inst_name, true);
 3293|      0|            if (validate_return != SPV_SUCCESS) return validate_return;
  ------------------
  |  Branch (3293:17): [True: 0, False: 0]
  ------------------
 3294|      0|          }
 3295|      0|          for (uint32_t word_index = 7; word_index < num_words; ++word_index) {
  ------------------
  |  Branch (3295:41): [True: 0, False: 0]
  ------------------
 3296|      0|            auto validate_param = ValidateOperandDebugType(
 3297|      0|                _, "Parameter Types", inst, word_index, ext_inst_name, true);
 3298|      0|            if (validate_param != SPV_SUCCESS) return validate_param;
  ------------------
  |  Branch (3298:17): [True: 0, False: 0]
  ------------------
 3299|      0|          }
 3300|      0|          break;
 3301|      0|        }
 3302|      0|        case CommonDebugInfoDebugTypeEnum: {
  ------------------
  |  Branch (3302:9): [True: 0, False: 0]
  ------------------
 3303|      0|          CHECK_OPERAND("Name", spv::Op::OpString, 5);
  ------------------
  |  |  132|      0|  do {                                                                      \
  |  |  133|      0|    auto result = ValidateOperandForDebugInfo(_, NAME, opcode, inst, index, \
  |  |  134|      0|                                              ext_inst_name);               \
  |  |  135|      0|    if (result != SPV_SUCCESS) return result;                               \
  |  |  ------------------
  |  |  |  Branch (135:9): [True: 0, False: 0]
  |  |  ------------------
  |  |  136|      0|  } while (0)
  |  |  ------------------
  |  |  |  Branch (136:12): [Folded - Ignored]
  |  |  ------------------
  ------------------
 3304|      0|          if (!DoesDebugInfoOperandMatchExpectation(
  ------------------
  |  Branch (3304:15): [True: 0, False: 0]
  ------------------
 3305|      0|                  _,
 3306|      0|                  [](CommonDebugInfoInstructions dbg_inst) {
 3307|      0|                    return dbg_inst == CommonDebugInfoDebugInfoNone;
 3308|      0|                  },
 3309|      0|                  inst, 6)) {
 3310|      0|            auto validate_underlying_type = ValidateOperandDebugType(
 3311|      0|                _, "Underlying Types", inst, 6, ext_inst_name, false);
 3312|      0|            if (validate_underlying_type != SPV_SUCCESS)
  ------------------
  |  Branch (3312:17): [True: 0, False: 0]
  ------------------
 3313|      0|              return validate_underlying_type;
 3314|      0|          }
 3315|      0|          CHECK_DEBUG_OPERAND("Source", CommonDebugInfoDebugSource, 7);
  ------------------
  |  |  211|      0|  do {                                                                         \
  |  |  212|      0|    auto result = ValidateDebugInfoOperand(_, NAME, debug_opcode, inst, index, \
  |  |  213|      0|                                           ext_inst_name);                     \
  |  |  214|      0|    if (result != SPV_SUCCESS) return result;                                  \
  |  |  ------------------
  |  |  |  Branch (214:9): [True: 0, False: 0]
  |  |  ------------------
  |  |  215|      0|  } while (0)
  |  |  ------------------
  |  |  |  Branch (215:12): [Folded - Ignored]
  |  |  ------------------
  ------------------
 3316|      0|          CHECK_CONST_UINT_OPERAND("Line", 8);
  ------------------
  |  |  139|      0|  if (vulkanDebugInfo) {                                     \
  |  |  ------------------
  |  |  |  Branch (139:7): [True: 0, False: 0]
  |  |  ------------------
  |  |  140|      0|    auto result = ValidateUint32ConstantOperandForDebugInfo( \
  |  |  141|      0|        _, NAME, inst, index, ext_inst_name);                \
  |  |  142|      0|    if (result != SPV_SUCCESS) return result;                \
  |  |  ------------------
  |  |  |  Branch (142:9): [True: 0, False: 0]
  |  |  ------------------
  |  |  143|      0|  }
  ------------------
 3317|      0|          CHECK_CONST_UINT_OPERAND("Column", 9);
  ------------------
  |  |  139|      0|  if (vulkanDebugInfo) {                                     \
  |  |  ------------------
  |  |  |  Branch (139:7): [True: 0, False: 0]
  |  |  ------------------
  |  |  140|      0|    auto result = ValidateUint32ConstantOperandForDebugInfo( \
  |  |  141|      0|        _, NAME, inst, index, ext_inst_name);                \
  |  |  142|      0|    if (result != SPV_SUCCESS) return result;                \
  |  |  ------------------
  |  |  |  Branch (142:9): [True: 0, False: 0]
  |  |  ------------------
  |  |  143|      0|  }
  ------------------
 3318|      0|          auto validate_parent =
 3319|      0|              ValidateOperandLexicalScope(_, "Parent", inst, 10, ext_inst_name);
 3320|      0|          if (validate_parent != SPV_SUCCESS) return validate_parent;
  ------------------
  |  Branch (3320:15): [True: 0, False: 0]
  ------------------
 3321|      0|          CHECK_OPERAND("Size", spv::Op::OpConstant, 11);
  ------------------
  |  |  132|      0|  do {                                                                      \
  |  |  133|      0|    auto result = ValidateOperandForDebugInfo(_, NAME, opcode, inst, index, \
  |  |  134|      0|                                              ext_inst_name);               \
  |  |  135|      0|    if (result != SPV_SUCCESS) return result;                               \
  |  |  ------------------
  |  |  |  Branch (135:9): [True: 0, False: 0]
  |  |  ------------------
  |  |  136|      0|  } while (0)
  |  |  ------------------
  |  |  |  Branch (136:12): [Folded - Ignored]
  |  |  ------------------
  ------------------
 3322|      0|          auto* size = _.FindDef(inst->word(11));
 3323|      0|          if (!_.IsIntScalarType(size->type_id()) || !size->word(3)) {
  ------------------
  |  Branch (3323:15): [True: 0, False: 0]
  |  Branch (3323:54): [True: 0, False: 0]
  ------------------
 3324|      0|            return _.diag(SPV_ERROR_INVALID_DATA, inst)
 3325|      0|                   << ext_inst_name() << ": expected operand Size is a "
 3326|      0|                   << "positive integer";
 3327|      0|          }
 3328|      0|          CHECK_CONST_UINT_OPERAND("Flags", 12);
  ------------------
  |  |  139|      0|  if (vulkanDebugInfo) {                                     \
  |  |  ------------------
  |  |  |  Branch (139:7): [True: 0, False: 0]
  |  |  ------------------
  |  |  140|      0|    auto result = ValidateUint32ConstantOperandForDebugInfo( \
  |  |  141|      0|        _, NAME, inst, index, ext_inst_name);                \
  |  |  142|      0|    if (result != SPV_SUCCESS) return result;                \
  |  |  ------------------
  |  |  |  Branch (142:9): [True: 0, False: 0]
  |  |  ------------------
  |  |  143|      0|  }
  ------------------
 3329|      0|          for (uint32_t word_index = 13; word_index + 1 < num_words;
  ------------------
  |  Branch (3329:42): [True: 0, False: 0]
  ------------------
 3330|      0|               word_index += 2) {
 3331|      0|            CHECK_OPERAND("Value", spv::Op::OpConstant, word_index);
  ------------------
  |  |  132|      0|  do {                                                                      \
  |  |  133|      0|    auto result = ValidateOperandForDebugInfo(_, NAME, opcode, inst, index, \
  |  |  134|      0|                                              ext_inst_name);               \
  |  |  135|      0|    if (result != SPV_SUCCESS) return result;                               \
  |  |  ------------------
  |  |  |  Branch (135:9): [True: 0, False: 0]
  |  |  ------------------
  |  |  136|      0|  } while (0)
  |  |  ------------------
  |  |  |  Branch (136:12): [Folded - Ignored]
  |  |  ------------------
  ------------------
 3332|      0|            CHECK_OPERAND("Name", spv::Op::OpString, word_index + 1);
  ------------------
  |  |  132|      0|  do {                                                                      \
  |  |  133|      0|    auto result = ValidateOperandForDebugInfo(_, NAME, opcode, inst, index, \
  |  |  134|      0|                                              ext_inst_name);               \
  |  |  135|      0|    if (result != SPV_SUCCESS) return result;                               \
  |  |  ------------------
  |  |  |  Branch (135:9): [True: 0, False: 0]
  |  |  ------------------
  |  |  136|      0|  } while (0)
  |  |  ------------------
  |  |  |  Branch (136:12): [Folded - Ignored]
  |  |  ------------------
  ------------------
 3333|      0|          }
 3334|      0|          break;
 3335|      0|        }
 3336|      0|        case CommonDebugInfoDebugTypeComposite: {
  ------------------
  |  Branch (3336:9): [True: 0, False: 0]
  ------------------
 3337|      0|          CHECK_OPERAND("Name", spv::Op::OpString, 5);
  ------------------
  |  |  132|      0|  do {                                                                      \
  |  |  133|      0|    auto result = ValidateOperandForDebugInfo(_, NAME, opcode, inst, index, \
  |  |  134|      0|                                              ext_inst_name);               \
  |  |  135|      0|    if (result != SPV_SUCCESS) return result;                               \
  |  |  ------------------
  |  |  |  Branch (135:9): [True: 0, False: 0]
  |  |  ------------------
  |  |  136|      0|  } while (0)
  |  |  ------------------
  |  |  |  Branch (136:12): [Folded - Ignored]
  |  |  ------------------
  ------------------
 3338|      0|          CHECK_DEBUG_OPERAND("Source", CommonDebugInfoDebugSource, 7);
  ------------------
  |  |  211|      0|  do {                                                                         \
  |  |  212|      0|    auto result = ValidateDebugInfoOperand(_, NAME, debug_opcode, inst, index, \
  |  |  213|      0|                                           ext_inst_name);                     \
  |  |  214|      0|    if (result != SPV_SUCCESS) return result;                                  \
  |  |  ------------------
  |  |  |  Branch (214:9): [True: 0, False: 0]
  |  |  ------------------
  |  |  215|      0|  } while (0)
  |  |  ------------------
  |  |  |  Branch (215:12): [Folded - Ignored]
  |  |  ------------------
  ------------------
 3339|      0|          CHECK_CONST_UINT_OPERAND("Line", 8);
  ------------------
  |  |  139|      0|  if (vulkanDebugInfo) {                                     \
  |  |  ------------------
  |  |  |  Branch (139:7): [True: 0, False: 0]
  |  |  ------------------
  |  |  140|      0|    auto result = ValidateUint32ConstantOperandForDebugInfo( \
  |  |  141|      0|        _, NAME, inst, index, ext_inst_name);                \
  |  |  142|      0|    if (result != SPV_SUCCESS) return result;                \
  |  |  ------------------
  |  |  |  Branch (142:9): [True: 0, False: 0]
  |  |  ------------------
  |  |  143|      0|  }
  ------------------
 3340|      0|          CHECK_CONST_UINT_OPERAND("Column", 9);
  ------------------
  |  |  139|      0|  if (vulkanDebugInfo) {                                     \
  |  |  ------------------
  |  |  |  Branch (139:7): [True: 0, False: 0]
  |  |  ------------------
  |  |  140|      0|    auto result = ValidateUint32ConstantOperandForDebugInfo( \
  |  |  141|      0|        _, NAME, inst, index, ext_inst_name);                \
  |  |  142|      0|    if (result != SPV_SUCCESS) return result;                \
  |  |  ------------------
  |  |  |  Branch (142:9): [True: 0, False: 0]
  |  |  ------------------
  |  |  143|      0|  }
  ------------------
 3341|      0|          auto validate_parent =
 3342|      0|              ValidateOperandLexicalScope(_, "Parent", inst, 10, ext_inst_name);
 3343|      0|          if (validate_parent != SPV_SUCCESS) return validate_parent;
  ------------------
  |  Branch (3343:15): [True: 0, False: 0]
  ------------------
 3344|      0|          CHECK_OPERAND("Linkage Name", spv::Op::OpString, 11);
  ------------------
  |  |  132|      0|  do {                                                                      \
  |  |  133|      0|    auto result = ValidateOperandForDebugInfo(_, NAME, opcode, inst, index, \
  |  |  134|      0|                                              ext_inst_name);               \
  |  |  135|      0|    if (result != SPV_SUCCESS) return result;                               \
  |  |  ------------------
  |  |  |  Branch (135:9): [True: 0, False: 0]
  |  |  ------------------
  |  |  136|      0|  } while (0)
  |  |  ------------------
  |  |  |  Branch (136:12): [Folded - Ignored]
  |  |  ------------------
  ------------------
 3345|      0|          if (!DoesDebugInfoOperandMatchExpectation(
  ------------------
  |  Branch (3345:15): [True: 0, False: 0]
  ------------------
 3346|      0|                  _,
 3347|      0|                  [](CommonDebugInfoInstructions dbg_inst) {
 3348|      0|                    return dbg_inst == CommonDebugInfoDebugInfoNone;
 3349|      0|                  },
 3350|      0|                  inst, 12)) {
 3351|      0|            CHECK_OPERAND("Size", spv::Op::OpConstant, 12);
  ------------------
  |  |  132|      0|  do {                                                                      \
  |  |  133|      0|    auto result = ValidateOperandForDebugInfo(_, NAME, opcode, inst, index, \
  |  |  134|      0|                                              ext_inst_name);               \
  |  |  135|      0|    if (result != SPV_SUCCESS) return result;                               \
  |  |  ------------------
  |  |  |  Branch (135:9): [True: 0, False: 0]
  |  |  ------------------
  |  |  136|      0|  } while (0)
  |  |  ------------------
  |  |  |  Branch (136:12): [Folded - Ignored]
  |  |  ------------------
  ------------------
 3352|      0|          }
 3353|      0|          CHECK_CONST_UINT_OPERAND("Flags", 13);
  ------------------
  |  |  139|      0|  if (vulkanDebugInfo) {                                     \
  |  |  ------------------
  |  |  |  Branch (139:7): [True: 0, False: 0]
  |  |  ------------------
  |  |  140|      0|    auto result = ValidateUint32ConstantOperandForDebugInfo( \
  |  |  141|      0|        _, NAME, inst, index, ext_inst_name);                \
  |  |  142|      0|    if (result != SPV_SUCCESS) return result;                \
  |  |  ------------------
  |  |  |  Branch (142:9): [True: 0, False: 0]
  |  |  ------------------
  |  |  143|      0|  }
  ------------------
 3354|      0|          for (uint32_t word_index = 14; word_index < num_words; ++word_index) {
  ------------------
  |  Branch (3354:42): [True: 0, False: 0]
  ------------------
 3355|      0|            if (!DoesDebugInfoOperandMatchExpectation(
  ------------------
  |  Branch (3355:17): [True: 0, False: 0]
  ------------------
 3356|      0|                    _,
 3357|      0|                    [](CommonDebugInfoInstructions dbg_inst) {
 3358|      0|                      return dbg_inst == CommonDebugInfoDebugTypeMember ||
 3359|      0|                             dbg_inst == CommonDebugInfoDebugFunction ||
 3360|      0|                             dbg_inst == CommonDebugInfoDebugTypeInheritance;
 3361|      0|                    },
 3362|      0|                    inst, word_index)) {
 3363|      0|              return _.diag(SPV_ERROR_INVALID_DATA, inst)
 3364|      0|                     << ext_inst_name() << ": "
 3365|      0|                     << "expected operand Members "
 3366|      0|                     << "must be DebugTypeMember, DebugFunction, or "
 3367|      0|                        "DebugTypeInheritance";
 3368|      0|            }
 3369|      0|          }
 3370|      0|          break;
 3371|      0|        }
 3372|      0|        case CommonDebugInfoDebugTypeMember: {
  ------------------
  |  Branch (3372:9): [True: 0, False: 0]
  ------------------
 3373|      0|          CHECK_OPERAND("Name", spv::Op::OpString, 5);
  ------------------
  |  |  132|      0|  do {                                                                      \
  |  |  133|      0|    auto result = ValidateOperandForDebugInfo(_, NAME, opcode, inst, index, \
  |  |  134|      0|                                              ext_inst_name);               \
  |  |  135|      0|    if (result != SPV_SUCCESS) return result;                               \
  |  |  ------------------
  |  |  |  Branch (135:9): [True: 0, False: 0]
  |  |  ------------------
  |  |  136|      0|  } while (0)
  |  |  ------------------
  |  |  |  Branch (136:12): [Folded - Ignored]
  |  |  ------------------
  ------------------
 3374|       |          // TODO: We need a spec discussion that we have to allow member types
 3375|       |          // to have template parameter.
 3376|      0|          auto validate_type =
 3377|      0|              ValidateOperandDebugType(_, "Type", inst, 6, ext_inst_name, true);
 3378|      0|          if (validate_type != SPV_SUCCESS) return validate_type;
  ------------------
  |  Branch (3378:15): [True: 0, False: 0]
  ------------------
 3379|      0|          CHECK_DEBUG_OPERAND("Source", CommonDebugInfoDebugSource, 7);
  ------------------
  |  |  211|      0|  do {                                                                         \
  |  |  212|      0|    auto result = ValidateDebugInfoOperand(_, NAME, debug_opcode, inst, index, \
  |  |  213|      0|                                           ext_inst_name);                     \
  |  |  214|      0|    if (result != SPV_SUCCESS) return result;                                  \
  |  |  ------------------
  |  |  |  Branch (214:9): [True: 0, False: 0]
  |  |  ------------------
  |  |  215|      0|  } while (0)
  |  |  ------------------
  |  |  |  Branch (215:12): [Folded - Ignored]
  |  |  ------------------
  ------------------
 3380|      0|          CHECK_CONST_UINT_OPERAND("Line", 8);
  ------------------
  |  |  139|      0|  if (vulkanDebugInfo) {                                     \
  |  |  ------------------
  |  |  |  Branch (139:7): [True: 0, False: 0]
  |  |  ------------------
  |  |  140|      0|    auto result = ValidateUint32ConstantOperandForDebugInfo( \
  |  |  141|      0|        _, NAME, inst, index, ext_inst_name);                \
  |  |  142|      0|    if (result != SPV_SUCCESS) return result;                \
  |  |  ------------------
  |  |  |  Branch (142:9): [True: 0, False: 0]
  |  |  ------------------
  |  |  143|      0|  }
  ------------------
 3381|      0|          CHECK_CONST_UINT_OPERAND("Column", 9);
  ------------------
  |  |  139|      0|  if (vulkanDebugInfo) {                                     \
  |  |  ------------------
  |  |  |  Branch (139:7): [True: 0, False: 0]
  |  |  ------------------
  |  |  140|      0|    auto result = ValidateUint32ConstantOperandForDebugInfo( \
  |  |  141|      0|        _, NAME, inst, index, ext_inst_name);                \
  |  |  142|      0|    if (result != SPV_SUCCESS) return result;                \
  |  |  ------------------
  |  |  |  Branch (142:9): [True: 0, False: 0]
  |  |  ------------------
  |  |  143|      0|  }
  ------------------
 3382|       |          // NonSemantic.Shader.DebugInfo doesn't have the Parent operand
 3383|      0|          if (vulkanDebugInfo) {
  ------------------
  |  Branch (3383:15): [True: 0, False: 0]
  ------------------
 3384|      0|            CHECK_OPERAND("Offset", spv::Op::OpConstant, 10);
  ------------------
  |  |  132|      0|  do {                                                                      \
  |  |  133|      0|    auto result = ValidateOperandForDebugInfo(_, NAME, opcode, inst, index, \
  |  |  134|      0|                                              ext_inst_name);               \
  |  |  135|      0|    if (result != SPV_SUCCESS) return result;                               \
  |  |  ------------------
  |  |  |  Branch (135:9): [True: 0, False: 0]
  |  |  ------------------
  |  |  136|      0|  } while (0)
  |  |  ------------------
  |  |  |  Branch (136:12): [Folded - Ignored]
  |  |  ------------------
  ------------------
 3385|      0|            CHECK_OPERAND("Size", spv::Op::OpConstant, 11);
  ------------------
  |  |  132|      0|  do {                                                                      \
  |  |  133|      0|    auto result = ValidateOperandForDebugInfo(_, NAME, opcode, inst, index, \
  |  |  134|      0|                                              ext_inst_name);               \
  |  |  135|      0|    if (result != SPV_SUCCESS) return result;                               \
  |  |  ------------------
  |  |  |  Branch (135:9): [True: 0, False: 0]
  |  |  ------------------
  |  |  136|      0|  } while (0)
  |  |  ------------------
  |  |  |  Branch (136:12): [Folded - Ignored]
  |  |  ------------------
  ------------------
 3386|      0|            CHECK_CONST_UINT_OPERAND("Flags", 12);
  ------------------
  |  |  139|      0|  if (vulkanDebugInfo) {                                     \
  |  |  ------------------
  |  |  |  Branch (139:7): [True: 0, False: 0]
  |  |  ------------------
  |  |  140|      0|    auto result = ValidateUint32ConstantOperandForDebugInfo( \
  |  |  141|      0|        _, NAME, inst, index, ext_inst_name);                \
  |  |  142|      0|    if (result != SPV_SUCCESS) return result;                \
  |  |  ------------------
  |  |  |  Branch (142:9): [True: 0, False: 0]
  |  |  ------------------
  |  |  143|      0|  }
  ------------------
 3387|      0|            if (num_words == 14)
  ------------------
  |  Branch (3387:17): [True: 0, False: 0]
  ------------------
 3388|      0|              CHECK_OPERAND("Value", spv::Op::OpConstant, 13);
  ------------------
  |  |  132|      0|  do {                                                                      \
  |  |  133|      0|    auto result = ValidateOperandForDebugInfo(_, NAME, opcode, inst, index, \
  |  |  134|      0|                                              ext_inst_name);               \
  |  |  135|      0|    if (result != SPV_SUCCESS) return result;                               \
  |  |  ------------------
  |  |  |  Branch (135:9): [True: 0, False: 0]
  |  |  ------------------
  |  |  136|      0|  } while (0)
  |  |  ------------------
  |  |  |  Branch (136:12): [Folded - Ignored]
  |  |  ------------------
  ------------------
 3389|      0|          } else {
 3390|      0|            CHECK_DEBUG_OPERAND("Parent", CommonDebugInfoDebugTypeComposite,
  ------------------
  |  |  211|      0|  do {                                                                         \
  |  |  212|      0|    auto result = ValidateDebugInfoOperand(_, NAME, debug_opcode, inst, index, \
  |  |  213|      0|                                           ext_inst_name);                     \
  |  |  214|      0|    if (result != SPV_SUCCESS) return result;                                  \
  |  |  ------------------
  |  |  |  Branch (214:9): [True: 0, False: 0]
  |  |  ------------------
  |  |  215|      0|  } while (0)
  |  |  ------------------
  |  |  |  Branch (215:12): [Folded - Ignored]
  |  |  ------------------
  ------------------
 3391|      0|                                10);
 3392|      0|            CHECK_OPERAND("Offset", spv::Op::OpConstant, 11);
  ------------------
  |  |  132|      0|  do {                                                                      \
  |  |  133|      0|    auto result = ValidateOperandForDebugInfo(_, NAME, opcode, inst, index, \
  |  |  134|      0|                                              ext_inst_name);               \
  |  |  135|      0|    if (result != SPV_SUCCESS) return result;                               \
  |  |  ------------------
  |  |  |  Branch (135:9): [True: 0, False: 0]
  |  |  ------------------
  |  |  136|      0|  } while (0)
  |  |  ------------------
  |  |  |  Branch (136:12): [Folded - Ignored]
  |  |  ------------------
  ------------------
 3393|      0|            CHECK_OPERAND("Size", spv::Op::OpConstant, 12);
  ------------------
  |  |  132|      0|  do {                                                                      \
  |  |  133|      0|    auto result = ValidateOperandForDebugInfo(_, NAME, opcode, inst, index, \
  |  |  134|      0|                                              ext_inst_name);               \
  |  |  135|      0|    if (result != SPV_SUCCESS) return result;                               \
  |  |  ------------------
  |  |  |  Branch (135:9): [True: 0, False: 0]
  |  |  ------------------
  |  |  136|      0|  } while (0)
  |  |  ------------------
  |  |  |  Branch (136:12): [Folded - Ignored]
  |  |  ------------------
  ------------------
 3394|      0|            CHECK_CONST_UINT_OPERAND("Flags", 13);
  ------------------
  |  |  139|      0|  if (vulkanDebugInfo) {                                     \
  |  |  ------------------
  |  |  |  Branch (139:7): [True: 0, False: 0]
  |  |  ------------------
  |  |  140|      0|    auto result = ValidateUint32ConstantOperandForDebugInfo( \
  |  |  141|      0|        _, NAME, inst, index, ext_inst_name);                \
  |  |  142|      0|    if (result != SPV_SUCCESS) return result;                \
  |  |  ------------------
  |  |  |  Branch (142:9): [True: 0, False: 0]
  |  |  ------------------
  |  |  143|      0|  }
  ------------------
 3395|      0|            if (num_words == 15)
  ------------------
  |  Branch (3395:17): [True: 0, False: 0]
  ------------------
 3396|      0|              CHECK_OPERAND("Value", spv::Op::OpConstant, 14);
  ------------------
  |  |  132|      0|  do {                                                                      \
  |  |  133|      0|    auto result = ValidateOperandForDebugInfo(_, NAME, opcode, inst, index, \
  |  |  134|      0|                                              ext_inst_name);               \
  |  |  135|      0|    if (result != SPV_SUCCESS) return result;                               \
  |  |  ------------------
  |  |  |  Branch (135:9): [True: 0, False: 0]
  |  |  ------------------
  |  |  136|      0|  } while (0)
  |  |  ------------------
  |  |  |  Branch (136:12): [Folded - Ignored]
  |  |  ------------------
  ------------------
 3397|      0|          }
 3398|      0|          break;
 3399|      0|        }
 3400|      0|        case CommonDebugInfoDebugTypeInheritance: {
  ------------------
  |  Branch (3400:9): [True: 0, False: 0]
  ------------------
 3401|      0|          CHECK_DEBUG_OPERAND("Child", CommonDebugInfoDebugTypeComposite, 5);
  ------------------
  |  |  211|      0|  do {                                                                         \
  |  |  212|      0|    auto result = ValidateDebugInfoOperand(_, NAME, debug_opcode, inst, index, \
  |  |  213|      0|                                           ext_inst_name);                     \
  |  |  214|      0|    if (result != SPV_SUCCESS) return result;                                  \
  |  |  ------------------
  |  |  |  Branch (214:9): [True: 0, False: 0]
  |  |  ------------------
  |  |  215|      0|  } while (0)
  |  |  ------------------
  |  |  |  Branch (215:12): [Folded - Ignored]
  |  |  ------------------
  ------------------
 3402|      0|          auto* debug_inst = _.FindDef(inst->word(5));
 3403|      0|          auto composite_type =
 3404|      0|              OpenCLDebugInfo100DebugCompositeType(debug_inst->word(6));
 3405|      0|          if (composite_type != OpenCLDebugInfo100Class &&
  ------------------
  |  Branch (3405:15): [True: 0, False: 0]
  ------------------
 3406|      0|              composite_type != OpenCLDebugInfo100Structure) {
  ------------------
  |  Branch (3406:15): [True: 0, False: 0]
  ------------------
 3407|      0|            return _.diag(SPV_ERROR_INVALID_DATA, inst)
 3408|      0|                   << ext_inst_name() << ": "
 3409|      0|                   << "expected operand Child must be class or struct debug "
 3410|      0|                      "type";
 3411|      0|          }
 3412|      0|          CHECK_DEBUG_OPERAND("Parent", CommonDebugInfoDebugTypeComposite, 6);
  ------------------
  |  |  211|      0|  do {                                                                         \
  |  |  212|      0|    auto result = ValidateDebugInfoOperand(_, NAME, debug_opcode, inst, index, \
  |  |  213|      0|                                           ext_inst_name);                     \
  |  |  214|      0|    if (result != SPV_SUCCESS) return result;                                  \
  |  |  ------------------
  |  |  |  Branch (214:9): [True: 0, False: 0]
  |  |  ------------------
  |  |  215|      0|  } while (0)
  |  |  ------------------
  |  |  |  Branch (215:12): [Folded - Ignored]
  |  |  ------------------
  ------------------
 3413|      0|          debug_inst = _.FindDef(inst->word(6));
 3414|      0|          composite_type =
 3415|      0|              OpenCLDebugInfo100DebugCompositeType(debug_inst->word(6));
 3416|      0|          if (composite_type != OpenCLDebugInfo100Class &&
  ------------------
  |  Branch (3416:15): [True: 0, False: 0]
  ------------------
 3417|      0|              composite_type != OpenCLDebugInfo100Structure) {
  ------------------
  |  Branch (3417:15): [True: 0, False: 0]
  ------------------
 3418|      0|            return _.diag(SPV_ERROR_INVALID_DATA, inst)
 3419|      0|                   << ext_inst_name() << ": "
 3420|      0|                   << "expected operand Parent must be class or struct debug "
 3421|      0|                      "type";
 3422|      0|          }
 3423|      0|          CHECK_OPERAND("Offset", spv::Op::OpConstant, 7);
  ------------------
  |  |  132|      0|  do {                                                                      \
  |  |  133|      0|    auto result = ValidateOperandForDebugInfo(_, NAME, opcode, inst, index, \
  |  |  134|      0|                                              ext_inst_name);               \
  |  |  135|      0|    if (result != SPV_SUCCESS) return result;                               \
  |  |  ------------------
  |  |  |  Branch (135:9): [True: 0, False: 0]
  |  |  ------------------
  |  |  136|      0|  } while (0)
  |  |  ------------------
  |  |  |  Branch (136:12): [Folded - Ignored]
  |  |  ------------------
  ------------------
 3424|      0|          CHECK_OPERAND("Size", spv::Op::OpConstant, 8);
  ------------------
  |  |  132|      0|  do {                                                                      \
  |  |  133|      0|    auto result = ValidateOperandForDebugInfo(_, NAME, opcode, inst, index, \
  |  |  134|      0|                                              ext_inst_name);               \
  |  |  135|      0|    if (result != SPV_SUCCESS) return result;                               \
  |  |  ------------------
  |  |  |  Branch (135:9): [True: 0, False: 0]
  |  |  ------------------
  |  |  136|      0|  } while (0)
  |  |  ------------------
  |  |  |  Branch (136:12): [Folded - Ignored]
  |  |  ------------------
  ------------------
 3425|      0|          CHECK_CONST_UINT_OPERAND("Flags", 9);
  ------------------
  |  |  139|      0|  if (vulkanDebugInfo) {                                     \
  |  |  ------------------
  |  |  |  Branch (139:7): [True: 0, False: 0]
  |  |  ------------------
  |  |  140|      0|    auto result = ValidateUint32ConstantOperandForDebugInfo( \
  |  |  141|      0|        _, NAME, inst, index, ext_inst_name);                \
  |  |  142|      0|    if (result != SPV_SUCCESS) return result;                \
  |  |  ------------------
  |  |  |  Branch (142:9): [True: 0, False: 0]
  |  |  ------------------
  |  |  143|      0|  }
  ------------------
 3426|      0|          break;
 3427|      0|        }
 3428|      0|        case CommonDebugInfoDebugFunction: {
  ------------------
  |  Branch (3428:9): [True: 0, False: 0]
  ------------------
 3429|      0|          CHECK_OPERAND("Name", spv::Op::OpString, 5);
  ------------------
  |  |  132|      0|  do {                                                                      \
  |  |  133|      0|    auto result = ValidateOperandForDebugInfo(_, NAME, opcode, inst, index, \
  |  |  134|      0|                                              ext_inst_name);               \
  |  |  135|      0|    if (result != SPV_SUCCESS) return result;                               \
  |  |  ------------------
  |  |  |  Branch (135:9): [True: 0, False: 0]
  |  |  ------------------
  |  |  136|      0|  } while (0)
  |  |  ------------------
  |  |  |  Branch (136:12): [Folded - Ignored]
  |  |  ------------------
  ------------------
 3430|      0|          auto validate_type = ValidateOperandDebugType(_, "Type", inst, 6,
 3431|      0|                                                        ext_inst_name, false);
 3432|      0|          if (validate_type != SPV_SUCCESS) return validate_type;
  ------------------
  |  Branch (3432:15): [True: 0, False: 0]
  ------------------
 3433|      0|          CHECK_DEBUG_OPERAND("Source", CommonDebugInfoDebugSource, 7);
  ------------------
  |  |  211|      0|  do {                                                                         \
  |  |  212|      0|    auto result = ValidateDebugInfoOperand(_, NAME, debug_opcode, inst, index, \
  |  |  213|      0|                                           ext_inst_name);                     \
  |  |  214|      0|    if (result != SPV_SUCCESS) return result;                                  \
  |  |  ------------------
  |  |  |  Branch (214:9): [True: 0, False: 0]
  |  |  ------------------
  |  |  215|      0|  } while (0)
  |  |  ------------------
  |  |  |  Branch (215:12): [Folded - Ignored]
  |  |  ------------------
  ------------------
 3434|      0|          CHECK_CONST_UINT_OPERAND("Line", 8);
  ------------------
  |  |  139|      0|  if (vulkanDebugInfo) {                                     \
  |  |  ------------------
  |  |  |  Branch (139:7): [True: 0, False: 0]
  |  |  ------------------
  |  |  140|      0|    auto result = ValidateUint32ConstantOperandForDebugInfo( \
  |  |  141|      0|        _, NAME, inst, index, ext_inst_name);                \
  |  |  142|      0|    if (result != SPV_SUCCESS) return result;                \
  |  |  ------------------
  |  |  |  Branch (142:9): [True: 0, False: 0]
  |  |  ------------------
  |  |  143|      0|  }
  ------------------
 3435|      0|          CHECK_CONST_UINT_OPERAND("Column", 9);
  ------------------
  |  |  139|      0|  if (vulkanDebugInfo) {                                     \
  |  |  ------------------
  |  |  |  Branch (139:7): [True: 0, False: 0]
  |  |  ------------------
  |  |  140|      0|    auto result = ValidateUint32ConstantOperandForDebugInfo( \
  |  |  141|      0|        _, NAME, inst, index, ext_inst_name);                \
  |  |  142|      0|    if (result != SPV_SUCCESS) return result;                \
  |  |  ------------------
  |  |  |  Branch (142:9): [True: 0, False: 0]
  |  |  ------------------
  |  |  143|      0|  }
  ------------------
 3436|      0|          auto validate_parent =
 3437|      0|              ValidateOperandLexicalScope(_, "Parent", inst, 10, ext_inst_name);
 3438|      0|          if (validate_parent != SPV_SUCCESS) return validate_parent;
  ------------------
  |  Branch (3438:15): [True: 0, False: 0]
  ------------------
 3439|      0|          CHECK_OPERAND("Linkage Name", spv::Op::OpString, 11);
  ------------------
  |  |  132|      0|  do {                                                                      \
  |  |  133|      0|    auto result = ValidateOperandForDebugInfo(_, NAME, opcode, inst, index, \
  |  |  134|      0|                                              ext_inst_name);               \
  |  |  135|      0|    if (result != SPV_SUCCESS) return result;                               \
  |  |  ------------------
  |  |  |  Branch (135:9): [True: 0, False: 0]
  |  |  ------------------
  |  |  136|      0|  } while (0)
  |  |  ------------------
  |  |  |  Branch (136:12): [Folded - Ignored]
  |  |  ------------------
  ------------------
 3440|      0|          CHECK_CONST_UINT_OPERAND("Flags", 12);
  ------------------
  |  |  139|      0|  if (vulkanDebugInfo) {                                     \
  |  |  ------------------
  |  |  |  Branch (139:7): [True: 0, False: 0]
  |  |  ------------------
  |  |  140|      0|    auto result = ValidateUint32ConstantOperandForDebugInfo( \
  |  |  141|      0|        _, NAME, inst, index, ext_inst_name);                \
  |  |  142|      0|    if (result != SPV_SUCCESS) return result;                \
  |  |  ------------------
  |  |  |  Branch (142:9): [True: 0, False: 0]
  |  |  ------------------
  |  |  143|      0|  }
  ------------------
 3441|      0|          CHECK_CONST_UINT_OPERAND("Scope Line", 13);
  ------------------
  |  |  139|      0|  if (vulkanDebugInfo) {                                     \
  |  |  ------------------
  |  |  |  Branch (139:7): [True: 0, False: 0]
  |  |  ------------------
  |  |  140|      0|    auto result = ValidateUint32ConstantOperandForDebugInfo( \
  |  |  141|      0|        _, NAME, inst, index, ext_inst_name);                \
  |  |  142|      0|    if (result != SPV_SUCCESS) return result;                \
  |  |  ------------------
  |  |  |  Branch (142:9): [True: 0, False: 0]
  |  |  ------------------
  |  |  143|      0|  }
  ------------------
 3442|       |          // NonSemantic.Shader.DebugInfo.100 doesn't include a reference to the
 3443|       |          // OpFunction
 3444|      0|          if (vulkanDebugInfo) {
  ------------------
  |  Branch (3444:15): [True: 0, False: 0]
  ------------------
 3445|      0|            if (num_words == 15) {
  ------------------
  |  Branch (3445:17): [True: 0, False: 0]
  ------------------
 3446|      0|              CHECK_DEBUG_OPERAND("Declaration",
  ------------------
  |  |  211|      0|  do {                                                                         \
  |  |  212|      0|    auto result = ValidateDebugInfoOperand(_, NAME, debug_opcode, inst, index, \
  |  |  213|      0|                                           ext_inst_name);                     \
  |  |  214|      0|    if (result != SPV_SUCCESS) return result;                                  \
  |  |  ------------------
  |  |  |  Branch (214:9): [True: 0, False: 0]
  |  |  ------------------
  |  |  215|      0|  } while (0)
  |  |  ------------------
  |  |  |  Branch (215:12): [Folded - Ignored]
  |  |  ------------------
  ------------------
 3447|      0|                                  CommonDebugInfoDebugFunctionDeclaration, 14);
 3448|      0|            }
 3449|      0|          } else {
 3450|      0|            if (!DoesDebugInfoOperandMatchExpectation(
  ------------------
  |  Branch (3450:17): [True: 0, False: 0]
  ------------------
 3451|      0|                    _,
 3452|      0|                    [](CommonDebugInfoInstructions dbg_inst) {
 3453|      0|                      return dbg_inst == CommonDebugInfoDebugInfoNone;
 3454|      0|                    },
 3455|      0|                    inst, 14)) {
 3456|      0|              CHECK_OPERAND("Function", spv::Op::OpFunction, 14);
  ------------------
  |  |  132|      0|  do {                                                                      \
  |  |  133|      0|    auto result = ValidateOperandForDebugInfo(_, NAME, opcode, inst, index, \
  |  |  134|      0|                                              ext_inst_name);               \
  |  |  135|      0|    if (result != SPV_SUCCESS) return result;                               \
  |  |  ------------------
  |  |  |  Branch (135:9): [True: 0, False: 0]
  |  |  ------------------
  |  |  136|      0|  } while (0)
  |  |  ------------------
  |  |  |  Branch (136:12): [Folded - Ignored]
  |  |  ------------------
  ------------------
 3457|      0|            }
 3458|      0|            if (num_words == 16) {
  ------------------
  |  Branch (3458:17): [True: 0, False: 0]
  ------------------
 3459|      0|              CHECK_DEBUG_OPERAND("Declaration",
  ------------------
  |  |  211|      0|  do {                                                                         \
  |  |  212|      0|    auto result = ValidateDebugInfoOperand(_, NAME, debug_opcode, inst, index, \
  |  |  213|      0|                                           ext_inst_name);                     \
  |  |  214|      0|    if (result != SPV_SUCCESS) return result;                                  \
  |  |  ------------------
  |  |  |  Branch (214:9): [True: 0, False: 0]
  |  |  ------------------
  |  |  215|      0|  } while (0)
  |  |  ------------------
  |  |  |  Branch (215:12): [Folded - Ignored]
  |  |  ------------------
  ------------------
 3460|      0|                                  CommonDebugInfoDebugFunctionDeclaration, 15);
 3461|      0|            }
 3462|      0|          }
 3463|      0|          break;
 3464|      0|        }
 3465|      0|        case CommonDebugInfoDebugFunctionDeclaration: {
  ------------------
  |  Branch (3465:9): [True: 0, False: 0]
  ------------------
 3466|      0|          CHECK_OPERAND("Name", spv::Op::OpString, 5);
  ------------------
  |  |  132|      0|  do {                                                                      \
  |  |  133|      0|    auto result = ValidateOperandForDebugInfo(_, NAME, opcode, inst, index, \
  |  |  134|      0|                                              ext_inst_name);               \
  |  |  135|      0|    if (result != SPV_SUCCESS) return result;                               \
  |  |  ------------------
  |  |  |  Branch (135:9): [True: 0, False: 0]
  |  |  ------------------
  |  |  136|      0|  } while (0)
  |  |  ------------------
  |  |  |  Branch (136:12): [Folded - Ignored]
  |  |  ------------------
  ------------------
 3467|      0|          auto validate_type = ValidateOperandDebugType(_, "Type", inst, 6,
 3468|      0|                                                        ext_inst_name, false);
 3469|      0|          if (validate_type != SPV_SUCCESS) return validate_type;
  ------------------
  |  Branch (3469:15): [True: 0, False: 0]
  ------------------
 3470|      0|          CHECK_DEBUG_OPERAND("Source", CommonDebugInfoDebugSource, 7);
  ------------------
  |  |  211|      0|  do {                                                                         \
  |  |  212|      0|    auto result = ValidateDebugInfoOperand(_, NAME, debug_opcode, inst, index, \
  |  |  213|      0|                                           ext_inst_name);                     \
  |  |  214|      0|    if (result != SPV_SUCCESS) return result;                                  \
  |  |  ------------------
  |  |  |  Branch (214:9): [True: 0, False: 0]
  |  |  ------------------
  |  |  215|      0|  } while (0)
  |  |  ------------------
  |  |  |  Branch (215:12): [Folded - Ignored]
  |  |  ------------------
  ------------------
 3471|      0|          CHECK_CONST_UINT_OPERAND("Line", 8);
  ------------------
  |  |  139|      0|  if (vulkanDebugInfo) {                                     \
  |  |  ------------------
  |  |  |  Branch (139:7): [True: 0, False: 0]
  |  |  ------------------
  |  |  140|      0|    auto result = ValidateUint32ConstantOperandForDebugInfo( \
  |  |  141|      0|        _, NAME, inst, index, ext_inst_name);                \
  |  |  142|      0|    if (result != SPV_SUCCESS) return result;                \
  |  |  ------------------
  |  |  |  Branch (142:9): [True: 0, False: 0]
  |  |  ------------------
  |  |  143|      0|  }
  ------------------
 3472|      0|          CHECK_CONST_UINT_OPERAND("Column", 9);
  ------------------
  |  |  139|      0|  if (vulkanDebugInfo) {                                     \
  |  |  ------------------
  |  |  |  Branch (139:7): [True: 0, False: 0]
  |  |  ------------------
  |  |  140|      0|    auto result = ValidateUint32ConstantOperandForDebugInfo( \
  |  |  141|      0|        _, NAME, inst, index, ext_inst_name);                \
  |  |  142|      0|    if (result != SPV_SUCCESS) return result;                \
  |  |  ------------------
  |  |  |  Branch (142:9): [True: 0, False: 0]
  |  |  ------------------
  |  |  143|      0|  }
  ------------------
 3473|      0|          auto validate_parent =
 3474|      0|              ValidateOperandLexicalScope(_, "Parent", inst, 10, ext_inst_name);
 3475|      0|          if (validate_parent != SPV_SUCCESS) return validate_parent;
  ------------------
  |  Branch (3475:15): [True: 0, False: 0]
  ------------------
 3476|      0|          CHECK_OPERAND("Linkage Name", spv::Op::OpString, 11);
  ------------------
  |  |  132|      0|  do {                                                                      \
  |  |  133|      0|    auto result = ValidateOperandForDebugInfo(_, NAME, opcode, inst, index, \
  |  |  134|      0|                                              ext_inst_name);               \
  |  |  135|      0|    if (result != SPV_SUCCESS) return result;                               \
  |  |  ------------------
  |  |  |  Branch (135:9): [True: 0, False: 0]
  |  |  ------------------
  |  |  136|      0|  } while (0)
  |  |  ------------------
  |  |  |  Branch (136:12): [Folded - Ignored]
  |  |  ------------------
  ------------------
 3477|      0|          CHECK_CONST_UINT_OPERAND("Flags", 12);
  ------------------
  |  |  139|      0|  if (vulkanDebugInfo) {                                     \
  |  |  ------------------
  |  |  |  Branch (139:7): [True: 0, False: 0]
  |  |  ------------------
  |  |  140|      0|    auto result = ValidateUint32ConstantOperandForDebugInfo( \
  |  |  141|      0|        _, NAME, inst, index, ext_inst_name);                \
  |  |  142|      0|    if (result != SPV_SUCCESS) return result;                \
  |  |  ------------------
  |  |  |  Branch (142:9): [True: 0, False: 0]
  |  |  ------------------
  |  |  143|      0|  }
  ------------------
 3478|      0|          break;
 3479|      0|        }
 3480|      0|        case CommonDebugInfoDebugLexicalBlock: {
  ------------------
  |  Branch (3480:9): [True: 0, False: 0]
  ------------------
 3481|      0|          CHECK_DEBUG_OPERAND("Source", CommonDebugInfoDebugSource, 5);
  ------------------
  |  |  211|      0|  do {                                                                         \
  |  |  212|      0|    auto result = ValidateDebugInfoOperand(_, NAME, debug_opcode, inst, index, \
  |  |  213|      0|                                           ext_inst_name);                     \
  |  |  214|      0|    if (result != SPV_SUCCESS) return result;                                  \
  |  |  ------------------
  |  |  |  Branch (214:9): [True: 0, False: 0]
  |  |  ------------------
  |  |  215|      0|  } while (0)
  |  |  ------------------
  |  |  |  Branch (215:12): [Folded - Ignored]
  |  |  ------------------
  ------------------
 3482|      0|          CHECK_CONST_UINT_OPERAND("Line", 6);
  ------------------
  |  |  139|      0|  if (vulkanDebugInfo) {                                     \
  |  |  ------------------
  |  |  |  Branch (139:7): [True: 0, False: 0]
  |  |  ------------------
  |  |  140|      0|    auto result = ValidateUint32ConstantOperandForDebugInfo( \
  |  |  141|      0|        _, NAME, inst, index, ext_inst_name);                \
  |  |  142|      0|    if (result != SPV_SUCCESS) return result;                \
  |  |  ------------------
  |  |  |  Branch (142:9): [True: 0, False: 0]
  |  |  ------------------
  |  |  143|      0|  }
  ------------------
 3483|      0|          CHECK_CONST_UINT_OPERAND("Column", 7);
  ------------------
  |  |  139|      0|  if (vulkanDebugInfo) {                                     \
  |  |  ------------------
  |  |  |  Branch (139:7): [True: 0, False: 0]
  |  |  ------------------
  |  |  140|      0|    auto result = ValidateUint32ConstantOperandForDebugInfo( \
  |  |  141|      0|        _, NAME, inst, index, ext_inst_name);                \
  |  |  142|      0|    if (result != SPV_SUCCESS) return result;                \
  |  |  ------------------
  |  |  |  Branch (142:9): [True: 0, False: 0]
  |  |  ------------------
  |  |  143|      0|  }
  ------------------
 3484|      0|          auto validate_parent =
 3485|      0|              ValidateOperandLexicalScope(_, "Parent", inst, 8, ext_inst_name);
 3486|      0|          if (validate_parent != SPV_SUCCESS) return validate_parent;
  ------------------
  |  Branch (3486:15): [True: 0, False: 0]
  ------------------
 3487|      0|          if (num_words == 10) CHECK_OPERAND("Name", spv::Op::OpString, 9);
  ------------------
  |  |  132|      0|  do {                                                                      \
  |  |  133|      0|    auto result = ValidateOperandForDebugInfo(_, NAME, opcode, inst, index, \
  |  |  134|      0|                                              ext_inst_name);               \
  |  |  135|      0|    if (result != SPV_SUCCESS) return result;                               \
  |  |  ------------------
  |  |  |  Branch (135:9): [True: 0, False: 0]
  |  |  ------------------
  |  |  136|      0|  } while (0)
  |  |  ------------------
  |  |  |  Branch (136:12): [Folded - Ignored]
  |  |  ------------------
  ------------------
  |  Branch (3487:15): [True: 0, False: 0]
  ------------------
 3488|      0|          break;
 3489|      0|        }
 3490|      0|        case CommonDebugInfoDebugScope: {
  ------------------
  |  Branch (3490:9): [True: 0, False: 0]
  ------------------
 3491|      0|          auto validate_scope =
 3492|      0|              ValidateOperandLexicalScope(_, "Scope", inst, 5, ext_inst_name);
 3493|      0|          if (validate_scope != SPV_SUCCESS) return validate_scope;
  ------------------
  |  Branch (3493:15): [True: 0, False: 0]
  ------------------
 3494|      0|          if (num_words == 7) {
  ------------------
  |  Branch (3494:15): [True: 0, False: 0]
  ------------------
 3495|      0|            CHECK_DEBUG_OPERAND("Inlined At", CommonDebugInfoDebugInlinedAt, 6);
  ------------------
  |  |  211|      0|  do {                                                                         \
  |  |  212|      0|    auto result = ValidateDebugInfoOperand(_, NAME, debug_opcode, inst, index, \
  |  |  213|      0|                                           ext_inst_name);                     \
  |  |  214|      0|    if (result != SPV_SUCCESS) return result;                                  \
  |  |  ------------------
  |  |  |  Branch (214:9): [True: 0, False: 0]
  |  |  ------------------
  |  |  215|      0|  } while (0)
  |  |  ------------------
  |  |  |  Branch (215:12): [Folded - Ignored]
  |  |  ------------------
  ------------------
 3496|      0|          }
 3497|      0|          break;
 3498|      0|        }
 3499|      0|        case CommonDebugInfoDebugLocalVariable: {
  ------------------
  |  Branch (3499:9): [True: 0, False: 0]
  ------------------
 3500|      0|          CHECK_OPERAND("Name", spv::Op::OpString, 5);
  ------------------
  |  |  132|      0|  do {                                                                      \
  |  |  133|      0|    auto result = ValidateOperandForDebugInfo(_, NAME, opcode, inst, index, \
  |  |  134|      0|                                              ext_inst_name);               \
  |  |  135|      0|    if (result != SPV_SUCCESS) return result;                               \
  |  |  ------------------
  |  |  |  Branch (135:9): [True: 0, False: 0]
  |  |  ------------------
  |  |  136|      0|  } while (0)
  |  |  ------------------
  |  |  |  Branch (136:12): [Folded - Ignored]
  |  |  ------------------
  ------------------
 3501|       |          // TODO: We need a spec discussion that we have to allow local
 3502|       |          // variable types to have template parameter.
 3503|      0|          auto validate_type =
 3504|      0|              ValidateOperandDebugType(_, "Type", inst, 6, ext_inst_name, true);
 3505|      0|          if (validate_type != SPV_SUCCESS) return validate_type;
  ------------------
  |  Branch (3505:15): [True: 0, False: 0]
  ------------------
 3506|      0|          CHECK_DEBUG_OPERAND("Source", CommonDebugInfoDebugSource, 7);
  ------------------
  |  |  211|      0|  do {                                                                         \
  |  |  212|      0|    auto result = ValidateDebugInfoOperand(_, NAME, debug_opcode, inst, index, \
  |  |  213|      0|                                           ext_inst_name);                     \
  |  |  214|      0|    if (result != SPV_SUCCESS) return result;                                  \
  |  |  ------------------
  |  |  |  Branch (214:9): [True: 0, False: 0]
  |  |  ------------------
  |  |  215|      0|  } while (0)
  |  |  ------------------
  |  |  |  Branch (215:12): [Folded - Ignored]
  |  |  ------------------
  ------------------
 3507|      0|          CHECK_CONST_UINT_OPERAND("Line", 8);
  ------------------
  |  |  139|      0|  if (vulkanDebugInfo) {                                     \
  |  |  ------------------
  |  |  |  Branch (139:7): [True: 0, False: 0]
  |  |  ------------------
  |  |  140|      0|    auto result = ValidateUint32ConstantOperandForDebugInfo( \
  |  |  141|      0|        _, NAME, inst, index, ext_inst_name);                \
  |  |  142|      0|    if (result != SPV_SUCCESS) return result;                \
  |  |  ------------------
  |  |  |  Branch (142:9): [True: 0, False: 0]
  |  |  ------------------
  |  |  143|      0|  }
  ------------------
 3508|      0|          CHECK_CONST_UINT_OPERAND("Column", 9);
  ------------------
  |  |  139|      0|  if (vulkanDebugInfo) {                                     \
  |  |  ------------------
  |  |  |  Branch (139:7): [True: 0, False: 0]
  |  |  ------------------
  |  |  140|      0|    auto result = ValidateUint32ConstantOperandForDebugInfo( \
  |  |  141|      0|        _, NAME, inst, index, ext_inst_name);                \
  |  |  142|      0|    if (result != SPV_SUCCESS) return result;                \
  |  |  ------------------
  |  |  |  Branch (142:9): [True: 0, False: 0]
  |  |  ------------------
  |  |  143|      0|  }
  ------------------
 3509|      0|          auto validate_parent =
 3510|      0|              ValidateOperandLexicalScope(_, "Parent", inst, 10, ext_inst_name);
 3511|      0|          if (validate_parent != SPV_SUCCESS) return validate_parent;
  ------------------
  |  Branch (3511:15): [True: 0, False: 0]
  ------------------
 3512|      0|          CHECK_CONST_UINT_OPERAND("Flags", 11);
  ------------------
  |  |  139|      0|  if (vulkanDebugInfo) {                                     \
  |  |  ------------------
  |  |  |  Branch (139:7): [True: 0, False: 0]
  |  |  ------------------
  |  |  140|      0|    auto result = ValidateUint32ConstantOperandForDebugInfo( \
  |  |  141|      0|        _, NAME, inst, index, ext_inst_name);                \
  |  |  142|      0|    if (result != SPV_SUCCESS) return result;                \
  |  |  ------------------
  |  |  |  Branch (142:9): [True: 0, False: 0]
  |  |  ------------------
  |  |  143|      0|  }
  ------------------
 3513|      0|          if (num_words == 13) {
  ------------------
  |  Branch (3513:15): [True: 0, False: 0]
  ------------------
 3514|      0|            CHECK_CONST_UINT_OPERAND("ArgNumber", 12);
  ------------------
  |  |  139|      0|  if (vulkanDebugInfo) {                                     \
  |  |  ------------------
  |  |  |  Branch (139:7): [True: 0, False: 0]
  |  |  ------------------
  |  |  140|      0|    auto result = ValidateUint32ConstantOperandForDebugInfo( \
  |  |  141|      0|        _, NAME, inst, index, ext_inst_name);                \
  |  |  142|      0|    if (result != SPV_SUCCESS) return result;                \
  |  |  ------------------
  |  |  |  Branch (142:9): [True: 0, False: 0]
  |  |  ------------------
  |  |  143|      0|  }
  ------------------
 3515|      0|          }
 3516|      0|          break;
 3517|      0|        }
 3518|      0|        case CommonDebugInfoDebugDeclare: {
  ------------------
  |  Branch (3518:9): [True: 0, False: 0]
  ------------------
 3519|      0|          CHECK_DEBUG_OPERAND("Local Variable",
  ------------------
  |  |  211|      0|  do {                                                                         \
  |  |  212|      0|    auto result = ValidateDebugInfoOperand(_, NAME, debug_opcode, inst, index, \
  |  |  213|      0|                                           ext_inst_name);                     \
  |  |  214|      0|    if (result != SPV_SUCCESS) return result;                                  \
  |  |  ------------------
  |  |  |  Branch (214:9): [True: 0, False: 0]
  |  |  ------------------
  |  |  215|      0|  } while (0)
  |  |  ------------------
  |  |  |  Branch (215:12): [Folded - Ignored]
  |  |  ------------------
  ------------------
 3520|      0|                              CommonDebugInfoDebugLocalVariable, 5);
 3521|      0|          auto* operand = _.FindDef(inst->word(6));
 3522|      0|          if (operand->opcode() != spv::Op::OpVariable &&
  ------------------
  |  Branch (3522:15): [True: 0, False: 0]
  ------------------
 3523|      0|              operand->opcode() != spv::Op::OpFunctionParameter) {
  ------------------
  |  Branch (3523:15): [True: 0, False: 0]
  ------------------
 3524|      0|            return _.diag(SPV_ERROR_INVALID_DATA, inst)
 3525|      0|                   << ext_inst_name() << ": "
 3526|      0|                   << "expected operand Variable must be a result id of "
 3527|      0|                      "OpVariable or OpFunctionParameter";
 3528|      0|          }
 3529|       |
 3530|      0|          CHECK_DEBUG_OPERAND("Expression", CommonDebugInfoDebugExpression, 7);
  ------------------
  |  |  211|      0|  do {                                                                         \
  |  |  212|      0|    auto result = ValidateDebugInfoOperand(_, NAME, debug_opcode, inst, index, \
  |  |  213|      0|                                           ext_inst_name);                     \
  |  |  214|      0|    if (result != SPV_SUCCESS) return result;                                  \
  |  |  ------------------
  |  |  |  Branch (214:9): [True: 0, False: 0]
  |  |  ------------------
  |  |  215|      0|  } while (0)
  |  |  ------------------
  |  |  |  Branch (215:12): [Folded - Ignored]
  |  |  ------------------
  ------------------
 3531|       |
 3532|      0|          if (vulkanDebugInfo) {
  ------------------
  |  Branch (3532:15): [True: 0, False: 0]
  ------------------
 3533|      0|            for (uint32_t word_index = 8; word_index < num_words;
  ------------------
  |  Branch (3533:43): [True: 0, False: 0]
  ------------------
 3534|      0|                 ++word_index) {
 3535|      0|              auto index_inst = _.FindDef(inst->word(word_index));
 3536|      0|              auto type_id = index_inst != nullptr ? index_inst->type_id() : 0;
  ------------------
  |  Branch (3536:30): [True: 0, False: 0]
  ------------------
 3537|      0|              if (type_id == 0 || !IsIntScalar(_, type_id, false, false))
  ------------------
  |  Branch (3537:19): [True: 0, False: 0]
  |  Branch (3537:35): [True: 0, False: 0]
  ------------------
 3538|      0|                return _.diag(SPV_ERROR_INVALID_DATA, inst)
 3539|      0|                       << ext_inst_name() << ": "
 3540|      0|                       << "expected index must be scalar integer";
 3541|      0|            }
 3542|      0|          }
 3543|      0|          break;
 3544|      0|        }
 3545|      0|        case CommonDebugInfoDebugExpression: {
  ------------------
  |  Branch (3545:9): [True: 0, False: 0]
  ------------------
 3546|      0|          for (uint32_t word_index = 5; word_index < num_words; ++word_index) {
  ------------------
  |  Branch (3546:41): [True: 0, False: 0]
  ------------------
 3547|      0|            CHECK_DEBUG_OPERAND("Operation", CommonDebugInfoDebugOperation,
  ------------------
  |  |  211|      0|  do {                                                                         \
  |  |  212|      0|    auto result = ValidateDebugInfoOperand(_, NAME, debug_opcode, inst, index, \
  |  |  213|      0|                                           ext_inst_name);                     \
  |  |  214|      0|    if (result != SPV_SUCCESS) return result;                                  \
  |  |  ------------------
  |  |  |  Branch (214:9): [True: 0, False: 0]
  |  |  ------------------
  |  |  215|      0|  } while (0)
  |  |  ------------------
  |  |  |  Branch (215:12): [Folded - Ignored]
  |  |  ------------------
  ------------------
 3548|      0|                                word_index);
 3549|      0|          }
 3550|      0|          break;
 3551|      0|        }
 3552|      0|        case CommonDebugInfoDebugTypeTemplate: {
  ------------------
  |  Branch (3552:9): [True: 0, False: 0]
  ------------------
 3553|      0|          if (!DoesDebugInfoOperandMatchExpectation(
  ------------------
  |  Branch (3553:15): [True: 0, False: 0]
  ------------------
 3554|      0|                  _,
 3555|      0|                  [](CommonDebugInfoInstructions dbg_inst) {
 3556|      0|                    return dbg_inst == CommonDebugInfoDebugTypeComposite ||
 3557|      0|                           dbg_inst == CommonDebugInfoDebugFunction;
 3558|      0|                  },
 3559|      0|                  inst, 5)) {
 3560|      0|            return _.diag(SPV_ERROR_INVALID_DATA, inst)
 3561|      0|                   << ext_inst_name() << ": "
 3562|      0|                   << "expected operand Target must be DebugTypeComposite "
 3563|      0|                   << "or DebugFunction";
 3564|      0|          }
 3565|      0|          for (uint32_t word_index = 6; word_index < num_words; ++word_index) {
  ------------------
  |  Branch (3565:41): [True: 0, False: 0]
  ------------------
 3566|      0|            if (!DoesDebugInfoOperandMatchExpectation(
  ------------------
  |  Branch (3566:17): [True: 0, False: 0]
  ------------------
 3567|      0|                    _,
 3568|      0|                    [](CommonDebugInfoInstructions dbg_inst) {
 3569|      0|                      return dbg_inst ==
 3570|      0|                                 CommonDebugInfoDebugTypeTemplateParameter ||
 3571|      0|                             dbg_inst ==
 3572|      0|                                 CommonDebugInfoDebugTypeTemplateTemplateParameter;
 3573|      0|                    },
 3574|      0|                    inst, word_index)) {
 3575|      0|              return _.diag(SPV_ERROR_INVALID_DATA, inst)
 3576|      0|                     << ext_inst_name() << ": "
 3577|      0|                     << "expected operand Parameters must be "
 3578|      0|                     << "DebugTypeTemplateParameter or "
 3579|      0|                     << "DebugTypeTemplateTemplateParameter";
 3580|      0|            }
 3581|      0|          }
 3582|      0|          break;
 3583|      0|        }
 3584|      0|        case CommonDebugInfoDebugTypeTemplateParameter: {
  ------------------
  |  Branch (3584:9): [True: 0, False: 0]
  ------------------
 3585|      0|          CHECK_OPERAND("Name", spv::Op::OpString, 5);
  ------------------
  |  |  132|      0|  do {                                                                      \
  |  |  133|      0|    auto result = ValidateOperandForDebugInfo(_, NAME, opcode, inst, index, \
  |  |  134|      0|                                              ext_inst_name);               \
  |  |  135|      0|    if (result != SPV_SUCCESS) return result;                               \
  |  |  ------------------
  |  |  |  Branch (135:9): [True: 0, False: 0]
  |  |  ------------------
  |  |  136|      0|  } while (0)
  |  |  ------------------
  |  |  |  Branch (136:12): [Folded - Ignored]
  |  |  ------------------
  ------------------
 3586|      0|          auto validate_actual_type = ValidateOperandDebugType(
 3587|      0|              _, "Actual Type", inst, 6, ext_inst_name, false);
 3588|      0|          if (validate_actual_type != SPV_SUCCESS) return validate_actual_type;
  ------------------
  |  Branch (3588:15): [True: 0, False: 0]
  ------------------
 3589|      0|          if (!DoesDebugInfoOperandMatchExpectation(
  ------------------
  |  Branch (3589:15): [True: 0, False: 0]
  ------------------
 3590|      0|                  _,
 3591|      0|                  [](CommonDebugInfoInstructions dbg_inst) {
 3592|      0|                    return dbg_inst == CommonDebugInfoDebugInfoNone;
 3593|      0|                  },
 3594|      0|                  inst, 7)) {
 3595|      0|            CHECK_OPERAND("Value", spv::Op::OpConstant, 7);
  ------------------
  |  |  132|      0|  do {                                                                      \
  |  |  133|      0|    auto result = ValidateOperandForDebugInfo(_, NAME, opcode, inst, index, \
  |  |  134|      0|                                              ext_inst_name);               \
  |  |  135|      0|    if (result != SPV_SUCCESS) return result;                               \
  |  |  ------------------
  |  |  |  Branch (135:9): [True: 0, False: 0]
  |  |  ------------------
  |  |  136|      0|  } while (0)
  |  |  ------------------
  |  |  |  Branch (136:12): [Folded - Ignored]
  |  |  ------------------
  ------------------
 3596|      0|          }
 3597|      0|          CHECK_DEBUG_OPERAND("Source", CommonDebugInfoDebugSource, 8);
  ------------------
  |  |  211|      0|  do {                                                                         \
  |  |  212|      0|    auto result = ValidateDebugInfoOperand(_, NAME, debug_opcode, inst, index, \
  |  |  213|      0|                                           ext_inst_name);                     \
  |  |  214|      0|    if (result != SPV_SUCCESS) return result;                                  \
  |  |  ------------------
  |  |  |  Branch (214:9): [True: 0, False: 0]
  |  |  ------------------
  |  |  215|      0|  } while (0)
  |  |  ------------------
  |  |  |  Branch (215:12): [Folded - Ignored]
  |  |  ------------------
  ------------------
 3598|      0|          CHECK_CONST_UINT_OPERAND("Line", 9);
  ------------------
  |  |  139|      0|  if (vulkanDebugInfo) {                                     \
  |  |  ------------------
  |  |  |  Branch (139:7): [True: 0, False: 0]
  |  |  ------------------
  |  |  140|      0|    auto result = ValidateUint32ConstantOperandForDebugInfo( \
  |  |  141|      0|        _, NAME, inst, index, ext_inst_name);                \
  |  |  142|      0|    if (result != SPV_SUCCESS) return result;                \
  |  |  ------------------
  |  |  |  Branch (142:9): [True: 0, False: 0]
  |  |  ------------------
  |  |  143|      0|  }
  ------------------
 3599|      0|          CHECK_CONST_UINT_OPERAND("Column", 10);
  ------------------
  |  |  139|      0|  if (vulkanDebugInfo) {                                     \
  |  |  ------------------
  |  |  |  Branch (139:7): [True: 0, False: 0]
  |  |  ------------------
  |  |  140|      0|    auto result = ValidateUint32ConstantOperandForDebugInfo( \
  |  |  141|      0|        _, NAME, inst, index, ext_inst_name);                \
  |  |  142|      0|    if (result != SPV_SUCCESS) return result;                \
  |  |  ------------------
  |  |  |  Branch (142:9): [True: 0, False: 0]
  |  |  ------------------
  |  |  143|      0|  }
  ------------------
 3600|      0|          break;
 3601|      0|        }
 3602|      0|        case CommonDebugInfoDebugGlobalVariable: {
  ------------------
  |  Branch (3602:9): [True: 0, False: 0]
  ------------------
 3603|      0|          CHECK_OPERAND("Name", spv::Op::OpString, 5);
  ------------------
  |  |  132|      0|  do {                                                                      \
  |  |  133|      0|    auto result = ValidateOperandForDebugInfo(_, NAME, opcode, inst, index, \
  |  |  134|      0|                                              ext_inst_name);               \
  |  |  135|      0|    if (result != SPV_SUCCESS) return result;                               \
  |  |  ------------------
  |  |  |  Branch (135:9): [True: 0, False: 0]
  |  |  ------------------
  |  |  136|      0|  } while (0)
  |  |  ------------------
  |  |  |  Branch (136:12): [Folded - Ignored]
  |  |  ------------------
  ------------------
 3604|      0|          auto validate_type = ValidateOperandDebugType(_, "Type", inst, 6,
 3605|      0|                                                        ext_inst_name, false);
 3606|      0|          if (validate_type != SPV_SUCCESS) return validate_type;
  ------------------
  |  Branch (3606:15): [True: 0, False: 0]
  ------------------
 3607|      0|          CHECK_DEBUG_OPERAND("Source", CommonDebugInfoDebugSource, 7);
  ------------------
  |  |  211|      0|  do {                                                                         \
  |  |  212|      0|    auto result = ValidateDebugInfoOperand(_, NAME, debug_opcode, inst, index, \
  |  |  213|      0|                                           ext_inst_name);                     \
  |  |  214|      0|    if (result != SPV_SUCCESS) return result;                                  \
  |  |  ------------------
  |  |  |  Branch (214:9): [True: 0, False: 0]
  |  |  ------------------
  |  |  215|      0|  } while (0)
  |  |  ------------------
  |  |  |  Branch (215:12): [Folded - Ignored]
  |  |  ------------------
  ------------------
 3608|      0|          CHECK_CONST_UINT_OPERAND("Line", 8);
  ------------------
  |  |  139|      0|  if (vulkanDebugInfo) {                                     \
  |  |  ------------------
  |  |  |  Branch (139:7): [True: 0, False: 0]
  |  |  ------------------
  |  |  140|      0|    auto result = ValidateUint32ConstantOperandForDebugInfo( \
  |  |  141|      0|        _, NAME, inst, index, ext_inst_name);                \
  |  |  142|      0|    if (result != SPV_SUCCESS) return result;                \
  |  |  ------------------
  |  |  |  Branch (142:9): [True: 0, False: 0]
  |  |  ------------------
  |  |  143|      0|  }
  ------------------
 3609|      0|          CHECK_CONST_UINT_OPERAND("Column", 9);
  ------------------
  |  |  139|      0|  if (vulkanDebugInfo) {                                     \
  |  |  ------------------
  |  |  |  Branch (139:7): [True: 0, False: 0]
  |  |  ------------------
  |  |  140|      0|    auto result = ValidateUint32ConstantOperandForDebugInfo( \
  |  |  141|      0|        _, NAME, inst, index, ext_inst_name);                \
  |  |  142|      0|    if (result != SPV_SUCCESS) return result;                \
  |  |  ------------------
  |  |  |  Branch (142:9): [True: 0, False: 0]
  |  |  ------------------
  |  |  143|      0|  }
  ------------------
 3610|      0|          auto validate_scope =
 3611|      0|              ValidateOperandLexicalScope(_, "Scope", inst, 10, ext_inst_name);
 3612|      0|          if (validate_scope != SPV_SUCCESS) return validate_scope;
  ------------------
  |  Branch (3612:15): [True: 0, False: 0]
  ------------------
 3613|      0|          CHECK_OPERAND("Linkage Name", spv::Op::OpString, 11);
  ------------------
  |  |  132|      0|  do {                                                                      \
  |  |  133|      0|    auto result = ValidateOperandForDebugInfo(_, NAME, opcode, inst, index, \
  |  |  134|      0|                                              ext_inst_name);               \
  |  |  135|      0|    if (result != SPV_SUCCESS) return result;                               \
  |  |  ------------------
  |  |  |  Branch (135:9): [True: 0, False: 0]
  |  |  ------------------
  |  |  136|      0|  } while (0)
  |  |  ------------------
  |  |  |  Branch (136:12): [Folded - Ignored]
  |  |  ------------------
  ------------------
 3614|      0|          if (!DoesDebugInfoOperandMatchExpectation(
  ------------------
  |  Branch (3614:15): [True: 0, False: 0]
  ------------------
 3615|      0|                  _,
 3616|      0|                  [](CommonDebugInfoInstructions dbg_inst) {
 3617|      0|                    return dbg_inst == CommonDebugInfoDebugInfoNone;
 3618|      0|                  },
 3619|      0|                  inst, 12)) {
 3620|      0|            auto* operand = _.FindDef(inst->word(12));
 3621|      0|            if (operand->opcode() != spv::Op::OpVariable &&
  ------------------
  |  Branch (3621:17): [True: 0, False: 0]
  ------------------
 3622|      0|                operand->opcode() != spv::Op::OpConstant) {
  ------------------
  |  Branch (3622:17): [True: 0, False: 0]
  ------------------
 3623|      0|              return _.diag(SPV_ERROR_INVALID_DATA, inst)
 3624|      0|                     << ext_inst_name() << ": "
 3625|      0|                     << "expected operand Variable must be a result id of "
 3626|      0|                        "OpVariable or OpConstant or DebugInfoNone";
 3627|      0|            }
 3628|      0|          }
 3629|      0|          if (num_words == 15) {
  ------------------
  |  Branch (3629:15): [True: 0, False: 0]
  ------------------
 3630|      0|            CHECK_DEBUG_OPERAND("Static Member Declaration",
  ------------------
  |  |  211|      0|  do {                                                                         \
  |  |  212|      0|    auto result = ValidateDebugInfoOperand(_, NAME, debug_opcode, inst, index, \
  |  |  213|      0|                                           ext_inst_name);                     \
  |  |  214|      0|    if (result != SPV_SUCCESS) return result;                                  \
  |  |  ------------------
  |  |  |  Branch (214:9): [True: 0, False: 0]
  |  |  ------------------
  |  |  215|      0|  } while (0)
  |  |  ------------------
  |  |  |  Branch (215:12): [Folded - Ignored]
  |  |  ------------------
  ------------------
 3631|      0|                                CommonDebugInfoDebugTypeMember, 14);
 3632|      0|          }
 3633|      0|          break;
 3634|      0|        }
 3635|      0|        case CommonDebugInfoDebugInlinedAt: {
  ------------------
  |  Branch (3635:9): [True: 0, False: 0]
  ------------------
 3636|      0|          CHECK_CONST_UINT_OPERAND("Line", 5);
  ------------------
  |  |  139|      0|  if (vulkanDebugInfo) {                                     \
  |  |  ------------------
  |  |  |  Branch (139:7): [True: 0, False: 0]
  |  |  ------------------
  |  |  140|      0|    auto result = ValidateUint32ConstantOperandForDebugInfo( \
  |  |  141|      0|        _, NAME, inst, index, ext_inst_name);                \
  |  |  142|      0|    if (result != SPV_SUCCESS) return result;                \
  |  |  ------------------
  |  |  |  Branch (142:9): [True: 0, False: 0]
  |  |  ------------------
  |  |  143|      0|  }
  ------------------
 3637|      0|          auto validate_scope =
 3638|      0|              ValidateOperandLexicalScope(_, "Scope", inst, 6, ext_inst_name);
 3639|      0|          if (validate_scope != SPV_SUCCESS) return validate_scope;
  ------------------
  |  Branch (3639:15): [True: 0, False: 0]
  ------------------
 3640|      0|          if (num_words == 8) {
  ------------------
  |  Branch (3640:15): [True: 0, False: 0]
  ------------------
 3641|      0|            CHECK_DEBUG_OPERAND("Inlined", CommonDebugInfoDebugInlinedAt, 7);
  ------------------
  |  |  211|      0|  do {                                                                         \
  |  |  212|      0|    auto result = ValidateDebugInfoOperand(_, NAME, debug_opcode, inst, index, \
  |  |  213|      0|                                           ext_inst_name);                     \
  |  |  214|      0|    if (result != SPV_SUCCESS) return result;                                  \
  |  |  ------------------
  |  |  |  Branch (214:9): [True: 0, False: 0]
  |  |  ------------------
  |  |  215|      0|  } while (0)
  |  |  ------------------
  |  |  |  Branch (215:12): [Folded - Ignored]
  |  |  ------------------
  ------------------
 3642|      0|          }
 3643|      0|          break;
 3644|      0|        }
 3645|      0|        case CommonDebugInfoDebugValue: {
  ------------------
  |  Branch (3645:9): [True: 0, False: 0]
  ------------------
 3646|      0|          CHECK_DEBUG_OPERAND("Local Variable",
  ------------------
  |  |  211|      0|  do {                                                                         \
  |  |  212|      0|    auto result = ValidateDebugInfoOperand(_, NAME, debug_opcode, inst, index, \
  |  |  213|      0|                                           ext_inst_name);                     \
  |  |  214|      0|    if (result != SPV_SUCCESS) return result;                                  \
  |  |  ------------------
  |  |  |  Branch (214:9): [True: 0, False: 0]
  |  |  ------------------
  |  |  215|      0|  } while (0)
  |  |  ------------------
  |  |  |  Branch (215:12): [Folded - Ignored]
  |  |  ------------------
  ------------------
 3647|      0|                              CommonDebugInfoDebugLocalVariable, 5);
 3648|      0|          CHECK_DEBUG_OPERAND("Expression", CommonDebugInfoDebugExpression, 7);
  ------------------
  |  |  211|      0|  do {                                                                         \
  |  |  212|      0|    auto result = ValidateDebugInfoOperand(_, NAME, debug_opcode, inst, index, \
  |  |  213|      0|                                           ext_inst_name);                     \
  |  |  214|      0|    if (result != SPV_SUCCESS) return result;                                  \
  |  |  ------------------
  |  |  |  Branch (214:9): [True: 0, False: 0]
  |  |  ------------------
  |  |  215|      0|  } while (0)
  |  |  ------------------
  |  |  |  Branch (215:12): [Folded - Ignored]
  |  |  ------------------
  ------------------
 3649|       |
 3650|      0|          for (uint32_t word_index = 8; word_index < num_words; ++word_index) {
  ------------------
  |  Branch (3650:41): [True: 0, False: 0]
  ------------------
 3651|       |            // TODO: The following code simply checks if it is a const int
 3652|       |            // scalar or a DebugLocalVariable or DebugGlobalVariable, but we
 3653|       |            // have to check it using the same validation for Indexes of
 3654|       |            // OpAccessChain.
 3655|      0|            if (!IsConstWithIntScalarType(_, inst, word_index) &&
  ------------------
  |  Branch (3655:17): [True: 0, False: 0]
  ------------------
 3656|      0|                !IsDebugVariableWithIntScalarType(_, inst, word_index)) {
  ------------------
  |  Branch (3656:17): [True: 0, False: 0]
  ------------------
 3657|      0|              return _.diag(SPV_ERROR_INVALID_DATA, inst)
 3658|      0|                     << ext_inst_name() << ": expected operand Indexes is "
 3659|      0|                     << "OpConstant, DebugGlobalVariable, or "
 3660|      0|                     << "type is OpConstant with an integer scalar type";
 3661|      0|            }
 3662|      0|          }
 3663|      0|          break;
 3664|      0|        }
 3665|       |
 3666|       |        // TODO: Add validation rules for remaining cases as well.
 3667|      0|        case CommonDebugInfoDebugTypePtrToMember:
  ------------------
  |  Branch (3667:9): [True: 0, False: 0]
  ------------------
 3668|      0|        case CommonDebugInfoDebugTypeTemplateTemplateParameter:
  ------------------
  |  Branch (3668:9): [True: 0, False: 0]
  ------------------
 3669|      0|        case CommonDebugInfoDebugTypeTemplateParameterPack:
  ------------------
  |  Branch (3669:9): [True: 0, False: 0]
  ------------------
 3670|      0|        case CommonDebugInfoDebugLexicalBlockDiscriminator:
  ------------------
  |  Branch (3670:9): [True: 0, False: 0]
  ------------------
 3671|      0|        case CommonDebugInfoDebugInlinedVariable:
  ------------------
  |  Branch (3671:9): [True: 0, False: 0]
  ------------------
 3672|      0|        case CommonDebugInfoDebugMacroDef:
  ------------------
  |  Branch (3672:9): [True: 0, False: 0]
  ------------------
 3673|      0|        case CommonDebugInfoDebugMacroUndef:
  ------------------
  |  Branch (3673:9): [True: 0, False: 0]
  ------------------
 3674|      0|        case CommonDebugInfoDebugImportedEntity:
  ------------------
  |  Branch (3674:9): [True: 0, False: 0]
  ------------------
 3675|      0|          break;
 3676|      0|        case CommonDebugInfoInstructionsMax:
  ------------------
  |  Branch (3676:9): [True: 0, False: 0]
  ------------------
 3677|      0|          assert(0);
 3678|      0|          break;
 3679|      0|      }
 3680|      0|    }
 3681|      0|  } else if (ext_inst_type == SPV_EXT_INST_TYPE_NONSEMANTIC_CLSPVREFLECTION) {
  ------------------
  |  Branch (3681:14): [True: 0, False: 0]
  ------------------
 3682|      0|    auto import_inst = _.FindDef(inst->GetOperandAs<uint32_t>(2));
 3683|      0|    const std::string name = import_inst->GetOperandAs<std::string>(1);
 3684|      0|    const std::string reflection = "NonSemantic.ClspvReflection.";
 3685|      0|    char* end_ptr;
 3686|      0|    auto version_string = name.substr(reflection.size());
 3687|      0|    if (version_string.empty()) {
  ------------------
  |  Branch (3687:9): [True: 0, False: 0]
  ------------------
 3688|      0|      return _.diag(SPV_ERROR_INVALID_DATA, import_inst)
 3689|      0|             << "Missing NonSemantic.ClspvReflection import version";
 3690|      0|    }
 3691|      0|    uint32_t version = static_cast<uint32_t>(
 3692|      0|        std::strtoul(version_string.c_str(), &end_ptr, 10));
 3693|      0|    if (end_ptr && *end_ptr != '\0') {
  ------------------
  |  Branch (3693:9): [True: 0, False: 0]
  |  Branch (3693:20): [True: 0, False: 0]
  ------------------
 3694|      0|      return _.diag(SPV_ERROR_INVALID_DATA, import_inst)
 3695|      0|             << "NonSemantic.ClspvReflection import does not encode the "
 3696|      0|                "version correctly";
 3697|      0|    }
 3698|      0|    if (version == 0 || version > NonSemanticClspvReflectionRevision) {
  ------------------
  |  Branch (3698:9): [True: 0, False: 0]
  |  Branch (3698:25): [True: 0, False: 0]
  ------------------
 3699|      0|      return _.diag(SPV_ERROR_INVALID_DATA, import_inst)
 3700|      0|             << "Unknown NonSemantic.ClspvReflection import version";
 3701|      0|    }
 3702|       |
 3703|      0|    return ValidateClspvReflectionInstruction(_, inst, version);
 3704|      0|  }
 3705|       |
 3706|  2.35k|  return SPV_SUCCESS;
 3707|  2.42k|}
_ZN8spvtools3val13ExtensionPassERNS0_17ValidationState_tEPKNS0_11InstructionE:
 3709|   286k|spv_result_t ExtensionPass(ValidationState_t& _, const Instruction* inst) {
 3710|   286k|  const spv::Op opcode = inst->opcode();
 3711|   286k|  if (opcode == spv::Op::OpExtension) return ValidateExtension(_, inst);
  ------------------
  |  Branch (3711:7): [True: 518, False: 286k]
  ------------------
 3712|   286k|  if (opcode == spv::Op::OpExtInstImport) return ValidateExtInstImport(_, inst);
  ------------------
  |  Branch (3712:7): [True: 775, False: 285k]
  ------------------
 3713|   285k|  if (opcode == spv::Op::OpExtInst) return ValidateExtInst(_, inst);
  ------------------
  |  Branch (3713:7): [True: 2.42k, False: 282k]
  ------------------
 3714|       |
 3715|   282k|  return SPV_SUCCESS;
 3716|   285k|}
validate_extensions.cpp:_ZZN8spvtools3val15ValidateExtInstERNS0_17ValidationState_tEPKNS0_11InstructionEENK3$_0clEv:
 1098|     71|  auto ext_inst_name = [&_, ext_inst_set, ext_inst_type, ext_inst_index]() {
 1099|     71|    spv_ext_inst_desc desc = nullptr;
 1100|     71|    if (_.grammar().lookupExtInst(ext_inst_type, ext_inst_index, &desc) !=
  ------------------
  |  Branch (1100:9): [True: 0, False: 71]
  ------------------
 1101|     71|            SPV_SUCCESS ||
 1102|     71|        !desc) {
  ------------------
  |  Branch (1102:9): [True: 0, False: 71]
  ------------------
 1103|      0|      return std::string("Unknown ExtInst");
 1104|      0|    }
 1105|       |
 1106|     71|    auto* import_inst = _.FindDef(ext_inst_set);
 1107|     71|    assert(import_inst);
 1108|       |
 1109|      0|    std::ostringstream ss;
 1110|     71|    ss << import_inst->GetOperandAs<std::string>(1);
 1111|     71|    ss << " ";
 1112|     71|    ss << desc->name;
 1113|       |
 1114|     71|    return ss.str();
 1115|     71|  };

_ZN8spvtools3val12FunctionPassERNS0_17ValidationState_tEPKNS0_11InstructionE:
  340|   285k|spv_result_t FunctionPass(ValidationState_t& _, const Instruction* inst) {
  341|   285k|  switch (inst->opcode()) {
  342|  2.75k|    case spv::Op::OpFunction:
  ------------------
  |  Branch (342:5): [True: 2.75k, False: 283k]
  ------------------
  343|  2.75k|      if (auto error = ValidateFunction(_, inst)) return error;
  ------------------
  |  Branch (343:16): [True: 28, False: 2.72k]
  ------------------
  344|  2.72k|      break;
  345|  2.72k|    case spv::Op::OpFunctionParameter:
  ------------------
  |  Branch (345:5): [True: 533, False: 285k]
  ------------------
  346|    533|      if (auto error = ValidateFunctionParameter(_, inst)) return error;
  ------------------
  |  Branch (346:16): [True: 7, False: 526]
  ------------------
  347|    526|      break;
  348|    526|    case spv::Op::OpFunctionCall:
  ------------------
  |  Branch (348:5): [True: 489, False: 285k]
  ------------------
  349|    489|      if (auto error = ValidateFunctionCall(_, inst)) return error;
  ------------------
  |  Branch (349:16): [True: 9, False: 480]
  ------------------
  350|    480|      break;
  351|   282k|    default:
  ------------------
  |  Branch (351:5): [True: 282k, False: 3.77k]
  ------------------
  352|   282k|      break;
  353|   285k|  }
  354|       |
  355|   285k|  return SPV_SUCCESS;
  356|   285k|}
validate_function.cpp:_ZN8spvtools3val12_GLOBAL__N_116ValidateFunctionERNS0_17ValidationState_tEPKNS0_11InstructionE:
   57|  2.75k|spv_result_t ValidateFunction(ValidationState_t& _, const Instruction* inst) {
   58|  2.75k|  const auto function_type_id = inst->GetOperandAs<uint32_t>(3);
   59|  2.75k|  const auto function_type = _.FindDef(function_type_id);
   60|  2.75k|  if (!function_type || spv::Op::OpTypeFunction != function_type->opcode()) {
  ------------------
  |  Branch (60:7): [True: 0, False: 2.75k]
  |  Branch (60:25): [True: 20, False: 2.73k]
  ------------------
   61|     20|    return _.diag(SPV_ERROR_INVALID_ID, inst)
   62|     20|           << "OpFunction Function Type <id> " << _.getIdName(function_type_id)
   63|     20|           << " is not a function type.";
   64|     20|  }
   65|       |
   66|  2.73k|  const auto return_id = function_type->GetOperandAs<uint32_t>(1);
   67|  2.73k|  if (return_id != inst->type_id()) {
  ------------------
  |  Branch (67:7): [True: 5, False: 2.72k]
  ------------------
   68|      5|    return _.diag(SPV_ERROR_INVALID_ID, inst)
   69|      5|           << "OpFunction Result Type <id> " << _.getIdName(inst->type_id())
   70|      5|           << " does not match the Function Type's return type <id> "
   71|      5|           << _.getIdName(return_id) << ".";
   72|      5|  }
   73|       |
   74|  2.72k|  const std::vector<spv::Op> acceptable = {
   75|  2.72k|      spv::Op::OpGroupDecorate,
   76|  2.72k|      spv::Op::OpDecorate,
   77|  2.72k|      spv::Op::OpEnqueueKernel,
   78|  2.72k|      spv::Op::OpEntryPoint,
   79|  2.72k|      spv::Op::OpExecutionMode,
   80|  2.72k|      spv::Op::OpExecutionModeId,
   81|  2.72k|      spv::Op::OpFunctionCall,
   82|  2.72k|      spv::Op::OpGetKernelNDrangeSubGroupCount,
   83|  2.72k|      spv::Op::OpGetKernelNDrangeMaxSubGroupSize,
   84|  2.72k|      spv::Op::OpGetKernelWorkGroupSize,
   85|  2.72k|      spv::Op::OpGetKernelPreferredWorkGroupSizeMultiple,
   86|  2.72k|      spv::Op::OpGetKernelLocalSizeForSubgroupCount,
   87|  2.72k|      spv::Op::OpGetKernelMaxNumSubgroups,
   88|  2.72k|      spv::Op::OpName};
   89|  3.89k|  for (auto& pair : inst->uses()) {
  ------------------
  |  Branch (89:19): [True: 3.89k, False: 2.72k]
  ------------------
   90|  3.89k|    const auto* use = pair.first;
   91|  3.89k|    if (std::find(acceptable.begin(), acceptable.end(), use->opcode()) ==
  ------------------
  |  Branch (91:9): [True: 3, False: 3.89k]
  |  Branch (91:9): [True: 3, False: 3.89k]
  ------------------
   92|  3.89k|            acceptable.end() &&
   93|  3.89k|        !use->IsNonSemantic() && !use->IsDebugInfo()) {
  ------------------
  |  Branch (93:9): [True: 3, False: 0]
  |  Branch (93:34): [True: 3, False: 0]
  ------------------
   94|      3|      return _.diag(SPV_ERROR_INVALID_ID, use)
   95|      3|             << "Invalid use of function result id " << _.getIdName(inst->id())
   96|      3|             << ".";
   97|      3|    }
   98|  3.89k|  }
   99|       |
  100|  2.72k|  return SPV_SUCCESS;
  101|  2.72k|}
validate_function.cpp:_ZN8spvtools3val12_GLOBAL__N_125ValidateFunctionParameterERNS0_17ValidationState_tEPKNS0_11InstructionE:
  104|    533|                                       const Instruction* inst) {
  105|       |  // NOTE: Find OpFunction & ensure OpFunctionParameter is not out of place.
  106|    533|  size_t param_index = 0;
  107|    533|  size_t inst_num = inst->LineNum() - 1;
  108|    533|  if (inst_num == 0) {
  ------------------
  |  Branch (108:7): [True: 0, False: 533]
  ------------------
  109|      0|    return _.diag(SPV_ERROR_INVALID_LAYOUT, inst)
  110|      0|           << "Function parameter cannot be the first instruction.";
  111|      0|  }
  112|       |
  113|    533|  auto func_inst = &_.ordered_instructions()[inst_num];
  114|    924|  while (--inst_num) {
  ------------------
  |  Branch (114:10): [True: 924, False: 0]
  ------------------
  115|    924|    func_inst = &_.ordered_instructions()[inst_num];
  116|    924|    if (func_inst->opcode() == spv::Op::OpFunction) {
  ------------------
  |  Branch (116:9): [True: 533, False: 391]
  ------------------
  117|    533|      break;
  118|    533|    } else if (func_inst->opcode() == spv::Op::OpFunctionParameter) {
  ------------------
  |  Branch (118:16): [True: 237, False: 154]
  ------------------
  119|    237|      ++param_index;
  120|    237|    }
  121|    924|  }
  122|       |
  123|    533|  if (func_inst->opcode() != spv::Op::OpFunction) {
  ------------------
  |  Branch (123:7): [True: 0, False: 533]
  ------------------
  124|      0|    return _.diag(SPV_ERROR_INVALID_LAYOUT, inst)
  125|      0|           << "Function parameter must be preceded by a function.";
  126|      0|  }
  127|       |
  128|    533|  const auto function_type_id = func_inst->GetOperandAs<uint32_t>(3);
  129|    533|  const auto function_type = _.FindDef(function_type_id);
  130|    533|  if (!function_type) {
  ------------------
  |  Branch (130:7): [True: 0, False: 533]
  ------------------
  131|      0|    return _.diag(SPV_ERROR_INVALID_ID, func_inst)
  132|      0|           << "Missing function type definition.";
  133|      0|  }
  134|    533|  if (param_index >= function_type->words().size() - 3) {
  ------------------
  |  Branch (134:7): [True: 3, False: 530]
  ------------------
  135|      3|    return _.diag(SPV_ERROR_INVALID_ID, inst)
  136|      3|           << "Too many OpFunctionParameters for " << func_inst->id()
  137|      3|           << ": expected " << function_type->words().size() - 3
  138|      3|           << " based on the function's type";
  139|      3|  }
  140|       |
  141|    530|  const auto param_type =
  142|    530|      _.FindDef(function_type->GetOperandAs<uint32_t>(param_index + 2));
  143|    530|  if (!param_type || inst->type_id() != param_type->id()) {
  ------------------
  |  Branch (143:7): [True: 0, False: 530]
  |  Branch (143:22): [True: 4, False: 526]
  ------------------
  144|      4|    return _.diag(SPV_ERROR_INVALID_ID, inst)
  145|      4|           << "OpFunctionParameter Result Type <id> "
  146|      4|           << _.getIdName(inst->type_id())
  147|      4|           << " does not match the OpTypeFunction parameter "
  148|      4|              "type of the same index.";
  149|      4|  }
  150|       |
  151|       |  // Validate that PhysicalStorageBuffer have one of Restrict, Aliased,
  152|       |  // RestrictPointer, or AliasedPointer.
  153|    526|  auto param_nonarray_type_id = param_type->id();
  154|    526|  while (_.GetIdOpcode(param_nonarray_type_id) == spv::Op::OpTypeArray) {
  ------------------
  |  Branch (154:10): [True: 0, False: 526]
  ------------------
  155|      0|    param_nonarray_type_id =
  156|      0|        _.FindDef(param_nonarray_type_id)->GetOperandAs<uint32_t>(1u);
  157|      0|  }
  158|    526|  if (_.GetIdOpcode(param_nonarray_type_id) == spv::Op::OpTypePointer) {
  ------------------
  |  Branch (158:7): [True: 510, False: 16]
  ------------------
  159|    510|    auto param_nonarray_type = _.FindDef(param_nonarray_type_id);
  160|    510|    if (param_nonarray_type->GetOperandAs<spv::StorageClass>(1u) ==
  ------------------
  |  Branch (160:9): [True: 0, False: 510]
  ------------------
  161|    510|        spv::StorageClass::PhysicalStorageBuffer) {
  162|       |      // check for Aliased or Restrict
  163|      0|      const auto& decorations = _.id_decorations(inst->id());
  164|       |
  165|      0|      bool foundAliased = std::any_of(
  166|      0|          decorations.begin(), decorations.end(), [](const Decoration& d) {
  167|      0|            return spv::Decoration::Aliased == d.dec_type();
  168|      0|          });
  169|       |
  170|      0|      bool foundRestrict = std::any_of(
  171|      0|          decorations.begin(), decorations.end(), [](const Decoration& d) {
  172|      0|            return spv::Decoration::Restrict == d.dec_type();
  173|      0|          });
  174|       |
  175|      0|      if (!foundAliased && !foundRestrict) {
  ------------------
  |  Branch (175:11): [True: 0, False: 0]
  |  Branch (175:28): [True: 0, False: 0]
  ------------------
  176|      0|        return _.diag(SPV_ERROR_INVALID_ID, inst)
  177|      0|               << "OpFunctionParameter " << inst->id()
  178|      0|               << ": expected Aliased or Restrict for PhysicalStorageBuffer "
  179|      0|                  "pointer.";
  180|      0|      }
  181|      0|      if (foundAliased && foundRestrict) {
  ------------------
  |  Branch (181:11): [True: 0, False: 0]
  |  Branch (181:27): [True: 0, False: 0]
  ------------------
  182|      0|        return _.diag(SPV_ERROR_INVALID_ID, inst)
  183|      0|               << "OpFunctionParameter " << inst->id()
  184|      0|               << ": can't specify both Aliased and Restrict for "
  185|      0|                  "PhysicalStorageBuffer pointer.";
  186|      0|      }
  187|    510|    } else {
  188|    510|      const auto pointee_type_id =
  189|    510|          param_nonarray_type->GetOperandAs<uint32_t>(2);
  190|    510|      const auto pointee_type = _.FindDef(pointee_type_id);
  191|    510|      if (spv::Op::OpTypePointer == pointee_type->opcode() &&
  ------------------
  |  Branch (191:11): [True: 3, False: 507]
  ------------------
  192|    510|          pointee_type->GetOperandAs<spv::StorageClass>(1u) ==
  ------------------
  |  Branch (192:11): [True: 0, False: 3]
  ------------------
  193|      3|              spv::StorageClass::PhysicalStorageBuffer) {
  194|       |        // check for AliasedPointer/RestrictPointer
  195|      0|        const auto& decorations = _.id_decorations(inst->id());
  196|       |
  197|      0|        bool foundAliased = std::any_of(
  198|      0|            decorations.begin(), decorations.end(), [](const Decoration& d) {
  199|      0|              return spv::Decoration::AliasedPointer == d.dec_type();
  200|      0|            });
  201|       |
  202|      0|        bool foundRestrict = std::any_of(
  203|      0|            decorations.begin(), decorations.end(), [](const Decoration& d) {
  204|      0|              return spv::Decoration::RestrictPointer == d.dec_type();
  205|      0|            });
  206|       |
  207|      0|        if (!foundAliased && !foundRestrict) {
  ------------------
  |  Branch (207:13): [True: 0, False: 0]
  |  Branch (207:30): [True: 0, False: 0]
  ------------------
  208|      0|          return _.diag(SPV_ERROR_INVALID_ID, inst)
  209|      0|                 << "OpFunctionParameter " << inst->id()
  210|      0|                 << ": expected AliasedPointer or RestrictPointer for "
  211|      0|                    "PhysicalStorageBuffer pointer.";
  212|      0|        }
  213|      0|        if (foundAliased && foundRestrict) {
  ------------------
  |  Branch (213:13): [True: 0, False: 0]
  |  Branch (213:29): [True: 0, False: 0]
  ------------------
  214|      0|          return _.diag(SPV_ERROR_INVALID_ID, inst)
  215|      0|                 << "OpFunctionParameter " << inst->id()
  216|      0|                 << ": can't specify both AliasedPointer and "
  217|      0|                    "RestrictPointer for PhysicalStorageBuffer pointer.";
  218|      0|        }
  219|      0|      }
  220|    510|    }
  221|    510|  }
  222|       |
  223|    526|  return SPV_SUCCESS;
  224|    526|}
validate_function.cpp:_ZN8spvtools3val12_GLOBAL__N_120ValidateFunctionCallERNS0_17ValidationState_tEPKNS0_11InstructionE:
  227|    489|                                  const Instruction* inst) {
  228|    489|  const auto function_id = inst->GetOperandAs<uint32_t>(2);
  229|    489|  const auto function = _.FindDef(function_id);
  230|    489|  if (!function || spv::Op::OpFunction != function->opcode()) {
  ------------------
  |  Branch (230:7): [True: 0, False: 489]
  |  Branch (230:20): [True: 2, False: 487]
  ------------------
  231|      2|    return _.diag(SPV_ERROR_INVALID_ID, inst)
  232|      2|           << "OpFunctionCall Function <id> " << _.getIdName(function_id)
  233|      2|           << " is not a function.";
  234|      2|  }
  235|       |
  236|    487|  auto return_type = _.FindDef(function->type_id());
  237|    487|  if (!return_type || return_type->id() != inst->type_id()) {
  ------------------
  |  Branch (237:7): [True: 0, False: 487]
  |  Branch (237:23): [True: 1, False: 486]
  ------------------
  238|      1|    return _.diag(SPV_ERROR_INVALID_ID, inst)
  239|      1|           << "OpFunctionCall Result Type <id> " << _.getIdName(inst->type_id())
  240|      1|           << "s type does not match Function <id> "
  241|      1|           << _.getIdName(return_type->id()) << "s return type.";
  242|      1|  }
  243|       |
  244|    486|  const auto function_type_id = function->GetOperandAs<uint32_t>(3);
  245|    486|  const auto function_type = _.FindDef(function_type_id);
  246|    486|  if (!function_type || function_type->opcode() != spv::Op::OpTypeFunction) {
  ------------------
  |  Branch (246:7): [True: 0, False: 486]
  |  Branch (246:25): [True: 1, False: 485]
  ------------------
  247|      1|    return _.diag(SPV_ERROR_INVALID_ID, inst)
  248|      1|           << "Missing function type definition.";
  249|      1|  }
  250|       |
  251|    485|  const auto function_call_arg_count = inst->words().size() - 4;
  252|    485|  const auto function_param_count = function_type->words().size() - 3;
  253|    485|  if (function_param_count != function_call_arg_count) {
  ------------------
  |  Branch (253:7): [True: 1, False: 484]
  ------------------
  254|      1|    return _.diag(SPV_ERROR_INVALID_ID, inst)
  255|      1|           << "OpFunctionCall Function <id>'s parameter count does not match "
  256|      1|              "the argument count.";
  257|      1|  }
  258|       |
  259|    484|  for (size_t argument_index = 3, param_index = 2;
  260|  1.19k|       argument_index < inst->operands().size();
  ------------------
  |  Branch (260:8): [True: 716, False: 480]
  ------------------
  261|    716|       argument_index++, param_index++) {
  262|    716|    const auto argument_id = inst->GetOperandAs<uint32_t>(argument_index);
  263|    716|    const auto argument = _.FindDef(argument_id);
  264|    716|    if (!argument) {
  ------------------
  |  Branch (264:9): [True: 0, False: 716]
  ------------------
  265|      0|      return _.diag(SPV_ERROR_INVALID_ID, inst)
  266|      0|             << "Missing argument " << argument_index - 3 << " definition.";
  267|      0|    }
  268|       |
  269|    716|    const auto argument_type = _.FindDef(argument->type_id());
  270|    716|    if (!argument_type) {
  ------------------
  |  Branch (270:9): [True: 0, False: 716]
  ------------------
  271|      0|      return _.diag(SPV_ERROR_INVALID_ID, inst)
  272|      0|             << "Missing argument " << argument_index - 3
  273|      0|             << " type definition.";
  274|      0|    }
  275|       |
  276|    716|    const auto parameter_type_id =
  277|    716|        function_type->GetOperandAs<uint32_t>(param_index);
  278|    716|    const auto parameter_type = _.FindDef(parameter_type_id);
  279|    716|    if (!parameter_type || argument_type->id() != parameter_type->id()) {
  ------------------
  |  Branch (279:9): [True: 0, False: 716]
  |  Branch (279:28): [True: 2, False: 714]
  ------------------
  280|      2|      if (!_.options()->before_hlsl_legalization ||
  ------------------
  |  Branch (280:11): [True: 2, False: 0]
  ------------------
  281|      2|          !DoPointeesLogicallyMatch(argument_type, parameter_type, _)) {
  ------------------
  |  Branch (281:11): [True: 0, False: 0]
  ------------------
  282|      2|        return _.diag(SPV_ERROR_INVALID_ID, inst)
  283|      2|               << "OpFunctionCall Argument <id> " << _.getIdName(argument_id)
  284|      2|               << "s type does not match Function <id> "
  285|      2|               << _.getIdName(parameter_type_id) << "s parameter type.";
  286|      2|      }
  287|      2|    }
  288|       |
  289|    714|    if (_.addressing_model() == spv::AddressingModel::Logical) {
  ------------------
  |  Branch (289:9): [True: 714, False: 0]
  ------------------
  290|    714|      if (parameter_type->opcode() == spv::Op::OpTypePointer &&
  ------------------
  |  Branch (290:11): [True: 707, False: 7]
  ------------------
  291|    714|          !_.options()->relax_logical_pointer) {
  ------------------
  |  Branch (291:11): [True: 707, False: 0]
  ------------------
  292|    707|        spv::StorageClass sc =
  293|    707|            parameter_type->GetOperandAs<spv::StorageClass>(1u);
  294|       |        // Validate which storage classes can be pointer operands.
  295|    707|        switch (sc) {
  296|      0|          case spv::StorageClass::UniformConstant:
  ------------------
  |  Branch (296:11): [True: 0, False: 707]
  ------------------
  297|    705|          case spv::StorageClass::Function:
  ------------------
  |  Branch (297:11): [True: 705, False: 2]
  ------------------
  298|    705|          case spv::StorageClass::Private:
  ------------------
  |  Branch (298:11): [True: 0, False: 707]
  ------------------
  299|    706|          case spv::StorageClass::Workgroup:
  ------------------
  |  Branch (299:11): [True: 1, False: 706]
  ------------------
  300|    706|          case spv::StorageClass::AtomicCounter:
  ------------------
  |  Branch (300:11): [True: 0, False: 707]
  ------------------
  301|       |            // These are always allowed.
  302|    706|            break;
  303|      0|          case spv::StorageClass::StorageBuffer:
  ------------------
  |  Branch (303:11): [True: 0, False: 707]
  ------------------
  304|      0|            if (!_.features().variable_pointers) {
  ------------------
  |  Branch (304:17): [True: 0, False: 0]
  ------------------
  305|      0|              return _.diag(SPV_ERROR_INVALID_ID, inst)
  306|      0|                     << "StorageBuffer pointer operand "
  307|      0|                     << _.getIdName(argument_id)
  308|      0|                     << " requires a variable pointers capability";
  309|      0|            }
  310|      0|            break;
  311|      1|          default:
  ------------------
  |  Branch (311:11): [True: 1, False: 706]
  ------------------
  312|      1|            return _.diag(SPV_ERROR_INVALID_ID, inst)
  313|      1|                   << "Invalid storage class for pointer operand "
  314|      1|                   << _.getIdName(argument_id);
  315|    707|        }
  316|       |
  317|       |        // Validate memory object declaration requirements.
  318|    706|        if (argument->opcode() != spv::Op::OpVariable &&
  ------------------
  |  Branch (318:13): [True: 7, False: 699]
  ------------------
  319|    706|            argument->opcode() != spv::Op::OpFunctionParameter) {
  ------------------
  |  Branch (319:13): [True: 1, False: 6]
  ------------------
  320|      1|          const bool ssbo_vptr = _.features().variable_pointers &&
  ------------------
  |  Branch (320:34): [True: 0, False: 1]
  ------------------
  321|      1|                                 sc == spv::StorageClass::StorageBuffer;
  ------------------
  |  Branch (321:34): [True: 0, False: 0]
  ------------------
  322|      1|          const bool wg_vptr =
  323|      1|              _.HasCapability(spv::Capability::VariablePointers) &&
  ------------------
  |  Branch (323:15): [True: 0, False: 1]
  ------------------
  324|      1|              sc == spv::StorageClass::Workgroup;
  ------------------
  |  Branch (324:15): [True: 0, False: 0]
  ------------------
  325|      1|          const bool uc_ptr = sc == spv::StorageClass::UniformConstant;
  326|      1|          if (!ssbo_vptr && !wg_vptr && !uc_ptr) {
  ------------------
  |  Branch (326:15): [True: 1, False: 0]
  |  Branch (326:29): [True: 1, False: 0]
  |  Branch (326:41): [True: 1, False: 0]
  ------------------
  327|      1|            return _.diag(SPV_ERROR_INVALID_ID, inst)
  328|      1|                   << "Pointer operand " << _.getIdName(argument_id)
  329|      1|                   << " must be a memory object declaration";
  330|      1|          }
  331|      1|        }
  332|    706|      }
  333|    714|    }
  334|    714|  }
  335|    480|  return SPV_SUCCESS;
  336|    484|}

_ZN8spvtools3val11UpdateIdUseERNS0_17ValidationState_tEPKNS0_11InstructionE:
   40|   310k|spv_result_t UpdateIdUse(ValidationState_t& _, const Instruction* inst) {
   41|   737k|  for (auto& operand : inst->operands()) {
  ------------------
  |  Branch (41:22): [True: 737k, False: 310k]
  ------------------
   42|   737k|    const spv_operand_type_t& type = operand.type;
   43|   737k|    const uint32_t operand_id = inst->word(operand.offset);
   44|   737k|    if (spvIsIdType(type) && type != SPV_OPERAND_TYPE_RESULT_ID) {
  ------------------
  |  Branch (44:9): [True: 627k, False: 109k]
  |  Branch (44:30): [True: 456k, False: 170k]
  ------------------
   45|   456k|      if (auto def = _.FindDef(operand_id))
  ------------------
  |  Branch (45:16): [True: 456k, False: 0]
  ------------------
   46|   456k|        def->RegisterUse(inst, operand.offset);
   47|   456k|    }
   48|   737k|  }
   49|       |
   50|   310k|  return SPV_SUCCESS;
   51|   310k|}
_ZN8spvtools3val28CheckIdDefinitionDominateUseERNS0_17ValidationState_tE:
   61|  1.07k|spv_result_t CheckIdDefinitionDominateUse(ValidationState_t& _) {
   62|  1.07k|  std::vector<const Instruction*> phi_instructions;
   63|  1.07k|  std::unordered_set<uint32_t> phi_ids;
   64|  98.0k|  for (const auto& inst : _.ordered_instructions()) {
  ------------------
  |  Branch (64:25): [True: 98.0k, False: 1.02k]
  ------------------
   65|  98.0k|    if (inst.id() == 0) continue;
  ------------------
  |  Branch (65:9): [True: 55.7k, False: 42.2k]
  ------------------
   66|  42.2k|    if (const Function* func = inst.function()) {
  ------------------
  |  Branch (66:25): [True: 27.6k, False: 14.6k]
  ------------------
   67|  27.6k|      if (const BasicBlock* block = inst.block()) {
  ------------------
  |  Branch (67:29): [True: 19.2k, False: 8.45k]
  ------------------
   68|       |        // If the Id is defined within a block then make sure all references to
   69|       |        // that Id appear in a blocks that are dominated by the defining block
   70|  55.2k|        for (auto& use_index_pair : inst.uses()) {
  ------------------
  |  Branch (70:35): [True: 55.2k, False: 19.1k]
  ------------------
   71|  55.2k|          const Instruction* use = use_index_pair.first;
   72|  55.2k|          if (const BasicBlock* use_block = use->block()) {
  ------------------
  |  Branch (72:33): [True: 52.5k, False: 2.66k]
  ------------------
   73|  52.5k|            if (use_block->reachable() == false) continue;
  ------------------
  |  Branch (73:17): [True: 1.62k, False: 50.9k]
  ------------------
   74|  50.9k|            if (use->opcode() == spv::Op::OpPhi) {
  ------------------
  |  Branch (74:17): [True: 1.25k, False: 49.6k]
  ------------------
   75|  1.25k|              if (phi_ids.insert(use->id()).second) {
  ------------------
  |  Branch (75:19): [True: 807, False: 448]
  ------------------
   76|    807|                phi_instructions.push_back(use);
   77|    807|              }
   78|  49.6k|            } else if (!block->dominates(*use->block())) {
  ------------------
  |  Branch (78:24): [True: 41, False: 49.6k]
  ------------------
   79|     41|              return _.diag(SPV_ERROR_INVALID_ID, use_block->label())
   80|     41|                     << "ID " << _.getIdName(inst.id()) << " defined in block "
   81|     41|                     << _.getIdName(block->id())
   82|     41|                     << " does not dominate its use in block "
   83|     41|                     << _.getIdName(use_block->id());
   84|     41|            }
   85|  50.9k|          }
   86|  55.2k|        }
   87|  19.2k|      } else {
   88|       |        // If the Ids defined within a function but not in a block(i.e. function
   89|       |        // parameters, block ids), then make sure all references to that Id
   90|       |        // appear within the same function
   91|  12.3k|        for (auto use : inst.uses()) {
  ------------------
  |  Branch (91:23): [True: 12.3k, False: 8.45k]
  ------------------
   92|  12.3k|          const Instruction* user = use.first;
   93|  12.3k|          if (user->function() && user->function() != func) {
  ------------------
  |  Branch (93:15): [True: 12.2k, False: 110]
  |  Branch (93:35): [True: 4, False: 12.2k]
  ------------------
   94|      4|            return _.diag(SPV_ERROR_INVALID_ID, _.FindDef(func->id()))
   95|      4|                   << "ID " << _.getIdName(inst.id()) << " used in function "
   96|      4|                   << _.getIdName(user->function()->id())
   97|      4|                   << " is used outside of it's defining function "
   98|      4|                   << _.getIdName(func->id());
   99|      4|          }
  100|  12.3k|        }
  101|  8.45k|      }
  102|  27.6k|    }
  103|       |    // NOTE: Ids defined outside of functions must appear before they are used
  104|       |    // This check is being performed in the IdPass function
  105|  42.2k|  }
  106|       |
  107|       |  // Check all OpPhi parent blocks are dominated by the variable's defining
  108|       |  // blocks
  109|  1.02k|  for (const Instruction* phi : phi_instructions) {
  ------------------
  |  Branch (109:31): [True: 656, False: 1.02k]
  ------------------
  110|    656|    if (phi->block()->reachable() == false) continue;
  ------------------
  |  Branch (110:9): [True: 0, False: 656]
  ------------------
  111|  2.01k|    for (size_t i = 3; i < phi->operands().size(); i += 2) {
  ------------------
  |  Branch (111:24): [True: 1.36k, False: 650]
  ------------------
  112|  1.36k|      const Instruction* variable = _.FindDef(phi->word(i));
  113|  1.36k|      const BasicBlock* parent =
  114|  1.36k|          phi->function()->GetBlock(phi->word(i + 1)).first;
  115|  1.36k|      if (variable->block() && parent->reachable() &&
  ------------------
  |  Branch (115:11): [True: 1.03k, False: 334]
  |  Branch (115:32): [True: 1.01k, False: 20]
  ------------------
  116|  1.36k|          !variable->block()->dominates(*parent)) {
  ------------------
  |  Branch (116:11): [True: 6, False: 1.00k]
  ------------------
  117|      6|        return _.diag(SPV_ERROR_INVALID_ID, phi)
  118|      6|               << "In OpPhi instruction " << _.getIdName(phi->id()) << ", ID "
  119|      6|               << _.getIdName(variable->id())
  120|      6|               << " definition does not dominate its parent "
  121|      6|               << _.getIdName(parent->id());
  122|      6|      }
  123|  1.36k|    }
  124|    656|  }
  125|       |
  126|  1.02k|  return SPV_SUCCESS;
  127|  1.02k|}
_ZN8spvtools3val6IdPassERNS0_17ValidationState_tEPNS0_11InstructionE:
  132|   389k|spv_result_t IdPass(ValidationState_t& _, Instruction* inst) {
  133|   389k|  auto can_have_forward_declared_ids =
  134|   389k|      inst->opcode() == spv::Op::OpExtInst &&
  ------------------
  |  Branch (134:7): [True: 3.44k, False: 385k]
  ------------------
  135|   389k|              spvExtInstIsDebugInfo(inst->ext_inst_type())
  ------------------
  |  Branch (135:15): [True: 5, False: 3.43k]
  ------------------
  136|   389k|          ? spvDbgInfoExtOperandCanBeForwardDeclaredFunction(
  137|      5|                inst->ext_inst_type(), inst->word(4))
  138|   389k|          : spvOperandCanBeForwardDeclaredFunction(inst->opcode());
  139|       |
  140|       |  // Keep track of a result id defined by this instruction.  0 means it
  141|       |  // does not define an id.
  142|   389k|  uint32_t result_id = 0;
  143|       |
  144|  1.74M|  for (unsigned i = 0; i < inst->operands().size(); i++) {
  ------------------
  |  Branch (144:24): [True: 1.35M, False: 388k]
  ------------------
  145|  1.35M|    const spv_parsed_operand_t& operand = inst->operand(i);
  146|  1.35M|    const spv_operand_type_t& type = operand.type;
  147|       |    // We only care about Id operands, which are a single word.
  148|  1.35M|    const uint32_t operand_word = inst->word(operand.offset);
  149|       |
  150|  1.35M|    auto ret = SPV_ERROR_INTERNAL;
  151|  1.35M|    switch (type) {
  152|   196k|      case SPV_OPERAND_TYPE_RESULT_ID:
  ------------------
  |  Branch (152:7): [True: 196k, False: 1.16M]
  ------------------
  153|       |        // NOTE: Multiple Id definitions are being checked by the binary parser.
  154|       |        //
  155|       |        // Defer undefined-forward-reference removal until after we've analyzed
  156|       |        // the remaining operands to this instruction.  Deferral only matters
  157|       |        // for OpPhi since it's the only case where it defines its own forward
  158|       |        // reference.  Other instructions that can have forward references
  159|       |        // either don't define a value or the forward reference is to a function
  160|       |        // Id (and hence defined outside of a function body).
  161|   196k|        result_id = operand_word;
  162|       |        // NOTE: The result Id is added (in RegisterInstruction) *after* all of
  163|       |        // the other Ids have been checked to avoid premature use in the same
  164|       |        // instruction.
  165|   196k|        ret = SPV_SUCCESS;
  166|   196k|        break;
  167|   865k|      case SPV_OPERAND_TYPE_ID:
  ------------------
  |  Branch (167:7): [True: 865k, False: 492k]
  ------------------
  168|   865k|      case SPV_OPERAND_TYPE_MEMORY_SEMANTICS_ID:
  ------------------
  |  Branch (168:7): [True: 619, False: 1.35M]
  ------------------
  169|   867k|      case SPV_OPERAND_TYPE_SCOPE_ID:
  ------------------
  |  Branch (169:7): [True: 1.23k, False: 1.35M]
  ------------------
  170|   867k|        if (const auto def = _.FindDef(operand_word)) {
  ------------------
  |  Branch (170:24): [True: 316k, False: 550k]
  ------------------
  171|   316k|          const auto opcode = inst->opcode();
  172|   316k|          if (spvOpcodeGeneratesType(def->opcode()) &&
  ------------------
  |  Branch (172:15): [True: 24.5k, False: 291k]
  ------------------
  173|   316k|              !spvOpcodeGeneratesType(opcode) && !spvOpcodeIsDebug(opcode) &&
  ------------------
  |  Branch (173:15): [True: 4.97k, False: 19.6k]
  |  Branch (173:50): [True: 4.83k, False: 144]
  ------------------
  174|   316k|              !inst->IsDebugInfo() && !inst->IsNonSemantic() &&
  ------------------
  |  Branch (174:15): [True: 4.83k, False: 0]
  |  Branch (174:39): [True: 4.82k, False: 5]
  ------------------
  175|   316k|              !spvOpcodeIsDecoration(opcode) && opcode != spv::Op::OpFunction &&
  ------------------
  |  Branch (175:15): [True: 4.78k, False: 36]
  |  Branch (175:49): [True: 9, False: 4.78k]
  ------------------
  176|   316k|              opcode != spv::Op::OpCooperativeMatrixLengthNV &&
  ------------------
  |  Branch (176:15): [True: 9, False: 0]
  ------------------
  177|   316k|              !(opcode == spv::Op::OpSpecConstantOp &&
  ------------------
  |  Branch (177:17): [True: 3, False: 6]
  ------------------
  178|      9|                spv::Op(inst->word(3)) ==
  ------------------
  |  Branch (178:17): [True: 3, False: 0]
  ------------------
  179|      6|                    spv::Op::OpCooperativeMatrixLengthNV)) {
  180|      6|            return _.diag(SPV_ERROR_INVALID_ID, inst)
  181|      6|                   << "Operand " << _.getIdName(operand_word)
  182|      6|                   << " cannot be a type";
  183|   316k|          } else if (def->type_id() == 0 && !spvOpcodeGeneratesType(opcode) &&
  ------------------
  |  Branch (183:22): [True: 55.1k, False: 261k]
  |  Branch (183:45): [True: 35.5k, False: 19.6k]
  ------------------
  184|   316k|                     !spvOpcodeIsDebug(opcode) && !inst->IsDebugInfo() &&
  ------------------
  |  Branch (184:22): [True: 35.3k, False: 176]
  |  Branch (184:51): [True: 35.3k, False: 0]
  ------------------
  185|   316k|                     !inst->IsNonSemantic() && !spvOpcodeIsDecoration(opcode) &&
  ------------------
  |  Branch (185:22): [True: 35.3k, False: 23]
  |  Branch (185:48): [True: 29.1k, False: 6.15k]
  ------------------
  186|   316k|                     !spvOpcodeIsBranch(opcode) && opcode != spv::Op::OpPhi &&
  ------------------
  |  Branch (186:22): [True: 23.4k, False: 5.68k]
  |  Branch (186:52): [True: 9.49k, False: 13.9k]
  ------------------
  187|   316k|                     opcode != spv::Op::OpExtInst &&
  ------------------
  |  Branch (187:22): [True: 6.00k, False: 3.48k]
  ------------------
  188|   316k|                     opcode != spv::Op::OpExtInstImport &&
  ------------------
  |  Branch (188:22): [True: 6.00k, False: 0]
  ------------------
  189|   316k|                     opcode != spv::Op::OpSelectionMerge &&
  ------------------
  |  Branch (189:22): [True: 5.51k, False: 488]
  ------------------
  190|   316k|                     opcode != spv::Op::OpLoopMerge &&
  ------------------
  |  Branch (190:22): [True: 4.80k, False: 717]
  ------------------
  191|   316k|                     opcode != spv::Op::OpFunction &&
  ------------------
  |  Branch (191:22): [True: 18, False: 4.78k]
  ------------------
  192|   316k|                     opcode != spv::Op::OpCooperativeMatrixLengthNV &&
  ------------------
  |  Branch (192:22): [True: 18, False: 0]
  ------------------
  193|   316k|                     !(opcode == spv::Op::OpSpecConstantOp &&
  ------------------
  |  Branch (193:24): [True: 3, False: 15]
  ------------------
  194|     18|                       spv::Op(inst->word(3)) ==
  ------------------
  |  Branch (194:24): [True: 3, False: 0]
  ------------------
  195|     15|                           spv::Op::OpCooperativeMatrixLengthNV)) {
  196|     15|            return _.diag(SPV_ERROR_INVALID_ID, inst)
  197|     15|                   << "Operand " << _.getIdName(operand_word)
  198|     15|                   << " requires a type";
  199|   316k|          } else if (def->IsNonSemantic() && !inst->IsNonSemantic()) {
  ------------------
  |  Branch (199:22): [True: 1, False: 316k]
  |  Branch (199:46): [True: 1, False: 0]
  ------------------
  200|      1|            return _.diag(SPV_ERROR_INVALID_ID, inst)
  201|      1|                   << "Operand " << _.getIdName(operand_word)
  202|      1|                   << " in semantic instruction cannot be a non-semantic "
  203|      1|                      "instruction";
  204|   316k|          } else {
  205|   316k|            ret = SPV_SUCCESS;
  206|   316k|          }
  207|   550k|        } else if (can_have_forward_declared_ids(i)) {
  ------------------
  |  Branch (207:20): [True: 550k, False: 82]
  ------------------
  208|   550k|          if (spvOpcodeGeneratesType(inst->opcode()) &&
  ------------------
  |  Branch (208:15): [True: 313, False: 550k]
  ------------------
  209|   550k|              !_.IsForwardPointer(operand_word)) {
  ------------------
  |  Branch (209:15): [True: 155, False: 158]
  ------------------
  210|    155|            ret = _.diag(SPV_ERROR_INVALID_ID, inst)
  211|    155|                  << "Operand " << _.getIdName(operand_word)
  212|    155|                  << " requires a previous definition";
  213|   550k|          } else {
  214|   550k|            ret = _.ForwardDeclareId(operand_word);
  215|   550k|          }
  216|   550k|        } else {
  217|     82|          ret = _.diag(SPV_ERROR_INVALID_ID, inst)
  218|     82|                << "ID " << _.getIdName(operand_word)
  219|     82|                << " has not been defined";
  220|     82|        }
  221|   867k|        break;
  222|   867k|      case SPV_OPERAND_TYPE_TYPE_ID:
  ------------------
  |  Branch (222:7): [True: 115k, False: 1.24M]
  ------------------
  223|   115k|        if (_.IsDefinedId(operand_word)) {
  ------------------
  |  Branch (223:13): [True: 115k, False: 120]
  ------------------
  224|   115k|          auto* def = _.FindDef(operand_word);
  225|   115k|          if (!spvOpcodeGeneratesType(def->opcode())) {
  ------------------
  |  Branch (225:15): [True: 0, False: 115k]
  ------------------
  226|      0|            ret = _.diag(SPV_ERROR_INVALID_ID, inst)
  227|      0|                  << "ID " << _.getIdName(operand_word) << " is not a type id";
  228|   115k|          } else {
  229|   115k|            ret = SPV_SUCCESS;
  230|   115k|          }
  231|   115k|        } else {
  232|    120|          ret = _.diag(SPV_ERROR_INVALID_ID, inst)
  233|    120|                << "ID " << _.getIdName(operand_word)
  234|    120|                << " has not been defined";
  235|    120|        }
  236|   115k|        break;
  237|   179k|      default:
  ------------------
  |  Branch (237:7): [True: 179k, False: 1.17M]
  ------------------
  238|   179k|        ret = SPV_SUCCESS;
  239|   179k|        break;
  240|  1.35M|    }
  241|  1.35M|    if (SPV_SUCCESS != ret) return ret;
  ------------------
  |  Branch (241:9): [True: 357, False: 1.35M]
  ------------------
  242|  1.35M|  }
  243|   388k|  if (result_id) _.RemoveIfForwardDeclared(result_id);
  ------------------
  |  Branch (243:7): [True: 196k, False: 192k]
  ------------------
  244|       |
  245|   388k|  return SPV_SUCCESS;
  246|   389k|}

_ZN8spvtools3val9ImagePassERNS0_17ValidationState_tEPKNS0_11InstructionE:
 2082|   285k|spv_result_t ImagePass(ValidationState_t& _, const Instruction* inst) {
 2083|   285k|  const spv::Op opcode = inst->opcode();
 2084|   285k|  if (IsImplicitLod(opcode)) {
  ------------------
  |  Branch (2084:7): [True: 86, False: 285k]
  ------------------
 2085|     86|    _.function(inst->function()->id())
 2086|     86|        ->RegisterExecutionModelLimitation([opcode](spv::ExecutionModel model,
 2087|     86|                                                    std::string* message) {
 2088|     86|          if (model != spv::ExecutionModel::Fragment &&
 2089|     86|              model != spv::ExecutionModel::GLCompute) {
 2090|     86|            if (message) {
 2091|     86|              *message =
 2092|     86|                  std::string(
 2093|     86|                      "ImplicitLod instructions require Fragment or GLCompute "
 2094|     86|                      "execution model: ") +
 2095|     86|                  spvOpcodeString(opcode);
 2096|     86|            }
 2097|     86|            return false;
 2098|     86|          }
 2099|     86|          return true;
 2100|     86|        });
 2101|     86|    _.function(inst->function()->id())
 2102|     86|        ->RegisterLimitation([opcode](const ValidationState_t& state,
 2103|     86|                                      const Function* entry_point,
 2104|     86|                                      std::string* message) {
 2105|     86|          const auto* models = state.GetExecutionModels(entry_point->id());
 2106|     86|          const auto* modes = state.GetExecutionModes(entry_point->id());
 2107|     86|          if (models &&
 2108|     86|              models->find(spv::ExecutionModel::GLCompute) != models->end() &&
 2109|     86|              (!modes ||
 2110|     86|               (modes->find(spv::ExecutionMode::DerivativeGroupLinearNV) ==
 2111|     86|                    modes->end() &&
 2112|     86|                modes->find(spv::ExecutionMode::DerivativeGroupQuadsNV) ==
 2113|     86|                    modes->end()))) {
 2114|     86|            if (message) {
 2115|     86|              *message =
 2116|     86|                  std::string(
 2117|     86|                      "ImplicitLod instructions require DerivativeGroupQuadsNV "
 2118|     86|                      "or DerivativeGroupLinearNV execution mode for GLCompute "
 2119|     86|                      "execution model: ") +
 2120|     86|                  spvOpcodeString(opcode);
 2121|     86|            }
 2122|     86|            return false;
 2123|     86|          }
 2124|     86|          return true;
 2125|     86|        });
 2126|     86|  }
 2127|       |
 2128|   285k|  switch (opcode) {
 2129|    194|    case spv::Op::OpTypeImage:
  ------------------
  |  Branch (2129:5): [True: 194, False: 285k]
  ------------------
 2130|    194|      return ValidateTypeImage(_, inst);
 2131|     89|    case spv::Op::OpTypeSampledImage:
  ------------------
  |  Branch (2131:5): [True: 89, False: 285k]
  ------------------
 2132|     89|      return ValidateTypeSampledImage(_, inst);
 2133|     34|    case spv::Op::OpSampledImage:
  ------------------
  |  Branch (2133:5): [True: 34, False: 285k]
  ------------------
 2134|     34|      return ValidateSampledImage(_, inst);
 2135|      3|    case spv::Op::OpImageTexelPointer:
  ------------------
  |  Branch (2135:5): [True: 3, False: 285k]
  ------------------
 2136|      3|      return ValidateImageTexelPointer(_, inst);
 2137|       |
 2138|     70|    case spv::Op::OpImageSampleImplicitLod:
  ------------------
  |  Branch (2138:5): [True: 70, False: 285k]
  ------------------
 2139|     71|    case spv::Op::OpImageSampleExplicitLod:
  ------------------
  |  Branch (2139:5): [True: 1, False: 285k]
  ------------------
 2140|     73|    case spv::Op::OpImageSampleProjImplicitLod:
  ------------------
  |  Branch (2140:5): [True: 2, False: 285k]
  ------------------
 2141|     73|    case spv::Op::OpImageSampleProjExplicitLod:
  ------------------
  |  Branch (2141:5): [True: 0, False: 285k]
  ------------------
 2142|     73|    case spv::Op::OpImageSparseSampleImplicitLod:
  ------------------
  |  Branch (2142:5): [True: 0, False: 285k]
  ------------------
 2143|     73|    case spv::Op::OpImageSparseSampleExplicitLod:
  ------------------
  |  Branch (2143:5): [True: 0, False: 285k]
  ------------------
 2144|     73|      return ValidateImageLod(_, inst);
 2145|       |
 2146|      8|    case spv::Op::OpImageSampleDrefImplicitLod:
  ------------------
  |  Branch (2146:5): [True: 8, False: 285k]
  ------------------
 2147|      8|    case spv::Op::OpImageSampleDrefExplicitLod:
  ------------------
  |  Branch (2147:5): [True: 0, False: 285k]
  ------------------
 2148|     14|    case spv::Op::OpImageSampleProjDrefImplicitLod:
  ------------------
  |  Branch (2148:5): [True: 6, False: 285k]
  ------------------
 2149|     14|    case spv::Op::OpImageSampleProjDrefExplicitLod:
  ------------------
  |  Branch (2149:5): [True: 0, False: 285k]
  ------------------
 2150|     14|    case spv::Op::OpImageSparseSampleDrefImplicitLod:
  ------------------
  |  Branch (2150:5): [True: 0, False: 285k]
  ------------------
 2151|     14|    case spv::Op::OpImageSparseSampleDrefExplicitLod:
  ------------------
  |  Branch (2151:5): [True: 0, False: 285k]
  ------------------
 2152|     14|      return ValidateImageDrefLod(_, inst);
 2153|       |
 2154|      4|    case spv::Op::OpImageFetch:
  ------------------
  |  Branch (2154:5): [True: 4, False: 285k]
  ------------------
 2155|      5|    case spv::Op::OpImageSparseFetch:
  ------------------
  |  Branch (2155:5): [True: 1, False: 285k]
  ------------------
 2156|      5|      return ValidateImageFetch(_, inst);
 2157|       |
 2158|      4|    case spv::Op::OpImageGather:
  ------------------
  |  Branch (2158:5): [True: 4, False: 285k]
  ------------------
 2159|      5|    case spv::Op::OpImageDrefGather:
  ------------------
  |  Branch (2159:5): [True: 1, False: 285k]
  ------------------
 2160|      5|    case spv::Op::OpImageSparseGather:
  ------------------
  |  Branch (2160:5): [True: 0, False: 285k]
  ------------------
 2161|      5|    case spv::Op::OpImageSparseDrefGather:
  ------------------
  |  Branch (2161:5): [True: 0, False: 285k]
  ------------------
 2162|      5|      return ValidateImageGather(_, inst);
 2163|       |
 2164|      7|    case spv::Op::OpImageRead:
  ------------------
  |  Branch (2164:5): [True: 7, False: 285k]
  ------------------
 2165|      7|    case spv::Op::OpImageSparseRead:
  ------------------
  |  Branch (2165:5): [True: 0, False: 285k]
  ------------------
 2166|      7|      return ValidateImageRead(_, inst);
 2167|       |
 2168|      1|    case spv::Op::OpImageWrite:
  ------------------
  |  Branch (2168:5): [True: 1, False: 285k]
  ------------------
 2169|      1|      return ValidateImageWrite(_, inst);
 2170|       |
 2171|      0|    case spv::Op::OpImage:
  ------------------
  |  Branch (2171:5): [True: 0, False: 285k]
  ------------------
 2172|      0|      return ValidateImage(_, inst);
 2173|       |
 2174|      1|    case spv::Op::OpImageQueryFormat:
  ------------------
  |  Branch (2174:5): [True: 1, False: 285k]
  ------------------
 2175|      1|    case spv::Op::OpImageQueryOrder:
  ------------------
  |  Branch (2175:5): [True: 0, False: 285k]
  ------------------
 2176|      1|      return ValidateImageQueryFormatOrOrder(_, inst);
 2177|       |
 2178|      2|    case spv::Op::OpImageQuerySizeLod:
  ------------------
  |  Branch (2178:5): [True: 2, False: 285k]
  ------------------
 2179|      2|      return ValidateImageQuerySizeLod(_, inst);
 2180|      4|    case spv::Op::OpImageQuerySize:
  ------------------
  |  Branch (2180:5): [True: 4, False: 285k]
  ------------------
 2181|      4|      return ValidateImageQuerySize(_, inst);
 2182|      0|    case spv::Op::OpImageQueryLod:
  ------------------
  |  Branch (2182:5): [True: 0, False: 285k]
  ------------------
 2183|      0|      return ValidateImageQueryLod(_, inst);
 2184|       |
 2185|      0|    case spv::Op::OpImageQueryLevels:
  ------------------
  |  Branch (2185:5): [True: 0, False: 285k]
  ------------------
 2186|      3|    case spv::Op::OpImageQuerySamples:
  ------------------
  |  Branch (2186:5): [True: 3, False: 285k]
  ------------------
 2187|      3|      return ValidateImageQueryLevelsOrSamples(_, inst);
 2188|       |
 2189|      0|    case spv::Op::OpImageSparseSampleProjImplicitLod:
  ------------------
  |  Branch (2189:5): [True: 0, False: 285k]
  ------------------
 2190|      0|    case spv::Op::OpImageSparseSampleProjExplicitLod:
  ------------------
  |  Branch (2190:5): [True: 0, False: 285k]
  ------------------
 2191|      0|    case spv::Op::OpImageSparseSampleProjDrefImplicitLod:
  ------------------
  |  Branch (2191:5): [True: 0, False: 285k]
  ------------------
 2192|      0|    case spv::Op::OpImageSparseSampleProjDrefExplicitLod:
  ------------------
  |  Branch (2192:5): [True: 0, False: 285k]
  ------------------
 2193|      0|      return ValidateImageSparseLod(_, inst);
 2194|       |
 2195|      0|    case spv::Op::OpImageSparseTexelsResident:
  ------------------
  |  Branch (2195:5): [True: 0, False: 285k]
  ------------------
 2196|      0|      return ValidateImageSparseTexelsResident(_, inst);
 2197|       |
 2198|   285k|    default:
  ------------------
  |  Branch (2198:5): [True: 285k, False: 435]
  ------------------
 2199|   285k|      break;
 2200|   285k|  }
 2201|       |
 2202|   285k|  return SPV_SUCCESS;
 2203|   285k|}
validate_image.cpp:_ZN8spvtools3val12_GLOBAL__N_113IsImplicitLodEN3spv2OpE:
  126|   285k|bool IsImplicitLod(spv::Op opcode) {
  127|   285k|  switch (opcode) {
  128|     70|    case spv::Op::OpImageSampleImplicitLod:
  ------------------
  |  Branch (128:5): [True: 70, False: 285k]
  ------------------
  129|     78|    case spv::Op::OpImageSampleDrefImplicitLod:
  ------------------
  |  Branch (129:5): [True: 8, False: 285k]
  ------------------
  130|     80|    case spv::Op::OpImageSampleProjImplicitLod:
  ------------------
  |  Branch (130:5): [True: 2, False: 285k]
  ------------------
  131|     86|    case spv::Op::OpImageSampleProjDrefImplicitLod:
  ------------------
  |  Branch (131:5): [True: 6, False: 285k]
  ------------------
  132|     86|    case spv::Op::OpImageSparseSampleImplicitLod:
  ------------------
  |  Branch (132:5): [True: 0, False: 285k]
  ------------------
  133|     86|    case spv::Op::OpImageSparseSampleDrefImplicitLod:
  ------------------
  |  Branch (133:5): [True: 0, False: 285k]
  ------------------
  134|     86|    case spv::Op::OpImageSparseSampleProjImplicitLod:
  ------------------
  |  Branch (134:5): [True: 0, False: 285k]
  ------------------
  135|     86|    case spv::Op::OpImageSparseSampleProjDrefImplicitLod:
  ------------------
  |  Branch (135:5): [True: 0, False: 285k]
  ------------------
  136|     86|      return true;
  137|   285k|    default:
  ------------------
  |  Branch (137:5): [True: 285k, False: 86]
  ------------------
  138|   285k|      break;
  139|   285k|  }
  140|   285k|  return false;
  141|   285k|}
validate_image.cpp:_ZN8spvtools3val12_GLOBAL__N_117ValidateTypeImageERNS0_17ValidationState_tEPKNS0_11InstructionE:
  778|    194|spv_result_t ValidateTypeImage(ValidationState_t& _, const Instruction* inst) {
  779|    194|  assert(inst->type_id() == 0);
  780|       |
  781|      0|  ImageTypeInfo info;
  782|    194|  if (!GetImageTypeInfo(_, inst->word(1), &info)) {
  ------------------
  |  Branch (782:7): [True: 0, False: 194]
  ------------------
  783|      0|    return _.diag(SPV_ERROR_INVALID_DATA, inst)
  784|      0|           << "Corrupt image type definition";
  785|      0|  }
  786|       |
  787|    194|  if (_.IsIntScalarType(info.sampled_type) &&
  ------------------
  |  Branch (787:7): [True: 24, False: 170]
  ------------------
  788|    194|      (64 == _.GetBitWidth(info.sampled_type)) &&
  ------------------
  |  Branch (788:7): [True: 0, False: 24]
  ------------------
  789|    194|      !_.HasCapability(spv::Capability::Int64ImageEXT)) {
  ------------------
  |  Branch (789:7): [True: 0, False: 0]
  ------------------
  790|      0|    return _.diag(SPV_ERROR_INVALID_DATA, inst)
  791|      0|           << "Capability Int64ImageEXT is required when using Sampled Type of "
  792|      0|              "64-bit int";
  793|      0|  }
  794|       |
  795|    194|  const auto target_env = _.context()->target_env;
  796|    194|  if (spvIsVulkanEnv(target_env)) {
  ------------------
  |  Branch (796:7): [True: 0, False: 194]
  ------------------
  797|      0|    if ((!_.IsFloatScalarType(info.sampled_type) &&
  ------------------
  |  Branch (797:10): [True: 0, False: 0]
  ------------------
  798|      0|         !_.IsIntScalarType(info.sampled_type)) ||
  ------------------
  |  Branch (798:10): [True: 0, False: 0]
  ------------------
  799|      0|        ((32 != _.GetBitWidth(info.sampled_type)) &&
  ------------------
  |  Branch (799:10): [True: 0, False: 0]
  ------------------
  800|      0|         (64 != _.GetBitWidth(info.sampled_type))) ||
  ------------------
  |  Branch (800:10): [True: 0, False: 0]
  ------------------
  801|      0|        ((64 == _.GetBitWidth(info.sampled_type)) &&
  ------------------
  |  Branch (801:10): [True: 0, False: 0]
  ------------------
  802|      0|         _.IsFloatScalarType(info.sampled_type))) {
  ------------------
  |  Branch (802:10): [True: 0, False: 0]
  ------------------
  803|      0|      return _.diag(SPV_ERROR_INVALID_DATA, inst)
  804|      0|             << _.VkErrorID(4656)
  805|      0|             << "Expected Sampled Type to be a 32-bit int, 64-bit int or "
  806|      0|                "32-bit float scalar type for Vulkan environment";
  807|      0|    }
  808|    194|  } else if (spvIsOpenCLEnv(target_env)) {
  ------------------
  |  Branch (808:14): [True: 0, False: 194]
  ------------------
  809|      0|    if (!_.IsVoidType(info.sampled_type)) {
  ------------------
  |  Branch (809:9): [True: 0, False: 0]
  ------------------
  810|      0|      return _.diag(SPV_ERROR_INVALID_DATA, inst)
  811|      0|             << "Sampled Type must be OpTypeVoid in the OpenCL environment.";
  812|      0|    }
  813|    194|  } else {
  814|    194|    const spv::Op sampled_type_opcode = _.GetIdOpcode(info.sampled_type);
  815|    194|    if (sampled_type_opcode != spv::Op::OpTypeVoid &&
  ------------------
  |  Branch (815:9): [True: 100, False: 94]
  ------------------
  816|    194|        sampled_type_opcode != spv::Op::OpTypeInt &&
  ------------------
  |  Branch (816:9): [True: 76, False: 24]
  ------------------
  817|    194|        sampled_type_opcode != spv::Op::OpTypeFloat) {
  ------------------
  |  Branch (817:9): [True: 4, False: 72]
  ------------------
  818|      4|      return _.diag(SPV_ERROR_INVALID_DATA, inst)
  819|      4|             << "Expected Sampled Type to be either void or"
  820|      4|             << " numerical scalar type";
  821|      4|    }
  822|    194|  }
  823|       |
  824|       |  // Universal checks on image type operands
  825|       |  // Dim and Format and Access Qualifier are checked elsewhere.
  826|       |
  827|    190|  if (info.depth > 2) {
  ------------------
  |  Branch (827:7): [True: 23, False: 167]
  ------------------
  828|     23|    return _.diag(SPV_ERROR_INVALID_DATA, inst)
  829|     23|           << "Invalid Depth " << info.depth << " (must be 0, 1 or 2)";
  830|     23|  }
  831|       |
  832|    167|  if (info.arrayed > 1) {
  ------------------
  |  Branch (832:7): [True: 31, False: 136]
  ------------------
  833|     31|    return _.diag(SPV_ERROR_INVALID_DATA, inst)
  834|     31|           << "Invalid Arrayed " << info.arrayed << " (must be 0 or 1)";
  835|     31|  }
  836|       |
  837|    136|  if (info.multisampled > 1) {
  ------------------
  |  Branch (837:7): [True: 23, False: 113]
  ------------------
  838|     23|    return _.diag(SPV_ERROR_INVALID_DATA, inst)
  839|     23|           << "Invalid MS " << info.multisampled << " (must be 0 or 1)";
  840|     23|  }
  841|       |
  842|    113|  if (info.sampled > 2) {
  ------------------
  |  Branch (842:7): [True: 14, False: 99]
  ------------------
  843|     14|    return _.diag(SPV_ERROR_INVALID_DATA, inst)
  844|     14|           << "Invalid Sampled " << info.sampled << " (must be 0, 1 or 2)";
  845|     14|  }
  846|       |
  847|     99|  if (info.dim == spv::Dim::SubpassData) {
  ------------------
  |  Branch (847:7): [True: 3, False: 96]
  ------------------
  848|      3|    if (info.sampled != 2) {
  ------------------
  |  Branch (848:9): [True: 1, False: 2]
  ------------------
  849|      1|      return _.diag(SPV_ERROR_INVALID_DATA, inst)
  850|      1|             << _.VkErrorID(6214) << "Dim SubpassData requires Sampled to be 2";
  851|      1|    }
  852|       |
  853|      2|    if (info.format != spv::ImageFormat::Unknown) {
  ------------------
  |  Branch (853:9): [True: 2, False: 0]
  ------------------
  854|      2|      return _.diag(SPV_ERROR_INVALID_DATA, inst)
  855|      2|             << "Dim SubpassData requires format Unknown";
  856|      2|    }
  857|     96|  } else {
  858|     96|    if (info.multisampled && (info.sampled == 2) &&
  ------------------
  |  Branch (858:9): [True: 12, False: 84]
  |  Branch (858:30): [True: 1, False: 11]
  ------------------
  859|     96|        !_.HasCapability(spv::Capability::StorageImageMultisample)) {
  ------------------
  |  Branch (859:9): [True: 1, False: 0]
  ------------------
  860|      1|      return _.diag(SPV_ERROR_INVALID_DATA, inst)
  861|      1|             << "Capability StorageImageMultisample is required when using "
  862|      1|                "multisampled storage image";
  863|      1|    }
  864|     96|  }
  865|       |
  866|     95|  if (spvIsOpenCLEnv(target_env)) {
  ------------------
  |  Branch (866:7): [True: 0, False: 95]
  ------------------
  867|      0|    if ((info.arrayed == 1) && (info.dim != spv::Dim::Dim1D) &&
  ------------------
  |  Branch (867:9): [True: 0, False: 0]
  |  Branch (867:32): [True: 0, False: 0]
  ------------------
  868|      0|        (info.dim != spv::Dim::Dim2D)) {
  ------------------
  |  Branch (868:9): [True: 0, False: 0]
  ------------------
  869|      0|      return _.diag(SPV_ERROR_INVALID_DATA, inst)
  870|      0|             << "In the OpenCL environment, Arrayed may only be set to 1 "
  871|      0|             << "when Dim is either 1D or 2D.";
  872|      0|    }
  873|       |
  874|      0|    if (info.multisampled != 0) {
  ------------------
  |  Branch (874:9): [True: 0, False: 0]
  ------------------
  875|      0|      return _.diag(SPV_ERROR_INVALID_DATA, inst)
  876|      0|             << "MS must be 0 in the OpenCL environment.";
  877|      0|    }
  878|       |
  879|      0|    if (info.sampled != 0) {
  ------------------
  |  Branch (879:9): [True: 0, False: 0]
  ------------------
  880|      0|      return _.diag(SPV_ERROR_INVALID_DATA, inst)
  881|      0|             << "Sampled must be 0 in the OpenCL environment.";
  882|      0|    }
  883|       |
  884|      0|    if (info.access_qualifier == spv::AccessQualifier::Max) {
  ------------------
  |  Branch (884:9): [True: 0, False: 0]
  ------------------
  885|      0|      return _.diag(SPV_ERROR_INVALID_DATA, inst)
  886|      0|             << "In the OpenCL environment, the optional Access Qualifier"
  887|      0|             << " must be present.";
  888|      0|    }
  889|      0|  }
  890|       |
  891|     95|  if (spvIsVulkanEnv(target_env)) {
  ------------------
  |  Branch (891:7): [True: 0, False: 95]
  ------------------
  892|      0|    if (info.sampled == 0) {
  ------------------
  |  Branch (892:9): [True: 0, False: 0]
  ------------------
  893|      0|      return _.diag(SPV_ERROR_INVALID_DATA, inst)
  894|      0|             << _.VkErrorID(4657)
  895|      0|             << "Sampled must be 1 or 2 in the Vulkan environment.";
  896|      0|    }
  897|       |
  898|      0|    if (info.dim == spv::Dim::SubpassData && info.arrayed != 0) {
  ------------------
  |  Branch (898:9): [True: 0, False: 0]
  |  Branch (898:46): [True: 0, False: 0]
  ------------------
  899|      0|      return _.diag(SPV_ERROR_INVALID_DATA, inst)
  900|      0|             << _.VkErrorID(6214) << "Dim SubpassData requires Arrayed to be 0";
  901|      0|    }
  902|      0|  }
  903|       |
  904|     95|  return SPV_SUCCESS;
  905|     95|}
validate_image.cpp:_ZN8spvtools3val12_GLOBAL__N_116GetImageTypeInfoERKNS0_17ValidationState_tEjPNS1_13ImageTypeInfoE:
   97|    387|                      ImageTypeInfo* info) {
   98|    387|  if (!id || !info) return false;
  ------------------
  |  Branch (98:7): [True: 0, False: 387]
  |  Branch (98:14): [True: 0, False: 387]
  ------------------
   99|       |
  100|    387|  const Instruction* inst = _.FindDef(id);
  101|    387|  assert(inst);
  102|       |
  103|    387|  if (inst->opcode() == spv::Op::OpTypeSampledImage) {
  ------------------
  |  Branch (103:7): [True: 77, False: 310]
  ------------------
  104|     77|    inst = _.FindDef(inst->word(2));
  105|     77|    assert(inst);
  106|     77|  }
  107|       |
  108|    387|  if (inst->opcode() != spv::Op::OpTypeImage) return false;
  ------------------
  |  Branch (108:7): [True: 0, False: 387]
  ------------------
  109|       |
  110|    387|  const size_t num_words = inst->words().size();
  111|    387|  if (num_words != 9 && num_words != 10) return false;
  ------------------
  |  Branch (111:7): [True: 0, False: 387]
  |  Branch (111:25): [True: 0, False: 0]
  ------------------
  112|       |
  113|    387|  info->sampled_type = inst->word(2);
  114|    387|  info->dim = static_cast<spv::Dim>(inst->word(3));
  115|    387|  info->depth = inst->word(4);
  116|    387|  info->arrayed = inst->word(5);
  117|    387|  info->multisampled = inst->word(6);
  118|    387|  info->sampled = inst->word(7);
  119|    387|  info->format = static_cast<spv::ImageFormat>(inst->word(8));
  120|    387|  info->access_qualifier =
  121|    387|      num_words < 10 ? spv::AccessQualifier::Max
  ------------------
  |  Branch (121:7): [True: 387, False: 0]
  ------------------
  122|    387|                     : static_cast<spv::AccessQualifier>(inst->word(9));
  123|    387|  return true;
  124|    387|}
validate_image.cpp:_ZN8spvtools3val12_GLOBAL__N_124ValidateTypeSampledImageERNS0_17ValidationState_tEPKNS0_11InstructionE:
  908|     89|                                      const Instruction* inst) {
  909|     89|  const uint32_t image_type = inst->word(2);
  910|     89|  if (_.GetIdOpcode(image_type) != spv::Op::OpTypeImage) {
  ------------------
  |  Branch (910:7): [True: 12, False: 77]
  ------------------
  911|     12|    return _.diag(SPV_ERROR_INVALID_DATA, inst)
  912|     12|           << "Expected Image to be of type OpTypeImage";
  913|     12|  }
  914|       |
  915|     77|  ImageTypeInfo info;
  916|     77|  if (!GetImageTypeInfo(_, image_type, &info)) {
  ------------------
  |  Branch (916:7): [True: 0, False: 77]
  ------------------
  917|      0|    return _.diag(SPV_ERROR_INVALID_DATA, inst)
  918|      0|           << "Corrupt image type definition";
  919|      0|  }
  920|       |  // OpenCL requires Sampled=0, checked elsewhere.
  921|       |  // Vulkan uses the Sampled=1 case.
  922|     77|  if ((info.sampled != 0) && (info.sampled != 1)) {
  ------------------
  |  Branch (922:7): [True: 54, False: 23]
  |  Branch (922:30): [True: 0, False: 54]
  ------------------
  923|      0|    return _.diag(SPV_ERROR_INVALID_DATA, inst)
  924|      0|           << _.VkErrorID(4657)
  925|      0|           << "Sampled image type requires an image type with \"Sampled\" "
  926|      0|              "operand set to 0 or 1";
  927|      0|  }
  928|       |
  929|       |  // This covers both OpTypeSampledImage and OpSampledImage.
  930|     77|  if (_.version() >= SPV_SPIRV_VERSION_WORD(1, 6) &&
  ------------------
  |  |   26|    154|  ((uint32_t(uint8_t(MAJOR)) << 16) | (uint32_t(uint8_t(MINOR)) << 8))
  ------------------
  |  Branch (930:7): [True: 0, False: 77]
  ------------------
  931|     77|      info.dim == spv::Dim::Buffer) {
  ------------------
  |  Branch (931:7): [True: 0, False: 0]
  ------------------
  932|      0|    return _.diag(SPV_ERROR_INVALID_ID, inst)
  933|      0|           << "In SPIR-V 1.6 or later, sampled image dimension must not be "
  934|      0|              "Buffer";
  935|      0|  }
  936|       |
  937|     77|  return SPV_SUCCESS;
  938|     77|}
validate_image.cpp:_ZN8spvtools3val12_GLOBAL__N_120ValidateSampledImageERNS0_17ValidationState_tEPKNS0_11InstructionE:
  972|     34|                                  const Instruction* inst) {
  973|     34|  if (_.GetIdOpcode(inst->type_id()) != spv::Op::OpTypeSampledImage) {
  ------------------
  |  Branch (973:7): [True: 0, False: 34]
  ------------------
  974|      0|    return _.diag(SPV_ERROR_INVALID_DATA, inst)
  975|      0|           << "Expected Result Type to be OpTypeSampledImage.";
  976|      0|  }
  977|       |
  978|     34|  const uint32_t image_type = _.GetOperandTypeId(inst, 2);
  979|     34|  if (_.GetIdOpcode(image_type) != spv::Op::OpTypeImage) {
  ------------------
  |  Branch (979:7): [True: 0, False: 34]
  ------------------
  980|      0|    return _.diag(SPV_ERROR_INVALID_DATA, inst)
  981|      0|           << "Expected Image to be of type OpTypeImage.";
  982|      0|  }
  983|       |
  984|     34|  ImageTypeInfo info;
  985|     34|  if (!GetImageTypeInfo(_, image_type, &info)) {
  ------------------
  |  Branch (985:7): [True: 0, False: 34]
  ------------------
  986|      0|    return _.diag(SPV_ERROR_INVALID_DATA, inst)
  987|      0|           << "Corrupt image type definition";
  988|      0|  }
  989|       |
  990|       |  // TODO(atgoo@github.com) Check compatibility of result type and received
  991|       |  // image.
  992|       |
  993|     34|  if (spvIsVulkanEnv(_.context()->target_env)) {
  ------------------
  |  Branch (993:7): [True: 0, False: 34]
  ------------------
  994|      0|    if (info.sampled != 1) {
  ------------------
  |  Branch (994:9): [True: 0, False: 0]
  ------------------
  995|      0|      return _.diag(SPV_ERROR_INVALID_DATA, inst)
  996|      0|             << _.VkErrorID(6671)
  997|      0|             << "Expected Image 'Sampled' parameter to be 1 for Vulkan "
  998|      0|                "environment.";
  999|      0|    }
 1000|     34|  } else {
 1001|     34|    if (info.sampled != 0 && info.sampled != 1) {
  ------------------
  |  Branch (1001:9): [True: 26, False: 8]
  |  Branch (1001:30): [True: 0, False: 26]
  ------------------
 1002|      0|      return _.diag(SPV_ERROR_INVALID_DATA, inst)
 1003|      0|             << "Expected Image 'Sampled' parameter to be 0 or 1";
 1004|      0|    }
 1005|     34|  }
 1006|       |
 1007|     34|  if (info.dim == spv::Dim::SubpassData) {
  ------------------
  |  Branch (1007:7): [True: 0, False: 34]
  ------------------
 1008|      0|    return _.diag(SPV_ERROR_INVALID_DATA, inst)
 1009|      0|           << "Expected Image 'Dim' parameter to be not SubpassData.";
 1010|      0|  }
 1011|       |
 1012|     34|  if (_.GetIdOpcode(_.GetOperandTypeId(inst, 3)) != spv::Op::OpTypeSampler) {
  ------------------
  |  Branch (1012:7): [True: 0, False: 34]
  ------------------
 1013|      0|    return _.diag(SPV_ERROR_INVALID_DATA, inst)
 1014|      0|           << "Expected Sampler to be of type OpTypeSampler";
 1015|      0|  }
 1016|       |
 1017|       |  // We need to validate 2 things:
 1018|       |  // * All OpSampledImage instructions must be in the same block in which their
 1019|       |  // Result <id> are consumed.
 1020|       |  // * Result <id> from OpSampledImage instructions must not appear as operands
 1021|       |  // to OpPhi instructions or OpSelect instructions, or any instructions other
 1022|       |  // than the image lookup and query instructions specified to take an operand
 1023|       |  // whose type is OpTypeSampledImage.
 1024|     34|  std::vector<Instruction*> consumers = _.getSampledImageConsumers(inst->id());
 1025|     34|  if (!consumers.empty()) {
  ------------------
  |  Branch (1025:7): [True: 21, False: 13]
  ------------------
 1026|     28|    for (auto consumer_instr : consumers) {
  ------------------
  |  Branch (1026:30): [True: 28, False: 19]
  ------------------
 1027|     28|      const auto consumer_opcode = consumer_instr->opcode();
 1028|     28|      if (consumer_instr->block() != inst->block()) {
  ------------------
  |  Branch (1028:11): [True: 0, False: 28]
  ------------------
 1029|      0|        return _.diag(SPV_ERROR_INVALID_ID, inst)
 1030|      0|               << "All OpSampledImage instructions must be in the same block "
 1031|      0|                  "in "
 1032|      0|                  "which their Result <id> are consumed. OpSampledImage Result "
 1033|      0|                  "Type <id> "
 1034|      0|               << _.getIdName(inst->id())
 1035|      0|               << " has a consumer in a different basic "
 1036|      0|                  "block. The consumer instruction <id> is "
 1037|      0|               << _.getIdName(consumer_instr->id()) << ".";
 1038|      0|      }
 1039|       |
 1040|     28|      if (consumer_opcode == spv::Op::OpPhi ||
  ------------------
  |  Branch (1040:11): [True: 0, False: 28]
  ------------------
 1041|     28|          consumer_opcode == spv::Op::OpSelect) {
  ------------------
  |  Branch (1041:11): [True: 1, False: 27]
  ------------------
 1042|      1|        return _.diag(SPV_ERROR_INVALID_ID, inst)
 1043|      1|               << "Result <id> from OpSampledImage instruction must not appear "
 1044|      1|                  "as "
 1045|      1|                  "operands of Op"
 1046|      1|               << spvOpcodeString(static_cast<spv::Op>(consumer_opcode)) << "."
 1047|      1|               << " Found result <id> " << _.getIdName(inst->id())
 1048|      1|               << " as an operand of <id> " << _.getIdName(consumer_instr->id())
 1049|      1|               << ".";
 1050|      1|      }
 1051|       |
 1052|     27|      if (!IsAllowedSampledImageOperand(consumer_opcode, _)) {
  ------------------
  |  Branch (1052:11): [True: 1, False: 26]
  ------------------
 1053|      1|        return _.diag(SPV_ERROR_INVALID_ID, inst)
 1054|      1|               << "Result <id> from OpSampledImage instruction must not appear "
 1055|      1|                  "as operand for Op"
 1056|      1|               << spvOpcodeString(static_cast<spv::Op>(consumer_opcode))
 1057|      1|               << ", since it is not specified as taking an "
 1058|      1|               << "OpTypeSampledImage."
 1059|      1|               << " Found result <id> " << _.getIdName(inst->id())
 1060|      1|               << " as an operand of <id> " << _.getIdName(consumer_instr->id())
 1061|      1|               << ".";
 1062|      1|      }
 1063|     27|    }
 1064|     21|  }
 1065|     32|  return SPV_SUCCESS;
 1066|     34|}
validate_image.cpp:_ZN8spvtools3val12_GLOBAL__N_128IsAllowedSampledImageOperandEN3spv2OpERNS0_17ValidationState_tE:
  940|     27|bool IsAllowedSampledImageOperand(spv::Op opcode, ValidationState_t& _) {
  941|     27|  switch (opcode) {
  942|      1|    case spv::Op::OpSampledImage:
  ------------------
  |  Branch (942:5): [True: 1, False: 26]
  ------------------
  943|      4|    case spv::Op::OpImageSampleImplicitLod:
  ------------------
  |  Branch (943:5): [True: 3, False: 24]
  ------------------
  944|      4|    case spv::Op::OpImageSampleExplicitLod:
  ------------------
  |  Branch (944:5): [True: 0, False: 27]
  ------------------
  945|     13|    case spv::Op::OpImageSampleDrefImplicitLod:
  ------------------
  |  Branch (945:5): [True: 9, False: 18]
  ------------------
  946|     13|    case spv::Op::OpImageSampleDrefExplicitLod:
  ------------------
  |  Branch (946:5): [True: 0, False: 27]
  ------------------
  947|     13|    case spv::Op::OpImageSampleProjImplicitLod:
  ------------------
  |  Branch (947:5): [True: 0, False: 27]
  ------------------
  948|     13|    case spv::Op::OpImageSampleProjExplicitLod:
  ------------------
  |  Branch (948:5): [True: 0, False: 27]
  ------------------
  949|     21|    case spv::Op::OpImageSampleProjDrefImplicitLod:
  ------------------
  |  Branch (949:5): [True: 8, False: 19]
  ------------------
  950|     21|    case spv::Op::OpImageSampleProjDrefExplicitLod:
  ------------------
  |  Branch (950:5): [True: 0, False: 27]
  ------------------
  951|     23|    case spv::Op::OpImageGather:
  ------------------
  |  Branch (951:5): [True: 2, False: 25]
  ------------------
  952|     26|    case spv::Op::OpImageDrefGather:
  ------------------
  |  Branch (952:5): [True: 3, False: 24]
  ------------------
  953|     26|    case spv::Op::OpImage:
  ------------------
  |  Branch (953:5): [True: 0, False: 27]
  ------------------
  954|     26|    case spv::Op::OpImageQueryLod:
  ------------------
  |  Branch (954:5): [True: 0, False: 27]
  ------------------
  955|     26|    case spv::Op::OpImageSparseSampleImplicitLod:
  ------------------
  |  Branch (955:5): [True: 0, False: 27]
  ------------------
  956|     26|    case spv::Op::OpImageSparseSampleExplicitLod:
  ------------------
  |  Branch (956:5): [True: 0, False: 27]
  ------------------
  957|     26|    case spv::Op::OpImageSparseSampleDrefImplicitLod:
  ------------------
  |  Branch (957:5): [True: 0, False: 27]
  ------------------
  958|     26|    case spv::Op::OpImageSparseSampleDrefExplicitLod:
  ------------------
  |  Branch (958:5): [True: 0, False: 27]
  ------------------
  959|     26|    case spv::Op::OpImageSparseGather:
  ------------------
  |  Branch (959:5): [True: 0, False: 27]
  ------------------
  960|     26|    case spv::Op::OpImageSparseDrefGather:
  ------------------
  |  Branch (960:5): [True: 0, False: 27]
  ------------------
  961|     26|    case spv::Op::OpCopyObject:
  ------------------
  |  Branch (961:5): [True: 0, False: 27]
  ------------------
  962|     26|      return true;
  963|      0|    case spv::Op::OpStore:
  ------------------
  |  Branch (963:5): [True: 0, False: 27]
  ------------------
  964|      0|      if (_.HasCapability(spv::Capability::BindlessTextureNV)) return true;
  ------------------
  |  Branch (964:11): [True: 0, False: 0]
  ------------------
  965|      0|      return false;
  966|      1|    default:
  ------------------
  |  Branch (966:5): [True: 1, False: 26]
  ------------------
  967|      1|      return false;
  968|     27|  }
  969|     27|}
validate_image.cpp:_ZN8spvtools3val12_GLOBAL__N_125ValidateImageTexelPointerERNS0_17ValidationState_tEPKNS0_11InstructionE:
 1069|      3|                                       const Instruction* inst) {
 1070|      3|  const auto result_type = _.FindDef(inst->type_id());
 1071|      3|  if (result_type->opcode() != spv::Op::OpTypePointer) {
  ------------------
  |  Branch (1071:7): [True: 1, False: 2]
  ------------------
 1072|      1|    return _.diag(SPV_ERROR_INVALID_DATA, inst)
 1073|      1|           << "Expected Result Type to be OpTypePointer";
 1074|      1|  }
 1075|       |
 1076|      2|  const auto storage_class = result_type->GetOperandAs<spv::StorageClass>(1);
 1077|      2|  if (storage_class != spv::StorageClass::Image) {
  ------------------
  |  Branch (1077:7): [True: 1, False: 1]
  ------------------
 1078|      1|    return _.diag(SPV_ERROR_INVALID_DATA, inst)
 1079|      1|           << "Expected Result Type to be OpTypePointer whose Storage Class "
 1080|      1|              "operand is Image";
 1081|      1|  }
 1082|       |
 1083|      1|  const auto ptr_type = result_type->GetOperandAs<uint32_t>(2);
 1084|      1|  const auto ptr_opcode = _.GetIdOpcode(ptr_type);
 1085|      1|  if (ptr_opcode != spv::Op::OpTypeInt && ptr_opcode != spv::Op::OpTypeFloat &&
  ------------------
  |  Branch (1085:7): [True: 0, False: 1]
  |  Branch (1085:43): [True: 0, False: 0]
  ------------------
 1086|      1|      ptr_opcode != spv::Op::OpTypeVoid) {
  ------------------
  |  Branch (1086:7): [True: 0, False: 0]
  ------------------
 1087|      0|    return _.diag(SPV_ERROR_INVALID_DATA, inst)
 1088|      0|           << "Expected Result Type to be OpTypePointer whose Type operand "
 1089|      0|              "must be a scalar numerical type or OpTypeVoid";
 1090|      0|  }
 1091|       |
 1092|      1|  const auto image_ptr = _.FindDef(_.GetOperandTypeId(inst, 2));
 1093|      1|  if (!image_ptr || image_ptr->opcode() != spv::Op::OpTypePointer) {
  ------------------
  |  Branch (1093:7): [True: 0, False: 1]
  |  Branch (1093:21): [True: 0, False: 1]
  ------------------
 1094|      0|    return _.diag(SPV_ERROR_INVALID_DATA, inst)
 1095|      0|           << "Expected Image to be OpTypePointer";
 1096|      0|  }
 1097|       |
 1098|      1|  const auto image_type = image_ptr->GetOperandAs<uint32_t>(2);
 1099|      1|  if (_.GetIdOpcode(image_type) != spv::Op::OpTypeImage) {
  ------------------
  |  Branch (1099:7): [True: 1, False: 0]
  ------------------
 1100|      1|    return _.diag(SPV_ERROR_INVALID_DATA, inst)
 1101|      1|           << "Expected Image to be OpTypePointer with Type OpTypeImage";
 1102|      1|  }
 1103|       |
 1104|      0|  ImageTypeInfo info;
 1105|      0|  if (!GetImageTypeInfo(_, image_type, &info)) {
  ------------------
  |  Branch (1105:7): [True: 0, False: 0]
  ------------------
 1106|      0|    return _.diag(SPV_ERROR_INVALID_DATA, inst)
 1107|      0|           << "Corrupt image type definition";
 1108|      0|  }
 1109|       |
 1110|      0|  if (info.sampled_type != ptr_type) {
  ------------------
  |  Branch (1110:7): [True: 0, False: 0]
  ------------------
 1111|      0|    return _.diag(SPV_ERROR_INVALID_DATA, inst)
 1112|      0|           << "Expected Image 'Sampled Type' to be the same as the Type "
 1113|      0|              "pointed to by Result Type";
 1114|      0|  }
 1115|       |
 1116|      0|  if (info.dim == spv::Dim::SubpassData) {
  ------------------
  |  Branch (1116:7): [True: 0, False: 0]
  ------------------
 1117|      0|    return _.diag(SPV_ERROR_INVALID_DATA, inst)
 1118|      0|           << "Image Dim SubpassData cannot be used with OpImageTexelPointer";
 1119|      0|  }
 1120|       |
 1121|      0|  const uint32_t coord_type = _.GetOperandTypeId(inst, 3);
 1122|      0|  if (!coord_type || !_.IsIntScalarOrVectorType(coord_type)) {
  ------------------
  |  Branch (1122:7): [True: 0, False: 0]
  |  Branch (1122:22): [True: 0, False: 0]
  ------------------
 1123|      0|    return _.diag(SPV_ERROR_INVALID_DATA, inst)
 1124|      0|           << "Expected Coordinate to be integer scalar or vector";
 1125|      0|  }
 1126|       |
 1127|      0|  uint32_t expected_coord_size = 0;
 1128|      0|  if (info.arrayed == 0) {
  ------------------
  |  Branch (1128:7): [True: 0, False: 0]
  ------------------
 1129|      0|    expected_coord_size = GetPlaneCoordSize(info);
 1130|      0|  } else if (info.arrayed == 1) {
  ------------------
  |  Branch (1130:14): [True: 0, False: 0]
  ------------------
 1131|      0|    switch (info.dim) {
 1132|      0|      case spv::Dim::Dim1D:
  ------------------
  |  Branch (1132:7): [True: 0, False: 0]
  ------------------
 1133|      0|        expected_coord_size = 2;
 1134|      0|        break;
 1135|      0|      case spv::Dim::Cube:
  ------------------
  |  Branch (1135:7): [True: 0, False: 0]
  ------------------
 1136|      0|      case spv::Dim::Dim2D:
  ------------------
  |  Branch (1136:7): [True: 0, False: 0]
  ------------------
 1137|      0|        expected_coord_size = 3;
 1138|      0|        break;
 1139|      0|      default:
  ------------------
  |  Branch (1139:7): [True: 0, False: 0]
  ------------------
 1140|      0|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
 1141|      0|               << "Expected Image 'Dim' must be one of 1D, 2D, or Cube when "
 1142|      0|                  "Arrayed is 1";
 1143|      0|        break;
 1144|      0|    }
 1145|      0|  }
 1146|       |
 1147|      0|  const uint32_t actual_coord_size = _.GetDimension(coord_type);
 1148|      0|  if (expected_coord_size != actual_coord_size) {
  ------------------
  |  Branch (1148:7): [True: 0, False: 0]
  ------------------
 1149|      0|    return _.diag(SPV_ERROR_INVALID_DATA, inst)
 1150|      0|           << "Expected Coordinate to have " << expected_coord_size
 1151|      0|           << " components, but given " << actual_coord_size;
 1152|      0|  }
 1153|       |
 1154|      0|  const uint32_t sample_type = _.GetOperandTypeId(inst, 4);
 1155|      0|  if (!sample_type || !_.IsIntScalarType(sample_type)) {
  ------------------
  |  Branch (1155:7): [True: 0, False: 0]
  |  Branch (1155:23): [True: 0, False: 0]
  ------------------
 1156|      0|    return _.diag(SPV_ERROR_INVALID_DATA, inst)
 1157|      0|           << "Expected Sample to be integer scalar";
 1158|      0|  }
 1159|       |
 1160|      0|  if (info.multisampled == 0) {
  ------------------
  |  Branch (1160:7): [True: 0, False: 0]
  ------------------
 1161|      0|    uint64_t ms = 0;
 1162|      0|    if (!_.GetConstantValUint64(inst->GetOperandAs<uint32_t>(4), &ms) ||
  ------------------
  |  Branch (1162:9): [True: 0, False: 0]
  ------------------
 1163|      0|        ms != 0) {
  ------------------
  |  Branch (1163:9): [True: 0, False: 0]
  ------------------
 1164|      0|      return _.diag(SPV_ERROR_INVALID_DATA, inst)
 1165|      0|             << "Expected Sample for Image with MS 0 to be a valid <id> for "
 1166|      0|                "the value 0";
 1167|      0|    }
 1168|      0|  }
 1169|       |
 1170|      0|  if (spvIsVulkanEnv(_.context()->target_env)) {
  ------------------
  |  Branch (1170:7): [True: 0, False: 0]
  ------------------
 1171|      0|    if ((info.format != spv::ImageFormat::R64i) &&
  ------------------
  |  Branch (1171:9): [True: 0, False: 0]
  ------------------
 1172|      0|        (info.format != spv::ImageFormat::R64ui) &&
  ------------------
  |  Branch (1172:9): [True: 0, False: 0]
  ------------------
 1173|      0|        (info.format != spv::ImageFormat::R32f) &&
  ------------------
  |  Branch (1173:9): [True: 0, False: 0]
  ------------------
 1174|      0|        (info.format != spv::ImageFormat::R32i) &&
  ------------------
  |  Branch (1174:9): [True: 0, False: 0]
  ------------------
 1175|      0|        (info.format != spv::ImageFormat::R32ui)) {
  ------------------
  |  Branch (1175:9): [True: 0, False: 0]
  ------------------
 1176|      0|      return _.diag(SPV_ERROR_INVALID_DATA, inst)
 1177|      0|             << _.VkErrorID(4658)
 1178|      0|             << "Expected the Image Format in Image to be R64i, R64ui, R32f, "
 1179|      0|                "R32i, or R32ui for Vulkan environment";
 1180|      0|    }
 1181|      0|  }
 1182|       |
 1183|      0|  return SPV_SUCCESS;
 1184|      0|}
validate_image.cpp:_ZN8spvtools3val12_GLOBAL__N_117GetPlaneCoordSizeERKNS1_13ImageTypeInfoE:
  203|     70|uint32_t GetPlaneCoordSize(const ImageTypeInfo& info) {
  204|     70|  uint32_t plane_size = 0;
  205|       |  // If this switch breaks your build, please add new values below.
  206|     70|  switch (info.dim) {
  ------------------
  |  Branch (206:11): [True: 0, False: 70]
  ------------------
  207|      3|    case spv::Dim::Dim1D:
  ------------------
  |  Branch (207:5): [True: 3, False: 67]
  ------------------
  208|      3|    case spv::Dim::Buffer:
  ------------------
  |  Branch (208:5): [True: 0, False: 70]
  ------------------
  209|      3|      plane_size = 1;
  210|      3|      break;
  211|     59|    case spv::Dim::Dim2D:
  ------------------
  |  Branch (211:5): [True: 59, False: 11]
  ------------------
  212|     59|    case spv::Dim::Rect:
  ------------------
  |  Branch (212:5): [True: 0, False: 70]
  ------------------
  213|     59|    case spv::Dim::SubpassData:
  ------------------
  |  Branch (213:5): [True: 0, False: 70]
  ------------------
  214|     59|      plane_size = 2;
  215|     59|      break;
  216|      4|    case spv::Dim::Dim3D:
  ------------------
  |  Branch (216:5): [True: 4, False: 66]
  ------------------
  217|      8|    case spv::Dim::Cube:
  ------------------
  |  Branch (217:5): [True: 4, False: 66]
  ------------------
  218|       |      // For Cube direction vector is used instead of UV.
  219|      8|      plane_size = 3;
  220|      8|      break;
  221|      0|    case spv::Dim::Max:
  ------------------
  |  Branch (221:5): [True: 0, False: 70]
  ------------------
  222|      0|      assert(0);
  223|      0|      break;
  224|     70|  }
  225|       |
  226|     70|  return plane_size;
  227|     70|}
validate_image.cpp:_ZN8spvtools3val12_GLOBAL__N_116ValidateImageLodERNS0_17ValidationState_tEPKNS0_11InstructionE:
 1186|     73|spv_result_t ValidateImageLod(ValidationState_t& _, const Instruction* inst) {
 1187|     73|  const spv::Op opcode = inst->opcode();
 1188|     73|  uint32_t actual_result_type = 0;
 1189|     73|  if (spv_result_t error = GetActualResultType(_, inst, &actual_result_type)) {
  ------------------
  |  Branch (1189:20): [True: 0, False: 73]
  ------------------
 1190|      0|    return error;
 1191|      0|  }
 1192|       |
 1193|     73|  if (!_.IsIntVectorType(actual_result_type) &&
  ------------------
  |  Branch (1193:7): [True: 72, False: 1]
  ------------------
 1194|     73|      !_.IsFloatVectorType(actual_result_type)) {
  ------------------
  |  Branch (1194:7): [True: 4, False: 68]
  ------------------
 1195|      4|    return _.diag(SPV_ERROR_INVALID_DATA, inst)
 1196|      4|           << "Expected " << GetActualResultTypeStr(opcode)
 1197|      4|           << " to be int or float vector type";
 1198|      4|  }
 1199|       |
 1200|     69|  if (_.GetDimension(actual_result_type) != 4) {
  ------------------
  |  Branch (1200:7): [True: 2, False: 67]
  ------------------
 1201|      2|    return _.diag(SPV_ERROR_INVALID_DATA, inst)
 1202|      2|           << "Expected " << GetActualResultTypeStr(opcode)
 1203|      2|           << " to have 4 components";
 1204|      2|  }
 1205|       |
 1206|     67|  const uint32_t image_type = _.GetOperandTypeId(inst, 2);
 1207|     67|  if (_.GetIdOpcode(image_type) != spv::Op::OpTypeSampledImage) {
  ------------------
  |  Branch (1207:7): [True: 1, False: 66]
  ------------------
 1208|      1|    return _.diag(SPV_ERROR_INVALID_DATA, inst)
 1209|      1|           << "Expected Sampled Image to be of type OpTypeSampledImage";
 1210|      1|  }
 1211|       |
 1212|     66|  ImageTypeInfo info;
 1213|     66|  if (!GetImageTypeInfo(_, image_type, &info)) {
  ------------------
  |  Branch (1213:7): [True: 0, False: 66]
  ------------------
 1214|      0|    return _.diag(SPV_ERROR_INVALID_DATA, inst)
 1215|      0|           << "Corrupt image type definition";
 1216|      0|  }
 1217|       |
 1218|     66|  if (IsProj(opcode)) {
  ------------------
  |  Branch (1218:7): [True: 1, False: 65]
  ------------------
 1219|      1|    if (spv_result_t result = ValidateImageProj(_, inst, info)) return result;
  ------------------
  |  Branch (1219:22): [True: 1, False: 0]
  ------------------
 1220|      1|  }
 1221|       |
 1222|     65|  if (info.multisampled) {
  ------------------
  |  Branch (1222:7): [True: 1, False: 64]
  ------------------
 1223|       |    // When using image operands, the Sample image operand is required if and
 1224|       |    // only if the image is multisampled (MS=1). The Sample image operand is
 1225|       |    // only allowed for fetch, read, and write.
 1226|      1|    return _.diag(SPV_ERROR_INVALID_DATA, inst)
 1227|      1|           << "Sampling operation is invalid for multisample image";
 1228|      1|  }
 1229|       |
 1230|     64|  if (_.GetIdOpcode(info.sampled_type) != spv::Op::OpTypeVoid) {
  ------------------
  |  Branch (1230:7): [True: 57, False: 7]
  ------------------
 1231|     57|    const uint32_t texel_component_type =
 1232|     57|        _.GetComponentType(actual_result_type);
 1233|     57|    if (texel_component_type != info.sampled_type) {
  ------------------
  |  Branch (1233:9): [True: 0, False: 57]
  ------------------
 1234|      0|      return _.diag(SPV_ERROR_INVALID_DATA, inst)
 1235|      0|             << "Expected Image 'Sampled Type' to be the same as "
 1236|      0|             << GetActualResultTypeStr(opcode) << " components";
 1237|      0|    }
 1238|     57|  }
 1239|       |
 1240|     64|  const uint32_t coord_type = _.GetOperandTypeId(inst, 3);
 1241|     64|  if ((opcode == spv::Op::OpImageSampleExplicitLod ||
  ------------------
  |  Branch (1241:8): [True: 0, False: 64]
  ------------------
 1242|     64|       opcode == spv::Op::OpImageSparseSampleExplicitLod) &&
  ------------------
  |  Branch (1242:8): [True: 0, False: 64]
  ------------------
 1243|     64|      _.HasCapability(spv::Capability::Kernel)) {
  ------------------
  |  Branch (1243:7): [True: 0, False: 0]
  ------------------
 1244|      0|    if (!_.IsFloatScalarOrVectorType(coord_type) &&
  ------------------
  |  Branch (1244:9): [True: 0, False: 0]
  ------------------
 1245|      0|        !_.IsIntScalarOrVectorType(coord_type)) {
  ------------------
  |  Branch (1245:9): [True: 0, False: 0]
  ------------------
 1246|      0|      return _.diag(SPV_ERROR_INVALID_DATA, inst)
 1247|      0|             << "Expected Coordinate to be int or float scalar or vector";
 1248|      0|    }
 1249|     64|  } else {
 1250|     64|    if (!_.IsFloatScalarOrVectorType(coord_type)) {
  ------------------
  |  Branch (1250:9): [True: 1, False: 63]
  ------------------
 1251|      1|      return _.diag(SPV_ERROR_INVALID_DATA, inst)
 1252|      1|             << "Expected Coordinate to be float scalar or vector";
 1253|      1|    }
 1254|     64|  }
 1255|       |
 1256|     63|  const uint32_t min_coord_size = GetMinCoordSize(opcode, info);
 1257|     63|  const uint32_t actual_coord_size = _.GetDimension(coord_type);
 1258|     63|  if (min_coord_size > actual_coord_size) {
  ------------------
  |  Branch (1258:7): [True: 3, False: 60]
  ------------------
 1259|      3|    return _.diag(SPV_ERROR_INVALID_DATA, inst)
 1260|      3|           << "Expected Coordinate to have at least " << min_coord_size
 1261|      3|           << " components, but given only " << actual_coord_size;
 1262|      3|  }
 1263|       |
 1264|     60|  const uint32_t mask = inst->words().size() <= 5 ? 0 : inst->word(5);
  ------------------
  |  Branch (1264:25): [True: 60, False: 0]
  ------------------
 1265|       |
 1266|     60|  if (mask & uint32_t(spv::ImageOperandsMask::ConstOffset)) {
  ------------------
  |  Branch (1266:7): [True: 0, False: 60]
  ------------------
 1267|      0|    if (spvIsOpenCLEnv(_.context()->target_env)) {
  ------------------
  |  Branch (1267:9): [True: 0, False: 0]
  ------------------
 1268|      0|      if (opcode == spv::Op::OpImageSampleExplicitLod) {
  ------------------
  |  Branch (1268:11): [True: 0, False: 0]
  ------------------
 1269|      0|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
 1270|      0|               << "ConstOffset image operand not allowed "
 1271|      0|               << "in the OpenCL environment.";
 1272|      0|      }
 1273|      0|    }
 1274|      0|  }
 1275|       |
 1276|     60|  if (spv_result_t result =
  ------------------
  |  Branch (1276:20): [True: 0, False: 60]
  ------------------
 1277|     60|          ValidateImageOperands(_, inst, info, /* word_index = */ 6))
 1278|      0|    return result;
 1279|       |
 1280|     60|  return SPV_SUCCESS;
 1281|     60|}
validate_image.cpp:_ZN8spvtools3val12_GLOBAL__N_119GetActualResultTypeERNS0_17ValidationState_tEPKNS0_11InstructionEPj:
  744|    104|                                 uint32_t* actual_result_type) {
  745|    104|  const spv::Op opcode = inst->opcode();
  746|       |
  747|    104|  if (IsSparse(opcode)) {
  ------------------
  |  Branch (747:7): [True: 1, False: 103]
  ------------------
  748|      1|    const Instruction* const type_inst = _.FindDef(inst->type_id());
  749|      1|    assert(type_inst);
  750|       |
  751|      1|    if (!type_inst || type_inst->opcode() != spv::Op::OpTypeStruct) {
  ------------------
  |  Branch (751:9): [True: 0, False: 1]
  |  Branch (751:23): [True: 1, False: 0]
  ------------------
  752|      1|      return _.diag(SPV_ERROR_INVALID_DATA, inst)
  753|      1|             << "Expected Result Type to be OpTypeStruct";
  754|      1|    }
  755|       |
  756|      0|    if (type_inst->words().size() != 4 ||
  ------------------
  |  Branch (756:9): [True: 0, False: 0]
  ------------------
  757|      0|        !_.IsIntScalarType(type_inst->word(2))) {
  ------------------
  |  Branch (757:9): [True: 0, False: 0]
  ------------------
  758|      0|      return _.diag(SPV_ERROR_INVALID_DATA, inst)
  759|      0|             << "Expected Result Type to be a struct containing an int "
  760|      0|                "scalar and a texel";
  761|      0|    }
  762|       |
  763|      0|    *actual_result_type = type_inst->word(3);
  764|    103|  } else {
  765|    103|    *actual_result_type = inst->type_id();
  766|    103|  }
  767|       |
  768|    103|  return SPV_SUCCESS;
  769|    104|}
validate_image.cpp:_ZN8spvtools3val12_GLOBAL__N_18IsSparseEN3spv2OpE:
  716|    119|bool IsSparse(spv::Op opcode) {
  717|    119|  switch (opcode) {
  718|      0|    case spv::Op::OpImageSparseSampleImplicitLod:
  ------------------
  |  Branch (718:5): [True: 0, False: 119]
  ------------------
  719|      0|    case spv::Op::OpImageSparseSampleExplicitLod:
  ------------------
  |  Branch (719:5): [True: 0, False: 119]
  ------------------
  720|      0|    case spv::Op::OpImageSparseSampleDrefImplicitLod:
  ------------------
  |  Branch (720:5): [True: 0, False: 119]
  ------------------
  721|      0|    case spv::Op::OpImageSparseSampleDrefExplicitLod:
  ------------------
  |  Branch (721:5): [True: 0, False: 119]
  ------------------
  722|      0|    case spv::Op::OpImageSparseSampleProjImplicitLod:
  ------------------
  |  Branch (722:5): [True: 0, False: 119]
  ------------------
  723|      0|    case spv::Op::OpImageSparseSampleProjExplicitLod:
  ------------------
  |  Branch (723:5): [True: 0, False: 119]
  ------------------
  724|      0|    case spv::Op::OpImageSparseSampleProjDrefImplicitLod:
  ------------------
  |  Branch (724:5): [True: 0, False: 119]
  ------------------
  725|      0|    case spv::Op::OpImageSparseSampleProjDrefExplicitLod:
  ------------------
  |  Branch (725:5): [True: 0, False: 119]
  ------------------
  726|      1|    case spv::Op::OpImageSparseFetch:
  ------------------
  |  Branch (726:5): [True: 1, False: 118]
  ------------------
  727|      1|    case spv::Op::OpImageSparseGather:
  ------------------
  |  Branch (727:5): [True: 0, False: 119]
  ------------------
  728|      1|    case spv::Op::OpImageSparseDrefGather:
  ------------------
  |  Branch (728:5): [True: 0, False: 119]
  ------------------
  729|      1|    case spv::Op::OpImageSparseTexelsResident:
  ------------------
  |  Branch (729:5): [True: 0, False: 119]
  ------------------
  730|      1|    case spv::Op::OpImageSparseRead: {
  ------------------
  |  Branch (730:5): [True: 0, False: 119]
  ------------------
  731|      1|      return true;
  732|      1|    }
  733|       |
  734|    118|    default: { return false; }
  ------------------
  |  Branch (734:5): [True: 118, False: 1]
  ------------------
  735|    119|  }
  736|       |
  737|      0|  return false;
  738|    119|}
validate_image.cpp:_ZN8spvtools3val12_GLOBAL__N_122GetActualResultTypeStrEN3spv2OpE:
  773|     15|const char* GetActualResultTypeStr(spv::Op opcode) {
  774|     15|  if (IsSparse(opcode)) return "Result Type's second member";
  ------------------
  |  Branch (774:7): [True: 0, False: 15]
  ------------------
  775|     15|  return "Result Type";
  776|     15|}
validate_image.cpp:_ZN8spvtools3val12_GLOBAL__N_16IsProjEN3spv2OpE:
  184|    147|bool IsProj(spv::Op opcode) {
  185|    147|  switch (opcode) {
  186|      1|    case spv::Op::OpImageSampleProjImplicitLod:
  ------------------
  |  Branch (186:5): [True: 1, False: 146]
  ------------------
  187|      9|    case spv::Op::OpImageSampleProjDrefImplicitLod:
  ------------------
  |  Branch (187:5): [True: 8, False: 139]
  ------------------
  188|      9|    case spv::Op::OpImageSparseSampleProjImplicitLod:
  ------------------
  |  Branch (188:5): [True: 0, False: 147]
  ------------------
  189|      9|    case spv::Op::OpImageSparseSampleProjDrefImplicitLod:
  ------------------
  |  Branch (189:5): [True: 0, False: 147]
  ------------------
  190|      9|    case spv::Op::OpImageSampleProjExplicitLod:
  ------------------
  |  Branch (190:5): [True: 0, False: 147]
  ------------------
  191|      9|    case spv::Op::OpImageSampleProjDrefExplicitLod:
  ------------------
  |  Branch (191:5): [True: 0, False: 147]
  ------------------
  192|      9|    case spv::Op::OpImageSparseSampleProjExplicitLod:
  ------------------
  |  Branch (192:5): [True: 0, False: 147]
  ------------------
  193|      9|    case spv::Op::OpImageSparseSampleProjDrefExplicitLod:
  ------------------
  |  Branch (193:5): [True: 0, False: 147]
  ------------------
  194|      9|      return true;
  195|    138|    default:
  ------------------
  |  Branch (195:5): [True: 138, False: 9]
  ------------------
  196|    138|      break;
  197|    147|  }
  198|    138|  return false;
  199|    147|}
validate_image.cpp:_ZN8spvtools3val12_GLOBAL__N_117ValidateImageProjERNS0_17ValidationState_tEPKNS0_11InstructionERKNS1_13ImageTypeInfoE:
  652|      6|                               const ImageTypeInfo& info) {
  653|      6|  if (info.dim != spv::Dim::Dim1D && info.dim != spv::Dim::Dim2D &&
  ------------------
  |  Branch (653:7): [True: 4, False: 2]
  |  Branch (653:38): [True: 4, False: 0]
  ------------------
  654|      6|      info.dim != spv::Dim::Dim3D && info.dim != spv::Dim::Rect) {
  ------------------
  |  Branch (654:7): [True: 1, False: 3]
  |  Branch (654:38): [True: 1, False: 0]
  ------------------
  655|      1|    return _.diag(SPV_ERROR_INVALID_DATA, inst)
  656|      1|           << "Expected Image 'Dim' parameter to be 1D, 2D, 3D or Rect";
  657|      1|  }
  658|       |
  659|      5|  if (info.multisampled != 0) {
  ------------------
  |  Branch (659:7): [True: 1, False: 4]
  ------------------
  660|      1|    return _.diag(SPV_ERROR_INVALID_DATA, inst)
  661|      1|           << "Expected Image 'MS' parameter to be 0";
  662|      1|  }
  663|       |
  664|      4|  if (info.arrayed != 0) {
  ------------------
  |  Branch (664:7): [True: 1, False: 3]
  ------------------
  665|      1|    return _.diag(SPV_ERROR_INVALID_DATA, inst)
  666|      1|           << "Expected Image 'arrayed' parameter to be 0";
  667|      1|  }
  668|       |
  669|      3|  return SPV_SUCCESS;
  670|      4|}
validate_image.cpp:_ZN8spvtools3val12_GLOBAL__N_115GetMinCoordSizeEN3spv2OpERKNS1_13ImageTypeInfoE:
  231|     70|uint32_t GetMinCoordSize(spv::Op opcode, const ImageTypeInfo& info) {
  232|     70|  if (info.dim == spv::Dim::Cube &&
  ------------------
  |  Branch (232:7): [True: 4, False: 66]
  ------------------
  233|     70|      (opcode == spv::Op::OpImageRead || opcode == spv::Op::OpImageWrite ||
  ------------------
  |  Branch (233:8): [True: 0, False: 4]
  |  Branch (233:42): [True: 0, False: 4]
  ------------------
  234|      4|       opcode == spv::Op::OpImageSparseRead)) {
  ------------------
  |  Branch (234:8): [True: 0, False: 4]
  ------------------
  235|       |    // These opcodes use UV for Cube, not direction vector.
  236|      0|    return 3;
  237|      0|  }
  238|       |
  239|     70|  return GetPlaneCoordSize(info) + info.arrayed + (IsProj(opcode) ? 1 : 0);
  ------------------
  |  Branch (239:52): [True: 3, False: 67]
  ------------------
  240|     70|}
validate_image.cpp:_ZN8spvtools3val12_GLOBAL__N_121ValidateImageOperandsERNS0_17ValidationState_tEPKNS0_11InstructionERKNS1_13ImageTypeInfoEj:
  247|     64|                                   uint32_t word_index) {
  248|     64|  static const bool kAllImageOperandsHandled = CheckAllImageOperandsHandled();
  249|     64|  (void)kAllImageOperandsHandled;
  250|       |
  251|     64|  const spv::Op opcode = inst->opcode();
  252|     64|  const size_t num_words = inst->words().size();
  253|       |
  254|     64|  const bool have_explicit_mask = (word_index - 1 < num_words);
  255|     64|  const uint32_t mask = have_explicit_mask ? inst->word(word_index - 1) : 0u;
  ------------------
  |  Branch (255:25): [True: 0, False: 64]
  ------------------
  256|       |
  257|     64|  if (have_explicit_mask) {
  ------------------
  |  Branch (257:7): [True: 0, False: 64]
  ------------------
  258|       |    // NonPrivate, Volatile, SignExtend, ZeroExtend take no operand words.
  259|      0|    const uint32_t mask_bits_having_operands =
  260|      0|        mask & ~uint32_t(spv::ImageOperandsMask::NonPrivateTexelKHR |
  261|      0|                         spv::ImageOperandsMask::VolatileTexelKHR |
  262|      0|                         spv::ImageOperandsMask::SignExtend |
  263|      0|                         spv::ImageOperandsMask::ZeroExtend |
  264|      0|                         spv::ImageOperandsMask::Nontemporal);
  265|      0|    size_t expected_num_image_operand_words =
  266|      0|        spvtools::utils::CountSetBits(mask_bits_having_operands);
  267|      0|    if (mask & uint32_t(spv::ImageOperandsMask::Grad)) {
  ------------------
  |  Branch (267:9): [True: 0, False: 0]
  ------------------
  268|       |      // Grad uses two words.
  269|      0|      ++expected_num_image_operand_words;
  270|      0|    }
  271|       |
  272|      0|    if (expected_num_image_operand_words != num_words - word_index) {
  ------------------
  |  Branch (272:9): [True: 0, False: 0]
  ------------------
  273|      0|      return _.diag(SPV_ERROR_INVALID_DATA, inst)
  274|      0|             << "Number of image operand ids doesn't correspond to the bit "
  275|      0|                "mask";
  276|      0|    }
  277|     64|  } else if (num_words != word_index - 1) {
  ------------------
  |  Branch (277:14): [True: 0, False: 64]
  ------------------
  278|      0|    return _.diag(SPV_ERROR_INVALID_DATA, inst)
  279|      0|           << "Number of image operand ids doesn't correspond to the bit mask";
  280|      0|  }
  281|       |
  282|     64|  if (info.multisampled &
  ------------------
  |  Branch (282:7): [True: 0, False: 64]
  ------------------
  283|     64|      (0 == (mask & uint32_t(spv::ImageOperandsMask::Sample)))) {
  284|      0|    return _.diag(SPV_ERROR_INVALID_DATA, inst)
  285|      0|           << "Image Operand Sample is required for operation on "
  286|      0|              "multi-sampled image";
  287|      0|  }
  288|       |
  289|       |  // After this point, only set bits in the image operands mask can cause
  290|       |  // the module to be invalid.
  291|     64|  if (mask == 0) return SPV_SUCCESS;
  ------------------
  |  Branch (291:7): [True: 64, False: 0]
  ------------------
  292|       |
  293|      0|  if (spvtools::utils::CountSetBits(
  ------------------
  |  Branch (293:7): [True: 0, False: 0]
  ------------------
  294|      0|          mask & uint32_t(spv::ImageOperandsMask::Offset |
  295|      0|                          spv::ImageOperandsMask::ConstOffset |
  296|      0|                          spv::ImageOperandsMask::ConstOffsets |
  297|      0|                          spv::ImageOperandsMask::Offsets)) > 1) {
  298|      0|    return _.diag(SPV_ERROR_INVALID_DATA, inst)
  299|      0|           << _.VkErrorID(4662)
  300|      0|           << "Image Operands Offset, ConstOffset, ConstOffsets, Offsets "
  301|      0|              "cannot be used together";
  302|      0|  }
  303|       |
  304|      0|  const bool is_implicit_lod = IsImplicitLod(opcode);
  305|      0|  const bool is_explicit_lod = IsExplicitLod(opcode);
  306|      0|  const bool is_valid_lod_operand = IsValidLodOperand(_, opcode);
  307|      0|  const bool is_valid_gather_lod_bias_amd = IsValidGatherLodBiasAMD(_, opcode);
  308|       |
  309|       |  // The checks should be done in the order of definition of OperandImage.
  310|       |
  311|      0|  if (mask & uint32_t(spv::ImageOperandsMask::Bias)) {
  ------------------
  |  Branch (311:7): [True: 0, False: 0]
  ------------------
  312|      0|    if (!is_implicit_lod && !is_valid_gather_lod_bias_amd) {
  ------------------
  |  Branch (312:9): [True: 0, False: 0]
  |  Branch (312:29): [True: 0, False: 0]
  ------------------
  313|      0|      return _.diag(SPV_ERROR_INVALID_DATA, inst)
  314|      0|             << "Image Operand Bias can only be used with ImplicitLod opcodes";
  315|      0|    }
  316|       |
  317|      0|    const uint32_t type_id = _.GetTypeId(inst->word(word_index++));
  318|      0|    if (!_.IsFloatScalarType(type_id)) {
  ------------------
  |  Branch (318:9): [True: 0, False: 0]
  ------------------
  319|      0|      return _.diag(SPV_ERROR_INVALID_DATA, inst)
  320|      0|             << "Expected Image Operand Bias to be float scalar";
  321|      0|    }
  322|       |
  323|      0|    if (info.dim != spv::Dim::Dim1D && info.dim != spv::Dim::Dim2D &&
  ------------------
  |  Branch (323:9): [True: 0, False: 0]
  |  Branch (323:40): [True: 0, False: 0]
  ------------------
  324|      0|        info.dim != spv::Dim::Dim3D && info.dim != spv::Dim::Cube) {
  ------------------
  |  Branch (324:9): [True: 0, False: 0]
  |  Branch (324:40): [True: 0, False: 0]
  ------------------
  325|      0|      return _.diag(SPV_ERROR_INVALID_DATA, inst)
  326|      0|             << "Image Operand Bias requires 'Dim' parameter to be 1D, 2D, 3D "
  327|      0|                "or Cube";
  328|      0|    }
  329|       |
  330|       |    // Multisampled is already checked.
  331|      0|  }
  332|       |
  333|      0|  if (mask & uint32_t(spv::ImageOperandsMask::Lod)) {
  ------------------
  |  Branch (333:7): [True: 0, False: 0]
  ------------------
  334|      0|    if (!is_valid_lod_operand && opcode != spv::Op::OpImageFetch &&
  ------------------
  |  Branch (334:9): [True: 0, False: 0]
  |  Branch (334:34): [True: 0, False: 0]
  ------------------
  335|      0|        opcode != spv::Op::OpImageSparseFetch &&
  ------------------
  |  Branch (335:9): [True: 0, False: 0]
  ------------------
  336|      0|        !is_valid_gather_lod_bias_amd) {
  ------------------
  |  Branch (336:9): [True: 0, False: 0]
  ------------------
  337|      0|      return _.diag(SPV_ERROR_INVALID_DATA, inst)
  338|      0|             << "Image Operand Lod can only be used with ExplicitLod opcodes "
  339|      0|             << "and OpImageFetch";
  340|      0|    }
  341|       |
  342|      0|    if (mask & uint32_t(spv::ImageOperandsMask::Grad)) {
  ------------------
  |  Branch (342:9): [True: 0, False: 0]
  ------------------
  343|      0|      return _.diag(SPV_ERROR_INVALID_DATA, inst)
  344|      0|             << "Image Operand bits Lod and Grad cannot be set at the same "
  345|      0|                "time";
  346|      0|    }
  347|       |
  348|      0|    const uint32_t type_id = _.GetTypeId(inst->word(word_index++));
  349|      0|    if (is_explicit_lod || is_valid_gather_lod_bias_amd) {
  ------------------
  |  Branch (349:9): [True: 0, False: 0]
  |  Branch (349:28): [True: 0, False: 0]
  ------------------
  350|      0|      if (!_.IsFloatScalarType(type_id)) {
  ------------------
  |  Branch (350:11): [True: 0, False: 0]
  ------------------
  351|      0|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
  352|      0|               << "Expected Image Operand Lod to be float scalar when used "
  353|      0|               << "with ExplicitLod";
  354|      0|      }
  355|      0|    } else {
  356|      0|      if (!_.IsIntScalarType(type_id)) {
  ------------------
  |  Branch (356:11): [True: 0, False: 0]
  ------------------
  357|      0|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
  358|      0|               << "Expected Image Operand Lod to be int scalar when used with "
  359|      0|               << "OpImageFetch";
  360|      0|      }
  361|      0|    }
  362|       |
  363|      0|    if (info.dim != spv::Dim::Dim1D && info.dim != spv::Dim::Dim2D &&
  ------------------
  |  Branch (363:9): [True: 0, False: 0]
  |  Branch (363:40): [True: 0, False: 0]
  ------------------
  364|      0|        info.dim != spv::Dim::Dim3D && info.dim != spv::Dim::Cube) {
  ------------------
  |  Branch (364:9): [True: 0, False: 0]
  |  Branch (364:40): [True: 0, False: 0]
  ------------------
  365|      0|      return _.diag(SPV_ERROR_INVALID_DATA, inst)
  366|      0|             << "Image Operand Lod requires 'Dim' parameter to be 1D, 2D, 3D "
  367|      0|                "or Cube";
  368|      0|    }
  369|       |
  370|       |    // Multisampled is already checked.
  371|      0|  }
  372|       |
  373|      0|  if (mask & uint32_t(spv::ImageOperandsMask::Grad)) {
  ------------------
  |  Branch (373:7): [True: 0, False: 0]
  ------------------
  374|      0|    if (!is_explicit_lod) {
  ------------------
  |  Branch (374:9): [True: 0, False: 0]
  ------------------
  375|      0|      return _.diag(SPV_ERROR_INVALID_DATA, inst)
  376|      0|             << "Image Operand Grad can only be used with ExplicitLod opcodes";
  377|      0|    }
  378|       |
  379|      0|    const uint32_t dx_type_id = _.GetTypeId(inst->word(word_index++));
  380|      0|    const uint32_t dy_type_id = _.GetTypeId(inst->word(word_index++));
  381|      0|    if (!_.IsFloatScalarOrVectorType(dx_type_id) ||
  ------------------
  |  Branch (381:9): [True: 0, False: 0]
  ------------------
  382|      0|        !_.IsFloatScalarOrVectorType(dy_type_id)) {
  ------------------
  |  Branch (382:9): [True: 0, False: 0]
  ------------------
  383|      0|      return _.diag(SPV_ERROR_INVALID_DATA, inst)
  384|      0|             << "Expected both Image Operand Grad ids to be float scalars or "
  385|      0|             << "vectors";
  386|      0|    }
  387|       |
  388|      0|    const uint32_t plane_size = GetPlaneCoordSize(info);
  389|      0|    const uint32_t dx_size = _.GetDimension(dx_type_id);
  390|      0|    const uint32_t dy_size = _.GetDimension(dy_type_id);
  391|      0|    if (plane_size != dx_size) {
  ------------------
  |  Branch (391:9): [True: 0, False: 0]
  ------------------
  392|      0|      return _.diag(SPV_ERROR_INVALID_DATA, inst)
  393|      0|             << "Expected Image Operand Grad dx to have " << plane_size
  394|      0|             << " components, but given " << dx_size;
  395|      0|    }
  396|       |
  397|      0|    if (plane_size != dy_size) {
  ------------------
  |  Branch (397:9): [True: 0, False: 0]
  ------------------
  398|      0|      return _.diag(SPV_ERROR_INVALID_DATA, inst)
  399|      0|             << "Expected Image Operand Grad dy to have " << plane_size
  400|      0|             << " components, but given " << dy_size;
  401|      0|    }
  402|       |
  403|       |    // Multisampled is already checked.
  404|      0|  }
  405|       |
  406|      0|  if (mask & uint32_t(spv::ImageOperandsMask::ConstOffset)) {
  ------------------
  |  Branch (406:7): [True: 0, False: 0]
  ------------------
  407|      0|    if (info.dim == spv::Dim::Cube) {
  ------------------
  |  Branch (407:9): [True: 0, False: 0]
  ------------------
  408|      0|      return _.diag(SPV_ERROR_INVALID_DATA, inst)
  409|      0|             << "Image Operand ConstOffset cannot be used with Cube Image "
  410|      0|                "'Dim'";
  411|      0|    }
  412|       |
  413|      0|    const uint32_t id = inst->word(word_index++);
  414|      0|    const uint32_t type_id = _.GetTypeId(id);
  415|      0|    if (!_.IsIntScalarOrVectorType(type_id)) {
  ------------------
  |  Branch (415:9): [True: 0, False: 0]
  ------------------
  416|      0|      return _.diag(SPV_ERROR_INVALID_DATA, inst)
  417|      0|             << "Expected Image Operand ConstOffset to be int scalar or "
  418|      0|             << "vector";
  419|      0|    }
  420|       |
  421|      0|    if (!spvOpcodeIsConstant(_.GetIdOpcode(id))) {
  ------------------
  |  Branch (421:9): [True: 0, False: 0]
  ------------------
  422|      0|      return _.diag(SPV_ERROR_INVALID_DATA, inst)
  423|      0|             << "Expected Image Operand ConstOffset to be a const object";
  424|      0|    }
  425|       |
  426|      0|    const uint32_t plane_size = GetPlaneCoordSize(info);
  427|      0|    const uint32_t offset_size = _.GetDimension(type_id);
  428|      0|    if (plane_size != offset_size) {
  ------------------
  |  Branch (428:9): [True: 0, False: 0]
  ------------------
  429|      0|      return _.diag(SPV_ERROR_INVALID_DATA, inst)
  430|      0|             << "Expected Image Operand ConstOffset to have " << plane_size
  431|      0|             << " components, but given " << offset_size;
  432|      0|    }
  433|      0|  }
  434|       |
  435|      0|  if (mask & uint32_t(spv::ImageOperandsMask::Offset)) {
  ------------------
  |  Branch (435:7): [True: 0, False: 0]
  ------------------
  436|      0|    if (info.dim == spv::Dim::Cube) {
  ------------------
  |  Branch (436:9): [True: 0, False: 0]
  ------------------
  437|      0|      return _.diag(SPV_ERROR_INVALID_DATA, inst)
  438|      0|             << "Image Operand Offset cannot be used with Cube Image 'Dim'";
  439|      0|    }
  440|       |
  441|      0|    const uint32_t id = inst->word(word_index++);
  442|      0|    const uint32_t type_id = _.GetTypeId(id);
  443|      0|    if (!_.IsIntScalarOrVectorType(type_id)) {
  ------------------
  |  Branch (443:9): [True: 0, False: 0]
  ------------------
  444|      0|      return _.diag(SPV_ERROR_INVALID_DATA, inst)
  445|      0|             << "Expected Image Operand Offset to be int scalar or "
  446|      0|             << "vector";
  447|      0|    }
  448|       |
  449|      0|    const uint32_t plane_size = GetPlaneCoordSize(info);
  450|      0|    const uint32_t offset_size = _.GetDimension(type_id);
  451|      0|    if (plane_size != offset_size) {
  ------------------
  |  Branch (451:9): [True: 0, False: 0]
  ------------------
  452|      0|      return _.diag(SPV_ERROR_INVALID_DATA, inst)
  453|      0|             << "Expected Image Operand Offset to have " << plane_size
  454|      0|             << " components, but given " << offset_size;
  455|      0|    }
  456|       |
  457|      0|    if (!_.options()->before_hlsl_legalization &&
  ------------------
  |  Branch (457:9): [True: 0, False: 0]
  ------------------
  458|      0|        spvIsVulkanEnv(_.context()->target_env)) {
  ------------------
  |  Branch (458:9): [True: 0, False: 0]
  ------------------
  459|      0|      if (opcode != spv::Op::OpImageGather &&
  ------------------
  |  Branch (459:11): [True: 0, False: 0]
  ------------------
  460|      0|          opcode != spv::Op::OpImageDrefGather &&
  ------------------
  |  Branch (460:11): [True: 0, False: 0]
  ------------------
  461|      0|          opcode != spv::Op::OpImageSparseGather &&
  ------------------
  |  Branch (461:11): [True: 0, False: 0]
  ------------------
  462|      0|          opcode != spv::Op::OpImageSparseDrefGather) {
  ------------------
  |  Branch (462:11): [True: 0, False: 0]
  ------------------
  463|      0|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
  464|      0|               << _.VkErrorID(4663)
  465|      0|               << "Image Operand Offset can only be used with "
  466|      0|                  "OpImage*Gather operations";
  467|      0|      }
  468|      0|    }
  469|      0|  }
  470|       |
  471|      0|  if (mask & uint32_t(spv::ImageOperandsMask::ConstOffsets)) {
  ------------------
  |  Branch (471:7): [True: 0, False: 0]
  ------------------
  472|      0|    if (opcode != spv::Op::OpImageGather &&
  ------------------
  |  Branch (472:9): [True: 0, False: 0]
  ------------------
  473|      0|        opcode != spv::Op::OpImageDrefGather &&
  ------------------
  |  Branch (473:9): [True: 0, False: 0]
  ------------------
  474|      0|        opcode != spv::Op::OpImageSparseGather &&
  ------------------
  |  Branch (474:9): [True: 0, False: 0]
  ------------------
  475|      0|        opcode != spv::Op::OpImageSparseDrefGather) {
  ------------------
  |  Branch (475:9): [True: 0, False: 0]
  ------------------
  476|      0|      return _.diag(SPV_ERROR_INVALID_DATA, inst)
  477|      0|             << "Image Operand ConstOffsets can only be used with "
  478|      0|                "OpImageGather and OpImageDrefGather";
  479|      0|    }
  480|       |
  481|      0|    if (info.dim == spv::Dim::Cube) {
  ------------------
  |  Branch (481:9): [True: 0, False: 0]
  ------------------
  482|      0|      return _.diag(SPV_ERROR_INVALID_DATA, inst)
  483|      0|             << "Image Operand ConstOffsets cannot be used with Cube Image "
  484|      0|                "'Dim'";
  485|      0|    }
  486|       |
  487|      0|    const uint32_t id = inst->word(word_index++);
  488|      0|    const uint32_t type_id = _.GetTypeId(id);
  489|      0|    const Instruction* type_inst = _.FindDef(type_id);
  490|      0|    assert(type_inst);
  491|       |
  492|      0|    if (type_inst->opcode() != spv::Op::OpTypeArray) {
  ------------------
  |  Branch (492:9): [True: 0, False: 0]
  ------------------
  493|      0|      return _.diag(SPV_ERROR_INVALID_DATA, inst)
  494|      0|             << "Expected Image Operand ConstOffsets to be an array of size 4";
  495|      0|    }
  496|       |
  497|      0|    uint64_t array_size = 0;
  498|      0|    if (!_.GetConstantValUint64(type_inst->word(3), &array_size)) {
  ------------------
  |  Branch (498:9): [True: 0, False: 0]
  ------------------
  499|      0|      assert(0 && "Array type definition is corrupt");
  500|      0|    }
  501|       |
  502|      0|    if (array_size != 4) {
  ------------------
  |  Branch (502:9): [True: 0, False: 0]
  ------------------
  503|      0|      return _.diag(SPV_ERROR_INVALID_DATA, inst)
  504|      0|             << "Expected Image Operand ConstOffsets to be an array of size 4";
  505|      0|    }
  506|       |
  507|      0|    const uint32_t component_type = type_inst->word(2);
  508|      0|    if (!_.IsIntVectorType(component_type) ||
  ------------------
  |  Branch (508:9): [True: 0, False: 0]
  ------------------
  509|      0|        _.GetDimension(component_type) != 2) {
  ------------------
  |  Branch (509:9): [True: 0, False: 0]
  ------------------
  510|      0|      return _.diag(SPV_ERROR_INVALID_DATA, inst)
  511|      0|             << "Expected Image Operand ConstOffsets array components to be "
  512|      0|                "int vectors of size 2";
  513|      0|    }
  514|       |
  515|      0|    if (!spvOpcodeIsConstant(_.GetIdOpcode(id))) {
  ------------------
  |  Branch (515:9): [True: 0, False: 0]
  ------------------
  516|      0|      return _.diag(SPV_ERROR_INVALID_DATA, inst)
  517|      0|             << "Expected Image Operand ConstOffsets to be a const object";
  518|      0|    }
  519|      0|  }
  520|       |
  521|      0|  if (mask & uint32_t(spv::ImageOperandsMask::Sample)) {
  ------------------
  |  Branch (521:7): [True: 0, False: 0]
  ------------------
  522|      0|    if (opcode != spv::Op::OpImageFetch && opcode != spv::Op::OpImageRead &&
  ------------------
  |  Branch (522:9): [True: 0, False: 0]
  |  Branch (522:44): [True: 0, False: 0]
  ------------------
  523|      0|        opcode != spv::Op::OpImageWrite &&
  ------------------
  |  Branch (523:9): [True: 0, False: 0]
  ------------------
  524|      0|        opcode != spv::Op::OpImageSparseFetch &&
  ------------------
  |  Branch (524:9): [True: 0, False: 0]
  ------------------
  525|      0|        opcode != spv::Op::OpImageSparseRead) {
  ------------------
  |  Branch (525:9): [True: 0, False: 0]
  ------------------
  526|      0|      return _.diag(SPV_ERROR_INVALID_DATA, inst)
  527|      0|             << "Image Operand Sample can only be used with OpImageFetch, "
  528|      0|             << "OpImageRead, OpImageWrite, OpImageSparseFetch and "
  529|      0|             << "OpImageSparseRead";
  530|      0|    }
  531|       |
  532|      0|    if (info.multisampled == 0) {
  ------------------
  |  Branch (532:9): [True: 0, False: 0]
  ------------------
  533|      0|      return _.diag(SPV_ERROR_INVALID_DATA, inst)
  534|      0|             << "Image Operand Sample requires non-zero 'MS' parameter";
  535|      0|    }
  536|       |
  537|      0|    const uint32_t type_id = _.GetTypeId(inst->word(word_index++));
  538|      0|    if (!_.IsIntScalarType(type_id)) {
  ------------------
  |  Branch (538:9): [True: 0, False: 0]
  ------------------
  539|      0|      return _.diag(SPV_ERROR_INVALID_DATA, inst)
  540|      0|             << "Expected Image Operand Sample to be int scalar";
  541|      0|    }
  542|      0|  }
  543|       |
  544|      0|  if (mask & uint32_t(spv::ImageOperandsMask::MinLod)) {
  ------------------
  |  Branch (544:7): [True: 0, False: 0]
  ------------------
  545|      0|    if (!is_implicit_lod && !(mask & uint32_t(spv::ImageOperandsMask::Grad))) {
  ------------------
  |  Branch (545:9): [True: 0, False: 0]
  |  Branch (545:29): [True: 0, False: 0]
  ------------------
  546|      0|      return _.diag(SPV_ERROR_INVALID_DATA, inst)
  547|      0|             << "Image Operand MinLod can only be used with ImplicitLod "
  548|      0|             << "opcodes or together with Image Operand Grad";
  549|      0|    }
  550|       |
  551|      0|    const uint32_t type_id = _.GetTypeId(inst->word(word_index++));
  552|      0|    if (!_.IsFloatScalarType(type_id)) {
  ------------------
  |  Branch (552:9): [True: 0, False: 0]
  ------------------
  553|      0|      return _.diag(SPV_ERROR_INVALID_DATA, inst)
  554|      0|             << "Expected Image Operand MinLod to be float scalar";
  555|      0|    }
  556|       |
  557|      0|    if (info.dim != spv::Dim::Dim1D && info.dim != spv::Dim::Dim2D &&
  ------------------
  |  Branch (557:9): [True: 0, False: 0]
  |  Branch (557:40): [True: 0, False: 0]
  ------------------
  558|      0|        info.dim != spv::Dim::Dim3D && info.dim != spv::Dim::Cube) {
  ------------------
  |  Branch (558:9): [True: 0, False: 0]
  |  Branch (558:40): [True: 0, False: 0]
  ------------------
  559|      0|      return _.diag(SPV_ERROR_INVALID_DATA, inst)
  560|      0|             << "Image Operand MinLod requires 'Dim' parameter to be 1D, 2D, "
  561|      0|                "3D or Cube";
  562|      0|    }
  563|       |
  564|      0|    if (info.multisampled != 0) {
  ------------------
  |  Branch (564:9): [True: 0, False: 0]
  ------------------
  565|      0|      return _.diag(SPV_ERROR_INVALID_DATA, inst)
  566|      0|             << "Image Operand MinLod requires 'MS' parameter to be 0";
  567|      0|    }
  568|      0|  }
  569|       |
  570|      0|  if (mask & uint32_t(spv::ImageOperandsMask::MakeTexelAvailableKHR)) {
  ------------------
  |  Branch (570:7): [True: 0, False: 0]
  ------------------
  571|       |    // Checked elsewhere: capability and memory model are correct.
  572|      0|    if (opcode != spv::Op::OpImageWrite) {
  ------------------
  |  Branch (572:9): [True: 0, False: 0]
  ------------------
  573|      0|      return _.diag(SPV_ERROR_INVALID_DATA, inst)
  574|      0|             << "Image Operand MakeTexelAvailableKHR can only be used with Op"
  575|      0|             << spvOpcodeString(spv::Op::OpImageWrite) << ": Op"
  576|      0|             << spvOpcodeString(opcode);
  577|      0|    }
  578|       |
  579|      0|    if (!(mask & uint32_t(spv::ImageOperandsMask::NonPrivateTexelKHR))) {
  ------------------
  |  Branch (579:9): [True: 0, False: 0]
  ------------------
  580|      0|      return _.diag(SPV_ERROR_INVALID_DATA, inst)
  581|      0|             << "Image Operand MakeTexelAvailableKHR requires "
  582|      0|                "NonPrivateTexelKHR is also specified: Op"
  583|      0|             << spvOpcodeString(opcode);
  584|      0|    }
  585|       |
  586|      0|    const auto available_scope = inst->word(word_index++);
  587|      0|    if (auto error = ValidateMemoryScope(_, inst, available_scope))
  ------------------
  |  Branch (587:14): [True: 0, False: 0]
  ------------------
  588|      0|      return error;
  589|      0|  }
  590|       |
  591|      0|  if (mask & uint32_t(spv::ImageOperandsMask::MakeTexelVisibleKHR)) {
  ------------------
  |  Branch (591:7): [True: 0, False: 0]
  ------------------
  592|       |    // Checked elsewhere: capability and memory model are correct.
  593|      0|    if (opcode != spv::Op::OpImageRead &&
  ------------------
  |  Branch (593:9): [True: 0, False: 0]
  ------------------
  594|      0|        opcode != spv::Op::OpImageSparseRead) {
  ------------------
  |  Branch (594:9): [True: 0, False: 0]
  ------------------
  595|      0|      return _.diag(SPV_ERROR_INVALID_DATA, inst)
  596|      0|             << "Image Operand MakeTexelVisibleKHR can only be used with Op"
  597|      0|             << spvOpcodeString(spv::Op::OpImageRead) << " or Op"
  598|      0|             << spvOpcodeString(spv::Op::OpImageSparseRead) << ": Op"
  599|      0|             << spvOpcodeString(opcode);
  600|      0|    }
  601|       |
  602|      0|    if (!(mask & uint32_t(spv::ImageOperandsMask::NonPrivateTexelKHR))) {
  ------------------
  |  Branch (602:9): [True: 0, False: 0]
  ------------------
  603|      0|      return _.diag(SPV_ERROR_INVALID_DATA, inst)
  604|      0|             << "Image Operand MakeTexelVisibleKHR requires NonPrivateTexelKHR "
  605|      0|                "is also specified: Op"
  606|      0|             << spvOpcodeString(opcode);
  607|      0|    }
  608|       |
  609|      0|    const auto visible_scope = inst->word(word_index++);
  610|      0|    if (auto error = ValidateMemoryScope(_, inst, visible_scope)) return error;
  ------------------
  |  Branch (610:14): [True: 0, False: 0]
  ------------------
  611|      0|  }
  612|       |
  613|      0|  if (mask & uint32_t(spv::ImageOperandsMask::SignExtend)) {
  ------------------
  |  Branch (613:7): [True: 0, False: 0]
  ------------------
  614|       |    // Checked elsewhere: SPIR-V 1.4 version or later.
  615|       |
  616|       |    // "The texel value is converted to the target value via sign extension.
  617|       |    // Only valid when the texel type is a scalar or vector of integer type."
  618|       |    //
  619|       |    // We don't have enough information to know what the texel type is.
  620|       |    // In OpenCL, knowledge is deferred until runtime: the image SampledType is
  621|       |    // void, and the Format is Unknown.
  622|       |    // In Vulkan, the texel type is only known in all cases by the pipeline
  623|       |    // setup.
  624|      0|  }
  625|       |
  626|      0|  if (mask & uint32_t(spv::ImageOperandsMask::ZeroExtend)) {
  ------------------
  |  Branch (626:7): [True: 0, False: 0]
  ------------------
  627|       |    // Checked elsewhere: SPIR-V 1.4 version or later.
  628|       |
  629|       |    // "The texel value is converted to the target value via zero extension.
  630|       |    // Only valid when the texel type is a scalar or vector of integer type."
  631|       |    //
  632|       |    // We don't have enough information to know what the texel type is.
  633|       |    // In OpenCL, knowledge is deferred until runtime: the image SampledType is
  634|       |    // void, and the Format is Unknown.
  635|       |    // In Vulkan, the texel type is only known in all cases by the pipeline
  636|       |    // setup.
  637|      0|  }
  638|       |
  639|      0|  if (mask & uint32_t(spv::ImageOperandsMask::Offsets)) {
  ------------------
  |  Branch (639:7): [True: 0, False: 0]
  ------------------
  640|       |    // TODO: add validation
  641|      0|  }
  642|       |
  643|      0|  if (mask & uint32_t(spv::ImageOperandsMask::Nontemporal)) {
  ------------------
  |  Branch (643:7): [True: 0, False: 0]
  ------------------
  644|       |    // Checked elsewhere: SPIR-V 1.6 version or later.
  645|      0|  }
  646|       |
  647|      0|  return SPV_SUCCESS;
  648|      0|}
validate_image.cpp:_ZN8spvtools3val12_GLOBAL__N_128CheckAllImageOperandsHandledEv:
   39|      1|bool CheckAllImageOperandsHandled() {
   40|      1|  spv::ImageOperandsMask enum_val = spv::ImageOperandsMask::Bias;
   41|       |
   42|       |  // Some improvised code to prevent the compiler from considering enum_val
   43|       |  // constant and optimizing the switch away.
   44|      1|  uint32_t stack_var = 0;
   45|      1|  if (reinterpret_cast<uintptr_t>(&stack_var) % 256)
  ------------------
  |  Branch (45:7): [True: 1, False: 0]
  ------------------
   46|      1|    enum_val = spv::ImageOperandsMask::Lod;
   47|       |
   48|      1|  switch (enum_val) {
  ------------------
  |  Branch (48:11): [True: 0, False: 1]
  ------------------
   49|       |    // Please update the validation rules in this module if you are changing
   50|       |    // the list of image operands, and add new enum values to this switch.
   51|      0|    case spv::ImageOperandsMask::MaskNone:
  ------------------
  |  Branch (51:5): [True: 0, False: 1]
  ------------------
   52|      0|      return false;
   53|      0|    case spv::ImageOperandsMask::Bias:
  ------------------
  |  Branch (53:5): [True: 0, False: 1]
  ------------------
   54|      1|    case spv::ImageOperandsMask::Lod:
  ------------------
  |  Branch (54:5): [True: 1, False: 0]
  ------------------
   55|      1|    case spv::ImageOperandsMask::Grad:
  ------------------
  |  Branch (55:5): [True: 0, False: 1]
  ------------------
   56|      1|    case spv::ImageOperandsMask::ConstOffset:
  ------------------
  |  Branch (56:5): [True: 0, False: 1]
  ------------------
   57|      1|    case spv::ImageOperandsMask::Offset:
  ------------------
  |  Branch (57:5): [True: 0, False: 1]
  ------------------
   58|      1|    case spv::ImageOperandsMask::ConstOffsets:
  ------------------
  |  Branch (58:5): [True: 0, False: 1]
  ------------------
   59|      1|    case spv::ImageOperandsMask::Sample:
  ------------------
  |  Branch (59:5): [True: 0, False: 1]
  ------------------
   60|      1|    case spv::ImageOperandsMask::MinLod:
  ------------------
  |  Branch (60:5): [True: 0, False: 1]
  ------------------
   61|       |
   62|       |    // TODO(dneto): Support image operands related to the Vulkan memory model.
   63|       |    // https://gitlab.khronos.org/spirv/spirv-tools/issues/32
   64|      1|    case spv::ImageOperandsMask::MakeTexelAvailableKHR:
  ------------------
  |  Branch (64:5): [True: 0, False: 1]
  ------------------
   65|      1|    case spv::ImageOperandsMask::MakeTexelVisibleKHR:
  ------------------
  |  Branch (65:5): [True: 0, False: 1]
  ------------------
   66|      1|    case spv::ImageOperandsMask::NonPrivateTexelKHR:
  ------------------
  |  Branch (66:5): [True: 0, False: 1]
  ------------------
   67|      1|    case spv::ImageOperandsMask::VolatileTexelKHR:
  ------------------
  |  Branch (67:5): [True: 0, False: 1]
  ------------------
   68|      1|    case spv::ImageOperandsMask::SignExtend:
  ------------------
  |  Branch (68:5): [True: 0, False: 1]
  ------------------
   69|      1|    case spv::ImageOperandsMask::ZeroExtend:
  ------------------
  |  Branch (69:5): [True: 0, False: 1]
  ------------------
   70|       |    // TODO(jaebaek): Move this line properly after handling image offsets
   71|       |    //                operand. This line temporarily fixes CI failure that
   72|       |    //                blocks other PRs.
   73|       |    // https://github.com/KhronosGroup/SPIRV-Tools/issues/4565
   74|      1|    case spv::ImageOperandsMask::Offsets:
  ------------------
  |  Branch (74:5): [True: 0, False: 1]
  ------------------
   75|      1|    case spv::ImageOperandsMask::Nontemporal:
  ------------------
  |  Branch (75:5): [True: 0, False: 1]
  ------------------
   76|      1|      return true;
   77|      1|  }
   78|      0|  return false;
   79|      1|}
validate_image.cpp:_ZN8spvtools3val12_GLOBAL__N_120ValidateImageDrefLodERNS0_17ValidationState_tEPKNS0_11InstructionE:
 1305|     14|                                  const Instruction* inst) {
 1306|     14|  const spv::Op opcode = inst->opcode();
 1307|     14|  uint32_t actual_result_type = 0;
 1308|     14|  if (spv_result_t error = GetActualResultType(_, inst, &actual_result_type)) {
  ------------------
  |  Branch (1308:20): [True: 0, False: 14]
  ------------------
 1309|      0|    return error;
 1310|      0|  }
 1311|       |
 1312|     14|  if (!_.IsIntScalarType(actual_result_type) &&
  ------------------
  |  Branch (1312:7): [True: 13, False: 1]
  ------------------
 1313|     14|      !_.IsFloatScalarType(actual_result_type)) {
  ------------------
  |  Branch (1313:7): [True: 1, False: 12]
  ------------------
 1314|      1|    return _.diag(SPV_ERROR_INVALID_DATA, inst)
 1315|      1|           << "Expected " << GetActualResultTypeStr(opcode)
 1316|      1|           << " to be int or float scalar type";
 1317|      1|  }
 1318|       |
 1319|     13|  const uint32_t image_type = _.GetOperandTypeId(inst, 2);
 1320|     13|  if (_.GetIdOpcode(image_type) != spv::Op::OpTypeSampledImage) {
  ------------------
  |  Branch (1320:7): [True: 2, False: 11]
  ------------------
 1321|      2|    return _.diag(SPV_ERROR_INVALID_DATA, inst)
 1322|      2|           << "Expected Sampled Image to be of type OpTypeSampledImage";
 1323|      2|  }
 1324|       |
 1325|     11|  ImageTypeInfo info;
 1326|     11|  if (!GetImageTypeInfo(_, image_type, &info)) {
  ------------------
  |  Branch (1326:7): [True: 0, False: 11]
  ------------------
 1327|      0|    return _.diag(SPV_ERROR_INVALID_DATA, inst)
 1328|      0|           << "Corrupt image type definition";
 1329|      0|  }
 1330|       |
 1331|     11|  if (IsProj(opcode)) {
  ------------------
  |  Branch (1331:7): [True: 5, False: 6]
  ------------------
 1332|      5|    if (spv_result_t result = ValidateImageProj(_, inst, info)) return result;
  ------------------
  |  Branch (1332:22): [True: 2, False: 3]
  ------------------
 1333|      5|  }
 1334|       |
 1335|      9|  if (info.multisampled) {
  ------------------
  |  Branch (1335:7): [True: 1, False: 8]
  ------------------
 1336|       |    // When using image operands, the Sample image operand is required if and
 1337|       |    // only if the image is multisampled (MS=1). The Sample image operand is
 1338|       |    // only allowed for fetch, read, and write.
 1339|      1|    return _.diag(SPV_ERROR_INVALID_DATA, inst)
 1340|      1|           << "Dref sampling operation is invalid for multisample image";
 1341|      1|  }
 1342|       |
 1343|      8|  if (actual_result_type != info.sampled_type) {
  ------------------
  |  Branch (1343:7): [True: 0, False: 8]
  ------------------
 1344|      0|    return _.diag(SPV_ERROR_INVALID_DATA, inst)
 1345|      0|           << "Expected Image 'Sampled Type' to be the same as "
 1346|      0|           << GetActualResultTypeStr(opcode);
 1347|      0|  }
 1348|       |
 1349|      8|  const uint32_t coord_type = _.GetOperandTypeId(inst, 3);
 1350|      8|  if (!_.IsFloatScalarOrVectorType(coord_type)) {
  ------------------
  |  Branch (1350:7): [True: 1, False: 7]
  ------------------
 1351|      1|    return _.diag(SPV_ERROR_INVALID_DATA, inst)
 1352|      1|           << "Expected Coordinate to be float scalar or vector";
 1353|      1|  }
 1354|       |
 1355|      7|  const uint32_t min_coord_size = GetMinCoordSize(opcode, info);
 1356|      7|  const uint32_t actual_coord_size = _.GetDimension(coord_type);
 1357|      7|  if (min_coord_size > actual_coord_size) {
  ------------------
  |  Branch (1357:7): [True: 1, False: 6]
  ------------------
 1358|      1|    return _.diag(SPV_ERROR_INVALID_DATA, inst)
 1359|      1|           << "Expected Coordinate to have at least " << min_coord_size
 1360|      1|           << " components, but given only " << actual_coord_size;
 1361|      1|  }
 1362|       |
 1363|      6|  if (spv_result_t result = ValidateImageDref(_, inst, info)) return result;
  ------------------
  |  Branch (1363:20): [True: 2, False: 4]
  ------------------
 1364|       |
 1365|      4|  if (spv_result_t result =
  ------------------
  |  Branch (1365:20): [True: 0, False: 4]
  ------------------
 1366|      4|          ValidateImageOperands(_, inst, info, /* word_index = */ 7))
 1367|      0|    return result;
 1368|       |
 1369|      4|  return SPV_SUCCESS;
 1370|      4|}
validate_image.cpp:_ZN8spvtools3val12_GLOBAL__N_117ValidateImageDrefERNS0_17ValidationState_tEPKNS0_11InstructionERKNS1_13ImageTypeInfoE:
 1285|      6|                               const ImageTypeInfo& info) {
 1286|      6|  const uint32_t dref_type = _.GetOperandTypeId(inst, 4);
 1287|      6|  if (!_.IsFloatScalarType(dref_type) || _.GetBitWidth(dref_type) != 32) {
  ------------------
  |  Branch (1287:7): [True: 2, False: 4]
  |  Branch (1287:42): [True: 0, False: 4]
  ------------------
 1288|      2|    return _.diag(SPV_ERROR_INVALID_DATA, inst)
 1289|      2|           << "Expected Dref to be of 32-bit float type";
 1290|      2|  }
 1291|       |
 1292|      4|  if (spvIsVulkanEnv(_.context()->target_env)) {
  ------------------
  |  Branch (1292:7): [True: 0, False: 4]
  ------------------
 1293|      0|    if (info.dim == spv::Dim::Dim3D) {
  ------------------
  |  Branch (1293:9): [True: 0, False: 0]
  ------------------
 1294|      0|      return _.diag(SPV_ERROR_INVALID_DATA, inst)
 1295|      0|             << _.VkErrorID(4777)
 1296|      0|             << "In Vulkan, OpImage*Dref* instructions must not use images "
 1297|      0|                "with a 3D Dim";
 1298|      0|    }
 1299|      0|  }
 1300|       |
 1301|      4|  return SPV_SUCCESS;
 1302|      4|}
validate_image.cpp:_ZN8spvtools3val12_GLOBAL__N_118ValidateImageFetchERNS0_17ValidationState_tEPKNS0_11InstructionE:
 1372|      5|spv_result_t ValidateImageFetch(ValidationState_t& _, const Instruction* inst) {
 1373|      5|  uint32_t actual_result_type = 0;
 1374|      5|  if (spv_result_t error = GetActualResultType(_, inst, &actual_result_type)) {
  ------------------
  |  Branch (1374:20): [True: 1, False: 4]
  ------------------
 1375|      1|    return error;
 1376|      1|  }
 1377|       |
 1378|      4|  const spv::Op opcode = inst->opcode();
 1379|      4|  if (!_.IsIntVectorType(actual_result_type) &&
  ------------------
  |  Branch (1379:7): [True: 3, False: 1]
  ------------------
 1380|      4|      !_.IsFloatVectorType(actual_result_type)) {
  ------------------
  |  Branch (1380:7): [True: 0, False: 3]
  ------------------
 1381|      0|    return _.diag(SPV_ERROR_INVALID_DATA, inst)
 1382|      0|           << "Expected " << GetActualResultTypeStr(opcode)
 1383|      0|           << " to be int or float vector type";
 1384|      0|  }
 1385|       |
 1386|      4|  if (_.GetDimension(actual_result_type) != 4) {
  ------------------
  |  Branch (1386:7): [True: 3, False: 1]
  ------------------
 1387|      3|    return _.diag(SPV_ERROR_INVALID_DATA, inst)
 1388|      3|           << "Expected " << GetActualResultTypeStr(opcode)
 1389|      3|           << " to have 4 components";
 1390|      3|  }
 1391|       |
 1392|      1|  const uint32_t image_type = _.GetOperandTypeId(inst, 2);
 1393|      1|  if (_.GetIdOpcode(image_type) != spv::Op::OpTypeImage) {
  ------------------
  |  Branch (1393:7): [True: 1, False: 0]
  ------------------
 1394|      1|    return _.diag(SPV_ERROR_INVALID_DATA, inst)
 1395|      1|           << "Expected Image to be of type OpTypeImage";
 1396|      1|  }
 1397|       |
 1398|      0|  ImageTypeInfo info;
 1399|      0|  if (!GetImageTypeInfo(_, image_type, &info)) {
  ------------------
  |  Branch (1399:7): [True: 0, False: 0]
  ------------------
 1400|      0|    return _.diag(SPV_ERROR_INVALID_DATA, inst)
 1401|      0|           << "Corrupt image type definition";
 1402|      0|  }
 1403|       |
 1404|      0|  if (_.GetIdOpcode(info.sampled_type) != spv::Op::OpTypeVoid) {
  ------------------
  |  Branch (1404:7): [True: 0, False: 0]
  ------------------
 1405|      0|    const uint32_t result_component_type =
 1406|      0|        _.GetComponentType(actual_result_type);
 1407|      0|    if (result_component_type != info.sampled_type) {
  ------------------
  |  Branch (1407:9): [True: 0, False: 0]
  ------------------
 1408|      0|      return _.diag(SPV_ERROR_INVALID_DATA, inst)
 1409|      0|             << "Expected Image 'Sampled Type' to be the same as "
 1410|      0|             << GetActualResultTypeStr(opcode) << " components";
 1411|      0|    }
 1412|      0|  }
 1413|       |
 1414|      0|  if (info.dim == spv::Dim::Cube) {
  ------------------
  |  Branch (1414:7): [True: 0, False: 0]
  ------------------
 1415|      0|    return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Image 'Dim' cannot be Cube";
 1416|      0|  }
 1417|       |
 1418|      0|  if (info.sampled != 1) {
  ------------------
  |  Branch (1418:7): [True: 0, False: 0]
  ------------------
 1419|      0|    return _.diag(SPV_ERROR_INVALID_DATA, inst)
 1420|      0|           << "Expected Image 'Sampled' parameter to be 1";
 1421|      0|  }
 1422|       |
 1423|      0|  const uint32_t coord_type = _.GetOperandTypeId(inst, 3);
 1424|      0|  if (!_.IsIntScalarOrVectorType(coord_type)) {
  ------------------
  |  Branch (1424:7): [True: 0, False: 0]
  ------------------
 1425|      0|    return _.diag(SPV_ERROR_INVALID_DATA, inst)
 1426|      0|           << "Expected Coordinate to be int scalar or vector";
 1427|      0|  }
 1428|       |
 1429|      0|  const uint32_t min_coord_size = GetMinCoordSize(opcode, info);
 1430|      0|  const uint32_t actual_coord_size = _.GetDimension(coord_type);
 1431|      0|  if (min_coord_size > actual_coord_size) {
  ------------------
  |  Branch (1431:7): [True: 0, False: 0]
  ------------------
 1432|      0|    return _.diag(SPV_ERROR_INVALID_DATA, inst)
 1433|      0|           << "Expected Coordinate to have at least " << min_coord_size
 1434|      0|           << " components, but given only " << actual_coord_size;
 1435|      0|  }
 1436|       |
 1437|      0|  if (spv_result_t result =
  ------------------
  |  Branch (1437:20): [True: 0, False: 0]
  ------------------
 1438|      0|          ValidateImageOperands(_, inst, info, /* word_index = */ 6))
 1439|      0|    return result;
 1440|       |
 1441|      0|  return SPV_SUCCESS;
 1442|      0|}
validate_image.cpp:_ZN8spvtools3val12_GLOBAL__N_119ValidateImageGatherERNS0_17ValidationState_tEPKNS0_11InstructionE:
 1445|      5|                                 const Instruction* inst) {
 1446|      5|  uint32_t actual_result_type = 0;
 1447|      5|  if (spv_result_t error = GetActualResultType(_, inst, &actual_result_type))
  ------------------
  |  Branch (1447:20): [True: 0, False: 5]
  ------------------
 1448|      0|    return error;
 1449|       |
 1450|      5|  const spv::Op opcode = inst->opcode();
 1451|      5|  if (!_.IsIntVectorType(actual_result_type) &&
  ------------------
  |  Branch (1451:7): [True: 4, False: 1]
  ------------------
 1452|      5|      !_.IsFloatVectorType(actual_result_type)) {
  ------------------
  |  Branch (1452:7): [True: 4, False: 0]
  ------------------
 1453|      4|    return _.diag(SPV_ERROR_INVALID_DATA, inst)
 1454|      4|           << "Expected " << GetActualResultTypeStr(opcode)
 1455|      4|           << " to be int or float vector type";
 1456|      4|  }
 1457|       |
 1458|      1|  if (_.GetDimension(actual_result_type) != 4) {
  ------------------
  |  Branch (1458:7): [True: 1, False: 0]
  ------------------
 1459|      1|    return _.diag(SPV_ERROR_INVALID_DATA, inst)
 1460|      1|           << "Expected " << GetActualResultTypeStr(opcode)
 1461|      1|           << " to have 4 components";
 1462|      1|  }
 1463|       |
 1464|      0|  const uint32_t image_type = _.GetOperandTypeId(inst, 2);
 1465|      0|  if (_.GetIdOpcode(image_type) != spv::Op::OpTypeSampledImage) {
  ------------------
  |  Branch (1465:7): [True: 0, False: 0]
  ------------------
 1466|      0|    return _.diag(SPV_ERROR_INVALID_DATA, inst)
 1467|      0|           << "Expected Sampled Image to be of type OpTypeSampledImage";
 1468|      0|  }
 1469|       |
 1470|      0|  ImageTypeInfo info;
 1471|      0|  if (!GetImageTypeInfo(_, image_type, &info)) {
  ------------------
  |  Branch (1471:7): [True: 0, False: 0]
  ------------------
 1472|      0|    return _.diag(SPV_ERROR_INVALID_DATA, inst)
 1473|      0|           << "Corrupt image type definition";
 1474|      0|  }
 1475|       |
 1476|      0|  if (info.multisampled) {
  ------------------
  |  Branch (1476:7): [True: 0, False: 0]
  ------------------
 1477|       |    // When using image operands, the Sample image operand is required if and
 1478|       |    // only if the image is multisampled (MS=1). The Sample image operand is
 1479|       |    // only allowed for fetch, read, and write.
 1480|      0|    return _.diag(SPV_ERROR_INVALID_DATA, inst)
 1481|      0|           << "Gather operation is invalid for multisample image";
 1482|      0|  }
 1483|       |
 1484|      0|  if (opcode == spv::Op::OpImageDrefGather ||
  ------------------
  |  Branch (1484:7): [True: 0, False: 0]
  ------------------
 1485|      0|      opcode == spv::Op::OpImageSparseDrefGather ||
  ------------------
  |  Branch (1485:7): [True: 0, False: 0]
  ------------------
 1486|      0|      _.GetIdOpcode(info.sampled_type) != spv::Op::OpTypeVoid) {
  ------------------
  |  Branch (1486:7): [True: 0, False: 0]
  ------------------
 1487|      0|    const uint32_t result_component_type =
 1488|      0|        _.GetComponentType(actual_result_type);
 1489|      0|    if (result_component_type != info.sampled_type) {
  ------------------
  |  Branch (1489:9): [True: 0, False: 0]
  ------------------
 1490|      0|      return _.diag(SPV_ERROR_INVALID_DATA, inst)
 1491|      0|             << "Expected Image 'Sampled Type' to be the same as "
 1492|      0|             << GetActualResultTypeStr(opcode) << " components";
 1493|      0|    }
 1494|      0|  }
 1495|       |
 1496|      0|  if (info.dim != spv::Dim::Dim2D && info.dim != spv::Dim::Cube &&
  ------------------
  |  Branch (1496:7): [True: 0, False: 0]
  |  Branch (1496:38): [True: 0, False: 0]
  ------------------
 1497|      0|      info.dim != spv::Dim::Rect) {
  ------------------
  |  Branch (1497:7): [True: 0, False: 0]
  ------------------
 1498|      0|    return _.diag(SPV_ERROR_INVALID_DATA, inst)
 1499|      0|           << _.VkErrorID(4777)
 1500|      0|           << "Expected Image 'Dim' to be 2D, Cube, or Rect";
 1501|      0|  }
 1502|       |
 1503|      0|  const uint32_t coord_type = _.GetOperandTypeId(inst, 3);
 1504|      0|  if (!_.IsFloatScalarOrVectorType(coord_type)) {
  ------------------
  |  Branch (1504:7): [True: 0, False: 0]
  ------------------
 1505|      0|    return _.diag(SPV_ERROR_INVALID_DATA, inst)
 1506|      0|           << "Expected Coordinate to be float scalar or vector";
 1507|      0|  }
 1508|       |
 1509|      0|  const uint32_t min_coord_size = GetMinCoordSize(opcode, info);
 1510|      0|  const uint32_t actual_coord_size = _.GetDimension(coord_type);
 1511|      0|  if (min_coord_size > actual_coord_size) {
  ------------------
  |  Branch (1511:7): [True: 0, False: 0]
  ------------------
 1512|      0|    return _.diag(SPV_ERROR_INVALID_DATA, inst)
 1513|      0|           << "Expected Coordinate to have at least " << min_coord_size
 1514|      0|           << " components, but given only " << actual_coord_size;
 1515|      0|  }
 1516|       |
 1517|      0|  if (opcode == spv::Op::OpImageGather ||
  ------------------
  |  Branch (1517:7): [True: 0, False: 0]
  ------------------
 1518|      0|      opcode == spv::Op::OpImageSparseGather) {
  ------------------
  |  Branch (1518:7): [True: 0, False: 0]
  ------------------
 1519|      0|    const uint32_t component = inst->GetOperandAs<uint32_t>(4);
 1520|      0|    const uint32_t component_index_type = _.GetTypeId(component);
 1521|      0|    if (!_.IsIntScalarType(component_index_type) ||
  ------------------
  |  Branch (1521:9): [True: 0, False: 0]
  ------------------
 1522|      0|        _.GetBitWidth(component_index_type) != 32) {
  ------------------
  |  Branch (1522:9): [True: 0, False: 0]
  ------------------
 1523|      0|      return _.diag(SPV_ERROR_INVALID_DATA, inst)
 1524|      0|             << "Expected Component to be 32-bit int scalar";
 1525|      0|    }
 1526|      0|    if (spvIsVulkanEnv(_.context()->target_env)) {
  ------------------
  |  Branch (1526:9): [True: 0, False: 0]
  ------------------
 1527|      0|      if (!spvOpcodeIsConstant(_.GetIdOpcode(component))) {
  ------------------
  |  Branch (1527:11): [True: 0, False: 0]
  ------------------
 1528|      0|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
 1529|      0|               << _.VkErrorID(4664)
 1530|      0|               << "Expected Component Operand to be a const object for Vulkan "
 1531|      0|                  "environment";
 1532|      0|      }
 1533|      0|    }
 1534|      0|  } else {
 1535|      0|    assert(opcode == spv::Op::OpImageDrefGather ||
 1536|      0|           opcode == spv::Op::OpImageSparseDrefGather);
 1537|      0|    if (spv_result_t result = ValidateImageDref(_, inst, info)) return result;
  ------------------
  |  Branch (1537:22): [True: 0, False: 0]
  ------------------
 1538|      0|  }
 1539|       |
 1540|      0|  if (spv_result_t result =
  ------------------
  |  Branch (1540:20): [True: 0, False: 0]
  ------------------
 1541|      0|          ValidateImageOperands(_, inst, info, /* word_index = */ 7))
 1542|      0|    return result;
 1543|       |
 1544|      0|  return SPV_SUCCESS;
 1545|      0|}
validate_image.cpp:_ZN8spvtools3val12_GLOBAL__N_117ValidateImageReadERNS0_17ValidationState_tEPKNS0_11InstructionE:
 1547|      7|spv_result_t ValidateImageRead(ValidationState_t& _, const Instruction* inst) {
 1548|      7|  const spv::Op opcode = inst->opcode();
 1549|      7|  uint32_t actual_result_type = 0;
 1550|      7|  if (spv_result_t error = GetActualResultType(_, inst, &actual_result_type)) {
  ------------------
  |  Branch (1550:20): [True: 0, False: 7]
  ------------------
 1551|      0|    return error;
 1552|      0|  }
 1553|       |
 1554|      7|  if (!_.IsIntScalarOrVectorType(actual_result_type) &&
  ------------------
  |  Branch (1554:7): [True: 3, False: 4]
  ------------------
 1555|      7|      !_.IsFloatScalarOrVectorType(actual_result_type)) {
  ------------------
  |  Branch (1555:7): [True: 0, False: 3]
  ------------------
 1556|      0|    return _.diag(SPV_ERROR_INVALID_DATA, inst)
 1557|      0|           << "Expected " << GetActualResultTypeStr(opcode)
 1558|      0|           << " to be int or float scalar or vector type";
 1559|      0|  }
 1560|       |
 1561|      7|  const auto target_env = _.context()->target_env;
 1562|       |  // Vulkan requires the result to be a 4-element int or float
 1563|       |  // vector.
 1564|      7|  if (spvIsVulkanEnv(target_env)) {
  ------------------
  |  Branch (1564:7): [True: 0, False: 7]
  ------------------
 1565|      0|    if (_.GetDimension(actual_result_type) != 4) {
  ------------------
  |  Branch (1565:9): [True: 0, False: 0]
  ------------------
 1566|      0|      return _.diag(SPV_ERROR_INVALID_DATA, inst)
 1567|      0|             << _.VkErrorID(4780) << "Expected "
 1568|      0|             << GetActualResultTypeStr(opcode) << " to have 4 components";
 1569|      0|    }
 1570|      0|  }  // Check OpenCL below, after we get the image info.
 1571|       |
 1572|      7|  const uint32_t image_type = _.GetOperandTypeId(inst, 2);
 1573|      7|  if (_.GetIdOpcode(image_type) != spv::Op::OpTypeImage) {
  ------------------
  |  Branch (1573:7): [True: 5, False: 2]
  ------------------
 1574|      5|    return _.diag(SPV_ERROR_INVALID_DATA, inst)
 1575|      5|           << "Expected Image to be of type OpTypeImage";
 1576|      5|  }
 1577|       |
 1578|      2|  ImageTypeInfo info;
 1579|      2|  if (!GetImageTypeInfo(_, image_type, &info)) {
  ------------------
  |  Branch (1579:7): [True: 0, False: 2]
  ------------------
 1580|      0|    return _.diag(SPV_ERROR_INVALID_DATA, inst)
 1581|      0|           << "Corrupt image type definition";
 1582|      0|  }
 1583|       |
 1584|      2|  if (spvIsOpenCLEnv(target_env)) {
  ------------------
  |  Branch (1584:7): [True: 0, False: 2]
  ------------------
 1585|       |    // In OpenCL, a read from a depth image returns a scalar float. In other
 1586|       |    // cases, the result is always a 4-element vector.
 1587|       |    // https://www.khronos.org/registry/OpenCL/specs/3.0-unified/html/OpenCL_Env.html#_data_format_for_reading_and_writing_images
 1588|       |    // https://www.khronos.org/registry/OpenCL/specs/3.0-unified/html/OpenCL_C.html#image-read-and-write-functions
 1589|       |    // The builtins for reading depth images are:
 1590|       |    //   float read_imagef(aQual image2d_depth_t image, int2 coord)
 1591|       |    //   float read_imagef(aQual image2d_array_depth_t image, int4 coord)
 1592|      0|    if (info.depth) {
  ------------------
  |  Branch (1592:9): [True: 0, False: 0]
  ------------------
 1593|      0|      if (!_.IsFloatScalarType(actual_result_type)) {
  ------------------
  |  Branch (1593:11): [True: 0, False: 0]
  ------------------
 1594|      0|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
 1595|      0|               << "Expected " << GetActualResultTypeStr(opcode)
 1596|      0|               << " from a depth image read to result in a scalar float value";
 1597|      0|      }
 1598|      0|    } else {
 1599|      0|      if (_.GetDimension(actual_result_type) != 4) {
  ------------------
  |  Branch (1599:11): [True: 0, False: 0]
  ------------------
 1600|      0|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
 1601|      0|               << "Expected " << GetActualResultTypeStr(opcode)
 1602|      0|               << " to have 4 components";
 1603|      0|      }
 1604|      0|    }
 1605|       |
 1606|      0|    const uint32_t mask = inst->words().size() <= 5 ? 0 : inst->word(5);
  ------------------
  |  Branch (1606:27): [True: 0, False: 0]
  ------------------
 1607|      0|    if (mask & uint32_t(spv::ImageOperandsMask::ConstOffset)) {
  ------------------
  |  Branch (1607:9): [True: 0, False: 0]
  ------------------
 1608|      0|      return _.diag(SPV_ERROR_INVALID_DATA, inst)
 1609|      0|             << "ConstOffset image operand not allowed "
 1610|      0|             << "in the OpenCL environment.";
 1611|      0|    }
 1612|      0|  }
 1613|       |
 1614|      2|  if (info.dim == spv::Dim::SubpassData) {
  ------------------
  |  Branch (1614:7): [True: 0, False: 2]
  ------------------
 1615|      0|    if (opcode == spv::Op::OpImageSparseRead) {
  ------------------
  |  Branch (1615:9): [True: 0, False: 0]
  ------------------
 1616|      0|      return _.diag(SPV_ERROR_INVALID_DATA, inst)
 1617|      0|             << "Image Dim SubpassData cannot be used with ImageSparseRead";
 1618|      0|    }
 1619|       |
 1620|      0|    _.function(inst->function()->id())
 1621|      0|        ->RegisterExecutionModelLimitation(
 1622|      0|            spv::ExecutionModel::Fragment,
 1623|      0|            std::string("Dim SubpassData requires Fragment execution model: ") +
 1624|      0|                spvOpcodeString(opcode));
 1625|      0|  }
 1626|       |
 1627|      2|  if (_.GetIdOpcode(info.sampled_type) != spv::Op::OpTypeVoid) {
  ------------------
  |  Branch (1627:7): [True: 2, False: 0]
  ------------------
 1628|      2|    const uint32_t result_component_type =
 1629|      2|        _.GetComponentType(actual_result_type);
 1630|      2|    if (result_component_type != info.sampled_type) {
  ------------------
  |  Branch (1630:9): [True: 0, False: 2]
  ------------------
 1631|      0|      return _.diag(SPV_ERROR_INVALID_DATA, inst)
 1632|      0|             << "Expected Image 'Sampled Type' to be the same as "
 1633|      0|             << GetActualResultTypeStr(opcode) << " components";
 1634|      0|    }
 1635|      2|  }
 1636|       |
 1637|      2|  if (spv_result_t result = ValidateImageReadWrite(_, inst, info))
  ------------------
  |  Branch (1637:20): [True: 0, False: 2]
  ------------------
 1638|      0|    return result;
 1639|       |
 1640|      2|  const uint32_t coord_type = _.GetOperandTypeId(inst, 3);
 1641|      2|  if (!_.IsIntScalarOrVectorType(coord_type)) {
  ------------------
  |  Branch (1641:7): [True: 2, False: 0]
  ------------------
 1642|      2|    return _.diag(SPV_ERROR_INVALID_DATA, inst)
 1643|      2|           << "Expected Coordinate to be int scalar or vector";
 1644|      2|  }
 1645|       |
 1646|      0|  const uint32_t min_coord_size = GetMinCoordSize(opcode, info);
 1647|      0|  const uint32_t actual_coord_size = _.GetDimension(coord_type);
 1648|      0|  if (min_coord_size > actual_coord_size) {
  ------------------
  |  Branch (1648:7): [True: 0, False: 0]
  ------------------
 1649|      0|    return _.diag(SPV_ERROR_INVALID_DATA, inst)
 1650|      0|           << "Expected Coordinate to have at least " << min_coord_size
 1651|      0|           << " components, but given only " << actual_coord_size;
 1652|      0|  }
 1653|       |
 1654|      0|  if (spvIsVulkanEnv(_.context()->target_env)) {
  ------------------
  |  Branch (1654:7): [True: 0, False: 0]
  ------------------
 1655|      0|    if (info.format == spv::ImageFormat::Unknown &&
  ------------------
  |  Branch (1655:9): [True: 0, False: 0]
  ------------------
 1656|      0|        info.dim != spv::Dim::SubpassData &&
  ------------------
  |  Branch (1656:9): [True: 0, False: 0]
  ------------------
 1657|      0|        !_.HasCapability(spv::Capability::StorageImageReadWithoutFormat)) {
  ------------------
  |  Branch (1657:9): [True: 0, False: 0]
  ------------------
 1658|      0|      return _.diag(SPV_ERROR_INVALID_DATA, inst)
 1659|      0|             << "Capability StorageImageReadWithoutFormat is required to "
 1660|      0|             << "read storage image";
 1661|      0|    }
 1662|      0|  }
 1663|       |
 1664|      0|  if (spv_result_t result =
  ------------------
  |  Branch (1664:20): [True: 0, False: 0]
  ------------------
 1665|      0|          ValidateImageOperands(_, inst, info, /* word_index = */ 6))
 1666|      0|    return result;
 1667|       |
 1668|      0|  return SPV_SUCCESS;
 1669|      0|}
validate_image.cpp:_ZN8spvtools3val12_GLOBAL__N_122ValidateImageReadWriteERNS0_17ValidationState_tEPKNS0_11InstructionERKNS1_13ImageTypeInfoE:
  675|      2|                                    const ImageTypeInfo& info) {
  676|      2|  if (info.sampled == 2) {
  ------------------
  |  Branch (676:7): [True: 1, False: 1]
  ------------------
  677|      1|    if (info.dim == spv::Dim::Dim1D &&
  ------------------
  |  Branch (677:9): [True: 0, False: 1]
  ------------------
  678|      1|        !_.HasCapability(spv::Capability::Image1D)) {
  ------------------
  |  Branch (678:9): [True: 0, False: 0]
  ------------------
  679|      0|      return _.diag(SPV_ERROR_INVALID_DATA, inst)
  680|      0|             << "Capability Image1D is required to access storage image";
  681|      1|    } else if (info.dim == spv::Dim::Rect &&
  ------------------
  |  Branch (681:16): [True: 0, False: 1]
  ------------------
  682|      1|               !_.HasCapability(spv::Capability::ImageRect)) {
  ------------------
  |  Branch (682:16): [True: 0, False: 0]
  ------------------
  683|      0|      return _.diag(SPV_ERROR_INVALID_DATA, inst)
  684|      0|             << "Capability ImageRect is required to access storage image";
  685|      1|    } else if (info.dim == spv::Dim::Buffer &&
  ------------------
  |  Branch (685:16): [True: 0, False: 1]
  ------------------
  686|      1|               !_.HasCapability(spv::Capability::ImageBuffer)) {
  ------------------
  |  Branch (686:16): [True: 0, False: 0]
  ------------------
  687|      0|      return _.diag(SPV_ERROR_INVALID_DATA, inst)
  688|      0|             << "Capability ImageBuffer is required to access storage image";
  689|      1|    } else if (info.dim == spv::Dim::Cube && info.arrayed == 1 &&
  ------------------
  |  Branch (689:16): [True: 0, False: 1]
  |  Branch (689:46): [True: 0, False: 0]
  ------------------
  690|      1|               !_.HasCapability(spv::Capability::ImageCubeArray)) {
  ------------------
  |  Branch (690:16): [True: 0, False: 0]
  ------------------
  691|      0|      return _.diag(SPV_ERROR_INVALID_DATA, inst)
  692|      0|             << "Capability ImageCubeArray is required to access "
  693|      0|             << "storage image";
  694|      0|    }
  695|       |
  696|      1|    if (info.multisampled == 1 &&
  ------------------
  |  Branch (696:9): [True: 0, False: 1]
  ------------------
  697|      1|        !_.HasCapability(spv::Capability::ImageMSArray)) {
  ------------------
  |  Branch (697:9): [True: 0, False: 0]
  ------------------
  698|       |#if 0
  699|       |      // TODO(atgoo@github.com) The description of this rule in the spec
  700|       |      // is unclear and Glslang doesn't declare ImageMSArray. Need to clarify
  701|       |      // and reenable.
  702|       |      return _.diag(SPV_ERROR_INVALID_DATA, inst)
  703|       |          << "Capability ImageMSArray is required to access storage "
  704|       |          << "image";
  705|       |#endif
  706|      0|    }
  707|      1|  } else if (info.sampled != 0) {
  ------------------
  |  Branch (707:14): [True: 0, False: 1]
  ------------------
  708|      0|    return _.diag(SPV_ERROR_INVALID_DATA, inst)
  709|      0|           << "Expected Image 'Sampled' parameter to be 0 or 2";
  710|      0|  }
  711|       |
  712|      2|  return SPV_SUCCESS;
  713|      2|}
validate_image.cpp:_ZN8spvtools3val12_GLOBAL__N_118ValidateImageWriteERNS0_17ValidationState_tEPKNS0_11InstructionE:
 1671|      1|spv_result_t ValidateImageWrite(ValidationState_t& _, const Instruction* inst) {
 1672|      1|  const uint32_t image_type = _.GetOperandTypeId(inst, 0);
 1673|      1|  if (_.GetIdOpcode(image_type) != spv::Op::OpTypeImage) {
  ------------------
  |  Branch (1673:7): [True: 1, False: 0]
  ------------------
 1674|      1|    return _.diag(SPV_ERROR_INVALID_DATA, inst)
 1675|      1|           << "Expected Image to be of type OpTypeImage";
 1676|      1|  }
 1677|       |
 1678|      0|  ImageTypeInfo info;
 1679|      0|  if (!GetImageTypeInfo(_, image_type, &info)) {
  ------------------
  |  Branch (1679:7): [True: 0, False: 0]
  ------------------
 1680|      0|    return _.diag(SPV_ERROR_INVALID_DATA, inst)
 1681|      0|           << "Corrupt image type definition";
 1682|      0|  }
 1683|       |
 1684|      0|  if (info.dim == spv::Dim::SubpassData) {
  ------------------
  |  Branch (1684:7): [True: 0, False: 0]
  ------------------
 1685|      0|    return _.diag(SPV_ERROR_INVALID_DATA, inst)
 1686|      0|           << "Image 'Dim' cannot be SubpassData";
 1687|      0|  }
 1688|       |
 1689|      0|  if (spv_result_t result = ValidateImageReadWrite(_, inst, info))
  ------------------
  |  Branch (1689:20): [True: 0, False: 0]
  ------------------
 1690|      0|    return result;
 1691|       |
 1692|      0|  const uint32_t coord_type = _.GetOperandTypeId(inst, 1);
 1693|      0|  if (!_.IsIntScalarOrVectorType(coord_type)) {
  ------------------
  |  Branch (1693:7): [True: 0, False: 0]
  ------------------
 1694|      0|    return _.diag(SPV_ERROR_INVALID_DATA, inst)
 1695|      0|           << "Expected Coordinate to be int scalar or vector";
 1696|      0|  }
 1697|       |
 1698|      0|  const uint32_t min_coord_size = GetMinCoordSize(inst->opcode(), info);
 1699|      0|  const uint32_t actual_coord_size = _.GetDimension(coord_type);
 1700|      0|  if (min_coord_size > actual_coord_size) {
  ------------------
  |  Branch (1700:7): [True: 0, False: 0]
  ------------------
 1701|      0|    return _.diag(SPV_ERROR_INVALID_DATA, inst)
 1702|      0|           << "Expected Coordinate to have at least " << min_coord_size
 1703|      0|           << " components, but given only " << actual_coord_size;
 1704|      0|  }
 1705|       |
 1706|       |  // because it needs to match with 'Sampled Type' the Texel can't be a boolean
 1707|      0|  const uint32_t texel_type = _.GetOperandTypeId(inst, 2);
 1708|      0|  if (!_.IsIntScalarOrVectorType(texel_type) &&
  ------------------
  |  Branch (1708:7): [True: 0, False: 0]
  ------------------
 1709|      0|      !_.IsFloatScalarOrVectorType(texel_type)) {
  ------------------
  |  Branch (1709:7): [True: 0, False: 0]
  ------------------
 1710|      0|    return _.diag(SPV_ERROR_INVALID_DATA, inst)
 1711|      0|           << "Expected Texel to be int or float vector or scalar";
 1712|      0|  }
 1713|       |
 1714|      0|  if (_.GetIdOpcode(info.sampled_type) != spv::Op::OpTypeVoid) {
  ------------------
  |  Branch (1714:7): [True: 0, False: 0]
  ------------------
 1715|      0|    const uint32_t texel_component_type = _.GetComponentType(texel_type);
 1716|      0|    if (texel_component_type != info.sampled_type) {
  ------------------
  |  Branch (1716:9): [True: 0, False: 0]
  ------------------
 1717|      0|      return _.diag(SPV_ERROR_INVALID_DATA, inst)
 1718|      0|             << "Expected Image 'Sampled Type' to be the same as Texel "
 1719|      0|             << "components";
 1720|      0|    }
 1721|      0|  }
 1722|       |
 1723|      0|  if (spvIsVulkanEnv(_.context()->target_env)) {
  ------------------
  |  Branch (1723:7): [True: 0, False: 0]
  ------------------
 1724|      0|    if (info.format == spv::ImageFormat::Unknown &&
  ------------------
  |  Branch (1724:9): [True: 0, False: 0]
  ------------------
 1725|      0|        info.dim != spv::Dim::SubpassData &&
  ------------------
  |  Branch (1725:9): [True: 0, False: 0]
  ------------------
 1726|      0|        !_.HasCapability(spv::Capability::StorageImageWriteWithoutFormat)) {
  ------------------
  |  Branch (1726:9): [True: 0, False: 0]
  ------------------
 1727|      0|      return _.diag(SPV_ERROR_INVALID_DATA, inst)
 1728|      0|             << "Capability StorageImageWriteWithoutFormat is required to "
 1729|      0|                "write "
 1730|      0|             << "to storage image";
 1731|      0|    }
 1732|      0|  }
 1733|       |
 1734|      0|  if (inst->words().size() > 4) {
  ------------------
  |  Branch (1734:7): [True: 0, False: 0]
  ------------------
 1735|      0|    if (spvIsOpenCLEnv(_.context()->target_env)) {
  ------------------
  |  Branch (1735:9): [True: 0, False: 0]
  ------------------
 1736|      0|      return _.diag(SPV_ERROR_INVALID_DATA, inst)
 1737|      0|             << "Optional Image Operands are not allowed in the OpenCL "
 1738|      0|             << "environment.";
 1739|      0|    }
 1740|      0|  }
 1741|       |
 1742|      0|  if (spv_result_t result =
  ------------------
  |  Branch (1742:20): [True: 0, False: 0]
  ------------------
 1743|      0|          ValidateImageOperands(_, inst, info, /* word_index = */ 5))
 1744|      0|    return result;
 1745|       |
 1746|      0|  return SPV_SUCCESS;
 1747|      0|}
validate_image.cpp:_ZN8spvtools3val12_GLOBAL__N_131ValidateImageQueryFormatOrOrderERNS0_17ValidationState_tEPKNS0_11InstructionE:
 1897|      1|                                             const Instruction* inst) {
 1898|      1|  if (!_.IsIntScalarType(inst->type_id())) {
  ------------------
  |  Branch (1898:7): [True: 1, False: 0]
  ------------------
 1899|      1|    return _.diag(SPV_ERROR_INVALID_DATA, inst)
 1900|      1|           << "Expected Result Type to be int scalar type";
 1901|      1|  }
 1902|       |
 1903|      0|  if (_.GetIdOpcode(_.GetOperandTypeId(inst, 2)) != spv::Op::OpTypeImage) {
  ------------------
  |  Branch (1903:7): [True: 0, False: 0]
  ------------------
 1904|      0|    return _.diag(SPV_ERROR_INVALID_DATA, inst)
 1905|      0|           << "Expected operand to be of type OpTypeImage";
 1906|      0|  }
 1907|      0|  return SPV_SUCCESS;
 1908|      0|}
validate_image.cpp:_ZN8spvtools3val12_GLOBAL__N_125ValidateImageQuerySizeLodERNS0_17ValidationState_tEPKNS0_11InstructionE:
 1774|      2|                                       const Instruction* inst) {
 1775|      2|  const uint32_t result_type = inst->type_id();
 1776|      2|  if (!_.IsIntScalarOrVectorType(result_type)) {
  ------------------
  |  Branch (1776:7): [True: 1, False: 1]
  ------------------
 1777|      1|    return _.diag(SPV_ERROR_INVALID_DATA, inst)
 1778|      1|           << "Expected Result Type to be int scalar or vector type";
 1779|      1|  }
 1780|       |
 1781|      1|  const uint32_t image_type = _.GetOperandTypeId(inst, 2);
 1782|      1|  if (_.GetIdOpcode(image_type) != spv::Op::OpTypeImage) {
  ------------------
  |  Branch (1782:7): [True: 1, False: 0]
  ------------------
 1783|      1|    return _.diag(SPV_ERROR_INVALID_DATA, inst)
 1784|      1|           << "Expected Image to be of type OpTypeImage";
 1785|      1|  }
 1786|       |
 1787|      0|  ImageTypeInfo info;
 1788|      0|  if (!GetImageTypeInfo(_, image_type, &info)) {
  ------------------
  |  Branch (1788:7): [True: 0, False: 0]
  ------------------
 1789|      0|    return _.diag(SPV_ERROR_INVALID_DATA, inst)
 1790|      0|           << "Corrupt image type definition";
 1791|      0|  }
 1792|       |
 1793|      0|  uint32_t expected_num_components = info.arrayed;
 1794|      0|  switch (info.dim) {
 1795|      0|    case spv::Dim::Dim1D:
  ------------------
  |  Branch (1795:5): [True: 0, False: 0]
  ------------------
 1796|      0|      expected_num_components += 1;
 1797|      0|      break;
 1798|      0|    case spv::Dim::Dim2D:
  ------------------
  |  Branch (1798:5): [True: 0, False: 0]
  ------------------
 1799|      0|    case spv::Dim::Cube:
  ------------------
  |  Branch (1799:5): [True: 0, False: 0]
  ------------------
 1800|      0|      expected_num_components += 2;
 1801|      0|      break;
 1802|      0|    case spv::Dim::Dim3D:
  ------------------
  |  Branch (1802:5): [True: 0, False: 0]
  ------------------
 1803|      0|      expected_num_components += 3;
 1804|      0|      break;
 1805|      0|    default:
  ------------------
  |  Branch (1805:5): [True: 0, False: 0]
  ------------------
 1806|      0|      return _.diag(SPV_ERROR_INVALID_DATA, inst)
 1807|      0|             << "Image 'Dim' must be 1D, 2D, 3D or Cube";
 1808|      0|  }
 1809|       |
 1810|      0|  if (info.multisampled != 0) {
  ------------------
  |  Branch (1810:7): [True: 0, False: 0]
  ------------------
 1811|      0|    return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Image 'MS' must be 0";
 1812|      0|  }
 1813|       |
 1814|      0|  const auto target_env = _.context()->target_env;
 1815|      0|  if (spvIsVulkanEnv(target_env)) {
  ------------------
  |  Branch (1815:7): [True: 0, False: 0]
  ------------------
 1816|      0|    if (info.sampled != 1) {
  ------------------
  |  Branch (1816:9): [True: 0, False: 0]
  ------------------
 1817|      0|      return _.diag(SPV_ERROR_INVALID_DATA, inst)
 1818|      0|             << _.VkErrorID(4659)
 1819|      0|             << "OpImageQuerySizeLod must only consume an \"Image\" operand "
 1820|      0|                "whose type has its \"Sampled\" operand set to 1";
 1821|      0|    }
 1822|      0|  }
 1823|       |
 1824|      0|  uint32_t result_num_components = _.GetDimension(result_type);
 1825|      0|  if (result_num_components != expected_num_components) {
  ------------------
  |  Branch (1825:7): [True: 0, False: 0]
  ------------------
 1826|      0|    return _.diag(SPV_ERROR_INVALID_DATA, inst)
 1827|      0|           << "Result Type has " << result_num_components << " components, "
 1828|      0|           << "but " << expected_num_components << " expected";
 1829|      0|  }
 1830|       |
 1831|      0|  const uint32_t lod_type = _.GetOperandTypeId(inst, 3);
 1832|      0|  if (!_.IsIntScalarType(lod_type)) {
  ------------------
  |  Branch (1832:7): [True: 0, False: 0]
  ------------------
 1833|      0|    return _.diag(SPV_ERROR_INVALID_DATA, inst)
 1834|      0|           << "Expected Level of Detail to be int scalar";
 1835|      0|  }
 1836|      0|  return SPV_SUCCESS;
 1837|      0|}
validate_image.cpp:_ZN8spvtools3val12_GLOBAL__N_122ValidateImageQuerySizeERNS0_17ValidationState_tEPKNS0_11InstructionE:
 1840|      4|                                    const Instruction* inst) {
 1841|      4|  const uint32_t result_type = inst->type_id();
 1842|      4|  if (!_.IsIntScalarOrVectorType(result_type)) {
  ------------------
  |  Branch (1842:7): [True: 4, False: 0]
  ------------------
 1843|      4|    return _.diag(SPV_ERROR_INVALID_DATA, inst)
 1844|      4|           << "Expected Result Type to be int scalar or vector type";
 1845|      4|  }
 1846|       |
 1847|      0|  const uint32_t image_type = _.GetOperandTypeId(inst, 2);
 1848|      0|  if (_.GetIdOpcode(image_type) != spv::Op::OpTypeImage) {
  ------------------
  |  Branch (1848:7): [True: 0, False: 0]
  ------------------
 1849|      0|    return _.diag(SPV_ERROR_INVALID_DATA, inst)
 1850|      0|           << "Expected Image to be of type OpTypeImage";
 1851|      0|  }
 1852|       |
 1853|      0|  ImageTypeInfo info;
 1854|      0|  if (!GetImageTypeInfo(_, image_type, &info)) {
  ------------------
  |  Branch (1854:7): [True: 0, False: 0]
  ------------------
 1855|      0|    return _.diag(SPV_ERROR_INVALID_DATA, inst)
 1856|      0|           << "Corrupt image type definition";
 1857|      0|  }
 1858|       |
 1859|      0|  uint32_t expected_num_components = info.arrayed;
 1860|      0|  switch (info.dim) {
 1861|      0|    case spv::Dim::Dim1D:
  ------------------
  |  Branch (1861:5): [True: 0, False: 0]
  ------------------
 1862|      0|    case spv::Dim::Buffer:
  ------------------
  |  Branch (1862:5): [True: 0, False: 0]
  ------------------
 1863|      0|      expected_num_components += 1;
 1864|      0|      break;
 1865|      0|    case spv::Dim::Dim2D:
  ------------------
  |  Branch (1865:5): [True: 0, False: 0]
  ------------------
 1866|      0|    case spv::Dim::Cube:
  ------------------
  |  Branch (1866:5): [True: 0, False: 0]
  ------------------
 1867|      0|    case spv::Dim::Rect:
  ------------------
  |  Branch (1867:5): [True: 0, False: 0]
  ------------------
 1868|      0|      expected_num_components += 2;
 1869|      0|      break;
 1870|      0|    case spv::Dim::Dim3D:
  ------------------
  |  Branch (1870:5): [True: 0, False: 0]
  ------------------
 1871|      0|      expected_num_components += 3;
 1872|      0|      break;
 1873|      0|    default:
  ------------------
  |  Branch (1873:5): [True: 0, False: 0]
  ------------------
 1874|      0|      return _.diag(SPV_ERROR_INVALID_DATA, inst)
 1875|      0|             << "Image 'Dim' must be 1D, Buffer, 2D, Cube, 3D or Rect";
 1876|      0|  }
 1877|       |
 1878|      0|  if (info.dim == spv::Dim::Dim1D || info.dim == spv::Dim::Dim2D ||
  ------------------
  |  Branch (1878:7): [True: 0, False: 0]
  |  Branch (1878:38): [True: 0, False: 0]
  ------------------
 1879|      0|      info.dim == spv::Dim::Dim3D || info.dim == spv::Dim::Cube) {
  ------------------
  |  Branch (1879:7): [True: 0, False: 0]
  |  Branch (1879:38): [True: 0, False: 0]
  ------------------
 1880|      0|    if (info.multisampled != 1 && info.sampled != 0 && info.sampled != 2) {
  ------------------
  |  Branch (1880:9): [True: 0, False: 0]
  |  Branch (1880:35): [True: 0, False: 0]
  |  Branch (1880:56): [True: 0, False: 0]
  ------------------
 1881|      0|      return _.diag(SPV_ERROR_INVALID_DATA, inst)
 1882|      0|             << "Image must have either 'MS'=1 or 'Sampled'=0 or 'Sampled'=2";
 1883|      0|    }
 1884|      0|  }
 1885|       |
 1886|      0|  uint32_t result_num_components = _.GetDimension(result_type);
 1887|      0|  if (result_num_components != expected_num_components) {
  ------------------
  |  Branch (1887:7): [True: 0, False: 0]
  ------------------
 1888|      0|    return _.diag(SPV_ERROR_INVALID_DATA, inst)
 1889|      0|           << "Result Type has " << result_num_components << " components, "
 1890|      0|           << "but " << expected_num_components << " expected";
 1891|      0|  }
 1892|       |
 1893|      0|  return SPV_SUCCESS;
 1894|      0|}
validate_image.cpp:_ZN8spvtools3val12_GLOBAL__N_133ValidateImageQueryLevelsOrSamplesERNS0_17ValidationState_tEPKNS0_11InstructionE:
 2016|      3|                                               const Instruction* inst) {
 2017|      3|  if (!_.IsIntScalarType(inst->type_id())) {
  ------------------
  |  Branch (2017:7): [True: 0, False: 3]
  ------------------
 2018|      0|    return _.diag(SPV_ERROR_INVALID_DATA, inst)
 2019|      0|           << "Expected Result Type to be int scalar type";
 2020|      0|  }
 2021|       |
 2022|      3|  const uint32_t image_type = _.GetOperandTypeId(inst, 2);
 2023|      3|  if (_.GetIdOpcode(image_type) != spv::Op::OpTypeImage) {
  ------------------
  |  Branch (2023:7): [True: 0, False: 3]
  ------------------
 2024|      0|    return _.diag(SPV_ERROR_INVALID_DATA, inst)
 2025|      0|           << "Expected Image to be of type OpTypeImage";
 2026|      0|  }
 2027|       |
 2028|      3|  ImageTypeInfo info;
 2029|      3|  if (!GetImageTypeInfo(_, image_type, &info)) {
  ------------------
  |  Branch (2029:7): [True: 0, False: 3]
  ------------------
 2030|      0|    return _.diag(SPV_ERROR_INVALID_DATA, inst)
 2031|      0|           << "Corrupt image type definition";
 2032|      0|  }
 2033|       |
 2034|      3|  const spv::Op opcode = inst->opcode();
 2035|      3|  if (opcode == spv::Op::OpImageQueryLevels) {
  ------------------
  |  Branch (2035:7): [True: 0, False: 3]
  ------------------
 2036|      0|    if (info.dim != spv::Dim::Dim1D && info.dim != spv::Dim::Dim2D &&
  ------------------
  |  Branch (2036:9): [True: 0, False: 0]
  |  Branch (2036:40): [True: 0, False: 0]
  ------------------
 2037|      0|        info.dim != spv::Dim::Dim3D && info.dim != spv::Dim::Cube) {
  ------------------
  |  Branch (2037:9): [True: 0, False: 0]
  |  Branch (2037:40): [True: 0, False: 0]
  ------------------
 2038|      0|      return _.diag(SPV_ERROR_INVALID_DATA, inst)
 2039|      0|             << "Image 'Dim' must be 1D, 2D, 3D or Cube";
 2040|      0|    }
 2041|      0|    const auto target_env = _.context()->target_env;
 2042|      0|    if (spvIsVulkanEnv(target_env)) {
  ------------------
  |  Branch (2042:9): [True: 0, False: 0]
  ------------------
 2043|      0|      if (info.sampled != 1) {
  ------------------
  |  Branch (2043:11): [True: 0, False: 0]
  ------------------
 2044|      0|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
 2045|      0|               << _.VkErrorID(4659)
 2046|      0|               << "OpImageQueryLevels must only consume an \"Image\" operand "
 2047|      0|                  "whose type has its \"Sampled\" operand set to 1";
 2048|      0|      }
 2049|      0|    }
 2050|      3|  } else {
 2051|      3|    assert(opcode == spv::Op::OpImageQuerySamples);
 2052|      3|    if (info.dim != spv::Dim::Dim2D) {
  ------------------
  |  Branch (2052:9): [True: 1, False: 2]
  ------------------
 2053|      1|      return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Image 'Dim' must be 2D";
 2054|      1|    }
 2055|       |
 2056|      2|    if (info.multisampled != 1) {
  ------------------
  |  Branch (2056:9): [True: 1, False: 1]
  ------------------
 2057|      1|      return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Image 'MS' must be 1";
 2058|      1|    }
 2059|      2|  }
 2060|      1|  return SPV_SUCCESS;
 2061|      3|}
validate_image.cpp:_ZZN8spvtools3val9ImagePassERNS0_17ValidationState_tEPKNS0_11InstructionEENK3$_0clEN3spv14ExecutionModelEPNSt3__112basic_stringIcNS9_11char_traitsIcEENS9_9allocatorIcEEEE:
 2087|     29|                                                    std::string* message) {
 2088|     29|          if (model != spv::ExecutionModel::Fragment &&
  ------------------
  |  Branch (2088:15): [True: 3, False: 26]
  ------------------
 2089|     29|              model != spv::ExecutionModel::GLCompute) {
  ------------------
  |  Branch (2089:15): [True: 1, False: 2]
  ------------------
 2090|      1|            if (message) {
  ------------------
  |  Branch (2090:17): [True: 1, False: 0]
  ------------------
 2091|      1|              *message =
 2092|      1|                  std::string(
 2093|      1|                      "ImplicitLod instructions require Fragment or GLCompute "
 2094|      1|                      "execution model: ") +
 2095|      1|                  spvOpcodeString(opcode);
 2096|      1|            }
 2097|      1|            return false;
 2098|      1|          }
 2099|     28|          return true;
 2100|     29|        });
validate_image.cpp:_ZZN8spvtools3val9ImagePassERNS0_17ValidationState_tEPKNS0_11InstructionEENK3$_1clERKS1_PKNS0_8FunctionEPNSt3__112basic_stringIcNSC_11char_traitsIcEENSC_9allocatorIcEEEE:
 2104|     28|                                      std::string* message) {
 2105|     28|          const auto* models = state.GetExecutionModels(entry_point->id());
 2106|     28|          const auto* modes = state.GetExecutionModes(entry_point->id());
 2107|     28|          if (models &&
  ------------------
  |  Branch (2107:15): [True: 28, False: 0]
  |  Branch (2107:15): [True: 2, False: 26]
  ------------------
 2108|     28|              models->find(spv::ExecutionModel::GLCompute) != models->end() &&
  ------------------
  |  Branch (2108:15): [True: 2, False: 26]
  ------------------
 2109|     28|              (!modes ||
  ------------------
  |  Branch (2109:16): [True: 2, False: 0]
  ------------------
 2110|      2|               (modes->find(spv::ExecutionMode::DerivativeGroupLinearNV) ==
  ------------------
  |  Branch (2110:17): [True: 0, False: 0]
  ------------------
 2111|      0|                    modes->end() &&
 2112|      0|                modes->find(spv::ExecutionMode::DerivativeGroupQuadsNV) ==
  ------------------
  |  Branch (2112:17): [True: 0, False: 0]
  ------------------
 2113|      2|                    modes->end()))) {
 2114|      2|            if (message) {
  ------------------
  |  Branch (2114:17): [True: 2, False: 0]
  ------------------
 2115|      2|              *message =
 2116|      2|                  std::string(
 2117|      2|                      "ImplicitLod instructions require DerivativeGroupQuadsNV "
 2118|      2|                      "or DerivativeGroupLinearNV execution mode for GLCompute "
 2119|      2|                      "execution model: ") +
 2120|      2|                  spvOpcodeString(opcode);
 2121|      2|            }
 2122|      2|            return false;
 2123|      2|          }
 2124|     26|          return true;
 2125|     28|        });

_ZN8spvtools3val15InstructionPassERNS0_17ValidationState_tEPKNS0_11InstructionE:
  465|   387k|spv_result_t InstructionPass(ValidationState_t& _, const Instruction* inst) {
  466|   387k|  const spv::Op opcode = inst->opcode();
  467|   387k|  if (opcode == spv::Op::OpExtension) {
  ------------------
  |  Branch (467:7): [True: 2.37k, False: 385k]
  ------------------
  468|  2.37k|    CheckIfKnownExtension(_, inst);
  469|   385k|  } else if (opcode == spv::Op::OpCapability) {
  ------------------
  |  Branch (469:14): [True: 7.02k, False: 378k]
  ------------------
  470|  7.02k|    _.RegisterCapability(inst->GetOperandAs<spv::Capability>(0));
  471|   378k|  } else if (opcode == spv::Op::OpMemoryModel) {
  ------------------
  |  Branch (471:14): [True: 5.43k, False: 372k]
  ------------------
  472|  5.43k|    if (_.has_memory_model_specified()) {
  ------------------
  |  Branch (472:9): [True: 2, False: 5.43k]
  ------------------
  473|      2|      return _.diag(SPV_ERROR_INVALID_LAYOUT, inst)
  474|      2|             << "OpMemoryModel should only be provided once.";
  475|      2|    }
  476|  5.43k|    _.set_addressing_model(inst->GetOperandAs<spv::AddressingModel>(0));
  477|  5.43k|    _.set_memory_model(inst->GetOperandAs<spv::MemoryModel>(1));
  478|   372k|  } else if (opcode == spv::Op::OpExecutionMode) {
  ------------------
  |  Branch (478:14): [True: 4.17k, False: 368k]
  ------------------
  479|  4.17k|    const uint32_t entry_point = inst->word(1);
  480|  4.17k|    _.RegisterExecutionModeForEntryPoint(entry_point,
  481|  4.17k|                                         spv::ExecutionMode(inst->word(2)));
  482|   368k|  } else if (opcode == spv::Op::OpVariable) {
  ------------------
  |  Branch (482:14): [True: 8.71k, False: 360k]
  ------------------
  483|  8.71k|    const auto storage_class = inst->GetOperandAs<spv::StorageClass>(2);
  484|  8.71k|    if (auto error = LimitCheckNumVars(_, inst->id(), storage_class)) {
  ------------------
  |  Branch (484:14): [True: 0, False: 8.71k]
  ------------------
  485|      0|      return error;
  486|      0|    }
  487|   360k|  } else if (opcode == spv::Op::OpSamplerImageAddressingModeNV) {
  ------------------
  |  Branch (487:14): [True: 1, False: 360k]
  ------------------
  488|      1|    if (!_.HasCapability(spv::Capability::BindlessTextureNV)) {
  ------------------
  |  Branch (488:9): [True: 1, False: 0]
  ------------------
  489|      1|      return _.diag(SPV_ERROR_MISSING_EXTENSION, inst)
  490|      1|             << "OpSamplerImageAddressingModeNV supported only with extension "
  491|      1|                "SPV_NV_bindless_texture";
  492|      1|    }
  493|      0|    uint32_t bitwidth = inst->GetOperandAs<uint32_t>(0);
  494|      0|    if (_.samplerimage_variable_address_mode() != 0) {
  ------------------
  |  Branch (494:9): [True: 0, False: 0]
  ------------------
  495|      0|      return _.diag(SPV_ERROR_INVALID_LAYOUT, inst)
  496|      0|             << "OpSamplerImageAddressingModeNV should only be provided once";
  497|      0|    }
  498|      0|    if (bitwidth != 32 && bitwidth != 64) {
  ------------------
  |  Branch (498:9): [True: 0, False: 0]
  |  Branch (498:27): [True: 0, False: 0]
  ------------------
  499|      0|      return _.diag(SPV_ERROR_INVALID_DATA, inst)
  500|      0|             << "OpSamplerImageAddressingModeNV bitwidth should be 64 or 32";
  501|      0|    }
  502|      0|    _.set_samplerimage_variable_address_mode(bitwidth);
  503|      0|  }
  504|       |
  505|   387k|  if (auto error = ReservedCheck(_, inst)) return error;
  ------------------
  |  Branch (505:12): [True: 0, False: 387k]
  ------------------
  506|   387k|  if (auto error = CapabilityCheck(_, inst)) return error;
  ------------------
  |  Branch (506:12): [True: 148, False: 387k]
  ------------------
  507|   387k|  if (auto error = LimitCheckIdBound(_, inst)) return error;
  ------------------
  |  Branch (507:12): [True: 245, False: 387k]
  ------------------
  508|   387k|  if (auto error = LimitCheckStruct(_, inst)) return error;
  ------------------
  |  Branch (508:12): [True: 0, False: 387k]
  ------------------
  509|   387k|  if (auto error = LimitCheckSwitch(_, inst)) return error;
  ------------------
  |  Branch (509:12): [True: 0, False: 387k]
  ------------------
  510|   387k|  if (auto error = VersionCheck(_, inst)) return error;
  ------------------
  |  Branch (510:12): [True: 2, False: 387k]
  ------------------
  511|       |
  512|       |  // All instruction checks have passed.
  513|   387k|  return SPV_SUCCESS;
  514|   387k|}
validate_instruction.cpp:_ZN8spvtools3val12_GLOBAL__N_121CheckIfKnownExtensionERNS0_17ValidationState_tEPKNS0_11InstructionE:
  453|  2.37k|                                   const Instruction* inst) {
  454|  2.37k|  const std::string extension_str = GetExtensionString(&(inst->c_inst()));
  455|  2.37k|  Extension extension;
  456|  2.37k|  if (!GetExtensionFromString(extension_str.c_str(), &extension)) {
  ------------------
  |  Branch (456:7): [True: 1.77k, False: 596]
  ------------------
  457|  1.77k|    return _.diag(SPV_WARNING, inst)
  458|  1.77k|           << "Found unrecognized extension " << extension_str;
  459|  1.77k|  }
  460|    596|  return SPV_SUCCESS;
  461|  2.37k|}
validate_instruction.cpp:_ZN8spvtools3val12_GLOBAL__N_117LimitCheckNumVarsERNS0_17ValidationState_tEjN3spv12StorageClassE:
  426|  8.71k|                               const spv::StorageClass storage_class) {
  427|  8.71k|  if (spv::StorageClass::Function == storage_class) {
  ------------------
  |  Branch (427:7): [True: 5.77k, False: 2.94k]
  ------------------
  428|  5.77k|    _.registerLocalVariable(var_id);
  429|  5.77k|    const uint32_t num_local_vars_limit =
  430|  5.77k|        _.options()->universal_limits_.max_local_variables;
  431|  5.77k|    if (_.num_local_vars() > num_local_vars_limit) {
  ------------------
  |  Branch (431:9): [True: 0, False: 5.77k]
  ------------------
  432|      0|      return _.diag(SPV_ERROR_INVALID_BINARY, nullptr)
  433|      0|             << "Number of local variables ('Function' Storage Class) "
  434|      0|                "exceeded the valid limit ("
  435|      0|             << num_local_vars_limit << ").";
  436|      0|    }
  437|  5.77k|  } else {
  438|  2.94k|    _.registerGlobalVariable(var_id);
  439|  2.94k|    const uint32_t num_global_vars_limit =
  440|  2.94k|        _.options()->universal_limits_.max_global_variables;
  441|  2.94k|    if (_.num_global_vars() > num_global_vars_limit) {
  ------------------
  |  Branch (441:9): [True: 0, False: 2.94k]
  ------------------
  442|      0|      return _.diag(SPV_ERROR_INVALID_BINARY, nullptr)
  443|      0|             << "Number of Global Variables (Storage Class other than "
  444|      0|                "'Function') exceeded the valid limit ("
  445|      0|             << num_global_vars_limit << ").";
  446|      0|    }
  447|  2.94k|  }
  448|  8.71k|  return SPV_SUCCESS;
  449|  8.71k|}
validate_instruction.cpp:_ZN8spvtools3val12_GLOBAL__N_113ReservedCheckERNS0_17ValidationState_tEPKNS0_11InstructionE:
  221|   387k|spv_result_t ReservedCheck(ValidationState_t& _, const Instruction* inst) {
  222|   387k|  const spv::Op opcode = inst->opcode();
  223|   387k|  switch (opcode) {
  224|       |    // These instructions are enabled by a capability, but should never
  225|       |    // be used anyway.
  226|      0|    case spv::Op::OpImageSparseSampleProjImplicitLod:
  ------------------
  |  Branch (226:5): [True: 0, False: 387k]
  ------------------
  227|      0|    case spv::Op::OpImageSparseSampleProjExplicitLod:
  ------------------
  |  Branch (227:5): [True: 0, False: 387k]
  ------------------
  228|      0|    case spv::Op::OpImageSparseSampleProjDrefImplicitLod:
  ------------------
  |  Branch (228:5): [True: 0, False: 387k]
  ------------------
  229|      0|    case spv::Op::OpImageSparseSampleProjDrefExplicitLod: {
  ------------------
  |  Branch (229:5): [True: 0, False: 387k]
  ------------------
  230|      0|      spv_opcode_desc inst_desc;
  231|      0|      _.grammar().lookupOpcode(opcode, &inst_desc);
  232|      0|      return _.diag(SPV_ERROR_INVALID_BINARY, inst)
  233|      0|             << "Invalid Opcode name 'Op" << inst_desc->name << "'";
  234|      0|    }
  235|   387k|    default:
  ------------------
  |  Branch (235:5): [True: 387k, False: 0]
  ------------------
  236|   387k|      break;
  237|   387k|  }
  238|   387k|  return SPV_SUCCESS;
  239|   387k|}
validate_instruction.cpp:_ZN8spvtools3val12_GLOBAL__N_115CapabilityCheckERNS0_17ValidationState_tEPKNS0_11InstructionE:
  244|   387k|spv_result_t CapabilityCheck(ValidationState_t& _, const Instruction* inst) {
  245|   387k|  const spv::Op opcode = inst->opcode();
  246|   387k|  CapabilitySet opcode_caps = EnablingCapabilitiesForOp(_, opcode);
  247|   387k|  if (!_.HasAnyOfCapabilities(opcode_caps)) {
  ------------------
  |  Branch (247:7): [True: 13, False: 387k]
  ------------------
  248|     13|    return _.diag(SPV_ERROR_INVALID_CAPABILITY, inst)
  249|     13|           << "Opcode " << spvOpcodeString(opcode)
  250|     13|           << " requires one of these capabilities: "
  251|     13|           << ToString(opcode_caps, _.grammar());
  252|     13|  }
  253|  1.34M|  for (size_t i = 0; i < inst->operands().size(); ++i) {
  ------------------
  |  Branch (253:22): [True: 960k, False: 387k]
  ------------------
  254|   960k|    const auto& operand = inst->operand(i);
  255|   960k|    const auto word = inst->word(operand.offset);
  256|   960k|    if (spvOperandIsConcreteMask(operand.type)) {
  ------------------
  |  Branch (256:9): [True: 37.1k, False: 923k]
  ------------------
  257|       |      // Check for required capabilities for each bit position of the mask.
  258|  1.22M|      for (uint32_t mask_bit = 0x80000000; mask_bit; mask_bit >>= 1) {
  ------------------
  |  Branch (258:44): [True: 1.18M, False: 37.1k]
  ------------------
  259|  1.18M|        if (word & mask_bit) {
  ------------------
  |  Branch (259:13): [True: 7.73k, False: 1.18M]
  ------------------
  260|  7.73k|          spv_result_t status =
  261|  7.73k|              CheckRequiredCapabilities(_, inst, i + 1, operand, mask_bit);
  262|  7.73k|          if (status != SPV_SUCCESS) return status;
  ------------------
  |  Branch (262:15): [True: 38, False: 7.69k]
  ------------------
  263|  7.73k|        }
  264|  1.18M|      }
  265|   923k|    } else if (spvIsIdType(operand.type)) {
  ------------------
  |  Branch (265:16): [True: 783k, False: 139k]
  ------------------
  266|       |      // TODO(dneto): Check the value referenced by this Id, if we can compute
  267|       |      // it.  For now, just punt, to fix issue 248:
  268|       |      // https://github.com/KhronosGroup/SPIRV-Tools/issues/248
  269|   783k|    } else {
  270|       |      // Check the operand word as a whole.
  271|   139k|      spv_result_t status =
  272|   139k|          CheckRequiredCapabilities(_, inst, i + 1, operand, word);
  273|   139k|      if (status != SPV_SUCCESS) return status;
  ------------------
  |  Branch (273:11): [True: 97, False: 139k]
  ------------------
  274|   139k|    }
  275|   960k|  }
  276|   387k|  return SPV_SUCCESS;
  277|   387k|}
validate_instruction.cpp:_ZN8spvtools3val12_GLOBAL__N_125EnablingCapabilitiesForOpERKNS0_17ValidationState_tEN3spv2OpE:
   63|   387k|                                        spv::Op opcode) {
   64|       |  // Exceptions for SPV_AMD_shader_ballot
   65|   387k|  switch (opcode) {
   66|       |    // Normally these would require Group capability
   67|      0|    case spv::Op::OpGroupIAddNonUniformAMD:
  ------------------
  |  Branch (67:5): [True: 0, False: 387k]
  ------------------
   68|      0|    case spv::Op::OpGroupFAddNonUniformAMD:
  ------------------
  |  Branch (68:5): [True: 0, False: 387k]
  ------------------
   69|      0|    case spv::Op::OpGroupFMinNonUniformAMD:
  ------------------
  |  Branch (69:5): [True: 0, False: 387k]
  ------------------
   70|      0|    case spv::Op::OpGroupUMinNonUniformAMD:
  ------------------
  |  Branch (70:5): [True: 0, False: 387k]
  ------------------
   71|      0|    case spv::Op::OpGroupSMinNonUniformAMD:
  ------------------
  |  Branch (71:5): [True: 0, False: 387k]
  ------------------
   72|      0|    case spv::Op::OpGroupFMaxNonUniformAMD:
  ------------------
  |  Branch (72:5): [True: 0, False: 387k]
  ------------------
   73|      0|    case spv::Op::OpGroupUMaxNonUniformAMD:
  ------------------
  |  Branch (73:5): [True: 0, False: 387k]
  ------------------
   74|      0|    case spv::Op::OpGroupSMaxNonUniformAMD:
  ------------------
  |  Branch (74:5): [True: 0, False: 387k]
  ------------------
   75|      0|      if (state.HasExtension(kSPV_AMD_shader_ballot)) return CapabilitySet();
  ------------------
  |  Branch (75:11): [True: 0, False: 0]
  ------------------
   76|      0|      break;
   77|   387k|    default:
  ------------------
  |  Branch (77:5): [True: 387k, False: 0]
  ------------------
   78|   387k|      break;
   79|   387k|  }
   80|       |  // Look it up in the grammar
   81|   387k|  spv_opcode_desc opcode_desc = {};
   82|   387k|  if (SPV_SUCCESS == state.grammar().lookupOpcode(opcode, &opcode_desc)) {
  ------------------
  |  Branch (82:7): [True: 387k, False: 0]
  ------------------
   83|   387k|    return state.grammar().filterCapsAgainstTargetEnv(
   84|   387k|        opcode_desc->capabilities, opcode_desc->numCapabilities);
   85|   387k|  }
   86|      0|  return CapabilitySet();
   87|   387k|}
validate_instruction.cpp:_ZN8spvtools3val12_GLOBAL__N_18ToStringERKNS_7EnumSetIN3spv10CapabilityEEERKNS_15AssemblyGrammarE:
   45|     96|                     const AssemblyGrammar& grammar) {
   46|     96|  std::stringstream ss;
   47|     96|  capabilities.ForEach([&grammar, &ss](spv::Capability cap) {
   48|     96|    spv_operand_desc desc;
   49|     96|    if (SPV_SUCCESS == grammar.lookupOperand(SPV_OPERAND_TYPE_CAPABILITY,
   50|     96|                                             uint32_t(cap), &desc))
   51|     96|      ss << desc->name << " ";
   52|     96|    else
   53|     96|      ss << uint32_t(cap) << " ";
   54|     96|  });
   55|     96|  return ss.str();
   56|     96|}
validate_instruction.cpp:_ZZN8spvtools3val12_GLOBAL__N_18ToStringERKNS_7EnumSetIN3spv10CapabilityEEERKNS_15AssemblyGrammarEENK3$_0clES4_:
   47|    112|  capabilities.ForEach([&grammar, &ss](spv::Capability cap) {
   48|    112|    spv_operand_desc desc;
   49|    112|    if (SPV_SUCCESS == grammar.lookupOperand(SPV_OPERAND_TYPE_CAPABILITY,
  ------------------
  |  Branch (49:9): [True: 112, False: 0]
  ------------------
   50|    112|                                             uint32_t(cap), &desc))
   51|    112|      ss << desc->name << " ";
   52|      0|    else
   53|      0|      ss << uint32_t(cap) << " ";
   54|    112|  });
validate_instruction.cpp:_ZN8spvtools3val12_GLOBAL__N_125CheckRequiredCapabilitiesERNS0_17ValidationState_tEPKNS0_11InstructionEmRK20spv_parsed_operand_tj:
  147|   147k|                                       uint32_t word) {
  148|       |  // Mere mention of PointSize, ClipDistance, or CullDistance in a Builtin
  149|       |  // decoration does not require the associated capability.  The use of such
  150|       |  // a variable value should trigger the capability requirement, but that's
  151|       |  // not implemented yet.  This rule is independent of target environment.
  152|       |  // See https://github.com/KhronosGroup/SPIRV-Tools/issues/365
  153|   147k|  if (operand.type == SPV_OPERAND_TYPE_BUILT_IN) {
  ------------------
  |  Branch (153:7): [True: 816, False: 146k]
  ------------------
  154|    816|    switch (spv::BuiltIn(word)) {
  155|    108|      case spv::BuiltIn::PointSize:
  ------------------
  |  Branch (155:7): [True: 108, False: 708]
  ------------------
  156|    117|      case spv::BuiltIn::ClipDistance:
  ------------------
  |  Branch (156:7): [True: 9, False: 807]
  ------------------
  157|    253|      case spv::BuiltIn::CullDistance:
  ------------------
  |  Branch (157:7): [True: 136, False: 680]
  ------------------
  158|    253|        return SPV_SUCCESS;
  159|    563|      default:
  ------------------
  |  Branch (159:7): [True: 563, False: 253]
  ------------------
  160|    563|        break;
  161|    816|    }
  162|   146k|  } else if (operand.type == SPV_OPERAND_TYPE_FP_ROUNDING_MODE) {
  ------------------
  |  Branch (162:14): [True: 24, False: 146k]
  ------------------
  163|       |    // Allow all FP rounding modes if requested
  164|     24|    if (state.features().free_fp_rounding_mode) {
  ------------------
  |  Branch (164:9): [True: 0, False: 24]
  ------------------
  165|      0|      return SPV_SUCCESS;
  166|      0|    }
  167|   146k|  } else if (operand.type == SPV_OPERAND_TYPE_GROUP_OPERATION &&
  ------------------
  |  Branch (167:14): [True: 0, False: 146k]
  ------------------
  168|   146k|             state.features().group_ops_reduce_and_scans &&
  ------------------
  |  Branch (168:14): [True: 0, False: 0]
  ------------------
  169|   146k|             (word <= uint32_t(spv::GroupOperation::ExclusiveScan))) {
  ------------------
  |  Branch (169:14): [True: 0, False: 0]
  ------------------
  170|       |    // Allow certain group operations if requested.
  171|      0|    return SPV_SUCCESS;
  172|      0|  }
  173|       |
  174|   147k|  CapabilitySet enabling_capabilities;
  175|   147k|  spv_operand_desc operand_desc = nullptr;
  176|   147k|  const auto lookup_result =
  177|   147k|      state.grammar().lookupOperand(operand.type, word, &operand_desc);
  178|   147k|  if (lookup_result == SPV_SUCCESS) {
  ------------------
  |  Branch (178:7): [True: 66.8k, False: 80.4k]
  ------------------
  179|       |    // Allow FPRoundingMode decoration if requested.
  180|  66.8k|    if (operand.type == SPV_OPERAND_TYPE_DECORATION &&
  ------------------
  |  Branch (180:9): [True: 16.3k, False: 50.4k]
  ------------------
  181|  66.8k|        spv::Decoration(operand_desc->value) ==
  ------------------
  |  Branch (181:9): [True: 24, False: 16.3k]
  ------------------
  182|  16.3k|            spv::Decoration::FPRoundingMode) {
  183|     24|      if (state.features().free_fp_rounding_mode) return SPV_SUCCESS;
  ------------------
  |  Branch (183:11): [True: 0, False: 24]
  ------------------
  184|       |
  185|       |      // Vulkan API requires more capabilities on rounding mode.
  186|     24|      if (spvIsVulkanEnv(state.context()->target_env)) {
  ------------------
  |  Branch (186:11): [True: 0, False: 24]
  ------------------
  187|      0|        enabling_capabilities.Add(spv::Capability::StorageUniformBufferBlock16);
  188|      0|        enabling_capabilities.Add(spv::Capability::StorageUniform16);
  189|      0|        enabling_capabilities.Add(spv::Capability::StoragePushConstant16);
  190|      0|        enabling_capabilities.Add(spv::Capability::StorageInputOutput16);
  191|      0|      }
  192|  66.7k|    } else {
  193|  66.7k|      enabling_capabilities = state.grammar().filterCapsAgainstTargetEnv(
  194|  66.7k|          operand_desc->capabilities, operand_desc->numCapabilities);
  195|  66.7k|    }
  196|       |
  197|       |    // When encountering an OpCapability instruction, the instruction pass
  198|       |    // registers a capability with the module *before* checking capabilities.
  199|       |    // So in the case of an OpCapability instruction, don't bother checking
  200|       |    // enablement by another capability.
  201|  66.8k|    if (inst->opcode() != spv::Op::OpCapability) {
  ------------------
  |  Branch (201:9): [True: 59.7k, False: 7.02k]
  ------------------
  202|  59.7k|      const bool enabled_by_cap =
  203|  59.7k|          state.HasAnyOfCapabilities(enabling_capabilities);
  204|  59.7k|      if (!enabling_capabilities.IsEmpty() && !enabled_by_cap) {
  ------------------
  |  Branch (204:11): [True: 32.3k, False: 27.4k]
  |  Branch (204:47): [True: 83, False: 32.2k]
  ------------------
  205|     83|        return state.diag(SPV_ERROR_INVALID_CAPABILITY, inst)
  206|     83|               << "Operand " << which_operand << " of "
  207|     83|               << spvOpcodeString(inst->opcode())
  208|     83|               << " requires one of these capabilities: "
  209|     83|               << ToString(enabling_capabilities, state.grammar());
  210|     83|      }
  211|  59.7k|    }
  212|  66.7k|    return OperandVersionExtensionCheck(state, inst, which_operand,
  213|  66.7k|                                        *operand_desc, word);
  214|  66.8k|  }
  215|  80.4k|  return SPV_SUCCESS;
  216|   147k|}
validate_instruction.cpp:_ZN8spvtools3val12_GLOBAL__N_128OperandVersionExtensionCheckERNS0_17ValidationState_tEPKNS0_11InstructionEmRK18spv_operand_desc_tj:
   95|  66.7k|    const spv_operand_desc_t& operand_desc, uint32_t word) {
   96|  66.7k|  const uint32_t module_version = _.version();
   97|  66.7k|  const uint32_t operand_min_version = operand_desc.minVersion;
   98|  66.7k|  const uint32_t operand_last_version = operand_desc.lastVersion;
   99|  66.7k|  const bool reserved = operand_min_version == 0xffffffffu;
  100|  66.7k|  const bool version_satisfied = !reserved &&
  ------------------
  |  Branch (100:34): [True: 66.6k, False: 44]
  ------------------
  101|  66.7k|                                 (operand_min_version <= module_version) &&
  ------------------
  |  Branch (101:34): [True: 66.2k, False: 487]
  ------------------
  102|  66.7k|                                 (module_version <= operand_last_version);
  ------------------
  |  Branch (102:34): [True: 66.2k, False: 0]
  ------------------
  103|       |
  104|  66.7k|  if (version_satisfied) {
  ------------------
  |  Branch (104:7): [True: 66.2k, False: 531]
  ------------------
  105|  66.2k|    return SPV_SUCCESS;
  106|  66.2k|  }
  107|       |
  108|    531|  if (operand_last_version < module_version) {
  ------------------
  |  Branch (108:7): [True: 0, False: 531]
  ------------------
  109|      0|    return _.diag(SPV_ERROR_WRONG_VERSION, inst)
  110|      0|           << spvtools::utils::CardinalToOrdinal(which_operand)
  111|      0|           << " operand of " << spvOpcodeString(inst->opcode()) << ": operand "
  112|      0|           << operand_desc.name << "(" << word << ") requires SPIR-V version "
  113|      0|           << SPV_SPIRV_VERSION_MAJOR_PART(operand_last_version) << "."
  ------------------
  |  |   28|      0|#define SPV_SPIRV_VERSION_MAJOR_PART(WORD) ((uint32_t(WORD) >> 16) & 0xff)
  ------------------
  114|      0|           << SPV_SPIRV_VERSION_MINOR_PART(operand_last_version)
  ------------------
  |  |   30|      0|#define SPV_SPIRV_VERSION_MINOR_PART(WORD) ((uint32_t(WORD) >> 8) & 0xff)
  ------------------
  115|      0|           << " or earlier";
  116|      0|  }
  117|       |
  118|    531|  if (!reserved && operand_desc.numExtensions == 0) {
  ------------------
  |  Branch (118:7): [True: 487, False: 44]
  |  Branch (118:20): [True: 12, False: 475]
  ------------------
  119|     12|    return _.diag(SPV_ERROR_WRONG_VERSION, inst)
  120|     12|           << spvtools::utils::CardinalToOrdinal(which_operand)
  121|     12|           << " operand of " << spvOpcodeString(inst->opcode()) << ": operand "
  122|     12|           << operand_desc.name << "(" << word << ") requires SPIR-V version "
  123|     12|           << SPV_SPIRV_VERSION_MAJOR_PART(operand_min_version) << "."
  ------------------
  |  |   28|     12|#define SPV_SPIRV_VERSION_MAJOR_PART(WORD) ((uint32_t(WORD) >> 16) & 0xff)
  ------------------
  124|     12|           << SPV_SPIRV_VERSION_MINOR_PART(operand_min_version) << " or later";
  ------------------
  |  |   30|     12|#define SPV_SPIRV_VERSION_MINOR_PART(WORD) ((uint32_t(WORD) >> 8) & 0xff)
  ------------------
  125|    519|  } else {
  126|    519|    ExtensionSet required_extensions(operand_desc.numExtensions,
  127|    519|                                     operand_desc.extensions);
  128|    519|    if (!_.HasAnyOfExtensions(required_extensions)) {
  ------------------
  |  Branch (128:9): [True: 40, False: 479]
  ------------------
  129|     40|      return _.diag(SPV_ERROR_MISSING_EXTENSION, inst)
  130|     40|             << spvtools::utils::CardinalToOrdinal(which_operand)
  131|     40|             << " operand of " << spvOpcodeString(inst->opcode())
  132|     40|             << ": operand " << operand_desc.name << "(" << word
  133|     40|             << ") requires one of these extensions: "
  134|     40|             << ExtensionSetToString(required_extensions);
  135|     40|    }
  136|    519|  }
  137|    479|  return SPV_SUCCESS;
  138|    531|}
validate_instruction.cpp:_ZN8spvtools3val12_GLOBAL__N_117LimitCheckIdBoundERNS0_17ValidationState_tEPKNS0_11InstructionE:
  350|   387k|spv_result_t LimitCheckIdBound(ValidationState_t& _, const Instruction* inst) {
  351|   387k|  if (inst->id() >= _.getIdBound()) {
  ------------------
  |  Branch (351:7): [True: 245, False: 387k]
  ------------------
  352|    245|    return _.diag(SPV_ERROR_INVALID_BINARY, inst)
  353|    245|           << "Result <id> '" << inst->id()
  354|    245|           << "' must be less than the ID bound '" << _.getIdBound() << "'.";
  355|    245|  }
  356|   387k|  return SPV_SUCCESS;
  357|   387k|}
validate_instruction.cpp:_ZN8spvtools3val12_GLOBAL__N_116LimitCheckStructERNS0_17ValidationState_tEPKNS0_11InstructionE:
  360|   387k|spv_result_t LimitCheckStruct(ValidationState_t& _, const Instruction* inst) {
  361|   387k|  if (spv::Op::OpTypeStruct != inst->opcode()) {
  ------------------
  |  Branch (361:7): [True: 383k, False: 3.97k]
  ------------------
  362|   383k|    return SPV_SUCCESS;
  363|   383k|  }
  364|       |
  365|       |  // Number of members is the number of operands of the instruction minus 1.
  366|       |  // One operand is the result ID.
  367|  3.97k|  const uint16_t limit =
  368|  3.97k|      static_cast<uint16_t>(_.options()->universal_limits_.max_struct_members);
  369|  3.97k|  if (inst->operands().size() - 1 > limit) {
  ------------------
  |  Branch (369:7): [True: 0, False: 3.97k]
  ------------------
  370|      0|    return _.diag(SPV_ERROR_INVALID_BINARY, inst)
  371|      0|           << "Number of OpTypeStruct members (" << inst->operands().size() - 1
  372|      0|           << ") has exceeded the limit (" << limit << ").";
  373|      0|  }
  374|       |
  375|       |  // Section 2.17 of SPIRV Spec specifies that the "Structure Nesting Depth"
  376|       |  // must be less than or equal to 255.
  377|       |  // This is interpreted as structures including other structures as
  378|       |  // members. The code does not follow pointers or look into arrays to see
  379|       |  // if we reach a structure downstream. The nesting depth of a struct is
  380|       |  // 1+(largest depth of any member). Scalars are at depth 0.
  381|  3.97k|  uint32_t max_member_depth = 0;
  382|       |  // Struct members start at word 2 of OpTypeStruct instruction.
  383|  7.49k|  for (size_t word_i = 2; word_i < inst->words().size(); ++word_i) {
  ------------------
  |  Branch (383:27): [True: 3.52k, False: 3.97k]
  ------------------
  384|  3.52k|    auto member = inst->word(word_i);
  385|  3.52k|    auto memberTypeInstr = _.FindDef(member);
  386|  3.52k|    if (memberTypeInstr && spv::Op::OpTypeStruct == memberTypeInstr->opcode()) {
  ------------------
  |  Branch (386:9): [True: 3.48k, False: 45]
  |  Branch (386:28): [True: 301, False: 3.18k]
  ------------------
  387|    301|      max_member_depth = std::max(
  388|    301|          max_member_depth, _.struct_nesting_depth(memberTypeInstr->id()));
  389|    301|    }
  390|  3.52k|  }
  391|       |
  392|  3.97k|  const uint32_t depth_limit = _.options()->universal_limits_.max_struct_depth;
  393|  3.97k|  const uint32_t cur_depth = 1 + max_member_depth;
  394|  3.97k|  _.set_struct_nesting_depth(inst->id(), cur_depth);
  395|  3.97k|  if (cur_depth > depth_limit) {
  ------------------
  |  Branch (395:7): [True: 0, False: 3.97k]
  ------------------
  396|      0|    return _.diag(SPV_ERROR_INVALID_BINARY, inst)
  397|      0|           << "Structure Nesting Depth may not be larger than " << depth_limit
  398|      0|           << ". Found " << cur_depth << ".";
  399|      0|  }
  400|  3.97k|  return SPV_SUCCESS;
  401|  3.97k|}
validate_instruction.cpp:_ZN8spvtools3val12_GLOBAL__N_116LimitCheckSwitchERNS0_17ValidationState_tEPKNS0_11InstructionE:
  405|   387k|spv_result_t LimitCheckSwitch(ValidationState_t& _, const Instruction* inst) {
  406|   387k|  if (spv::Op::OpSwitch == inst->opcode()) {
  ------------------
  |  Branch (406:7): [True: 2.86k, False: 384k]
  ------------------
  407|       |    // The instruction syntax is as follows:
  408|       |    // OpSwitch <selector ID> <Default ID> literal label literal label ...
  409|       |    // literal,label pairs come after the first 2 operands.
  410|       |    // It is guaranteed at this point that num_operands is an even number.
  411|  2.86k|    size_t num_pairs = (inst->operands().size() - 2) / 2;
  412|  2.86k|    const unsigned int num_pairs_limit =
  413|  2.86k|        _.options()->universal_limits_.max_switch_branches;
  414|  2.86k|    if (num_pairs > num_pairs_limit) {
  ------------------
  |  Branch (414:9): [True: 0, False: 2.86k]
  ------------------
  415|      0|      return _.diag(SPV_ERROR_INVALID_BINARY, inst)
  416|      0|             << "Number of (literal, label) pairs in OpSwitch (" << num_pairs
  417|      0|             << ") exceeds the limit (" << num_pairs_limit << ").";
  418|      0|    }
  419|  2.86k|  }
  420|   387k|  return SPV_SUCCESS;
  421|   387k|}
validate_instruction.cpp:_ZN8spvtools3val12_GLOBAL__N_112VersionCheckERNS0_17ValidationState_tEPKNS0_11InstructionE:
  282|   387k|spv_result_t VersionCheck(ValidationState_t& _, const Instruction* inst) {
  283|   387k|  const auto opcode = inst->opcode();
  284|   387k|  spv_opcode_desc inst_desc;
  285|   387k|  const spv_result_t r = _.grammar().lookupOpcode(opcode, &inst_desc);
  286|   387k|  assert(r == SPV_SUCCESS);
  287|      0|  (void)r;
  288|       |
  289|   387k|  const auto min_version = inst_desc->minVersion;
  290|   387k|  const auto last_version = inst_desc->lastVersion;
  291|   387k|  const auto module_version = _.version();
  292|       |
  293|   387k|  if (last_version < module_version) {
  ------------------
  |  Branch (293:7): [True: 0, False: 387k]
  ------------------
  294|      0|    return _.diag(SPV_ERROR_WRONG_VERSION, inst)
  295|      0|           << spvOpcodeString(opcode) << " requires SPIR-V version "
  296|      0|           << SPV_SPIRV_VERSION_MAJOR_PART(last_version) << "."
  ------------------
  |  |   28|      0|#define SPV_SPIRV_VERSION_MAJOR_PART(WORD) ((uint32_t(WORD) >> 16) & 0xff)
  ------------------
  297|      0|           << SPV_SPIRV_VERSION_MINOR_PART(last_version) << " or earlier";
  ------------------
  |  |   30|      0|#define SPV_SPIRV_VERSION_MINOR_PART(WORD) ((uint32_t(WORD) >> 8) & 0xff)
  ------------------
  298|      0|  }
  299|       |
  300|       |  // OpTerminateInvocation is special because it is enabled by Shader
  301|       |  // capability, but also requires an extension and/or version check.
  302|   387k|  const bool capability_check_is_sufficient =
  303|   387k|      inst->opcode() != spv::Op::OpTerminateInvocation;
  304|       |
  305|   387k|  if (capability_check_is_sufficient && (inst_desc->numCapabilities > 0u)) {
  ------------------
  |  Branch (305:7): [True: 387k, False: 0]
  |  Branch (305:41): [True: 3.52k, False: 383k]
  ------------------
  306|       |    // We already checked that the direct capability dependency has been
  307|       |    // satisfied. We don't need to check any further.
  308|  3.52k|    return SPV_SUCCESS;
  309|  3.52k|  }
  310|       |
  311|   383k|  ExtensionSet exts(inst_desc->numExtensions, inst_desc->extensions);
  312|   383k|  if (exts.IsEmpty()) {
  ------------------
  |  Branch (312:7): [True: 383k, False: 2]
  ------------------
  313|       |    // If no extensions can enable this instruction, then emit error
  314|       |    // messages only concerning core SPIR-V versions if errors happen.
  315|   383k|    if (min_version == ~0u) {
  ------------------
  |  Branch (315:9): [True: 0, False: 383k]
  ------------------
  316|      0|      return _.diag(SPV_ERROR_WRONG_VERSION, inst)
  317|      0|             << spvOpcodeString(opcode) << " is reserved for future use.";
  318|      0|    }
  319|       |
  320|   383k|    if (module_version < min_version) {
  ------------------
  |  Branch (320:9): [True: 0, False: 383k]
  ------------------
  321|      0|      return _.diag(SPV_ERROR_WRONG_VERSION, inst)
  322|      0|             << spvOpcodeString(opcode) << " requires SPIR-V version "
  323|      0|             << SPV_SPIRV_VERSION_MAJOR_PART(min_version) << "."
  ------------------
  |  |   28|      0|#define SPV_SPIRV_VERSION_MAJOR_PART(WORD) ((uint32_t(WORD) >> 16) & 0xff)
  ------------------
  324|      0|             << SPV_SPIRV_VERSION_MINOR_PART(min_version) << " at minimum.";
  ------------------
  |  |   30|      0|#define SPV_SPIRV_VERSION_MINOR_PART(WORD) ((uint32_t(WORD) >> 8) & 0xff)
  ------------------
  325|      0|    }
  326|   383k|  } else if (!_.HasAnyOfExtensions(exts)) {
  ------------------
  |  Branch (326:14): [True: 2, False: 0]
  ------------------
  327|       |    // Otherwise, we only error out when no enabling extensions are
  328|       |    // registered.
  329|      2|    if (min_version == ~0u) {
  ------------------
  |  Branch (329:9): [True: 0, False: 2]
  ------------------
  330|      0|      return _.diag(SPV_ERROR_MISSING_EXTENSION, inst)
  331|      0|             << spvOpcodeString(opcode)
  332|      0|             << " requires one of the following extensions: "
  333|      0|             << ExtensionSetToString(exts);
  334|      0|    }
  335|       |
  336|      2|    if (module_version < min_version) {
  ------------------
  |  Branch (336:9): [True: 2, False: 0]
  ------------------
  337|      2|      return _.diag(SPV_ERROR_WRONG_VERSION, inst)
  338|      2|             << spvOpcodeString(opcode) << " requires SPIR-V version "
  339|      2|             << SPV_SPIRV_VERSION_MAJOR_PART(min_version) << "."
  ------------------
  |  |   28|      2|#define SPV_SPIRV_VERSION_MAJOR_PART(WORD) ((uint32_t(WORD) >> 16) & 0xff)
  ------------------
  340|      2|             << SPV_SPIRV_VERSION_MINOR_PART(min_version)
  ------------------
  |  |   30|      2|#define SPV_SPIRV_VERSION_MINOR_PART(WORD) ((uint32_t(WORD) >> 8) & 0xff)
  ------------------
  341|      2|             << " at minimum or one of the following extensions: "
  342|      2|             << ExtensionSetToString(exts);
  343|      2|    }
  344|      2|  }
  345|       |
  346|   383k|  return SPV_SUCCESS;
  347|   383k|}

_ZN8spvtools3val18ValidateInterfacesERNS0_17ValidationState_tE:
  542|    664|spv_result_t ValidateInterfaces(ValidationState_t& _) {
  543|    664|  bool is_spv_1_4 = _.version() >= SPV_SPIRV_VERSION_WORD(1, 4);
  ------------------
  |  |   26|    664|  ((uint32_t(uint8_t(MAJOR)) << 16) | (uint32_t(uint8_t(MINOR)) << 8))
  ------------------
  544|  73.1k|  for (auto& inst : _.ordered_instructions()) {
  ------------------
  |  Branch (544:19): [True: 73.1k, False: 633]
  ------------------
  545|  73.1k|    if (is_interface_variable(&inst, is_spv_1_4)) {
  ------------------
  |  Branch (545:9): [True: 298, False: 72.8k]
  ------------------
  546|    298|      if (auto error = check_interface_variable(_, &inst)) {
  ------------------
  |  Branch (546:16): [True: 31, False: 267]
  ------------------
  547|     31|        return error;
  548|     31|      }
  549|    298|    }
  550|  73.1k|  }
  551|       |
  552|    633|  if (spvIsVulkanEnv(_.context()->target_env)) {
  ------------------
  |  Branch (552:7): [True: 0, False: 633]
  ------------------
  553|      0|    for (auto& inst : _.ordered_instructions()) {
  ------------------
  |  Branch (553:21): [True: 0, False: 0]
  ------------------
  554|      0|      if (inst.opcode() == spv::Op::OpEntryPoint) {
  ------------------
  |  Branch (554:11): [True: 0, False: 0]
  ------------------
  555|      0|        if (auto error = ValidateLocations(_, &inst)) {
  ------------------
  |  Branch (555:18): [True: 0, False: 0]
  ------------------
  556|      0|          return error;
  557|      0|        }
  558|      0|      }
  559|      0|      if (inst.opcode() == spv::Op::OpTypeVoid) break;
  ------------------
  |  Branch (559:11): [True: 0, False: 0]
  ------------------
  560|      0|    }
  561|      0|  }
  562|       |
  563|    633|  return SPV_SUCCESS;
  564|    633|}
validate_interfaces.cpp:_ZN8spvtools3val12_GLOBAL__N_121is_interface_variableEPKNS0_11InstructionEb:
   35|  73.1k|bool is_interface_variable(const Instruction* inst, bool is_spv_1_4) {
   36|  73.1k|  if (is_spv_1_4) {
  ------------------
  |  Branch (36:7): [True: 0, False: 73.1k]
  ------------------
   37|       |    // Starting in SPIR-V 1.4, all global variables are interface variables.
   38|      0|    return inst->opcode() == spv::Op::OpVariable &&
  ------------------
  |  Branch (38:12): [True: 0, False: 0]
  ------------------
   39|      0|           inst->GetOperandAs<spv::StorageClass>(2u) !=
  ------------------
  |  Branch (39:12): [True: 0, False: 0]
  ------------------
   40|      0|               spv::StorageClass::Function;
   41|  73.1k|  } else {
   42|  73.1k|    return inst->opcode() == spv::Op::OpVariable &&
  ------------------
  |  Branch (42:12): [True: 1.79k, False: 71.3k]
  ------------------
   43|  73.1k|           (inst->GetOperandAs<spv::StorageClass>(2u) ==
  ------------------
  |  Branch (43:13): [True: 144, False: 1.65k]
  ------------------
   44|  1.79k|                spv::StorageClass::Input ||
   45|  1.79k|            inst->GetOperandAs<spv::StorageClass>(2u) ==
  ------------------
  |  Branch (45:13): [True: 154, False: 1.49k]
  ------------------
   46|  1.65k|                spv::StorageClass::Output);
   47|  73.1k|  }
   48|  73.1k|}
validate_interfaces.cpp:_ZN8spvtools3val12_GLOBAL__N_124check_interface_variableERNS0_17ValidationState_tEPKNS0_11InstructionE:
   53|    298|                                      const Instruction* var) {
   54|    298|  std::vector<const Function*> functions;
   55|    298|  std::vector<const Instruction*> uses;
   56|  25.9k|  for (auto use : var->uses()) {
  ------------------
  |  Branch (56:17): [True: 25.9k, False: 298]
  ------------------
   57|  25.9k|    uses.push_back(use.first);
   58|  25.9k|  }
   59|  26.2k|  for (uint32_t i = 0; i < uses.size(); ++i) {
  ------------------
  |  Branch (59:24): [True: 25.9k, False: 298]
  ------------------
   60|  25.9k|    const auto user = uses[i];
   61|  25.9k|    if (const Function* func = user->function()) {
  ------------------
  |  Branch (61:25): [True: 24.9k, False: 991]
  ------------------
   62|  24.9k|      functions.push_back(func);
   63|  24.9k|    } else {
   64|       |      // In the rare case that the variable is used by another instruction in
   65|       |      // the global scope, continue searching for an instruction used in a
   66|       |      // function.
   67|    991|      for (auto use : user->uses()) {
  ------------------
  |  Branch (67:21): [True: 0, False: 991]
  ------------------
   68|      0|        uses.push_back(use.first);
   69|      0|      }
   70|    991|    }
   71|  25.9k|  }
   72|       |
   73|    298|  std::sort(functions.begin(), functions.end(),
   74|    298|            [](const Function* lhs, const Function* rhs) {
   75|    298|              return lhs->id() < rhs->id();
   76|    298|            });
   77|    298|  functions.erase(std::unique(functions.begin(), functions.end()),
   78|    298|                  functions.end());
   79|       |
   80|    298|  std::vector<uint32_t> entry_points;
   81|    298|  for (const auto func : functions) {
  ------------------
  |  Branch (81:24): [True: 268, False: 298]
  ------------------
   82|    268|    for (auto id : _.FunctionEntryPoints(func->id())) {
  ------------------
  |  Branch (82:18): [True: 235, False: 268]
  ------------------
   83|    235|      entry_points.push_back(id);
   84|    235|    }
   85|    268|  }
   86|       |
   87|    298|  std::sort(entry_points.begin(), entry_points.end());
   88|    298|  entry_points.erase(std::unique(entry_points.begin(), entry_points.end()),
   89|    298|                     entry_points.end());
   90|       |
   91|    298|  for (auto id : entry_points) {
  ------------------
  |  Branch (91:16): [True: 216, False: 267]
  ------------------
   92|    217|    for (const auto& desc : _.entry_point_descriptions(id)) {
  ------------------
  |  Branch (92:27): [True: 217, False: 185]
  ------------------
   93|    217|      bool found = false;
   94|    276|      for (auto interface : desc.interfaces) {
  ------------------
  |  Branch (94:27): [True: 276, False: 31]
  ------------------
   95|    276|        if (var->id() == interface) {
  ------------------
  |  Branch (95:13): [True: 186, False: 90]
  ------------------
   96|    186|          found = true;
   97|    186|          break;
   98|    186|        }
   99|    276|      }
  100|    217|      if (!found) {
  ------------------
  |  Branch (100:11): [True: 31, False: 186]
  ------------------
  101|     31|        return _.diag(SPV_ERROR_INVALID_ID, var)
  102|     31|               << "Interface variable id <" << var->id()
  103|     31|               << "> is used by entry point '" << desc.name << "' id <" << id
  104|     31|               << ">, but is not listed as an interface";
  105|     31|      }
  106|    217|    }
  107|    216|  }
  108|       |
  109|    267|  return SPV_SUCCESS;
  110|    298|}
validate_interfaces.cpp:_ZZN8spvtools3val12_GLOBAL__N_124check_interface_variableERNS0_17ValidationState_tEPKNS0_11InstructionEENK3$_0clEPKNS0_8FunctionESA_:
   74|  49.3k|            [](const Function* lhs, const Function* rhs) {
   75|  49.3k|              return lhs->id() < rhs->id();
   76|  49.3k|            });

_ZN8spvtools3val16ModuleLayoutPassERNS0_17ValidationState_tEPKNS0_11InstructionE:
  359|   392k|spv_result_t ModuleLayoutPass(ValidationState_t& _, const Instruction* inst) {
  360|   392k|  const spv::Op opcode = inst->opcode();
  361|       |
  362|   392k|  switch (_.current_layout_section()) {
  ------------------
  |  Branch (362:11): [True: 0, False: 392k]
  ------------------
  363|  13.4k|    case kLayoutCapabilities:
  ------------------
  |  Branch (363:5): [True: 13.4k, False: 378k]
  ------------------
  364|  15.6k|    case kLayoutExtensions:
  ------------------
  |  Branch (364:5): [True: 2.16k, False: 389k]
  ------------------
  365|  16.6k|    case kLayoutExtInstImport:
  ------------------
  |  Branch (365:5): [True: 969, False: 391k]
  ------------------
  366|  21.9k|    case kLayoutMemoryModel:
  ------------------
  |  Branch (366:5): [True: 5.34k, False: 386k]
  ------------------
  367|  21.9k|    case kLayoutSamplerImageAddressMode:
  ------------------
  |  Branch (367:5): [True: 0, False: 392k]
  ------------------
  368|  24.9k|    case kLayoutEntryPoint:
  ------------------
  |  Branch (368:5): [True: 3.00k, False: 389k]
  ------------------
  369|  28.9k|    case kLayoutExecutionMode:
  ------------------
  |  Branch (369:5): [True: 4.01k, False: 388k]
  ------------------
  370|  29.7k|    case kLayoutDebug1:
  ------------------
  |  Branch (370:5): [True: 774, False: 391k]
  ------------------
  371|  32.2k|    case kLayoutDebug2:
  ------------------
  |  Branch (371:5): [True: 2.44k, False: 389k]
  ------------------
  372|  32.2k|    case kLayoutDebug3:
  ------------------
  |  Branch (372:5): [True: 0, False: 392k]
  ------------------
  373|  51.2k|    case kLayoutAnnotations:
  ------------------
  |  Branch (373:5): [True: 19.0k, False: 373k]
  ------------------
  374|   113k|    case kLayoutTypes:
  ------------------
  |  Branch (374:5): [True: 62.3k, False: 329k]
  ------------------
  375|   113k|      if (auto error = ModuleScopedInstructions(_, inst, opcode)) return error;
  ------------------
  |  Branch (375:16): [True: 752, False: 112k]
  ------------------
  376|   112k|      break;
  377|   112k|    case kLayoutFunctionDeclarations:
  ------------------
  |  Branch (377:5): [True: 7.42k, False: 384k]
  ------------------
  378|   278k|    case kLayoutFunctionDefinitions:
  ------------------
  |  Branch (378:5): [True: 271k, False: 120k]
  ------------------
  379|   278k|      if (auto error = FunctionScopedInstructions(_, inst, opcode)) {
  ------------------
  |  Branch (379:16): [True: 78, False: 278k]
  ------------------
  380|     78|        return error;
  381|     78|      }
  382|   278k|      break;
  383|   392k|  }
  384|   391k|  return SPV_SUCCESS;
  385|   392k|}
validate_layout.cpp:_ZN8spvtools3val12_GLOBAL__N_124ModuleScopedInstructionsERNS0_17ValidationState_tEPKNS0_11InstructionEN3spv2OpE:
   38|   113k|                                      const Instruction* inst, spv::Op opcode) {
   39|   113k|  switch (opcode) {
   40|      5|    case spv::Op::OpExtInst:
  ------------------
  |  Branch (40:5): [True: 5, False: 113k]
  ------------------
   41|      5|      if (spvExtInstIsDebugInfo(inst->ext_inst_type())) {
  ------------------
  |  Branch (41:11): [True: 0, False: 5]
  ------------------
   42|      0|        const uint32_t ext_inst_index = inst->word(4);
   43|      0|        bool local_debug_info = false;
   44|      0|        if (inst->ext_inst_type() == SPV_EXT_INST_TYPE_OPENCL_DEBUGINFO_100) {
  ------------------
  |  Branch (44:13): [True: 0, False: 0]
  ------------------
   45|      0|          const OpenCLDebugInfo100Instructions ext_inst_key =
   46|      0|              OpenCLDebugInfo100Instructions(ext_inst_index);
   47|      0|          if (ext_inst_key == OpenCLDebugInfo100DebugScope ||
  ------------------
  |  Branch (47:15): [True: 0, False: 0]
  ------------------
   48|      0|              ext_inst_key == OpenCLDebugInfo100DebugNoScope ||
  ------------------
  |  Branch (48:15): [True: 0, False: 0]
  ------------------
   49|      0|              ext_inst_key == OpenCLDebugInfo100DebugDeclare ||
  ------------------
  |  Branch (49:15): [True: 0, False: 0]
  ------------------
   50|      0|              ext_inst_key == OpenCLDebugInfo100DebugValue) {
  ------------------
  |  Branch (50:15): [True: 0, False: 0]
  ------------------
   51|      0|            local_debug_info = true;
   52|      0|          }
   53|      0|        } else if (inst->ext_inst_type() ==
  ------------------
  |  Branch (53:20): [True: 0, False: 0]
  ------------------
   54|      0|                   SPV_EXT_INST_TYPE_NONSEMANTIC_SHADER_DEBUGINFO_100) {
   55|      0|          const NonSemanticShaderDebugInfo100Instructions ext_inst_key =
   56|      0|              NonSemanticShaderDebugInfo100Instructions(ext_inst_index);
   57|      0|          if (ext_inst_key == NonSemanticShaderDebugInfo100DebugScope ||
  ------------------
  |  Branch (57:15): [True: 0, False: 0]
  ------------------
   58|      0|              ext_inst_key == NonSemanticShaderDebugInfo100DebugNoScope ||
  ------------------
  |  Branch (58:15): [True: 0, False: 0]
  ------------------
   59|      0|              ext_inst_key == NonSemanticShaderDebugInfo100DebugDeclare ||
  ------------------
  |  Branch (59:15): [True: 0, False: 0]
  ------------------
   60|      0|              ext_inst_key == NonSemanticShaderDebugInfo100DebugValue ||
  ------------------
  |  Branch (60:15): [True: 0, False: 0]
  ------------------
   61|      0|              ext_inst_key == NonSemanticShaderDebugInfo100DebugLine ||
  ------------------
  |  Branch (61:15): [True: 0, False: 0]
  ------------------
   62|      0|              ext_inst_key == NonSemanticShaderDebugInfo100DebugNoLine ||
  ------------------
  |  Branch (62:15): [True: 0, False: 0]
  ------------------
   63|      0|              ext_inst_key ==
  ------------------
  |  Branch (63:15): [True: 0, False: 0]
  ------------------
   64|      0|                  NonSemanticShaderDebugInfo100DebugFunctionDefinition) {
   65|      0|            local_debug_info = true;
   66|      0|          }
   67|      0|        } else {
   68|      0|          const DebugInfoInstructions ext_inst_key =
   69|      0|              DebugInfoInstructions(ext_inst_index);
   70|      0|          if (ext_inst_key == DebugInfoDebugScope ||
  ------------------
  |  Branch (70:15): [True: 0, False: 0]
  ------------------
   71|      0|              ext_inst_key == DebugInfoDebugNoScope ||
  ------------------
  |  Branch (71:15): [True: 0, False: 0]
  ------------------
   72|      0|              ext_inst_key == DebugInfoDebugDeclare ||
  ------------------
  |  Branch (72:15): [True: 0, False: 0]
  ------------------
   73|      0|              ext_inst_key == DebugInfoDebugValue) {
  ------------------
  |  Branch (73:15): [True: 0, False: 0]
  ------------------
   74|      0|            local_debug_info = true;
   75|      0|          }
   76|      0|        }
   77|       |
   78|      0|        if (local_debug_info) {
  ------------------
  |  Branch (78:13): [True: 0, False: 0]
  ------------------
   79|      0|          if (_.in_function_body() == false) {
  ------------------
  |  Branch (79:15): [True: 0, False: 0]
  ------------------
   80|       |            // DebugScope, DebugNoScope, DebugDeclare, DebugValue must
   81|       |            // appear in a function body.
   82|      0|            return _.diag(SPV_ERROR_INVALID_LAYOUT, inst)
   83|      0|                   << "DebugScope, DebugNoScope, DebugDeclare, DebugValue "
   84|      0|                   << "of debug info extension must appear in a function "
   85|      0|                   << "body";
   86|      0|          }
   87|      0|        } else {
   88|       |          // Debug info extinst opcodes other than DebugScope, DebugNoScope,
   89|       |          // DebugDeclare, DebugValue must be placed between section 9 (types,
   90|       |          // constants, global variables) and section 10 (function
   91|       |          // declarations).
   92|      0|          if (_.current_layout_section() < kLayoutTypes ||
  ------------------
  |  Branch (92:15): [True: 0, False: 0]
  ------------------
   93|      0|              _.current_layout_section() >= kLayoutFunctionDeclarations) {
  ------------------
  |  Branch (93:15): [True: 0, False: 0]
  ------------------
   94|      0|            return _.diag(SPV_ERROR_INVALID_LAYOUT, inst)
   95|      0|                   << "Debug info extension instructions other than "
   96|      0|                   << "DebugScope, DebugNoScope, DebugDeclare, DebugValue "
   97|      0|                   << "must appear between section 9 (types, constants, "
   98|      0|                   << "global variables) and section 10 (function "
   99|      0|                   << "declarations)";
  100|      0|          }
  101|      0|        }
  102|      5|      } else if (spvExtInstIsNonSemantic(inst->ext_inst_type())) {
  ------------------
  |  Branch (102:18): [True: 5, False: 0]
  ------------------
  103|       |        // non-semantic extinst opcodes are allowed beginning in the types
  104|       |        // section, but since they must name a return type they cannot be the
  105|       |        // first instruction in the types section. Therefore check that we are
  106|       |        // already in it.
  107|      5|        if (_.current_layout_section() < kLayoutTypes) {
  ------------------
  |  Branch (107:13): [True: 0, False: 5]
  ------------------
  108|      0|          return _.diag(SPV_ERROR_INVALID_LAYOUT, inst)
  109|      0|                 << "Non-semantic OpExtInst must not appear before types "
  110|      0|                 << "section";
  111|      0|        }
  112|      5|      } else {
  113|       |        // otherwise they must be used in a block
  114|      0|        if (_.current_layout_section() < kLayoutFunctionDefinitions) {
  ------------------
  |  Branch (114:13): [True: 0, False: 0]
  ------------------
  115|      0|          return _.diag(SPV_ERROR_INVALID_LAYOUT, inst)
  116|      0|                 << spvOpcodeString(opcode) << " must appear in a block";
  117|      0|        }
  118|      0|      }
  119|      5|      break;
  120|   113k|    default:
  ------------------
  |  Branch (120:5): [True: 113k, False: 5]
  ------------------
  121|   113k|      break;
  122|   113k|  }
  123|       |
  124|   172k|  while (_.IsOpcodeInCurrentLayoutSection(opcode) == false) {
  ------------------
  |  Branch (124:10): [True: 62.7k, False: 109k]
  ------------------
  125|  62.7k|    if (_.IsOpcodeInPreviousLayoutSection(opcode)) {
  ------------------
  |  Branch (125:9): [True: 16, False: 62.7k]
  ------------------
  126|     16|      return _.diag(SPV_ERROR_INVALID_LAYOUT, inst)
  127|     16|             << spvOpcodeString(opcode) << " is in an invalid layout section";
  128|     16|    }
  129|       |
  130|  62.7k|    _.ProgressToNextLayoutSectionOrder();
  131|       |
  132|  62.7k|    switch (_.current_layout_section()) {
  133|  6.13k|      case kLayoutMemoryModel:
  ------------------
  |  Branch (133:7): [True: 6.13k, False: 56.5k]
  ------------------
  134|  6.13k|        if (opcode != spv::Op::OpMemoryModel) {
  ------------------
  |  Branch (134:13): [True: 697, False: 5.43k]
  ------------------
  135|    697|          return _.diag(SPV_ERROR_INVALID_LAYOUT, inst)
  136|    697|                 << spvOpcodeString(opcode)
  137|    697|                 << " cannot appear before the memory model instruction";
  138|    697|        }
  139|  5.43k|        break;
  140|  5.43k|      case kLayoutFunctionDeclarations:
  ------------------
  |  Branch (140:7): [True: 3.52k, False: 59.1k]
  ------------------
  141|       |        // All module sections have been processed. Recursively call
  142|       |        // ModuleLayoutPass to process the next section of the module
  143|  3.52k|        return ModuleLayoutPass(_, inst);
  144|  53.0k|      default:
  ------------------
  |  Branch (144:7): [True: 53.0k, False: 9.65k]
  ------------------
  145|  53.0k|        break;
  146|  62.7k|    }
  147|  62.7k|  }
  148|   109k|  return SPV_SUCCESS;
  149|   113k|}
validate_layout.cpp:_ZN8spvtools3val12_GLOBAL__N_126FunctionScopedInstructionsERNS0_17ValidationState_tEPKNS0_11InstructionEN3spv2OpE:
  158|   278k|                                        spv::Op opcode) {
  159|       |  // Make sure we advance into the function definitions when we hit
  160|       |  // non-function declaration instructions.
  161|   278k|  if (_.current_layout_section() == kLayoutFunctionDeclarations &&
  ------------------
  |  Branch (161:7): [True: 7.42k, False: 271k]
  ------------------
  162|   278k|      !_.IsOpcodeInCurrentLayoutSection(opcode)) {
  ------------------
  |  Branch (162:7): [True: 3.14k, False: 4.28k]
  ------------------
  163|  3.14k|    _.ProgressToNextLayoutSectionOrder();
  164|       |
  165|  3.14k|    if (_.in_function_body()) {
  ------------------
  |  Branch (165:9): [True: 3.10k, False: 37]
  ------------------
  166|  3.10k|      if (auto error = _.current_function().RegisterSetFunctionDeclType(
  ------------------
  |  Branch (166:16): [True: 0, False: 3.10k]
  ------------------
  167|  3.10k|              FunctionDecl::kFunctionDeclDefinition)) {
  168|      0|        return error;
  169|      0|      }
  170|  3.10k|    }
  171|  3.14k|  }
  172|       |
  173|   278k|  if (_.IsOpcodeInCurrentLayoutSection(opcode)) {
  ------------------
  |  Branch (173:7): [True: 278k, False: 11]
  ------------------
  174|   278k|    switch (opcode) {
  175|  4.78k|      case spv::Op::OpFunction: {
  ------------------
  |  Branch (175:7): [True: 4.78k, False: 273k]
  ------------------
  176|  4.78k|        if (_.in_function_body()) {
  ------------------
  |  Branch (176:13): [True: 2, False: 4.78k]
  ------------------
  177|      2|          return _.diag(SPV_ERROR_INVALID_LAYOUT, inst)
  178|      2|                 << "Cannot declare a function in a function body";
  179|      2|        }
  180|  4.78k|        auto control_mask = inst->GetOperandAs<spv::FunctionControlMask>(2);
  181|  4.78k|        if (auto error =
  ------------------
  |  Branch (181:18): [True: 0, False: 4.78k]
  ------------------
  182|  4.78k|                _.RegisterFunction(inst->id(), inst->type_id(), control_mask,
  183|  4.78k|                                   inst->GetOperandAs<uint32_t>(3)))
  184|      0|          return error;
  185|  4.78k|        if (_.current_layout_section() == kLayoutFunctionDefinitions) {
  ------------------
  |  Branch (185:13): [True: 1.10k, False: 3.68k]
  ------------------
  186|  1.10k|          if (auto error = _.current_function().RegisterSetFunctionDeclType(
  ------------------
  |  Branch (186:20): [True: 0, False: 1.10k]
  ------------------
  187|  1.10k|                  FunctionDecl::kFunctionDeclDefinition))
  188|      0|            return error;
  189|  1.10k|        }
  190|  4.78k|      } break;
  191|       |
  192|  4.78k|      case spv::Op::OpFunctionParameter:
  ------------------
  |  Branch (192:7): [True: 734, False: 277k]
  ------------------
  193|    734|        if (_.in_function_body() == false) {
  ------------------
  |  Branch (193:13): [True: 0, False: 734]
  ------------------
  194|      0|          return _.diag(SPV_ERROR_INVALID_LAYOUT, inst)
  195|      0|                 << "Function parameter instructions must be in a "
  196|      0|                    "function body";
  197|      0|        }
  198|    734|        if (_.current_function().block_count() != 0) {
  ------------------
  |  Branch (198:13): [True: 0, False: 734]
  ------------------
  199|      0|          return _.diag(SPV_ERROR_INVALID_LAYOUT, inst)
  200|      0|                 << "Function parameters must only appear immediately after "
  201|      0|                    "the function definition";
  202|      0|        }
  203|    734|        if (auto error = _.current_function().RegisterFunctionParameter(
  ------------------
  |  Branch (203:18): [True: 0, False: 734]
  ------------------
  204|    734|                inst->id(), inst->type_id()))
  205|      0|          return error;
  206|    734|        break;
  207|       |
  208|  3.90k|      case spv::Op::OpFunctionEnd:
  ------------------
  |  Branch (208:7): [True: 3.90k, False: 274k]
  ------------------
  209|  3.90k|        if (_.in_function_body() == false) {
  ------------------
  |  Branch (209:13): [True: 9, False: 3.89k]
  ------------------
  210|      9|          return _.diag(SPV_ERROR_INVALID_LAYOUT, inst)
  211|      9|                 << "Function end instructions must be in a function body";
  212|      9|        }
  213|  3.89k|        if (_.in_block()) {
  ------------------
  |  Branch (213:13): [True: 2, False: 3.89k]
  ------------------
  214|      2|          return _.diag(SPV_ERROR_INVALID_LAYOUT, inst)
  215|      2|                 << "Function end cannot be called in blocks";
  216|      2|        }
  217|  3.89k|        if (_.current_function().block_count() == 0 &&
  ------------------
  |  Branch (217:13): [True: 519, False: 3.37k]
  ------------------
  218|  3.89k|            _.current_layout_section() == kLayoutFunctionDefinitions) {
  ------------------
  |  Branch (218:13): [True: 1, False: 518]
  ------------------
  219|      1|          return _.diag(SPV_ERROR_INVALID_LAYOUT, inst)
  220|      1|                 << "Function declarations must appear before "
  221|      1|                    "function definitions.";
  222|      1|        }
  223|  3.89k|        if (_.current_layout_section() == kLayoutFunctionDeclarations) {
  ------------------
  |  Branch (223:13): [True: 518, False: 3.37k]
  ------------------
  224|    518|          if (auto error = _.current_function().RegisterSetFunctionDeclType(
  ------------------
  |  Branch (224:20): [True: 0, False: 518]
  ------------------
  225|    518|                  FunctionDecl::kFunctionDeclDeclaration))
  226|      0|            return error;
  227|    518|        }
  228|  3.89k|        if (auto error = _.RegisterFunctionEnd()) return error;
  ------------------
  |  Branch (228:18): [True: 0, False: 3.89k]
  ------------------
  229|  3.89k|        break;
  230|       |
  231|  3.89k|      case spv::Op::OpLine:
  ------------------
  |  Branch (231:7): [True: 158, False: 278k]
  ------------------
  232|  1.28k|      case spv::Op::OpNoLine:
  ------------------
  |  Branch (232:7): [True: 1.12k, False: 277k]
  ------------------
  233|  1.28k|        break;
  234|  50.8k|      case spv::Op::OpLabel:
  ------------------
  |  Branch (234:7): [True: 50.8k, False: 227k]
  ------------------
  235|       |        // If the label is encountered then the current function is a
  236|       |        // definition so set the function to a declaration and update the
  237|       |        // module section
  238|  50.8k|        if (_.in_function_body() == false) {
  ------------------
  |  Branch (238:13): [True: 6, False: 50.8k]
  ------------------
  239|      6|          return _.diag(SPV_ERROR_INVALID_LAYOUT, inst)
  240|      6|                 << "Label instructions must be in a function body";
  241|      6|        }
  242|  50.8k|        if (_.in_block()) {
  ------------------
  |  Branch (242:13): [True: 1, False: 50.8k]
  ------------------
  243|      1|          return _.diag(SPV_ERROR_INVALID_LAYOUT, inst)
  244|      1|                 << "A block must end with a branch instruction.";
  245|      1|        }
  246|  50.8k|        break;
  247|       |
  248|  50.8k|      case spv::Op::OpExtInst:
  ------------------
  |  Branch (248:7): [True: 3.42k, False: 275k]
  ------------------
  249|  3.42k|        if (spvExtInstIsDebugInfo(inst->ext_inst_type())) {
  ------------------
  |  Branch (249:13): [True: 0, False: 3.42k]
  ------------------
  250|      0|          const uint32_t ext_inst_index = inst->word(4);
  251|      0|          bool local_debug_info = false;
  252|      0|          if (inst->ext_inst_type() == SPV_EXT_INST_TYPE_OPENCL_DEBUGINFO_100) {
  ------------------
  |  Branch (252:15): [True: 0, False: 0]
  ------------------
  253|      0|            const OpenCLDebugInfo100Instructions ext_inst_key =
  254|      0|                OpenCLDebugInfo100Instructions(ext_inst_index);
  255|      0|            if (ext_inst_key == OpenCLDebugInfo100DebugScope ||
  ------------------
  |  Branch (255:17): [True: 0, False: 0]
  ------------------
  256|      0|                ext_inst_key == OpenCLDebugInfo100DebugNoScope ||
  ------------------
  |  Branch (256:17): [True: 0, False: 0]
  ------------------
  257|      0|                ext_inst_key == OpenCLDebugInfo100DebugDeclare ||
  ------------------
  |  Branch (257:17): [True: 0, False: 0]
  ------------------
  258|      0|                ext_inst_key == OpenCLDebugInfo100DebugValue) {
  ------------------
  |  Branch (258:17): [True: 0, False: 0]
  ------------------
  259|      0|              local_debug_info = true;
  260|      0|            }
  261|      0|          } else if (inst->ext_inst_type() ==
  ------------------
  |  Branch (261:22): [True: 0, False: 0]
  ------------------
  262|      0|                     SPV_EXT_INST_TYPE_NONSEMANTIC_SHADER_DEBUGINFO_100) {
  263|      0|            const NonSemanticShaderDebugInfo100Instructions ext_inst_key =
  264|      0|                NonSemanticShaderDebugInfo100Instructions(ext_inst_index);
  265|      0|            if (ext_inst_key == NonSemanticShaderDebugInfo100DebugScope ||
  ------------------
  |  Branch (265:17): [True: 0, False: 0]
  ------------------
  266|      0|                ext_inst_key == NonSemanticShaderDebugInfo100DebugNoScope ||
  ------------------
  |  Branch (266:17): [True: 0, False: 0]
  ------------------
  267|      0|                ext_inst_key == NonSemanticShaderDebugInfo100DebugDeclare ||
  ------------------
  |  Branch (267:17): [True: 0, False: 0]
  ------------------
  268|      0|                ext_inst_key == NonSemanticShaderDebugInfo100DebugValue ||
  ------------------
  |  Branch (268:17): [True: 0, False: 0]
  ------------------
  269|      0|                ext_inst_key == NonSemanticShaderDebugInfo100DebugLine ||
  ------------------
  |  Branch (269:17): [True: 0, False: 0]
  ------------------
  270|      0|                ext_inst_key == NonSemanticShaderDebugInfo100DebugNoLine ||
  ------------------
  |  Branch (270:17): [True: 0, False: 0]
  ------------------
  271|      0|                ext_inst_key ==
  ------------------
  |  Branch (271:17): [True: 0, False: 0]
  ------------------
  272|      0|                    NonSemanticShaderDebugInfo100DebugFunctionDefinition) {
  273|      0|              local_debug_info = true;
  274|      0|            }
  275|      0|          } else {
  276|      0|            const DebugInfoInstructions ext_inst_key =
  277|      0|                DebugInfoInstructions(ext_inst_index);
  278|      0|            if (ext_inst_key == DebugInfoDebugScope ||
  ------------------
  |  Branch (278:17): [True: 0, False: 0]
  ------------------
  279|      0|                ext_inst_key == DebugInfoDebugNoScope ||
  ------------------
  |  Branch (279:17): [True: 0, False: 0]
  ------------------
  280|      0|                ext_inst_key == DebugInfoDebugDeclare ||
  ------------------
  |  Branch (280:17): [True: 0, False: 0]
  ------------------
  281|      0|                ext_inst_key == DebugInfoDebugValue) {
  ------------------
  |  Branch (281:17): [True: 0, False: 0]
  ------------------
  282|      0|              local_debug_info = true;
  283|      0|            }
  284|      0|          }
  285|       |
  286|      0|          if (local_debug_info) {
  ------------------
  |  Branch (286:15): [True: 0, False: 0]
  ------------------
  287|      0|            if (_.in_function_body() == false) {
  ------------------
  |  Branch (287:17): [True: 0, False: 0]
  ------------------
  288|       |              // DebugScope, DebugNoScope, DebugDeclare, DebugValue must
  289|       |              // appear in a function body.
  290|      0|              return _.diag(SPV_ERROR_INVALID_LAYOUT, inst)
  291|      0|                     << "DebugScope, DebugNoScope, DebugDeclare, DebugValue "
  292|      0|                     << "of debug info extension must appear in a function "
  293|      0|                     << "body";
  294|      0|            }
  295|      0|          } else {
  296|       |            // Debug info extinst opcodes other than DebugScope, DebugNoScope,
  297|       |            // DebugDeclare, DebugValue must be placed between section 9 (types,
  298|       |            // constants, global variables) and section 10 (function
  299|       |            // declarations).
  300|      0|            if (_.current_layout_section() < kLayoutTypes ||
  ------------------
  |  Branch (300:17): [True: 0, False: 0]
  ------------------
  301|      0|                _.current_layout_section() >= kLayoutFunctionDeclarations) {
  ------------------
  |  Branch (301:17): [True: 0, False: 0]
  ------------------
  302|      0|              return _.diag(SPV_ERROR_INVALID_LAYOUT, inst)
  303|      0|                     << "Debug info extension instructions other than "
  304|      0|                     << "DebugScope, DebugNoScope, DebugDeclare, DebugValue "
  305|      0|                     << "must appear between section 9 (types, constants, "
  306|      0|                     << "global variables) and section 10 (function "
  307|      0|                     << "declarations)";
  308|      0|            }
  309|      0|          }
  310|  3.42k|        } else if (spvExtInstIsNonSemantic(inst->ext_inst_type())) {
  ------------------
  |  Branch (310:20): [True: 7, False: 3.42k]
  ------------------
  311|       |          // non-semantic extinst opcodes are allowed beginning in the types
  312|       |          // section, but must either be placed outside a function declaration,
  313|       |          // or inside a block.
  314|      7|          if (_.current_layout_section() < kLayoutTypes) {
  ------------------
  |  Branch (314:15): [True: 0, False: 7]
  ------------------
  315|      0|            return _.diag(SPV_ERROR_INVALID_LAYOUT, inst)
  316|      0|                   << "Non-semantic OpExtInst must not appear before types "
  317|      0|                   << "section";
  318|      7|          } else if (_.in_function_body() && _.in_block() == false) {
  ------------------
  |  Branch (318:22): [True: 6, False: 1]
  |  Branch (318:46): [True: 1, False: 5]
  ------------------
  319|      1|            return _.diag(SPV_ERROR_INVALID_LAYOUT, inst)
  320|      1|                   << "Non-semantic OpExtInst within function definition must "
  321|      1|                      "appear in a block";
  322|      1|          }
  323|  3.42k|        } else {
  324|       |          // otherwise they must be used in a block
  325|  3.42k|          if (_.in_block() == false) {
  ------------------
  |  Branch (325:15): [True: 0, False: 3.42k]
  ------------------
  326|      0|            return _.diag(SPV_ERROR_INVALID_LAYOUT, inst)
  327|      0|                   << spvOpcodeString(opcode) << " must appear in a block";
  328|      0|          }
  329|  3.42k|        }
  330|  3.42k|        break;
  331|       |
  332|   213k|      default:
  ------------------
  |  Branch (332:7): [True: 213k, False: 64.9k]
  ------------------
  333|   213k|        if (_.current_layout_section() == kLayoutFunctionDeclarations &&
  ------------------
  |  Branch (333:13): [True: 0, False: 213k]
  ------------------
  334|   213k|            _.in_function_body()) {
  ------------------
  |  Branch (334:13): [True: 0, False: 0]
  ------------------
  335|      0|          return _.diag(SPV_ERROR_INVALID_LAYOUT, inst)
  336|      0|                 << "A function must begin with a label";
  337|   213k|        } else {
  338|   213k|          if (_.in_block() == false) {
  ------------------
  |  Branch (338:15): [True: 45, False: 213k]
  ------------------
  339|     45|            return _.diag(SPV_ERROR_INVALID_LAYOUT, inst)
  340|     45|                   << spvOpcodeString(opcode) << " must appear in a block";
  341|     45|          }
  342|   213k|        }
  343|   213k|        break;
  344|   278k|    }
  345|   278k|  } else {
  346|     11|    return _.diag(SPV_ERROR_INVALID_LAYOUT, inst)
  347|     11|           << spvOpcodeString(opcode)
  348|     11|           << " cannot appear in a function declaration";
  349|     11|  }
  350|   278k|  return SPV_SUCCESS;
  351|   278k|}

_ZN8spvtools3val12LiteralsPassERNS0_17ValidationState_tEPKNS0_11InstructionE:
   67|   285k|spv_result_t LiteralsPass(ValidationState_t& _, const Instruction* inst) {
   68|       |  // For every operand that is a literal number
   69|   956k|  for (size_t i = 0; i < inst->operands().size(); i++) {
  ------------------
  |  Branch (69:22): [True: 671k, False: 285k]
  ------------------
   70|   671k|    const spv_parsed_operand_t& operand = inst->operand(i);
   71|   671k|    if (!IsLiteralNumber(operand)) continue;
  ------------------
  |  Branch (71:9): [True: 633k, False: 38.0k]
  ------------------
   72|       |
   73|       |    // The upper bits are always in the last word (little-endian)
   74|  38.0k|    int last_index = operand.offset + operand.num_words - 1;
   75|  38.0k|    const uint32_t upper_word = inst->word(last_index);
   76|       |
   77|       |    // TODO(jcaraban): is the |word size| defined in some header?
   78|  38.0k|    const uint32_t word_size = 32;
   79|  38.0k|    uint32_t bit_width = operand.number_bit_width;
   80|       |
   81|       |    // Bit widths that are a multiple of the word size have no upper bits
   82|  38.0k|    const auto remaining_value_bits = bit_width % word_size;
   83|  38.0k|    if (remaining_value_bits == 0) continue;
  ------------------
  |  Branch (83:9): [True: 38.0k, False: 24]
  ------------------
   84|       |
   85|     24|    const bool signedness = operand.number_kind == SPV_NUMBER_SIGNED_INT;
   86|       |
   87|     24|    if (!VerifyUpperBits(upper_word, remaining_value_bits, signedness)) {
  ------------------
  |  Branch (87:9): [True: 7, False: 17]
  ------------------
   88|      7|      return _.diag(SPV_ERROR_INVALID_VALUE, inst)
   89|      7|             << "The high-order bits of a literal number in instruction <id> "
   90|      7|             << inst->id() << " must be 0 for a floating-point type, "
   91|      7|             << "or 0 for an integer type with Signedness of 0, "
   92|      7|             << "or sign extended when Signedness is 1";
   93|      7|    }
   94|     24|  }
   95|   285k|  return SPV_SUCCESS;
   96|   285k|}
validate_literals.cpp:_ZN8spvtools3val12_GLOBAL__N_115IsLiteralNumberERK20spv_parsed_operand_t:
   31|   671k|bool IsLiteralNumber(const spv_parsed_operand_t& operand) {
   32|   671k|  switch (operand.number_kind) {
   33|  10.7k|    case SPV_NUMBER_SIGNED_INT:
  ------------------
  |  Branch (33:5): [True: 10.7k, False: 660k]
  ------------------
   34|  34.8k|    case SPV_NUMBER_UNSIGNED_INT:
  ------------------
  |  Branch (34:5): [True: 24.1k, False: 647k]
  ------------------
   35|  38.0k|    case SPV_NUMBER_FLOATING:
  ------------------
  |  Branch (35:5): [True: 3.21k, False: 668k]
  ------------------
   36|  38.0k|      return true;
   37|   633k|    default:
  ------------------
  |  Branch (37:5): [True: 633k, False: 38.0k]
  ------------------
   38|   633k|      return false;
   39|   671k|  }
   40|   671k|}
validate_literals.cpp:_ZN8spvtools3val12_GLOBAL__N_115VerifyUpperBitsEjjb:
   44|     24|bool VerifyUpperBits(uint32_t word, uint32_t width, bool signed_int) {
   45|     24|  assert(width < 32);
   46|      0|  assert(0 < width);
   47|      0|  const uint32_t upper_mask = 0xFFFFFFFFu << width;
   48|     24|  const uint32_t upper_bits = word & upper_mask;
   49|       |
   50|     24|  bool result = false;
   51|     24|  if (signed_int) {
  ------------------
  |  Branch (51:7): [True: 16, False: 8]
  ------------------
   52|     16|    const uint32_t sign_bit = word & (1u << (width - 1));
   53|     16|    if (sign_bit) {
  ------------------
  |  Branch (53:9): [True: 3, False: 13]
  ------------------
   54|      3|      result = upper_bits == upper_mask;
   55|     13|    } else {
   56|     13|      result = upper_bits == 0;
   57|     13|    }
   58|     16|  } else {
   59|      8|    result = upper_bits == 0;
   60|      8|  }
   61|     24|  return result;
   62|     24|}

_ZN8spvtools3val12LogicalsPassERNS0_17ValidationState_tEPKNS0_11InstructionE:
   28|   285k|spv_result_t LogicalsPass(ValidationState_t& _, const Instruction* inst) {
   29|   285k|  const spv::Op opcode = inst->opcode();
   30|   285k|  const uint32_t result_type = inst->type_id();
   31|       |
   32|   285k|  switch (opcode) {
   33|      2|    case spv::Op::OpAny:
  ------------------
  |  Branch (33:5): [True: 2, False: 285k]
  ------------------
   34|      4|    case spv::Op::OpAll: {
  ------------------
  |  Branch (34:5): [True: 2, False: 285k]
  ------------------
   35|      4|      if (!_.IsBoolScalarType(result_type))
  ------------------
  |  Branch (35:11): [True: 1, False: 3]
  ------------------
   36|      1|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
   37|      1|               << "Expected bool scalar type as Result Type: "
   38|      1|               << spvOpcodeString(opcode);
   39|       |
   40|      3|      const uint32_t vector_type = _.GetOperandTypeId(inst, 2);
   41|      3|      if (!vector_type || !_.IsBoolVectorType(vector_type))
  ------------------
  |  Branch (41:11): [True: 0, False: 3]
  |  Branch (41:27): [True: 3, False: 0]
  ------------------
   42|      3|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
   43|      3|               << "Expected operand to be vector bool: "
   44|      3|               << spvOpcodeString(opcode);
   45|       |
   46|      0|      break;
   47|      3|    }
   48|       |
   49|     85|    case spv::Op::OpIsNan:
  ------------------
  |  Branch (49:5): [True: 85, False: 285k]
  ------------------
   50|    100|    case spv::Op::OpIsInf:
  ------------------
  |  Branch (50:5): [True: 15, False: 285k]
  ------------------
   51|    100|    case spv::Op::OpIsFinite:
  ------------------
  |  Branch (51:5): [True: 0, False: 285k]
  ------------------
   52|    100|    case spv::Op::OpIsNormal:
  ------------------
  |  Branch (52:5): [True: 0, False: 285k]
  ------------------
   53|    101|    case spv::Op::OpSignBitSet: {
  ------------------
  |  Branch (53:5): [True: 1, False: 285k]
  ------------------
   54|    101|      if (!_.IsBoolScalarType(result_type) && !_.IsBoolVectorType(result_type))
  ------------------
  |  Branch (54:11): [True: 6, False: 95]
  |  Branch (54:47): [True: 6, False: 0]
  ------------------
   55|      6|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
   56|      6|               << "Expected bool scalar or vector type as Result Type: "
   57|      6|               << spvOpcodeString(opcode);
   58|       |
   59|     95|      const uint32_t operand_type = _.GetOperandTypeId(inst, 2);
   60|     95|      if (!operand_type || (!_.IsFloatScalarType(operand_type) &&
  ------------------
  |  Branch (60:11): [True: 0, False: 95]
  |  Branch (60:29): [True: 2, False: 93]
  ------------------
   61|     95|                            !_.IsFloatVectorType(operand_type)))
  ------------------
  |  Branch (61:29): [True: 2, False: 0]
  ------------------
   62|      2|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
   63|      2|               << "Expected operand to be scalar or vector float: "
   64|      2|               << spvOpcodeString(opcode);
   65|       |
   66|     93|      if (_.GetDimension(result_type) != _.GetDimension(operand_type))
  ------------------
  |  Branch (66:11): [True: 0, False: 93]
  ------------------
   67|      0|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
   68|      0|               << "Expected vector sizes of Result Type and the operand to be "
   69|      0|                  "equal: "
   70|      0|               << spvOpcodeString(opcode);
   71|       |
   72|     93|      break;
   73|     93|    }
   74|       |
   75|     93|    case spv::Op::OpFOrdEqual:
  ------------------
  |  Branch (75:5): [True: 4, False: 285k]
  ------------------
   76|     13|    case spv::Op::OpFUnordEqual:
  ------------------
  |  Branch (76:5): [True: 9, False: 285k]
  ------------------
   77|     19|    case spv::Op::OpFOrdNotEqual:
  ------------------
  |  Branch (77:5): [True: 6, False: 285k]
  ------------------
   78|     21|    case spv::Op::OpFUnordNotEqual:
  ------------------
  |  Branch (78:5): [True: 2, False: 285k]
  ------------------
   79|    429|    case spv::Op::OpFOrdLessThan:
  ------------------
  |  Branch (79:5): [True: 408, False: 285k]
  ------------------
   80|    435|    case spv::Op::OpFUnordLessThan:
  ------------------
  |  Branch (80:5): [True: 6, False: 285k]
  ------------------
   81|    618|    case spv::Op::OpFOrdGreaterThan:
  ------------------
  |  Branch (81:5): [True: 183, False: 285k]
  ------------------
   82|    630|    case spv::Op::OpFUnordGreaterThan:
  ------------------
  |  Branch (82:5): [True: 12, False: 285k]
  ------------------
   83|    694|    case spv::Op::OpFOrdLessThanEqual:
  ------------------
  |  Branch (83:5): [True: 64, False: 285k]
  ------------------
   84|    708|    case spv::Op::OpFUnordLessThanEqual:
  ------------------
  |  Branch (84:5): [True: 14, False: 285k]
  ------------------
   85|    756|    case spv::Op::OpFOrdGreaterThanEqual:
  ------------------
  |  Branch (85:5): [True: 48, False: 285k]
  ------------------
   86|    778|    case spv::Op::OpFUnordGreaterThanEqual:
  ------------------
  |  Branch (86:5): [True: 22, False: 285k]
  ------------------
   87|    778|    case spv::Op::OpLessOrGreater:
  ------------------
  |  Branch (87:5): [True: 0, False: 285k]
  ------------------
   88|    779|    case spv::Op::OpOrdered:
  ------------------
  |  Branch (88:5): [True: 1, False: 285k]
  ------------------
   89|    779|    case spv::Op::OpUnordered: {
  ------------------
  |  Branch (89:5): [True: 0, False: 285k]
  ------------------
   90|    779|      if (!_.IsBoolScalarType(result_type) && !_.IsBoolVectorType(result_type))
  ------------------
  |  Branch (90:11): [True: 7, False: 772]
  |  Branch (90:47): [True: 7, False: 0]
  ------------------
   91|      7|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
   92|      7|               << "Expected bool scalar or vector type as Result Type: "
   93|      7|               << spvOpcodeString(opcode);
   94|       |
   95|    772|      const uint32_t left_operand_type = _.GetOperandTypeId(inst, 2);
   96|    772|      if (!left_operand_type || (!_.IsFloatScalarType(left_operand_type) &&
  ------------------
  |  Branch (96:11): [True: 0, False: 772]
  |  Branch (96:34): [True: 4, False: 768]
  ------------------
   97|    772|                                 !_.IsFloatVectorType(left_operand_type)))
  ------------------
  |  Branch (97:34): [True: 2, False: 2]
  ------------------
   98|      2|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
   99|      2|               << "Expected operands to be scalar or vector float: "
  100|      2|               << spvOpcodeString(opcode);
  101|       |
  102|    770|      if (_.GetDimension(result_type) != _.GetDimension(left_operand_type))
  ------------------
  |  Branch (102:11): [True: 2, False: 768]
  ------------------
  103|      2|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
  104|      2|               << "Expected vector sizes of Result Type and the operands to be "
  105|      2|                  "equal: "
  106|      2|               << spvOpcodeString(opcode);
  107|       |
  108|    768|      if (left_operand_type != _.GetOperandTypeId(inst, 3))
  ------------------
  |  Branch (108:11): [True: 1, False: 767]
  ------------------
  109|      1|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
  110|      1|               << "Expected left and right operands to have the same type: "
  111|      1|               << spvOpcodeString(opcode);
  112|       |
  113|    767|      break;
  114|    768|    }
  115|       |
  116|    767|    case spv::Op::OpLogicalEqual:
  ------------------
  |  Branch (116:5): [True: 1, False: 285k]
  ------------------
  117|      1|    case spv::Op::OpLogicalNotEqual:
  ------------------
  |  Branch (117:5): [True: 0, False: 285k]
  ------------------
  118|      1|    case spv::Op::OpLogicalOr:
  ------------------
  |  Branch (118:5): [True: 0, False: 285k]
  ------------------
  119|    138|    case spv::Op::OpLogicalAnd: {
  ------------------
  |  Branch (119:5): [True: 137, False: 285k]
  ------------------
  120|    138|      if (!_.IsBoolScalarType(result_type) && !_.IsBoolVectorType(result_type))
  ------------------
  |  Branch (120:11): [True: 0, False: 138]
  |  Branch (120:47): [True: 0, False: 0]
  ------------------
  121|      0|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
  122|      0|               << "Expected bool scalar or vector type as Result Type: "
  123|      0|               << spvOpcodeString(opcode);
  124|       |
  125|    138|      if (result_type != _.GetOperandTypeId(inst, 2) ||
  ------------------
  |  Branch (125:11): [True: 2, False: 136]
  ------------------
  126|    138|          result_type != _.GetOperandTypeId(inst, 3))
  ------------------
  |  Branch (126:11): [True: 0, False: 136]
  ------------------
  127|      2|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
  128|      2|               << "Expected both operands to be of Result Type: "
  129|      2|               << spvOpcodeString(opcode);
  130|       |
  131|    136|      break;
  132|    138|    }
  133|       |
  134|    207|    case spv::Op::OpLogicalNot: {
  ------------------
  |  Branch (134:5): [True: 207, False: 285k]
  ------------------
  135|    207|      if (!_.IsBoolScalarType(result_type) && !_.IsBoolVectorType(result_type))
  ------------------
  |  Branch (135:11): [True: 0, False: 207]
  |  Branch (135:47): [True: 0, False: 0]
  ------------------
  136|      0|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
  137|      0|               << "Expected bool scalar or vector type as Result Type: "
  138|      0|               << spvOpcodeString(opcode);
  139|       |
  140|    207|      if (result_type != _.GetOperandTypeId(inst, 2))
  ------------------
  |  Branch (140:11): [True: 1, False: 206]
  ------------------
  141|      1|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
  142|      1|               << "Expected operand to be of Result Type: "
  143|      1|               << spvOpcodeString(opcode);
  144|       |
  145|    206|      break;
  146|    207|    }
  147|       |
  148|    468|    case spv::Op::OpSelect: {
  ------------------
  |  Branch (148:5): [True: 468, False: 285k]
  ------------------
  149|    468|      uint32_t dimension = 1;
  150|    468|      {
  151|    468|        const Instruction* type_inst = _.FindDef(result_type);
  152|    468|        assert(type_inst);
  153|       |
  154|      0|        const auto composites = _.features().select_between_composites;
  155|    468|        auto fail = [&_, composites, inst, opcode]() -> spv_result_t {
  156|    468|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
  157|    468|                 << "Expected scalar or "
  158|    468|                 << (composites ? "composite" : "vector")
  159|    468|                 << " type as Result Type: " << spvOpcodeString(opcode);
  160|    468|        };
  161|       |
  162|    468|        const spv::Op type_opcode = type_inst->opcode();
  163|    468|        switch (type_opcode) {
  164|      1|          case spv::Op::OpTypePointer: {
  ------------------
  |  Branch (164:11): [True: 1, False: 467]
  ------------------
  165|      1|            if (_.addressing_model() == spv::AddressingModel::Logical &&
  ------------------
  |  Branch (165:17): [True: 1, False: 0]
  ------------------
  166|      1|                !_.features().variable_pointers)
  ------------------
  |  Branch (166:17): [True: 1, False: 0]
  ------------------
  167|      1|              return _.diag(SPV_ERROR_INVALID_DATA, inst)
  168|      1|                     << "Using pointers with OpSelect requires capability "
  169|      1|                     << "VariablePointers or VariablePointersStorageBuffer";
  170|      0|            break;
  171|      1|          }
  172|       |
  173|      0|          case spv::Op::OpTypeSampledImage:
  ------------------
  |  Branch (173:11): [True: 0, False: 468]
  ------------------
  174|      0|          case spv::Op::OpTypeImage:
  ------------------
  |  Branch (174:11): [True: 0, False: 468]
  ------------------
  175|      0|          case spv::Op::OpTypeSampler: {
  ------------------
  |  Branch (175:11): [True: 0, False: 468]
  ------------------
  176|      0|            if (!_.HasCapability(spv::Capability::BindlessTextureNV))
  ------------------
  |  Branch (176:17): [True: 0, False: 0]
  ------------------
  177|      0|              return _.diag(SPV_ERROR_INVALID_DATA, inst)
  178|      0|                     << "Using image/sampler with OpSelect requires capability "
  179|      0|                     << "BindlessTextureNV";
  180|      0|            break;
  181|      0|          }
  182|       |
  183|      0|          case spv::Op::OpTypeVector: {
  ------------------
  |  Branch (183:11): [True: 0, False: 468]
  ------------------
  184|      0|            dimension = type_inst->word(3);
  185|      0|            break;
  186|      0|          }
  187|       |
  188|      3|          case spv::Op::OpTypeBool:
  ------------------
  |  Branch (188:11): [True: 3, False: 465]
  ------------------
  189|    372|          case spv::Op::OpTypeInt:
  ------------------
  |  Branch (189:11): [True: 369, False: 99]
  ------------------
  190|    466|          case spv::Op::OpTypeFloat: {
  ------------------
  |  Branch (190:11): [True: 94, False: 374]
  ------------------
  191|    466|            break;
  192|    372|          }
  193|       |
  194|       |          // Not RuntimeArray because of other rules.
  195|      0|          case spv::Op::OpTypeArray:
  ------------------
  |  Branch (195:11): [True: 0, False: 468]
  ------------------
  196|      1|          case spv::Op::OpTypeMatrix:
  ------------------
  |  Branch (196:11): [True: 1, False: 467]
  ------------------
  197|      1|          case spv::Op::OpTypeStruct: {
  ------------------
  |  Branch (197:11): [True: 0, False: 468]
  ------------------
  198|      1|            if (!composites) return fail();
  ------------------
  |  Branch (198:17): [True: 1, False: 0]
  ------------------
  199|      0|            break;
  200|      1|          }
  201|       |
  202|      0|          default:
  ------------------
  |  Branch (202:11): [True: 0, False: 468]
  ------------------
  203|      0|            return fail();
  204|    468|        }
  205|       |
  206|    466|        const uint32_t condition_type = _.GetOperandTypeId(inst, 2);
  207|    466|        const uint32_t left_type = _.GetOperandTypeId(inst, 3);
  208|    466|        const uint32_t right_type = _.GetOperandTypeId(inst, 4);
  209|       |
  210|    466|        if (!condition_type || (!_.IsBoolScalarType(condition_type) &&
  ------------------
  |  Branch (210:13): [True: 0, False: 466]
  |  Branch (210:33): [True: 0, False: 466]
  ------------------
  211|    466|                                !_.IsBoolVectorType(condition_type)))
  ------------------
  |  Branch (211:33): [True: 0, False: 0]
  ------------------
  212|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
  213|      0|                 << "Expected bool scalar or vector type as condition: "
  214|      0|                 << spvOpcodeString(opcode);
  215|       |
  216|    466|        if (_.GetDimension(condition_type) != dimension) {
  ------------------
  |  Branch (216:13): [True: 0, False: 466]
  ------------------
  217|       |          // If the condition is a vector type, then the result must also be a
  218|       |          // vector with matching dimensions. In SPIR-V 1.4, a scalar condition
  219|       |          // can be used to select between vector types. |composites| is a
  220|       |          // proxy for SPIR-V 1.4 functionality.
  221|      0|          if (!composites || _.IsBoolVectorType(condition_type)) {
  ------------------
  |  Branch (221:15): [True: 0, False: 0]
  |  Branch (221:30): [True: 0, False: 0]
  ------------------
  222|      0|            return _.diag(SPV_ERROR_INVALID_DATA, inst)
  223|      0|                   << "Expected vector sizes of Result Type and the condition "
  224|      0|                      "to be equal: "
  225|      0|                   << spvOpcodeString(opcode);
  226|      0|          }
  227|      0|        }
  228|       |
  229|    466|        if (result_type != left_type || result_type != right_type)
  ------------------
  |  Branch (229:13): [True: 1, False: 465]
  |  Branch (229:41): [True: 0, False: 465]
  ------------------
  230|      1|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
  231|      1|                 << "Expected both objects to be of Result Type: "
  232|      1|                 << spvOpcodeString(opcode);
  233|       |
  234|    465|        break;
  235|    466|      }
  236|    466|    }
  237|       |
  238|  2.61k|    case spv::Op::OpIEqual:
  ------------------
  |  Branch (238:5): [True: 2.61k, False: 282k]
  ------------------
  239|  3.09k|    case spv::Op::OpINotEqual:
  ------------------
  |  Branch (239:5): [True: 473, False: 285k]
  ------------------
  240|  3.13k|    case spv::Op::OpUGreaterThan:
  ------------------
  |  Branch (240:5): [True: 46, False: 285k]
  ------------------
  241|  3.29k|    case spv::Op::OpUGreaterThanEqual:
  ------------------
  |  Branch (241:5): [True: 160, False: 285k]
  ------------------
  242|  3.39k|    case spv::Op::OpULessThan:
  ------------------
  |  Branch (242:5): [True: 103, False: 285k]
  ------------------
  243|  3.55k|    case spv::Op::OpULessThanEqual:
  ------------------
  |  Branch (243:5): [True: 160, False: 285k]
  ------------------
  244|  4.06k|    case spv::Op::OpSGreaterThan:
  ------------------
  |  Branch (244:5): [True: 510, False: 285k]
  ------------------
  245|  4.30k|    case spv::Op::OpSGreaterThanEqual:
  ------------------
  |  Branch (245:5): [True: 237, False: 285k]
  ------------------
  246|  5.95k|    case spv::Op::OpSLessThan:
  ------------------
  |  Branch (246:5): [True: 1.65k, False: 283k]
  ------------------
  247|  8.09k|    case spv::Op::OpSLessThanEqual: {
  ------------------
  |  Branch (247:5): [True: 2.13k, False: 283k]
  ------------------
  248|  8.09k|      if (!_.IsBoolScalarType(result_type) && !_.IsBoolVectorType(result_type))
  ------------------
  |  Branch (248:11): [True: 7, False: 8.09k]
  |  Branch (248:47): [True: 7, False: 0]
  ------------------
  249|      7|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
  250|      7|               << "Expected bool scalar or vector type as Result Type: "
  251|      7|               << spvOpcodeString(opcode);
  252|       |
  253|  8.09k|      const uint32_t left_type = _.GetOperandTypeId(inst, 2);
  254|  8.09k|      const uint32_t right_type = _.GetOperandTypeId(inst, 3);
  255|       |
  256|  8.09k|      if (!left_type ||
  ------------------
  |  Branch (256:11): [True: 0, False: 8.09k]
  ------------------
  257|  8.09k|          (!_.IsIntScalarType(left_type) && !_.IsIntVectorType(left_type)))
  ------------------
  |  Branch (257:12): [True: 1, False: 8.09k]
  |  Branch (257:45): [True: 1, False: 0]
  ------------------
  258|      1|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
  259|      1|               << "Expected operands to be scalar or vector int: "
  260|      1|               << spvOpcodeString(opcode);
  261|       |
  262|  8.09k|      if (_.GetDimension(result_type) != _.GetDimension(left_type))
  ------------------
  |  Branch (262:11): [True: 0, False: 8.09k]
  ------------------
  263|      0|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
  264|      0|               << "Expected vector sizes of Result Type and the operands to be"
  265|      0|               << " equal: " << spvOpcodeString(opcode);
  266|       |
  267|  8.09k|      if (!right_type ||
  ------------------
  |  Branch (267:11): [True: 0, False: 8.09k]
  ------------------
  268|  8.09k|          (!_.IsIntScalarType(right_type) && !_.IsIntVectorType(right_type)))
  ------------------
  |  Branch (268:12): [True: 2, False: 8.08k]
  |  Branch (268:46): [True: 2, False: 0]
  ------------------
  269|      2|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
  270|      2|               << "Expected operands to be scalar or vector int: "
  271|      2|               << spvOpcodeString(opcode);
  272|       |
  273|  8.08k|      if (_.GetDimension(result_type) != _.GetDimension(right_type))
  ------------------
  |  Branch (273:11): [True: 0, False: 8.08k]
  ------------------
  274|      0|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
  275|      0|               << "Expected vector sizes of Result Type and the operands to be"
  276|      0|               << " equal: " << spvOpcodeString(opcode);
  277|       |
  278|  8.08k|      if (_.GetBitWidth(left_type) != _.GetBitWidth(right_type))
  ------------------
  |  Branch (278:11): [True: 0, False: 8.08k]
  ------------------
  279|      0|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
  280|      0|               << "Expected both operands to have the same component bit "
  281|      0|                  "width: "
  282|      0|               << spvOpcodeString(opcode);
  283|       |
  284|  8.08k|      break;
  285|  8.08k|    }
  286|       |
  287|   275k|    default:
  ------------------
  |  Branch (287:5): [True: 275k, False: 9.79k]
  ------------------
  288|   275k|      break;
  289|   285k|  }
  290|       |
  291|   285k|  return SPV_SUCCESS;
  292|   285k|}
validate_logicals.cpp:_ZZN8spvtools3val12LogicalsPassERNS0_17ValidationState_tEPKNS0_11InstructionEENK3$_0clEv:
  155|      1|        auto fail = [&_, composites, inst, opcode]() -> spv_result_t {
  156|      1|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
  157|      1|                 << "Expected scalar or "
  158|      1|                 << (composites ? "composite" : "vector")
  ------------------
  |  Branch (158:22): [True: 0, False: 1]
  ------------------
  159|      1|                 << " type as Result Type: " << spvOpcodeString(opcode);
  160|      1|        };

_ZN8spvtools3val10MemoryPassERNS0_17ValidationState_tEPKNS0_11InstructionE:
 1728|   286k|spv_result_t MemoryPass(ValidationState_t& _, const Instruction* inst) {
 1729|   286k|  switch (inst->opcode()) {
 1730|  7.09k|    case spv::Op::OpVariable:
  ------------------
  |  Branch (1730:5): [True: 7.09k, False: 278k]
  ------------------
 1731|  7.09k|      if (auto error = ValidateVariable(_, inst)) return error;
  ------------------
  |  Branch (1731:16): [True: 28, False: 7.07k]
  ------------------
 1732|  7.07k|      break;
 1733|  16.5k|    case spv::Op::OpLoad:
  ------------------
  |  Branch (1733:5): [True: 16.5k, False: 269k]
  ------------------
 1734|  16.5k|      if (auto error = ValidateLoad(_, inst)) return error;
  ------------------
  |  Branch (1734:16): [True: 14, False: 16.5k]
  ------------------
 1735|  16.5k|      break;
 1736|  34.1k|    case spv::Op::OpStore:
  ------------------
  |  Branch (1736:5): [True: 34.1k, False: 251k]
  ------------------
 1737|  34.1k|      if (auto error = ValidateStore(_, inst)) return error;
  ------------------
  |  Branch (1737:16): [True: 20, False: 34.1k]
  ------------------
 1738|  34.1k|      break;
 1739|  34.1k|    case spv::Op::OpCopyMemory:
  ------------------
  |  Branch (1739:5): [True: 17, False: 286k]
  ------------------
 1740|     17|    case spv::Op::OpCopyMemorySized:
  ------------------
  |  Branch (1740:5): [True: 0, False: 286k]
  ------------------
 1741|     17|      if (auto error = ValidateCopyMemory(_, inst)) return error;
  ------------------
  |  Branch (1741:16): [True: 7, False: 10]
  ------------------
 1742|     10|      break;
 1743|     10|    case spv::Op::OpPtrAccessChain:
  ------------------
  |  Branch (1743:5): [True: 5, False: 286k]
  ------------------
 1744|      5|      if (auto error = ValidatePtrAccessChain(_, inst)) return error;
  ------------------
  |  Branch (1744:16): [True: 2, False: 3]
  ------------------
 1745|      3|      break;
 1746|  11.1k|    case spv::Op::OpAccessChain:
  ------------------
  |  Branch (1746:5): [True: 11.1k, False: 274k]
  ------------------
 1747|  11.2k|    case spv::Op::OpInBoundsAccessChain:
  ------------------
  |  Branch (1747:5): [True: 101, False: 285k]
  ------------------
 1748|  11.2k|    case spv::Op::OpInBoundsPtrAccessChain:
  ------------------
  |  Branch (1748:5): [True: 4, False: 286k]
  ------------------
 1749|  11.2k|      if (auto error = ValidateAccessChain(_, inst)) return error;
  ------------------
  |  Branch (1749:16): [True: 26, False: 11.2k]
  ------------------
 1750|  11.2k|      break;
 1751|  11.2k|    case spv::Op::OpArrayLength:
  ------------------
  |  Branch (1751:5): [True: 2, False: 286k]
  ------------------
 1752|      2|      if (auto error = ValidateArrayLength(_, inst)) return error;
  ------------------
  |  Branch (1752:16): [True: 2, False: 0]
  ------------------
 1753|      0|      break;
 1754|      0|    case spv::Op::OpCooperativeMatrixLoadNV:
  ------------------
  |  Branch (1754:5): [True: 0, False: 286k]
  ------------------
 1755|      0|    case spv::Op::OpCooperativeMatrixStoreNV:
  ------------------
  |  Branch (1755:5): [True: 0, False: 286k]
  ------------------
 1756|      0|      if (auto error = ValidateCooperativeMatrixLoadStoreNV(_, inst))
  ------------------
  |  Branch (1756:16): [True: 0, False: 0]
  ------------------
 1757|      0|        return error;
 1758|      0|      break;
 1759|      0|    case spv::Op::OpCooperativeMatrixLengthNV:
  ------------------
  |  Branch (1759:5): [True: 0, False: 286k]
  ------------------
 1760|      0|      if (auto error = ValidateCooperativeMatrixLengthNV(_, inst)) return error;
  ------------------
  |  Branch (1760:16): [True: 0, False: 0]
  ------------------
 1761|      0|      break;
 1762|      0|    case spv::Op::OpPtrEqual:
  ------------------
  |  Branch (1762:5): [True: 0, False: 286k]
  ------------------
 1763|      0|    case spv::Op::OpPtrNotEqual:
  ------------------
  |  Branch (1763:5): [True: 0, False: 286k]
  ------------------
 1764|      2|    case spv::Op::OpPtrDiff:
  ------------------
  |  Branch (1764:5): [True: 2, False: 286k]
  ------------------
 1765|      2|      if (auto error = ValidatePtrComparison(_, inst)) return error;
  ------------------
  |  Branch (1765:16): [True: 2, False: 0]
  ------------------
 1766|      0|      break;
 1767|      3|    case spv::Op::OpImageTexelPointer:
  ------------------
  |  Branch (1767:5): [True: 3, False: 286k]
  ------------------
 1768|      3|    case spv::Op::OpGenericPtrMemSemantics:
  ------------------
  |  Branch (1768:5): [True: 0, False: 286k]
  ------------------
 1769|   216k|    default:
  ------------------
  |  Branch (1769:5): [True: 216k, False: 69.0k]
  ------------------
 1770|   216k|      break;
 1771|   286k|  }
 1772|       |
 1773|   285k|  return SPV_SUCCESS;
 1774|   286k|}
validate_memory.cpp:_ZN8spvtools3val12_GLOBAL__N_116ValidateVariableERNS0_17ValidationState_tEPKNS0_11InstructionE:
  404|  7.09k|spv_result_t ValidateVariable(ValidationState_t& _, const Instruction* inst) {
  405|  7.09k|  auto result_type = _.FindDef(inst->type_id());
  406|  7.09k|  if (!result_type || result_type->opcode() != spv::Op::OpTypePointer) {
  ------------------
  |  Branch (406:7): [True: 0, False: 7.09k]
  |  Branch (406:23): [True: 3, False: 7.09k]
  ------------------
  407|      3|    return _.diag(SPV_ERROR_INVALID_ID, inst)
  408|      3|           << "OpVariable Result Type <id> " << _.getIdName(inst->type_id())
  409|      3|           << " is not a pointer type.";
  410|      3|  }
  411|       |
  412|  7.09k|  const auto type_index = 2;
  413|  7.09k|  const auto value_id = result_type->GetOperandAs<uint32_t>(type_index);
  414|  7.09k|  auto value_type = _.FindDef(value_id);
  415|       |
  416|  7.09k|  const auto initializer_index = 3;
  417|  7.09k|  const auto storage_class_index = 2;
  418|  7.09k|  if (initializer_index < inst->operands().size()) {
  ------------------
  |  Branch (418:7): [True: 10, False: 7.08k]
  ------------------
  419|     10|    const auto initializer_id = inst->GetOperandAs<uint32_t>(initializer_index);
  420|     10|    const auto initializer = _.FindDef(initializer_id);
  421|     10|    const auto is_module_scope_var =
  422|     10|        initializer && (initializer->opcode() == spv::Op::OpVariable) &&
  ------------------
  |  Branch (422:9): [True: 10, False: 0]
  |  Branch (422:24): [True: 1, False: 9]
  ------------------
  423|     10|        (initializer->GetOperandAs<spv::StorageClass>(storage_class_index) !=
  ------------------
  |  Branch (423:9): [True: 1, False: 0]
  ------------------
  424|      1|         spv::StorageClass::Function);
  425|     10|    const auto is_constant =
  426|     10|        initializer && spvOpcodeIsConstant(initializer->opcode());
  ------------------
  |  Branch (426:9): [True: 10, False: 0]
  |  Branch (426:24): [True: 9, False: 1]
  ------------------
  427|     10|    if (!initializer || !(is_constant || is_module_scope_var)) {
  ------------------
  |  Branch (427:9): [True: 0, False: 10]
  |  Branch (427:27): [True: 9, False: 1]
  |  Branch (427:42): [True: 1, False: 0]
  ------------------
  428|      0|      return _.diag(SPV_ERROR_INVALID_ID, inst)
  429|      0|             << "OpVariable Initializer <id> " << _.getIdName(initializer_id)
  430|      0|             << " is not a constant or module-scope variable.";
  431|      0|    }
  432|     10|    if (initializer->type_id() != value_id) {
  ------------------
  |  Branch (432:9): [True: 1, False: 9]
  ------------------
  433|      1|      return _.diag(SPV_ERROR_INVALID_ID, inst)
  434|      1|             << "Initializer type must match the type pointed to by the Result "
  435|      1|                "Type";
  436|      1|    }
  437|     10|  }
  438|       |
  439|  7.09k|  auto storage_class =
  440|  7.09k|      inst->GetOperandAs<spv::StorageClass>(storage_class_index);
  441|  7.09k|  if (storage_class != spv::StorageClass::Workgroup &&
  ------------------
  |  Branch (441:7): [True: 7.07k, False: 16]
  ------------------
  442|  7.09k|      storage_class != spv::StorageClass::CrossWorkgroup &&
  ------------------
  |  Branch (442:7): [True: 7.07k, False: 4]
  ------------------
  443|  7.09k|      storage_class != spv::StorageClass::Private &&
  ------------------
  |  Branch (443:7): [True: 6.74k, False: 329]
  ------------------
  444|  7.09k|      storage_class != spv::StorageClass::Function &&
  ------------------
  |  Branch (444:7): [True: 2.15k, False: 4.59k]
  ------------------
  445|  7.09k|      storage_class != spv::StorageClass::RayPayloadKHR &&
  ------------------
  |  Branch (445:7): [True: 2.15k, False: 0]
  ------------------
  446|  7.09k|      storage_class != spv::StorageClass::IncomingRayPayloadKHR &&
  ------------------
  |  Branch (446:7): [True: 2.15k, False: 0]
  ------------------
  447|  7.09k|      storage_class != spv::StorageClass::HitAttributeKHR &&
  ------------------
  |  Branch (447:7): [True: 2.15k, False: 0]
  ------------------
  448|  7.09k|      storage_class != spv::StorageClass::CallableDataKHR &&
  ------------------
  |  Branch (448:7): [True: 2.15k, False: 0]
  ------------------
  449|  7.09k|      storage_class != spv::StorageClass::IncomingCallableDataKHR &&
  ------------------
  |  Branch (449:7): [True: 2.15k, False: 0]
  ------------------
  450|  7.09k|      storage_class != spv::StorageClass::TaskPayloadWorkgroupEXT &&
  ------------------
  |  Branch (450:7): [True: 2.15k, False: 0]
  ------------------
  451|  7.09k|      storage_class != spv::StorageClass::HitObjectAttributeNV) {
  ------------------
  |  Branch (451:7): [True: 2.15k, False: 0]
  ------------------
  452|  2.15k|    bool storage_input_or_output = storage_class == spv::StorageClass::Input ||
  ------------------
  |  Branch (452:36): [True: 524, False: 1.63k]
  ------------------
  453|  2.15k|                                   storage_class == spv::StorageClass::Output;
  ------------------
  |  Branch (453:36): [True: 773, False: 858]
  ------------------
  454|  2.15k|    bool builtin = false;
  455|  2.15k|    if (storage_input_or_output) {
  ------------------
  |  Branch (455:9): [True: 1.29k, False: 858]
  ------------------
  456|  2.28k|      for (const Decoration& decoration : _.id_decorations(inst->id())) {
  ------------------
  |  Branch (456:41): [True: 2.28k, False: 1.18k]
  ------------------
  457|  2.28k|        if (decoration.dec_type() == spv::Decoration::BuiltIn) {
  ------------------
  |  Branch (457:13): [True: 117, False: 2.16k]
  ------------------
  458|    117|          builtin = true;
  459|    117|          break;
  460|    117|        }
  461|  2.28k|      }
  462|  1.29k|    }
  463|  2.15k|    if (!builtin &&
  ------------------
  |  Branch (463:9): [True: 2.03k, False: 117]
  ------------------
  464|  2.15k|        ContainsInvalidBool(_, value_type, storage_input_or_output)) {
  ------------------
  |  Branch (464:9): [True: 1, False: 2.03k]
  ------------------
  465|      1|      if (storage_input_or_output) {
  ------------------
  |  Branch (465:11): [True: 0, False: 1]
  ------------------
  466|      0|        return _.diag(SPV_ERROR_INVALID_ID, inst)
  467|      0|               << _.VkErrorID(7290)
  468|      0|               << "If OpTypeBool is stored in conjunction with OpVariable "
  469|      0|                  "using Input or Output Storage Classes it requires a BuiltIn "
  470|      0|                  "decoration";
  471|       |
  472|      1|      } else {
  473|      1|        return _.diag(SPV_ERROR_INVALID_ID, inst)
  474|      1|               << "If OpTypeBool is stored in conjunction with OpVariable, it "
  475|      1|                  "can only be used with non-externally visible shader Storage "
  476|      1|                  "Classes: Workgroup, CrossWorkgroup, Private, Function, "
  477|      1|                  "Input, Output, RayPayloadKHR, IncomingRayPayloadKHR, "
  478|      1|                  "HitAttributeKHR, CallableDataKHR, or "
  479|      1|                  "IncomingCallableDataKHR";
  480|      1|      }
  481|      1|    }
  482|  2.15k|  }
  483|       |
  484|  7.09k|  if (!_.IsValidStorageClass(storage_class)) {
  ------------------
  |  Branch (484:7): [True: 0, False: 7.09k]
  ------------------
  485|      0|    return _.diag(SPV_ERROR_INVALID_BINARY, inst)
  486|      0|           << _.VkErrorID(4643)
  487|      0|           << "Invalid storage class for target environment";
  488|      0|  }
  489|       |
  490|  7.09k|  if (storage_class == spv::StorageClass::Generic) {
  ------------------
  |  Branch (490:7): [True: 1, False: 7.09k]
  ------------------
  491|      1|    return _.diag(SPV_ERROR_INVALID_BINARY, inst)
  492|      1|           << "OpVariable storage class cannot be Generic";
  493|      1|  }
  494|       |
  495|  7.09k|  if (inst->function() && storage_class != spv::StorageClass::Function) {
  ------------------
  |  Branch (495:7): [True: 4.59k, False: 2.49k]
  |  Branch (495:27): [True: 4, False: 4.59k]
  ------------------
  496|      4|    return _.diag(SPV_ERROR_INVALID_LAYOUT, inst)
  497|      4|           << "Variables must have a function[7] storage class inside"
  498|      4|              " of a function";
  499|      4|  }
  500|       |
  501|  7.08k|  if (!inst->function() && storage_class == spv::StorageClass::Function) {
  ------------------
  |  Branch (501:7): [True: 2.49k, False: 4.59k]
  |  Branch (501:28): [True: 0, False: 2.49k]
  ------------------
  502|      0|    return _.diag(SPV_ERROR_INVALID_LAYOUT, inst)
  503|      0|           << "Variables can not have a function[7] storage class "
  504|      0|              "outside of a function";
  505|      0|  }
  506|       |
  507|       |  // SPIR-V 3.32.8: Check that pointer type and variable type have the same
  508|       |  // storage class.
  509|  7.08k|  const auto result_storage_class_index = 1;
  510|  7.08k|  const auto result_storage_class =
  511|  7.08k|      result_type->GetOperandAs<spv::StorageClass>(result_storage_class_index);
  512|  7.08k|  if (storage_class != result_storage_class) {
  ------------------
  |  Branch (512:7): [True: 17, False: 7.07k]
  ------------------
  513|     17|    return _.diag(SPV_ERROR_INVALID_ID, inst)
  514|     17|           << "From SPIR-V spec, section 3.32.8 on OpVariable:\n"
  515|     17|           << "Its Storage Class operand must be the same as the Storage Class "
  516|     17|           << "operand of the result type.";
  517|     17|  }
  518|       |
  519|       |  // Variable pointer related restrictions.
  520|  7.07k|  const auto pointee = _.FindDef(result_type->word(3));
  521|  7.07k|  if (_.addressing_model() == spv::AddressingModel::Logical &&
  ------------------
  |  Branch (521:7): [True: 7.04k, False: 23]
  ------------------
  522|  7.07k|      !_.options()->relax_logical_pointer) {
  ------------------
  |  Branch (522:7): [True: 7.04k, False: 0]
  ------------------
  523|       |    // VariablePointersStorageBuffer is implied by VariablePointers.
  524|  7.04k|    if (pointee->opcode() == spv::Op::OpTypePointer) {
  ------------------
  |  Branch (524:9): [True: 0, False: 7.04k]
  ------------------
  525|      0|      if (!_.HasCapability(spv::Capability::VariablePointersStorageBuffer)) {
  ------------------
  |  Branch (525:11): [True: 0, False: 0]
  ------------------
  526|      0|        return _.diag(SPV_ERROR_INVALID_ID, inst)
  527|      0|               << "In Logical addressing, variables may not allocate a pointer "
  528|      0|               << "type";
  529|      0|      } else if (storage_class != spv::StorageClass::Function &&
  ------------------
  |  Branch (529:18): [True: 0, False: 0]
  ------------------
  530|      0|                 storage_class != spv::StorageClass::Private) {
  ------------------
  |  Branch (530:18): [True: 0, False: 0]
  ------------------
  531|      0|        return _.diag(SPV_ERROR_INVALID_ID, inst)
  532|      0|               << "In Logical addressing with variable pointers, variables "
  533|      0|               << "that allocate pointers must be in Function or Private "
  534|      0|               << "storage classes";
  535|      0|      }
  536|      0|    }
  537|  7.04k|  }
  538|       |
  539|  7.07k|  if (spvIsVulkanEnv(_.context()->target_env)) {
  ------------------
  |  Branch (539:7): [True: 0, False: 7.07k]
  ------------------
  540|       |    // Vulkan Push Constant Interface section: Check type of PushConstant
  541|       |    // variables.
  542|      0|    if (storage_class == spv::StorageClass::PushConstant) {
  ------------------
  |  Branch (542:9): [True: 0, False: 0]
  ------------------
  543|      0|      if (pointee->opcode() != spv::Op::OpTypeStruct) {
  ------------------
  |  Branch (543:11): [True: 0, False: 0]
  ------------------
  544|      0|        return _.diag(SPV_ERROR_INVALID_ID, inst)
  545|      0|               << _.VkErrorID(6808) << "PushConstant OpVariable <id> "
  546|      0|               << _.getIdName(inst->id()) << " has illegal type.\n"
  547|      0|               << "From Vulkan spec, Push Constant Interface section:\n"
  548|      0|               << "Such variables must be typed as OpTypeStruct";
  549|      0|      }
  550|      0|    }
  551|       |
  552|       |    // Vulkan Descriptor Set Interface: Check type of UniformConstant and
  553|       |    // Uniform variables.
  554|      0|    if (storage_class == spv::StorageClass::UniformConstant) {
  ------------------
  |  Branch (554:9): [True: 0, False: 0]
  ------------------
  555|      0|      if (!IsAllowedTypeOrArrayOfSame(
  ------------------
  |  Branch (555:11): [True: 0, False: 0]
  ------------------
  556|      0|              _, pointee,
  557|      0|              {spv::Op::OpTypeImage, spv::Op::OpTypeSampler,
  558|      0|               spv::Op::OpTypeSampledImage,
  559|      0|               spv::Op::OpTypeAccelerationStructureKHR})) {
  560|      0|        return _.diag(SPV_ERROR_INVALID_ID, inst)
  561|      0|               << _.VkErrorID(4655) << "UniformConstant OpVariable <id> "
  562|      0|               << _.getIdName(inst->id()) << " has illegal type.\n"
  563|      0|               << "Variables identified with the UniformConstant storage class "
  564|      0|               << "are used only as handles to refer to opaque resources. Such "
  565|      0|               << "variables must be typed as OpTypeImage, OpTypeSampler, "
  566|      0|               << "OpTypeSampledImage, OpTypeAccelerationStructureKHR, "
  567|      0|               << "or an array of one of these types.";
  568|      0|      }
  569|      0|    }
  570|       |
  571|      0|    if (storage_class == spv::StorageClass::Uniform) {
  ------------------
  |  Branch (571:9): [True: 0, False: 0]
  ------------------
  572|      0|      if (!IsAllowedTypeOrArrayOfSame(_, pointee, {spv::Op::OpTypeStruct})) {
  ------------------
  |  Branch (572:11): [True: 0, False: 0]
  ------------------
  573|      0|        return _.diag(SPV_ERROR_INVALID_ID, inst)
  574|      0|               << _.VkErrorID(6807) << "Uniform OpVariable <id> "
  575|      0|               << _.getIdName(inst->id()) << " has illegal type.\n"
  576|      0|               << "From Vulkan spec:\n"
  577|      0|               << "Variables identified with the Uniform storage class are "
  578|      0|               << "used to access transparent buffer backed resources. Such "
  579|      0|               << "variables must be typed as OpTypeStruct, or an array of "
  580|      0|               << "this type";
  581|      0|      }
  582|      0|    }
  583|       |
  584|      0|    if (storage_class == spv::StorageClass::StorageBuffer) {
  ------------------
  |  Branch (584:9): [True: 0, False: 0]
  ------------------
  585|      0|      if (!IsAllowedTypeOrArrayOfSame(_, pointee, {spv::Op::OpTypeStruct})) {
  ------------------
  |  Branch (585:11): [True: 0, False: 0]
  ------------------
  586|      0|        return _.diag(SPV_ERROR_INVALID_ID, inst)
  587|      0|               << _.VkErrorID(6807) << "StorageBuffer OpVariable <id> "
  588|      0|               << _.getIdName(inst->id()) << " has illegal type.\n"
  589|      0|               << "From Vulkan spec:\n"
  590|      0|               << "Variables identified with the StorageBuffer storage class "
  591|      0|                  "are used to access transparent buffer backed resources. "
  592|      0|                  "Such variables must be typed as OpTypeStruct, or an array "
  593|      0|                  "of this type";
  594|      0|      }
  595|      0|    }
  596|       |
  597|       |    // Check for invalid use of Invariant
  598|      0|    if (storage_class != spv::StorageClass::Input &&
  ------------------
  |  Branch (598:9): [True: 0, False: 0]
  ------------------
  599|      0|        storage_class != spv::StorageClass::Output) {
  ------------------
  |  Branch (599:9): [True: 0, False: 0]
  ------------------
  600|      0|      if (_.HasDecoration(inst->id(), spv::Decoration::Invariant)) {
  ------------------
  |  Branch (600:11): [True: 0, False: 0]
  ------------------
  601|      0|        return _.diag(SPV_ERROR_INVALID_ID, inst)
  602|      0|               << _.VkErrorID(4677)
  603|      0|               << "Variable decorated with Invariant must only be identified "
  604|      0|                  "with the Input or Output storage class in Vulkan "
  605|      0|                  "environment.";
  606|      0|      }
  607|       |      // Need to check if only the members in a struct are decorated
  608|      0|      if (value_type && value_type->opcode() == spv::Op::OpTypeStruct) {
  ------------------
  |  Branch (608:11): [True: 0, False: 0]
  |  Branch (608:25): [True: 0, False: 0]
  ------------------
  609|      0|        if (_.HasDecoration(value_id, spv::Decoration::Invariant)) {
  ------------------
  |  Branch (609:13): [True: 0, False: 0]
  ------------------
  610|      0|          return _.diag(SPV_ERROR_INVALID_ID, inst)
  611|      0|                 << _.VkErrorID(4677)
  612|      0|                 << "Variable struct member decorated with Invariant must only "
  613|      0|                    "be identified with the Input or Output storage class in "
  614|      0|                    "Vulkan environment.";
  615|      0|        }
  616|      0|      }
  617|      0|    }
  618|       |
  619|       |    // Initializers in Vulkan are only allowed in some storage clases
  620|      0|    if (inst->operands().size() > 3) {
  ------------------
  |  Branch (620:9): [True: 0, False: 0]
  ------------------
  621|      0|      if (storage_class == spv::StorageClass::Workgroup) {
  ------------------
  |  Branch (621:11): [True: 0, False: 0]
  ------------------
  622|      0|        auto init_id = inst->GetOperandAs<uint32_t>(3);
  623|      0|        auto init = _.FindDef(init_id);
  624|      0|        if (init->opcode() != spv::Op::OpConstantNull) {
  ------------------
  |  Branch (624:13): [True: 0, False: 0]
  ------------------
  625|      0|          return _.diag(SPV_ERROR_INVALID_ID, inst)
  626|      0|                 << _.VkErrorID(4734) << "OpVariable, <id> "
  627|      0|                 << _.getIdName(inst->id())
  628|      0|                 << ", initializers are limited to OpConstantNull in "
  629|      0|                    "Workgroup "
  630|      0|                    "storage class";
  631|      0|        }
  632|      0|      } else if (storage_class != spv::StorageClass::Output &&
  ------------------
  |  Branch (632:18): [True: 0, False: 0]
  ------------------
  633|      0|                 storage_class != spv::StorageClass::Private &&
  ------------------
  |  Branch (633:18): [True: 0, False: 0]
  ------------------
  634|      0|                 storage_class != spv::StorageClass::Function) {
  ------------------
  |  Branch (634:18): [True: 0, False: 0]
  ------------------
  635|      0|        return _.diag(SPV_ERROR_INVALID_ID, inst)
  636|      0|               << _.VkErrorID(4651) << "OpVariable, <id> "
  637|      0|               << _.getIdName(inst->id())
  638|      0|               << ", has a disallowed initializer & storage class "
  639|      0|               << "combination.\n"
  640|      0|               << "From " << spvLogStringForEnv(_.context()->target_env)
  641|      0|               << " spec:\n"
  642|      0|               << "Variable declarations that include initializers must have "
  643|      0|               << "one of the following storage classes: Output, Private, "
  644|      0|               << "Function or Workgroup";
  645|      0|      }
  646|      0|    }
  647|      0|  }
  648|       |
  649|  7.07k|  if (inst->operands().size() > 3) {
  ------------------
  |  Branch (649:7): [True: 9, False: 7.06k]
  ------------------
  650|      9|    if (storage_class == spv::StorageClass::TaskPayloadWorkgroupEXT) {
  ------------------
  |  Branch (650:9): [True: 0, False: 9]
  ------------------
  651|      0|      return _.diag(SPV_ERROR_INVALID_ID, inst)
  652|      0|             << "OpVariable, <id> " << _.getIdName(inst->id())
  653|      0|             << ", initializer are not allowed for TaskPayloadWorkgroupEXT";
  654|      0|    }
  655|      9|    if (storage_class == spv::StorageClass::Input) {
  ------------------
  |  Branch (655:9): [True: 0, False: 9]
  ------------------
  656|      0|      return _.diag(SPV_ERROR_INVALID_ID, inst)
  657|      0|             << "OpVariable, <id> " << _.getIdName(inst->id())
  658|      0|             << ", initializer are not allowed for Input";
  659|      0|    }
  660|      9|    if (storage_class == spv::StorageClass::HitObjectAttributeNV) {
  ------------------
  |  Branch (660:9): [True: 0, False: 9]
  ------------------
  661|      0|      return _.diag(SPV_ERROR_INVALID_ID, inst)
  662|      0|             << "OpVariable, <id> " << _.getIdName(inst->id())
  663|      0|             << ", initializer are not allowed for HitObjectAttributeNV";
  664|      0|    }
  665|      9|  }
  666|       |
  667|  7.07k|  if (storage_class == spv::StorageClass::PhysicalStorageBuffer) {
  ------------------
  |  Branch (667:7): [True: 0, False: 7.07k]
  ------------------
  668|      0|    return _.diag(SPV_ERROR_INVALID_ID, inst)
  669|      0|           << "PhysicalStorageBuffer must not be used with OpVariable.";
  670|      0|  }
  671|       |
  672|  7.07k|  auto pointee_base = pointee;
  673|  7.68k|  while (pointee_base->opcode() == spv::Op::OpTypeArray) {
  ------------------
  |  Branch (673:10): [True: 618, False: 7.07k]
  ------------------
  674|    618|    pointee_base = _.FindDef(pointee_base->GetOperandAs<uint32_t>(1u));
  675|    618|  }
  676|  7.07k|  if (pointee_base->opcode() == spv::Op::OpTypePointer) {
  ------------------
  |  Branch (676:7): [True: 5, False: 7.06k]
  ------------------
  677|      5|    if (pointee_base->GetOperandAs<spv::StorageClass>(1u) ==
  ------------------
  |  Branch (677:9): [True: 0, False: 5]
  ------------------
  678|      5|        spv::StorageClass::PhysicalStorageBuffer) {
  679|       |      // check for AliasedPointer/RestrictPointer
  680|      0|      bool foundAliased =
  681|      0|          _.HasDecoration(inst->id(), spv::Decoration::AliasedPointer);
  682|      0|      bool foundRestrict =
  683|      0|          _.HasDecoration(inst->id(), spv::Decoration::RestrictPointer);
  684|      0|      if (!foundAliased && !foundRestrict) {
  ------------------
  |  Branch (684:11): [True: 0, False: 0]
  |  Branch (684:28): [True: 0, False: 0]
  ------------------
  685|      0|        return _.diag(SPV_ERROR_INVALID_ID, inst)
  686|      0|               << "OpVariable " << inst->id()
  687|      0|               << ": expected AliasedPointer or RestrictPointer for "
  688|      0|               << "PhysicalStorageBuffer pointer.";
  689|      0|      }
  690|      0|      if (foundAliased && foundRestrict) {
  ------------------
  |  Branch (690:11): [True: 0, False: 0]
  |  Branch (690:27): [True: 0, False: 0]
  ------------------
  691|      0|        return _.diag(SPV_ERROR_INVALID_ID, inst)
  692|      0|               << "OpVariable " << inst->id()
  693|      0|               << ": can't specify both AliasedPointer and "
  694|      0|               << "RestrictPointer for PhysicalStorageBuffer pointer.";
  695|      0|      }
  696|      0|    }
  697|      5|  }
  698|       |
  699|       |  // Vulkan specific validation rules for OpTypeRuntimeArray
  700|  7.07k|  if (spvIsVulkanEnv(_.context()->target_env)) {
  ------------------
  |  Branch (700:7): [True: 0, False: 7.07k]
  ------------------
  701|       |    // OpTypeRuntimeArray should only ever be in a container like OpTypeStruct,
  702|       |    // so should never appear as a bare variable.
  703|       |    // Unless the module has the RuntimeDescriptorArrayEXT capability.
  704|      0|    if (value_type && value_type->opcode() == spv::Op::OpTypeRuntimeArray) {
  ------------------
  |  Branch (704:9): [True: 0, False: 0]
  |  Branch (704:23): [True: 0, False: 0]
  ------------------
  705|      0|      if (!_.HasCapability(spv::Capability::RuntimeDescriptorArrayEXT)) {
  ------------------
  |  Branch (705:11): [True: 0, False: 0]
  ------------------
  706|      0|        return _.diag(SPV_ERROR_INVALID_ID, inst)
  707|      0|               << _.VkErrorID(4680) << "OpVariable, <id> "
  708|      0|               << _.getIdName(inst->id())
  709|      0|               << ", is attempting to create memory for an illegal type, "
  710|      0|               << "OpTypeRuntimeArray.\nFor Vulkan OpTypeRuntimeArray can only "
  711|      0|               << "appear as the final member of an OpTypeStruct, thus cannot "
  712|      0|               << "be instantiated via OpVariable";
  713|      0|      } else {
  714|       |        // A bare variable OpTypeRuntimeArray is allowed in this context, but
  715|       |        // still need to check the storage class.
  716|      0|        if (storage_class != spv::StorageClass::StorageBuffer &&
  ------------------
  |  Branch (716:13): [True: 0, False: 0]
  ------------------
  717|      0|            storage_class != spv::StorageClass::Uniform &&
  ------------------
  |  Branch (717:13): [True: 0, False: 0]
  ------------------
  718|      0|            storage_class != spv::StorageClass::UniformConstant) {
  ------------------
  |  Branch (718:13): [True: 0, False: 0]
  ------------------
  719|      0|          return _.diag(SPV_ERROR_INVALID_ID, inst)
  720|      0|                 << _.VkErrorID(4680)
  721|      0|                 << "For Vulkan with RuntimeDescriptorArrayEXT, a variable "
  722|      0|                 << "containing OpTypeRuntimeArray must have storage class of "
  723|      0|                 << "StorageBuffer, Uniform, or UniformConstant.";
  724|      0|        }
  725|      0|      }
  726|      0|    }
  727|       |
  728|       |    // If an OpStruct has an OpTypeRuntimeArray somewhere within it, then it
  729|       |    // must either have the storage class StorageBuffer and be decorated
  730|       |    // with Block, or it must be in the Uniform storage class and be decorated
  731|       |    // as BufferBlock.
  732|      0|    if (value_type && value_type->opcode() == spv::Op::OpTypeStruct) {
  ------------------
  |  Branch (732:9): [True: 0, False: 0]
  |  Branch (732:23): [True: 0, False: 0]
  ------------------
  733|      0|      if (DoesStructContainRTA(_, value_type)) {
  ------------------
  |  Branch (733:11): [True: 0, False: 0]
  ------------------
  734|      0|        if (storage_class == spv::StorageClass::StorageBuffer ||
  ------------------
  |  Branch (734:13): [True: 0, False: 0]
  ------------------
  735|      0|            storage_class == spv::StorageClass::PhysicalStorageBuffer) {
  ------------------
  |  Branch (735:13): [True: 0, False: 0]
  ------------------
  736|      0|          if (!_.HasDecoration(value_id, spv::Decoration::Block)) {
  ------------------
  |  Branch (736:15): [True: 0, False: 0]
  ------------------
  737|      0|            return _.diag(SPV_ERROR_INVALID_ID, inst)
  738|      0|                   << _.VkErrorID(4680)
  739|      0|                   << "For Vulkan, an OpTypeStruct variable containing an "
  740|      0|                   << "OpTypeRuntimeArray must be decorated with Block if it "
  741|      0|                   << "has storage class StorageBuffer or "
  742|      0|                      "PhysicalStorageBuffer.";
  743|      0|          }
  744|      0|        } else if (storage_class == spv::StorageClass::Uniform) {
  ------------------
  |  Branch (744:20): [True: 0, False: 0]
  ------------------
  745|      0|          if (!_.HasDecoration(value_id, spv::Decoration::BufferBlock)) {
  ------------------
  |  Branch (745:15): [True: 0, False: 0]
  ------------------
  746|      0|            return _.diag(SPV_ERROR_INVALID_ID, inst)
  747|      0|                   << _.VkErrorID(4680)
  748|      0|                   << "For Vulkan, an OpTypeStruct variable containing an "
  749|      0|                   << "OpTypeRuntimeArray must be decorated with BufferBlock "
  750|      0|                   << "if it has storage class Uniform.";
  751|      0|          }
  752|      0|        } else {
  753|      0|          return _.diag(SPV_ERROR_INVALID_ID, inst)
  754|      0|                 << _.VkErrorID(4680)
  755|      0|                 << "For Vulkan, OpTypeStruct variables containing "
  756|      0|                 << "OpTypeRuntimeArray must have storage class of "
  757|      0|                 << "StorageBuffer, PhysicalStorageBuffer, or Uniform.";
  758|      0|        }
  759|      0|      }
  760|      0|    }
  761|      0|  }
  762|       |
  763|       |  // Cooperative matrix types can only be allocated in Function or Private
  764|  7.07k|  if ((storage_class != spv::StorageClass::Function &&
  ------------------
  |  Branch (764:8): [True: 2.48k, False: 4.59k]
  ------------------
  765|  7.07k|       storage_class != spv::StorageClass::Private) &&
  ------------------
  |  Branch (765:8): [True: 2.15k, False: 329]
  ------------------
  766|  7.07k|      ContainsCooperativeMatrix(_, pointee)) {
  ------------------
  |  Branch (766:7): [True: 0, False: 2.15k]
  ------------------
  767|      0|    return _.diag(SPV_ERROR_INVALID_ID, inst)
  768|      0|           << "Cooperative matrix types (or types containing them) can only be "
  769|      0|              "allocated "
  770|      0|           << "in Function or Private storage classes or as function "
  771|      0|              "parameters";
  772|      0|  }
  773|       |
  774|  7.07k|  if (_.HasCapability(spv::Capability::Shader)) {
  ------------------
  |  Branch (774:7): [True: 7.06k, False: 4]
  ------------------
  775|       |    // Don't allow variables containing 16-bit elements without the appropriate
  776|       |    // capabilities.
  777|  7.06k|    if ((!_.HasCapability(spv::Capability::Int16) &&
  ------------------
  |  Branch (777:10): [True: 7.05k, False: 12]
  ------------------
  778|  7.06k|         _.ContainsSizedIntOrFloatType(value_id, spv::Op::OpTypeInt, 16)) ||
  ------------------
  |  Branch (778:10): [True: 0, False: 7.05k]
  ------------------
  779|  7.06k|        (!_.HasCapability(spv::Capability::Float16) &&
  ------------------
  |  Branch (779:10): [True: 7.05k, False: 8]
  ------------------
  780|  7.06k|         _.ContainsSizedIntOrFloatType(value_id, spv::Op::OpTypeFloat, 16))) {
  ------------------
  |  Branch (780:10): [True: 1, False: 7.05k]
  ------------------
  781|      1|      auto underlying_type = value_type;
  782|      1|      while (underlying_type->opcode() == spv::Op::OpTypePointer) {
  ------------------
  |  Branch (782:14): [True: 0, False: 1]
  ------------------
  783|      0|        storage_class = underlying_type->GetOperandAs<spv::StorageClass>(1u);
  784|      0|        underlying_type =
  785|      0|            _.FindDef(underlying_type->GetOperandAs<uint32_t>(2u));
  786|      0|      }
  787|      1|      bool storage_class_ok = true;
  788|      1|      std::string sc_name = _.grammar().lookupOperandName(
  789|      1|          SPV_OPERAND_TYPE_STORAGE_CLASS, uint32_t(storage_class));
  790|      1|      switch (storage_class) {
  791|      0|        case spv::StorageClass::StorageBuffer:
  ------------------
  |  Branch (791:9): [True: 0, False: 1]
  ------------------
  792|      0|        case spv::StorageClass::PhysicalStorageBuffer:
  ------------------
  |  Branch (792:9): [True: 0, False: 1]
  ------------------
  793|      0|          if (!_.HasCapability(spv::Capability::StorageBuffer16BitAccess)) {
  ------------------
  |  Branch (793:15): [True: 0, False: 0]
  ------------------
  794|      0|            storage_class_ok = false;
  795|      0|          }
  796|      0|          break;
  797|      0|        case spv::StorageClass::Uniform:
  ------------------
  |  Branch (797:9): [True: 0, False: 1]
  ------------------
  798|      0|          if (!_.HasCapability(
  ------------------
  |  Branch (798:15): [True: 0, False: 0]
  ------------------
  799|      0|                  spv::Capability::UniformAndStorageBuffer16BitAccess)) {
  800|      0|            if (underlying_type->opcode() == spv::Op::OpTypeArray ||
  ------------------
  |  Branch (800:17): [True: 0, False: 0]
  ------------------
  801|      0|                underlying_type->opcode() == spv::Op::OpTypeRuntimeArray) {
  ------------------
  |  Branch (801:17): [True: 0, False: 0]
  ------------------
  802|      0|              underlying_type =
  803|      0|                  _.FindDef(underlying_type->GetOperandAs<uint32_t>(1u));
  804|      0|            }
  805|      0|            if (!_.HasCapability(spv::Capability::StorageBuffer16BitAccess) ||
  ------------------
  |  Branch (805:17): [True: 0, False: 0]
  ------------------
  806|      0|                !_.HasDecoration(underlying_type->id(),
  ------------------
  |  Branch (806:17): [True: 0, False: 0]
  ------------------
  807|      0|                                 spv::Decoration::BufferBlock)) {
  808|      0|              storage_class_ok = false;
  809|      0|            }
  810|      0|          }
  811|      0|          break;
  812|      0|        case spv::StorageClass::PushConstant:
  ------------------
  |  Branch (812:9): [True: 0, False: 1]
  ------------------
  813|      0|          if (!_.HasCapability(spv::Capability::StoragePushConstant16)) {
  ------------------
  |  Branch (813:15): [True: 0, False: 0]
  ------------------
  814|      0|            storage_class_ok = false;
  815|      0|          }
  816|      0|          break;
  817|      0|        case spv::StorageClass::Input:
  ------------------
  |  Branch (817:9): [True: 0, False: 1]
  ------------------
  818|      0|        case spv::StorageClass::Output:
  ------------------
  |  Branch (818:9): [True: 0, False: 1]
  ------------------
  819|      0|          if (!_.HasCapability(spv::Capability::StorageInputOutput16)) {
  ------------------
  |  Branch (819:15): [True: 0, False: 0]
  ------------------
  820|      0|            storage_class_ok = false;
  821|      0|          }
  822|      0|          break;
  823|      1|        case spv::StorageClass::Workgroup:
  ------------------
  |  Branch (823:9): [True: 1, False: 0]
  ------------------
  824|      1|          if (!_.HasCapability(
  ------------------
  |  Branch (824:15): [True: 1, False: 0]
  ------------------
  825|      1|                  spv::Capability::
  826|      1|                      WorkgroupMemoryExplicitLayout16BitAccessKHR)) {
  827|      1|            storage_class_ok = false;
  828|      1|          }
  829|      1|          break;
  830|      0|        default:
  ------------------
  |  Branch (830:9): [True: 0, False: 1]
  ------------------
  831|      0|          return _.diag(SPV_ERROR_INVALID_ID, inst)
  832|      0|                 << "Cannot allocate a variable containing a 16-bit type in "
  833|      0|                 << sc_name << " storage class";
  834|      1|      }
  835|      1|      if (!storage_class_ok) {
  ------------------
  |  Branch (835:11): [True: 1, False: 0]
  ------------------
  836|      1|        return _.diag(SPV_ERROR_INVALID_ID, inst)
  837|      1|               << "Allocating a variable containing a 16-bit element in "
  838|      1|               << sc_name << " storage class requires an additional capability";
  839|      1|      }
  840|      1|    }
  841|       |    // Don't allow variables containing 8-bit elements without the appropriate
  842|       |    // capabilities.
  843|  7.06k|    if (!_.HasCapability(spv::Capability::Int8) &&
  ------------------
  |  Branch (843:9): [True: 7.05k, False: 13]
  ------------------
  844|  7.06k|        _.ContainsSizedIntOrFloatType(value_id, spv::Op::OpTypeInt, 8)) {
  ------------------
  |  Branch (844:9): [True: 0, False: 7.05k]
  ------------------
  845|      0|      auto underlying_type = value_type;
  846|      0|      while (underlying_type->opcode() == spv::Op::OpTypePointer) {
  ------------------
  |  Branch (846:14): [True: 0, False: 0]
  ------------------
  847|      0|        storage_class = underlying_type->GetOperandAs<spv::StorageClass>(1u);
  848|      0|        underlying_type =
  849|      0|            _.FindDef(underlying_type->GetOperandAs<uint32_t>(2u));
  850|      0|      }
  851|      0|      bool storage_class_ok = true;
  852|      0|      std::string sc_name = _.grammar().lookupOperandName(
  853|      0|          SPV_OPERAND_TYPE_STORAGE_CLASS, uint32_t(storage_class));
  854|      0|      switch (storage_class) {
  855|      0|        case spv::StorageClass::StorageBuffer:
  ------------------
  |  Branch (855:9): [True: 0, False: 0]
  ------------------
  856|      0|        case spv::StorageClass::PhysicalStorageBuffer:
  ------------------
  |  Branch (856:9): [True: 0, False: 0]
  ------------------
  857|      0|          if (!_.HasCapability(spv::Capability::StorageBuffer8BitAccess)) {
  ------------------
  |  Branch (857:15): [True: 0, False: 0]
  ------------------
  858|      0|            storage_class_ok = false;
  859|      0|          }
  860|      0|          break;
  861|      0|        case spv::StorageClass::Uniform:
  ------------------
  |  Branch (861:9): [True: 0, False: 0]
  ------------------
  862|      0|          if (!_.HasCapability(
  ------------------
  |  Branch (862:15): [True: 0, False: 0]
  ------------------
  863|      0|                  spv::Capability::UniformAndStorageBuffer8BitAccess)) {
  864|      0|            if (underlying_type->opcode() == spv::Op::OpTypeArray ||
  ------------------
  |  Branch (864:17): [True: 0, False: 0]
  ------------------
  865|      0|                underlying_type->opcode() == spv::Op::OpTypeRuntimeArray) {
  ------------------
  |  Branch (865:17): [True: 0, False: 0]
  ------------------
  866|      0|              underlying_type =
  867|      0|                  _.FindDef(underlying_type->GetOperandAs<uint32_t>(1u));
  868|      0|            }
  869|      0|            if (!_.HasCapability(spv::Capability::StorageBuffer8BitAccess) ||
  ------------------
  |  Branch (869:17): [True: 0, False: 0]
  ------------------
  870|      0|                !_.HasDecoration(underlying_type->id(),
  ------------------
  |  Branch (870:17): [True: 0, False: 0]
  ------------------
  871|      0|                                 spv::Decoration::BufferBlock)) {
  872|      0|              storage_class_ok = false;
  873|      0|            }
  874|      0|          }
  875|      0|          break;
  876|      0|        case spv::StorageClass::PushConstant:
  ------------------
  |  Branch (876:9): [True: 0, False: 0]
  ------------------
  877|      0|          if (!_.HasCapability(spv::Capability::StoragePushConstant8)) {
  ------------------
  |  Branch (877:15): [True: 0, False: 0]
  ------------------
  878|      0|            storage_class_ok = false;
  879|      0|          }
  880|      0|          break;
  881|      0|        case spv::StorageClass::Workgroup:
  ------------------
  |  Branch (881:9): [True: 0, False: 0]
  ------------------
  882|      0|          if (!_.HasCapability(
  ------------------
  |  Branch (882:15): [True: 0, False: 0]
  ------------------
  883|      0|                  spv::Capability::
  884|      0|                      WorkgroupMemoryExplicitLayout8BitAccessKHR)) {
  885|      0|            storage_class_ok = false;
  886|      0|          }
  887|      0|          break;
  888|      0|        default:
  ------------------
  |  Branch (888:9): [True: 0, False: 0]
  ------------------
  889|      0|          return _.diag(SPV_ERROR_INVALID_ID, inst)
  890|      0|                 << "Cannot allocate a variable containing a 8-bit type in "
  891|      0|                 << sc_name << " storage class";
  892|      0|      }
  893|      0|      if (!storage_class_ok) {
  ------------------
  |  Branch (893:11): [True: 0, False: 0]
  ------------------
  894|      0|        return _.diag(SPV_ERROR_INVALID_ID, inst)
  895|      0|               << "Allocating a variable containing a 8-bit element in "
  896|      0|               << sc_name << " storage class requires an additional capability";
  897|      0|      }
  898|      0|    }
  899|  7.06k|  }
  900|       |
  901|  7.07k|  return SPV_SUCCESS;
  902|  7.07k|}
validate_memory.cpp:_ZN8spvtools3val12_GLOBAL__N_119ContainsInvalidBoolERNS0_17ValidationState_tEPKNS0_11InstructionEb:
  163|  4.73k|                         bool skip_builtin) {
  164|  4.73k|  if (skip_builtin) {
  ------------------
  |  Branch (164:7): [True: 2.35k, False: 2.37k]
  ------------------
  165|  4.86k|    for (const Decoration& decoration : _.id_decorations(storage->id())) {
  ------------------
  |  Branch (165:39): [True: 4.86k, False: 2.32k]
  ------------------
  166|  4.86k|      if (decoration.dec_type() == spv::Decoration::BuiltIn) return false;
  ------------------
  |  Branch (166:11): [True: 27, False: 4.84k]
  ------------------
  167|  4.86k|    }
  168|  2.35k|  }
  169|       |
  170|  4.70k|  const size_t elem_type_index = 1;
  171|  4.70k|  uint32_t elem_type_id;
  172|  4.70k|  Instruction* elem_type;
  173|       |
  174|  4.70k|  switch (storage->opcode()) {
  175|      1|    case spv::Op::OpTypeBool:
  ------------------
  |  Branch (175:5): [True: 1, False: 4.70k]
  ------------------
  176|      1|      return true;
  177|  1.43k|    case spv::Op::OpTypeVector:
  ------------------
  |  Branch (177:5): [True: 1.43k, False: 3.27k]
  ------------------
  178|  1.47k|    case spv::Op::OpTypeMatrix:
  ------------------
  |  Branch (178:5): [True: 33, False: 4.67k]
  ------------------
  179|  1.65k|    case spv::Op::OpTypeArray:
  ------------------
  |  Branch (179:5): [True: 185, False: 4.52k]
  ------------------
  180|  1.74k|    case spv::Op::OpTypeRuntimeArray:
  ------------------
  |  Branch (180:5): [True: 86, False: 4.62k]
  ------------------
  181|  1.74k|      elem_type_id = storage->GetOperandAs<uint32_t>(elem_type_index);
  182|  1.74k|      elem_type = _.FindDef(elem_type_id);
  183|  1.74k|      return ContainsInvalidBool(_, elem_type, skip_builtin);
  184|    924|    case spv::Op::OpTypeStruct:
  ------------------
  |  Branch (184:5): [True: 924, False: 3.78k]
  ------------------
  185|    924|      for (size_t member_type_index = 1;
  186|  1.87k|           member_type_index < storage->operands().size();
  ------------------
  |  Branch (186:12): [True: 956, False: 922]
  ------------------
  187|    956|           ++member_type_index) {
  188|    956|        auto member_type_id =
  189|    956|            storage->GetOperandAs<uint32_t>(member_type_index);
  190|    956|        auto member_type = _.FindDef(member_type_id);
  191|    956|        if (ContainsInvalidBool(_, member_type, skip_builtin)) return true;
  ------------------
  |  Branch (191:13): [True: 2, False: 954]
  ------------------
  192|    956|      }
  193|  2.96k|    default:
  ------------------
  |  Branch (193:5): [True: 2.04k, False: 2.66k]
  ------------------
  194|  2.96k|      break;
  195|  4.70k|  }
  196|  2.96k|  return false;
  197|  4.70k|}
validate_memory.cpp:_ZN8spvtools3val12_GLOBAL__N_125ContainsCooperativeMatrixERNS0_17ValidationState_tEPKNS0_11InstructionE:
  200|  3.48k|                               const Instruction* storage) {
  201|  3.48k|  const size_t elem_type_index = 1;
  202|  3.48k|  uint32_t elem_type_id;
  203|  3.48k|  Instruction* elem_type;
  204|       |
  205|  3.48k|  switch (storage->opcode()) {
  206|      0|    case spv::Op::OpTypeCooperativeMatrixNV:
  ------------------
  |  Branch (206:5): [True: 0, False: 3.48k]
  ------------------
  207|      0|      return true;
  208|    253|    case spv::Op::OpTypeArray:
  ------------------
  |  Branch (208:5): [True: 253, False: 3.23k]
  ------------------
  209|    336|    case spv::Op::OpTypeRuntimeArray:
  ------------------
  |  Branch (209:5): [True: 83, False: 3.40k]
  ------------------
  210|    336|      elem_type_id = storage->GetOperandAs<uint32_t>(elem_type_index);
  211|    336|      elem_type = _.FindDef(elem_type_id);
  212|    336|      return ContainsCooperativeMatrix(_, elem_type);
  213|    965|    case spv::Op::OpTypeStruct:
  ------------------
  |  Branch (213:5): [True: 965, False: 2.52k]
  ------------------
  214|    965|      for (size_t member_type_index = 1;
  215|  1.96k|           member_type_index < storage->operands().size();
  ------------------
  |  Branch (215:12): [True: 999, False: 965]
  ------------------
  216|    999|           ++member_type_index) {
  217|    999|        auto member_type_id =
  218|    999|            storage->GetOperandAs<uint32_t>(member_type_index);
  219|    999|        auto member_type = _.FindDef(member_type_id);
  220|    999|        if (ContainsCooperativeMatrix(_, member_type)) return true;
  ------------------
  |  Branch (220:13): [True: 0, False: 999]
  ------------------
  221|    999|      }
  222|    965|      break;
  223|  2.18k|    default:
  ------------------
  |  Branch (223:5): [True: 2.18k, False: 1.30k]
  ------------------
  224|  2.18k|      break;
  225|  3.48k|  }
  226|  3.15k|  return false;
  227|  3.48k|}
validate_memory.cpp:_ZN8spvtools3val12_GLOBAL__N_112ValidateLoadERNS0_17ValidationState_tEPKNS0_11InstructionE:
  904|  16.5k|spv_result_t ValidateLoad(ValidationState_t& _, const Instruction* inst) {
  905|  16.5k|  const auto result_type = _.FindDef(inst->type_id());
  906|  16.5k|  if (!result_type) {
  ------------------
  |  Branch (906:7): [True: 0, False: 16.5k]
  ------------------
  907|      0|    return _.diag(SPV_ERROR_INVALID_ID, inst)
  908|      0|           << "OpLoad Result Type <id> " << _.getIdName(inst->type_id())
  909|      0|           << " is not defined.";
  910|      0|  }
  911|       |
  912|  16.5k|  const auto pointer_index = 2;
  913|  16.5k|  const auto pointer_id = inst->GetOperandAs<uint32_t>(pointer_index);
  914|  16.5k|  const auto pointer = _.FindDef(pointer_id);
  915|  16.5k|  if (!pointer ||
  ------------------
  |  Branch (915:7): [True: 0, False: 16.5k]
  ------------------
  916|  16.5k|      ((_.addressing_model() == spv::AddressingModel::Logical) &&
  ------------------
  |  Branch (916:8): [True: 16.5k, False: 11]
  ------------------
  917|  16.5k|       ((!_.features().variable_pointers &&
  ------------------
  |  Branch (917:10): [True: 16.5k, False: 0]
  ------------------
  918|  16.5k|         !spvOpcodeReturnsLogicalPointer(pointer->opcode())) ||
  ------------------
  |  Branch (918:10): [True: 3, False: 16.5k]
  ------------------
  919|  16.5k|        (_.features().variable_pointers &&
  ------------------
  |  Branch (919:10): [True: 0, False: 16.5k]
  ------------------
  920|  16.5k|         !spvOpcodeReturnsLogicalVariablePointer(pointer->opcode()))))) {
  ------------------
  |  Branch (920:10): [True: 0, False: 0]
  ------------------
  921|      3|    return _.diag(SPV_ERROR_INVALID_ID, inst)
  922|      3|           << "OpLoad Pointer <id> " << _.getIdName(pointer_id)
  923|      3|           << " is not a logical pointer.";
  924|      3|  }
  925|       |
  926|  16.5k|  const auto pointer_type = _.FindDef(pointer->type_id());
  927|  16.5k|  if (!pointer_type || pointer_type->opcode() != spv::Op::OpTypePointer) {
  ------------------
  |  Branch (927:7): [True: 0, False: 16.5k]
  |  Branch (927:24): [True: 1, False: 16.5k]
  ------------------
  928|      1|    return _.diag(SPV_ERROR_INVALID_ID, inst)
  929|      1|           << "OpLoad type for pointer <id> " << _.getIdName(pointer_id)
  930|      1|           << " is not a pointer type.";
  931|      1|  }
  932|       |
  933|  16.5k|  uint32_t pointee_data_type;
  934|  16.5k|  spv::StorageClass storage_class;
  935|  16.5k|  if (!_.GetPointerTypeInfo(pointer_type->id(), &pointee_data_type,
  ------------------
  |  Branch (935:7): [True: 0, False: 16.5k]
  ------------------
  936|  16.5k|                            &storage_class) ||
  937|  16.5k|      result_type->id() != pointee_data_type) {
  ------------------
  |  Branch (937:7): [True: 10, False: 16.5k]
  ------------------
  938|     10|    return _.diag(SPV_ERROR_INVALID_ID, inst)
  939|     10|           << "OpLoad Result Type <id> " << _.getIdName(inst->type_id())
  940|     10|           << " does not match Pointer <id> " << _.getIdName(pointer->id())
  941|     10|           << "s type.";
  942|     10|  }
  943|       |
  944|  16.5k|  if (!_.options()->before_hlsl_legalization &&
  ------------------
  |  Branch (944:7): [True: 16.5k, False: 0]
  ------------------
  945|  16.5k|      _.ContainsRuntimeArray(inst->type_id())) {
  ------------------
  |  Branch (945:7): [True: 0, False: 16.5k]
  ------------------
  946|      0|    return _.diag(SPV_ERROR_INVALID_ID, inst)
  947|      0|           << "Cannot load a runtime-sized array";
  948|      0|  }
  949|       |
  950|  16.5k|  if (auto error = CheckMemoryAccess(_, inst, 3)) return error;
  ------------------
  |  Branch (950:12): [True: 0, False: 16.5k]
  ------------------
  951|       |
  952|  16.5k|  if (_.HasCapability(spv::Capability::Shader) &&
  ------------------
  |  Branch (952:7): [True: 16.5k, False: 1]
  ------------------
  953|  16.5k|      _.ContainsLimitedUseIntOrFloatType(inst->type_id()) &&
  ------------------
  |  Branch (953:7): [True: 0, False: 16.5k]
  ------------------
  954|  16.5k|      result_type->opcode() != spv::Op::OpTypePointer) {
  ------------------
  |  Branch (954:7): [True: 0, False: 0]
  ------------------
  955|      0|    if (result_type->opcode() != spv::Op::OpTypeInt &&
  ------------------
  |  Branch (955:9): [True: 0, False: 0]
  ------------------
  956|      0|        result_type->opcode() != spv::Op::OpTypeFloat &&
  ------------------
  |  Branch (956:9): [True: 0, False: 0]
  ------------------
  957|      0|        result_type->opcode() != spv::Op::OpTypeVector &&
  ------------------
  |  Branch (957:9): [True: 0, False: 0]
  ------------------
  958|      0|        result_type->opcode() != spv::Op::OpTypeMatrix) {
  ------------------
  |  Branch (958:9): [True: 0, False: 0]
  ------------------
  959|      0|      return _.diag(SPV_ERROR_INVALID_ID, inst)
  960|      0|             << "8- or 16-bit loads must be a scalar, vector or matrix type";
  961|      0|    }
  962|      0|  }
  963|       |
  964|  16.5k|  return SPV_SUCCESS;
  965|  16.5k|}
validate_memory.cpp:_ZN8spvtools3val12_GLOBAL__N_117CheckMemoryAccessERNS0_17ValidationState_tEPKNS0_11InstructionEj:
  312|  50.6k|                               uint32_t index) {
  313|  50.6k|  spv::StorageClass dst_sc, src_sc;
  314|  50.6k|  std::tie(dst_sc, src_sc) = GetStorageClass(_, inst);
  315|  50.6k|  if (inst->operands().size() <= index) {
  ------------------
  |  Branch (315:7): [True: 50.6k, False: 0]
  ------------------
  316|       |    // Cases where lack of some operand is invalid
  317|  50.6k|    if (src_sc == spv::StorageClass::PhysicalStorageBuffer ||
  ------------------
  |  Branch (317:9): [True: 0, False: 50.6k]
  ------------------
  318|  50.6k|        dst_sc == spv::StorageClass::PhysicalStorageBuffer) {
  ------------------
  |  Branch (318:9): [True: 0, False: 50.6k]
  ------------------
  319|      0|      return _.diag(SPV_ERROR_INVALID_ID, inst)
  320|      0|             << _.VkErrorID(4708)
  321|      0|             << "Memory accesses with PhysicalStorageBuffer must use Aligned.";
  322|      0|    }
  323|  50.6k|    return SPV_SUCCESS;
  324|  50.6k|  }
  325|       |
  326|      0|  const uint32_t mask = inst->GetOperandAs<uint32_t>(index);
  327|      0|  if (mask & uint32_t(spv::MemoryAccessMask::MakePointerAvailableKHR)) {
  ------------------
  |  Branch (327:7): [True: 0, False: 0]
  ------------------
  328|      0|    if (inst->opcode() == spv::Op::OpLoad ||
  ------------------
  |  Branch (328:9): [True: 0, False: 0]
  ------------------
  329|      0|        inst->opcode() == spv::Op::OpCooperativeMatrixLoadNV) {
  ------------------
  |  Branch (329:9): [True: 0, False: 0]
  ------------------
  330|      0|      return _.diag(SPV_ERROR_INVALID_ID, inst)
  331|      0|             << "MakePointerAvailableKHR cannot be used with OpLoad.";
  332|      0|    }
  333|       |
  334|      0|    if (!(mask & uint32_t(spv::MemoryAccessMask::NonPrivatePointerKHR))) {
  ------------------
  |  Branch (334:9): [True: 0, False: 0]
  ------------------
  335|      0|      return _.diag(SPV_ERROR_INVALID_ID, inst)
  336|      0|             << "NonPrivatePointerKHR must be specified if "
  337|      0|                "MakePointerAvailableKHR is specified.";
  338|      0|    }
  339|       |
  340|       |    // Check the associated scope for MakeAvailableKHR.
  341|      0|    const auto available_scope = GetMakeAvailableScope(inst, mask, index);
  342|      0|    if (auto error = ValidateMemoryScope(_, inst, available_scope))
  ------------------
  |  Branch (342:14): [True: 0, False: 0]
  ------------------
  343|      0|      return error;
  344|      0|  }
  345|       |
  346|      0|  if (mask & uint32_t(spv::MemoryAccessMask::MakePointerVisibleKHR)) {
  ------------------
  |  Branch (346:7): [True: 0, False: 0]
  ------------------
  347|      0|    if (inst->opcode() == spv::Op::OpStore ||
  ------------------
  |  Branch (347:9): [True: 0, False: 0]
  ------------------
  348|      0|        inst->opcode() == spv::Op::OpCooperativeMatrixStoreNV) {
  ------------------
  |  Branch (348:9): [True: 0, False: 0]
  ------------------
  349|      0|      return _.diag(SPV_ERROR_INVALID_ID, inst)
  350|      0|             << "MakePointerVisibleKHR cannot be used with OpStore.";
  351|      0|    }
  352|       |
  353|      0|    if (!(mask & uint32_t(spv::MemoryAccessMask::NonPrivatePointerKHR))) {
  ------------------
  |  Branch (353:9): [True: 0, False: 0]
  ------------------
  354|      0|      return _.diag(SPV_ERROR_INVALID_ID, inst)
  355|      0|             << "NonPrivatePointerKHR must be specified if "
  356|      0|             << "MakePointerVisibleKHR is specified.";
  357|      0|    }
  358|       |
  359|       |    // Check the associated scope for MakeVisibleKHR.
  360|      0|    const auto visible_scope = GetMakeVisibleScope(inst, mask, index);
  361|      0|    if (auto error = ValidateMemoryScope(_, inst, visible_scope)) return error;
  ------------------
  |  Branch (361:14): [True: 0, False: 0]
  ------------------
  362|      0|  }
  363|       |
  364|      0|  if (mask & uint32_t(spv::MemoryAccessMask::NonPrivatePointerKHR)) {
  ------------------
  |  Branch (364:7): [True: 0, False: 0]
  ------------------
  365|      0|    if (dst_sc != spv::StorageClass::Uniform &&
  ------------------
  |  Branch (365:9): [True: 0, False: 0]
  ------------------
  366|      0|        dst_sc != spv::StorageClass::Workgroup &&
  ------------------
  |  Branch (366:9): [True: 0, False: 0]
  ------------------
  367|      0|        dst_sc != spv::StorageClass::CrossWorkgroup &&
  ------------------
  |  Branch (367:9): [True: 0, False: 0]
  ------------------
  368|      0|        dst_sc != spv::StorageClass::Generic &&
  ------------------
  |  Branch (368:9): [True: 0, False: 0]
  ------------------
  369|      0|        dst_sc != spv::StorageClass::Image &&
  ------------------
  |  Branch (369:9): [True: 0, False: 0]
  ------------------
  370|      0|        dst_sc != spv::StorageClass::StorageBuffer &&
  ------------------
  |  Branch (370:9): [True: 0, False: 0]
  ------------------
  371|      0|        dst_sc != spv::StorageClass::PhysicalStorageBuffer) {
  ------------------
  |  Branch (371:9): [True: 0, False: 0]
  ------------------
  372|      0|      return _.diag(SPV_ERROR_INVALID_ID, inst)
  373|      0|             << "NonPrivatePointerKHR requires a pointer in Uniform, "
  374|      0|             << "Workgroup, CrossWorkgroup, Generic, Image or StorageBuffer "
  375|      0|             << "storage classes.";
  376|      0|    }
  377|      0|    if (src_sc != spv::StorageClass::Max &&
  ------------------
  |  Branch (377:9): [True: 0, False: 0]
  ------------------
  378|      0|        src_sc != spv::StorageClass::Uniform &&
  ------------------
  |  Branch (378:9): [True: 0, False: 0]
  ------------------
  379|      0|        src_sc != spv::StorageClass::Workgroup &&
  ------------------
  |  Branch (379:9): [True: 0, False: 0]
  ------------------
  380|      0|        src_sc != spv::StorageClass::CrossWorkgroup &&
  ------------------
  |  Branch (380:9): [True: 0, False: 0]
  ------------------
  381|      0|        src_sc != spv::StorageClass::Generic &&
  ------------------
  |  Branch (381:9): [True: 0, False: 0]
  ------------------
  382|      0|        src_sc != spv::StorageClass::Image &&
  ------------------
  |  Branch (382:9): [True: 0, False: 0]
  ------------------
  383|      0|        src_sc != spv::StorageClass::StorageBuffer &&
  ------------------
  |  Branch (383:9): [True: 0, False: 0]
  ------------------
  384|      0|        src_sc != spv::StorageClass::PhysicalStorageBuffer) {
  ------------------
  |  Branch (384:9): [True: 0, False: 0]
  ------------------
  385|      0|      return _.diag(SPV_ERROR_INVALID_ID, inst)
  386|      0|             << "NonPrivatePointerKHR requires a pointer in Uniform, "
  387|      0|             << "Workgroup, CrossWorkgroup, Generic, Image or StorageBuffer "
  388|      0|             << "storage classes.";
  389|      0|    }
  390|      0|  }
  391|       |
  392|      0|  if (!(mask & uint32_t(spv::MemoryAccessMask::Aligned))) {
  ------------------
  |  Branch (392:7): [True: 0, False: 0]
  ------------------
  393|      0|    if (src_sc == spv::StorageClass::PhysicalStorageBuffer ||
  ------------------
  |  Branch (393:9): [True: 0, False: 0]
  ------------------
  394|      0|        dst_sc == spv::StorageClass::PhysicalStorageBuffer) {
  ------------------
  |  Branch (394:9): [True: 0, False: 0]
  ------------------
  395|      0|      return _.diag(SPV_ERROR_INVALID_ID, inst)
  396|      0|             << _.VkErrorID(4708)
  397|      0|             << "Memory accesses with PhysicalStorageBuffer must use Aligned.";
  398|      0|    }
  399|      0|  }
  400|       |
  401|      0|  return SPV_SUCCESS;
  402|      0|}
validate_memory.cpp:_ZN8spvtools3val12_GLOBAL__N_115GetStorageClassERNS0_17ValidationState_tEPKNS0_11InstructionE:
  230|  50.6k|    ValidationState_t& _, const Instruction* inst) {
  231|  50.6k|  spv::StorageClass dst_sc = spv::StorageClass::Max;
  232|  50.6k|  spv::StorageClass src_sc = spv::StorageClass::Max;
  233|  50.6k|  switch (inst->opcode()) {
  234|      0|    case spv::Op::OpCooperativeMatrixLoadNV:
  ------------------
  |  Branch (234:5): [True: 0, False: 50.6k]
  ------------------
  235|  16.5k|    case spv::Op::OpLoad: {
  ------------------
  |  Branch (235:5): [True: 16.5k, False: 34.1k]
  ------------------
  236|  16.5k|      auto load_pointer = _.FindDef(inst->GetOperandAs<uint32_t>(2));
  237|  16.5k|      auto load_pointer_type = _.FindDef(load_pointer->type_id());
  238|  16.5k|      dst_sc = load_pointer_type->GetOperandAs<spv::StorageClass>(1);
  239|  16.5k|      break;
  240|      0|    }
  241|      0|    case spv::Op::OpCooperativeMatrixStoreNV:
  ------------------
  |  Branch (241:5): [True: 0, False: 50.6k]
  ------------------
  242|  34.1k|    case spv::Op::OpStore: {
  ------------------
  |  Branch (242:5): [True: 34.1k, False: 16.5k]
  ------------------
  243|  34.1k|      auto store_pointer = _.FindDef(inst->GetOperandAs<uint32_t>(0));
  244|  34.1k|      auto store_pointer_type = _.FindDef(store_pointer->type_id());
  245|  34.1k|      dst_sc = store_pointer_type->GetOperandAs<spv::StorageClass>(1);
  246|  34.1k|      break;
  247|      0|    }
  248|      0|    case spv::Op::OpCopyMemory:
  ------------------
  |  Branch (248:5): [True: 0, False: 50.6k]
  ------------------
  249|      0|    case spv::Op::OpCopyMemorySized: {
  ------------------
  |  Branch (249:5): [True: 0, False: 50.6k]
  ------------------
  250|      0|      auto dst = _.FindDef(inst->GetOperandAs<uint32_t>(0));
  251|      0|      auto dst_type = _.FindDef(dst->type_id());
  252|      0|      dst_sc = dst_type->GetOperandAs<spv::StorageClass>(1);
  253|      0|      auto src = _.FindDef(inst->GetOperandAs<uint32_t>(1));
  254|      0|      auto src_type = _.FindDef(src->type_id());
  255|      0|      src_sc = src_type->GetOperandAs<spv::StorageClass>(1);
  256|      0|      break;
  257|      0|    }
  258|      0|    default:
  ------------------
  |  Branch (258:5): [True: 0, False: 50.6k]
  ------------------
  259|      0|      break;
  260|  50.6k|  }
  261|       |
  262|  50.6k|  return std::make_pair(dst_sc, src_sc);
  263|  50.6k|}
validate_memory.cpp:_ZN8spvtools3val12_GLOBAL__N_113ValidateStoreERNS0_17ValidationState_tEPKNS0_11InstructionE:
  967|  34.1k|spv_result_t ValidateStore(ValidationState_t& _, const Instruction* inst) {
  968|  34.1k|  const auto pointer_index = 0;
  969|  34.1k|  const auto pointer_id = inst->GetOperandAs<uint32_t>(pointer_index);
  970|  34.1k|  const auto pointer = _.FindDef(pointer_id);
  971|  34.1k|  if (!pointer ||
  ------------------
  |  Branch (971:7): [True: 0, False: 34.1k]
  ------------------
  972|  34.1k|      (_.addressing_model() == spv::AddressingModel::Logical &&
  ------------------
  |  Branch (972:8): [True: 34.1k, False: 5]
  ------------------
  973|  34.1k|       ((!_.features().variable_pointers &&
  ------------------
  |  Branch (973:10): [True: 34.1k, False: 0]
  ------------------
  974|  34.1k|         !spvOpcodeReturnsLogicalPointer(pointer->opcode())) ||
  ------------------
  |  Branch (974:10): [True: 2, False: 34.1k]
  ------------------
  975|  34.1k|        (_.features().variable_pointers &&
  ------------------
  |  Branch (975:10): [True: 0, False: 34.1k]
  ------------------
  976|  34.1k|         !spvOpcodeReturnsLogicalVariablePointer(pointer->opcode()))))) {
  ------------------
  |  Branch (976:10): [True: 0, False: 0]
  ------------------
  977|      2|    return _.diag(SPV_ERROR_INVALID_ID, inst)
  978|      2|           << "OpStore Pointer <id> " << _.getIdName(pointer_id)
  979|      2|           << " is not a logical pointer.";
  980|      2|  }
  981|  34.1k|  const auto pointer_type = _.FindDef(pointer->type_id());
  982|  34.1k|  if (!pointer_type || pointer_type->opcode() != spv::Op::OpTypePointer) {
  ------------------
  |  Branch (982:7): [True: 0, False: 34.1k]
  |  Branch (982:24): [True: 2, False: 34.1k]
  ------------------
  983|      2|    return _.diag(SPV_ERROR_INVALID_ID, inst)
  984|      2|           << "OpStore type for pointer <id> " << _.getIdName(pointer_id)
  985|      2|           << " is not a pointer type.";
  986|      2|  }
  987|  34.1k|  const auto type_id = pointer_type->GetOperandAs<uint32_t>(2);
  988|  34.1k|  const auto type = _.FindDef(type_id);
  989|  34.1k|  if (!type || spv::Op::OpTypeVoid == type->opcode()) {
  ------------------
  |  Branch (989:7): [True: 0, False: 34.1k]
  |  Branch (989:16): [True: 1, False: 34.1k]
  ------------------
  990|      1|    return _.diag(SPV_ERROR_INVALID_ID, inst)
  991|      1|           << "OpStore Pointer <id> " << _.getIdName(pointer_id)
  992|      1|           << "s type is void.";
  993|      1|  }
  994|       |
  995|       |  // validate storage class
  996|  34.1k|  {
  997|  34.1k|    uint32_t data_type;
  998|  34.1k|    spv::StorageClass storage_class;
  999|  34.1k|    if (!_.GetPointerTypeInfo(pointer_type->id(), &data_type, &storage_class)) {
  ------------------
  |  Branch (999:9): [True: 0, False: 34.1k]
  ------------------
 1000|      0|      return _.diag(SPV_ERROR_INVALID_ID, inst)
 1001|      0|             << "OpStore Pointer <id> " << _.getIdName(pointer_id)
 1002|      0|             << " is not pointer type";
 1003|      0|    }
 1004|       |
 1005|  34.1k|    if (storage_class == spv::StorageClass::UniformConstant ||
  ------------------
  |  Branch (1005:9): [True: 0, False: 34.1k]
  ------------------
 1006|  34.1k|        storage_class == spv::StorageClass::Input ||
  ------------------
  |  Branch (1006:9): [True: 3, False: 34.1k]
  ------------------
 1007|  34.1k|        storage_class == spv::StorageClass::PushConstant) {
  ------------------
  |  Branch (1007:9): [True: 0, False: 34.1k]
  ------------------
 1008|      3|      return _.diag(SPV_ERROR_INVALID_ID, inst)
 1009|      3|             << "OpStore Pointer <id> " << _.getIdName(pointer_id)
 1010|      3|             << " storage class is read-only";
 1011|  34.1k|    } else if (storage_class == spv::StorageClass::ShaderRecordBufferKHR) {
  ------------------
  |  Branch (1011:16): [True: 0, False: 34.1k]
  ------------------
 1012|      0|      return _.diag(SPV_ERROR_INVALID_ID, inst)
 1013|      0|             << "ShaderRecordBufferKHR Storage Class variables are read only";
 1014|  34.1k|    } else if (storage_class == spv::StorageClass::HitAttributeKHR) {
  ------------------
  |  Branch (1014:16): [True: 0, False: 34.1k]
  ------------------
 1015|      0|      std::string errorVUID = _.VkErrorID(4703);
 1016|      0|      _.function(inst->function()->id())
 1017|      0|          ->RegisterExecutionModelLimitation(
 1018|      0|              [errorVUID](spv::ExecutionModel model, std::string* message) {
 1019|      0|                if (model == spv::ExecutionModel::AnyHitKHR ||
 1020|      0|                    model == spv::ExecutionModel::ClosestHitKHR) {
 1021|      0|                  if (message) {
 1022|      0|                    *message =
 1023|      0|                        errorVUID +
 1024|      0|                        "HitAttributeKHR Storage Class variables are read only "
 1025|      0|                        "with AnyHitKHR and ClosestHitKHR";
 1026|      0|                  }
 1027|      0|                  return false;
 1028|      0|                }
 1029|      0|                return true;
 1030|      0|              });
 1031|      0|    }
 1032|       |
 1033|  34.1k|    if (spvIsVulkanEnv(_.context()->target_env) &&
  ------------------
  |  Branch (1033:9): [True: 0, False: 34.1k]
  ------------------
 1034|  34.1k|        storage_class == spv::StorageClass::Uniform) {
  ------------------
  |  Branch (1034:9): [True: 0, False: 0]
  ------------------
 1035|      0|      auto base_ptr = _.TracePointer(pointer);
 1036|      0|      if (base_ptr->opcode() == spv::Op::OpVariable) {
  ------------------
  |  Branch (1036:11): [True: 0, False: 0]
  ------------------
 1037|       |        // If it's not a variable a different check should catch the problem.
 1038|      0|        auto base_type = _.FindDef(base_ptr->GetOperandAs<uint32_t>(0));
 1039|       |        // Get the pointed-to type.
 1040|      0|        base_type = _.FindDef(base_type->GetOperandAs<uint32_t>(2u));
 1041|      0|        if (base_type->opcode() == spv::Op::OpTypeArray ||
  ------------------
  |  Branch (1041:13): [True: 0, False: 0]
  ------------------
 1042|      0|            base_type->opcode() == spv::Op::OpTypeRuntimeArray) {
  ------------------
  |  Branch (1042:13): [True: 0, False: 0]
  ------------------
 1043|      0|          base_type = _.FindDef(base_type->GetOperandAs<uint32_t>(1u));
 1044|      0|        }
 1045|      0|        if (_.HasDecoration(base_type->id(), spv::Decoration::Block)) {
  ------------------
  |  Branch (1045:13): [True: 0, False: 0]
  ------------------
 1046|      0|          return _.diag(SPV_ERROR_INVALID_ID, inst)
 1047|      0|                 << _.VkErrorID(6925)
 1048|      0|                 << "In the Vulkan environment, cannot store to Uniform Blocks";
 1049|      0|        }
 1050|      0|      }
 1051|      0|    }
 1052|  34.1k|  }
 1053|       |
 1054|  34.1k|  const auto object_index = 1;
 1055|  34.1k|  const auto object_id = inst->GetOperandAs<uint32_t>(object_index);
 1056|  34.1k|  const auto object = _.FindDef(object_id);
 1057|  34.1k|  if (!object || !object->type_id()) {
  ------------------
  |  Branch (1057:7): [True: 0, False: 34.1k]
  |  Branch (1057:18): [True: 0, False: 34.1k]
  ------------------
 1058|      0|    return _.diag(SPV_ERROR_INVALID_ID, inst)
 1059|      0|           << "OpStore Object <id> " << _.getIdName(object_id)
 1060|      0|           << " is not an object.";
 1061|      0|  }
 1062|  34.1k|  const auto object_type = _.FindDef(object->type_id());
 1063|  34.1k|  if (!object_type || spv::Op::OpTypeVoid == object_type->opcode()) {
  ------------------
  |  Branch (1063:7): [True: 0, False: 34.1k]
  |  Branch (1063:23): [True: 0, False: 34.1k]
  ------------------
 1064|      0|    return _.diag(SPV_ERROR_INVALID_ID, inst)
 1065|      0|           << "OpStore Object <id> " << _.getIdName(object_id)
 1066|      0|           << "s type is void.";
 1067|      0|  }
 1068|       |
 1069|  34.1k|  if (type->id() != object_type->id()) {
  ------------------
  |  Branch (1069:7): [True: 12, False: 34.1k]
  ------------------
 1070|     12|    if (!_.options()->relax_struct_store ||
  ------------------
  |  Branch (1070:9): [True: 12, False: 0]
  ------------------
 1071|     12|        type->opcode() != spv::Op::OpTypeStruct ||
  ------------------
  |  Branch (1071:9): [True: 0, False: 0]
  ------------------
 1072|     12|        object_type->opcode() != spv::Op::OpTypeStruct) {
  ------------------
  |  Branch (1072:9): [True: 0, False: 0]
  ------------------
 1073|     12|      return _.diag(SPV_ERROR_INVALID_ID, inst)
 1074|     12|             << "OpStore Pointer <id> " << _.getIdName(pointer_id)
 1075|     12|             << "s type does not match Object <id> "
 1076|     12|             << _.getIdName(object->id()) << "s type.";
 1077|     12|    }
 1078|       |
 1079|       |    // TODO: Check for layout compatible matricies and arrays as well.
 1080|      0|    if (!AreLayoutCompatibleStructs(_, type, object_type)) {
  ------------------
  |  Branch (1080:9): [True: 0, False: 0]
  ------------------
 1081|      0|      return _.diag(SPV_ERROR_INVALID_ID, inst)
 1082|      0|             << "OpStore Pointer <id> " << _.getIdName(pointer_id)
 1083|      0|             << "s layout does not match Object <id> "
 1084|      0|             << _.getIdName(object->id()) << "s layout.";
 1085|      0|    }
 1086|      0|  }
 1087|       |
 1088|  34.1k|  if (auto error = CheckMemoryAccess(_, inst, 2)) return error;
  ------------------
  |  Branch (1088:12): [True: 0, False: 34.1k]
  ------------------
 1089|       |
 1090|  34.1k|  if (_.HasCapability(spv::Capability::Shader) &&
  ------------------
  |  Branch (1090:7): [True: 34.1k, False: 0]
  ------------------
 1091|  34.1k|      _.ContainsLimitedUseIntOrFloatType(inst->type_id()) &&
  ------------------
  |  Branch (1091:7): [True: 0, False: 34.1k]
  ------------------
 1092|  34.1k|      object_type->opcode() != spv::Op::OpTypePointer) {
  ------------------
  |  Branch (1092:7): [True: 0, False: 0]
  ------------------
 1093|      0|    if (object_type->opcode() != spv::Op::OpTypeInt &&
  ------------------
  |  Branch (1093:9): [True: 0, False: 0]
  ------------------
 1094|      0|        object_type->opcode() != spv::Op::OpTypeFloat &&
  ------------------
  |  Branch (1094:9): [True: 0, False: 0]
  ------------------
 1095|      0|        object_type->opcode() != spv::Op::OpTypeVector &&
  ------------------
  |  Branch (1095:9): [True: 0, False: 0]
  ------------------
 1096|      0|        object_type->opcode() != spv::Op::OpTypeMatrix) {
  ------------------
  |  Branch (1096:9): [True: 0, False: 0]
  ------------------
 1097|      0|      return _.diag(SPV_ERROR_INVALID_ID, inst)
 1098|      0|             << "8- or 16-bit stores must be a scalar, vector or matrix type";
 1099|      0|    }
 1100|      0|  }
 1101|       |
 1102|  34.1k|  return SPV_SUCCESS;
 1103|  34.1k|}
validate_memory.cpp:_ZN8spvtools3val12_GLOBAL__N_118ValidateCopyMemoryERNS0_17ValidationState_tEPKNS0_11InstructionE:
 1153|     17|spv_result_t ValidateCopyMemory(ValidationState_t& _, const Instruction* inst) {
 1154|     17|  const auto target_index = 0;
 1155|     17|  const auto target_id = inst->GetOperandAs<uint32_t>(target_index);
 1156|     17|  const auto target = _.FindDef(target_id);
 1157|     17|  if (!target) {
  ------------------
  |  Branch (1157:7): [True: 0, False: 17]
  ------------------
 1158|      0|    return _.diag(SPV_ERROR_INVALID_ID, inst)
 1159|      0|           << "Target operand <id> " << _.getIdName(target_id)
 1160|      0|           << " is not defined.";
 1161|      0|  }
 1162|       |
 1163|     17|  const auto source_index = 1;
 1164|     17|  const auto source_id = inst->GetOperandAs<uint32_t>(source_index);
 1165|     17|  const auto source = _.FindDef(source_id);
 1166|     17|  if (!source) {
  ------------------
  |  Branch (1166:7): [True: 0, False: 17]
  ------------------
 1167|      0|    return _.diag(SPV_ERROR_INVALID_ID, inst)
 1168|      0|           << "Source operand <id> " << _.getIdName(source_id)
 1169|      0|           << " is not defined.";
 1170|      0|  }
 1171|       |
 1172|     17|  const auto target_pointer_type = _.FindDef(target->type_id());
 1173|     17|  if (!target_pointer_type ||
  ------------------
  |  Branch (1173:7): [True: 0, False: 17]
  ------------------
 1174|     17|      target_pointer_type->opcode() != spv::Op::OpTypePointer) {
  ------------------
  |  Branch (1174:7): [True: 2, False: 15]
  ------------------
 1175|      2|    return _.diag(SPV_ERROR_INVALID_ID, inst)
 1176|      2|           << "Target operand <id> " << _.getIdName(target_id)
 1177|      2|           << " is not a pointer.";
 1178|      2|  }
 1179|       |
 1180|     15|  const auto source_pointer_type = _.FindDef(source->type_id());
 1181|     15|  if (!source_pointer_type ||
  ------------------
  |  Branch (1181:7): [True: 0, False: 15]
  ------------------
 1182|     15|      source_pointer_type->opcode() != spv::Op::OpTypePointer) {
  ------------------
  |  Branch (1182:7): [True: 3, False: 12]
  ------------------
 1183|      3|    return _.diag(SPV_ERROR_INVALID_ID, inst)
 1184|      3|           << "Source operand <id> " << _.getIdName(source_id)
 1185|      3|           << " is not a pointer.";
 1186|      3|  }
 1187|       |
 1188|     12|  if (inst->opcode() == spv::Op::OpCopyMemory) {
  ------------------
  |  Branch (1188:7): [True: 12, False: 0]
  ------------------
 1189|     12|    const auto target_type =
 1190|     12|        _.FindDef(target_pointer_type->GetOperandAs<uint32_t>(2));
 1191|     12|    if (!target_type || target_type->opcode() == spv::Op::OpTypeVoid) {
  ------------------
  |  Branch (1191:9): [True: 0, False: 12]
  |  Branch (1191:25): [True: 1, False: 11]
  ------------------
 1192|      1|      return _.diag(SPV_ERROR_INVALID_ID, inst)
 1193|      1|             << "Target operand <id> " << _.getIdName(target_id)
 1194|      1|             << " cannot be a void pointer.";
 1195|      1|    }
 1196|       |
 1197|     11|    const auto source_type =
 1198|     11|        _.FindDef(source_pointer_type->GetOperandAs<uint32_t>(2));
 1199|     11|    if (!source_type || source_type->opcode() == spv::Op::OpTypeVoid) {
  ------------------
  |  Branch (1199:9): [True: 0, False: 11]
  |  Branch (1199:25): [True: 1, False: 10]
  ------------------
 1200|      1|      return _.diag(SPV_ERROR_INVALID_ID, inst)
 1201|      1|             << "Source operand <id> " << _.getIdName(source_id)
 1202|      1|             << " cannot be a void pointer.";
 1203|      1|    }
 1204|       |
 1205|     10|    if (target_type->id() != source_type->id()) {
  ------------------
  |  Branch (1205:9): [True: 0, False: 10]
  ------------------
 1206|      0|      return _.diag(SPV_ERROR_INVALID_ID, inst)
 1207|      0|             << "Target <id> " << _.getIdName(source_id)
 1208|      0|             << "s type does not match Source <id> "
 1209|      0|             << _.getIdName(source_type->id()) << "s type.";
 1210|      0|    }
 1211|     10|  } else {
 1212|      0|    const auto size_id = inst->GetOperandAs<uint32_t>(2);
 1213|      0|    const auto size = _.FindDef(size_id);
 1214|      0|    if (!size) {
  ------------------
  |  Branch (1214:9): [True: 0, False: 0]
  ------------------
 1215|      0|      return _.diag(SPV_ERROR_INVALID_ID, inst)
 1216|      0|             << "Size operand <id> " << _.getIdName(size_id)
 1217|      0|             << " is not defined.";
 1218|      0|    }
 1219|       |
 1220|      0|    const auto size_type = _.FindDef(size->type_id());
 1221|      0|    if (!_.IsIntScalarType(size_type->id())) {
  ------------------
  |  Branch (1221:9): [True: 0, False: 0]
  ------------------
 1222|      0|      return _.diag(SPV_ERROR_INVALID_ID, inst)
 1223|      0|             << "Size operand <id> " << _.getIdName(size_id)
 1224|      0|             << " must be a scalar integer type.";
 1225|      0|    }
 1226|       |
 1227|      0|    bool is_zero = true;
 1228|      0|    switch (size->opcode()) {
 1229|      0|      case spv::Op::OpConstantNull:
  ------------------
  |  Branch (1229:7): [True: 0, False: 0]
  ------------------
 1230|      0|        return _.diag(SPV_ERROR_INVALID_ID, inst)
 1231|      0|               << "Size operand <id> " << _.getIdName(size_id)
 1232|      0|               << " cannot be a constant zero.";
 1233|      0|      case spv::Op::OpConstant:
  ------------------
  |  Branch (1233:7): [True: 0, False: 0]
  ------------------
 1234|      0|        if (size_type->word(3) == 1 &&
  ------------------
  |  Branch (1234:13): [True: 0, False: 0]
  ------------------
 1235|      0|            size->word(size->words().size() - 1) & 0x80000000) {
  ------------------
  |  Branch (1235:13): [True: 0, False: 0]
  ------------------
 1236|      0|          return _.diag(SPV_ERROR_INVALID_ID, inst)
 1237|      0|                 << "Size operand <id> " << _.getIdName(size_id)
 1238|      0|                 << " cannot have the sign bit set to 1.";
 1239|      0|        }
 1240|      0|        for (size_t i = 3; is_zero && i < size->words().size(); ++i) {
  ------------------
  |  Branch (1240:28): [True: 0, False: 0]
  |  Branch (1240:39): [True: 0, False: 0]
  ------------------
 1241|      0|          is_zero &= (size->word(i) == 0);
 1242|      0|        }
 1243|      0|        if (is_zero) {
  ------------------
  |  Branch (1243:13): [True: 0, False: 0]
  ------------------
 1244|      0|          return _.diag(SPV_ERROR_INVALID_ID, inst)
 1245|      0|                 << "Size operand <id> " << _.getIdName(size_id)
 1246|      0|                 << " cannot be a constant zero.";
 1247|      0|        }
 1248|      0|        break;
 1249|      0|      default:
  ------------------
  |  Branch (1249:7): [True: 0, False: 0]
  ------------------
 1250|       |        // Cannot infer any other opcodes.
 1251|      0|        break;
 1252|      0|    }
 1253|      0|  }
 1254|     10|  if (auto error = ValidateCopyMemoryMemoryAccess(_, inst)) return error;
  ------------------
  |  Branch (1254:12): [True: 0, False: 10]
  ------------------
 1255|       |
 1256|       |  // Get past the pointers to avoid checking a pointer copy.
 1257|     10|  auto sub_type = _.FindDef(target_pointer_type->GetOperandAs<uint32_t>(2));
 1258|     10|  while (sub_type->opcode() == spv::Op::OpTypePointer) {
  ------------------
  |  Branch (1258:10): [True: 0, False: 10]
  ------------------
 1259|      0|    sub_type = _.FindDef(sub_type->GetOperandAs<uint32_t>(2));
 1260|      0|  }
 1261|     10|  if (_.HasCapability(spv::Capability::Shader) &&
  ------------------
  |  Branch (1261:7): [True: 10, False: 0]
  ------------------
 1262|     10|      _.ContainsLimitedUseIntOrFloatType(sub_type->id())) {
  ------------------
  |  Branch (1262:7): [True: 0, False: 10]
  ------------------
 1263|      0|    return _.diag(SPV_ERROR_INVALID_ID, inst)
 1264|      0|           << "Cannot copy memory of objects containing 8- or 16-bit types";
 1265|      0|  }
 1266|       |
 1267|     10|  return SPV_SUCCESS;
 1268|     10|}
validate_memory.cpp:_ZN8spvtools3val12_GLOBAL__N_130ValidateCopyMemoryMemoryAccessERNS0_17ValidationState_tEPKNS0_11InstructionE:
 1106|     10|                                            const Instruction* inst) {
 1107|     10|  assert(inst->opcode() == spv::Op::OpCopyMemory ||
 1108|     10|         inst->opcode() == spv::Op::OpCopyMemorySized);
 1109|      0|  const uint32_t first_access_index =
 1110|     10|      inst->opcode() == spv::Op::OpCopyMemory ? 2 : 3;
  ------------------
  |  Branch (1110:7): [True: 10, False: 0]
  ------------------
 1111|     10|  if (inst->operands().size() > first_access_index) {
  ------------------
  |  Branch (1111:7): [True: 0, False: 10]
  ------------------
 1112|      0|    if (auto error = CheckMemoryAccess(_, inst, first_access_index))
  ------------------
  |  Branch (1112:14): [True: 0, False: 0]
  ------------------
 1113|      0|      return error;
 1114|       |
 1115|      0|    const auto first_access = inst->GetOperandAs<uint32_t>(first_access_index);
 1116|      0|    const uint32_t second_access_index =
 1117|      0|        first_access_index + MemoryAccessNumWords(first_access);
 1118|      0|    if (inst->operands().size() > second_access_index) {
  ------------------
  |  Branch (1118:9): [True: 0, False: 0]
  ------------------
 1119|      0|      if (_.features().copy_memory_permits_two_memory_accesses) {
  ------------------
  |  Branch (1119:11): [True: 0, False: 0]
  ------------------
 1120|      0|        if (auto error = CheckMemoryAccess(_, inst, second_access_index))
  ------------------
  |  Branch (1120:18): [True: 0, False: 0]
  ------------------
 1121|      0|          return error;
 1122|       |
 1123|       |        // In the two-access form in SPIR-V 1.4 and later:
 1124|       |        //  - the first is the target (write) access and it can't have
 1125|       |        //  make-visible.
 1126|       |        //  - the second is the source (read) access and it can't have
 1127|       |        //  make-available.
 1128|      0|        if (first_access &
  ------------------
  |  Branch (1128:13): [True: 0, False: 0]
  ------------------
 1129|      0|            uint32_t(spv::MemoryAccessMask::MakePointerVisibleKHR)) {
 1130|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
 1131|      0|                 << "Target memory access must not include "
 1132|      0|                    "MakePointerVisibleKHR";
 1133|      0|        }
 1134|      0|        const auto second_access =
 1135|      0|            inst->GetOperandAs<uint32_t>(second_access_index);
 1136|      0|        if (second_access &
  ------------------
  |  Branch (1136:13): [True: 0, False: 0]
  ------------------
 1137|      0|            uint32_t(spv::MemoryAccessMask::MakePointerAvailableKHR)) {
 1138|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
 1139|      0|                 << "Source memory access must not include "
 1140|      0|                    "MakePointerAvailableKHR";
 1141|      0|        }
 1142|      0|      } else {
 1143|      0|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
 1144|      0|               << spvOpcodeString(static_cast<spv::Op>(inst->opcode()))
 1145|      0|               << " with two memory access operands requires SPIR-V 1.4 or "
 1146|      0|                  "later";
 1147|      0|      }
 1148|      0|    }
 1149|      0|  }
 1150|     10|  return SPV_SUCCESS;
 1151|     10|}
validate_memory.cpp:_ZN8spvtools3val12_GLOBAL__N_122ValidatePtrAccessChainERNS0_17ValidationState_tEPKNS0_11InstructionE:
 1426|      5|                                    const Instruction* inst) {
 1427|      5|  if (_.addressing_model() == spv::AddressingModel::Logical) {
  ------------------
  |  Branch (1427:7): [True: 0, False: 5]
  ------------------
 1428|      0|    if (!_.features().variable_pointers) {
  ------------------
  |  Branch (1428:9): [True: 0, False: 0]
  ------------------
 1429|      0|      return _.diag(SPV_ERROR_INVALID_DATA, inst)
 1430|      0|             << "Generating variable pointers requires capability "
 1431|      0|             << "VariablePointers or VariablePointersStorageBuffer";
 1432|      0|    }
 1433|      0|  }
 1434|       |
 1435|       |  // Need to call first, will make sure Base is a valid ID
 1436|      5|  if (auto error = ValidateAccessChain(_, inst)) return error;
  ------------------
  |  Branch (1436:12): [True: 1, False: 4]
  ------------------
 1437|       |
 1438|      4|  const auto base_id = inst->GetOperandAs<uint32_t>(2);
 1439|      4|  const auto base = _.FindDef(base_id);
 1440|      4|  const auto base_type = _.FindDef(base->type_id());
 1441|      4|  const auto base_type_storage_class =
 1442|      4|      base_type->GetOperandAs<spv::StorageClass>(1);
 1443|       |
 1444|      4|  if (_.HasCapability(spv::Capability::Shader) &&
  ------------------
  |  Branch (1444:7): [True: 4, False: 0]
  ------------------
 1445|      4|      (base_type_storage_class == spv::StorageClass::Uniform ||
  ------------------
  |  Branch (1445:8): [True: 1, False: 3]
  ------------------
 1446|      4|       base_type_storage_class == spv::StorageClass::StorageBuffer ||
  ------------------
  |  Branch (1446:8): [True: 0, False: 3]
  ------------------
 1447|      4|       base_type_storage_class == spv::StorageClass::PhysicalStorageBuffer ||
  ------------------
  |  Branch (1447:8): [True: 0, False: 3]
  ------------------
 1448|      4|       base_type_storage_class == spv::StorageClass::PushConstant ||
  ------------------
  |  Branch (1448:8): [True: 0, False: 3]
  ------------------
 1449|      4|       (_.HasCapability(spv::Capability::WorkgroupMemoryExplicitLayoutKHR) &&
  ------------------
  |  Branch (1449:9): [True: 0, False: 3]
  ------------------
 1450|      3|        base_type_storage_class == spv::StorageClass::Workgroup)) &&
  ------------------
  |  Branch (1450:9): [True: 0, False: 0]
  ------------------
 1451|      4|      !_.HasDecoration(base_type->id(), spv::Decoration::ArrayStride)) {
  ------------------
  |  Branch (1451:7): [True: 1, False: 0]
  ------------------
 1452|      1|    return _.diag(SPV_ERROR_INVALID_DATA, inst)
 1453|      1|           << "OpPtrAccessChain must have a Base whose type is decorated "
 1454|      1|              "with ArrayStride";
 1455|      1|  }
 1456|       |
 1457|      3|  if (spvIsVulkanEnv(_.context()->target_env)) {
  ------------------
  |  Branch (1457:7): [True: 0, False: 3]
  ------------------
 1458|      0|    if (base_type_storage_class == spv::StorageClass::Workgroup) {
  ------------------
  |  Branch (1458:9): [True: 0, False: 0]
  ------------------
 1459|      0|      if (!_.HasCapability(spv::Capability::VariablePointers)) {
  ------------------
  |  Branch (1459:11): [True: 0, False: 0]
  ------------------
 1460|      0|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
 1461|      0|               << _.VkErrorID(7651)
 1462|      0|               << "OpPtrAccessChain Base operand pointing to Workgroup "
 1463|      0|                  "storage class must use VariablePointers capability";
 1464|      0|      }
 1465|      0|    } else if (base_type_storage_class == spv::StorageClass::StorageBuffer) {
  ------------------
  |  Branch (1465:16): [True: 0, False: 0]
  ------------------
 1466|      0|      if (!_.features().variable_pointers) {
  ------------------
  |  Branch (1466:11): [True: 0, False: 0]
  ------------------
 1467|      0|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
 1468|      0|               << _.VkErrorID(7652)
 1469|      0|               << "OpPtrAccessChain Base operand pointing to StorageBuffer "
 1470|      0|                  "storage class must use VariablePointers or "
 1471|      0|                  "VariablePointersStorageBuffer capability";
 1472|      0|      }
 1473|      0|    } else if (base_type_storage_class !=
  ------------------
  |  Branch (1473:16): [True: 0, False: 0]
  ------------------
 1474|      0|               spv::StorageClass::PhysicalStorageBuffer) {
 1475|      0|      return _.diag(SPV_ERROR_INVALID_DATA, inst)
 1476|      0|             << _.VkErrorID(7650)
 1477|      0|             << "OpPtrAccessChain Base operand must point to Workgroup, "
 1478|      0|                "StorageBuffer, or PhysicalStorageBuffer storage class";
 1479|      0|    }
 1480|      0|  }
 1481|       |
 1482|      3|  return SPV_SUCCESS;
 1483|      3|}
validate_memory.cpp:_ZN8spvtools3val12_GLOBAL__N_119ValidateAccessChainERNS0_17ValidationState_tEPKNS0_11InstructionE:
 1271|  11.2k|                                 const Instruction* inst) {
 1272|  11.2k|  std::string instr_name =
 1273|  11.2k|      "Op" + std::string(spvOpcodeString(static_cast<spv::Op>(inst->opcode())));
 1274|       |
 1275|       |  // The result type must be OpTypePointer.
 1276|  11.2k|  auto result_type = _.FindDef(inst->type_id());
 1277|  11.2k|  if (spv::Op::OpTypePointer != result_type->opcode()) {
  ------------------
  |  Branch (1277:7): [True: 7, False: 11.2k]
  ------------------
 1278|      7|    return _.diag(SPV_ERROR_INVALID_ID, inst)
 1279|      7|           << "The Result Type of " << instr_name << " <id> "
 1280|      7|           << _.getIdName(inst->id()) << " must be OpTypePointer. Found Op"
 1281|      7|           << spvOpcodeString(static_cast<spv::Op>(result_type->opcode()))
 1282|      7|           << ".";
 1283|      7|  }
 1284|       |
 1285|       |  // Result type is a pointer. Find out what it's pointing to.
 1286|       |  // This will be used to make sure the indexing results in the same type.
 1287|       |  // OpTypePointer word 3 is the type being pointed to.
 1288|  11.2k|  const auto result_type_pointee = _.FindDef(result_type->word(3));
 1289|       |
 1290|       |  // Base must be a pointer, pointing to the base of a composite object.
 1291|  11.2k|  const auto base_index = 2;
 1292|  11.2k|  const auto base_id = inst->GetOperandAs<uint32_t>(base_index);
 1293|  11.2k|  const auto base = _.FindDef(base_id);
 1294|  11.2k|  const auto base_type = _.FindDef(base->type_id());
 1295|  11.2k|  if (!base_type || spv::Op::OpTypePointer != base_type->opcode()) {
  ------------------
  |  Branch (1295:7): [True: 0, False: 11.2k]
  |  Branch (1295:21): [True: 1, False: 11.2k]
  ------------------
 1296|      1|    return _.diag(SPV_ERROR_INVALID_ID, inst)
 1297|      1|           << "The Base <id> " << _.getIdName(base_id) << " in " << instr_name
 1298|      1|           << " instruction must be a pointer.";
 1299|      1|  }
 1300|       |
 1301|       |  // The result pointer storage class and base pointer storage class must match.
 1302|       |  // Word 2 of OpTypePointer is the Storage Class.
 1303|  11.2k|  auto result_type_storage_class = result_type->word(2);
 1304|  11.2k|  auto base_type_storage_class = base_type->word(2);
 1305|  11.2k|  if (result_type_storage_class != base_type_storage_class) {
  ------------------
  |  Branch (1305:7): [True: 0, False: 11.2k]
  ------------------
 1306|      0|    return _.diag(SPV_ERROR_INVALID_ID, inst)
 1307|      0|           << "The result pointer storage class and base "
 1308|      0|              "pointer storage class in "
 1309|      0|           << instr_name << " do not match.";
 1310|      0|  }
 1311|       |
 1312|       |  // The type pointed to by OpTypePointer (word 3) must be a composite type.
 1313|  11.2k|  auto type_pointee = _.FindDef(base_type->word(3));
 1314|       |
 1315|       |  // Check Universal Limit (SPIR-V Spec. Section 2.17).
 1316|       |  // The number of indexes passed to OpAccessChain may not exceed 255
 1317|       |  // The instruction includes 4 words + N words (for N indexes)
 1318|  11.2k|  size_t num_indexes = inst->words().size() - 4;
 1319|  11.2k|  if (inst->opcode() == spv::Op::OpPtrAccessChain ||
  ------------------
  |  Branch (1319:7): [True: 4, False: 11.2k]
  ------------------
 1320|  11.2k|      inst->opcode() == spv::Op::OpInBoundsPtrAccessChain) {
  ------------------
  |  Branch (1320:7): [True: 4, False: 11.2k]
  ------------------
 1321|       |    // In pointer access chains, the element operand is required, but not
 1322|       |    // counted as an index.
 1323|      8|    --num_indexes;
 1324|      8|  }
 1325|  11.2k|  const size_t num_indexes_limit =
 1326|  11.2k|      _.options()->universal_limits_.max_access_chain_indexes;
 1327|  11.2k|  if (num_indexes > num_indexes_limit) {
  ------------------
  |  Branch (1327:7): [True: 0, False: 11.2k]
  ------------------
 1328|      0|    return _.diag(SPV_ERROR_INVALID_ID, inst)
 1329|      0|           << "The number of indexes in " << instr_name << " may not exceed "
 1330|      0|           << num_indexes_limit << ". Found " << num_indexes << " indexes.";
 1331|      0|  }
 1332|       |  // Indexes walk the type hierarchy to the desired depth, potentially down to
 1333|       |  // scalar granularity. The first index in Indexes will select the top-level
 1334|       |  // member/element/component/element of the base composite. All composite
 1335|       |  // constituents use zero-based numbering, as described by their OpType...
 1336|       |  // instruction. The second index will apply similarly to that result, and so
 1337|       |  // on. Once any non-composite type is reached, there must be no remaining
 1338|       |  // (unused) indexes.
 1339|  11.2k|  auto starting_index = 4;
 1340|  11.2k|  if (inst->opcode() == spv::Op::OpPtrAccessChain ||
  ------------------
  |  Branch (1340:7): [True: 4, False: 11.2k]
  ------------------
 1341|  11.2k|      inst->opcode() == spv::Op::OpInBoundsPtrAccessChain) {
  ------------------
  |  Branch (1341:7): [True: 4, False: 11.2k]
  ------------------
 1342|      8|    ++starting_index;
 1343|      8|  }
 1344|  27.6k|  for (size_t i = starting_index; i < inst->words().size(); ++i) {
  ------------------
  |  Branch (1344:35): [True: 16.4k, False: 11.2k]
  ------------------
 1345|  16.4k|    const uint32_t cur_word = inst->words()[i];
 1346|       |    // Earlier ID checks ensure that cur_word definition exists.
 1347|  16.4k|    auto cur_word_instr = _.FindDef(cur_word);
 1348|       |    // The index must be a scalar integer type (See OpAccessChain in the Spec.)
 1349|  16.4k|    auto index_type = _.FindDef(cur_word_instr->type_id());
 1350|  16.4k|    if (!index_type || spv::Op::OpTypeInt != index_type->opcode()) {
  ------------------
  |  Branch (1350:9): [True: 0, False: 16.4k]
  |  Branch (1350:24): [True: 2, False: 16.4k]
  ------------------
 1351|      2|      return _.diag(SPV_ERROR_INVALID_ID, inst)
 1352|      2|             << "Indexes passed to " << instr_name
 1353|      2|             << " must be of type integer.";
 1354|      2|    }
 1355|  16.4k|    switch (type_pointee->opcode()) {
 1356|    668|      case spv::Op::OpTypeMatrix:
  ------------------
  |  Branch (1356:7): [True: 668, False: 15.7k]
  ------------------
 1357|  3.65k|      case spv::Op::OpTypeVector:
  ------------------
  |  Branch (1357:7): [True: 2.98k, False: 13.4k]
  ------------------
 1358|  3.65k|      case spv::Op::OpTypeCooperativeMatrixNV:
  ------------------
  |  Branch (1358:7): [True: 0, False: 16.4k]
  ------------------
 1359|  11.2k|      case spv::Op::OpTypeArray:
  ------------------
  |  Branch (1359:7): [True: 7.60k, False: 8.82k]
  ------------------
 1360|  11.2k|      case spv::Op::OpTypeRuntimeArray: {
  ------------------
  |  Branch (1360:7): [True: 30, False: 16.3k]
  ------------------
 1361|       |        // In OpTypeMatrix, OpTypeVector, spv::Op::OpTypeCooperativeMatrixNV,
 1362|       |        // OpTypeArray, and OpTypeRuntimeArray, word 2 is the Element Type.
 1363|  11.2k|        type_pointee = _.FindDef(type_pointee->word(2));
 1364|  11.2k|        break;
 1365|  11.2k|      }
 1366|  5.13k|      case spv::Op::OpTypeStruct: {
  ------------------
  |  Branch (1366:7): [True: 5.13k, False: 11.2k]
  ------------------
 1367|       |        // In case of structures, there is an additional constraint on the
 1368|       |        // index: the index must be an OpConstant.
 1369|  5.13k|        if (spv::Op::OpConstant != cur_word_instr->opcode()) {
  ------------------
  |  Branch (1369:13): [True: 0, False: 5.13k]
  ------------------
 1370|      0|          return _.diag(SPV_ERROR_INVALID_ID, cur_word_instr)
 1371|      0|                 << "The <id> passed to " << instr_name
 1372|      0|                 << " to index into a "
 1373|      0|                    "structure must be an OpConstant.";
 1374|      0|        }
 1375|       |        // Get the index value from the OpConstant (word 3 of OpConstant).
 1376|       |        // OpConstant could be a signed integer. But it's okay to treat it as
 1377|       |        // unsigned because a negative constant int would never be seen as
 1378|       |        // correct as a struct offset, since structs can't have more than 2
 1379|       |        // billion members.
 1380|  5.13k|        const uint32_t cur_index = cur_word_instr->word(3);
 1381|       |        // The index points to the struct member we want, therefore, the index
 1382|       |        // should be less than the number of struct members.
 1383|  5.13k|        const uint32_t num_struct_members =
 1384|  5.13k|            static_cast<uint32_t>(type_pointee->words().size() - 2);
 1385|  5.13k|        if (cur_index >= num_struct_members) {
  ------------------
  |  Branch (1385:13): [True: 11, False: 5.12k]
  ------------------
 1386|     11|          return _.diag(SPV_ERROR_INVALID_ID, cur_word_instr)
 1387|     11|                 << "Index is out of bounds: " << instr_name
 1388|     11|                 << " can not find index " << cur_index
 1389|     11|                 << " into the structure <id> "
 1390|     11|                 << _.getIdName(type_pointee->id()) << ". This structure has "
 1391|     11|                 << num_struct_members << " members. Largest valid index is "
 1392|     11|                 << num_struct_members - 1 << ".";
 1393|     11|        }
 1394|       |        // Struct members IDs start at word 2 of OpTypeStruct.
 1395|  5.12k|        auto structMemberId = type_pointee->word(cur_index + 2);
 1396|  5.12k|        type_pointee = _.FindDef(structMemberId);
 1397|  5.12k|        break;
 1398|  5.13k|      }
 1399|      0|      default: {
  ------------------
  |  Branch (1399:7): [True: 0, False: 16.4k]
  ------------------
 1400|       |        // Give an error. reached non-composite type while indexes still remain.
 1401|      0|        return _.diag(SPV_ERROR_INVALID_ID, inst)
 1402|      0|               << instr_name
 1403|      0|               << " reached non-composite type while indexes "
 1404|      0|                  "still remain to be traversed.";
 1405|  5.13k|      }
 1406|  16.4k|    }
 1407|  16.4k|  }
 1408|       |  // At this point, we have fully walked down from the base using the indeces.
 1409|       |  // The type being pointed to should be the same as the result type.
 1410|  11.2k|  if (type_pointee->id() != result_type_pointee->id()) {
  ------------------
  |  Branch (1410:7): [True: 6, False: 11.2k]
  ------------------
 1411|      6|    return _.diag(SPV_ERROR_INVALID_ID, inst)
 1412|      6|           << instr_name << " result type (Op"
 1413|      6|           << spvOpcodeString(
 1414|      6|                  static_cast<spv::Op>(result_type_pointee->opcode()))
 1415|      6|           << ") does not match the type that results from indexing into the "
 1416|      6|              "base "
 1417|      6|              "<id> (Op"
 1418|      6|           << spvOpcodeString(static_cast<spv::Op>(type_pointee->opcode()))
 1419|      6|           << ").";
 1420|      6|  }
 1421|       |
 1422|  11.2k|  return SPV_SUCCESS;
 1423|  11.2k|}
validate_memory.cpp:_ZN8spvtools3val12_GLOBAL__N_119ValidateArrayLengthERNS0_17ValidationState_tEPKNS0_11InstructionE:
 1486|      2|                                 const Instruction* inst) {
 1487|      2|  std::string instr_name =
 1488|      2|      "Op" + std::string(spvOpcodeString(static_cast<spv::Op>(inst->opcode())));
 1489|       |
 1490|       |  // Result type must be a 32-bit unsigned int.
 1491|      2|  auto result_type = state.FindDef(inst->type_id());
 1492|      2|  if (result_type->opcode() != spv::Op::OpTypeInt ||
  ------------------
  |  Branch (1492:7): [True: 1, False: 1]
  ------------------
 1493|      2|      result_type->GetOperandAs<uint32_t>(1) != 32 ||
  ------------------
  |  Branch (1493:7): [True: 0, False: 1]
  ------------------
 1494|      2|      result_type->GetOperandAs<uint32_t>(2) != 0) {
  ------------------
  |  Branch (1494:7): [True: 0, False: 1]
  ------------------
 1495|      1|    return state.diag(SPV_ERROR_INVALID_ID, inst)
 1496|      1|           << "The Result Type of " << instr_name << " <id> "
 1497|      1|           << state.getIdName(inst->id())
 1498|      1|           << " must be OpTypeInt with width 32 and signedness 0.";
 1499|      1|  }
 1500|       |
 1501|       |  // The structure that is passed in must be an pointer to a structure, whose
 1502|       |  // last element is a runtime array.
 1503|      1|  auto pointer = state.FindDef(inst->GetOperandAs<uint32_t>(2));
 1504|      1|  auto pointer_type = state.FindDef(pointer->type_id());
 1505|      1|  if (pointer_type->opcode() != spv::Op::OpTypePointer) {
  ------------------
  |  Branch (1505:7): [True: 0, False: 1]
  ------------------
 1506|      0|    return state.diag(SPV_ERROR_INVALID_ID, inst)
 1507|      0|           << "The Structure's type in " << instr_name << " <id> "
 1508|      0|           << state.getIdName(inst->id())
 1509|      0|           << " must be a pointer to an OpTypeStruct.";
 1510|      0|  }
 1511|       |
 1512|      1|  auto structure_type = state.FindDef(pointer_type->GetOperandAs<uint32_t>(2));
 1513|      1|  if (structure_type->opcode() != spv::Op::OpTypeStruct) {
  ------------------
  |  Branch (1513:7): [True: 0, False: 1]
  ------------------
 1514|      0|    return state.diag(SPV_ERROR_INVALID_ID, inst)
 1515|      0|           << "The Structure's type in " << instr_name << " <id> "
 1516|      0|           << state.getIdName(inst->id())
 1517|      0|           << " must be a pointer to an OpTypeStruct.";
 1518|      0|  }
 1519|       |
 1520|      1|  auto num_of_members = structure_type->operands().size() - 1;
 1521|      1|  auto last_member =
 1522|      1|      state.FindDef(structure_type->GetOperandAs<uint32_t>(num_of_members));
 1523|      1|  if (last_member->opcode() != spv::Op::OpTypeRuntimeArray) {
  ------------------
  |  Branch (1523:7): [True: 1, False: 0]
  ------------------
 1524|      1|    return state.diag(SPV_ERROR_INVALID_ID, inst)
 1525|      1|           << "The Structure's last member in " << instr_name << " <id> "
 1526|      1|           << state.getIdName(inst->id()) << " must be an OpTypeRuntimeArray.";
 1527|      1|  }
 1528|       |
 1529|       |  // The array member must the index of the last element (the run time
 1530|       |  // array).
 1531|      0|  if (inst->GetOperandAs<uint32_t>(3) != num_of_members - 1) {
  ------------------
  |  Branch (1531:7): [True: 0, False: 0]
  ------------------
 1532|      0|    return state.diag(SPV_ERROR_INVALID_ID, inst)
 1533|      0|           << "The array member in " << instr_name << " <id> "
 1534|      0|           << state.getIdName(inst->id())
 1535|      0|           << " must be an the last member of the struct.";
 1536|      0|  }
 1537|      0|  return SPV_SUCCESS;
 1538|      0|}
validate_memory.cpp:_ZN8spvtools3val12_GLOBAL__N_121ValidatePtrComparisonERNS0_17ValidationState_tEPKNS0_11InstructionE:
 1671|      2|                                   const Instruction* inst) {
 1672|      2|  if (_.addressing_model() == spv::AddressingModel::Logical &&
  ------------------
  |  Branch (1672:7): [True: 1, False: 1]
  ------------------
 1673|      2|      !_.features().variable_pointers) {
  ------------------
  |  Branch (1673:7): [True: 1, False: 0]
  ------------------
 1674|      1|    return _.diag(SPV_ERROR_INVALID_ID, inst)
 1675|      1|           << "Instruction cannot for logical addressing model be used without "
 1676|      1|              "a variable pointers capability";
 1677|      1|  }
 1678|       |
 1679|      1|  const auto result_type = _.FindDef(inst->type_id());
 1680|      1|  if (inst->opcode() == spv::Op::OpPtrDiff) {
  ------------------
  |  Branch (1680:7): [True: 1, False: 0]
  ------------------
 1681|      1|    if (!result_type || result_type->opcode() != spv::Op::OpTypeInt) {
  ------------------
  |  Branch (1681:9): [True: 0, False: 1]
  |  Branch (1681:25): [True: 1, False: 0]
  ------------------
 1682|      1|      return _.diag(SPV_ERROR_INVALID_ID, inst)
 1683|      1|             << "Result Type must be an integer scalar";
 1684|      1|    }
 1685|      1|  } else {
 1686|      0|    if (!result_type || result_type->opcode() != spv::Op::OpTypeBool) {
  ------------------
  |  Branch (1686:9): [True: 0, False: 0]
  |  Branch (1686:25): [True: 0, False: 0]
  ------------------
 1687|      0|      return _.diag(SPV_ERROR_INVALID_ID, inst)
 1688|      0|             << "Result Type must be OpTypeBool";
 1689|      0|    }
 1690|      0|  }
 1691|       |
 1692|      0|  const auto op1 = _.FindDef(inst->GetOperandAs<uint32_t>(2u));
 1693|      0|  const auto op2 = _.FindDef(inst->GetOperandAs<uint32_t>(3u));
 1694|      0|  if (!op1 || !op2 || op1->type_id() != op2->type_id()) {
  ------------------
  |  Branch (1694:7): [True: 0, False: 0]
  |  Branch (1694:15): [True: 0, False: 0]
  |  Branch (1694:23): [True: 0, False: 0]
  ------------------
 1695|      0|    return _.diag(SPV_ERROR_INVALID_ID, inst)
 1696|      0|           << "The types of Operand 1 and Operand 2 must match";
 1697|      0|  }
 1698|      0|  const auto op1_type = _.FindDef(op1->type_id());
 1699|      0|  if (!op1_type || op1_type->opcode() != spv::Op::OpTypePointer) {
  ------------------
  |  Branch (1699:7): [True: 0, False: 0]
  |  Branch (1699:20): [True: 0, False: 0]
  ------------------
 1700|      0|    return _.diag(SPV_ERROR_INVALID_ID, inst)
 1701|      0|           << "Operand type must be a pointer";
 1702|      0|  }
 1703|       |
 1704|      0|  spv::StorageClass sc = op1_type->GetOperandAs<spv::StorageClass>(1u);
 1705|      0|  if (_.addressing_model() == spv::AddressingModel::Logical) {
  ------------------
  |  Branch (1705:7): [True: 0, False: 0]
  ------------------
 1706|      0|    if (sc != spv::StorageClass::Workgroup &&
  ------------------
  |  Branch (1706:9): [True: 0, False: 0]
  ------------------
 1707|      0|        sc != spv::StorageClass::StorageBuffer) {
  ------------------
  |  Branch (1707:9): [True: 0, False: 0]
  ------------------
 1708|      0|      return _.diag(SPV_ERROR_INVALID_ID, inst)
 1709|      0|             << "Invalid pointer storage class";
 1710|      0|    }
 1711|       |
 1712|      0|    if (sc == spv::StorageClass::Workgroup &&
  ------------------
  |  Branch (1712:9): [True: 0, False: 0]
  ------------------
 1713|      0|        !_.HasCapability(spv::Capability::VariablePointers)) {
  ------------------
  |  Branch (1713:9): [True: 0, False: 0]
  ------------------
 1714|      0|      return _.diag(SPV_ERROR_INVALID_ID, inst)
 1715|      0|             << "Workgroup storage class pointer requires VariablePointers "
 1716|      0|                "capability to be specified";
 1717|      0|    }
 1718|      0|  } else if (sc == spv::StorageClass::PhysicalStorageBuffer) {
  ------------------
  |  Branch (1718:14): [True: 0, False: 0]
  ------------------
 1719|      0|    return _.diag(SPV_ERROR_INVALID_ID, inst)
 1720|      0|           << "Cannot use a pointer in the PhysicalStorageBuffer storage class";
 1721|      0|  }
 1722|       |
 1723|      0|  return SPV_SUCCESS;
 1724|      0|}

_ZN8spvtools3val23ValidateMemorySemanticsERNS0_17ValidationState_tEPKNS0_11InstructionEjj:
   29|    389|                                     uint32_t memory_scope) {
   30|    389|  const spv::Op opcode = inst->opcode();
   31|    389|  const auto id = inst->GetOperandAs<const uint32_t>(operand_index);
   32|    389|  bool is_int32 = false, is_const_int32 = false;
   33|    389|  uint32_t value = 0;
   34|    389|  std::tie(is_int32, is_const_int32, value) = _.EvalInt32IfConst(id);
   35|       |
   36|    389|  if (!is_int32) {
  ------------------
  |  Branch (36:7): [True: 1, False: 388]
  ------------------
   37|      1|    return _.diag(SPV_ERROR_INVALID_DATA, inst)
   38|      1|           << spvOpcodeString(opcode)
   39|      1|           << ": expected Memory Semantics to be a 32-bit int";
   40|      1|  }
   41|       |
   42|    388|  if (!is_const_int32) {
  ------------------
  |  Branch (42:7): [True: 15, False: 373]
  ------------------
   43|     15|    if (_.HasCapability(spv::Capability::Shader) &&
  ------------------
  |  Branch (43:9): [True: 0, False: 15]
  ------------------
   44|     15|        !_.HasCapability(spv::Capability::CooperativeMatrixNV)) {
  ------------------
  |  Branch (44:9): [True: 0, False: 0]
  ------------------
   45|      0|      return _.diag(SPV_ERROR_INVALID_DATA, inst)
   46|      0|             << "Memory Semantics ids must be OpConstant when Shader "
   47|      0|                "capability is present";
   48|      0|    }
   49|       |
   50|     15|    if (_.HasCapability(spv::Capability::Shader) &&
  ------------------
  |  Branch (50:9): [True: 0, False: 15]
  ------------------
   51|     15|        _.HasCapability(spv::Capability::CooperativeMatrixNV) &&
  ------------------
  |  Branch (51:9): [True: 0, False: 0]
  ------------------
   52|     15|        !spvOpcodeIsConstant(_.GetIdOpcode(id))) {
  ------------------
  |  Branch (52:9): [True: 0, False: 0]
  ------------------
   53|      0|      return _.diag(SPV_ERROR_INVALID_DATA, inst)
   54|      0|             << "Memory Semantics must be a constant instruction when "
   55|      0|                "CooperativeMatrixNV capability is present";
   56|      0|    }
   57|     15|    return SPV_SUCCESS;
   58|     15|  }
   59|       |
   60|    373|  const size_t num_memory_order_set_bits = spvtools::utils::CountSetBits(
   61|    373|      value & uint32_t(spv::MemorySemanticsMask::Acquire |
   62|    373|                       spv::MemorySemanticsMask::Release |
   63|    373|                       spv::MemorySemanticsMask::AcquireRelease |
   64|    373|                       spv::MemorySemanticsMask::SequentiallyConsistent));
   65|       |
   66|    373|  if (num_memory_order_set_bits > 1) {
  ------------------
  |  Branch (66:7): [True: 0, False: 373]
  ------------------
   67|      0|    return _.diag(SPV_ERROR_INVALID_DATA, inst)
   68|      0|           << spvOpcodeString(opcode)
   69|      0|           << ": Memory Semantics can have at most one of the following "
   70|      0|              "bits "
   71|      0|              "set: Acquire, Release, AcquireRelease or "
   72|      0|              "SequentiallyConsistent";
   73|      0|  }
   74|       |
   75|    373|  if (_.memory_model() == spv::MemoryModel::VulkanKHR &&
  ------------------
  |  Branch (75:7): [True: 0, False: 373]
  ------------------
   76|    373|      value & uint32_t(spv::MemorySemanticsMask::SequentiallyConsistent)) {
  ------------------
  |  Branch (76:7): [True: 0, False: 0]
  ------------------
   77|      0|    return _.diag(SPV_ERROR_INVALID_DATA, inst)
   78|      0|           << "SequentiallyConsistent memory "
   79|      0|              "semantics cannot be used with "
   80|      0|              "the VulkanKHR memory model.";
   81|      0|  }
   82|       |
   83|    373|  if (value & uint32_t(spv::MemorySemanticsMask::MakeAvailableKHR) &&
  ------------------
  |  Branch (83:7): [True: 1, False: 372]
  ------------------
   84|    373|      !_.HasCapability(spv::Capability::VulkanMemoryModelKHR)) {
  ------------------
  |  Branch (84:7): [True: 1, False: 0]
  ------------------
   85|      1|    return _.diag(SPV_ERROR_INVALID_DATA, inst)
   86|      1|           << spvOpcodeString(opcode)
   87|      1|           << ": Memory Semantics MakeAvailableKHR requires capability "
   88|      1|           << "VulkanMemoryModelKHR";
   89|      1|  }
   90|       |
   91|    372|  if (value & uint32_t(spv::MemorySemanticsMask::MakeVisibleKHR) &&
  ------------------
  |  Branch (91:7): [True: 1, False: 371]
  ------------------
   92|    372|      !_.HasCapability(spv::Capability::VulkanMemoryModelKHR)) {
  ------------------
  |  Branch (92:7): [True: 1, False: 0]
  ------------------
   93|      1|    return _.diag(SPV_ERROR_INVALID_DATA, inst)
   94|      1|           << spvOpcodeString(opcode)
   95|      1|           << ": Memory Semantics MakeVisibleKHR requires capability "
   96|      1|           << "VulkanMemoryModelKHR";
   97|      1|  }
   98|       |
   99|    371|  if (value & uint32_t(spv::MemorySemanticsMask::OutputMemoryKHR) &&
  ------------------
  |  Branch (99:7): [True: 1, False: 370]
  ------------------
  100|    371|      !_.HasCapability(spv::Capability::VulkanMemoryModelKHR)) {
  ------------------
  |  Branch (100:7): [True: 1, False: 0]
  ------------------
  101|      1|    return _.diag(SPV_ERROR_INVALID_DATA, inst)
  102|      1|           << spvOpcodeString(opcode)
  103|      1|           << ": Memory Semantics OutputMemoryKHR requires capability "
  104|      1|           << "VulkanMemoryModelKHR";
  105|      1|  }
  106|       |
  107|    370|  if (value & uint32_t(spv::MemorySemanticsMask::Volatile)) {
  ------------------
  |  Branch (107:7): [True: 0, False: 370]
  ------------------
  108|      0|    if (!_.HasCapability(spv::Capability::VulkanMemoryModelKHR)) {
  ------------------
  |  Branch (108:9): [True: 0, False: 0]
  ------------------
  109|      0|      return _.diag(SPV_ERROR_INVALID_DATA, inst)
  110|      0|             << spvOpcodeString(opcode)
  111|      0|             << ": Memory Semantics Volatile requires capability "
  112|      0|                "VulkanMemoryModelKHR";
  113|      0|    }
  114|       |
  115|      0|    if (!spvOpcodeIsAtomicOp(inst->opcode())) {
  ------------------
  |  Branch (115:9): [True: 0, False: 0]
  ------------------
  116|      0|      return _.diag(SPV_ERROR_INVALID_DATA, inst)
  117|      0|             << "Memory Semantics Volatile can only be used with atomic "
  118|      0|                "instructions";
  119|      0|    }
  120|      0|  }
  121|       |
  122|    370|  if (value & uint32_t(spv::MemorySemanticsMask::UniformMemory) &&
  ------------------
  |  Branch (122:7): [True: 122, False: 248]
  ------------------
  123|    370|      !_.HasCapability(spv::Capability::Shader)) {
  ------------------
  |  Branch (123:7): [True: 0, False: 122]
  ------------------
  124|      0|    return _.diag(SPV_ERROR_INVALID_DATA, inst)
  125|      0|           << spvOpcodeString(opcode)
  126|      0|           << ": Memory Semantics UniformMemory requires capability Shader";
  127|      0|  }
  128|       |
  129|       |  // Checking for spv::Capability::AtomicStorage is intentionally not done here.
  130|       |  // See https://github.com/KhronosGroup/glslang/issues/1618 for the reasoning
  131|       |  // why.
  132|       |
  133|    370|  if (value & uint32_t(spv::MemorySemanticsMask::MakeAvailableKHR |
  ------------------
  |  Branch (133:7): [True: 0, False: 370]
  ------------------
  134|    370|                       spv::MemorySemanticsMask::MakeVisibleKHR)) {
  135|      0|    const bool includes_storage_class =
  136|      0|        value & uint32_t(spv::MemorySemanticsMask::UniformMemory |
  137|      0|                         spv::MemorySemanticsMask::SubgroupMemory |
  138|      0|                         spv::MemorySemanticsMask::WorkgroupMemory |
  139|      0|                         spv::MemorySemanticsMask::CrossWorkgroupMemory |
  140|      0|                         spv::MemorySemanticsMask::AtomicCounterMemory |
  141|      0|                         spv::MemorySemanticsMask::ImageMemory |
  142|      0|                         spv::MemorySemanticsMask::OutputMemoryKHR);
  143|       |
  144|      0|    if (!includes_storage_class) {
  ------------------
  |  Branch (144:9): [True: 0, False: 0]
  ------------------
  145|      0|      return _.diag(SPV_ERROR_INVALID_DATA, inst)
  146|      0|             << spvOpcodeString(opcode)
  147|      0|             << ": expected Memory Semantics to include a storage class";
  148|      0|    }
  149|      0|  }
  150|       |
  151|    370|  if (value & uint32_t(spv::MemorySemanticsMask::MakeVisibleKHR) &&
  ------------------
  |  Branch (151:7): [True: 0, False: 370]
  ------------------
  152|    370|      !(value & uint32_t(spv::MemorySemanticsMask::Acquire |
  ------------------
  |  Branch (152:7): [True: 0, False: 0]
  ------------------
  153|      0|                         spv::MemorySemanticsMask::AcquireRelease))) {
  154|      0|    return _.diag(SPV_ERROR_INVALID_DATA, inst)
  155|      0|           << spvOpcodeString(opcode)
  156|      0|           << ": MakeVisibleKHR Memory Semantics also requires either Acquire "
  157|      0|              "or AcquireRelease Memory Semantics";
  158|      0|  }
  159|       |
  160|    370|  if (value & uint32_t(spv::MemorySemanticsMask::MakeAvailableKHR) &&
  ------------------
  |  Branch (160:7): [True: 0, False: 370]
  ------------------
  161|    370|      !(value & uint32_t(spv::MemorySemanticsMask::Release |
  ------------------
  |  Branch (161:7): [True: 0, False: 0]
  ------------------
  162|      0|                         spv::MemorySemanticsMask::AcquireRelease))) {
  163|      0|    return _.diag(SPV_ERROR_INVALID_DATA, inst)
  164|      0|           << spvOpcodeString(opcode)
  165|      0|           << ": MakeAvailableKHR Memory Semantics also requires either "
  166|      0|              "Release or AcquireRelease Memory Semantics";
  167|      0|  }
  168|       |
  169|    370|  if (spvIsVulkanEnv(_.context()->target_env)) {
  ------------------
  |  Branch (169:7): [True: 0, False: 370]
  ------------------
  170|      0|    const bool includes_storage_class =
  171|      0|        value & uint32_t(spv::MemorySemanticsMask::UniformMemory |
  172|      0|                         spv::MemorySemanticsMask::WorkgroupMemory |
  173|      0|                         spv::MemorySemanticsMask::ImageMemory |
  174|      0|                         spv::MemorySemanticsMask::OutputMemoryKHR);
  175|       |
  176|      0|    if (opcode == spv::Op::OpMemoryBarrier && !num_memory_order_set_bits) {
  ------------------
  |  Branch (176:9): [True: 0, False: 0]
  |  Branch (176:47): [True: 0, False: 0]
  ------------------
  177|      0|      return _.diag(SPV_ERROR_INVALID_DATA, inst)
  178|      0|             << _.VkErrorID(4732) << spvOpcodeString(opcode)
  179|      0|             << ": Vulkan specification requires Memory Semantics to have "
  180|      0|                "one "
  181|      0|                "of the following bits set: Acquire, Release, "
  182|      0|                "AcquireRelease "
  183|      0|                "or SequentiallyConsistent";
  184|      0|    } else if (opcode != spv::Op::OpMemoryBarrier &&
  ------------------
  |  Branch (184:16): [True: 0, False: 0]
  ------------------
  185|      0|               num_memory_order_set_bits) {
  ------------------
  |  Branch (185:16): [True: 0, False: 0]
  ------------------
  186|       |      // should leave only atomics and control barriers for Vulkan env
  187|      0|      bool memory_is_int32 = false, memory_is_const_int32 = false;
  188|      0|      uint32_t memory_value = 0;
  189|      0|      std::tie(memory_is_int32, memory_is_const_int32, memory_value) =
  190|      0|          _.EvalInt32IfConst(memory_scope);
  191|      0|      if (memory_is_int32 &&
  ------------------
  |  Branch (191:11): [True: 0, False: 0]
  ------------------
  192|      0|          spv::Scope(memory_value) == spv::Scope::Invocation) {
  ------------------
  |  Branch (192:11): [True: 0, False: 0]
  ------------------
  193|      0|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
  194|      0|               << _.VkErrorID(4641) << spvOpcodeString(opcode)
  195|      0|               << ": Vulkan specification requires Memory Semantics to be None "
  196|      0|                  "if used with Invocation Memory Scope";
  197|      0|      }
  198|      0|    }
  199|       |
  200|      0|    if (opcode == spv::Op::OpMemoryBarrier && !includes_storage_class) {
  ------------------
  |  Branch (200:9): [True: 0, False: 0]
  |  Branch (200:47): [True: 0, False: 0]
  ------------------
  201|      0|      return _.diag(SPV_ERROR_INVALID_DATA, inst)
  202|      0|             << _.VkErrorID(4733) << spvOpcodeString(opcode)
  203|      0|             << ": expected Memory Semantics to include a Vulkan-supported "
  204|      0|                "storage class";
  205|      0|    }
  206|       |
  207|       |#if 0
  208|       |    // TODO(atgoo@github.com): this check fails Vulkan CTS, reenable once fixed.
  209|       |    if (opcode == spv::Op::OpControlBarrier && value && !includes_storage_class) {
  210|       |      return _.diag(SPV_ERROR_INVALID_DATA, inst)
  211|       |             << spvOpcodeString(opcode)
  212|       |             << ": expected Memory Semantics to include a Vulkan-supported "
  213|       |                "storage class if Memory Semantics is not None";
  214|       |    }
  215|       |#endif
  216|      0|  }
  217|       |
  218|    370|  if (opcode == spv::Op::OpAtomicFlagClear &&
  ------------------
  |  Branch (218:7): [True: 0, False: 370]
  ------------------
  219|    370|      (value & uint32_t(spv::MemorySemanticsMask::Acquire) ||
  ------------------
  |  Branch (219:8): [True: 0, False: 0]
  ------------------
  220|      0|       value & uint32_t(spv::MemorySemanticsMask::AcquireRelease))) {
  ------------------
  |  Branch (220:8): [True: 0, False: 0]
  ------------------
  221|      0|    return _.diag(SPV_ERROR_INVALID_DATA, inst)
  222|      0|           << "Memory Semantics Acquire and AcquireRelease cannot be used "
  223|      0|              "with "
  224|      0|           << spvOpcodeString(opcode);
  225|      0|  }
  226|       |
  227|    370|  if (opcode == spv::Op::OpAtomicCompareExchange && operand_index == 5 &&
  ------------------
  |  Branch (227:7): [True: 0, False: 370]
  |  Branch (227:53): [True: 0, False: 0]
  ------------------
  228|    370|      (value & uint32_t(spv::MemorySemanticsMask::Release) ||
  ------------------
  |  Branch (228:8): [True: 0, False: 0]
  ------------------
  229|      0|       value & uint32_t(spv::MemorySemanticsMask::AcquireRelease))) {
  ------------------
  |  Branch (229:8): [True: 0, False: 0]
  ------------------
  230|      0|    return _.diag(SPV_ERROR_INVALID_DATA, inst)
  231|      0|           << spvOpcodeString(opcode)
  232|      0|           << ": Memory Semantics Release and AcquireRelease cannot be "
  233|      0|              "used "
  234|      0|              "for operand Unequal";
  235|      0|  }
  236|       |
  237|    370|  if (spvIsVulkanEnv(_.context()->target_env)) {
  ------------------
  |  Branch (237:7): [True: 0, False: 370]
  ------------------
  238|      0|    if (opcode == spv::Op::OpAtomicLoad &&
  ------------------
  |  Branch (238:9): [True: 0, False: 0]
  ------------------
  239|      0|        (value & uint32_t(spv::MemorySemanticsMask::Release) ||
  ------------------
  |  Branch (239:10): [True: 0, False: 0]
  ------------------
  240|      0|         value & uint32_t(spv::MemorySemanticsMask::AcquireRelease) ||
  ------------------
  |  Branch (240:10): [True: 0, False: 0]
  ------------------
  241|      0|         value & uint32_t(spv::MemorySemanticsMask::SequentiallyConsistent))) {
  ------------------
  |  Branch (241:10): [True: 0, False: 0]
  ------------------
  242|      0|      return _.diag(SPV_ERROR_INVALID_DATA, inst)
  243|      0|             << _.VkErrorID(4731)
  244|      0|             << "Vulkan spec disallows OpAtomicLoad with Memory Semantics "
  245|      0|                "Release, AcquireRelease and SequentiallyConsistent";
  246|      0|    }
  247|       |
  248|      0|    if (opcode == spv::Op::OpAtomicStore &&
  ------------------
  |  Branch (248:9): [True: 0, False: 0]
  ------------------
  249|      0|        (value & uint32_t(spv::MemorySemanticsMask::Acquire) ||
  ------------------
  |  Branch (249:10): [True: 0, False: 0]
  ------------------
  250|      0|         value & uint32_t(spv::MemorySemanticsMask::AcquireRelease) ||
  ------------------
  |  Branch (250:10): [True: 0, False: 0]
  ------------------
  251|      0|         value & uint32_t(spv::MemorySemanticsMask::SequentiallyConsistent))) {
  ------------------
  |  Branch (251:10): [True: 0, False: 0]
  ------------------
  252|      0|      return _.diag(SPV_ERROR_INVALID_DATA, inst)
  253|      0|             << _.VkErrorID(4730)
  254|      0|             << "Vulkan spec disallows OpAtomicStore with Memory Semantics "
  255|      0|                "Acquire, AcquireRelease and SequentiallyConsistent";
  256|      0|    }
  257|      0|  }
  258|       |
  259|       |  // TODO(atgoo@github.com) Add checks for OpenCL and OpenGL environments.
  260|       |
  261|    370|  return SPV_SUCCESS;
  262|    370|}

_ZN8spvtools3val15MeshShadingPassERNS0_17ValidationState_tEPKNS0_11InstructionE:
   25|   285k|spv_result_t MeshShadingPass(ValidationState_t& _, const Instruction* inst) {
   26|   285k|  const spv::Op opcode = inst->opcode();
   27|   285k|  switch (opcode) {
   28|      0|    case spv::Op::OpEmitMeshTasksEXT: {
  ------------------
  |  Branch (28:5): [True: 0, False: 285k]
  ------------------
   29|      0|      _.function(inst->function()->id())
   30|      0|          ->RegisterExecutionModelLimitation(
   31|      0|              [](spv::ExecutionModel model, std::string* message) {
   32|      0|                if (model != spv::ExecutionModel::TaskEXT) {
   33|      0|                  if (message) {
   34|      0|                    *message =
   35|      0|                        "OpEmitMeshTasksEXT requires TaskEXT execution model";
   36|      0|                  }
   37|      0|                  return false;
   38|      0|                }
   39|      0|                return true;
   40|      0|              });
   41|       |
   42|      0|      const uint32_t group_count_x = _.GetOperandTypeId(inst, 0);
   43|      0|      if (!_.IsUnsignedIntScalarType(group_count_x) ||
  ------------------
  |  Branch (43:11): [True: 0, False: 0]
  ------------------
   44|      0|          _.GetBitWidth(group_count_x) != 32) {
  ------------------
  |  Branch (44:11): [True: 0, False: 0]
  ------------------
   45|      0|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
   46|      0|               << "Group Count X must be a 32-bit unsigned int scalar";
   47|      0|      }
   48|       |
   49|      0|      const uint32_t group_count_y = _.GetOperandTypeId(inst, 1);
   50|      0|      if (!_.IsUnsignedIntScalarType(group_count_y) ||
  ------------------
  |  Branch (50:11): [True: 0, False: 0]
  ------------------
   51|      0|          _.GetBitWidth(group_count_y) != 32) {
  ------------------
  |  Branch (51:11): [True: 0, False: 0]
  ------------------
   52|      0|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
   53|      0|               << "Group Count Y must be a 32-bit unsigned int scalar";
   54|      0|      }
   55|       |
   56|      0|      const uint32_t group_count_z = _.GetOperandTypeId(inst, 2);
   57|      0|      if (!_.IsUnsignedIntScalarType(group_count_z) ||
  ------------------
  |  Branch (57:11): [True: 0, False: 0]
  ------------------
   58|      0|          _.GetBitWidth(group_count_z) != 32) {
  ------------------
  |  Branch (58:11): [True: 0, False: 0]
  ------------------
   59|      0|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
   60|      0|               << "Group Count Z must be a 32-bit unsigned int scalar";
   61|      0|      }
   62|       |
   63|      0|      if (inst->operands().size() == 4) {
  ------------------
  |  Branch (63:11): [True: 0, False: 0]
  ------------------
   64|      0|        const auto payload = _.FindDef(inst->GetOperandAs<uint32_t>(3));
   65|      0|        if (payload->opcode() != spv::Op::OpVariable) {
  ------------------
  |  Branch (65:13): [True: 0, False: 0]
  ------------------
   66|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
   67|      0|                 << "Payload must be the result of a OpVariable";
   68|      0|        }
   69|      0|        if (payload->GetOperandAs<spv::StorageClass>(2) !=
  ------------------
  |  Branch (69:13): [True: 0, False: 0]
  ------------------
   70|      0|            spv::StorageClass::TaskPayloadWorkgroupEXT) {
   71|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
   72|      0|                 << "Payload OpVariable must have a storage class of "
   73|      0|                    "TaskPayloadWorkgroupEXT";
   74|      0|        }
   75|      0|      }
   76|      0|      break;
   77|      0|    }
   78|       |
   79|      0|    case spv::Op::OpSetMeshOutputsEXT: {
  ------------------
  |  Branch (79:5): [True: 0, False: 285k]
  ------------------
   80|      0|      _.function(inst->function()->id())
   81|      0|          ->RegisterExecutionModelLimitation(
   82|      0|              [](spv::ExecutionModel model, std::string* message) {
   83|      0|                if (model != spv::ExecutionModel::MeshEXT) {
   84|      0|                  if (message) {
   85|      0|                    *message =
   86|      0|                        "OpSetMeshOutputsEXT requires MeshEXT execution model";
   87|      0|                  }
   88|      0|                  return false;
   89|      0|                }
   90|      0|                return true;
   91|      0|              });
   92|       |
   93|      0|      const uint32_t vertex_count = _.GetOperandTypeId(inst, 0);
   94|      0|      if (!_.IsUnsignedIntScalarType(vertex_count) ||
  ------------------
  |  Branch (94:11): [True: 0, False: 0]
  ------------------
   95|      0|          _.GetBitWidth(vertex_count) != 32) {
  ------------------
  |  Branch (95:11): [True: 0, False: 0]
  ------------------
   96|      0|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
   97|      0|               << "Vertex Count must be a 32-bit unsigned int scalar";
   98|      0|      }
   99|       |
  100|      0|      const uint32_t primitive_count = _.GetOperandTypeId(inst, 1);
  101|      0|      if (!_.IsUnsignedIntScalarType(primitive_count) ||
  ------------------
  |  Branch (101:11): [True: 0, False: 0]
  ------------------
  102|      0|          _.GetBitWidth(primitive_count) != 32) {
  ------------------
  |  Branch (102:11): [True: 0, False: 0]
  ------------------
  103|      0|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
  104|      0|               << "Primitive Count must be a 32-bit unsigned int scalar";
  105|      0|      }
  106|       |
  107|      0|      break;
  108|      0|    }
  109|       |
  110|      0|    case spv::Op::OpWritePackedPrimitiveIndices4x8NV: {
  ------------------
  |  Branch (110:5): [True: 0, False: 285k]
  ------------------
  111|       |      // No validation rules (for the moment).
  112|      0|      break;
  113|      0|    }
  114|       |
  115|   285k|    default:
  ------------------
  |  Branch (115:5): [True: 285k, False: 0]
  ------------------
  116|   285k|      break;
  117|   285k|  }
  118|       |
  119|   285k|  return SPV_SUCCESS;
  120|   285k|}

_ZN8spvtools3val8MiscPassERNS0_17ValidationState_tEPKNS0_11InstructionE:
  106|   286k|spv_result_t MiscPass(ValidationState_t& _, const Instruction* inst) {
  107|   286k|  switch (inst->opcode()) {
  108|    372|    case spv::Op::OpUndef:
  ------------------
  |  Branch (108:5): [True: 372, False: 286k]
  ------------------
  109|    372|      if (auto error = ValidateUndef(_, inst)) return error;
  ------------------
  |  Branch (109:16): [True: 2, False: 370]
  ------------------
  110|    370|      break;
  111|   286k|    default:
  ------------------
  |  Branch (111:5): [True: 286k, False: 372]
  ------------------
  112|   286k|      break;
  113|   286k|  }
  114|   286k|  switch (inst->opcode()) {
  115|      0|    case spv::Op::OpBeginInvocationInterlockEXT:
  ------------------
  |  Branch (115:5): [True: 0, False: 286k]
  ------------------
  116|      0|    case spv::Op::OpEndInvocationInterlockEXT:
  ------------------
  |  Branch (116:5): [True: 0, False: 286k]
  ------------------
  117|      0|      _.function(inst->function()->id())
  118|      0|          ->RegisterExecutionModelLimitation(
  119|      0|              spv::ExecutionModel::Fragment,
  120|      0|              "OpBeginInvocationInterlockEXT/OpEndInvocationInterlockEXT "
  121|      0|              "require Fragment execution model");
  122|       |
  123|      0|      _.function(inst->function()->id())
  124|      0|          ->RegisterLimitation([](const ValidationState_t& state,
  125|      0|                                  const Function* entry_point,
  126|      0|                                  std::string* message) {
  127|      0|            const auto* execution_modes =
  128|      0|                state.GetExecutionModes(entry_point->id());
  129|       |
  130|      0|            auto find_interlock = [](const spv::ExecutionMode& mode) {
  131|      0|              switch (mode) {
  132|      0|                case spv::ExecutionMode::PixelInterlockOrderedEXT:
  133|      0|                case spv::ExecutionMode::PixelInterlockUnorderedEXT:
  134|      0|                case spv::ExecutionMode::SampleInterlockOrderedEXT:
  135|      0|                case spv::ExecutionMode::SampleInterlockUnorderedEXT:
  136|      0|                case spv::ExecutionMode::ShadingRateInterlockOrderedEXT:
  137|      0|                case spv::ExecutionMode::ShadingRateInterlockUnorderedEXT:
  138|      0|                  return true;
  139|      0|                default:
  140|      0|                  return false;
  141|      0|              }
  142|      0|            };
  143|       |
  144|      0|            bool found = false;
  145|      0|            if (execution_modes) {
  146|      0|              auto i = std::find_if(execution_modes->begin(),
  147|      0|                                    execution_modes->end(), find_interlock);
  148|      0|              found = (i != execution_modes->end());
  149|      0|            }
  150|       |
  151|      0|            if (!found) {
  152|      0|              *message =
  153|      0|                  "OpBeginInvocationInterlockEXT/OpEndInvocationInterlockEXT "
  154|      0|                  "require a fragment shader interlock execution mode.";
  155|      0|              return false;
  156|      0|            }
  157|      0|            return true;
  158|      0|          });
  159|      0|      break;
  160|      0|    case spv::Op::OpDemoteToHelperInvocationEXT:
  ------------------
  |  Branch (160:5): [True: 0, False: 286k]
  ------------------
  161|      0|      _.function(inst->function()->id())
  162|      0|          ->RegisterExecutionModelLimitation(
  163|      0|              spv::ExecutionModel::Fragment,
  164|      0|              "OpDemoteToHelperInvocationEXT requires Fragment execution "
  165|      0|              "model");
  166|      0|      break;
  167|      0|    case spv::Op::OpIsHelperInvocationEXT: {
  ------------------
  |  Branch (167:5): [True: 0, False: 286k]
  ------------------
  168|      0|      const uint32_t result_type = inst->type_id();
  169|      0|      _.function(inst->function()->id())
  170|      0|          ->RegisterExecutionModelLimitation(
  171|      0|              spv::ExecutionModel::Fragment,
  172|      0|              "OpIsHelperInvocationEXT requires Fragment execution model");
  173|      0|      if (!_.IsBoolScalarType(result_type))
  ------------------
  |  Branch (173:11): [True: 0, False: 0]
  ------------------
  174|      0|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
  175|      0|               << "Expected bool scalar type as Result Type: "
  176|      0|               << spvOpcodeString(inst->opcode());
  177|      0|      break;
  178|      0|    }
  179|      0|    case spv::Op::OpReadClockKHR:
  ------------------
  |  Branch (179:5): [True: 0, False: 286k]
  ------------------
  180|      0|      if (auto error = ValidateShaderClock(_, inst)) {
  ------------------
  |  Branch (180:16): [True: 0, False: 0]
  ------------------
  181|      0|        return error;
  182|      0|      }
  183|      0|      break;
  184|      0|    case spv::Op::OpAssumeTrueKHR:
  ------------------
  |  Branch (184:5): [True: 0, False: 286k]
  ------------------
  185|      0|      if (auto error = ValidateAssumeTrue(_, inst)) {
  ------------------
  |  Branch (185:16): [True: 0, False: 0]
  ------------------
  186|      0|        return error;
  187|      0|      }
  188|      0|      break;
  189|      0|    case spv::Op::OpExpectKHR:
  ------------------
  |  Branch (189:5): [True: 0, False: 286k]
  ------------------
  190|      0|      if (auto error = ValidateExpect(_, inst)) {
  ------------------
  |  Branch (190:16): [True: 0, False: 0]
  ------------------
  191|      0|        return error;
  192|      0|      }
  193|      0|      break;
  194|   286k|    default:
  ------------------
  |  Branch (194:5): [True: 286k, False: 0]
  ------------------
  195|   286k|      break;
  196|   286k|  }
  197|       |
  198|   286k|  return SPV_SUCCESS;
  199|   286k|}
validate_misc.cpp:_ZN8spvtools3val12_GLOBAL__N_113ValidateUndefERNS0_17ValidationState_tEPKNS0_11InstructionE:
   28|    372|spv_result_t ValidateUndef(ValidationState_t& _, const Instruction* inst) {
   29|    372|  if (_.IsVoidType(inst->type_id())) {
  ------------------
  |  Branch (29:7): [True: 1, False: 371]
  ------------------
   30|      1|    return _.diag(SPV_ERROR_INVALID_ID, inst)
   31|      1|           << "Cannot create undefined values with void type";
   32|      1|  }
   33|    371|  if (_.HasCapability(spv::Capability::Shader) &&
  ------------------
  |  Branch (33:7): [True: 361, False: 10]
  ------------------
   34|    371|      _.ContainsLimitedUseIntOrFloatType(inst->type_id()) &&
  ------------------
  |  Branch (34:7): [True: 1, False: 360]
  ------------------
   35|    371|      !_.IsPointerType(inst->type_id())) {
  ------------------
  |  Branch (35:7): [True: 1, False: 0]
  ------------------
   36|      1|    return _.diag(SPV_ERROR_INVALID_ID, inst)
   37|      1|           << "Cannot create undefined values with 8- or 16-bit types";
   38|      1|  }
   39|       |
   40|    370|  return SPV_SUCCESS;
   41|    371|}

_ZN8spvtools3val15ModeSettingPassERNS0_17ValidationState_tEPKNS0_11InstructionE:
  636|   286k|spv_result_t ModeSettingPass(ValidationState_t& _, const Instruction* inst) {
  637|   286k|  switch (inst->opcode()) {
  638|  1.77k|    case spv::Op::OpEntryPoint:
  ------------------
  |  Branch (638:5): [True: 1.77k, False: 284k]
  ------------------
  639|  1.77k|      if (auto error = ValidateEntryPoint(_, inst)) return error;
  ------------------
  |  Branch (639:16): [True: 22, False: 1.75k]
  ------------------
  640|  1.75k|      break;
  641|  1.75k|    case spv::Op::OpExecutionMode:
  ------------------
  |  Branch (641:5): [True: 1.49k, False: 284k]
  ------------------
  642|  1.49k|    case spv::Op::OpExecutionModeId:
  ------------------
  |  Branch (642:5): [True: 0, False: 286k]
  ------------------
  643|  1.49k|      if (auto error = ValidateExecutionMode(_, inst)) return error;
  ------------------
  |  Branch (643:16): [True: 27, False: 1.47k]
  ------------------
  644|  1.47k|      break;
  645|  3.66k|    case spv::Op::OpMemoryModel:
  ------------------
  |  Branch (645:5): [True: 3.66k, False: 282k]
  ------------------
  646|  3.66k|      if (auto error = ValidateMemoryModel(_, inst)) return error;
  ------------------
  |  Branch (646:16): [True: 0, False: 3.66k]
  ------------------
  647|  3.66k|      break;
  648|   279k|    default:
  ------------------
  |  Branch (648:5): [True: 279k, False: 6.94k]
  ------------------
  649|   279k|      break;
  650|   286k|  }
  651|   286k|  return SPV_SUCCESS;
  652|   286k|}
validate_mode_setting.cpp:_ZN8spvtools3val12_GLOBAL__N_118ValidateEntryPointERNS0_17ValidationState_tEPKNS0_11InstructionE:
   27|  1.77k|spv_result_t ValidateEntryPoint(ValidationState_t& _, const Instruction* inst) {
   28|  1.77k|  const auto entry_point_id = inst->GetOperandAs<uint32_t>(1);
   29|  1.77k|  auto entry_point = _.FindDef(entry_point_id);
   30|  1.77k|  if (!entry_point || spv::Op::OpFunction != entry_point->opcode()) {
  ------------------
  |  Branch (30:7): [True: 0, False: 1.77k]
  |  Branch (30:23): [True: 7, False: 1.77k]
  ------------------
   31|      7|    return _.diag(SPV_ERROR_INVALID_ID, inst)
   32|      7|           << "OpEntryPoint Entry Point <id> " << _.getIdName(entry_point_id)
   33|      7|           << " is not a function.";
   34|      7|  }
   35|       |
   36|       |  // Only check the shader execution models
   37|  1.77k|  const spv::ExecutionModel execution_model =
   38|  1.77k|      inst->GetOperandAs<spv::ExecutionModel>(0);
   39|  1.77k|  if (execution_model != spv::ExecutionModel::Kernel) {
  ------------------
  |  Branch (39:7): [True: 1.77k, False: 0]
  ------------------
   40|  1.77k|    const auto entry_point_type_id = entry_point->GetOperandAs<uint32_t>(3);
   41|  1.77k|    const auto entry_point_type = _.FindDef(entry_point_type_id);
   42|  1.77k|    if (!entry_point_type || 3 != entry_point_type->words().size()) {
  ------------------
  |  Branch (42:9): [True: 0, False: 1.77k]
  |  Branch (42:30): [True: 1, False: 1.77k]
  ------------------
   43|      1|      return _.diag(SPV_ERROR_INVALID_ID, inst)
   44|      1|             << _.VkErrorID(4633) << "OpEntryPoint Entry Point <id> "
   45|      1|             << _.getIdName(entry_point_id)
   46|      1|             << "s function parameter count is not zero.";
   47|      1|    }
   48|  1.77k|  }
   49|       |
   50|  1.77k|  auto return_type = _.FindDef(entry_point->type_id());
   51|  1.77k|  if (!return_type || spv::Op::OpTypeVoid != return_type->opcode()) {
  ------------------
  |  Branch (51:7): [True: 0, False: 1.77k]
  |  Branch (51:23): [True: 2, False: 1.76k]
  ------------------
   52|      2|    return _.diag(SPV_ERROR_INVALID_ID, inst)
   53|      2|           << _.VkErrorID(4633) << "OpEntryPoint Entry Point <id> "
   54|      2|           << _.getIdName(entry_point_id)
   55|      2|           << "s function return type is not void.";
   56|      2|  }
   57|       |
   58|  1.76k|  const auto* execution_modes = _.GetExecutionModes(entry_point_id);
   59|  1.76k|  if (_.HasCapability(spv::Capability::Shader)) {
  ------------------
  |  Branch (59:7): [True: 1.76k, False: 0]
  ------------------
   60|  1.76k|    switch (execution_model) {
   61|  1.24k|      case spv::ExecutionModel::Fragment:
  ------------------
  |  Branch (61:7): [True: 1.24k, False: 528]
  ------------------
   62|  1.24k|        if (execution_modes &&
  ------------------
  |  Branch (62:13): [True: 1.23k, False: 3]
  |  Branch (62:13): [True: 0, False: 1.24k]
  ------------------
   63|  1.24k|            execution_modes->count(spv::ExecutionMode::OriginUpperLeft) &&
  ------------------
  |  Branch (63:13): [True: 1.17k, False: 66]
  ------------------
   64|  1.24k|            execution_modes->count(spv::ExecutionMode::OriginLowerLeft)) {
  ------------------
  |  Branch (64:13): [True: 0, False: 1.17k]
  ------------------
   65|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
   66|      0|                 << "Fragment execution model entry points can only specify "
   67|      0|                    "one of OriginUpperLeft or OriginLowerLeft execution "
   68|      0|                    "modes.";
   69|      0|        }
   70|  1.24k|        if (!execution_modes ||
  ------------------
  |  Branch (70:13): [True: 3, False: 1.23k]
  |  Branch (70:13): [True: 6, False: 1.23k]
  ------------------
   71|  1.24k|            (!execution_modes->count(spv::ExecutionMode::OriginUpperLeft) &&
  ------------------
  |  Branch (71:14): [True: 66, False: 1.17k]
  ------------------
   72|  1.23k|             !execution_modes->count(spv::ExecutionMode::OriginLowerLeft))) {
  ------------------
  |  Branch (72:14): [True: 3, False: 63]
  ------------------
   73|      6|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
   74|      6|                 << "Fragment execution model entry points require either an "
   75|      6|                    "OriginUpperLeft or OriginLowerLeft execution mode.";
   76|      6|        }
   77|  1.23k|        if (execution_modes &&
  ------------------
  |  Branch (77:13): [True: 1.23k, False: 0]
  ------------------
   78|  1.23k|            1 < std::count_if(execution_modes->begin(), execution_modes->end(),
  ------------------
  |  Branch (78:13): [True: 1, False: 1.23k]
  ------------------
   79|  1.23k|                              [](const spv::ExecutionMode& mode) {
   80|  1.23k|                                switch (mode) {
   81|  1.23k|                                  case spv::ExecutionMode::DepthGreater:
   82|  1.23k|                                  case spv::ExecutionMode::DepthLess:
   83|  1.23k|                                  case spv::ExecutionMode::DepthUnchanged:
   84|  1.23k|                                    return true;
   85|  1.23k|                                  default:
   86|  1.23k|                                    return false;
   87|  1.23k|                                }
   88|  1.23k|                              })) {
   89|      1|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
   90|      1|                 << "Fragment execution model entry points can specify at most "
   91|      1|                    "one of DepthGreater, DepthLess or DepthUnchanged "
   92|      1|                    "execution modes.";
   93|      1|        }
   94|  1.23k|        if (execution_modes &&
  ------------------
  |  Branch (94:13): [True: 1.23k, False: 0]
  ------------------
   95|  1.23k|            1 < std::count_if(
  ------------------
  |  Branch (95:13): [True: 0, False: 1.23k]
  ------------------
   96|  1.23k|                    execution_modes->begin(), execution_modes->end(),
   97|  1.23k|                    [](const spv::ExecutionMode& mode) {
   98|  1.23k|                      switch (mode) {
   99|  1.23k|                        case spv::ExecutionMode::PixelInterlockOrderedEXT:
  100|  1.23k|                        case spv::ExecutionMode::PixelInterlockUnorderedEXT:
  101|  1.23k|                        case spv::ExecutionMode::SampleInterlockOrderedEXT:
  102|  1.23k|                        case spv::ExecutionMode::SampleInterlockUnorderedEXT:
  103|  1.23k|                        case spv::ExecutionMode::ShadingRateInterlockOrderedEXT:
  104|  1.23k|                        case spv::ExecutionMode::
  105|  1.23k|                            ShadingRateInterlockUnorderedEXT:
  106|  1.23k|                          return true;
  107|  1.23k|                        default:
  108|  1.23k|                          return false;
  109|  1.23k|                      }
  110|  1.23k|                    })) {
  111|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
  112|      0|                 << "Fragment execution model entry points can specify at most "
  113|      0|                    "one fragment shader interlock execution mode.";
  114|      0|        }
  115|  1.23k|        if (execution_modes &&
  ------------------
  |  Branch (115:13): [True: 1.23k, False: 0]
  ------------------
  116|  1.23k|            1 < std::count_if(
  ------------------
  |  Branch (116:13): [True: 0, False: 1.23k]
  ------------------
  117|  1.23k|                    execution_modes->begin(), execution_modes->end(),
  118|  1.23k|                    [](const spv::ExecutionMode& mode) {
  119|  1.23k|                      switch (mode) {
  120|  1.23k|                        case spv::ExecutionMode::StencilRefUnchangedFrontAMD:
  121|  1.23k|                        case spv::ExecutionMode::StencilRefLessFrontAMD:
  122|  1.23k|                        case spv::ExecutionMode::StencilRefGreaterFrontAMD:
  123|  1.23k|                          return true;
  124|  1.23k|                        default:
  125|  1.23k|                          return false;
  126|  1.23k|                      }
  127|  1.23k|                    })) {
  128|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
  129|      0|                 << "Fragment execution model entry points can specify at most "
  130|      0|                    "one of StencilRefUnchangedFrontAMD, "
  131|      0|                    "StencilRefLessFrontAMD or StencilRefGreaterFrontAMD "
  132|      0|                    "execution modes.";
  133|      0|        }
  134|  1.23k|        if (execution_modes &&
  ------------------
  |  Branch (134:13): [True: 1.23k, False: 0]
  ------------------
  135|  1.23k|            1 < std::count_if(
  ------------------
  |  Branch (135:13): [True: 0, False: 1.23k]
  ------------------
  136|  1.23k|                    execution_modes->begin(), execution_modes->end(),
  137|  1.23k|                    [](const spv::ExecutionMode& mode) {
  138|  1.23k|                      switch (mode) {
  139|  1.23k|                        case spv::ExecutionMode::StencilRefUnchangedBackAMD:
  140|  1.23k|                        case spv::ExecutionMode::StencilRefLessBackAMD:
  141|  1.23k|                        case spv::ExecutionMode::StencilRefGreaterBackAMD:
  142|  1.23k|                          return true;
  143|  1.23k|                        default:
  144|  1.23k|                          return false;
  145|  1.23k|                      }
  146|  1.23k|                    })) {
  147|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
  148|      0|                 << "Fragment execution model entry points can specify at most "
  149|      0|                    "one of StencilRefUnchangedBackAMD, "
  150|      0|                    "StencilRefLessBackAMD or StencilRefGreaterBackAMD "
  151|      0|                    "execution modes.";
  152|      0|        }
  153|  1.23k|        break;
  154|  1.23k|      case spv::ExecutionModel::TessellationControl:
  ------------------
  |  Branch (154:7): [True: 106, False: 1.66k]
  ------------------
  155|    168|      case spv::ExecutionModel::TessellationEvaluation:
  ------------------
  |  Branch (155:7): [True: 62, False: 1.70k]
  ------------------
  156|    168|        if (execution_modes &&
  ------------------
  |  Branch (156:13): [True: 41, False: 127]
  ------------------
  157|    168|            1 < std::count_if(
  ------------------
  |  Branch (157:13): [True: 0, False: 41]
  ------------------
  158|     41|                    execution_modes->begin(), execution_modes->end(),
  159|     41|                    [](const spv::ExecutionMode& mode) {
  160|     41|                      switch (mode) {
  161|     41|                        case spv::ExecutionMode::SpacingEqual:
  162|     41|                        case spv::ExecutionMode::SpacingFractionalEven:
  163|     41|                        case spv::ExecutionMode::SpacingFractionalOdd:
  164|     41|                          return true;
  165|     41|                        default:
  166|     41|                          return false;
  167|     41|                      }
  168|     41|                    })) {
  169|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
  170|      0|                 << "Tessellation execution model entry points can specify at "
  171|      0|                    "most one of SpacingEqual, SpacingFractionalOdd or "
  172|      0|                    "SpacingFractionalEven execution modes.";
  173|      0|        }
  174|    168|        if (execution_modes &&
  ------------------
  |  Branch (174:13): [True: 41, False: 127]
  ------------------
  175|    168|            1 < std::count_if(execution_modes->begin(), execution_modes->end(),
  ------------------
  |  Branch (175:13): [True: 0, False: 41]
  ------------------
  176|     41|                              [](const spv::ExecutionMode& mode) {
  177|     41|                                switch (mode) {
  178|     41|                                  case spv::ExecutionMode::Triangles:
  179|     41|                                  case spv::ExecutionMode::Quads:
  180|     41|                                  case spv::ExecutionMode::Isolines:
  181|     41|                                    return true;
  182|     41|                                  default:
  183|     41|                                    return false;
  184|     41|                                }
  185|     41|                              })) {
  186|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
  187|      0|                 << "Tessellation execution model entry points can specify at "
  188|      0|                    "most one of Triangles, Quads or Isolines execution modes.";
  189|      0|        }
  190|    168|        if (execution_modes &&
  ------------------
  |  Branch (190:13): [True: 41, False: 127]
  ------------------
  191|    168|            1 < std::count_if(execution_modes->begin(), execution_modes->end(),
  ------------------
  |  Branch (191:13): [True: 0, False: 41]
  ------------------
  192|     41|                              [](const spv::ExecutionMode& mode) {
  193|     41|                                switch (mode) {
  194|     41|                                  case spv::ExecutionMode::VertexOrderCw:
  195|     41|                                  case spv::ExecutionMode::VertexOrderCcw:
  196|     41|                                    return true;
  197|     41|                                  default:
  198|     41|                                    return false;
  199|     41|                                }
  200|     41|                              })) {
  201|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
  202|      0|                 << "Tessellation execution model entry points can specify at "
  203|      0|                    "most one of VertexOrderCw or VertexOrderCcw execution "
  204|      0|                    "modes.";
  205|      0|        }
  206|    168|        break;
  207|    168|      case spv::ExecutionModel::Geometry:
  ------------------
  |  Branch (207:7): [True: 32, False: 1.73k]
  ------------------
  208|     32|        if (!execution_modes ||
  ------------------
  |  Branch (208:13): [True: 1, False: 31]
  ------------------
  209|     32|            1 != std::count_if(
  ------------------
  |  Branch (209:13): [True: 2, False: 29]
  ------------------
  210|     31|                     execution_modes->begin(), execution_modes->end(),
  211|     31|                     [](const spv::ExecutionMode& mode) {
  212|     31|                       switch (mode) {
  213|     31|                         case spv::ExecutionMode::InputPoints:
  214|     31|                         case spv::ExecutionMode::InputLines:
  215|     31|                         case spv::ExecutionMode::InputLinesAdjacency:
  216|     31|                         case spv::ExecutionMode::Triangles:
  217|     31|                         case spv::ExecutionMode::InputTrianglesAdjacency:
  218|     31|                           return true;
  219|     31|                         default:
  220|     31|                           return false;
  221|     31|                       }
  222|     31|                     })) {
  223|      3|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
  224|      3|                 << "Geometry execution model entry points must specify "
  225|      3|                    "exactly one of InputPoints, InputLines, "
  226|      3|                    "InputLinesAdjacency, Triangles or InputTrianglesAdjacency "
  227|      3|                    "execution modes.";
  228|      3|        }
  229|     29|        if (!execution_modes ||
  ------------------
  |  Branch (229:13): [True: 0, False: 29]
  ------------------
  230|     29|            1 != std::count_if(execution_modes->begin(), execution_modes->end(),
  ------------------
  |  Branch (230:13): [True: 2, False: 27]
  ------------------
  231|     29|                               [](const spv::ExecutionMode& mode) {
  232|     29|                                 switch (mode) {
  233|     29|                                   case spv::ExecutionMode::OutputPoints:
  234|     29|                                   case spv::ExecutionMode::OutputLineStrip:
  235|     29|                                   case spv::ExecutionMode::OutputTriangleStrip:
  236|     29|                                     return true;
  237|     29|                                   default:
  238|     29|                                     return false;
  239|     29|                                 }
  240|     29|                               })) {
  241|      2|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
  242|      2|                 << "Geometry execution model entry points must specify "
  243|      2|                    "exactly one of OutputPoints, OutputLineStrip or "
  244|      2|                    "OutputTriangleStrip execution modes.";
  245|      2|        }
  246|     27|        break;
  247|     27|      case spv::ExecutionModel::MeshEXT:
  ------------------
  |  Branch (247:7): [True: 0, False: 1.76k]
  ------------------
  248|      0|        if (!execution_modes ||
  ------------------
  |  Branch (248:13): [True: 0, False: 0]
  ------------------
  249|      0|            1 != std::count_if(execution_modes->begin(), execution_modes->end(),
  ------------------
  |  Branch (249:13): [True: 0, False: 0]
  ------------------
  250|      0|                               [](const spv::ExecutionMode& mode) {
  251|      0|                                 switch (mode) {
  252|      0|                                   case spv::ExecutionMode::OutputPoints:
  253|      0|                                   case spv::ExecutionMode::OutputLinesEXT:
  254|      0|                                   case spv::ExecutionMode::OutputTrianglesEXT:
  255|      0|                                     return true;
  256|      0|                                   default:
  257|      0|                                     return false;
  258|      0|                                 }
  259|      0|                               })) {
  260|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
  261|      0|                 << "MeshEXT execution model entry points must specify exactly "
  262|      0|                    "one of OutputPoints, OutputLinesEXT, or "
  263|      0|                    "OutputTrianglesEXT Execution Modes.";
  264|      0|        } else if (2 != std::count_if(
  ------------------
  |  Branch (264:20): [True: 0, False: 0]
  ------------------
  265|      0|                            execution_modes->begin(), execution_modes->end(),
  266|      0|                            [](const spv::ExecutionMode& mode) {
  267|      0|                              switch (mode) {
  268|      0|                                case spv::ExecutionMode::OutputPrimitivesEXT:
  269|      0|                                case spv::ExecutionMode::OutputVertices:
  270|      0|                                  return true;
  271|      0|                                default:
  272|      0|                                  return false;
  273|      0|                              }
  274|      0|                            })) {
  275|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
  276|      0|                 << "MeshEXT execution model entry points must specify both "
  277|      0|                    "OutputPrimitivesEXT and OutputVertices Execution Modes.";
  278|      0|        }
  279|      0|        break;
  280|    328|      default:
  ------------------
  |  Branch (280:7): [True: 328, False: 1.44k]
  ------------------
  281|    328|        break;
  282|  1.76k|    }
  283|  1.76k|  }
  284|       |
  285|  1.75k|  if (spvIsVulkanEnv(_.context()->target_env)) {
  ------------------
  |  Branch (285:7): [True: 0, False: 1.75k]
  ------------------
  286|      0|    switch (execution_model) {
  287|      0|      case spv::ExecutionModel::GLCompute:
  ------------------
  |  Branch (287:7): [True: 0, False: 0]
  ------------------
  288|      0|        if (!execution_modes ||
  ------------------
  |  Branch (288:13): [True: 0, False: 0]
  |  Branch (288:13): [True: 0, False: 0]
  ------------------
  289|      0|            !execution_modes->count(spv::ExecutionMode::LocalSize)) {
  ------------------
  |  Branch (289:13): [True: 0, False: 0]
  ------------------
  290|      0|          bool ok = false;
  291|      0|          for (auto& i : _.ordered_instructions()) {
  ------------------
  |  Branch (291:24): [True: 0, False: 0]
  ------------------
  292|      0|            if (i.opcode() == spv::Op::OpDecorate) {
  ------------------
  |  Branch (292:17): [True: 0, False: 0]
  ------------------
  293|      0|              if (i.operands().size() > 2) {
  ------------------
  |  Branch (293:19): [True: 0, False: 0]
  ------------------
  294|      0|                if (i.GetOperandAs<spv::Decoration>(1) ==
  ------------------
  |  Branch (294:21): [True: 0, False: 0]
  ------------------
  295|      0|                        spv::Decoration::BuiltIn &&
  296|      0|                    i.GetOperandAs<spv::BuiltIn>(2) ==
  ------------------
  |  Branch (296:21): [True: 0, False: 0]
  ------------------
  297|      0|                        spv::BuiltIn::WorkgroupSize) {
  298|      0|                  ok = true;
  299|      0|                  break;
  300|      0|                }
  301|      0|              }
  302|      0|            }
  303|      0|            if (i.opcode() == spv::Op::OpExecutionModeId) {
  ------------------
  |  Branch (303:17): [True: 0, False: 0]
  ------------------
  304|      0|              const auto mode = i.GetOperandAs<spv::ExecutionMode>(1);
  305|      0|              if (mode == spv::ExecutionMode::LocalSizeId) {
  ------------------
  |  Branch (305:19): [True: 0, False: 0]
  ------------------
  306|      0|                ok = true;
  307|      0|                break;
  308|      0|              }
  309|      0|            }
  310|      0|          }
  311|      0|          if (!ok) {
  ------------------
  |  Branch (311:15): [True: 0, False: 0]
  ------------------
  312|      0|            return _.diag(SPV_ERROR_INVALID_DATA, inst)
  313|      0|                   << _.VkErrorID(6426)
  314|      0|                   << "In the Vulkan environment, GLCompute execution model "
  315|      0|                      "entry points require either the LocalSize or "
  316|      0|                      "LocalSizeId execution mode or an object decorated with "
  317|      0|                      "WorkgroupSize must be specified.";
  318|      0|          }
  319|      0|        }
  320|      0|        break;
  321|      0|      default:
  ------------------
  |  Branch (321:7): [True: 0, False: 0]
  ------------------
  322|      0|        break;
  323|      0|    }
  324|      0|  }
  325|       |
  326|  1.75k|  return SPV_SUCCESS;
  327|  1.75k|}
validate_mode_setting.cpp:_ZZN8spvtools3val12_GLOBAL__N_118ValidateEntryPointERNS0_17ValidationState_tEPKNS0_11InstructionEENK3$_0clERKN3spv13ExecutionModeE:
   79|  1.32k|                              [](const spv::ExecutionMode& mode) {
   80|  1.32k|                                switch (mode) {
   81|      5|                                  case spv::ExecutionMode::DepthGreater:
  ------------------
  |  Branch (81:35): [True: 5, False: 1.32k]
  ------------------
   82|     11|                                  case spv::ExecutionMode::DepthLess:
  ------------------
  |  Branch (82:35): [True: 6, False: 1.32k]
  ------------------
   83|     19|                                  case spv::ExecutionMode::DepthUnchanged:
  ------------------
  |  Branch (83:35): [True: 8, False: 1.32k]
  ------------------
   84|     19|                                    return true;
   85|  1.31k|                                  default:
  ------------------
  |  Branch (85:35): [True: 1.31k, False: 19]
  ------------------
   86|  1.31k|                                    return false;
   87|  1.32k|                                }
   88|  1.32k|                              })) {
validate_mode_setting.cpp:_ZZN8spvtools3val12_GLOBAL__N_118ValidateEntryPointERNS0_17ValidationState_tEPKNS0_11InstructionEENK3$_1clERKN3spv13ExecutionModeE:
   97|  1.32k|                    [](const spv::ExecutionMode& mode) {
   98|  1.32k|                      switch (mode) {
   99|      0|                        case spv::ExecutionMode::PixelInterlockOrderedEXT:
  ------------------
  |  Branch (99:25): [True: 0, False: 1.32k]
  ------------------
  100|      0|                        case spv::ExecutionMode::PixelInterlockUnorderedEXT:
  ------------------
  |  Branch (100:25): [True: 0, False: 1.32k]
  ------------------
  101|      0|                        case spv::ExecutionMode::SampleInterlockOrderedEXT:
  ------------------
  |  Branch (101:25): [True: 0, False: 1.32k]
  ------------------
  102|      0|                        case spv::ExecutionMode::SampleInterlockUnorderedEXT:
  ------------------
  |  Branch (102:25): [True: 0, False: 1.32k]
  ------------------
  103|      0|                        case spv::ExecutionMode::ShadingRateInterlockOrderedEXT:
  ------------------
  |  Branch (103:25): [True: 0, False: 1.32k]
  ------------------
  104|      0|                        case spv::ExecutionMode::
  ------------------
  |  Branch (104:25): [True: 0, False: 1.32k]
  ------------------
  105|      0|                            ShadingRateInterlockUnorderedEXT:
  106|      0|                          return true;
  107|  1.32k|                        default:
  ------------------
  |  Branch (107:25): [True: 1.32k, False: 0]
  ------------------
  108|  1.32k|                          return false;
  109|  1.32k|                      }
  110|  1.32k|                    })) {
validate_mode_setting.cpp:_ZZN8spvtools3val12_GLOBAL__N_118ValidateEntryPointERNS0_17ValidationState_tEPKNS0_11InstructionEENK3$_2clERKN3spv13ExecutionModeE:
  118|  1.32k|                    [](const spv::ExecutionMode& mode) {
  119|  1.32k|                      switch (mode) {
  120|      0|                        case spv::ExecutionMode::StencilRefUnchangedFrontAMD:
  ------------------
  |  Branch (120:25): [True: 0, False: 1.32k]
  ------------------
  121|      0|                        case spv::ExecutionMode::StencilRefLessFrontAMD:
  ------------------
  |  Branch (121:25): [True: 0, False: 1.32k]
  ------------------
  122|      0|                        case spv::ExecutionMode::StencilRefGreaterFrontAMD:
  ------------------
  |  Branch (122:25): [True: 0, False: 1.32k]
  ------------------
  123|      0|                          return true;
  124|  1.32k|                        default:
  ------------------
  |  Branch (124:25): [True: 1.32k, False: 0]
  ------------------
  125|  1.32k|                          return false;
  126|  1.32k|                      }
  127|  1.32k|                    })) {
validate_mode_setting.cpp:_ZZN8spvtools3val12_GLOBAL__N_118ValidateEntryPointERNS0_17ValidationState_tEPKNS0_11InstructionEENK3$_3clERKN3spv13ExecutionModeE:
  137|  1.32k|                    [](const spv::ExecutionMode& mode) {
  138|  1.32k|                      switch (mode) {
  139|      0|                        case spv::ExecutionMode::StencilRefUnchangedBackAMD:
  ------------------
  |  Branch (139:25): [True: 0, False: 1.32k]
  ------------------
  140|      0|                        case spv::ExecutionMode::StencilRefLessBackAMD:
  ------------------
  |  Branch (140:25): [True: 0, False: 1.32k]
  ------------------
  141|      0|                        case spv::ExecutionMode::StencilRefGreaterBackAMD:
  ------------------
  |  Branch (141:25): [True: 0, False: 1.32k]
  ------------------
  142|      0|                          return true;
  143|  1.32k|                        default:
  ------------------
  |  Branch (143:25): [True: 1.32k, False: 0]
  ------------------
  144|  1.32k|                          return false;
  145|  1.32k|                      }
  146|  1.32k|                    })) {
validate_mode_setting.cpp:_ZZN8spvtools3val12_GLOBAL__N_118ValidateEntryPointERNS0_17ValidationState_tEPKNS0_11InstructionEENK3$_4clERKN3spv13ExecutionModeE:
  159|     72|                    [](const spv::ExecutionMode& mode) {
  160|     72|                      switch (mode) {
  161|      6|                        case spv::ExecutionMode::SpacingEqual:
  ------------------
  |  Branch (161:25): [True: 6, False: 66]
  ------------------
  162|      9|                        case spv::ExecutionMode::SpacingFractionalEven:
  ------------------
  |  Branch (162:25): [True: 3, False: 69]
  ------------------
  163|     17|                        case spv::ExecutionMode::SpacingFractionalOdd:
  ------------------
  |  Branch (163:25): [True: 8, False: 64]
  ------------------
  164|     17|                          return true;
  165|     55|                        default:
  ------------------
  |  Branch (165:25): [True: 55, False: 17]
  ------------------
  166|     55|                          return false;
  167|     72|                      }
  168|     72|                    })) {
validate_mode_setting.cpp:_ZZN8spvtools3val12_GLOBAL__N_118ValidateEntryPointERNS0_17ValidationState_tEPKNS0_11InstructionEENK3$_5clERKN3spv13ExecutionModeE:
  176|     72|                              [](const spv::ExecutionMode& mode) {
  177|     72|                                switch (mode) {
  178|     13|                                  case spv::ExecutionMode::Triangles:
  ------------------
  |  Branch (178:35): [True: 13, False: 59]
  ------------------
  179|     19|                                  case spv::ExecutionMode::Quads:
  ------------------
  |  Branch (179:35): [True: 6, False: 66]
  ------------------
  180|     19|                                  case spv::ExecutionMode::Isolines:
  ------------------
  |  Branch (180:35): [True: 0, False: 72]
  ------------------
  181|     19|                                    return true;
  182|     53|                                  default:
  ------------------
  |  Branch (182:35): [True: 53, False: 19]
  ------------------
  183|     53|                                    return false;
  184|     72|                                }
  185|     72|                              })) {
validate_mode_setting.cpp:_ZZN8spvtools3val12_GLOBAL__N_118ValidateEntryPointERNS0_17ValidationState_tEPKNS0_11InstructionEENK3$_6clERKN3spv13ExecutionModeE:
  192|     72|                              [](const spv::ExecutionMode& mode) {
  193|     72|                                switch (mode) {
  194|      5|                                  case spv::ExecutionMode::VertexOrderCw:
  ------------------
  |  Branch (194:35): [True: 5, False: 67]
  ------------------
  195|      9|                                  case spv::ExecutionMode::VertexOrderCcw:
  ------------------
  |  Branch (195:35): [True: 4, False: 68]
  ------------------
  196|      9|                                    return true;
  197|     63|                                  default:
  ------------------
  |  Branch (197:35): [True: 63, False: 9]
  ------------------
  198|     63|                                    return false;
  199|     72|                                }
  200|     72|                              })) {
validate_mode_setting.cpp:_ZZN8spvtools3val12_GLOBAL__N_118ValidateEntryPointERNS0_17ValidationState_tEPKNS0_11InstructionEENK3$_7clERKN3spv13ExecutionModeE:
  211|     77|                     [](const spv::ExecutionMode& mode) {
  212|     77|                       switch (mode) {
  213|      3|                         case spv::ExecutionMode::InputPoints:
  ------------------
  |  Branch (213:26): [True: 3, False: 74]
  ------------------
  214|     11|                         case spv::ExecutionMode::InputLines:
  ------------------
  |  Branch (214:26): [True: 8, False: 69]
  ------------------
  215|     24|                         case spv::ExecutionMode::InputLinesAdjacency:
  ------------------
  |  Branch (215:26): [True: 13, False: 64]
  ------------------
  216|     28|                         case spv::ExecutionMode::Triangles:
  ------------------
  |  Branch (216:26): [True: 4, False: 73]
  ------------------
  217|     34|                         case spv::ExecutionMode::InputTrianglesAdjacency:
  ------------------
  |  Branch (217:26): [True: 6, False: 71]
  ------------------
  218|     34|                           return true;
  219|     43|                         default:
  ------------------
  |  Branch (219:26): [True: 43, False: 34]
  ------------------
  220|     43|                           return false;
  221|     77|                       }
  222|     77|                     })) {
validate_mode_setting.cpp:_ZZN8spvtools3val12_GLOBAL__N_118ValidateEntryPointERNS0_17ValidationState_tEPKNS0_11InstructionEENK3$_8clERKN3spv13ExecutionModeE:
  231|     72|                               [](const spv::ExecutionMode& mode) {
  232|     72|                                 switch (mode) {
  233|     13|                                   case spv::ExecutionMode::OutputPoints:
  ------------------
  |  Branch (233:36): [True: 13, False: 59]
  ------------------
  234|     21|                                   case spv::ExecutionMode::OutputLineStrip:
  ------------------
  |  Branch (234:36): [True: 8, False: 64]
  ------------------
  235|     32|                                   case spv::ExecutionMode::OutputTriangleStrip:
  ------------------
  |  Branch (235:36): [True: 11, False: 61]
  ------------------
  236|     32|                                     return true;
  237|     40|                                   default:
  ------------------
  |  Branch (237:36): [True: 40, False: 32]
  ------------------
  238|     40|                                     return false;
  239|     72|                                 }
  240|     72|                               })) {
validate_mode_setting.cpp:_ZN8spvtools3val12_GLOBAL__N_121ValidateExecutionModeERNS0_17ValidationState_tEPKNS0_11InstructionE:
  330|  1.49k|                                   const Instruction* inst) {
  331|  1.49k|  const auto entry_point_id = inst->GetOperandAs<uint32_t>(0);
  332|  1.49k|  const auto found = std::find(_.entry_points().cbegin(),
  333|  1.49k|                               _.entry_points().cend(), entry_point_id);
  334|  1.49k|  if (found == _.entry_points().cend()) {
  ------------------
  |  Branch (334:7): [True: 6, False: 1.49k]
  ------------------
  335|      6|    return _.diag(SPV_ERROR_INVALID_ID, inst)
  336|      6|           << "OpExecutionMode Entry Point <id> " << _.getIdName(entry_point_id)
  337|      6|           << " is not the Entry Point "
  338|      6|              "operand of an OpEntryPoint.";
  339|      6|  }
  340|       |
  341|  1.49k|  const auto mode = inst->GetOperandAs<spv::ExecutionMode>(1);
  342|  1.49k|  if (inst->opcode() == spv::Op::OpExecutionModeId) {
  ------------------
  |  Branch (342:7): [True: 0, False: 1.49k]
  ------------------
  343|      0|    size_t operand_count = inst->operands().size();
  344|      0|    for (size_t i = 2; i < operand_count; ++i) {
  ------------------
  |  Branch (344:24): [True: 0, False: 0]
  ------------------
  345|      0|      const auto operand_id = inst->GetOperandAs<uint32_t>(2);
  346|      0|      const auto* operand_inst = _.FindDef(operand_id);
  347|      0|      if (mode == spv::ExecutionMode::SubgroupsPerWorkgroupId ||
  ------------------
  |  Branch (347:11): [True: 0, False: 0]
  ------------------
  348|      0|          mode == spv::ExecutionMode::LocalSizeHintId ||
  ------------------
  |  Branch (348:11): [True: 0, False: 0]
  ------------------
  349|      0|          mode == spv::ExecutionMode::LocalSizeId) {
  ------------------
  |  Branch (349:11): [True: 0, False: 0]
  ------------------
  350|      0|        if (!spvOpcodeIsConstant(operand_inst->opcode())) {
  ------------------
  |  Branch (350:13): [True: 0, False: 0]
  ------------------
  351|      0|          return _.diag(SPV_ERROR_INVALID_ID, inst)
  352|      0|                 << "For OpExecutionModeId all Extra Operand ids must be "
  353|      0|                    "constant "
  354|      0|                    "instructions.";
  355|      0|        }
  356|      0|      } else {
  357|      0|        return _.diag(SPV_ERROR_INVALID_ID, inst)
  358|      0|               << "OpExecutionModeId is only valid when the Mode operand is an "
  359|      0|                  "execution mode that takes Extra Operands that are id "
  360|      0|                  "operands.";
  361|      0|      }
  362|      0|    }
  363|  1.49k|  } else if (mode == spv::ExecutionMode::SubgroupsPerWorkgroupId ||
  ------------------
  |  Branch (363:14): [True: 0, False: 1.49k]
  ------------------
  364|  1.49k|             mode == spv::ExecutionMode::LocalSizeHintId ||
  ------------------
  |  Branch (364:14): [True: 0, False: 1.49k]
  ------------------
  365|  1.49k|             mode == spv::ExecutionMode::LocalSizeId) {
  ------------------
  |  Branch (365:14): [True: 0, False: 1.49k]
  ------------------
  366|      0|    return _.diag(SPV_ERROR_INVALID_DATA, inst)
  367|      0|           << "OpExecutionMode is only valid when the Mode operand is an "
  368|      0|              "execution mode that takes no Extra Operands, or takes Extra "
  369|      0|              "Operands that are not id operands.";
  370|      0|  }
  371|       |
  372|  1.49k|  const auto* models = _.GetExecutionModels(entry_point_id);
  373|  1.49k|  switch (mode) {
  374|     16|    case spv::ExecutionMode::Invocations:
  ------------------
  |  Branch (374:5): [True: 16, False: 1.47k]
  ------------------
  375|     18|    case spv::ExecutionMode::InputPoints:
  ------------------
  |  Branch (375:5): [True: 2, False: 1.49k]
  ------------------
  376|     42|    case spv::ExecutionMode::InputLines:
  ------------------
  |  Branch (376:5): [True: 24, False: 1.46k]
  ------------------
  377|     60|    case spv::ExecutionMode::InputLinesAdjacency:
  ------------------
  |  Branch (377:5): [True: 18, False: 1.47k]
  ------------------
  378|     72|    case spv::ExecutionMode::InputTrianglesAdjacency:
  ------------------
  |  Branch (378:5): [True: 12, False: 1.48k]
  ------------------
  379|     83|    case spv::ExecutionMode::OutputLineStrip:
  ------------------
  |  Branch (379:5): [True: 11, False: 1.48k]
  ------------------
  380|    130|    case spv::ExecutionMode::OutputTriangleStrip:
  ------------------
  |  Branch (380:5): [True: 47, False: 1.44k]
  ------------------
  381|    130|      if (!std::all_of(models->begin(), models->end(),
  ------------------
  |  Branch (381:11): [True: 3, False: 127]
  ------------------
  382|    130|                       [](const spv::ExecutionModel& model) {
  383|    130|                         return model == spv::ExecutionModel::Geometry;
  384|    130|                       })) {
  385|      3|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
  386|      3|               << "Execution mode can only be used with the Geometry execution "
  387|      3|                  "model.";
  388|      3|      }
  389|    127|      break;
  390|    127|    case spv::ExecutionMode::OutputPoints:
  ------------------
  |  Branch (390:5): [True: 13, False: 1.47k]
  ------------------
  391|     13|      if (!std::all_of(
  ------------------
  |  Branch (391:11): [True: 1, False: 12]
  ------------------
  392|     13|              models->begin(), models->end(),
  393|     13|              [&_](const spv::ExecutionModel& model) {
  394|     13|                switch (model) {
  395|     13|                  case spv::ExecutionModel::Geometry:
  396|     13|                    return true;
  397|     13|                  case spv::ExecutionModel::MeshNV:
  398|     13|                    return _.HasCapability(spv::Capability::MeshShadingNV);
  399|     13|                  case spv::ExecutionModel::MeshEXT:
  400|     13|                    return _.HasCapability(spv::Capability::MeshShadingEXT);
  401|     13|                  default:
  402|     13|                    return false;
  403|     13|                }
  404|     13|              })) {
  405|      1|        if (_.HasCapability(spv::Capability::MeshShadingNV) ||
  ------------------
  |  Branch (405:13): [True: 0, False: 1]
  ------------------
  406|      1|            _.HasCapability(spv::Capability::MeshShadingEXT)) {
  ------------------
  |  Branch (406:13): [True: 0, False: 1]
  ------------------
  407|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
  408|      0|                 << "Execution mode can only be used with the Geometry "
  409|      0|                    "MeshNV or MeshEXT execution model.";
  410|      1|        } else {
  411|      1|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
  412|      1|                 << "Execution mode can only be used with the Geometry "
  413|      1|                    "execution "
  414|      1|                    "model.";
  415|      1|        }
  416|      1|      }
  417|     12|      break;
  418|     12|    case spv::ExecutionMode::SpacingEqual:
  ------------------
  |  Branch (418:5): [True: 11, False: 1.48k]
  ------------------
  419|     15|    case spv::ExecutionMode::SpacingFractionalEven:
  ------------------
  |  Branch (419:5): [True: 4, False: 1.48k]
  ------------------
  420|     27|    case spv::ExecutionMode::SpacingFractionalOdd:
  ------------------
  |  Branch (420:5): [True: 12, False: 1.48k]
  ------------------
  421|     60|    case spv::ExecutionMode::VertexOrderCw:
  ------------------
  |  Branch (421:5): [True: 33, False: 1.45k]
  ------------------
  422|     65|    case spv::ExecutionMode::VertexOrderCcw:
  ------------------
  |  Branch (422:5): [True: 5, False: 1.48k]
  ------------------
  423|     79|    case spv::ExecutionMode::PointMode:
  ------------------
  |  Branch (423:5): [True: 14, False: 1.47k]
  ------------------
  424|     85|    case spv::ExecutionMode::Quads:
  ------------------
  |  Branch (424:5): [True: 6, False: 1.48k]
  ------------------
  425|     85|    case spv::ExecutionMode::Isolines:
  ------------------
  |  Branch (425:5): [True: 0, False: 1.49k]
  ------------------
  426|     85|      if (!std::all_of(
  ------------------
  |  Branch (426:11): [True: 11, False: 74]
  ------------------
  427|     85|              models->begin(), models->end(),
  428|     85|              [](const spv::ExecutionModel& model) {
  429|     85|                return (model == spv::ExecutionModel::TessellationControl) ||
  430|     85|                       (model == spv::ExecutionModel::TessellationEvaluation);
  431|     85|              })) {
  432|     11|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
  433|     11|               << "Execution mode can only be used with a tessellation "
  434|     11|                  "execution model.";
  435|     11|      }
  436|     74|      break;
  437|     74|    case spv::ExecutionMode::Triangles:
  ------------------
  |  Branch (437:5): [True: 18, False: 1.47k]
  ------------------
  438|     18|      if (!std::all_of(models->begin(), models->end(),
  ------------------
  |  Branch (438:11): [True: 0, False: 18]
  ------------------
  439|     18|                       [](const spv::ExecutionModel& model) {
  440|     18|                         switch (model) {
  441|     18|                           case spv::ExecutionModel::Geometry:
  442|     18|                           case spv::ExecutionModel::TessellationControl:
  443|     18|                           case spv::ExecutionModel::TessellationEvaluation:
  444|     18|                             return true;
  445|     18|                           default:
  446|     18|                             return false;
  447|     18|                         }
  448|     18|                       })) {
  449|      0|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
  450|      0|               << "Execution mode can only be used with a Geometry or "
  451|      0|                  "tessellation execution model.";
  452|      0|      }
  453|     18|      break;
  454|     18|    case spv::ExecutionMode::OutputVertices:
  ------------------
  |  Branch (454:5): [True: 10, False: 1.48k]
  ------------------
  455|     10|      if (!std::all_of(
  ------------------
  |  Branch (455:11): [True: 0, False: 10]
  ------------------
  456|     10|              models->begin(), models->end(),
  457|     10|              [&_](const spv::ExecutionModel& model) {
  458|     10|                switch (model) {
  459|     10|                  case spv::ExecutionModel::Geometry:
  460|     10|                  case spv::ExecutionModel::TessellationControl:
  461|     10|                  case spv::ExecutionModel::TessellationEvaluation:
  462|     10|                    return true;
  463|     10|                  case spv::ExecutionModel::MeshNV:
  464|     10|                    return _.HasCapability(spv::Capability::MeshShadingNV);
  465|     10|                  case spv::ExecutionModel::MeshEXT:
  466|     10|                    return _.HasCapability(spv::Capability::MeshShadingEXT);
  467|     10|                  default:
  468|     10|                    return false;
  469|     10|                }
  470|     10|              })) {
  471|      0|        if (_.HasCapability(spv::Capability::MeshShadingNV) ||
  ------------------
  |  Branch (471:13): [True: 0, False: 0]
  ------------------
  472|      0|            _.HasCapability(spv::Capability::MeshShadingEXT)) {
  ------------------
  |  Branch (472:13): [True: 0, False: 0]
  ------------------
  473|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
  474|      0|                 << "Execution mode can only be used with a Geometry, "
  475|      0|                    "tessellation, MeshNV or MeshEXT execution model.";
  476|      0|        } else {
  477|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
  478|      0|                 << "Execution mode can only be used with a Geometry or "
  479|      0|                    "tessellation execution model.";
  480|      0|        }
  481|      0|      }
  482|     10|      break;
  483|     10|    case spv::ExecutionMode::OutputLinesEXT:
  ------------------
  |  Branch (483:5): [True: 0, False: 1.49k]
  ------------------
  484|      0|    case spv::ExecutionMode::OutputTrianglesEXT:
  ------------------
  |  Branch (484:5): [True: 0, False: 1.49k]
  ------------------
  485|      0|    case spv::ExecutionMode::OutputPrimitivesEXT:
  ------------------
  |  Branch (485:5): [True: 0, False: 1.49k]
  ------------------
  486|      0|      if (!std::all_of(models->begin(), models->end(),
  ------------------
  |  Branch (486:11): [True: 0, False: 0]
  ------------------
  487|      0|                       [](const spv::ExecutionModel& model) {
  488|      0|                         return (model == spv::ExecutionModel::MeshEXT ||
  489|      0|                                 model == spv::ExecutionModel::MeshNV);
  490|      0|                       })) {
  491|      0|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
  492|      0|               << "Execution mode can only be used with the MeshEXT or MeshNV "
  493|      0|                  "execution "
  494|      0|                  "model.";
  495|      0|      }
  496|      0|      break;
  497|      5|    case spv::ExecutionMode::PixelCenterInteger:
  ------------------
  |  Branch (497:5): [True: 5, False: 1.48k]
  ------------------
  498|  1.13k|    case spv::ExecutionMode::OriginUpperLeft:
  ------------------
  |  Branch (498:5): [True: 1.12k, False: 364]
  ------------------
  499|  1.18k|    case spv::ExecutionMode::OriginLowerLeft:
  ------------------
  |  Branch (499:5): [True: 54, False: 1.43k]
  ------------------
  500|  1.20k|    case spv::ExecutionMode::EarlyFragmentTests:
  ------------------
  |  Branch (500:5): [True: 18, False: 1.47k]
  ------------------
  501|  1.20k|    case spv::ExecutionMode::DepthReplacing:
  ------------------
  |  Branch (501:5): [True: 0, False: 1.49k]
  ------------------
  502|  1.20k|    case spv::ExecutionMode::DepthGreater:
  ------------------
  |  Branch (502:5): [True: 2, False: 1.49k]
  ------------------
  503|  1.21k|    case spv::ExecutionMode::DepthLess:
  ------------------
  |  Branch (503:5): [True: 4, False: 1.48k]
  ------------------
  504|  1.23k|    case spv::ExecutionMode::DepthUnchanged:
  ------------------
  |  Branch (504:5): [True: 19, False: 1.47k]
  ------------------
  505|  1.23k|    case spv::ExecutionMode::PixelInterlockOrderedEXT:
  ------------------
  |  Branch (505:5): [True: 0, False: 1.49k]
  ------------------
  506|  1.23k|    case spv::ExecutionMode::PixelInterlockUnorderedEXT:
  ------------------
  |  Branch (506:5): [True: 0, False: 1.49k]
  ------------------
  507|  1.23k|    case spv::ExecutionMode::SampleInterlockOrderedEXT:
  ------------------
  |  Branch (507:5): [True: 0, False: 1.49k]
  ------------------
  508|  1.23k|    case spv::ExecutionMode::SampleInterlockUnorderedEXT:
  ------------------
  |  Branch (508:5): [True: 0, False: 1.49k]
  ------------------
  509|  1.23k|    case spv::ExecutionMode::ShadingRateInterlockOrderedEXT:
  ------------------
  |  Branch (509:5): [True: 0, False: 1.49k]
  ------------------
  510|  1.23k|    case spv::ExecutionMode::ShadingRateInterlockUnorderedEXT:
  ------------------
  |  Branch (510:5): [True: 0, False: 1.49k]
  ------------------
  511|  1.23k|    case spv::ExecutionMode::EarlyAndLateFragmentTestsAMD:
  ------------------
  |  Branch (511:5): [True: 0, False: 1.49k]
  ------------------
  512|  1.23k|    case spv::ExecutionMode::StencilRefUnchangedFrontAMD:
  ------------------
  |  Branch (512:5): [True: 0, False: 1.49k]
  ------------------
  513|  1.23k|    case spv::ExecutionMode::StencilRefGreaterFrontAMD:
  ------------------
  |  Branch (513:5): [True: 0, False: 1.49k]
  ------------------
  514|  1.23k|    case spv::ExecutionMode::StencilRefLessFrontAMD:
  ------------------
  |  Branch (514:5): [True: 0, False: 1.49k]
  ------------------
  515|  1.23k|    case spv::ExecutionMode::StencilRefUnchangedBackAMD:
  ------------------
  |  Branch (515:5): [True: 0, False: 1.49k]
  ------------------
  516|  1.23k|    case spv::ExecutionMode::StencilRefGreaterBackAMD:
  ------------------
  |  Branch (516:5): [True: 0, False: 1.49k]
  ------------------
  517|  1.23k|    case spv::ExecutionMode::StencilRefLessBackAMD:
  ------------------
  |  Branch (517:5): [True: 0, False: 1.49k]
  ------------------
  518|  1.23k|      if (!std::all_of(models->begin(), models->end(),
  ------------------
  |  Branch (518:11): [True: 6, False: 1.22k]
  ------------------
  519|  1.23k|                       [](const spv::ExecutionModel& model) {
  520|  1.23k|                         return model == spv::ExecutionModel::Fragment;
  521|  1.23k|                       })) {
  522|      6|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
  523|      6|               << "Execution mode can only be used with the Fragment execution "
  524|      6|                  "model.";
  525|      6|      }
  526|  1.22k|      break;
  527|  1.22k|    case spv::ExecutionMode::LocalSizeHint:
  ------------------
  |  Branch (527:5): [True: 0, False: 1.49k]
  ------------------
  528|      0|    case spv::ExecutionMode::VecTypeHint:
  ------------------
  |  Branch (528:5): [True: 0, False: 1.49k]
  ------------------
  529|      0|    case spv::ExecutionMode::ContractionOff:
  ------------------
  |  Branch (529:5): [True: 0, False: 1.49k]
  ------------------
  530|      0|    case spv::ExecutionMode::LocalSizeHintId:
  ------------------
  |  Branch (530:5): [True: 0, False: 1.49k]
  ------------------
  531|      0|      if (!std::all_of(models->begin(), models->end(),
  ------------------
  |  Branch (531:11): [True: 0, False: 0]
  ------------------
  532|      0|                       [](const spv::ExecutionModel& model) {
  533|      0|                         return model == spv::ExecutionModel::Kernel;
  534|      0|                       })) {
  535|      0|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
  536|      0|               << "Execution mode can only be used with the Kernel execution "
  537|      0|                  "model.";
  538|      0|      }
  539|      0|      break;
  540|      6|    case spv::ExecutionMode::LocalSize:
  ------------------
  |  Branch (540:5): [True: 6, False: 1.48k]
  ------------------
  541|      6|    case spv::ExecutionMode::LocalSizeId:
  ------------------
  |  Branch (541:5): [True: 0, False: 1.49k]
  ------------------
  542|      6|      if (mode == spv::ExecutionMode::LocalSizeId && !_.IsLocalSizeIdAllowed())
  ------------------
  |  Branch (542:11): [True: 0, False: 6]
  |  Branch (542:54): [True: 0, False: 0]
  ------------------
  543|      0|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
  544|      0|               << "LocalSizeId mode is not allowed by the current environment.";
  545|       |
  546|      6|      if (!std::all_of(
  ------------------
  |  Branch (546:11): [True: 0, False: 6]
  ------------------
  547|      6|              models->begin(), models->end(),
  548|      6|              [&_](const spv::ExecutionModel& model) {
  549|      6|                switch (model) {
  550|      6|                  case spv::ExecutionModel::Kernel:
  551|      6|                  case spv::ExecutionModel::GLCompute:
  552|      6|                    return true;
  553|      6|                  case spv::ExecutionModel::TaskNV:
  554|      6|                  case spv::ExecutionModel::MeshNV:
  555|      6|                    return _.HasCapability(spv::Capability::MeshShadingNV);
  556|      6|                  case spv::ExecutionModel::TaskEXT:
  557|      6|                  case spv::ExecutionModel::MeshEXT:
  558|      6|                    return _.HasCapability(spv::Capability::MeshShadingEXT);
  559|      6|                  default:
  560|      6|                    return false;
  561|      6|                }
  562|      6|              })) {
  563|      0|        if (_.HasCapability(spv::Capability::MeshShadingNV) ||
  ------------------
  |  Branch (563:13): [True: 0, False: 0]
  ------------------
  564|      0|            _.HasCapability(spv::Capability::MeshShadingEXT)) {
  ------------------
  |  Branch (564:13): [True: 0, False: 0]
  ------------------
  565|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
  566|      0|                 << "Execution mode can only be used with a Kernel, GLCompute, "
  567|      0|                    "MeshNV, MeshEXT, TaskNV or TaskEXT execution model.";
  568|      0|        } else {
  569|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
  570|      0|                 << "Execution mode can only be used with a Kernel or "
  571|      0|                    "GLCompute "
  572|      0|                    "execution model.";
  573|      0|        }
  574|      0|      }
  575|      6|    default:
  ------------------
  |  Branch (575:5): [True: 0, False: 1.49k]
  ------------------
  576|      6|      break;
  577|  1.49k|  }
  578|       |
  579|  1.47k|  if (spvIsVulkanEnv(_.context()->target_env)) {
  ------------------
  |  Branch (579:7): [True: 0, False: 1.47k]
  ------------------
  580|      0|    if (mode == spv::ExecutionMode::OriginLowerLeft) {
  ------------------
  |  Branch (580:9): [True: 0, False: 0]
  ------------------
  581|      0|      return _.diag(SPV_ERROR_INVALID_DATA, inst)
  582|      0|             << _.VkErrorID(4653)
  583|      0|             << "In the Vulkan environment, the OriginLowerLeft execution mode "
  584|      0|                "must not be used.";
  585|      0|    }
  586|      0|    if (mode == spv::ExecutionMode::PixelCenterInteger) {
  ------------------
  |  Branch (586:9): [True: 0, False: 0]
  ------------------
  587|      0|      return _.diag(SPV_ERROR_INVALID_DATA, inst)
  588|      0|             << _.VkErrorID(4654)
  589|      0|             << "In the Vulkan environment, the PixelCenterInteger execution "
  590|      0|                "mode must not be used.";
  591|      0|    }
  592|      0|  }
  593|       |
  594|  1.47k|  return SPV_SUCCESS;
  595|  1.47k|}
validate_mode_setting.cpp:_ZZN8spvtools3val12_GLOBAL__N_121ValidateExecutionModeERNS0_17ValidationState_tEPKNS0_11InstructionEENK4$_11clERKN3spv14ExecutionModelE:
  382|    131|                       [](const spv::ExecutionModel& model) {
  383|    131|                         return model == spv::ExecutionModel::Geometry;
  384|    131|                       })) {
validate_mode_setting.cpp:_ZZN8spvtools3val12_GLOBAL__N_121ValidateExecutionModeERNS0_17ValidationState_tEPKNS0_11InstructionEENK4$_12clERKN3spv14ExecutionModelE:
  393|     14|              [&_](const spv::ExecutionModel& model) {
  394|     14|                switch (model) {
  395|     13|                  case spv::ExecutionModel::Geometry:
  ------------------
  |  Branch (395:19): [True: 13, False: 1]
  ------------------
  396|     13|                    return true;
  397|      0|                  case spv::ExecutionModel::MeshNV:
  ------------------
  |  Branch (397:19): [True: 0, False: 14]
  ------------------
  398|      0|                    return _.HasCapability(spv::Capability::MeshShadingNV);
  399|      0|                  case spv::ExecutionModel::MeshEXT:
  ------------------
  |  Branch (399:19): [True: 0, False: 14]
  ------------------
  400|      0|                    return _.HasCapability(spv::Capability::MeshShadingEXT);
  401|      1|                  default:
  ------------------
  |  Branch (401:19): [True: 1, False: 13]
  ------------------
  402|      1|                    return false;
  403|     14|                }
  404|     14|              })) {
validate_mode_setting.cpp:_ZZN8spvtools3val12_GLOBAL__N_121ValidateExecutionModeERNS0_17ValidationState_tEPKNS0_11InstructionEENK4$_13clERKN3spv14ExecutionModelE:
  428|     99|              [](const spv::ExecutionModel& model) {
  429|     99|                return (model == spv::ExecutionModel::TessellationControl) ||
  ------------------
  |  Branch (429:24): [True: 34, False: 65]
  ------------------
  430|     99|                       (model == spv::ExecutionModel::TessellationEvaluation);
  ------------------
  |  Branch (430:24): [True: 54, False: 11]
  ------------------
  431|     99|              })) {
validate_mode_setting.cpp:_ZZN8spvtools3val12_GLOBAL__N_121ValidateExecutionModeERNS0_17ValidationState_tEPKNS0_11InstructionEENK4$_14clERKN3spv14ExecutionModelE:
  439|     27|                       [](const spv::ExecutionModel& model) {
  440|     27|                         switch (model) {
  441|      1|                           case spv::ExecutionModel::Geometry:
  ------------------
  |  Branch (441:28): [True: 1, False: 26]
  ------------------
  442|     11|                           case spv::ExecutionModel::TessellationControl:
  ------------------
  |  Branch (442:28): [True: 10, False: 17]
  ------------------
  443|     27|                           case spv::ExecutionModel::TessellationEvaluation:
  ------------------
  |  Branch (443:28): [True: 16, False: 11]
  ------------------
  444|     27|                             return true;
  445|      0|                           default:
  ------------------
  |  Branch (445:28): [True: 0, False: 27]
  ------------------
  446|      0|                             return false;
  447|     27|                         }
  448|     27|                       })) {
validate_mode_setting.cpp:_ZZN8spvtools3val12_GLOBAL__N_121ValidateExecutionModeERNS0_17ValidationState_tEPKNS0_11InstructionEENK4$_15clERKN3spv14ExecutionModelE:
  457|     10|              [&_](const spv::ExecutionModel& model) {
  458|     10|                switch (model) {
  459|     10|                  case spv::ExecutionModel::Geometry:
  ------------------
  |  Branch (459:19): [True: 10, False: 0]
  ------------------
  460|     10|                  case spv::ExecutionModel::TessellationControl:
  ------------------
  |  Branch (460:19): [True: 0, False: 10]
  ------------------
  461|     10|                  case spv::ExecutionModel::TessellationEvaluation:
  ------------------
  |  Branch (461:19): [True: 0, False: 10]
  ------------------
  462|     10|                    return true;
  463|      0|                  case spv::ExecutionModel::MeshNV:
  ------------------
  |  Branch (463:19): [True: 0, False: 10]
  ------------------
  464|      0|                    return _.HasCapability(spv::Capability::MeshShadingNV);
  465|      0|                  case spv::ExecutionModel::MeshEXT:
  ------------------
  |  Branch (465:19): [True: 0, False: 10]
  ------------------
  466|      0|                    return _.HasCapability(spv::Capability::MeshShadingEXT);
  467|      0|                  default:
  ------------------
  |  Branch (467:19): [True: 0, False: 10]
  ------------------
  468|      0|                    return false;
  469|     10|                }
  470|     10|              })) {
validate_mode_setting.cpp:_ZZN8spvtools3val12_GLOBAL__N_121ValidateExecutionModeERNS0_17ValidationState_tEPKNS0_11InstructionEENK4$_17clERKN3spv14ExecutionModelE:
  519|  1.23k|                       [](const spv::ExecutionModel& model) {
  520|  1.23k|                         return model == spv::ExecutionModel::Fragment;
  521|  1.23k|                       })) {
validate_mode_setting.cpp:_ZZN8spvtools3val12_GLOBAL__N_121ValidateExecutionModeERNS0_17ValidationState_tEPKNS0_11InstructionEENK4$_19clERKN3spv14ExecutionModelE:
  548|      6|              [&_](const spv::ExecutionModel& model) {
  549|      6|                switch (model) {
  550|      0|                  case spv::ExecutionModel::Kernel:
  ------------------
  |  Branch (550:19): [True: 0, False: 6]
  ------------------
  551|      6|                  case spv::ExecutionModel::GLCompute:
  ------------------
  |  Branch (551:19): [True: 6, False: 0]
  ------------------
  552|      6|                    return true;
  553|      0|                  case spv::ExecutionModel::TaskNV:
  ------------------
  |  Branch (553:19): [True: 0, False: 6]
  ------------------
  554|      0|                  case spv::ExecutionModel::MeshNV:
  ------------------
  |  Branch (554:19): [True: 0, False: 6]
  ------------------
  555|      0|                    return _.HasCapability(spv::Capability::MeshShadingNV);
  556|      0|                  case spv::ExecutionModel::TaskEXT:
  ------------------
  |  Branch (556:19): [True: 0, False: 6]
  ------------------
  557|      0|                  case spv::ExecutionModel::MeshEXT:
  ------------------
  |  Branch (557:19): [True: 0, False: 6]
  ------------------
  558|      0|                    return _.HasCapability(spv::Capability::MeshShadingEXT);
  559|      0|                  default:
  ------------------
  |  Branch (559:19): [True: 0, False: 6]
  ------------------
  560|      0|                    return false;
  561|      6|                }
  562|      6|              })) {
validate_mode_setting.cpp:_ZN8spvtools3val12_GLOBAL__N_119ValidateMemoryModelERNS0_17ValidationState_tEPKNS0_11InstructionE:
  598|  3.66k|                                 const Instruction* inst) {
  599|       |  // Already produced an error if multiple memory model instructions are
  600|       |  // present.
  601|  3.66k|  if (_.memory_model() != spv::MemoryModel::VulkanKHR &&
  ------------------
  |  Branch (601:7): [True: 3.63k, False: 31]
  ------------------
  602|  3.66k|      _.HasCapability(spv::Capability::VulkanMemoryModelKHR)) {
  ------------------
  |  Branch (602:7): [True: 0, False: 3.63k]
  ------------------
  603|      0|    return _.diag(SPV_ERROR_INVALID_DATA, inst)
  604|      0|           << "VulkanMemoryModelKHR capability must only be specified if "
  605|      0|              "the VulkanKHR memory model is used.";
  606|      0|  }
  607|       |
  608|  3.66k|  if (spvIsOpenCLEnv(_.context()->target_env)) {
  ------------------
  |  Branch (608:7): [True: 0, False: 3.66k]
  ------------------
  609|      0|    if ((_.addressing_model() != spv::AddressingModel::Physical32) &&
  ------------------
  |  Branch (609:9): [True: 0, False: 0]
  ------------------
  610|      0|        (_.addressing_model() != spv::AddressingModel::Physical64)) {
  ------------------
  |  Branch (610:9): [True: 0, False: 0]
  ------------------
  611|      0|      return _.diag(SPV_ERROR_INVALID_DATA, inst)
  612|      0|             << "Addressing model must be Physical32 or Physical64 "
  613|      0|             << "in the OpenCL environment.";
  614|      0|    }
  615|      0|    if (_.memory_model() != spv::MemoryModel::OpenCL) {
  ------------------
  |  Branch (615:9): [True: 0, False: 0]
  ------------------
  616|      0|      return _.diag(SPV_ERROR_INVALID_DATA, inst)
  617|      0|             << "Memory model must be OpenCL in the OpenCL environment.";
  618|      0|    }
  619|      0|  }
  620|       |
  621|  3.66k|  if (spvIsVulkanEnv(_.context()->target_env)) {
  ------------------
  |  Branch (621:7): [True: 0, False: 3.66k]
  ------------------
  622|      0|    if ((_.addressing_model() != spv::AddressingModel::Logical) &&
  ------------------
  |  Branch (622:9): [True: 0, False: 0]
  ------------------
  623|      0|        (_.addressing_model() !=
  ------------------
  |  Branch (623:9): [True: 0, False: 0]
  ------------------
  624|      0|         spv::AddressingModel::PhysicalStorageBuffer64)) {
  625|      0|      return _.diag(SPV_ERROR_INVALID_DATA, inst)
  626|      0|             << _.VkErrorID(4635)
  627|      0|             << "Addressing model must be Logical or PhysicalStorageBuffer64 "
  628|      0|             << "in the Vulkan environment.";
  629|      0|    }
  630|      0|  }
  631|  3.66k|  return SPV_SUCCESS;
  632|  3.66k|}

_ZN8spvtools3val14NonUniformPassERNS0_17ValidationState_tEPKNS0_11InstructionE:
  122|   285k|spv_result_t NonUniformPass(ValidationState_t& _, const Instruction* inst) {
  123|   285k|  const spv::Op opcode = inst->opcode();
  124|       |
  125|   285k|  if (spvOpcodeIsNonUniformGroupOperation(opcode)) {
  ------------------
  |  Branch (125:7): [True: 0, False: 285k]
  ------------------
  126|      0|    const uint32_t execution_scope = inst->word(3);
  127|      0|    if (auto error = ValidateExecutionScope(_, inst, execution_scope)) {
  ------------------
  |  Branch (127:14): [True: 0, False: 0]
  ------------------
  128|      0|      return error;
  129|      0|    }
  130|      0|  }
  131|       |
  132|   285k|  switch (opcode) {
  133|      0|    case spv::Op::OpGroupNonUniformBallotBitCount:
  ------------------
  |  Branch (133:5): [True: 0, False: 285k]
  ------------------
  134|      0|      return ValidateGroupNonUniformBallotBitCount(_, inst);
  135|      0|    case spv::Op::OpGroupNonUniformRotateKHR:
  ------------------
  |  Branch (135:5): [True: 0, False: 285k]
  ------------------
  136|      0|      return ValidateGroupNonUniformRotateKHR(_, inst);
  137|   285k|    default:
  ------------------
  |  Branch (137:5): [True: 285k, False: 0]
  ------------------
  138|   285k|      break;
  139|   285k|  }
  140|       |
  141|   285k|  return SPV_SUCCESS;
  142|   285k|}

_ZN8spvtools3val14PrimitivesPassERNS0_17ValidationState_tEPKNS0_11InstructionE:
   30|   285k|spv_result_t PrimitivesPass(ValidationState_t& _, const Instruction* inst) {
   31|   285k|  const spv::Op opcode = inst->opcode();
   32|       |
   33|   285k|  switch (opcode) {
   34|      0|    case spv::Op::OpEmitVertex:
  ------------------
  |  Branch (34:5): [True: 0, False: 285k]
  ------------------
   35|      0|    case spv::Op::OpEndPrimitive:
  ------------------
  |  Branch (35:5): [True: 0, False: 285k]
  ------------------
   36|      0|    case spv::Op::OpEmitStreamVertex:
  ------------------
  |  Branch (36:5): [True: 0, False: 285k]
  ------------------
   37|      0|    case spv::Op::OpEndStreamPrimitive:
  ------------------
  |  Branch (37:5): [True: 0, False: 285k]
  ------------------
   38|      0|      _.function(inst->function()->id())
   39|      0|          ->RegisterExecutionModelLimitation(
   40|      0|              spv::ExecutionModel::Geometry,
   41|      0|              std::string(spvOpcodeString(opcode)) +
   42|      0|                  " instructions require Geometry execution model");
   43|      0|      break;
   44|   285k|    default:
  ------------------
  |  Branch (44:5): [True: 285k, False: 0]
  ------------------
   45|   285k|      break;
   46|   285k|  }
   47|       |
   48|   285k|  switch (opcode) {
   49|      0|    case spv::Op::OpEmitStreamVertex:
  ------------------
  |  Branch (49:5): [True: 0, False: 285k]
  ------------------
   50|      0|    case spv::Op::OpEndStreamPrimitive: {
  ------------------
  |  Branch (50:5): [True: 0, False: 285k]
  ------------------
   51|      0|      const uint32_t stream_id = inst->word(1);
   52|      0|      const uint32_t stream_type = _.GetTypeId(stream_id);
   53|      0|      if (!_.IsIntScalarType(stream_type)) {
  ------------------
  |  Branch (53:11): [True: 0, False: 0]
  ------------------
   54|      0|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
   55|      0|               << spvOpcodeString(opcode)
   56|      0|               << ": expected Stream to be int scalar";
   57|      0|      }
   58|       |
   59|      0|      const spv::Op stream_opcode = _.GetIdOpcode(stream_id);
   60|      0|      if (!spvOpcodeIsConstant(stream_opcode)) {
  ------------------
  |  Branch (60:11): [True: 0, False: 0]
  ------------------
   61|      0|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
   62|      0|               << spvOpcodeString(opcode)
   63|      0|               << ": expected Stream to be constant instruction";
   64|      0|      }
   65|      0|    }
   66|       |
   67|   285k|    default:
  ------------------
  |  Branch (67:5): [True: 285k, False: 0]
  ------------------
   68|   285k|      break;
   69|   285k|  }
   70|       |
   71|   285k|  return SPV_SUCCESS;
   72|   285k|}

_ZN8spvtools3val12RayQueryPassERNS0_17ValidationState_tEPKNS0_11InstructionE:
   70|   285k|spv_result_t RayQueryPass(ValidationState_t& _, const Instruction* inst) {
   71|   285k|  const spv::Op opcode = inst->opcode();
   72|   285k|  const uint32_t result_type = inst->type_id();
   73|       |
   74|   285k|  switch (opcode) {
   75|      0|    case spv::Op::OpRayQueryInitializeKHR: {
  ------------------
  |  Branch (75:5): [True: 0, False: 285k]
  ------------------
   76|      0|      if (auto error = ValidateRayQueryPointer(_, inst, 0)) return error;
  ------------------
  |  Branch (76:16): [True: 0, False: 0]
  ------------------
   77|       |
   78|      0|      if (_.GetIdOpcode(_.GetOperandTypeId(inst, 1)) !=
  ------------------
  |  Branch (78:11): [True: 0, False: 0]
  ------------------
   79|      0|          spv::Op::OpTypeAccelerationStructureKHR) {
   80|      0|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
   81|      0|               << "Expected Acceleration Structure to be of type "
   82|      0|                  "OpTypeAccelerationStructureKHR";
   83|      0|      }
   84|       |
   85|      0|      const uint32_t ray_flags = _.GetOperandTypeId(inst, 2);
   86|      0|      if (!_.IsIntScalarType(ray_flags) || _.GetBitWidth(ray_flags) != 32) {
  ------------------
  |  Branch (86:11): [True: 0, False: 0]
  |  Branch (86:44): [True: 0, False: 0]
  ------------------
   87|      0|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
   88|      0|               << "Ray Flags must be a 32-bit int scalar";
   89|      0|      }
   90|       |
   91|      0|      const uint32_t cull_mask = _.GetOperandTypeId(inst, 3);
   92|      0|      if (!_.IsIntScalarType(cull_mask) || _.GetBitWidth(cull_mask) != 32) {
  ------------------
  |  Branch (92:11): [True: 0, False: 0]
  |  Branch (92:44): [True: 0, False: 0]
  ------------------
   93|      0|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
   94|      0|               << "Cull Mask must be a 32-bit int scalar";
   95|      0|      }
   96|       |
   97|      0|      const uint32_t ray_origin = _.GetOperandTypeId(inst, 4);
   98|      0|      if (!_.IsFloatVectorType(ray_origin) || _.GetDimension(ray_origin) != 3 ||
  ------------------
  |  Branch (98:11): [True: 0, False: 0]
  |  Branch (98:47): [True: 0, False: 0]
  ------------------
   99|      0|          _.GetBitWidth(ray_origin) != 32) {
  ------------------
  |  Branch (99:11): [True: 0, False: 0]
  ------------------
  100|      0|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
  101|      0|               << "Ray Origin must be a 32-bit float 3-component vector";
  102|      0|      }
  103|       |
  104|      0|      const uint32_t ray_tmin = _.GetOperandTypeId(inst, 5);
  105|      0|      if (!_.IsFloatScalarType(ray_tmin) || _.GetBitWidth(ray_tmin) != 32) {
  ------------------
  |  Branch (105:11): [True: 0, False: 0]
  |  Branch (105:45): [True: 0, False: 0]
  ------------------
  106|      0|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
  107|      0|               << "Ray TMin must be a 32-bit float scalar";
  108|      0|      }
  109|       |
  110|      0|      const uint32_t ray_direction = _.GetOperandTypeId(inst, 6);
  111|      0|      if (!_.IsFloatVectorType(ray_direction) ||
  ------------------
  |  Branch (111:11): [True: 0, False: 0]
  ------------------
  112|      0|          _.GetDimension(ray_direction) != 3 ||
  ------------------
  |  Branch (112:11): [True: 0, False: 0]
  ------------------
  113|      0|          _.GetBitWidth(ray_direction) != 32) {
  ------------------
  |  Branch (113:11): [True: 0, False: 0]
  ------------------
  114|      0|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
  115|      0|               << "Ray Direction must be a 32-bit float 3-component vector";
  116|      0|      }
  117|       |
  118|      0|      const uint32_t ray_tmax = _.GetOperandTypeId(inst, 7);
  119|      0|      if (!_.IsFloatScalarType(ray_tmax) || _.GetBitWidth(ray_tmax) != 32) {
  ------------------
  |  Branch (119:11): [True: 0, False: 0]
  |  Branch (119:45): [True: 0, False: 0]
  ------------------
  120|      0|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
  121|      0|               << "Ray TMax must be a 32-bit float scalar";
  122|      0|      }
  123|      0|      break;
  124|      0|    }
  125|       |
  126|      0|    case spv::Op::OpRayQueryTerminateKHR:
  ------------------
  |  Branch (126:5): [True: 0, False: 285k]
  ------------------
  127|      0|    case spv::Op::OpRayQueryConfirmIntersectionKHR: {
  ------------------
  |  Branch (127:5): [True: 0, False: 285k]
  ------------------
  128|      0|      if (auto error = ValidateRayQueryPointer(_, inst, 0)) return error;
  ------------------
  |  Branch (128:16): [True: 0, False: 0]
  ------------------
  129|      0|      break;
  130|      0|    }
  131|       |
  132|      0|    case spv::Op::OpRayQueryGenerateIntersectionKHR: {
  ------------------
  |  Branch (132:5): [True: 0, False: 285k]
  ------------------
  133|      0|      if (auto error = ValidateRayQueryPointer(_, inst, 0)) return error;
  ------------------
  |  Branch (133:16): [True: 0, False: 0]
  ------------------
  134|       |
  135|      0|      const uint32_t hit_t_id = _.GetOperandTypeId(inst, 1);
  136|      0|      if (!_.IsFloatScalarType(hit_t_id) || _.GetBitWidth(hit_t_id) != 32) {
  ------------------
  |  Branch (136:11): [True: 0, False: 0]
  |  Branch (136:45): [True: 0, False: 0]
  ------------------
  137|      0|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
  138|      0|               << "Hit T must be a 32-bit float scalar";
  139|      0|      }
  140|       |
  141|      0|      break;
  142|      0|    }
  143|       |
  144|      0|    case spv::Op::OpRayQueryGetIntersectionFrontFaceKHR:
  ------------------
  |  Branch (144:5): [True: 0, False: 285k]
  ------------------
  145|      0|    case spv::Op::OpRayQueryProceedKHR:
  ------------------
  |  Branch (145:5): [True: 0, False: 285k]
  ------------------
  146|      0|    case spv::Op::OpRayQueryGetIntersectionCandidateAABBOpaqueKHR: {
  ------------------
  |  Branch (146:5): [True: 0, False: 285k]
  ------------------
  147|      0|      if (auto error = ValidateRayQueryPointer(_, inst, 2)) return error;
  ------------------
  |  Branch (147:16): [True: 0, False: 0]
  ------------------
  148|       |
  149|      0|      if (!_.IsBoolScalarType(result_type)) {
  ------------------
  |  Branch (149:11): [True: 0, False: 0]
  ------------------
  150|      0|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
  151|      0|               << "expected Result Type to be bool scalar type";
  152|      0|      }
  153|       |
  154|      0|      if (opcode == spv::Op::OpRayQueryGetIntersectionFrontFaceKHR) {
  ------------------
  |  Branch (154:11): [True: 0, False: 0]
  ------------------
  155|      0|        if (auto error = ValidateIntersectionId(_, inst, 3)) return error;
  ------------------
  |  Branch (155:18): [True: 0, False: 0]
  ------------------
  156|      0|      }
  157|       |
  158|      0|      break;
  159|      0|    }
  160|       |
  161|      0|    case spv::Op::OpRayQueryGetIntersectionTKHR:
  ------------------
  |  Branch (161:5): [True: 0, False: 285k]
  ------------------
  162|      0|    case spv::Op::OpRayQueryGetRayTMinKHR: {
  ------------------
  |  Branch (162:5): [True: 0, False: 285k]
  ------------------
  163|      0|      if (auto error = ValidateRayQueryPointer(_, inst, 2)) return error;
  ------------------
  |  Branch (163:16): [True: 0, False: 0]
  ------------------
  164|       |
  165|      0|      if (!_.IsFloatScalarType(result_type) ||
  ------------------
  |  Branch (165:11): [True: 0, False: 0]
  ------------------
  166|      0|          _.GetBitWidth(result_type) != 32) {
  ------------------
  |  Branch (166:11): [True: 0, False: 0]
  ------------------
  167|      0|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
  168|      0|               << "expected Result Type to be 32-bit float scalar type";
  169|      0|      }
  170|       |
  171|      0|      if (opcode == spv::Op::OpRayQueryGetIntersectionTKHR) {
  ------------------
  |  Branch (171:11): [True: 0, False: 0]
  ------------------
  172|      0|        if (auto error = ValidateIntersectionId(_, inst, 3)) return error;
  ------------------
  |  Branch (172:18): [True: 0, False: 0]
  ------------------
  173|      0|      }
  174|       |
  175|      0|      break;
  176|      0|    }
  177|       |
  178|      0|    case spv::Op::OpRayQueryGetIntersectionTypeKHR:
  ------------------
  |  Branch (178:5): [True: 0, False: 285k]
  ------------------
  179|      0|    case spv::Op::OpRayQueryGetIntersectionInstanceCustomIndexKHR:
  ------------------
  |  Branch (179:5): [True: 0, False: 285k]
  ------------------
  180|      0|    case spv::Op::OpRayQueryGetIntersectionInstanceIdKHR:
  ------------------
  |  Branch (180:5): [True: 0, False: 285k]
  ------------------
  181|      0|    case spv::Op::
  ------------------
  |  Branch (181:5): [True: 0, False: 285k]
  ------------------
  182|      0|        OpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetKHR:
  183|      0|    case spv::Op::OpRayQueryGetIntersectionGeometryIndexKHR:
  ------------------
  |  Branch (183:5): [True: 0, False: 285k]
  ------------------
  184|      0|    case spv::Op::OpRayQueryGetIntersectionPrimitiveIndexKHR:
  ------------------
  |  Branch (184:5): [True: 0, False: 285k]
  ------------------
  185|      0|    case spv::Op::OpRayQueryGetRayFlagsKHR: {
  ------------------
  |  Branch (185:5): [True: 0, False: 285k]
  ------------------
  186|      0|      if (auto error = ValidateRayQueryPointer(_, inst, 2)) return error;
  ------------------
  |  Branch (186:16): [True: 0, False: 0]
  ------------------
  187|       |
  188|      0|      if (!_.IsIntScalarType(result_type) || _.GetBitWidth(result_type) != 32) {
  ------------------
  |  Branch (188:11): [True: 0, False: 0]
  |  Branch (188:46): [True: 0, False: 0]
  ------------------
  189|      0|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
  190|      0|               << "expected Result Type to be 32-bit int scalar type";
  191|      0|      }
  192|       |
  193|      0|      if (opcode != spv::Op::OpRayQueryGetRayFlagsKHR) {
  ------------------
  |  Branch (193:11): [True: 0, False: 0]
  ------------------
  194|      0|        if (auto error = ValidateIntersectionId(_, inst, 3)) return error;
  ------------------
  |  Branch (194:18): [True: 0, False: 0]
  ------------------
  195|      0|      }
  196|       |
  197|      0|      break;
  198|      0|    }
  199|       |
  200|      0|    case spv::Op::OpRayQueryGetIntersectionObjectRayDirectionKHR:
  ------------------
  |  Branch (200:5): [True: 0, False: 285k]
  ------------------
  201|      0|    case spv::Op::OpRayQueryGetIntersectionObjectRayOriginKHR:
  ------------------
  |  Branch (201:5): [True: 0, False: 285k]
  ------------------
  202|      0|    case spv::Op::OpRayQueryGetWorldRayDirectionKHR:
  ------------------
  |  Branch (202:5): [True: 0, False: 285k]
  ------------------
  203|      0|    case spv::Op::OpRayQueryGetWorldRayOriginKHR: {
  ------------------
  |  Branch (203:5): [True: 0, False: 285k]
  ------------------
  204|      0|      if (auto error = ValidateRayQueryPointer(_, inst, 2)) return error;
  ------------------
  |  Branch (204:16): [True: 0, False: 0]
  ------------------
  205|       |
  206|      0|      if (!_.IsFloatVectorType(result_type) ||
  ------------------
  |  Branch (206:11): [True: 0, False: 0]
  ------------------
  207|      0|          _.GetDimension(result_type) != 3 ||
  ------------------
  |  Branch (207:11): [True: 0, False: 0]
  ------------------
  208|      0|          _.GetBitWidth(result_type) != 32) {
  ------------------
  |  Branch (208:11): [True: 0, False: 0]
  ------------------
  209|      0|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
  210|      0|               << "expected Result Type to be 32-bit float 3-component "
  211|      0|                  "vector type";
  212|      0|      }
  213|       |
  214|      0|      if (opcode == spv::Op::OpRayQueryGetIntersectionObjectRayDirectionKHR ||
  ------------------
  |  Branch (214:11): [True: 0, False: 0]
  ------------------
  215|      0|          opcode == spv::Op::OpRayQueryGetIntersectionObjectRayOriginKHR) {
  ------------------
  |  Branch (215:11): [True: 0, False: 0]
  ------------------
  216|      0|        if (auto error = ValidateIntersectionId(_, inst, 3)) return error;
  ------------------
  |  Branch (216:18): [True: 0, False: 0]
  ------------------
  217|      0|      }
  218|       |
  219|      0|      break;
  220|      0|    }
  221|       |
  222|      0|    case spv::Op::OpRayQueryGetIntersectionBarycentricsKHR: {
  ------------------
  |  Branch (222:5): [True: 0, False: 285k]
  ------------------
  223|      0|      if (auto error = ValidateRayQueryPointer(_, inst, 2)) return error;
  ------------------
  |  Branch (223:16): [True: 0, False: 0]
  ------------------
  224|      0|      if (auto error = ValidateIntersectionId(_, inst, 3)) return error;
  ------------------
  |  Branch (224:16): [True: 0, False: 0]
  ------------------
  225|       |
  226|      0|      if (!_.IsFloatVectorType(result_type) ||
  ------------------
  |  Branch (226:11): [True: 0, False: 0]
  ------------------
  227|      0|          _.GetDimension(result_type) != 2 ||
  ------------------
  |  Branch (227:11): [True: 0, False: 0]
  ------------------
  228|      0|          _.GetBitWidth(result_type) != 32) {
  ------------------
  |  Branch (228:11): [True: 0, False: 0]
  ------------------
  229|      0|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
  230|      0|               << "expected Result Type to be 32-bit float 2-component "
  231|      0|                  "vector type";
  232|      0|      }
  233|       |
  234|      0|      break;
  235|      0|    }
  236|       |
  237|      0|    case spv::Op::OpRayQueryGetIntersectionObjectToWorldKHR:
  ------------------
  |  Branch (237:5): [True: 0, False: 285k]
  ------------------
  238|      0|    case spv::Op::OpRayQueryGetIntersectionWorldToObjectKHR: {
  ------------------
  |  Branch (238:5): [True: 0, False: 285k]
  ------------------
  239|      0|      if (auto error = ValidateRayQueryPointer(_, inst, 2)) return error;
  ------------------
  |  Branch (239:16): [True: 0, False: 0]
  ------------------
  240|      0|      if (auto error = ValidateIntersectionId(_, inst, 3)) return error;
  ------------------
  |  Branch (240:16): [True: 0, False: 0]
  ------------------
  241|       |
  242|      0|      uint32_t num_rows = 0;
  243|      0|      uint32_t num_cols = 0;
  244|      0|      uint32_t col_type = 0;
  245|      0|      uint32_t component_type = 0;
  246|      0|      if (!_.GetMatrixTypeInfo(result_type, &num_rows, &num_cols, &col_type,
  ------------------
  |  Branch (246:11): [True: 0, False: 0]
  ------------------
  247|      0|                               &component_type)) {
  248|      0|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
  249|      0|               << "expected matrix type as Result Type";
  250|      0|      }
  251|       |
  252|      0|      if (num_cols != 4) {
  ------------------
  |  Branch (252:11): [True: 0, False: 0]
  ------------------
  253|      0|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
  254|      0|               << "expected Result Type matrix to have a Column Count of 4";
  255|      0|      }
  256|       |
  257|      0|      if (!_.IsFloatScalarType(component_type) ||
  ------------------
  |  Branch (257:11): [True: 0, False: 0]
  ------------------
  258|      0|          _.GetBitWidth(result_type) != 32 || num_rows != 3) {
  ------------------
  |  Branch (258:11): [True: 0, False: 0]
  |  Branch (258:47): [True: 0, False: 0]
  ------------------
  259|      0|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
  260|      0|               << "expected Result Type matrix to have a Column Type of "
  261|      0|                  "3-component 32-bit float vectors";
  262|      0|      }
  263|      0|      break;
  264|      0|    }
  265|       |
  266|   285k|    default:
  ------------------
  |  Branch (266:5): [True: 285k, False: 0]
  ------------------
  267|   285k|      break;
  268|   285k|  }
  269|       |
  270|   285k|  return SPV_SUCCESS;
  271|   285k|}

_ZN8spvtools3val14RayTracingPassERNS0_17ValidationState_tEPKNS0_11InstructionE:
   25|   285k|spv_result_t RayTracingPass(ValidationState_t& _, const Instruction* inst) {
   26|   285k|  const spv::Op opcode = inst->opcode();
   27|   285k|  const uint32_t result_type = inst->type_id();
   28|       |
   29|   285k|  switch (opcode) {
   30|      0|    case spv::Op::OpTraceRayKHR: {
  ------------------
  |  Branch (30:5): [True: 0, False: 285k]
  ------------------
   31|      0|      _.function(inst->function()->id())
   32|      0|          ->RegisterExecutionModelLimitation(
   33|      0|              [](spv::ExecutionModel model, std::string* message) {
   34|      0|                if (model != spv::ExecutionModel::RayGenerationKHR &&
   35|      0|                    model != spv::ExecutionModel::ClosestHitKHR &&
   36|      0|                    model != spv::ExecutionModel::MissKHR) {
   37|      0|                  if (message) {
   38|      0|                    *message =
   39|      0|                        "OpTraceRayKHR requires RayGenerationKHR, "
   40|      0|                        "ClosestHitKHR and MissKHR execution models";
   41|      0|                  }
   42|      0|                  return false;
   43|      0|                }
   44|      0|                return true;
   45|      0|              });
   46|       |
   47|      0|      if (_.GetIdOpcode(_.GetOperandTypeId(inst, 0)) !=
  ------------------
  |  Branch (47:11): [True: 0, False: 0]
  ------------------
   48|      0|          spv::Op::OpTypeAccelerationStructureKHR) {
   49|      0|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
   50|      0|               << "Expected Acceleration Structure to be of type "
   51|      0|                  "OpTypeAccelerationStructureKHR";
   52|      0|      }
   53|       |
   54|      0|      const uint32_t ray_flags = _.GetOperandTypeId(inst, 1);
   55|      0|      if (!_.IsIntScalarType(ray_flags) || _.GetBitWidth(ray_flags) != 32) {
  ------------------
  |  Branch (55:11): [True: 0, False: 0]
  |  Branch (55:44): [True: 0, False: 0]
  ------------------
   56|      0|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
   57|      0|               << "Ray Flags must be a 32-bit int scalar";
   58|      0|      }
   59|       |
   60|      0|      const uint32_t cull_mask = _.GetOperandTypeId(inst, 2);
   61|      0|      if (!_.IsIntScalarType(cull_mask) || _.GetBitWidth(cull_mask) != 32) {
  ------------------
  |  Branch (61:11): [True: 0, False: 0]
  |  Branch (61:44): [True: 0, False: 0]
  ------------------
   62|      0|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
   63|      0|               << "Cull Mask must be a 32-bit int scalar";
   64|      0|      }
   65|       |
   66|      0|      const uint32_t sbt_offset = _.GetOperandTypeId(inst, 3);
   67|      0|      if (!_.IsIntScalarType(sbt_offset) || _.GetBitWidth(sbt_offset) != 32) {
  ------------------
  |  Branch (67:11): [True: 0, False: 0]
  |  Branch (67:45): [True: 0, False: 0]
  ------------------
   68|      0|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
   69|      0|               << "SBT Offset must be a 32-bit int scalar";
   70|      0|      }
   71|       |
   72|      0|      const uint32_t sbt_stride = _.GetOperandTypeId(inst, 4);
   73|      0|      if (!_.IsIntScalarType(sbt_stride) || _.GetBitWidth(sbt_stride) != 32) {
  ------------------
  |  Branch (73:11): [True: 0, False: 0]
  |  Branch (73:45): [True: 0, False: 0]
  ------------------
   74|      0|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
   75|      0|               << "SBT Stride must be a 32-bit int scalar";
   76|      0|      }
   77|       |
   78|      0|      const uint32_t miss_index = _.GetOperandTypeId(inst, 5);
   79|      0|      if (!_.IsIntScalarType(miss_index) || _.GetBitWidth(miss_index) != 32) {
  ------------------
  |  Branch (79:11): [True: 0, False: 0]
  |  Branch (79:45): [True: 0, False: 0]
  ------------------
   80|      0|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
   81|      0|               << "Miss Index must be a 32-bit int scalar";
   82|      0|      }
   83|       |
   84|      0|      const uint32_t ray_origin = _.GetOperandTypeId(inst, 6);
   85|      0|      if (!_.IsFloatVectorType(ray_origin) || _.GetDimension(ray_origin) != 3 ||
  ------------------
  |  Branch (85:11): [True: 0, False: 0]
  |  Branch (85:47): [True: 0, False: 0]
  ------------------
   86|      0|          _.GetBitWidth(ray_origin) != 32) {
  ------------------
  |  Branch (86:11): [True: 0, False: 0]
  ------------------
   87|      0|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
   88|      0|               << "Ray Origin must be a 32-bit float 3-component vector";
   89|      0|      }
   90|       |
   91|      0|      const uint32_t ray_tmin = _.GetOperandTypeId(inst, 7);
   92|      0|      if (!_.IsFloatScalarType(ray_tmin) || _.GetBitWidth(ray_tmin) != 32) {
  ------------------
  |  Branch (92:11): [True: 0, False: 0]
  |  Branch (92:45): [True: 0, False: 0]
  ------------------
   93|      0|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
   94|      0|               << "Ray TMin must be a 32-bit float scalar";
   95|      0|      }
   96|       |
   97|      0|      const uint32_t ray_direction = _.GetOperandTypeId(inst, 8);
   98|      0|      if (!_.IsFloatVectorType(ray_direction) ||
  ------------------
  |  Branch (98:11): [True: 0, False: 0]
  ------------------
   99|      0|          _.GetDimension(ray_direction) != 3 ||
  ------------------
  |  Branch (99:11): [True: 0, False: 0]
  ------------------
  100|      0|          _.GetBitWidth(ray_direction) != 32) {
  ------------------
  |  Branch (100:11): [True: 0, False: 0]
  ------------------
  101|      0|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
  102|      0|               << "Ray Direction must be a 32-bit float 3-component vector";
  103|      0|      }
  104|       |
  105|      0|      const uint32_t ray_tmax = _.GetOperandTypeId(inst, 9);
  106|      0|      if (!_.IsFloatScalarType(ray_tmax) || _.GetBitWidth(ray_tmax) != 32) {
  ------------------
  |  Branch (106:11): [True: 0, False: 0]
  |  Branch (106:45): [True: 0, False: 0]
  ------------------
  107|      0|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
  108|      0|               << "Ray TMax must be a 32-bit float scalar";
  109|      0|      }
  110|       |
  111|      0|      const Instruction* payload = _.FindDef(inst->GetOperandAs<uint32_t>(10));
  112|      0|      if (payload->opcode() != spv::Op::OpVariable) {
  ------------------
  |  Branch (112:11): [True: 0, False: 0]
  ------------------
  113|      0|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
  114|      0|               << "Payload must be the result of a OpVariable";
  115|      0|      } else if (payload->GetOperandAs<spv::StorageClass>(2) !=
  ------------------
  |  Branch (115:18): [True: 0, False: 0]
  ------------------
  116|      0|                     spv::StorageClass::RayPayloadKHR &&
  117|      0|                 payload->GetOperandAs<spv::StorageClass>(2) !=
  ------------------
  |  Branch (117:18): [True: 0, False: 0]
  ------------------
  118|      0|                     spv::StorageClass::IncomingRayPayloadKHR) {
  119|      0|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
  120|      0|               << "Payload must have storage class RayPayloadKHR or "
  121|      0|                  "IncomingRayPayloadKHR";
  122|      0|      }
  123|      0|      break;
  124|      0|    }
  125|       |
  126|      0|    case spv::Op::OpReportIntersectionKHR: {
  ------------------
  |  Branch (126:5): [True: 0, False: 285k]
  ------------------
  127|      0|      _.function(inst->function()->id())
  128|      0|          ->RegisterExecutionModelLimitation(
  129|      0|              [](spv::ExecutionModel model, std::string* message) {
  130|      0|                if (model != spv::ExecutionModel::IntersectionKHR) {
  131|      0|                  if (message) {
  132|      0|                    *message =
  133|      0|                        "OpReportIntersectionKHR requires IntersectionKHR "
  134|      0|                        "execution model";
  135|      0|                  }
  136|      0|                  return false;
  137|      0|                }
  138|      0|                return true;
  139|      0|              });
  140|       |
  141|      0|      if (!_.IsBoolScalarType(result_type)) {
  ------------------
  |  Branch (141:11): [True: 0, False: 0]
  ------------------
  142|      0|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
  143|      0|               << "expected Result Type to be bool scalar type";
  144|      0|      }
  145|       |
  146|      0|      const uint32_t hit = _.GetOperandTypeId(inst, 2);
  147|      0|      if (!_.IsFloatScalarType(hit) || _.GetBitWidth(hit) != 32) {
  ------------------
  |  Branch (147:11): [True: 0, False: 0]
  |  Branch (147:40): [True: 0, False: 0]
  ------------------
  148|      0|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
  149|      0|               << "Hit must be a 32-bit int scalar";
  150|      0|      }
  151|       |
  152|      0|      const uint32_t hit_kind = _.GetOperandTypeId(inst, 3);
  153|      0|      if (!_.IsUnsignedIntScalarType(hit_kind) ||
  ------------------
  |  Branch (153:11): [True: 0, False: 0]
  ------------------
  154|      0|          _.GetBitWidth(hit_kind) != 32) {
  ------------------
  |  Branch (154:11): [True: 0, False: 0]
  ------------------
  155|      0|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
  156|      0|               << "Hit Kind must be a 32-bit unsigned int scalar";
  157|      0|      }
  158|      0|      break;
  159|      0|    }
  160|       |
  161|      0|    case spv::Op::OpExecuteCallableKHR: {
  ------------------
  |  Branch (161:5): [True: 0, False: 285k]
  ------------------
  162|      0|      _.function(inst->function()->id())
  163|      0|          ->RegisterExecutionModelLimitation([](spv::ExecutionModel model,
  164|      0|                                                std::string* message) {
  165|      0|            if (model != spv::ExecutionModel::RayGenerationKHR &&
  166|      0|                model != spv::ExecutionModel::ClosestHitKHR &&
  167|      0|                model != spv::ExecutionModel::MissKHR &&
  168|      0|                model != spv::ExecutionModel::CallableKHR) {
  169|      0|              if (message) {
  170|      0|                *message =
  171|      0|                    "OpExecuteCallableKHR requires RayGenerationKHR, "
  172|      0|                    "ClosestHitKHR, MissKHR and CallableKHR execution models";
  173|      0|              }
  174|      0|              return false;
  175|      0|            }
  176|      0|            return true;
  177|      0|          });
  178|       |
  179|      0|      const uint32_t sbt_index = _.GetOperandTypeId(inst, 0);
  180|      0|      if (!_.IsUnsignedIntScalarType(sbt_index) ||
  ------------------
  |  Branch (180:11): [True: 0, False: 0]
  ------------------
  181|      0|          _.GetBitWidth(sbt_index) != 32) {
  ------------------
  |  Branch (181:11): [True: 0, False: 0]
  ------------------
  182|      0|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
  183|      0|               << "SBT Index must be a 32-bit unsigned int scalar";
  184|      0|      }
  185|       |
  186|      0|      const auto callable_data = _.FindDef(inst->GetOperandAs<uint32_t>(1));
  187|      0|      if (callable_data->opcode() != spv::Op::OpVariable) {
  ------------------
  |  Branch (187:11): [True: 0, False: 0]
  ------------------
  188|      0|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
  189|      0|               << "Callable Data must be the result of a OpVariable";
  190|      0|      } else if (callable_data->GetOperandAs<spv::StorageClass>(2) !=
  ------------------
  |  Branch (190:18): [True: 0, False: 0]
  ------------------
  191|      0|                     spv::StorageClass::CallableDataKHR &&
  192|      0|                 callable_data->GetOperandAs<spv::StorageClass>(2) !=
  ------------------
  |  Branch (192:18): [True: 0, False: 0]
  ------------------
  193|      0|                     spv::StorageClass::IncomingCallableDataKHR) {
  194|      0|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
  195|      0|               << "Callable Data must have storage class CallableDataKHR or "
  196|      0|                  "IncomingCallableDataKHR";
  197|      0|      }
  198|       |
  199|      0|      break;
  200|      0|    }
  201|       |
  202|   285k|    default:
  ------------------
  |  Branch (202:5): [True: 285k, False: 0]
  ------------------
  203|   285k|      break;
  204|   285k|  }
  205|       |
  206|   285k|  return SPV_SUCCESS;
  207|   285k|}

_ZN8spvtools3val16RayReorderNVPassERNS0_17ValidationState_tEPKNS0_11InstructionE:
  250|   285k|spv_result_t RayReorderNVPass(ValidationState_t& _, const Instruction* inst) {
  251|   285k|  const spv::Op opcode = inst->opcode();
  252|   285k|  const uint32_t result_type = inst->type_id();
  253|       |
  254|   285k|  auto RegisterOpcodeForValidModel = [](ValidationState_t& vs,
  255|   285k|                                        const Instruction* rtinst) {
  256|   285k|    std::string opcode_name = spvOpcodeString(rtinst->opcode());
  257|   285k|    vs.function(rtinst->function()->id())
  258|   285k|        ->RegisterExecutionModelLimitation(
  259|   285k|            [opcode_name](spv::ExecutionModel model, std::string* message) {
  260|   285k|              if (model != spv::ExecutionModel::RayGenerationKHR &&
  261|   285k|                  model != spv::ExecutionModel::ClosestHitKHR &&
  262|   285k|                  model != spv::ExecutionModel::MissKHR) {
  263|   285k|                if (message) {
  264|   285k|                  *message = opcode_name +
  265|   285k|                             " requires RayGenerationKHR, ClosestHitKHR and "
  266|   285k|                             "MissKHR execution models";
  267|   285k|                }
  268|   285k|                return false;
  269|   285k|              }
  270|   285k|              return true;
  271|   285k|            });
  272|   285k|    return;
  273|   285k|  };
  274|       |
  275|   285k|  switch (opcode) {
  276|      0|    case spv::Op::OpHitObjectIsMissNV:
  ------------------
  |  Branch (276:5): [True: 0, False: 285k]
  ------------------
  277|      0|    case spv::Op::OpHitObjectIsHitNV:
  ------------------
  |  Branch (277:5): [True: 0, False: 285k]
  ------------------
  278|      0|    case spv::Op::OpHitObjectIsEmptyNV: {
  ------------------
  |  Branch (278:5): [True: 0, False: 285k]
  ------------------
  279|      0|      RegisterOpcodeForValidModel(_, inst);
  280|      0|      if (!_.IsBoolScalarType(result_type)) {
  ------------------
  |  Branch (280:11): [True: 0, False: 0]
  ------------------
  281|      0|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
  282|      0|               << "expected Result Type to be bool scalar type";
  283|      0|      }
  284|       |
  285|      0|      if (auto error = ValidateHitObjectPointer(_, inst, 2)) return error;
  ------------------
  |  Branch (285:16): [True: 0, False: 0]
  ------------------
  286|      0|      break;
  287|      0|    }
  288|       |
  289|      0|    case spv::Op::OpHitObjectGetShaderRecordBufferHandleNV: {
  ------------------
  |  Branch (289:5): [True: 0, False: 285k]
  ------------------
  290|      0|      RegisterOpcodeForValidModel(_, inst);
  291|      0|      if (auto error = ValidateHitObjectPointer(_, inst, 2)) return error;
  ------------------
  |  Branch (291:16): [True: 0, False: 0]
  ------------------
  292|       |
  293|      0|      if (!_.IsIntVectorType(result_type) ||
  ------------------
  |  Branch (293:11): [True: 0, False: 0]
  ------------------
  294|      0|          (_.GetDimension(result_type) != 2) ||
  ------------------
  |  Branch (294:11): [True: 0, False: 0]
  ------------------
  295|      0|          (_.GetBitWidth(result_type) != 32))
  ------------------
  |  Branch (295:11): [True: 0, False: 0]
  ------------------
  296|      0|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
  297|      0|               << "Expected 32-bit integer type 2-component vector as Result "
  298|      0|                  "Type: "
  299|      0|               << spvOpcodeString(opcode);
  300|      0|      break;
  301|      0|    }
  302|       |
  303|      0|    case spv::Op::OpHitObjectGetHitKindNV:
  ------------------
  |  Branch (303:5): [True: 0, False: 285k]
  ------------------
  304|      0|    case spv::Op::OpHitObjectGetPrimitiveIndexNV:
  ------------------
  |  Branch (304:5): [True: 0, False: 285k]
  ------------------
  305|      0|    case spv::Op::OpHitObjectGetGeometryIndexNV:
  ------------------
  |  Branch (305:5): [True: 0, False: 285k]
  ------------------
  306|      0|    case spv::Op::OpHitObjectGetInstanceIdNV:
  ------------------
  |  Branch (306:5): [True: 0, False: 285k]
  ------------------
  307|      0|    case spv::Op::OpHitObjectGetInstanceCustomIndexNV:
  ------------------
  |  Branch (307:5): [True: 0, False: 285k]
  ------------------
  308|      0|    case spv::Op::OpHitObjectGetShaderBindingTableRecordIndexNV: {
  ------------------
  |  Branch (308:5): [True: 0, False: 285k]
  ------------------
  309|      0|      RegisterOpcodeForValidModel(_, inst);
  310|      0|      if (auto error = ValidateHitObjectPointer(_, inst, 2)) return error;
  ------------------
  |  Branch (310:16): [True: 0, False: 0]
  ------------------
  311|       |
  312|      0|      if (!_.IsIntScalarType(result_type) || !_.GetBitWidth(result_type))
  ------------------
  |  Branch (312:11): [True: 0, False: 0]
  |  Branch (312:46): [True: 0, False: 0]
  ------------------
  313|      0|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
  314|      0|               << "Expected 32-bit integer type scalar as Result Type: "
  315|      0|               << spvOpcodeString(opcode);
  316|      0|      break;
  317|      0|    }
  318|       |
  319|      0|    case spv::Op::OpHitObjectGetCurrentTimeNV:
  ------------------
  |  Branch (319:5): [True: 0, False: 285k]
  ------------------
  320|      0|    case spv::Op::OpHitObjectGetRayTMaxNV:
  ------------------
  |  Branch (320:5): [True: 0, False: 285k]
  ------------------
  321|      0|    case spv::Op::OpHitObjectGetRayTMinNV: {
  ------------------
  |  Branch (321:5): [True: 0, False: 285k]
  ------------------
  322|      0|      RegisterOpcodeForValidModel(_, inst);
  323|      0|      if (auto error = ValidateHitObjectPointer(_, inst, 2)) return error;
  ------------------
  |  Branch (323:16): [True: 0, False: 0]
  ------------------
  324|       |
  325|      0|      if (!_.IsFloatScalarType(result_type) || _.GetBitWidth(result_type) != 32)
  ------------------
  |  Branch (325:11): [True: 0, False: 0]
  |  Branch (325:48): [True: 0, False: 0]
  ------------------
  326|      0|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
  327|      0|               << "Expected 32-bit floating-point type scalar as Result Type: "
  328|      0|               << spvOpcodeString(opcode);
  329|      0|      break;
  330|      0|    }
  331|       |
  332|      0|    case spv::Op::OpHitObjectGetObjectToWorldNV:
  ------------------
  |  Branch (332:5): [True: 0, False: 285k]
  ------------------
  333|      0|    case spv::Op::OpHitObjectGetWorldToObjectNV: {
  ------------------
  |  Branch (333:5): [True: 0, False: 285k]
  ------------------
  334|      0|      RegisterOpcodeForValidModel(_, inst);
  335|      0|      if (auto error = ValidateHitObjectPointer(_, inst, 2)) return error;
  ------------------
  |  Branch (335:16): [True: 0, False: 0]
  ------------------
  336|       |
  337|      0|      uint32_t num_rows = 0;
  338|      0|      uint32_t num_cols = 0;
  339|      0|      uint32_t col_type = 0;
  340|      0|      uint32_t component_type = 0;
  341|       |
  342|      0|      if (!_.GetMatrixTypeInfo(result_type, &num_rows, &num_cols, &col_type,
  ------------------
  |  Branch (342:11): [True: 0, False: 0]
  ------------------
  343|      0|                               &component_type)) {
  344|      0|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
  345|      0|               << "expected matrix type as Result Type: "
  346|      0|               << spvOpcodeString(opcode);
  347|      0|      }
  348|       |
  349|      0|      if (num_cols != 4) {
  ------------------
  |  Branch (349:11): [True: 0, False: 0]
  ------------------
  350|      0|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
  351|      0|               << "expected Result Type matrix to have a Column Count of 4"
  352|      0|               << spvOpcodeString(opcode);
  353|      0|      }
  354|       |
  355|      0|      if (!_.IsFloatScalarType(component_type) ||
  ------------------
  |  Branch (355:11): [True: 0, False: 0]
  ------------------
  356|      0|          _.GetBitWidth(result_type) != 32 || num_rows != 3) {
  ------------------
  |  Branch (356:11): [True: 0, False: 0]
  |  Branch (356:47): [True: 0, False: 0]
  ------------------
  357|      0|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
  358|      0|               << "expected Result Type matrix to have a Column Type of "
  359|      0|                  "3-component 32-bit float vectors: "
  360|      0|               << spvOpcodeString(opcode);
  361|      0|      }
  362|      0|      break;
  363|      0|    }
  364|       |
  365|      0|    case spv::Op::OpHitObjectGetObjectRayOriginNV:
  ------------------
  |  Branch (365:5): [True: 0, False: 285k]
  ------------------
  366|      0|    case spv::Op::OpHitObjectGetObjectRayDirectionNV:
  ------------------
  |  Branch (366:5): [True: 0, False: 285k]
  ------------------
  367|      0|    case spv::Op::OpHitObjectGetWorldRayDirectionNV:
  ------------------
  |  Branch (367:5): [True: 0, False: 285k]
  ------------------
  368|      0|    case spv::Op::OpHitObjectGetWorldRayOriginNV: {
  ------------------
  |  Branch (368:5): [True: 0, False: 285k]
  ------------------
  369|      0|      RegisterOpcodeForValidModel(_, inst);
  370|      0|      if (auto error = ValidateHitObjectPointer(_, inst, 2)) return error;
  ------------------
  |  Branch (370:16): [True: 0, False: 0]
  ------------------
  371|       |
  372|      0|      if (!_.IsFloatVectorType(result_type) ||
  ------------------
  |  Branch (372:11): [True: 0, False: 0]
  ------------------
  373|      0|          (_.GetDimension(result_type) != 3) ||
  ------------------
  |  Branch (373:11): [True: 0, False: 0]
  ------------------
  374|      0|          (_.GetBitWidth(result_type) != 32))
  ------------------
  |  Branch (374:11): [True: 0, False: 0]
  ------------------
  375|      0|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
  376|      0|               << "Expected 32-bit floating-point type 3-component vector as "
  377|      0|                  "Result Type: "
  378|      0|               << spvOpcodeString(opcode);
  379|      0|      break;
  380|      0|    }
  381|       |
  382|      0|    case spv::Op::OpHitObjectGetAttributesNV: {
  ------------------
  |  Branch (382:5): [True: 0, False: 285k]
  ------------------
  383|      0|      RegisterOpcodeForValidModel(_, inst);
  384|      0|      if (auto error = ValidateHitObjectPointer(_, inst, 0)) return error;
  ------------------
  |  Branch (384:16): [True: 0, False: 0]
  ------------------
  385|       |
  386|      0|      const uint32_t hit_object_attr_id = inst->GetOperandAs<uint32_t>(1);
  387|      0|      auto variable = _.FindDef(hit_object_attr_id);
  388|      0|      const auto var_opcode = variable->opcode();
  389|      0|      if (!variable || var_opcode != spv::Op::OpVariable ||
  ------------------
  |  Branch (389:11): [True: 0, False: 0]
  |  Branch (389:24): [True: 0, False: 0]
  ------------------
  390|      0|          variable->GetOperandAs<spv::StorageClass>(2) !=
  ------------------
  |  Branch (390:11): [True: 0, False: 0]
  ------------------
  391|      0|              spv::StorageClass::HitObjectAttributeNV) {
  392|      0|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
  393|      0|               << "Hit Object Attributes id must be a OpVariable of storage "
  394|      0|                  "class HitObjectAttributeNV";
  395|      0|      }
  396|      0|      break;
  397|      0|    }
  398|       |
  399|      0|    case spv::Op::OpHitObjectExecuteShaderNV: {
  ------------------
  |  Branch (399:5): [True: 0, False: 285k]
  ------------------
  400|      0|      RegisterOpcodeForValidModel(_, inst);
  401|      0|      if (auto error = ValidateHitObjectPointer(_, inst, 0)) return error;
  ------------------
  |  Branch (401:16): [True: 0, False: 0]
  ------------------
  402|       |
  403|      0|      const uint32_t hit_object_attr_id = inst->GetOperandAs<uint32_t>(1);
  404|      0|      auto variable = _.FindDef(hit_object_attr_id);
  405|      0|      const auto var_opcode = variable->opcode();
  406|      0|      if (!variable || var_opcode != spv::Op::OpVariable ||
  ------------------
  |  Branch (406:11): [True: 0, False: 0]
  |  Branch (406:24): [True: 0, False: 0]
  ------------------
  407|      0|          (variable->GetOperandAs<spv::StorageClass>(2)) !=
  ------------------
  |  Branch (407:11): [True: 0, False: 0]
  ------------------
  408|      0|              spv::StorageClass::RayPayloadKHR) {
  409|      0|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
  410|      0|               << "Hit Object Attributes id must be a OpVariable of storage "
  411|      0|                  "class RayPayloadKHR";
  412|      0|      }
  413|      0|      break;
  414|      0|    }
  415|       |
  416|      0|    case spv::Op::OpHitObjectRecordEmptyNV: {
  ------------------
  |  Branch (416:5): [True: 0, False: 285k]
  ------------------
  417|      0|      RegisterOpcodeForValidModel(_, inst);
  418|      0|      if (auto error = ValidateHitObjectPointer(_, inst, 0)) return error;
  ------------------
  |  Branch (418:16): [True: 0, False: 0]
  ------------------
  419|      0|      break;
  420|      0|    }
  421|       |
  422|      0|    case spv::Op::OpHitObjectRecordMissNV: {
  ------------------
  |  Branch (422:5): [True: 0, False: 285k]
  ------------------
  423|      0|      RegisterOpcodeForValidModel(_, inst);
  424|      0|      if (auto error = ValidateHitObjectPointer(_, inst, 0)) return error;
  ------------------
  |  Branch (424:16): [True: 0, False: 0]
  ------------------
  425|       |
  426|      0|      const uint32_t miss_index = _.GetOperandTypeId(inst, 1);
  427|      0|      if (!_.IsUnsignedIntScalarType(miss_index) ||
  ------------------
  |  Branch (427:11): [True: 0, False: 0]
  ------------------
  428|      0|          _.GetBitWidth(miss_index) != 32) {
  ------------------
  |  Branch (428:11): [True: 0, False: 0]
  ------------------
  429|      0|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
  430|      0|               << "Miss Index must be a 32-bit int scalar";
  431|      0|      }
  432|       |
  433|      0|      const uint32_t ray_origin = _.GetOperandTypeId(inst, 2);
  434|      0|      if (!_.IsFloatVectorType(ray_origin) || _.GetDimension(ray_origin) != 3 ||
  ------------------
  |  Branch (434:11): [True: 0, False: 0]
  |  Branch (434:47): [True: 0, False: 0]
  ------------------
  435|      0|          _.GetBitWidth(ray_origin) != 32) {
  ------------------
  |  Branch (435:11): [True: 0, False: 0]
  ------------------
  436|      0|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
  437|      0|               << "Ray Origin must be a 32-bit float 3-component vector";
  438|      0|      }
  439|       |
  440|      0|      const uint32_t ray_tmin = _.GetOperandTypeId(inst, 3);
  441|      0|      if (!_.IsFloatScalarType(ray_tmin) || _.GetBitWidth(ray_tmin) != 32) {
  ------------------
  |  Branch (441:11): [True: 0, False: 0]
  |  Branch (441:45): [True: 0, False: 0]
  ------------------
  442|      0|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
  443|      0|               << "Ray TMin must be a 32-bit float scalar";
  444|      0|      }
  445|       |
  446|      0|      const uint32_t ray_direction = _.GetOperandTypeId(inst, 4);
  447|      0|      if (!_.IsFloatVectorType(ray_direction) ||
  ------------------
  |  Branch (447:11): [True: 0, False: 0]
  ------------------
  448|      0|          _.GetDimension(ray_direction) != 3 ||
  ------------------
  |  Branch (448:11): [True: 0, False: 0]
  ------------------
  449|      0|          _.GetBitWidth(ray_direction) != 32) {
  ------------------
  |  Branch (449:11): [True: 0, False: 0]
  ------------------
  450|      0|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
  451|      0|               << "Ray Direction must be a 32-bit float 3-component vector";
  452|      0|      }
  453|       |
  454|      0|      const uint32_t ray_tmax = _.GetOperandTypeId(inst, 5);
  455|      0|      if (!_.IsFloatScalarType(ray_tmax) || _.GetBitWidth(ray_tmax) != 32) {
  ------------------
  |  Branch (455:11): [True: 0, False: 0]
  |  Branch (455:45): [True: 0, False: 0]
  ------------------
  456|      0|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
  457|      0|               << "Ray TMax must be a 32-bit float scalar";
  458|      0|      }
  459|      0|      break;
  460|      0|    }
  461|       |
  462|      0|    case spv::Op::OpHitObjectRecordHitWithIndexNV: {
  ------------------
  |  Branch (462:5): [True: 0, False: 285k]
  ------------------
  463|      0|      RegisterOpcodeForValidModel(_, inst);
  464|      0|      if (auto error = ValidateHitObjectPointer(_, inst, 0)) return error;
  ------------------
  |  Branch (464:16): [True: 0, False: 0]
  ------------------
  465|       |
  466|      0|      if (auto error = ValidateHitObjectInstructionCommonParameters(
  ------------------
  |  Branch (466:16): [True: 0, False: 0]
  ------------------
  467|      0|              _, inst, 1 /* Acceleration Struct */, 2 /* Instance Id */,
  468|      0|              3 /* Primtive Id */, 4 /* Geometry Index */,
  469|      0|              KRayParamInvalidId /* Ray Flags */,
  470|      0|              KRayParamInvalidId /* Cull Mask */, 5 /* Hit Kind*/,
  471|      0|              6 /* SBT index */, KRayParamInvalidId /* SBT Offset */,
  472|      0|              KRayParamInvalidId /* SBT Stride */,
  473|      0|              KRayParamInvalidId /* SBT Record Offset */,
  474|      0|              KRayParamInvalidId /* SBT Record Stride */,
  475|      0|              KRayParamInvalidId /* Miss Index */, 7 /* Ray Origin */,
  476|      0|              8 /* Ray TMin */, 9 /* Ray Direction */, 10 /* Ray TMax */,
  477|      0|              KRayParamInvalidId /* Payload */, 11 /* Hit Object Attribute */))
  478|      0|        return error;
  479|       |
  480|      0|      break;
  481|      0|    }
  482|       |
  483|      0|    case spv::Op::OpHitObjectRecordHitNV: {
  ------------------
  |  Branch (483:5): [True: 0, False: 285k]
  ------------------
  484|      0|      RegisterOpcodeForValidModel(_, inst);
  485|      0|      if (auto error = ValidateHitObjectPointer(_, inst, 0)) return error;
  ------------------
  |  Branch (485:16): [True: 0, False: 0]
  ------------------
  486|       |
  487|      0|      if (auto error = ValidateHitObjectInstructionCommonParameters(
  ------------------
  |  Branch (487:16): [True: 0, False: 0]
  ------------------
  488|      0|              _, inst, 1 /* Acceleration Struct */, 2 /* Instance Id */,
  489|      0|              3 /* Primtive Id */, 4 /* Geometry Index */,
  490|      0|              KRayParamInvalidId /* Ray Flags */,
  491|      0|              KRayParamInvalidId /* Cull Mask */, 5 /* Hit Kind*/,
  492|      0|              KRayParamInvalidId /* SBT index */,
  493|      0|              KRayParamInvalidId /* SBT Offset */,
  494|      0|              KRayParamInvalidId /* SBT Stride */, 6 /* SBT Record Offset */,
  495|      0|              7 /* SBT Record Stride */, KRayParamInvalidId /* Miss Index */,
  496|      0|              8 /* Ray Origin */, 9 /* Ray TMin */, 10 /* Ray Direction */,
  497|      0|              11 /* Ray TMax */, KRayParamInvalidId /* Payload */,
  498|      0|              12 /* Hit Object Attribute */))
  499|      0|        return error;
  500|       |
  501|      0|      break;
  502|      0|    }
  503|       |
  504|      0|    case spv::Op::OpHitObjectTraceRayMotionNV: {
  ------------------
  |  Branch (504:5): [True: 0, False: 285k]
  ------------------
  505|      0|      RegisterOpcodeForValidModel(_, inst);
  506|      0|      if (auto error = ValidateHitObjectPointer(_, inst, 0)) return error;
  ------------------
  |  Branch (506:16): [True: 0, False: 0]
  ------------------
  507|       |
  508|      0|      if (auto error = ValidateHitObjectInstructionCommonParameters(
  ------------------
  |  Branch (508:16): [True: 0, False: 0]
  ------------------
  509|      0|              _, inst, 1 /* Acceleration Struct */,
  510|      0|              KRayParamInvalidId /* Instance Id */,
  511|      0|              KRayParamInvalidId /* Primtive Id */,
  512|      0|              KRayParamInvalidId /* Geometry Index */, 2 /* Ray Flags */,
  513|      0|              3 /* Cull Mask */, KRayParamInvalidId /* Hit Kind*/,
  514|      0|              KRayParamInvalidId /* SBT index */, 4 /* SBT Offset */,
  515|      0|              5 /* SBT Stride */, KRayParamInvalidId /* SBT Record Offset */,
  516|      0|              KRayParamInvalidId /* SBT Record Stride */, 6 /* Miss Index */,
  517|      0|              7 /* Ray Origin */, 8 /* Ray TMin */, 9 /* Ray Direction */,
  518|      0|              10 /* Ray TMax */, 12 /* Payload */,
  519|      0|              KRayParamInvalidId /* Hit Object Attribute */))
  520|      0|        return error;
  521|       |      // Current Time
  522|      0|      const uint32_t current_time_id = _.GetOperandTypeId(inst, 11);
  523|      0|      if (!_.IsFloatScalarType(current_time_id) ||
  ------------------
  |  Branch (523:11): [True: 0, False: 0]
  ------------------
  524|      0|          _.GetBitWidth(current_time_id) != 32) {
  ------------------
  |  Branch (524:11): [True: 0, False: 0]
  ------------------
  525|      0|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
  526|      0|               << "Current Times must be a 32-bit float scalar type";
  527|      0|      }
  528|       |
  529|      0|      break;
  530|      0|    }
  531|       |
  532|      0|    case spv::Op::OpHitObjectTraceRayNV: {
  ------------------
  |  Branch (532:5): [True: 0, False: 285k]
  ------------------
  533|      0|      RegisterOpcodeForValidModel(_, inst);
  534|      0|      if (auto error = ValidateHitObjectPointer(_, inst, 0)) return error;
  ------------------
  |  Branch (534:16): [True: 0, False: 0]
  ------------------
  535|       |
  536|      0|      if (auto error = ValidateHitObjectInstructionCommonParameters(
  ------------------
  |  Branch (536:16): [True: 0, False: 0]
  ------------------
  537|      0|              _, inst, 1 /* Acceleration Struct */,
  538|      0|              KRayParamInvalidId /* Instance Id */,
  539|      0|              KRayParamInvalidId /* Primtive Id */,
  540|      0|              KRayParamInvalidId /* Geometry Index */, 2 /* Ray Flags */,
  541|      0|              3 /* Cull Mask */, KRayParamInvalidId /* Hit Kind*/,
  542|      0|              KRayParamInvalidId /* SBT index */, 4 /* SBT Offset */,
  543|      0|              5 /* SBT Stride */, KRayParamInvalidId /* SBT Record Offset */,
  544|      0|              KRayParamInvalidId /* SBT Record Stride */, 6 /* Miss Index */,
  545|      0|              7 /* Ray Origin */, 8 /* Ray TMin */, 9 /* Ray Direction */,
  546|      0|              10 /* Ray TMax */, 11 /* Payload */,
  547|      0|              KRayParamInvalidId /* Hit Object Attribute */))
  548|      0|        return error;
  549|      0|      break;
  550|      0|    }
  551|       |
  552|      0|    case spv::Op::OpReorderThreadWithHitObjectNV: {
  ------------------
  |  Branch (552:5): [True: 0, False: 285k]
  ------------------
  553|      0|      std::string opcode_name = spvOpcodeString(inst->opcode());
  554|      0|      _.function(inst->function()->id())
  555|      0|          ->RegisterExecutionModelLimitation(
  556|      0|              [opcode_name](spv::ExecutionModel model, std::string* message) {
  557|      0|                if (model != spv::ExecutionModel::RayGenerationKHR) {
  558|      0|                  if (message) {
  559|      0|                    *message = opcode_name +
  560|      0|                               " requires RayGenerationKHR execution model";
  561|      0|                  }
  562|      0|                  return false;
  563|      0|                }
  564|      0|                return true;
  565|      0|              });
  566|       |
  567|      0|      if (auto error = ValidateHitObjectPointer(_, inst, 0)) return error;
  ------------------
  |  Branch (567:16): [True: 0, False: 0]
  ------------------
  568|       |
  569|      0|      if (inst->operands().size() > 1) {
  ------------------
  |  Branch (569:11): [True: 0, False: 0]
  ------------------
  570|      0|        if (inst->operands().size() != 3) {
  ------------------
  |  Branch (570:13): [True: 0, False: 0]
  ------------------
  571|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
  572|      0|                 << "Hint and Bits are optional together i.e "
  573|      0|                 << " Either both Hint and Bits should be provided or neither.";
  574|      0|        }
  575|       |
  576|       |        // Validate the optional opreands Hint and Bits
  577|      0|        const uint32_t hint_id = _.GetOperandTypeId(inst, 1);
  578|      0|        if (!_.IsIntScalarType(hint_id) || _.GetBitWidth(hint_id) != 32) {
  ------------------
  |  Branch (578:13): [True: 0, False: 0]
  |  Branch (578:44): [True: 0, False: 0]
  ------------------
  579|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
  580|      0|                 << "Hint must be a 32-bit int scalar";
  581|      0|        }
  582|      0|        const uint32_t bits_id = _.GetOperandTypeId(inst, 2);
  583|      0|        if (!_.IsIntScalarType(bits_id) || _.GetBitWidth(bits_id) != 32) {
  ------------------
  |  Branch (583:13): [True: 0, False: 0]
  |  Branch (583:44): [True: 0, False: 0]
  ------------------
  584|      0|          return _.diag(SPV_ERROR_INVALID_DATA, inst)
  585|      0|                 << "bits must be a 32-bit int scalar";
  586|      0|        }
  587|      0|      }
  588|      0|      break;
  589|      0|    }
  590|       |
  591|      0|    case spv::Op::OpReorderThreadWithHintNV: {
  ------------------
  |  Branch (591:5): [True: 0, False: 285k]
  ------------------
  592|      0|      std::string opcode_name = spvOpcodeString(inst->opcode());
  593|      0|      _.function(inst->function()->id())
  594|      0|          ->RegisterExecutionModelLimitation(
  595|      0|              [opcode_name](spv::ExecutionModel model, std::string* message) {
  596|      0|                if (model != spv::ExecutionModel::RayGenerationKHR) {
  597|      0|                  if (message) {
  598|      0|                    *message = opcode_name +
  599|      0|                               " requires RayGenerationKHR execution model";
  600|      0|                  }
  601|      0|                  return false;
  602|      0|                }
  603|      0|                return true;
  604|      0|              });
  605|       |
  606|      0|      const uint32_t hint_id = _.GetOperandTypeId(inst, 0);
  607|      0|      if (!_.IsIntScalarType(hint_id) || _.GetBitWidth(hint_id) != 32) {
  ------------------
  |  Branch (607:11): [True: 0, False: 0]
  |  Branch (607:42): [True: 0, False: 0]
  ------------------
  608|      0|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
  609|      0|               << "Hint must be a 32-bit int scalar";
  610|      0|      }
  611|       |
  612|      0|      const uint32_t bits_id = _.GetOperandTypeId(inst, 1);
  613|      0|      if (!_.IsIntScalarType(bits_id) || _.GetBitWidth(bits_id) != 32) {
  ------------------
  |  Branch (613:11): [True: 0, False: 0]
  |  Branch (613:42): [True: 0, False: 0]
  ------------------
  614|      0|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
  615|      0|               << "bits must be a 32-bit int scalar";
  616|      0|      }
  617|      0|    }
  618|       |
  619|   285k|    default:
  ------------------
  |  Branch (619:5): [True: 285k, False: 0]
  ------------------
  620|   285k|      break;
  621|   285k|  }
  622|   285k|  return SPV_SUCCESS;
  623|   285k|}

_ZN8spvtools3val12IsValidScopeEj:
   25|    755|bool IsValidScope(uint32_t scope) {
   26|       |  // Deliberately avoid a default case so we have to update the list when the
   27|       |  // scopes list changes.
   28|    755|  switch (static_cast<spv::Scope>(scope)) {
  ------------------
  |  Branch (28:11): [True: 17, False: 738]
  ------------------
   29|     11|    case spv::Scope::CrossDevice:
  ------------------
  |  Branch (29:5): [True: 11, False: 744]
  ------------------
   30|    325|    case spv::Scope::Device:
  ------------------
  |  Branch (30:5): [True: 314, False: 441]
  ------------------
   31|    371|    case spv::Scope::Workgroup:
  ------------------
  |  Branch (31:5): [True: 46, False: 709]
  ------------------
   32|    706|    case spv::Scope::Subgroup:
  ------------------
  |  Branch (32:5): [True: 335, False: 420]
  ------------------
   33|    737|    case spv::Scope::Invocation:
  ------------------
  |  Branch (33:5): [True: 31, False: 724]
  ------------------
   34|    737|    case spv::Scope::QueueFamilyKHR:
  ------------------
  |  Branch (34:5): [True: 0, False: 755]
  ------------------
   35|    738|    case spv::Scope::ShaderCallKHR:
  ------------------
  |  Branch (35:5): [True: 1, False: 754]
  ------------------
   36|    738|      return true;
   37|      0|    case spv::Scope::Max:
  ------------------
  |  Branch (37:5): [True: 0, False: 755]
  ------------------
   38|      0|      break;
   39|    755|  }
   40|     17|  return false;
   41|    755|}
_ZN8spvtools3val13ValidateScopeERNS0_17ValidationState_tEPKNS0_11InstructionEj:
   44|    786|                           uint32_t scope) {
   45|    786|  spv::Op opcode = inst->opcode();
   46|    786|  bool is_int32 = false, is_const_int32 = false;
   47|    786|  uint32_t value = 0;
   48|    786|  std::tie(is_int32, is_const_int32, value) = _.EvalInt32IfConst(scope);
   49|       |
   50|    786|  if (!is_int32) {
  ------------------
  |  Branch (50:7): [True: 1, False: 785]
  ------------------
   51|      1|    return _.diag(SPV_ERROR_INVALID_DATA, inst)
   52|      1|           << spvOpcodeString(opcode) << ": expected scope to be a 32-bit int";
   53|      1|  }
   54|       |
   55|    785|  if (!is_const_int32) {
  ------------------
  |  Branch (55:7): [True: 30, False: 755]
  ------------------
   56|     30|    if (_.HasCapability(spv::Capability::Shader) &&
  ------------------
  |  Branch (56:9): [True: 0, False: 30]
  ------------------
   57|     30|        !_.HasCapability(spv::Capability::CooperativeMatrixNV)) {
  ------------------
  |  Branch (57:9): [True: 0, False: 0]
  ------------------
   58|      0|      return _.diag(SPV_ERROR_INVALID_DATA, inst)
   59|      0|             << "Scope ids must be OpConstant when Shader capability is "
   60|      0|             << "present";
   61|      0|    }
   62|     30|    if (_.HasCapability(spv::Capability::Shader) &&
  ------------------
  |  Branch (62:9): [True: 0, False: 30]
  ------------------
   63|     30|        _.HasCapability(spv::Capability::CooperativeMatrixNV) &&
  ------------------
  |  Branch (63:9): [True: 0, False: 0]
  ------------------
   64|     30|        !spvOpcodeIsConstant(_.GetIdOpcode(scope))) {
  ------------------
  |  Branch (64:9): [True: 0, False: 0]
  ------------------
   65|      0|      return _.diag(SPV_ERROR_INVALID_DATA, inst)
   66|      0|             << "Scope ids must be constant or specialization constant when "
   67|      0|             << "CooperativeMatrixNV capability is present";
   68|      0|    }
   69|     30|  }
   70|       |
   71|    785|  if (is_const_int32 && !IsValidScope(value)) {
  ------------------
  |  Branch (71:7): [True: 755, False: 30]
  |  Branch (71:25): [True: 17, False: 738]
  ------------------
   72|     17|    return _.diag(SPV_ERROR_INVALID_DATA, inst)
   73|     17|           << "Invalid scope value:\n " << _.Disassemble(*_.FindDef(scope));
   74|     17|  }
   75|       |
   76|    768|  return SPV_SUCCESS;
   77|    785|}
_ZN8spvtools3val22ValidateExecutionScopeERNS0_17ValidationState_tEPKNS0_11InstructionEj:
   80|    392|                                    const Instruction* inst, uint32_t scope) {
   81|    392|  spv::Op opcode = inst->opcode();
   82|    392|  bool is_int32 = false, is_const_int32 = false;
   83|    392|  uint32_t tmp_value = 0;
   84|    392|  std::tie(is_int32, is_const_int32, tmp_value) = _.EvalInt32IfConst(scope);
   85|       |
   86|    392|  if (auto error = ValidateScope(_, inst, scope)) {
  ------------------
  |  Branch (86:12): [True: 13, False: 379]
  ------------------
   87|     13|    return error;
   88|     13|  }
   89|       |
   90|    379|  if (!is_const_int32) {
  ------------------
  |  Branch (90:7): [True: 15, False: 364]
  ------------------
   91|     15|    return SPV_SUCCESS;
   92|     15|  }
   93|       |
   94|    364|  spv::Scope value = spv::Scope(tmp_value);
   95|       |
   96|       |  // Vulkan specific rules
   97|    364|  if (spvIsVulkanEnv(_.context()->target_env)) {
  ------------------
  |  Branch (97:7): [True: 0, False: 364]
  ------------------
   98|       |    // Vulkan 1.1 specific rules
   99|      0|    if (_.context()->target_env != SPV_ENV_VULKAN_1_0) {
  ------------------
  |  Branch (99:9): [True: 0, False: 0]
  ------------------
  100|       |      // Scope for Non Uniform Group Operations must be limited to Subgroup
  101|      0|      if (spvOpcodeIsNonUniformGroupOperation(opcode) &&
  ------------------
  |  Branch (101:11): [True: 0, False: 0]
  ------------------
  102|      0|          value != spv::Scope::Subgroup) {
  ------------------
  |  Branch (102:11): [True: 0, False: 0]
  ------------------
  103|      0|        return _.diag(SPV_ERROR_INVALID_DATA, inst)
  104|      0|               << _.VkErrorID(4642) << spvOpcodeString(opcode)
  105|      0|               << ": in Vulkan environment Execution scope is limited to "
  106|      0|               << "Subgroup";
  107|      0|      }
  108|      0|    }
  109|       |
  110|       |    // OpControlBarrier must only use Subgroup execution scope for a subset of
  111|       |    // execution models.
  112|      0|    if (opcode == spv::Op::OpControlBarrier && value != spv::Scope::Subgroup) {
  ------------------
  |  Branch (112:9): [True: 0, False: 0]
  |  Branch (112:48): [True: 0, False: 0]
  ------------------
  113|      0|      std::string errorVUID = _.VkErrorID(4682);
  114|      0|      _.function(inst->function()->id())
  115|      0|          ->RegisterExecutionModelLimitation([errorVUID](
  116|      0|                                                 spv::ExecutionModel model,
  117|      0|                                                 std::string* message) {
  118|      0|            if (model == spv::ExecutionModel::Fragment ||
  119|      0|                model == spv::ExecutionModel::Vertex ||
  120|      0|                model == spv::ExecutionModel::Geometry ||
  121|      0|                model == spv::ExecutionModel::TessellationEvaluation ||
  122|      0|                model == spv::ExecutionModel::RayGenerationKHR ||
  123|      0|                model == spv::ExecutionModel::IntersectionKHR ||
  124|      0|                model == spv::ExecutionModel::AnyHitKHR ||
  125|      0|                model == spv::ExecutionModel::ClosestHitKHR ||
  126|      0|                model == spv::ExecutionModel::MissKHR) {
  127|      0|              if (message) {
  128|      0|                *message =
  129|      0|                    errorVUID +
  130|      0|                    "in Vulkan environment, OpControlBarrier execution scope "
  131|      0|                    "must be Subgroup for Fragment, Vertex, Geometry, "
  132|      0|                    "TessellationEvaluation, RayGeneration, Intersection, "
  133|      0|                    "AnyHit, ClosestHit, and Miss execution models";
  134|      0|              }
  135|      0|              return false;
  136|      0|            }
  137|      0|            return true;
  138|      0|          });
  139|      0|    }
  140|       |
  141|       |    // Only subset of execution models support Workgroup.
  142|      0|    if (value == spv::Scope::Workgroup) {
  ------------------
  |  Branch (142:9): [True: 0, False: 0]
  ------------------
  143|      0|      std::string errorVUID = _.VkErrorID(4637);
  144|      0|      _.function(inst->function()->id())
  145|      0|          ->RegisterExecutionModelLimitation(
  146|      0|              [errorVUID](spv::ExecutionModel model, std::string* message) {
  147|      0|                if (model != spv::ExecutionModel::TaskNV &&
  148|      0|                    model != spv::ExecutionModel::MeshNV &&
  149|      0|                    model != spv::ExecutionModel::TaskEXT &&
  150|      0|                    model != spv::ExecutionModel::MeshEXT &&
  151|      0|                    model != spv::ExecutionModel::TessellationControl &&
  152|      0|                    model != spv::ExecutionModel::GLCompute) {
  153|      0|                  if (message) {
  154|      0|                    *message =
  155|      0|                        errorVUID +
  156|      0|                        "in Vulkan environment, Workgroup execution scope is "
  157|      0|                        "only for TaskNV, MeshNV, TaskEXT, MeshEXT, "
  158|      0|                        "TessellationControl, and GLCompute execution models";
  159|      0|                  }
  160|      0|                  return false;
  161|      0|                }
  162|      0|                return true;
  163|      0|              });
  164|      0|    }
  165|       |
  166|       |    // Vulkan generic rules
  167|       |    // Scope for execution must be limited to Workgroup or Subgroup
  168|      0|    if (value != spv::Scope::Workgroup && value != spv::Scope::Subgroup) {
  ------------------
  |  Branch (168:9): [True: 0, False: 0]
  |  Branch (168:43): [True: 0, False: 0]
  ------------------
  169|      0|      return _.diag(SPV_ERROR_INVALID_DATA, inst)
  170|      0|             << _.VkErrorID(4636) << spvOpcodeString(opcode)
  171|      0|             << ": in Vulkan environment Execution Scope is limited to "
  172|      0|             << "Workgroup and Subgroup";
  173|      0|    }
  174|      0|  }
  175|       |
  176|       |  // TODO(atgoo@github.com) Add checks for OpenCL and OpenGL environments.
  177|       |
  178|       |  // General SPIRV rules
  179|       |  // Scope for execution must be limited to Workgroup or Subgroup for
  180|       |  // non-uniform operations
  181|    364|  if (spvOpcodeIsNonUniformGroupOperation(opcode) &&
  ------------------
  |  Branch (181:7): [True: 0, False: 364]
  ------------------
  182|    364|      value != spv::Scope::Subgroup && value != spv::Scope::Workgroup) {
  ------------------
  |  Branch (182:7): [True: 0, False: 0]
  |  Branch (182:40): [True: 0, False: 0]
  ------------------
  183|      0|    return _.diag(SPV_ERROR_INVALID_DATA, inst)
  184|      0|           << spvOpcodeString(opcode)
  185|      0|           << ": Execution scope is limited to Subgroup or Workgroup";
  186|      0|  }
  187|       |
  188|    364|  return SPV_SUCCESS;
  189|    364|}
_ZN8spvtools3val19ValidateMemoryScopeERNS0_17ValidationState_tEPKNS0_11InstructionEj:
  192|    394|                                 uint32_t scope) {
  193|    394|  const spv::Op opcode = inst->opcode();
  194|    394|  bool is_int32 = false, is_const_int32 = false;
  195|    394|  uint32_t tmp_value = 0;
  196|    394|  std::tie(is_int32, is_const_int32, tmp_value) = _.EvalInt32IfConst(scope);
  197|       |
  198|    394|  if (auto error = ValidateScope(_, inst, scope)) {
  ------------------
  |  Branch (198:12): [True: 5, False: 389]
  ------------------
  199|      5|    return error;
  200|      5|  }
  201|       |
  202|    389|  if (!is_const_int32) {
  ------------------
  |  Branch (202:7): [True: 15, False: 374]
  ------------------
  203|     15|    return SPV_SUCCESS;
  204|     15|  }
  205|       |
  206|    374|  spv::Scope value = spv::Scope(tmp_value);
  207|       |
  208|    374|  if (value == spv::Scope::QueueFamilyKHR) {
  ------------------
  |  Branch (208:7): [True: 0, False: 374]
  ------------------
  209|      0|    if (_.HasCapability(spv::Capability::VulkanMemoryModelKHR)) {
  ------------------
  |  Branch (209:9): [True: 0, False: 0]
  ------------------
  210|      0|      return SPV_SUCCESS;
  211|      0|    } else {
  212|      0|      return _.diag(SPV_ERROR_INVALID_DATA, inst)
  213|      0|             << spvOpcodeString(opcode)
  214|      0|             << ": Memory Scope QueueFamilyKHR requires capability "
  215|      0|             << "VulkanMemoryModelKHR";
  216|      0|    }
  217|      0|  }
  218|       |
  219|    374|  if (value == spv::Scope::Device &&
  ------------------
  |  Branch (219:7): [True: 159, False: 215]
  ------------------
  220|    374|      _.HasCapability(spv::Capability::VulkanMemoryModelKHR) &&
  ------------------
  |  Branch (220:7): [True: 0, False: 159]
  ------------------
  221|    374|      !_.HasCapability(spv::Capability::VulkanMemoryModelDeviceScopeKHR)) {
  ------------------
  |  Branch (221:7): [True: 0, False: 0]
  ------------------
  222|      0|    return _.diag(SPV_ERROR_INVALID_DATA, inst)
  223|      0|           << "Use of device scope with VulkanKHR memory model requires the "
  224|      0|           << "VulkanMemoryModelDeviceScopeKHR capability";
  225|      0|  }
  226|       |
  227|       |  // Vulkan Specific rules
  228|    374|  if (spvIsVulkanEnv(_.context()->target_env)) {
  ------------------
  |  Branch (228:7): [True: 0, False: 374]
  ------------------
  229|      0|    if (value != spv::Scope::Device && value != spv::Scope::Workgroup &&
  ------------------
  |  Branch (229:9): [True: 0, False: 0]
  |  Branch (229:40): [True: 0, False: 0]
  ------------------
  230|      0|        value != spv::Scope::Subgroup && value != spv::Scope::Invocation &&
  ------------------
  |  Branch (230:9): [True: 0, False: 0]
  |  Branch (230:42): [True: 0, False: 0]
  ------------------
  231|      0|        value != spv::Scope::ShaderCallKHR &&
  ------------------
  |  Branch (231:9): [True: 0, False: 0]
  ------------------
  232|      0|        value != spv::Scope::QueueFamily) {
  ------------------
  |  Branch (232:9): [True: 0, False: 0]
  ------------------
  233|      0|      return _.diag(SPV_ERROR_INVALID_DATA, inst)
  234|      0|             << _.VkErrorID(4638) << spvOpcodeString(opcode)
  235|      0|             << ": in Vulkan environment Memory Scope is limited to Device, "
  236|      0|                "QueueFamily, Workgroup, ShaderCallKHR, Subgroup, or "
  237|      0|                "Invocation";
  238|      0|    } else if (_.context()->target_env == SPV_ENV_VULKAN_1_0 &&
  ------------------
  |  Branch (238:16): [True: 0, False: 0]
  ------------------
  239|      0|               value == spv::Scope::Subgroup &&
  ------------------
  |  Branch (239:16): [True: 0, False: 0]
  ------------------
  240|      0|               !_.HasCapability(spv::Capability::SubgroupBallotKHR) &&
  ------------------
  |  Branch (240:16): [True: 0, False: 0]
  ------------------
  241|      0|               !_.HasCapability(spv::Capability::SubgroupVoteKHR)) {
  ------------------
  |  Branch (241:16): [True: 0, False: 0]
  ------------------
  242|      0|      return _.diag(SPV_ERROR_INVALID_DATA, inst)
  243|      0|             << _.VkErrorID(6997) << spvOpcodeString(opcode)
  244|      0|             << ": in Vulkan 1.0 environment Memory Scope is can not be "
  245|      0|                "Subgroup without SubgroupBallotKHR or SubgroupVoteKHR "
  246|      0|                "declared";
  247|      0|    }
  248|       |
  249|      0|    if (value == spv::Scope::ShaderCallKHR) {
  ------------------
  |  Branch (249:9): [True: 0, False: 0]
  ------------------
  250|      0|      std::string errorVUID = _.VkErrorID(4640);
  251|      0|      _.function(inst->function()->id())
  252|      0|          ->RegisterExecutionModelLimitation(
  253|      0|              [errorVUID](spv::ExecutionModel model, std::string* message) {
  254|      0|                if (model != spv::ExecutionModel::RayGenerationKHR &&
  255|      0|                    model != spv::ExecutionModel::IntersectionKHR &&
  256|      0|                    model != spv::ExecutionModel::AnyHitKHR &&
  257|      0|                    model != spv::ExecutionModel::ClosestHitKHR &&
  258|      0|                    model != spv::ExecutionModel::MissKHR &&
  259|      0|                    model != spv::ExecutionModel::CallableKHR) {
  260|      0|                  if (message) {
  261|      0|                    *message =
  262|      0|                        errorVUID +
  263|      0|                        "ShaderCallKHR Memory Scope requires a ray tracing "
  264|      0|                        "execution model";
  265|      0|                  }
  266|      0|                  return false;
  267|      0|                }
  268|      0|                return true;
  269|      0|              });
  270|      0|    }
  271|       |
  272|      0|    if (value == spv::Scope::Workgroup) {
  ------------------
  |  Branch (272:9): [True: 0, False: 0]
  ------------------
  273|      0|      std::string errorVUID = _.VkErrorID(7321);
  274|      0|      _.function(inst->function()->id())
  275|      0|          ->RegisterExecutionModelLimitation(
  276|      0|              [errorVUID](spv::ExecutionModel model, std::string* message) {
  277|      0|                if (model != spv::ExecutionModel::GLCompute &&
  278|      0|                    model != spv::ExecutionModel::TessellationControl &&
  279|      0|                    model != spv::ExecutionModel::TaskNV &&
  280|      0|                    model != spv::ExecutionModel::MeshNV &&
  281|      0|                    model != spv::ExecutionModel::TaskEXT &&
  282|      0|                    model != spv::ExecutionModel::MeshEXT) {
  283|      0|                  if (message) {
  284|      0|                    *message = errorVUID +
  285|      0|                               "Workgroup Memory Scope is limited to MeshNV, "
  286|      0|                               "TaskNV, MeshEXT, TaskEXT, TessellationControl, "
  287|      0|                               "and GLCompute execution model";
  288|      0|                  }
  289|      0|                  return false;
  290|      0|                }
  291|      0|                return true;
  292|      0|              });
  293|       |
  294|      0|      if (_.memory_model() == spv::MemoryModel::GLSL450) {
  ------------------
  |  Branch (294:11): [True: 0, False: 0]
  ------------------
  295|      0|        errorVUID = _.VkErrorID(7320);
  296|      0|        _.function(inst->function()->id())
  297|      0|            ->RegisterExecutionModelLimitation(
  298|      0|                [errorVUID](spv::ExecutionModel model, std::string* message) {
  299|      0|                  if (model == spv::ExecutionModel::TessellationControl) {
  300|      0|                    if (message) {
  301|      0|                      *message =
  302|      0|                          errorVUID +
  303|      0|                          "Workgroup Memory Scope can't be used with "
  304|      0|                          "TessellationControl using GLSL450 Memory Model";
  305|      0|                    }
  306|      0|                    return false;
  307|      0|                  }
  308|      0|                  return true;
  309|      0|                });
  310|      0|      }
  311|      0|    }
  312|      0|  }
  313|       |
  314|       |  // TODO(atgoo@github.com) Add checks for OpenCL and OpenGL environments.
  315|       |
  316|    374|  return SPV_SUCCESS;
  317|    374|}

_ZN8spvtools3val21ValidateSmallTypeUsesERNS0_17ValidationState_tEPKNS0_11InstructionE:
   24|  69.8k|                                   const Instruction* inst) {
   25|  69.8k|  if (!_.HasCapability(spv::Capability::Shader) || inst->type_id() == 0 ||
  ------------------
  |  Branch (25:7): [True: 458, False: 69.4k]
  |  Branch (25:52): [True: 50.1k, False: 19.2k]
  ------------------
   26|  69.8k|      !_.ContainsLimitedUseIntOrFloatType(inst->type_id())) {
  ------------------
  |  Branch (26:7): [True: 19.2k, False: 0]
  ------------------
   27|  69.8k|    return SPV_SUCCESS;
   28|  69.8k|  }
   29|       |
   30|      0|  if (_.IsPointerType(inst->type_id())) return SPV_SUCCESS;
  ------------------
  |  Branch (30:7): [True: 0, False: 0]
  ------------------
   31|       |
   32|       |  // The validator should previously have checked ways to generate 8- or 16-bit
   33|       |  // types. So we only need to considervalid paths from source to sink.
   34|       |  // When restricted, uses of 8- or 16-bit types can only be stores,
   35|       |  // width-only conversions, decorations and copy object.
   36|      0|  for (auto use : inst->uses()) {
  ------------------
  |  Branch (36:17): [True: 0, False: 0]
  ------------------
   37|      0|    const auto* user = use.first;
   38|      0|    switch (user->opcode()) {
   39|      0|      case spv::Op::OpDecorate:
  ------------------
  |  Branch (39:7): [True: 0, False: 0]
  ------------------
   40|      0|      case spv::Op::OpDecorateId:
  ------------------
  |  Branch (40:7): [True: 0, False: 0]
  ------------------
   41|      0|      case spv::Op::OpCopyObject:
  ------------------
  |  Branch (41:7): [True: 0, False: 0]
  ------------------
   42|      0|      case spv::Op::OpStore:
  ------------------
  |  Branch (42:7): [True: 0, False: 0]
  ------------------
   43|      0|      case spv::Op::OpFConvert:
  ------------------
  |  Branch (43:7): [True: 0, False: 0]
  ------------------
   44|      0|      case spv::Op::OpUConvert:
  ------------------
  |  Branch (44:7): [True: 0, False: 0]
  ------------------
   45|      0|      case spv::Op::OpSConvert:
  ------------------
  |  Branch (45:7): [True: 0, False: 0]
  ------------------
   46|      0|        break;
   47|      0|      default:
  ------------------
  |  Branch (47:7): [True: 0, False: 0]
  ------------------
   48|      0|        return _.diag(SPV_ERROR_INVALID_ID, user)
   49|      0|               << "Invalid use of 8- or 16-bit result";
   50|      0|    }
   51|      0|  }
   52|       |
   53|      0|  return SPV_SUCCESS;
   54|      0|}

_ZN8spvtools3val8TypePassERNS0_17ValidationState_tEPKNS0_11InstructionE:
  603|   286k|spv_result_t TypePass(ValidationState_t& _, const Instruction* inst) {
  604|   286k|  if (!spvOpcodeGeneratesType(inst->opcode()) &&
  ------------------
  |  Branch (604:7): [True: 263k, False: 22.8k]
  ------------------
  605|   286k|      inst->opcode() != spv::Op::OpTypeForwardPointer) {
  ------------------
  |  Branch (605:7): [True: 263k, False: 2]
  ------------------
  606|   263k|    return SPV_SUCCESS;
  607|   263k|  }
  608|       |
  609|  22.8k|  if (auto error = ValidateUniqueness(_, inst)) return error;
  ------------------
  |  Branch (609:12): [True: 1, False: 22.8k]
  ------------------
  610|       |
  611|  22.8k|  switch (inst->opcode()) {
  612|  2.48k|    case spv::Op::OpTypeInt:
  ------------------
  |  Branch (612:5): [True: 2.48k, False: 20.3k]
  ------------------
  613|  2.48k|      if (auto error = ValidateTypeInt(_, inst)) return error;
  ------------------
  |  Branch (613:16): [True: 111, False: 2.37k]
  ------------------
  614|  2.37k|      break;
  615|  2.37k|    case spv::Op::OpTypeFloat:
  ------------------
  |  Branch (615:5): [True: 1.35k, False: 21.4k]
  ------------------
  616|  1.35k|      if (auto error = ValidateTypeFloat(_, inst)) return error;
  ------------------
  |  Branch (616:16): [True: 89, False: 1.26k]
  ------------------
  617|  1.26k|      break;
  618|  1.93k|    case spv::Op::OpTypeVector:
  ------------------
  |  Branch (618:5): [True: 1.93k, False: 20.9k]
  ------------------
  619|  1.93k|      if (auto error = ValidateTypeVector(_, inst)) return error;
  ------------------
  |  Branch (619:16): [True: 28, False: 1.91k]
  ------------------
  620|  1.91k|      break;
  621|  1.91k|    case spv::Op::OpTypeMatrix:
  ------------------
  |  Branch (621:5): [True: 613, False: 22.2k]
  ------------------
  622|    613|      if (auto error = ValidateTypeMatrix(_, inst)) return error;
  ------------------
  |  Branch (622:16): [True: 18, False: 595]
  ------------------
  623|    595|      break;
  624|    927|    case spv::Op::OpTypeArray:
  ------------------
  |  Branch (624:5): [True: 927, False: 21.9k]
  ------------------
  625|    927|      if (auto error = ValidateTypeArray(_, inst)) return error;
  ------------------
  |  Branch (625:16): [True: 15, False: 912]
  ------------------
  626|    912|      break;
  627|    912|    case spv::Op::OpTypeRuntimeArray:
  ------------------
  |  Branch (627:5): [True: 64, False: 22.7k]
  ------------------
  628|     64|      if (auto error = ValidateTypeRuntimeArray(_, inst)) return error;
  ------------------
  |  Branch (628:16): [True: 4, False: 60]
  ------------------
  629|     60|      break;
  630|  3.33k|    case spv::Op::OpTypeStruct:
  ------------------
  |  Branch (630:5): [True: 3.33k, False: 19.5k]
  ------------------
  631|  3.33k|      if (auto error = ValidateTypeStruct(_, inst)) return error;
  ------------------
  |  Branch (631:16): [True: 11, False: 3.32k]
  ------------------
  632|  3.32k|      break;
  633|  5.60k|    case spv::Op::OpTypePointer:
  ------------------
  |  Branch (633:5): [True: 5.60k, False: 17.2k]
  ------------------
  634|  5.60k|      if (auto error = ValidateTypePointer(_, inst)) return error;
  ------------------
  |  Branch (634:16): [True: 3, False: 5.60k]
  ------------------
  635|  5.60k|      break;
  636|  5.60k|    case spv::Op::OpTypeFunction:
  ------------------
  |  Branch (636:5): [True: 2.88k, False: 19.9k]
  ------------------
  637|  2.88k|      if (auto error = ValidateTypeFunction(_, inst)) return error;
  ------------------
  |  Branch (637:16): [True: 14, False: 2.86k]
  ------------------
  638|  2.86k|      break;
  639|  2.86k|    case spv::Op::OpTypeForwardPointer:
  ------------------
  |  Branch (639:5): [True: 2, False: 22.8k]
  ------------------
  640|      2|      if (auto error = ValidateTypeForwardPointer(_, inst)) return error;
  ------------------
  |  Branch (640:16): [True: 2, False: 0]
  ------------------
  641|      0|      break;
  642|      0|    case spv::Op::OpTypeCooperativeMatrixNV:
  ------------------
  |  Branch (642:5): [True: 0, False: 22.8k]
  ------------------
  643|      0|      if (auto error = ValidateTypeCooperativeMatrixNV(_, inst)) return error;
  ------------------
  |  Branch (643:16): [True: 0, False: 0]
  ------------------
  644|      0|      break;
  645|  3.64k|    default:
  ------------------
  |  Branch (645:5): [True: 3.64k, False: 19.2k]
  ------------------
  646|  3.64k|      break;
  647|  22.8k|  }
  648|       |
  649|  22.5k|  return SPV_SUCCESS;
  650|  22.8k|}
validate_type.cpp:_ZN8spvtools3val12_GLOBAL__N_118ValidateUniquenessERNS0_17ValidationState_tEPKNS0_11InstructionE:
   47|  22.8k|spv_result_t ValidateUniqueness(ValidationState_t& _, const Instruction* inst) {
   48|  22.8k|  if (_.HasExtension(Extension::kSPV_VALIDATOR_ignore_type_decl_unique))
  ------------------
  |  Branch (48:7): [True: 7, False: 22.8k]
  ------------------
   49|      7|    return SPV_SUCCESS;
   50|       |
   51|  22.8k|  const auto opcode = inst->opcode();
   52|  22.8k|  if (opcode != spv::Op::OpTypeArray && opcode != spv::Op::OpTypeRuntimeArray &&
  ------------------
  |  Branch (52:7): [True: 21.9k, False: 927]
  |  Branch (52:41): [True: 21.8k, False: 64]
  ------------------
   53|  22.8k|      opcode != spv::Op::OpTypeStruct && opcode != spv::Op::OpTypePointer &&
  ------------------
  |  Branch (53:7): [True: 18.5k, False: 3.33k]
  |  Branch (53:42): [True: 12.9k, False: 5.60k]
  ------------------
   54|  22.8k|      !_.RegisterUniqueTypeDeclaration(inst)) {
  ------------------
  |  Branch (54:7): [True: 1, False: 12.9k]
  ------------------
   55|      1|    return _.diag(SPV_ERROR_INVALID_DATA, inst)
   56|      1|           << "Duplicate non-aggregate type declarations are not allowed. "
   57|      1|              "Opcode: "
   58|      1|           << spvOpcodeString(opcode) << " id: " << inst->id();
   59|      1|  }
   60|       |
   61|  22.8k|  return SPV_SUCCESS;
   62|  22.8k|}
validate_type.cpp:_ZN8spvtools3val12_GLOBAL__N_115ValidateTypeIntERNS0_17ValidationState_tEPKNS0_11InstructionE:
   64|  2.48k|spv_result_t ValidateTypeInt(ValidationState_t& _, const Instruction* inst) {
   65|       |  // Validates that the number of bits specified for an Int type is valid.
   66|       |  // Scalar integer types can be parameterized only with 32-bits.
   67|       |  // Int8, Int16, and Int64 capabilities allow using 8-bit, 16-bit, and 64-bit
   68|       |  // integers, respectively.
   69|  2.48k|  auto num_bits = inst->GetOperandAs<const uint32_t>(1);
   70|  2.48k|  if (num_bits != 32) {
  ------------------
  |  Branch (70:7): [True: 92, False: 2.38k]
  ------------------
   71|     92|    if (num_bits == 8) {
  ------------------
  |  Branch (71:9): [True: 22, False: 70]
  ------------------
   72|     22|      if (_.features().declare_int8_type) {
  ------------------
  |  Branch (72:11): [True: 18, False: 4]
  ------------------
   73|     18|        return SPV_SUCCESS;
   74|     18|      }
   75|      4|      return _.diag(SPV_ERROR_INVALID_DATA, inst)
   76|      4|             << "Using an 8-bit integer type requires the Int8 capability,"
   77|      4|                " or an extension that explicitly enables 8-bit integers.";
   78|     70|    } else if (num_bits == 16) {
  ------------------
  |  Branch (78:16): [True: 2, False: 68]
  ------------------
   79|      2|      if (_.features().declare_int16_type) {
  ------------------
  |  Branch (79:11): [True: 0, False: 2]
  ------------------
   80|      0|        return SPV_SUCCESS;
   81|      0|      }
   82|      2|      return _.diag(SPV_ERROR_INVALID_DATA, inst)
   83|      2|             << "Using a 16-bit integer type requires the Int16 capability,"
   84|      2|                " or an extension that explicitly enables 16-bit integers.";
   85|     68|    } else if (num_bits == 64) {
  ------------------
  |  Branch (85:16): [True: 4, False: 64]
  ------------------
   86|      4|      if (_.HasCapability(spv::Capability::Int64)) {
  ------------------
  |  Branch (86:11): [True: 2, False: 2]
  ------------------
   87|      2|        return SPV_SUCCESS;
   88|      2|      }
   89|      2|      return _.diag(SPV_ERROR_INVALID_DATA, inst)
   90|      2|             << "Using a 64-bit integer type requires the Int64 capability.";
   91|     64|    } else {
   92|     64|      return _.diag(SPV_ERROR_INVALID_DATA, inst)
   93|     64|             << "Invalid number of bits (" << num_bits
   94|     64|             << ") used for OpTypeInt.";
   95|     64|    }
   96|     92|  }
   97|       |
   98|  2.38k|  const auto signedness_index = 2;
   99|  2.38k|  const auto signedness = inst->GetOperandAs<uint32_t>(signedness_index);
  100|  2.38k|  if (signedness != 0 && signedness != 1) {
  ------------------
  |  Branch (100:7): [True: 1.21k, False: 1.17k]
  |  Branch (100:26): [True: 39, False: 1.17k]
  ------------------
  101|     39|    return _.diag(SPV_ERROR_INVALID_VALUE, inst)
  102|     39|           << "OpTypeInt has invalid signedness:";
  103|     39|  }
  104|       |
  105|       |  // SPIR-V Spec 2.16.3: Validation Rules for Kernel Capabilities: The
  106|       |  // Signedness in OpTypeInt must always be 0.
  107|  2.35k|  if (spv::Op::OpTypeInt == inst->opcode() &&
  ------------------
  |  Branch (107:7): [True: 2.35k, False: 0]
  ------------------
  108|  2.35k|      _.HasCapability(spv::Capability::Kernel) &&
  ------------------
  |  Branch (108:7): [True: 14, False: 2.33k]
  ------------------
  109|  2.35k|      inst->GetOperandAs<uint32_t>(2) != 0u) {
  ------------------
  |  Branch (109:7): [True: 0, False: 14]
  ------------------
  110|      0|    return _.diag(SPV_ERROR_INVALID_BINARY, inst)
  111|      0|           << "The Signedness in OpTypeInt "
  112|      0|              "must always be 0 when Kernel "
  113|      0|              "capability is used.";
  114|      0|  }
  115|       |
  116|  2.35k|  return SPV_SUCCESS;
  117|  2.35k|}
validate_type.cpp:_ZN8spvtools3val12_GLOBAL__N_117ValidateTypeFloatERNS0_17ValidationState_tEPKNS0_11InstructionE:
  119|  1.35k|spv_result_t ValidateTypeFloat(ValidationState_t& _, const Instruction* inst) {
  120|       |  // Validates that the number of bits specified for an Int type is valid.
  121|       |  // Scalar integer types can be parameterized only with 32-bits.
  122|       |  // Int8, Int16, and Int64 capabilities allow using 8-bit, 16-bit, and 64-bit
  123|       |  // integers, respectively.
  124|  1.35k|  auto num_bits = inst->GetOperandAs<const uint32_t>(1);
  125|  1.35k|  if (num_bits == 32) {
  ------------------
  |  Branch (125:7): [True: 1.25k, False: 99]
  ------------------
  126|  1.25k|    return SPV_SUCCESS;
  127|  1.25k|  }
  128|     99|  if (num_bits == 16) {
  ------------------
  |  Branch (128:7): [True: 15, False: 84]
  ------------------
  129|     15|    if (_.features().declare_float16_type) {
  ------------------
  |  Branch (129:9): [True: 10, False: 5]
  ------------------
  130|     10|      return SPV_SUCCESS;
  131|     10|    }
  132|      5|    return _.diag(SPV_ERROR_INVALID_DATA, inst)
  133|      5|           << "Using a 16-bit floating point "
  134|      5|           << "type requires the Float16 or Float16Buffer capability,"
  135|      5|              " or an extension that explicitly enables 16-bit floating point.";
  136|     15|  }
  137|     84|  if (num_bits == 64) {
  ------------------
  |  Branch (137:7): [True: 0, False: 84]
  ------------------
  138|      0|    if (_.HasCapability(spv::Capability::Float64)) {
  ------------------
  |  Branch (138:9): [True: 0, False: 0]
  ------------------
  139|      0|      return SPV_SUCCESS;
  140|      0|    }
  141|      0|    return _.diag(SPV_ERROR_INVALID_DATA, inst)
  142|      0|           << "Using a 64-bit floating point "
  143|      0|           << "type requires the Float64 capability.";
  144|      0|  }
  145|     84|  return _.diag(SPV_ERROR_INVALID_DATA, inst)
  146|     84|         << "Invalid number of bits (" << num_bits << ") used for OpTypeFloat.";
  147|     84|}
validate_type.cpp:_ZN8spvtools3val12_GLOBAL__N_118ValidateTypeVectorERNS0_17ValidationState_tEPKNS0_11InstructionE:
  149|  1.93k|spv_result_t ValidateTypeVector(ValidationState_t& _, const Instruction* inst) {
  150|  1.93k|  const auto component_index = 1;
  151|  1.93k|  const auto component_id = inst->GetOperandAs<uint32_t>(component_index);
  152|  1.93k|  const auto component_type = _.FindDef(component_id);
  153|  1.93k|  if (!component_type || !spvOpcodeIsScalarType(component_type->opcode())) {
  ------------------
  |  Branch (153:7): [True: 0, False: 1.93k]
  |  Branch (153:26): [True: 1, False: 1.93k]
  ------------------
  154|      1|    return _.diag(SPV_ERROR_INVALID_ID, inst)
  155|      1|           << "OpTypeVector Component Type <id> " << _.getIdName(component_id)
  156|      1|           << " is not a scalar type.";
  157|      1|  }
  158|       |
  159|       |  // Validates that the number of components in the vector is valid.
  160|       |  // Vector types can only be parameterized as having 2, 3, or 4 components.
  161|       |  // If the Vector16 capability is added, 8 and 16 components are also allowed.
  162|  1.93k|  auto num_components = inst->GetOperandAs<const uint32_t>(2);
  163|  1.93k|  if (num_components == 2 || num_components == 3 || num_components == 4) {
  ------------------
  |  Branch (163:7): [True: 659, False: 1.27k]
  |  Branch (163:30): [True: 407, False: 872]
  |  Branch (163:53): [True: 843, False: 29]
  ------------------
  164|  1.90k|    return SPV_SUCCESS;
  165|  1.90k|  } else if (num_components == 8 || num_components == 16) {
  ------------------
  |  Branch (165:14): [True: 2, False: 27]
  |  Branch (165:37): [True: 2, False: 25]
  ------------------
  166|      4|    if (_.HasCapability(spv::Capability::Vector16)) {
  ------------------
  |  Branch (166:9): [True: 2, False: 2]
  ------------------
  167|      2|      return SPV_SUCCESS;
  168|      2|    }
  169|      2|    return _.diag(SPV_ERROR_INVALID_DATA, inst)
  170|      2|           << "Having " << num_components << " components for "
  171|      2|           << spvOpcodeString(inst->opcode())
  172|      2|           << " requires the Vector16 capability";
  173|     25|  } else {
  174|     25|    return _.diag(SPV_ERROR_INVALID_DATA, inst)
  175|     25|           << "Illegal number of components (" << num_components << ") for "
  176|     25|           << spvOpcodeString(inst->opcode());
  177|     25|  }
  178|       |
  179|      0|  return SPV_SUCCESS;
  180|  1.93k|}
validate_type.cpp:_ZN8spvtools3val12_GLOBAL__N_118ValidateTypeMatrixERNS0_17ValidationState_tEPKNS0_11InstructionE:
  182|    613|spv_result_t ValidateTypeMatrix(ValidationState_t& _, const Instruction* inst) {
  183|    613|  const auto column_type_index = 1;
  184|    613|  const auto column_type_id = inst->GetOperandAs<uint32_t>(column_type_index);
  185|    613|  const auto column_type = _.FindDef(column_type_id);
  186|    613|  if (!column_type || spv::Op::OpTypeVector != column_type->opcode()) {
  ------------------
  |  Branch (186:7): [True: 0, False: 613]
  |  Branch (186:23): [True: 1, False: 612]
  ------------------
  187|      1|    return _.diag(SPV_ERROR_INVALID_ID, inst)
  188|      1|           << "Columns in a matrix must be of type vector.";
  189|      1|  }
  190|       |
  191|       |  // Trace back once more to find out the type of components in the vector.
  192|       |  // Operand 1 is the <id> of the type of data in the vector.
  193|    612|  const auto comp_type_id = column_type->GetOperandAs<uint32_t>(1);
  194|    612|  auto comp_type_instruction = _.FindDef(comp_type_id);
  195|    612|  if (comp_type_instruction->opcode() != spv::Op::OpTypeFloat) {
  ------------------
  |  Branch (195:7): [True: 1, False: 611]
  ------------------
  196|      1|    return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Matrix types can only be "
  197|      1|                                                   "parameterized with "
  198|      1|                                                   "floating-point types.";
  199|      1|  }
  200|       |
  201|       |  // Validates that the matrix has 2,3, or 4 columns.
  202|    611|  auto num_cols = inst->GetOperandAs<const uint32_t>(2);
  203|    611|  if (num_cols != 2 && num_cols != 3 && num_cols != 4) {
  ------------------
  |  Branch (203:7): [True: 412, False: 199]
  |  Branch (203:24): [True: 209, False: 203]
  |  Branch (203:41): [True: 16, False: 193]
  ------------------
  204|     16|    return _.diag(SPV_ERROR_INVALID_DATA, inst) << "Matrix types can only be "
  205|     16|                                                   "parameterized as having "
  206|     16|                                                   "only 2, 3, or 4 columns.";
  207|     16|  }
  208|       |
  209|    595|  return SPV_SUCCESS;
  210|    611|}
validate_type.cpp:_ZN8spvtools3val12_GLOBAL__N_117ValidateTypeArrayERNS0_17ValidationState_tEPKNS0_11InstructionE:
  212|    927|spv_result_t ValidateTypeArray(ValidationState_t& _, const Instruction* inst) {
  213|    927|  const auto element_type_index = 1;
  214|    927|  const auto element_type_id = inst->GetOperandAs<uint32_t>(element_type_index);
  215|    927|  const auto element_type = _.FindDef(element_type_id);
  216|    927|  if (!element_type || !spvOpcodeGeneratesType(element_type->opcode())) {
  ------------------
  |  Branch (216:7): [True: 0, False: 927]
  |  Branch (216:24): [True: 2, False: 925]
  ------------------
  217|      2|    return _.diag(SPV_ERROR_INVALID_ID, inst)
  218|      2|           << "OpTypeArray Element Type <id> " << _.getIdName(element_type_id)
  219|      2|           << " is not a type.";
  220|      2|  }
  221|       |
  222|    925|  if (element_type->opcode() == spv::Op::OpTypeVoid) {
  ------------------
  |  Branch (222:7): [True: 1, False: 924]
  ------------------
  223|      1|    return _.diag(SPV_ERROR_INVALID_ID, inst)
  224|      1|           << "OpTypeArray Element Type <id> " << _.getIdName(element_type_id)
  225|      1|           << " is a void type.";
  226|      1|  }
  227|       |
  228|    924|  if (spvIsVulkanEnv(_.context()->target_env) &&
  ------------------
  |  Branch (228:7): [True: 0, False: 924]
  ------------------
  229|    924|      element_type->opcode() == spv::Op::OpTypeRuntimeArray) {
  ------------------
  |  Branch (229:7): [True: 0, False: 0]
  ------------------
  230|      0|    return _.diag(SPV_ERROR_INVALID_ID, inst)
  231|      0|           << _.VkErrorID(4680) << "OpTypeArray Element Type <id> "
  232|      0|           << _.getIdName(element_type_id) << " is not valid in "
  233|      0|           << spvLogStringForEnv(_.context()->target_env) << " environments.";
  234|      0|  }
  235|       |
  236|    924|  const auto length_index = 2;
  237|    924|  const auto length_id = inst->GetOperandAs<uint32_t>(length_index);
  238|    924|  const auto length = _.FindDef(length_id);
  239|    924|  if (!length || !spvOpcodeIsConstant(length->opcode())) {
  ------------------
  |  Branch (239:7): [True: 0, False: 924]
  |  Branch (239:18): [True: 1, False: 923]
  ------------------
  240|      1|    return _.diag(SPV_ERROR_INVALID_ID, inst)
  241|      1|           << "OpTypeArray Length <id> " << _.getIdName(length_id)
  242|      1|           << " is not a scalar constant type.";
  243|      1|  }
  244|       |
  245|       |  // NOTE: Check the initialiser value of the constant
  246|    923|  const auto const_inst = length->words();
  247|    923|  const auto const_result_type_index = 1;
  248|    923|  const auto const_result_type = _.FindDef(const_inst[const_result_type_index]);
  249|    923|  if (!const_result_type || spv::Op::OpTypeInt != const_result_type->opcode()) {
  ------------------
  |  Branch (249:7): [True: 0, False: 923]
  |  Branch (249:29): [True: 2, False: 921]
  ------------------
  250|      2|    return _.diag(SPV_ERROR_INVALID_ID, inst)
  251|      2|           << "OpTypeArray Length <id> " << _.getIdName(length_id)
  252|      2|           << " is not a constant integer type.";
  253|      2|  }
  254|       |
  255|    921|  switch (length->opcode()) {
  256|     51|    case spv::Op::OpSpecConstant:
  ------------------
  |  Branch (256:5): [True: 51, False: 870]
  ------------------
  257|    921|    case spv::Op::OpConstant: {
  ------------------
  |  Branch (257:5): [True: 870, False: 51]
  ------------------
  258|    921|      auto& type_words = const_result_type->words();
  259|    921|      const bool is_signed = type_words[3] > 0;
  260|    921|      const uint32_t width = type_words[2];
  261|    921|      const int64_t ivalue = ConstantLiteralAsInt64(width, length->words());
  262|    921|      if (ivalue == 0 || (ivalue < 0 && is_signed)) {
  ------------------
  |  Branch (262:11): [True: 2, False: 919]
  |  Branch (262:27): [True: 227, False: 692]
  |  Branch (262:41): [True: 7, False: 220]
  ------------------
  263|      9|        return _.diag(SPV_ERROR_INVALID_ID, inst)
  264|      9|               << "OpTypeArray Length <id> " << _.getIdName(length_id)
  265|      9|               << " default value must be at least 1: found " << ivalue;
  266|      9|      }
  267|    921|    } break;
  268|    912|    case spv::Op::OpConstantNull:
  ------------------
  |  Branch (268:5): [True: 0, False: 921]
  ------------------
  269|      0|      return _.diag(SPV_ERROR_INVALID_ID, inst)
  270|      0|             << "OpTypeArray Length <id> " << _.getIdName(length_id)
  271|      0|             << " default value must be at least 1.";
  272|      0|    case spv::Op::OpSpecConstantOp:
  ------------------
  |  Branch (272:5): [True: 0, False: 921]
  ------------------
  273|       |      // Assume it's OK, rather than try to evaluate the operation.
  274|      0|      break;
  275|      0|    default:
  ------------------
  |  Branch (275:5): [True: 0, False: 921]
  ------------------
  276|      0|      assert(0 && "bug in spvOpcodeIsConstant() or result type isn't int");
  277|    921|  }
  278|    912|  return SPV_SUCCESS;
  279|    921|}
validate_type.cpp:_ZN8spvtools3val12_GLOBAL__N_122ConstantLiteralAsInt64EjRKNSt3__16vectorIjNS2_9allocatorIjEEEE:
   33|    921|                               const std::vector<uint32_t>& const_words) {
   34|    921|  const uint32_t lo_word = const_words[3];
   35|    921|  if (width <= 32) return int32_t(lo_word);
  ------------------
  |  Branch (35:7): [True: 921, False: 0]
  ------------------
   36|      0|  assert(width <= 64);
   37|      0|  assert(const_words.size() > 4);
   38|      0|  const uint32_t hi_word = const_words[4];  // Must exist, per spec.
   39|      0|  return static_cast<int64_t>(uint64_t(lo_word) | uint64_t(hi_word) << 32);
   40|    921|}
validate_type.cpp:_ZN8spvtools3val12_GLOBAL__N_124ValidateTypeRuntimeArrayERNS0_17ValidationState_tEPKNS0_11InstructionE:
  282|     64|                                      const Instruction* inst) {
  283|     64|  const auto element_type_index = 1;
  284|     64|  const auto element_id = inst->GetOperandAs<uint32_t>(element_type_index);
  285|     64|  const auto element_type = _.FindDef(element_id);
  286|     64|  if (!element_type || !spvOpcodeGeneratesType(element_type->opcode())) {
  ------------------
  |  Branch (286:7): [True: 0, False: 64]
  |  Branch (286:24): [True: 0, False: 64]
  ------------------
  287|      0|    return _.diag(SPV_ERROR_INVALID_ID, inst)
  288|      0|           << "OpTypeRuntimeArray Element Type <id> " << _.getIdName(element_id)
  289|      0|           << " is not a type.";
  290|      0|  }
  291|       |
  292|     64|  if (element_type->opcode() == spv::Op::OpTypeVoid) {
  ------------------
  |  Branch (292:7): [True: 4, False: 60]
  ------------------
  293|      4|    return _.diag(SPV_ERROR_INVALID_ID, inst)
  294|      4|           << "OpTypeRuntimeArray Element Type <id> " << _.getIdName(element_id)
  295|      4|           << " is a void type.";
  296|      4|  }
  297|       |
  298|     60|  if (spvIsVulkanEnv(_.context()->target_env) &&
  ------------------
  |  Branch (298:7): [True: 0, False: 60]
  ------------------
  299|     60|      element_type->opcode() == spv::Op::OpTypeRuntimeArray) {
  ------------------
  |  Branch (299:7): [True: 0, False: 0]
  ------------------
  300|      0|    return _.diag(SPV_ERROR_INVALID_ID, inst)
  301|      0|           << _.VkErrorID(4680) << "OpTypeRuntimeArray Element Type <id> "
  302|      0|           << _.getIdName(element_id) << " is not valid in "
  303|      0|           << spvLogStringForEnv(_.context()->target_env) << " environments.";
  304|      0|  }
  305|       |
  306|     60|  return SPV_SUCCESS;
  307|     60|}
validate_type.cpp:_ZN8spvtools3val12_GLOBAL__N_118ValidateTypeStructERNS0_17ValidationState_tEPKNS0_11InstructionE:
  309|  3.33k|spv_result_t ValidateTypeStruct(ValidationState_t& _, const Instruction* inst) {
  310|  3.33k|  const uint32_t struct_id = inst->GetOperandAs<uint32_t>(0);
  311|  3.33k|  for (size_t member_type_index = 1;
  312|  5.85k|       member_type_index < inst->operands().size(); ++member_type_index) {
  ------------------
  |  Branch (312:8): [True: 2.53k, False: 3.32k]
  ------------------
  313|  2.53k|    auto member_type_id = inst->GetOperandAs<uint32_t>(member_type_index);
  314|  2.53k|    if (member_type_id == inst->id()) {
  ------------------
  |  Branch (314:9): [True: 0, False: 2.53k]
  ------------------
  315|      0|      return _.diag(SPV_ERROR_INVALID_ID, inst)
  316|      0|             << "Structure members may not be self references";
  317|      0|    }
  318|       |
  319|  2.53k|    auto member_type = _.FindDef(member_type_id);
  320|  2.53k|    if (!member_type || !spvOpcodeGeneratesType(member_type->opcode())) {
  ------------------
  |  Branch (320:9): [True: 0, False: 2.53k]
  |  Branch (320:25): [True: 10, False: 2.52k]
  ------------------
  321|     10|      return _.diag(SPV_ERROR_INVALID_ID, inst)
  322|     10|             << "OpTypeStruct Member Type <id> " << _.getIdName(member_type_id)
  323|     10|             << " is not a type.";
  324|     10|    }
  325|  2.52k|    if (member_type->opcode() == spv::Op::OpTypeVoid) {
  ------------------
  |  Branch (325:9): [True: 0, False: 2.52k]
  ------------------
  326|      0|      return _.diag(SPV_ERROR_INVALID_ID, inst)
  327|      0|             << "Structures cannot contain a void type.";
  328|      0|    }
  329|  2.52k|    if (spv::Op::OpTypeStruct == member_type->opcode() &&
  ------------------
  |  Branch (329:9): [True: 298, False: 2.22k]
  ------------------
  330|  2.52k|        _.IsStructTypeWithBuiltInMember(member_type_id)) {
  ------------------
  |  Branch (330:9): [True: 1, False: 297]
  ------------------
  331|      1|      return _.diag(SPV_ERROR_INVALID_ID, inst)
  332|      1|             << "Structure <id> " << _.getIdName(member_type_id)
  333|      1|             << " contains members with BuiltIn decoration. Therefore this "
  334|      1|             << "structure may not be contained as a member of another "
  335|      1|             << "structure "
  336|      1|             << "type. Structure <id> " << _.getIdName(struct_id)
  337|      1|             << " contains structure <id> " << _.getIdName(member_type_id)
  338|      1|             << ".";
  339|      1|    }
  340|       |
  341|  2.51k|    if (spvIsVulkanEnv(_.context()->target_env) &&
  ------------------
  |  Branch (341:9): [True: 0, False: 2.51k]
  ------------------
  342|  2.51k|        member_type->opcode() == spv::Op::OpTypeRuntimeArray) {
  ------------------
  |  Branch (342:9): [True: 0, False: 0]
  ------------------
  343|      0|      const bool is_last_member =
  344|      0|          member_type_index == inst->operands().size() - 1;
  345|      0|      if (!is_last_member) {
  ------------------
  |  Branch (345:11): [True: 0, False: 0]
  ------------------
  346|      0|        return _.diag(SPV_ERROR_INVALID_ID, inst)
  347|      0|               << _.VkErrorID(4680) << "In "
  348|      0|               << spvLogStringForEnv(_.context()->target_env)
  349|      0|               << ", OpTypeRuntimeArray must only be used for the last member "
  350|      0|                  "of an OpTypeStruct";
  351|      0|      }
  352|       |
  353|      0|      if (!_.HasDecoration(inst->id(), spv::Decoration::Block) &&
  ------------------
  |  Branch (353:11): [True: 0, False: 0]
  ------------------
  354|      0|          !_.HasDecoration(inst->id(), spv::Decoration::BufferBlock)) {
  ------------------
  |  Branch (354:11): [True: 0, False: 0]
  ------------------
  355|      0|        return _.diag(SPV_ERROR_INVALID_ID, inst)
  356|      0|               << _.VkErrorID(4680)
  357|      0|               << spvLogStringForEnv(_.context()->target_env)
  358|      0|               << ", OpTypeStruct containing an OpTypeRuntimeArray "
  359|      0|               << "must be decorated with Block or BufferBlock.";
  360|      0|      }
  361|      0|    }
  362|  2.51k|  }
  363|       |
  364|  3.32k|  bool has_nested_blockOrBufferBlock_struct = false;
  365|       |  // Struct members start at word 2 of OpTypeStruct instruction.
  366|  5.84k|  for (size_t word_i = 2; word_i < inst->words().size(); ++word_i) {
  ------------------
  |  Branch (366:27): [True: 2.51k, False: 3.32k]
  ------------------
  367|  2.51k|    auto member = inst->word(word_i);
  368|  2.51k|    auto memberTypeInstr = _.FindDef(member);
  369|  2.51k|    if (memberTypeInstr && spv::Op::OpTypeStruct == memberTypeInstr->opcode()) {
  ------------------
  |  Branch (369:9): [True: 2.51k, False: 0]
  |  Branch (369:28): [True: 297, False: 2.22k]
  ------------------
  370|    297|      if (_.HasDecoration(memberTypeInstr->id(), spv::Decoration::Block) ||
  ------------------
  |  Branch (370:11): [True: 29, False: 268]
  ------------------
  371|    297|          _.HasDecoration(memberTypeInstr->id(),
  ------------------
  |  Branch (371:11): [True: 11, False: 257]
  ------------------
  372|    268|                          spv::Decoration::BufferBlock) ||
  373|    297|          _.GetHasNestedBlockOrBufferBlockStruct(memberTypeInstr->id()))
  ------------------
  |  Branch (373:11): [True: 8, False: 249]
  ------------------
  374|     48|        has_nested_blockOrBufferBlock_struct = true;
  375|    297|    }
  376|  2.51k|  }
  377|       |
  378|  3.32k|  _.SetHasNestedBlockOrBufferBlockStruct(inst->id(),
  379|  3.32k|                                         has_nested_blockOrBufferBlock_struct);
  380|  3.32k|  if (_.GetHasNestedBlockOrBufferBlockStruct(inst->id()) &&
  ------------------
  |  Branch (380:7): [True: 42, False: 3.28k]
  ------------------
  381|  3.32k|      (_.HasDecoration(inst->id(), spv::Decoration::BufferBlock) ||
  ------------------
  |  Branch (381:8): [True: 0, False: 42]
  ------------------
  382|     42|       _.HasDecoration(inst->id(), spv::Decoration::Block))) {
  ------------------
  |  Branch (382:8): [True: 0, False: 42]
  ------------------
  383|      0|    return _.diag(SPV_ERROR_INVALID_ID, inst)
  384|      0|           << "rules: A Block or BufferBlock cannot be nested within another "
  385|      0|              "Block or BufferBlock. ";
  386|      0|  }
  387|       |
  388|  3.32k|  std::unordered_set<uint32_t> built_in_members;
  389|  4.85k|  for (auto decoration : _.id_decorations(struct_id)) {
  ------------------
  |  Branch (389:24): [True: 4.85k, False: 3.32k]
  ------------------
  390|  4.85k|    if (decoration.dec_type() == spv::Decoration::BuiltIn &&
  ------------------
  |  Branch (390:9): [True: 90, False: 4.76k]
  ------------------
  391|  4.85k|        decoration.struct_member_index() != Decoration::kInvalidMember) {
  ------------------
  |  Branch (391:9): [True: 26, False: 64]
  ------------------
  392|     26|      built_in_members.insert(decoration.struct_member_index());
  393|     26|    }
  394|  4.85k|  }
  395|  3.32k|  int num_struct_members = static_cast<int>(inst->operands().size() - 1);
  396|  3.32k|  int num_builtin_members = static_cast<int>(built_in_members.size());
  397|  3.32k|  if (num_builtin_members > 0 && num_builtin_members != num_struct_members) {
  ------------------
  |  Branch (397:7): [True: 22, False: 3.30k]
  |  Branch (397:34): [True: 0, False: 22]
  ------------------
  398|      0|    return _.diag(SPV_ERROR_INVALID_ID, inst)
  399|      0|           << "When BuiltIn decoration is applied to a structure-type member, "
  400|      0|           << "all members of that structure type must also be decorated with "
  401|      0|           << "BuiltIn (No allowed mixing of built-in variables and "
  402|      0|           << "non-built-in variables within a single structure). Structure id "
  403|      0|           << struct_id << " does not meet this requirement.";
  404|      0|  }
  405|  3.32k|  if (num_builtin_members > 0) {
  ------------------
  |  Branch (405:7): [True: 22, False: 3.30k]
  ------------------
  406|     22|    _.RegisterStructTypeWithBuiltInMember(struct_id);
  407|     22|  }
  408|       |
  409|  3.32k|  const auto isOpaqueType = [&_](const Instruction* opaque_inst) {
  410|  3.32k|    auto opcode = opaque_inst->opcode();
  411|  3.32k|    if (_.HasCapability(spv::Capability::BindlessTextureNV) &&
  412|  3.32k|        (opcode == spv::Op::OpTypeImage || opcode == spv::Op::OpTypeSampler ||
  413|  3.32k|         opcode == spv::Op::OpTypeSampledImage)) {
  414|  3.32k|      return false;
  415|  3.32k|    } else if (spvOpcodeIsBaseOpaqueType(opcode)) {
  416|  3.32k|      return true;
  417|  3.32k|    }
  418|  3.32k|    return false;
  419|  3.32k|  };
  420|       |
  421|  3.32k|  if (spvIsVulkanEnv(_.context()->target_env) &&
  ------------------
  |  Branch (421:7): [True: 0, False: 3.32k]
  |  Branch (421:7): [True: 0, False: 3.32k]
  ------------------
  422|  3.32k|      !_.options()->before_hlsl_legalization &&
  ------------------
  |  Branch (422:7): [True: 0, False: 0]
  ------------------
  423|  3.32k|      _.ContainsType(inst->id(), isOpaqueType)) {
  ------------------
  |  Branch (423:7): [True: 0, False: 0]
  ------------------
  424|      0|    return _.diag(SPV_ERROR_INVALID_ID, inst)
  425|      0|           << _.VkErrorID(4667) << "In "
  426|      0|           << spvLogStringForEnv(_.context()->target_env)
  427|      0|           << ", OpTypeStruct must not contain an opaque type.";
  428|      0|  }
  429|       |
  430|  3.32k|  return SPV_SUCCESS;
  431|  3.32k|}
validate_type.cpp:_ZN8spvtools3val12_GLOBAL__N_119ValidateTypePointerERNS0_17ValidationState_tEPKNS0_11InstructionE:
  434|  5.60k|                                 const Instruction* inst) {
  435|  5.60k|  auto type_id = inst->GetOperandAs<uint32_t>(2);
  436|  5.60k|  auto type = _.FindDef(type_id);
  437|  5.60k|  if (!type || !spvOpcodeGeneratesType(type->opcode())) {
  ------------------
  |  Branch (437:7): [True: 0, False: 5.60k]
  |  Branch (437:16): [True: 3, False: 5.60k]
  ------------------
  438|      3|    return _.diag(SPV_ERROR_INVALID_ID, inst)
  439|      3|           << "OpTypePointer Type <id> " << _.getIdName(type_id)
  440|      3|           << " is not a type.";
  441|      3|  }
  442|       |  // See if this points to a storage image.
  443|  5.60k|  const auto storage_class = inst->GetOperandAs<spv::StorageClass>(1);
  444|  5.60k|  if (storage_class == spv::StorageClass::UniformConstant) {
  ------------------
  |  Branch (444:7): [True: 159, False: 5.44k]
  ------------------
  445|       |    // Unpack an optional level of arraying.
  446|    159|    if (type->opcode() == spv::Op::OpTypeArray ||
  ------------------
  |  Branch (446:9): [True: 0, False: 159]
  ------------------
  447|    159|        type->opcode() == spv::Op::OpTypeRuntimeArray) {
  ------------------
  |  Branch (447:9): [True: 3, False: 156]
  ------------------
  448|      3|      type_id = type->GetOperandAs<uint32_t>(1);
  449|      3|      type = _.FindDef(type_id);
  450|      3|    }
  451|    159|    if (type->opcode() == spv::Op::OpTypeImage) {
  ------------------
  |  Branch (451:9): [True: 33, False: 126]
  ------------------
  452|     33|      const auto sampled = type->GetOperandAs<uint32_t>(6);
  453|       |      // 2 indicates this image is known to be be used without a sampler, i.e.
  454|       |      // a storage image.
  455|     33|      if (sampled == 2) _.RegisterPointerToStorageImage(inst->id());
  ------------------
  |  Branch (455:11): [True: 8, False: 25]
  ------------------
  456|     33|    }
  457|    159|  }
  458|       |
  459|  5.60k|  if (!_.IsValidStorageClass(storage_class)) {
  ------------------
  |  Branch (459:7): [True: 0, False: 5.60k]
  ------------------
  460|      0|    return _.diag(SPV_ERROR_INVALID_BINARY, inst)
  461|      0|           << _.VkErrorID(4643)
  462|      0|           << "Invalid storage class for target environment";
  463|      0|  }
  464|       |
  465|  5.60k|  return SPV_SUCCESS;
  466|  5.60k|}
validate_type.cpp:_ZN8spvtools3val12_GLOBAL__N_120ValidateTypeFunctionERNS0_17ValidationState_tEPKNS0_11InstructionE:
  469|  2.88k|                                  const Instruction* inst) {
  470|  2.88k|  const auto return_type_id = inst->GetOperandAs<uint32_t>(1);
  471|  2.88k|  const auto return_type = _.FindDef(return_type_id);
  472|  2.88k|  if (!return_type || !spvOpcodeGeneratesType(return_type->opcode())) {
  ------------------
  |  Branch (472:7): [True: 0, False: 2.88k]
  |  Branch (472:23): [True: 2, False: 2.87k]
  ------------------
  473|      2|    return _.diag(SPV_ERROR_INVALID_ID, inst)
  474|      2|           << "OpTypeFunction Return Type <id> " << _.getIdName(return_type_id)
  475|      2|           << " is not a type.";
  476|      2|  }
  477|  2.87k|  size_t num_args = 0;
  478|  3.72k|  for (size_t param_type_index = 2; param_type_index < inst->operands().size();
  ------------------
  |  Branch (478:37): [True: 849, False: 2.87k]
  ------------------
  479|  2.87k|       ++param_type_index, ++num_args) {
  480|    849|    const auto param_id = inst->GetOperandAs<uint32_t>(param_type_index);
  481|    849|    const auto param_type = _.FindDef(param_id);
  482|    849|    if (!param_type || !spvOpcodeGeneratesType(param_type->opcode())) {
  ------------------
  |  Branch (482:9): [True: 0, False: 849]
  |  Branch (482:24): [True: 1, False: 848]
  ------------------
  483|      1|      return _.diag(SPV_ERROR_INVALID_ID, inst)
  484|      1|             << "OpTypeFunction Parameter Type <id> " << _.getIdName(param_id)
  485|      1|             << " is not a type.";
  486|      1|    }
  487|       |
  488|    848|    if (param_type->opcode() == spv::Op::OpTypeVoid) {
  ------------------
  |  Branch (488:9): [True: 1, False: 847]
  ------------------
  489|      1|      return _.diag(SPV_ERROR_INVALID_ID, inst)
  490|      1|             << "OpTypeFunction Parameter Type <id> " << _.getIdName(param_id)
  491|      1|             << " cannot be OpTypeVoid.";
  492|      1|    }
  493|    848|  }
  494|  2.87k|  const uint32_t num_function_args_limit =
  495|  2.87k|      _.options()->universal_limits_.max_function_args;
  496|  2.87k|  if (num_args > num_function_args_limit) {
  ------------------
  |  Branch (496:7): [True: 0, False: 2.87k]
  ------------------
  497|      0|    return _.diag(SPV_ERROR_INVALID_ID, inst)
  498|      0|           << "OpTypeFunction may not take more than "
  499|      0|           << num_function_args_limit << " arguments. OpTypeFunction <id> "
  500|      0|           << _.getIdName(inst->GetOperandAs<uint32_t>(0)) << " has "
  501|      0|           << num_args << " arguments.";
  502|      0|  }
  503|       |
  504|       |  // The only valid uses of OpTypeFunction are in an OpFunction, debugging, or
  505|       |  // decoration instruction.
  506|  3.30k|  for (auto& pair : inst->uses()) {
  ------------------
  |  Branch (506:19): [True: 3.30k, False: 2.86k]
  ------------------
  507|  3.30k|    const auto* use = pair.first;
  508|  3.30k|    if (use->opcode() != spv::Op::OpFunction &&
  ------------------
  |  Branch (508:9): [True: 431, False: 2.87k]
  ------------------
  509|  3.30k|        !spvOpcodeIsDebug(use->opcode()) && !use->IsNonSemantic() &&
  ------------------
  |  Branch (509:9): [True: 304, False: 127]
  |  Branch (509:45): [True: 304, False: 0]
  ------------------
  510|  3.30k|        !spvOpcodeIsDecoration(use->opcode())) {
  ------------------
  |  Branch (510:9): [True: 10, False: 294]
  ------------------
  511|     10|      return _.diag(SPV_ERROR_INVALID_ID, use)
  512|     10|             << "Invalid use of function type result id "
  513|     10|             << _.getIdName(inst->id()) << ".";
  514|     10|    }
  515|  3.30k|  }
  516|       |
  517|  2.86k|  return SPV_SUCCESS;
  518|  2.87k|}
validate_type.cpp:_ZN8spvtools3val12_GLOBAL__N_126ValidateTypeForwardPointerERNS0_17ValidationState_tEPKNS0_11InstructionE:
  521|      2|                                        const Instruction* inst) {
  522|      2|  const auto pointer_type_id = inst->GetOperandAs<uint32_t>(0);
  523|      2|  const auto pointer_type_inst = _.FindDef(pointer_type_id);
  524|      2|  if (pointer_type_inst->opcode() != spv::Op::OpTypePointer) {
  ------------------
  |  Branch (524:7): [True: 2, False: 0]
  ------------------
  525|      2|    return _.diag(SPV_ERROR_INVALID_ID, inst)
  526|      2|           << "Pointer type in OpTypeForwardPointer is not a pointer type.";
  527|      2|  }
  528|       |
  529|      0|  const auto storage_class = inst->GetOperandAs<spv::StorageClass>(1);
  530|      0|  if (storage_class != pointer_type_inst->GetOperandAs<spv::StorageClass>(1)) {
  ------------------
  |  Branch (530:7): [True: 0, False: 0]
  ------------------
  531|      0|    return _.diag(SPV_ERROR_INVALID_ID, inst)
  532|      0|           << "Storage class in OpTypeForwardPointer does not match the "
  533|      0|           << "pointer definition.";
  534|      0|  }
  535|       |
  536|      0|  const auto pointee_type_id = pointer_type_inst->GetOperandAs<uint32_t>(2);
  537|      0|  const auto pointee_type = _.FindDef(pointee_type_id);
  538|      0|  if (!pointee_type || pointee_type->opcode() != spv::Op::OpTypeStruct) {
  ------------------
  |  Branch (538:7): [True: 0, False: 0]
  |  Branch (538:24): [True: 0, False: 0]
  ------------------
  539|      0|    return _.diag(SPV_ERROR_INVALID_ID, inst)
  540|      0|           << "Forward pointers must point to a structure";
  541|      0|  }
  542|       |
  543|      0|  if (spvIsVulkanEnv(_.context()->target_env)) {
  ------------------
  |  Branch (543:7): [True: 0, False: 0]
  ------------------
  544|      0|    if (storage_class != spv::StorageClass::PhysicalStorageBuffer) {
  ------------------
  |  Branch (544:9): [True: 0, False: 0]
  ------------------
  545|      0|      return _.diag(SPV_ERROR_INVALID_ID, inst)
  546|      0|             << _.VkErrorID(4711)
  547|      0|             << "In Vulkan, OpTypeForwardPointer must have "
  548|      0|             << "a storage class of PhysicalStorageBuffer.";
  549|      0|    }
  550|      0|  }
  551|       |
  552|      0|  return SPV_SUCCESS;
  553|      0|}

_ZN8spvtools3val17ValidationState_tC2EPK13spv_context_tPK23spv_validator_options_tPKjmj:
  171|  8.24k|      max_num_of_warnings_(max_warnings) {
  172|  8.24k|  assert(opt && "Validator options may not be Null.");
  173|       |
  174|      0|  const auto env = context_->target_env;
  175|       |
  176|  8.24k|  if (spvIsVulkanEnv(env)) {
  ------------------
  |  Branch (176:7): [True: 0, False: 8.24k]
  ------------------
  177|       |    // Vulkan 1.1 includes VK_KHR_relaxed_block_layout in core.
  178|      0|    if (env != SPV_ENV_VULKAN_1_0) {
  ------------------
  |  Branch (178:9): [True: 0, False: 0]
  ------------------
  179|      0|      features_.env_relaxed_block_layout = true;
  180|      0|    }
  181|      0|  }
  182|       |
  183|       |  // LocalSizeId is only disallowed prior to Vulkan 1.3 without maintenance4.
  184|  8.24k|  switch (env) {
  185|      0|    case SPV_ENV_VULKAN_1_0:
  ------------------
  |  Branch (185:5): [True: 0, False: 8.24k]
  ------------------
  186|      0|    case SPV_ENV_VULKAN_1_1:
  ------------------
  |  Branch (186:5): [True: 0, False: 8.24k]
  ------------------
  187|      0|    case SPV_ENV_VULKAN_1_1_SPIRV_1_4:
  ------------------
  |  Branch (187:5): [True: 0, False: 8.24k]
  ------------------
  188|      0|    case SPV_ENV_VULKAN_1_2:
  ------------------
  |  Branch (188:5): [True: 0, False: 8.24k]
  ------------------
  189|      0|      features_.env_allow_localsizeid = false;
  190|      0|      break;
  191|  8.24k|    default:
  ------------------
  |  Branch (191:5): [True: 8.24k, False: 0]
  ------------------
  192|  8.24k|      features_.env_allow_localsizeid = true;
  193|  8.24k|      break;
  194|  8.24k|  }
  195|       |
  196|       |  // Only attempt to count if we have words, otherwise let the other validation
  197|       |  // fail and generate an error.
  198|  8.24k|  if (num_words > 0) {
  ------------------
  |  Branch (198:7): [True: 8.23k, False: 3]
  ------------------
  199|       |    // Count the number of instructions in the binary.
  200|       |    // This parse should not produce any error messages. Hijack the context and
  201|       |    // replace the message consumer so that we do not pollute any state in input
  202|       |    // consumer.
  203|  8.23k|    spv_context_t hijacked_context = *ctx;
  204|  8.23k|    hijacked_context.consumer = [](spv_message_level_t, const char*,
  205|  8.23k|                                   const spv_position_t&, const char*) {};
  206|  8.23k|    spvBinaryParse(&hijacked_context, this, words, num_words, setHeader,
  207|  8.23k|                   CountInstructions,
  208|  8.23k|                   /* diagnostic = */ nullptr);
  209|  8.23k|    preallocateStorage();
  210|  8.23k|  }
  211|  8.24k|  UpdateFeaturesBasedOnSpirvVersion(&features_, version_);
  212|       |
  213|  8.24k|  name_mapper_ = spvtools::GetTrivialNameMapper();
  214|  8.24k|  if (options_->use_friendly_names) {
  ------------------
  |  Branch (214:7): [True: 8.24k, False: 0]
  ------------------
  215|  8.24k|    friendly_mapper_ = spvtools::MakeUnique<spvtools::FriendlyNameMapper>(
  216|  8.24k|        context_, words_, num_words_);
  217|  8.24k|    name_mapper_ = friendly_mapper_->GetNameMapper();
  218|  8.24k|  }
  219|  8.24k|}
_ZN8spvtools3val17ValidationState_t18preallocateStorageEv:
  221|  8.23k|void ValidationState_t::preallocateStorage() {
  222|  8.23k|  ordered_instructions_.reserve(total_instructions_);
  223|  8.23k|  module_functions_.reserve(total_functions_);
  224|  8.23k|}
_ZN8spvtools3val17ValidationState_t16ForwardDeclareIdEj:
  226|   550k|spv_result_t ValidationState_t::ForwardDeclareId(uint32_t id) {
  227|   550k|  unresolved_forward_ids_.insert(id);
  228|   550k|  return SPV_SUCCESS;
  229|   550k|}
_ZN8spvtools3val17ValidationState_t23RemoveIfForwardDeclaredEj:
  231|   196k|spv_result_t ValidationState_t::RemoveIfForwardDeclared(uint32_t id) {
  232|   196k|  unresolved_forward_ids_.erase(id);
  233|   196k|  return SPV_SUCCESS;
  234|   196k|}
_ZN8spvtools3val17ValidationState_t22RegisterForwardPointerEj:
  236|    251|spv_result_t ValidationState_t::RegisterForwardPointer(uint32_t id) {
  237|    251|  forward_pointer_ids_.insert(id);
  238|    251|  return SPV_SUCCESS;
  239|    251|}
_ZNK8spvtools3val17ValidationState_t16IsForwardPointerEj:
  241|  12.1k|bool ValidationState_t::IsForwardPointer(uint32_t id) const {
  242|  12.1k|  return (forward_pointer_ids_.find(id) != forward_pointer_ids_.end());
  243|  12.1k|}
_ZN8spvtools3val17ValidationState_t14AssignNameToIdEjNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEE:
  245|  3.36k|void ValidationState_t::AssignNameToId(uint32_t id, std::string name) {
  246|  3.36k|  operand_names_[id] = name;
  247|  3.36k|}
_ZNK8spvtools3val17ValidationState_t9getIdNameEj:
  249|  18.1k|std::string ValidationState_t::getIdName(uint32_t id) const {
  250|  18.1k|  const std::string id_name = name_mapper_(id);
  251|       |
  252|  18.1k|  std::stringstream out;
  253|  18.1k|  out << "'" << id << "[%" << id_name << "]'";
  254|  18.1k|  return out.str();
  255|  18.1k|}
_ZNK8spvtools3val17ValidationState_t27unresolved_forward_id_countEv:
  257|  4.27k|size_t ValidationState_t::unresolved_forward_id_count() const {
  258|  4.27k|  return unresolved_forward_ids_.size();
  259|  4.27k|}
_ZNK8spvtools3val17ValidationState_t20UnresolvedForwardIdsEv:
  261|    602|std::vector<uint32_t> ValidationState_t::UnresolvedForwardIds() const {
  262|    602|  std::vector<uint32_t> out(std::begin(unresolved_forward_ids_),
  263|    602|                            std::end(unresolved_forward_ids_));
  264|    602|  return out;
  265|    602|}
_ZNK8spvtools3val17ValidationState_t11IsDefinedIdEj:
  267|   115k|bool ValidationState_t::IsDefinedId(uint32_t id) const {
  268|   115k|  return all_definitions_.find(id) != std::end(all_definitions_);
  269|   115k|}
_ZNK8spvtools3val17ValidationState_t7FindDefEj:
  271|   779k|const Instruction* ValidationState_t::FindDef(uint32_t id) const {
  272|   779k|  auto it = all_definitions_.find(id);
  273|   779k|  if (it == all_definitions_.end()) return nullptr;
  ------------------
  |  Branch (273:7): [True: 102k, False: 677k]
  ------------------
  274|   677k|  return it->second;
  275|   779k|}
_ZN8spvtools3val17ValidationState_t7FindDefEj:
  277|  2.66M|Instruction* ValidationState_t::FindDef(uint32_t id) {
  278|  2.66M|  auto it = all_definitions_.find(id);
  279|  2.66M|  if (it == all_definitions_.end()) return nullptr;
  ------------------
  |  Branch (279:7): [True: 706k, False: 1.95M]
  ------------------
  280|  1.95M|  return it->second;
  281|  2.66M|}
_ZNK8spvtools3val17ValidationState_t22current_layout_sectionEv:
  283|   956k|ModuleLayoutSection ValidationState_t::current_layout_section() const {
  284|   956k|  return current_layout_section_;
  285|   956k|}
_ZN8spvtools3val17ValidationState_t32ProgressToNextLayoutSectionOrderEv:
  287|  65.8k|void ValidationState_t::ProgressToNextLayoutSectionOrder() {
  288|       |  // Guard against going past the last element(kLayoutFunctionDefinitions)
  289|  65.8k|  if (current_layout_section_ <= kLayoutFunctionDefinitions) {
  ------------------
  |  Branch (289:7): [True: 65.8k, False: 0]
  ------------------
  290|  65.8k|    current_layout_section_ =
  291|  65.8k|        static_cast<ModuleLayoutSection>(current_layout_section_ + 1);
  292|  65.8k|  }
  293|  65.8k|}
_ZN8spvtools3val17ValidationState_t31IsOpcodeInPreviousLayoutSectionEN3spv2OpE:
  295|  62.7k|bool ValidationState_t::IsOpcodeInPreviousLayoutSection(spv::Op op) {
  296|  62.7k|  ModuleLayoutSection section =
  297|  62.7k|      InstructionLayoutSection(current_layout_section_, op);
  298|  62.7k|  return section < current_layout_section_;
  299|  62.7k|}
_ZN8spvtools3val17ValidationState_t30IsOpcodeInCurrentLayoutSectionEN3spv2OpE:
  301|   458k|bool ValidationState_t::IsOpcodeInCurrentLayoutSection(spv::Op op) {
  302|   458k|  return IsInstructionInLayoutSection(current_layout_section_, op);
  303|   458k|}
_ZN8spvtools3val17ValidationState_t4diagE12spv_result_tPKNS0_11InstructionE:
  306|  7.95k|                                         const Instruction* inst) {
  307|  7.95k|  if (error_code == SPV_WARNING) {
  ------------------
  |  Branch (307:7): [True: 1.77k, False: 6.17k]
  ------------------
  308|  1.77k|    if (num_of_warnings_ == max_num_of_warnings_) {
  ------------------
  |  Branch (308:9): [True: 1.33k, False: 437]
  ------------------
  309|  1.33k|      DiagnosticStream({0, 0, 0}, context_->consumer, "", error_code)
  310|  1.33k|          << "Other warnings have been suppressed.\n";
  311|  1.33k|    }
  312|  1.77k|    if (num_of_warnings_ >= max_num_of_warnings_) {
  ------------------
  |  Branch (312:9): [True: 1.33k, False: 437]
  ------------------
  313|  1.33k|      return DiagnosticStream({0, 0, 0}, nullptr, "", error_code);
  314|  1.33k|    }
  315|    437|    ++num_of_warnings_;
  316|    437|  }
  317|       |
  318|  6.61k|  std::string disassembly;
  319|  6.61k|  if (inst) disassembly = Disassemble(*inst);
  ------------------
  |  Branch (319:7): [True: 4.43k, False: 2.18k]
  ------------------
  320|       |
  321|  6.61k|  return DiagnosticStream({0, 0, inst ? inst->LineNum() : 0},
  ------------------
  |  Branch (321:34): [True: 4.43k, False: 2.18k]
  ------------------
  322|  6.61k|                          context_->consumer, disassembly, error_code);
  323|  7.95k|}
_ZN8spvtools3val17ValidationState_t9functionsEv:
  325|  12.3k|std::vector<Function>& ValidationState_t::functions() {
  326|  12.3k|  return module_functions_;
  327|  12.3k|}
_ZN8spvtools3val17ValidationState_t16current_functionEv:
  329|   906k|Function& ValidationState_t::current_function() {
  330|   906k|  assert(in_function_body());
  331|      0|  return module_functions_.back();
  332|   906k|}
_ZN8spvtools3val17ValidationState_t8functionEj:
  345|  3.84k|Function* ValidationState_t::function(uint32_t id) {
  346|  3.84k|  auto it = id_to_function_.find(id);
  347|  3.84k|  if (it == id_to_function_.end()) return nullptr;
  ------------------
  |  Branch (347:7): [True: 0, False: 3.84k]
  ------------------
  348|  3.84k|  return it->second;
  349|  3.84k|}
_ZNK8spvtools3val17ValidationState_t16in_function_bodyEv:
  351|  1.37M|bool ValidationState_t::in_function_body() const { return in_function_; }
_ZNK8spvtools3val17ValidationState_t8in_blockEv:
  353|   548k|bool ValidationState_t::in_block() const {
  354|   548k|  return module_functions_.empty() == false &&
  ------------------
  |  Branch (354:10): [True: 548k, False: 26]
  ------------------
  355|   548k|         module_functions_.back().current_block() != nullptr;
  ------------------
  |  Branch (355:10): [True: 434k, False: 114k]
  ------------------
  356|   548k|}
_ZN8spvtools3val17ValidationState_t18RegisterCapabilityEN3spv10CapabilityE:
  358|  16.2k|void ValidationState_t::RegisterCapability(spv::Capability cap) {
  359|       |  // Avoid redundant work.  Otherwise the recursion could induce work
  360|       |  // quadrdatic in the capability dependency depth. (Ok, not much, but
  361|       |  // it's something.)
  362|  16.2k|  if (module_capabilities_.Contains(cap)) return;
  ------------------
  |  Branch (362:7): [True: 1.02k, False: 15.2k]
  ------------------
  363|       |
  364|  15.2k|  module_capabilities_.Add(cap);
  365|  15.2k|  spv_operand_desc desc;
  366|  15.2k|  if (SPV_SUCCESS == grammar_.lookupOperand(SPV_OPERAND_TYPE_CAPABILITY,
  ------------------
  |  Branch (366:7): [True: 15.2k, False: 6]
  ------------------
  367|  15.2k|                                            uint32_t(cap), &desc)) {
  368|  15.2k|    CapabilitySet(desc->numCapabilities, desc->capabilities)
  369|  15.2k|        .ForEach([this](spv::Capability c) { RegisterCapability(c); });
  370|  15.2k|  }
  371|       |
  372|  15.2k|  switch (cap) {
  373|     98|    case spv::Capability::Kernel:
  ------------------
  |  Branch (373:5): [True: 98, False: 15.1k]
  ------------------
  374|     98|      features_.group_ops_reduce_and_scans = true;
  375|     98|      break;
  376|     30|    case spv::Capability::Int8:
  ------------------
  |  Branch (376:5): [True: 30, False: 15.2k]
  ------------------
  377|     30|      features_.use_int8_type = true;
  378|     30|      features_.declare_int8_type = true;
  379|     30|      break;
  380|      1|    case spv::Capability::StorageBuffer8BitAccess:
  ------------------
  |  Branch (380:5): [True: 1, False: 15.2k]
  ------------------
  381|      1|    case spv::Capability::UniformAndStorageBuffer8BitAccess:
  ------------------
  |  Branch (381:5): [True: 0, False: 15.2k]
  ------------------
  382|      2|    case spv::Capability::StoragePushConstant8:
  ------------------
  |  Branch (382:5): [True: 1, False: 15.2k]
  ------------------
  383|      3|    case spv::Capability::WorkgroupMemoryExplicitLayout8BitAccessKHR:
  ------------------
  |  Branch (383:5): [True: 1, False: 15.2k]
  ------------------
  384|      3|      features_.declare_int8_type = true;
  385|      3|      break;
  386|     11|    case spv::Capability::Int16:
  ------------------
  |  Branch (386:5): [True: 11, False: 15.2k]
  ------------------
  387|     11|      features_.declare_int16_type = true;
  388|     11|      break;
  389|     17|    case spv::Capability::Float16:
  ------------------
  |  Branch (389:5): [True: 17, False: 15.2k]
  ------------------
  390|     44|    case spv::Capability::Float16Buffer:
  ------------------
  |  Branch (390:5): [True: 27, False: 15.2k]
  ------------------
  391|     44|      features_.declare_float16_type = true;
  392|     44|      break;
  393|      1|    case spv::Capability::StorageUniformBufferBlock16:
  ------------------
  |  Branch (393:5): [True: 1, False: 15.2k]
  ------------------
  394|      1|    case spv::Capability::StorageUniform16:
  ------------------
  |  Branch (394:5): [True: 0, False: 15.2k]
  ------------------
  395|      2|    case spv::Capability::StoragePushConstant16:
  ------------------
  |  Branch (395:5): [True: 1, False: 15.2k]
  ------------------
  396|      3|    case spv::Capability::StorageInputOutput16:
  ------------------
  |  Branch (396:5): [True: 1, False: 15.2k]
  ------------------
  397|      4|    case spv::Capability::WorkgroupMemoryExplicitLayout16BitAccessKHR:
  ------------------
  |  Branch (397:5): [True: 1, False: 15.2k]
  ------------------
  398|      4|      features_.declare_int16_type = true;
  399|      4|      features_.declare_float16_type = true;
  400|      4|      features_.free_fp_rounding_mode = true;
  401|      4|      break;
  402|      1|    case spv::Capability::VariablePointers:
  ------------------
  |  Branch (402:5): [True: 1, False: 15.2k]
  ------------------
  403|      2|    case spv::Capability::VariablePointersStorageBuffer:
  ------------------
  |  Branch (403:5): [True: 1, False: 15.2k]
  ------------------
  404|      2|      features_.variable_pointers = true;
  405|      2|      break;
  406|  15.0k|    default:
  ------------------
  |  Branch (406:5): [True: 15.0k, False: 192]
  ------------------
  407|       |      // TODO(dneto): For now don't validate SPV_NV_ray_tracing, which uses
  408|       |      // capability spv::Capability::RayTracingNV.
  409|       |      // spv::Capability::RayTracingProvisionalKHR would need the same
  410|       |      // treatment. One of the differences going from SPV_KHR_ray_tracing from
  411|       |      // provisional to final spec was the provisional spec uses Locations
  412|       |      // for variables in certain storage classes, just like the
  413|       |      // SPV_NV_ray_tracing extension.  So it mimics the NVIDIA extension.
  414|       |      // The final SPV_KHR_ray_tracing uses a different capability token
  415|       |      // number, so it doesn't fall into this case.
  416|  15.0k|      break;
  417|  15.2k|  }
  418|  15.2k|}
_ZN8spvtools3val17ValidationState_t17RegisterExtensionENS_9ExtensionE:
  420|  1.05k|void ValidationState_t::RegisterExtension(Extension ext) {
  421|  1.05k|  if (module_extensions_.Contains(ext)) return;
  ------------------
  |  Branch (421:7): [True: 865, False: 193]
  ------------------
  422|       |
  423|    193|  module_extensions_.Add(ext);
  424|       |
  425|    193|  switch (ext) {
  426|      1|    case kSPV_AMD_gpu_shader_half_float:
  ------------------
  |  Branch (426:5): [True: 1, False: 192]
  ------------------
  427|      1|    case kSPV_AMD_gpu_shader_half_float_fetch:
  ------------------
  |  Branch (427:5): [True: 0, False: 193]
  ------------------
  428|       |      // SPV_AMD_gpu_shader_half_float enables float16 type.
  429|       |      // https://github.com/KhronosGroup/SPIRV-Tools/issues/1375
  430|      1|      features_.declare_float16_type = true;
  431|      1|      break;
  432|      0|    case kSPV_AMD_gpu_shader_int16:
  ------------------
  |  Branch (432:5): [True: 0, False: 193]
  ------------------
  433|       |      // This is not yet in the extension, but it's recommended for it.
  434|       |      // See https://github.com/KhronosGroup/glslang/issues/848
  435|      0|      features_.uconvert_spec_constant_op = true;
  436|      0|      break;
  437|      0|    case kSPV_AMD_shader_ballot:
  ------------------
  |  Branch (437:5): [True: 0, False: 193]
  ------------------
  438|       |      // The grammar doesn't encode the fact that SPV_AMD_shader_ballot
  439|       |      // enables the use of group operations Reduce, InclusiveScan,
  440|       |      // and ExclusiveScan.  Enable it manually.
  441|       |      // https://github.com/KhronosGroup/SPIRV-Tools/issues/991
  442|      0|      features_.group_ops_reduce_and_scans = true;
  443|      0|      break;
  444|    192|    default:
  ------------------
  |  Branch (444:5): [True: 192, False: 1]
  ------------------
  445|    192|      break;
  446|    193|  }
  447|    193|}
_ZNK8spvtools3val17ValidationState_t20HasAnyOfCapabilitiesERKNS_7EnumSetIN3spv10CapabilityEEE:
  450|   447k|    const CapabilitySet& capabilities) const {
  451|   447k|  return module_capabilities_.HasAnyOf(capabilities);
  452|   447k|}
_ZNK8spvtools3val17ValidationState_t18HasAnyOfExtensionsERKNS_7EnumSetINS_9ExtensionEEE:
  455|    521|    const ExtensionSet& extensions) const {
  456|    521|  return module_extensions_.HasAnyOf(extensions);
  457|    521|}
_ZN8spvtools3val17ValidationState_t20set_addressing_modelEN3spv15AddressingModelE:
  459|  5.43k|void ValidationState_t::set_addressing_model(spv::AddressingModel am) {
  460|  5.43k|  addressing_model_ = am;
  461|  5.43k|  switch (am) {
  462|     41|    case spv::AddressingModel::Physical32:
  ------------------
  |  Branch (462:5): [True: 41, False: 5.39k]
  ------------------
  463|     41|      pointer_size_and_alignment_ = 4;
  464|     41|      break;
  465|  5.37k|    default:
  ------------------
  |  Branch (465:5): [True: 5.37k, False: 60]
  ------------------
  466|       |    // fall through
  467|  5.39k|    case spv::AddressingModel::Physical64:
  ------------------
  |  Branch (467:5): [True: 19, False: 5.41k]
  ------------------
  468|  5.39k|    case spv::AddressingModel::PhysicalStorageBuffer64:
  ------------------
  |  Branch (468:5): [True: 0, False: 5.43k]
  ------------------
  469|  5.39k|      pointer_size_and_alignment_ = 8;
  470|  5.39k|      break;
  471|  5.43k|  }
  472|  5.43k|}
_ZNK8spvtools3val17ValidationState_t16addressing_modelEv:
  474|  58.8k|spv::AddressingModel ValidationState_t::addressing_model() const {
  475|  58.8k|  return addressing_model_;
  476|  58.8k|}
_ZN8spvtools3val17ValidationState_t16set_memory_modelEN3spv11MemoryModelE:
  478|  5.43k|void ValidationState_t::set_memory_model(spv::MemoryModel mm) {
  479|  5.43k|  memory_model_ = mm;
  480|  5.43k|}
_ZNK8spvtools3val17ValidationState_t12memory_modelEv:
  482|  4.77k|spv::MemoryModel ValidationState_t::memory_model() const {
  483|  4.77k|  return memory_model_;
  484|  4.77k|}
_ZN8spvtools3val17ValidationState_t16RegisterFunctionEjjN3spv19FunctionControlMaskEj:
  497|  4.78k|    spv::FunctionControlMask function_control, uint32_t function_type_id) {
  498|  4.78k|  assert(in_function_body() == false &&
  499|  4.78k|         "RegisterFunction can only be called when parsing the binary outside "
  500|  4.78k|         "of another function");
  501|      0|  in_function_ = true;
  502|  4.78k|  module_functions_.emplace_back(id, ret_type_id, function_control,
  503|  4.78k|                                 function_type_id);
  504|  4.78k|  id_to_function_.emplace(id, &current_function());
  505|       |
  506|       |  // TODO(umar): validate function type and type_id
  507|       |
  508|  4.78k|  return SPV_SUCCESS;
  509|  4.78k|}
_ZN8spvtools3val17ValidationState_t19RegisterFunctionEndEv:
  511|  3.89k|spv_result_t ValidationState_t::RegisterFunctionEnd() {
  512|  3.89k|  assert(in_function_body() == true &&
  513|  3.89k|         "RegisterFunctionEnd can only be called when parsing the binary "
  514|  3.89k|         "inside of another function");
  515|      0|  assert(in_block() == false &&
  516|  3.89k|         "RegisterFunctionParameter can only be called when parsing the binary "
  517|  3.89k|         "outside of a block");
  518|      0|  current_function().RegisterFunctionEnd();
  519|  3.89k|  in_function_ = false;
  520|  3.89k|  return SPV_SUCCESS;
  521|  3.89k|}
_ZN8spvtools3val17ValidationState_t21AddOrderedInstructionEPK24spv_parsed_instruction_t:
  524|   499k|    const spv_parsed_instruction_t* inst) {
  525|   499k|  ordered_instructions_.emplace_back(inst);
  526|   499k|  ordered_instructions_.back().SetLineNum(ordered_instructions_.size());
  527|   499k|  return &ordered_instructions_.back();
  528|   499k|}
_ZN8spvtools3val17ValidationState_t24RegisterDebugInstructionEPKNS0_11InstructionE:
  531|   499k|void ValidationState_t::RegisterDebugInstruction(const Instruction* inst) {
  532|   499k|  switch (inst->opcode()) {
  533|  3.02k|    case spv::Op::OpName: {
  ------------------
  |  Branch (533:5): [True: 3.02k, False: 496k]
  ------------------
  534|  3.02k|      const auto target = inst->GetOperandAs<uint32_t>(0);
  535|  3.02k|      const std::string str = inst->GetOperandAs<std::string>(1);
  536|  3.02k|      AssignNameToId(target, str);
  537|  3.02k|      break;
  538|      0|    }
  539|    335|    case spv::Op::OpMemberName: {
  ------------------
  |  Branch (539:5): [True: 335, False: 499k]
  ------------------
  540|    335|      const auto target = inst->GetOperandAs<uint32_t>(0);
  541|    335|      const std::string str = inst->GetOperandAs<std::string>(2);
  542|    335|      AssignNameToId(target, str);
  543|    335|      break;
  544|      0|    }
  545|      8|    case spv::Op::OpSourceContinued:
  ------------------
  |  Branch (545:5): [True: 8, False: 499k]
  ------------------
  546|    724|    case spv::Op::OpSource:
  ------------------
  |  Branch (546:5): [True: 716, False: 499k]
  ------------------
  547|    982|    case spv::Op::OpSourceExtension:
  ------------------
  |  Branch (547:5): [True: 258, False: 499k]
  ------------------
  548|  1.00k|    case spv::Op::OpString:
  ------------------
  |  Branch (548:5): [True: 20, False: 499k]
  ------------------
  549|  1.31k|    case spv::Op::OpLine:
  ------------------
  |  Branch (549:5): [True: 310, False: 499k]
  ------------------
  550|  18.1k|    case spv::Op::OpNoLine:
  ------------------
  |  Branch (550:5): [True: 16.8k, False: 482k]
  ------------------
  551|   496k|    default:
  ------------------
  |  Branch (551:5): [True: 478k, False: 21.5k]
  ------------------
  552|   496k|      break;
  553|   499k|  }
  554|   499k|}
_ZN8spvtools3val17ValidationState_t19RegisterInstructionEPNS0_11InstructionE:
  556|   387k|void ValidationState_t::RegisterInstruction(Instruction* inst) {
  557|   387k|  if (inst->id()) all_definitions_.insert(std::make_pair(inst->id(), inst));
  ------------------
  |  Branch (557:7): [True: 195k, False: 191k]
  ------------------
  558|       |
  559|       |  // Some validation checks are easier by getting all the consumers
  560|  1.34M|  for (size_t i = 0; i < inst->operands().size(); ++i) {
  ------------------
  |  Branch (560:22): [True: 959k, False: 387k]
  ------------------
  561|   959k|    const spv_parsed_operand_t& operand = inst->operand(i);
  562|   959k|    if ((SPV_OPERAND_TYPE_ID == operand.type) ||
  ------------------
  |  Branch (562:9): [True: 470k, False: 489k]
  ------------------
  563|   959k|        (SPV_OPERAND_TYPE_TYPE_ID == operand.type)) {
  ------------------
  |  Branch (563:9): [True: 115k, False: 374k]
  ------------------
  564|   585k|      const uint32_t operand_word = inst->word(operand.offset);
  565|   585k|      Instruction* operand_inst = FindDef(operand_word);
  566|   585k|      if (!operand_inst) {
  ------------------
  |  Branch (566:11): [True: 155k, False: 429k]
  ------------------
  567|   155k|        continue;
  568|   155k|      }
  569|       |
  570|       |      // If the instruction is using an OpTypeSampledImage as an operand, it
  571|       |      // should be recorded. The validator will ensure that all usages of an
  572|       |      // OpTypeSampledImage and its definition are in the same basic block.
  573|   429k|      if ((SPV_OPERAND_TYPE_ID == operand.type) &&
  ------------------
  |  Branch (573:11): [True: 314k, False: 115k]
  ------------------
  574|   429k|          (spv::Op::OpSampledImage == operand_inst->opcode())) {
  ------------------
  |  Branch (574:11): [True: 149, False: 314k]
  ------------------
  575|    149|        RegisterSampledImageConsumer(operand_word, inst);
  576|    149|      }
  577|       |
  578|       |      // In order to track storage classes (not Function) used per execution
  579|       |      // model we can't use RegisterExecutionModelLimitation on instructions
  580|       |      // like OpTypePointer which are going to be in the pre-function section.
  581|       |      // Instead just need to register storage class usage for consumers in a
  582|       |      // function block.
  583|   429k|      if (inst->function()) {
  ------------------
  |  Branch (583:11): [True: 359k, False: 69.7k]
  ------------------
  584|   359k|        if (operand_inst->opcode() == spv::Op::OpTypePointer) {
  ------------------
  |  Branch (584:13): [True: 20.2k, False: 339k]
  ------------------
  585|  20.2k|          RegisterStorageClassConsumer(
  586|  20.2k|              operand_inst->GetOperandAs<spv::StorageClass>(1), inst);
  587|   339k|        } else if (operand_inst->opcode() == spv::Op::OpVariable) {
  ------------------
  |  Branch (587:20): [True: 62.7k, False: 276k]
  ------------------
  588|  62.7k|          RegisterStorageClassConsumer(
  589|  62.7k|              operand_inst->GetOperandAs<spv::StorageClass>(2), inst);
  590|  62.7k|        }
  591|   359k|      }
  592|   429k|    }
  593|   959k|  }
  594|   387k|}
_ZNK8spvtools3val17ValidationState_t24getSampledImageConsumersEj:
  597|     34|    uint32_t sampled_image_id) const {
  598|     34|  std::vector<Instruction*> result;
  599|     34|  auto iter = sampled_image_consumers_.find(sampled_image_id);
  600|     34|  if (iter != sampled_image_consumers_.end()) {
  ------------------
  |  Branch (600:7): [True: 21, False: 13]
  ------------------
  601|     21|    result = iter->second;
  602|     21|  }
  603|     34|  return result;
  604|     34|}
_ZN8spvtools3val17ValidationState_t28RegisterSampledImageConsumerEjPNS0_11InstructionE:
  607|    149|                                                     Instruction* consumer) {
  608|    149|  sampled_image_consumers_[sampled_image_id].push_back(consumer);
  609|    149|}
_ZN8spvtools3val17ValidationState_t28RegisterStorageClassConsumerEN3spv12StorageClassEPNS0_11InstructionE:
  612|  83.0k|    spv::StorageClass storage_class, Instruction* consumer) {
  613|  83.0k|  if (spvIsVulkanEnv(context()->target_env)) {
  ------------------
  |  Branch (613:7): [True: 0, False: 83.0k]
  ------------------
  614|      0|    if (storage_class == spv::StorageClass::Output) {
  ------------------
  |  Branch (614:9): [True: 0, False: 0]
  ------------------
  615|      0|      std::string errorVUID = VkErrorID(4644);
  616|      0|      function(consumer->function()->id())
  617|      0|          ->RegisterExecutionModelLimitation([errorVUID](
  618|      0|                                                 spv::ExecutionModel model,
  619|      0|                                                 std::string* message) {
  620|      0|            if (model == spv::ExecutionModel::GLCompute ||
  621|      0|                model == spv::ExecutionModel::RayGenerationKHR ||
  622|      0|                model == spv::ExecutionModel::IntersectionKHR ||
  623|      0|                model == spv::ExecutionModel::AnyHitKHR ||
  624|      0|                model == spv::ExecutionModel::ClosestHitKHR ||
  625|      0|                model == spv::ExecutionModel::MissKHR ||
  626|      0|                model == spv::ExecutionModel::CallableKHR) {
  627|      0|              if (message) {
  628|      0|                *message =
  629|      0|                    errorVUID +
  630|      0|                    "in Vulkan environment, Output Storage Class must not be "
  631|      0|                    "used in GLCompute, RayGenerationKHR, IntersectionKHR, "
  632|      0|                    "AnyHitKHR, ClosestHitKHR, MissKHR, or CallableKHR "
  633|      0|                    "execution models";
  634|      0|              }
  635|      0|              return false;
  636|      0|            }
  637|      0|            return true;
  638|      0|          });
  639|      0|    }
  640|       |
  641|      0|    if (storage_class == spv::StorageClass::Workgroup) {
  ------------------
  |  Branch (641:9): [True: 0, False: 0]
  ------------------
  642|      0|      std::string errorVUID = VkErrorID(4645);
  643|      0|      function(consumer->function()->id())
  644|      0|          ->RegisterExecutionModelLimitation([errorVUID](
  645|      0|                                                 spv::ExecutionModel model,
  646|      0|                                                 std::string* message) {
  647|      0|            if (model != spv::ExecutionModel::GLCompute &&
  648|      0|                model != spv::ExecutionModel::TaskNV &&
  649|      0|                model != spv::ExecutionModel::MeshNV &&
  650|      0|                model != spv::ExecutionModel::TaskEXT &&
  651|      0|                model != spv::ExecutionModel::MeshEXT) {
  652|      0|              if (message) {
  653|      0|                *message =
  654|      0|                    errorVUID +
  655|      0|                    "in Vulkan environment, Workgroup Storage Class is limited "
  656|      0|                    "to MeshNV, TaskNV, and GLCompute execution model";
  657|      0|              }
  658|      0|              return false;
  659|      0|            }
  660|      0|            return true;
  661|      0|          });
  662|      0|    }
  663|      0|  }
  664|       |
  665|  83.0k|  if (storage_class == spv::StorageClass::CallableDataKHR) {
  ------------------
  |  Branch (665:7): [True: 0, False: 83.0k]
  ------------------
  666|      0|    std::string errorVUID = VkErrorID(4704);
  667|      0|    function(consumer->function()->id())
  668|      0|        ->RegisterExecutionModelLimitation([errorVUID](
  669|      0|                                               spv::ExecutionModel model,
  670|      0|                                               std::string* message) {
  671|      0|          if (model != spv::ExecutionModel::RayGenerationKHR &&
  672|      0|              model != spv::ExecutionModel::ClosestHitKHR &&
  673|      0|              model != spv::ExecutionModel::CallableKHR &&
  674|      0|              model != spv::ExecutionModel::MissKHR) {
  675|      0|            if (message) {
  676|      0|              *message = errorVUID +
  677|      0|                         "CallableDataKHR Storage Class is limited to "
  678|      0|                         "RayGenerationKHR, ClosestHitKHR, CallableKHR, and "
  679|      0|                         "MissKHR execution model";
  680|      0|            }
  681|      0|            return false;
  682|      0|          }
  683|      0|          return true;
  684|      0|        });
  685|  83.0k|  } else if (storage_class == spv::StorageClass::IncomingCallableDataKHR) {
  ------------------
  |  Branch (685:14): [True: 0, False: 83.0k]
  ------------------
  686|      0|    std::string errorVUID = VkErrorID(4705);
  687|      0|    function(consumer->function()->id())
  688|      0|        ->RegisterExecutionModelLimitation([errorVUID](
  689|      0|                                               spv::ExecutionModel model,
  690|      0|                                               std::string* message) {
  691|      0|          if (model != spv::ExecutionModel::CallableKHR) {
  692|      0|            if (message) {
  693|      0|              *message = errorVUID +
  694|      0|                         "IncomingCallableDataKHR Storage Class is limited to "
  695|      0|                         "CallableKHR execution model";
  696|      0|            }
  697|      0|            return false;
  698|      0|          }
  699|      0|          return true;
  700|      0|        });
  701|  83.0k|  } else if (storage_class == spv::StorageClass::RayPayloadKHR) {
  ------------------
  |  Branch (701:14): [True: 0, False: 83.0k]
  ------------------
  702|      0|    std::string errorVUID = VkErrorID(4698);
  703|      0|    function(consumer->function()->id())
  704|      0|        ->RegisterExecutionModelLimitation([errorVUID](
  705|      0|                                               spv::ExecutionModel model,
  706|      0|                                               std::string* message) {
  707|      0|          if (model != spv::ExecutionModel::RayGenerationKHR &&
  708|      0|              model != spv::ExecutionModel::ClosestHitKHR &&
  709|      0|              model != spv::ExecutionModel::MissKHR) {
  710|      0|            if (message) {
  711|      0|              *message =
  712|      0|                  errorVUID +
  713|      0|                  "RayPayloadKHR Storage Class is limited to RayGenerationKHR, "
  714|      0|                  "ClosestHitKHR, and MissKHR execution model";
  715|      0|            }
  716|      0|            return false;
  717|      0|          }
  718|      0|          return true;
  719|      0|        });
  720|  83.0k|  } else if (storage_class == spv::StorageClass::HitAttributeKHR) {
  ------------------
  |  Branch (720:14): [True: 0, False: 83.0k]
  ------------------
  721|      0|    std::string errorVUID = VkErrorID(4701);
  722|      0|    function(consumer->function()->id())
  723|      0|        ->RegisterExecutionModelLimitation(
  724|      0|            [errorVUID](spv::ExecutionModel model, std::string* message) {
  725|      0|              if (model != spv::ExecutionModel::IntersectionKHR &&
  726|      0|                  model != spv::ExecutionModel::AnyHitKHR &&
  727|      0|                  model != spv::ExecutionModel::ClosestHitKHR) {
  728|      0|                if (message) {
  729|      0|                  *message = errorVUID +
  730|      0|                             "HitAttributeKHR Storage Class is limited to "
  731|      0|                             "IntersectionKHR, AnyHitKHR, sand ClosestHitKHR "
  732|      0|                             "execution model";
  733|      0|                }
  734|      0|                return false;
  735|      0|              }
  736|      0|              return true;
  737|      0|            });
  738|  83.0k|  } else if (storage_class == spv::StorageClass::IncomingRayPayloadKHR) {
  ------------------
  |  Branch (738:14): [True: 0, False: 83.0k]
  ------------------
  739|      0|    std::string errorVUID = VkErrorID(4699);
  740|      0|    function(consumer->function()->id())
  741|      0|        ->RegisterExecutionModelLimitation(
  742|      0|            [errorVUID](spv::ExecutionModel model, std::string* message) {
  743|      0|              if (model != spv::ExecutionModel::AnyHitKHR &&
  744|      0|                  model != spv::ExecutionModel::ClosestHitKHR &&
  745|      0|                  model != spv::ExecutionModel::MissKHR) {
  746|      0|                if (message) {
  747|      0|                  *message =
  748|      0|                      errorVUID +
  749|      0|                      "IncomingRayPayloadKHR Storage Class is limited to "
  750|      0|                      "AnyHitKHR, ClosestHitKHR, and MissKHR execution model";
  751|      0|                }
  752|      0|                return false;
  753|      0|              }
  754|      0|              return true;
  755|      0|            });
  756|  83.0k|  } else if (storage_class == spv::StorageClass::ShaderRecordBufferKHR) {
  ------------------
  |  Branch (756:14): [True: 0, False: 83.0k]
  ------------------
  757|      0|    std::string errorVUID = VkErrorID(7119);
  758|      0|    function(consumer->function()->id())
  759|      0|        ->RegisterExecutionModelLimitation(
  760|      0|            [errorVUID](spv::ExecutionModel model, std::string* message) {
  761|      0|              if (model != spv::ExecutionModel::RayGenerationKHR &&
  762|      0|                  model != spv::ExecutionModel::IntersectionKHR &&
  763|      0|                  model != spv::ExecutionModel::AnyHitKHR &&
  764|      0|                  model != spv::ExecutionModel::ClosestHitKHR &&
  765|      0|                  model != spv::ExecutionModel::CallableKHR &&
  766|      0|                  model != spv::ExecutionModel::MissKHR) {
  767|      0|                if (message) {
  768|      0|                  *message =
  769|      0|                      errorVUID +
  770|      0|                      "ShaderRecordBufferKHR Storage Class is limited to "
  771|      0|                      "RayGenerationKHR, IntersectionKHR, AnyHitKHR, "
  772|      0|                      "ClosestHitKHR, CallableKHR, and MissKHR execution model";
  773|      0|                }
  774|      0|                return false;
  775|      0|              }
  776|      0|              return true;
  777|      0|            });
  778|  83.0k|  } else if (storage_class == spv::StorageClass::TaskPayloadWorkgroupEXT) {
  ------------------
  |  Branch (778:14): [True: 0, False: 83.0k]
  ------------------
  779|      0|    function(consumer->function()->id())
  780|      0|        ->RegisterExecutionModelLimitation(
  781|      0|            [](spv::ExecutionModel model, std::string* message) {
  782|      0|              if (model != spv::ExecutionModel::TaskEXT &&
  783|      0|                  model != spv::ExecutionModel::MeshEXT) {
  784|      0|                if (message) {
  785|      0|                  *message =
  786|      0|                      "TaskPayloadWorkgroupEXT Storage Class is limited to "
  787|      0|                      "TaskEXT and MeshKHR execution model";
  788|      0|                }
  789|      0|                return false;
  790|      0|              }
  791|      0|              return true;
  792|      0|            });
  793|  83.0k|  } else if (storage_class == spv::StorageClass::HitObjectAttributeNV) {
  ------------------
  |  Branch (793:14): [True: 0, False: 83.0k]
  ------------------
  794|      0|    function(consumer->function()->id())
  795|      0|        ->RegisterExecutionModelLimitation([](spv::ExecutionModel model,
  796|      0|                                              std::string* message) {
  797|      0|          if (model != spv::ExecutionModel::RayGenerationKHR &&
  798|      0|              model != spv::ExecutionModel::ClosestHitKHR &&
  799|      0|              model != spv::ExecutionModel::MissKHR) {
  800|      0|            if (message) {
  801|      0|              *message =
  802|      0|                  "HitObjectAttributeNV Storage Class is limited to "
  803|      0|                  "RayGenerationKHR, ClosestHitKHR or MissKHR execution model";
  804|      0|            }
  805|      0|            return false;
  806|      0|          }
  807|      0|          return true;
  808|      0|        });
  809|      0|  }
  810|  83.0k|}
_ZNK8spvtools3val17ValidationState_t10getIdBoundEv:
  812|   387k|uint32_t ValidationState_t::getIdBound() const { return id_bound_; }
_ZN8spvtools3val17ValidationState_t10setIdBoundEj:
  814|  8.11k|void ValidationState_t::setIdBound(const uint32_t bound) { id_bound_ = bound; }
_ZN8spvtools3val17ValidationState_t29RegisterUniqueTypeDeclarationEPKNS0_11InstructionE:
  816|  12.9k|bool ValidationState_t::RegisterUniqueTypeDeclaration(const Instruction* inst) {
  817|  12.9k|  std::vector<uint32_t> key;
  818|  12.9k|  key.push_back(static_cast<uint32_t>(inst->opcode()));
  819|  42.4k|  for (size_t index = 0; index < inst->operands().size(); ++index) {
  ------------------
  |  Branch (819:26): [True: 29.5k, False: 12.9k]
  ------------------
  820|  29.5k|    const spv_parsed_operand_t& operand = inst->operand(index);
  821|       |
  822|  29.5k|    if (operand.type == SPV_OPERAND_TYPE_RESULT_ID) continue;
  ------------------
  |  Branch (822:9): [True: 12.9k, False: 16.6k]
  ------------------
  823|       |
  824|  16.6k|    const int words_begin = operand.offset;
  825|  16.6k|    const int words_end = words_begin + operand.num_words;
  826|  16.6k|    assert(words_end <= static_cast<int>(inst->words().size()));
  827|       |
  828|      0|    key.insert(key.end(), inst->words().begin() + words_begin,
  829|  16.6k|               inst->words().begin() + words_end);
  830|  16.6k|  }
  831|       |
  832|  12.9k|  return unique_type_declarations_.insert(std::move(key)).second;
  833|  12.9k|}
_ZNK8spvtools3val17ValidationState_t9GetTypeIdEj:
  835|  70.0k|uint32_t ValidationState_t::GetTypeId(uint32_t id) const {
  836|  70.0k|  const Instruction* inst = FindDef(id);
  837|  70.0k|  return inst ? inst->type_id() : 0;
  ------------------
  |  Branch (837:10): [True: 70.0k, False: 0]
  ------------------
  838|  70.0k|}
_ZNK8spvtools3val17ValidationState_t11GetIdOpcodeEj:
  840|  20.9k|spv::Op ValidationState_t::GetIdOpcode(uint32_t id) const {
  841|  20.9k|  const Instruction* inst = FindDef(id);
  842|  20.9k|  return inst ? inst->opcode() : spv::Op::OpNop;
  ------------------
  |  Branch (842:10): [True: 20.9k, False: 0]
  ------------------
  843|  20.9k|}
_ZNK8spvtools3val17ValidationState_t16GetComponentTypeEj:
  845|  38.5k|uint32_t ValidationState_t::GetComponentType(uint32_t id) const {
  846|  38.5k|  const Instruction* inst = FindDef(id);
  847|  38.5k|  assert(inst);
  848|       |
  849|      0|  switch (inst->opcode()) {
  850|    604|    case spv::Op::OpTypeFloat:
  ------------------
  |  Branch (850:5): [True: 604, False: 37.9k]
  ------------------
  851|  33.6k|    case spv::Op::OpTypeInt:
  ------------------
  |  Branch (851:5): [True: 33.0k, False: 5.52k]
  ------------------
  852|  33.6k|    case spv::Op::OpTypeBool:
  ------------------
  |  Branch (852:5): [True: 0, False: 38.5k]
  ------------------
  853|  33.6k|      return id;
  854|       |
  855|  4.91k|    case spv::Op::OpTypeVector:
  ------------------
  |  Branch (855:5): [True: 4.91k, False: 33.6k]
  ------------------
  856|  4.91k|      return inst->word(2);
  857|       |
  858|      4|    case spv::Op::OpTypeMatrix:
  ------------------
  |  Branch (858:5): [True: 4, False: 38.5k]
  ------------------
  859|      4|      return GetComponentType(inst->word(2));
  860|       |
  861|      0|    case spv::Op::OpTypeCooperativeMatrixNV:
  ------------------
  |  Branch (861:5): [True: 0, False: 38.5k]
  ------------------
  862|      0|      return inst->word(2);
  863|       |
  864|      0|    default:
  ------------------
  |  Branch (864:5): [True: 0, False: 38.5k]
  ------------------
  865|      0|      break;
  866|  38.5k|  }
  867|       |
  868|      0|  if (inst->type_id()) return GetComponentType(inst->type_id());
  ------------------
  |  Branch (868:7): [True: 0, False: 0]
  ------------------
  869|       |
  870|      0|  assert(0);
  871|      0|  return 0;
  872|      0|}
_ZNK8spvtools3val17ValidationState_t12GetDimensionEj:
  874|  54.5k|uint32_t ValidationState_t::GetDimension(uint32_t id) const {
  875|  54.5k|  const Instruction* inst = FindDef(id);
  876|  54.5k|  assert(inst);
  877|       |
  878|      0|  switch (inst->opcode()) {
  879|  2.52k|    case spv::Op::OpTypeFloat:
  ------------------
  |  Branch (879:5): [True: 2.52k, False: 52.0k]
  ------------------
  880|  35.3k|    case spv::Op::OpTypeInt:
  ------------------
  |  Branch (880:5): [True: 32.7k, False: 21.7k]
  ------------------
  881|  52.8k|    case spv::Op::OpTypeBool:
  ------------------
  |  Branch (881:5): [True: 17.5k, False: 37.0k]
  ------------------
  882|  52.8k|      return 1;
  883|       |
  884|  1.71k|    case spv::Op::OpTypeVector:
  ------------------
  |  Branch (884:5): [True: 1.71k, False: 52.8k]
  ------------------
  885|  1.71k|    case spv::Op::OpTypeMatrix:
  ------------------
  |  Branch (885:5): [True: 0, False: 54.5k]
  ------------------
  886|  1.71k|      return inst->word(3);
  887|       |
  888|      0|    case spv::Op::OpTypeCooperativeMatrixNV:
  ------------------
  |  Branch (888:5): [True: 0, False: 54.5k]
  ------------------
  889|       |      // Actual dimension isn't known, return 0
  890|      0|      return 0;
  891|       |
  892|      0|    default:
  ------------------
  |  Branch (892:5): [True: 0, False: 54.5k]
  ------------------
  893|      0|      break;
  894|  54.5k|  }
  895|       |
  896|      0|  if (inst->type_id()) return GetDimension(inst->type_id());
  ------------------
  |  Branch (896:7): [True: 0, False: 0]
  ------------------
  897|       |
  898|      0|  assert(0);
  899|      0|  return 0;
  900|      0|}
_ZNK8spvtools3val17ValidationState_t11GetBitWidthEj:
  902|  33.9k|uint32_t ValidationState_t::GetBitWidth(uint32_t id) const {
  903|  33.9k|  const uint32_t component_type_id = GetComponentType(id);
  904|  33.9k|  const Instruction* inst = FindDef(component_type_id);
  905|  33.9k|  assert(inst);
  906|       |
  907|  33.9k|  if (inst->opcode() == spv::Op::OpTypeFloat ||
  ------------------
  |  Branch (907:7): [True: 801, False: 33.1k]
  ------------------
  908|  33.9k|      inst->opcode() == spv::Op::OpTypeInt)
  ------------------
  |  Branch (908:7): [True: 33.1k, False: 0]
  ------------------
  909|  33.9k|    return inst->word(2);
  910|       |
  911|      0|  if (inst->opcode() == spv::Op::OpTypeBool) return 1;
  ------------------
  |  Branch (911:7): [True: 0, False: 0]
  ------------------
  912|       |
  913|      0|  assert(0);
  914|      0|  return 0;
  915|      0|}
_ZNK8spvtools3val17ValidationState_t10IsVoidTypeEj:
  917|  7.23k|bool ValidationState_t::IsVoidType(uint32_t id) const {
  918|  7.23k|  const Instruction* inst = FindDef(id);
  919|  7.23k|  return inst && inst->opcode() == spv::Op::OpTypeVoid;
  ------------------
  |  Branch (919:10): [True: 7.23k, False: 0]
  |  Branch (919:18): [True: 1, False: 7.22k]
  ------------------
  920|  7.23k|}
_ZNK8spvtools3val17ValidationState_t17IsFloatScalarTypeEj:
  922|  9.37k|bool ValidationState_t::IsFloatScalarType(uint32_t id) const {
  923|  9.37k|  const Instruction* inst = FindDef(id);
  924|  9.37k|  return inst && inst->opcode() == spv::Op::OpTypeFloat;
  ------------------
  |  Branch (924:10): [True: 9.37k, False: 1]
  |  Branch (924:18): [True: 8.41k, False: 954]
  ------------------
  925|  9.37k|}
_ZNK8spvtools3val17ValidationState_t17IsFloatVectorTypeEj:
  927|  1.52k|bool ValidationState_t::IsFloatVectorType(uint32_t id) const {
  928|  1.52k|  const Instruction* inst = FindDef(id);
  929|  1.52k|  if (!inst) {
  ------------------
  |  Branch (929:7): [True: 2, False: 1.52k]
  ------------------
  930|      2|    return false;
  931|      2|  }
  932|       |
  933|  1.52k|  if (inst->opcode() == spv::Op::OpTypeVector) {
  ------------------
  |  Branch (933:7): [True: 1.49k, False: 27]
  ------------------
  934|  1.49k|    return IsFloatScalarType(GetComponentType(id));
  935|  1.49k|  }
  936|       |
  937|     27|  return false;
  938|  1.52k|}
_ZNK8spvtools3val17ValidationState_t25IsFloatScalarOrVectorTypeEj:
  940|  2.35k|bool ValidationState_t::IsFloatScalarOrVectorType(uint32_t id) const {
  941|  2.35k|  const Instruction* inst = FindDef(id);
  942|  2.35k|  if (!inst) {
  ------------------
  |  Branch (942:7): [True: 1, False: 2.34k]
  ------------------
  943|      1|    return false;
  944|      1|  }
  945|       |
  946|  2.34k|  if (inst->opcode() == spv::Op::OpTypeFloat) {
  ------------------
  |  Branch (946:7): [True: 1.26k, False: 1.08k]
  ------------------
  947|  1.26k|    return true;
  948|  1.26k|  }
  949|       |
  950|  1.08k|  if (inst->opcode() == spv::Op::OpTypeVector) {
  ------------------
  |  Branch (950:7): [True: 1.06k, False: 22]
  ------------------
  951|  1.06k|    return IsFloatScalarType(GetComponentType(id));
  952|  1.06k|  }
  953|       |
  954|     22|  return false;
  955|  1.08k|}
_ZNK8spvtools3val17ValidationState_t15IsIntScalarTypeEj:
  957|  37.8k|bool ValidationState_t::IsIntScalarType(uint32_t id) const {
  958|  37.8k|  const Instruction* inst = FindDef(id);
  959|  37.8k|  return inst && inst->opcode() == spv::Op::OpTypeInt;
  ------------------
  |  Branch (959:10): [True: 37.8k, False: 2]
  |  Branch (959:18): [True: 37.3k, False: 524]
  ------------------
  960|  37.8k|}
_ZNK8spvtools3val17ValidationState_t15IsIntVectorTypeEj:
  962|    274|bool ValidationState_t::IsIntVectorType(uint32_t id) const {
  963|    274|  const Instruction* inst = FindDef(id);
  964|    274|  if (!inst) {
  ------------------
  |  Branch (964:7): [True: 0, False: 274]
  ------------------
  965|      0|    return false;
  966|      0|  }
  967|       |
  968|    274|  if (inst->opcode() == spv::Op::OpTypeVector) {
  ------------------
  |  Branch (968:7): [True: 215, False: 59]
  ------------------
  969|    215|    return IsIntScalarType(GetComponentType(id));
  970|    215|  }
  971|       |
  972|     59|  return false;
  973|    274|}
_ZNK8spvtools3val17ValidationState_t23IsIntScalarOrVectorTypeEj:
  975|    678|bool ValidationState_t::IsIntScalarOrVectorType(uint32_t id) const {
  976|    678|  const Instruction* inst = FindDef(id);
  977|    678|  if (!inst) {
  ------------------
  |  Branch (977:7): [True: 2, False: 676]
  ------------------
  978|      2|    return false;
  979|      2|  }
  980|       |
  981|    676|  if (inst->opcode() == spv::Op::OpTypeInt) {
  ------------------
  |  Branch (981:7): [True: 649, False: 27]
  ------------------
  982|    649|    return true;
  983|    649|  }
  984|       |
  985|     27|  if (inst->opcode() == spv::Op::OpTypeVector) {
  ------------------
  |  Branch (985:7): [True: 10, False: 17]
  ------------------
  986|     10|    return IsIntScalarType(GetComponentType(id));
  987|     10|  }
  988|       |
  989|     17|  return false;
  990|     27|}
_ZNK8spvtools3val17ValidationState_t23IsUnsignedIntScalarTypeEj:
  992|     56|bool ValidationState_t::IsUnsignedIntScalarType(uint32_t id) const {
  993|     56|  const Instruction* inst = FindDef(id);
  994|     56|  return inst && inst->opcode() == spv::Op::OpTypeInt && inst->word(3) == 0;
  ------------------
  |  Branch (994:10): [True: 56, False: 0]
  |  Branch (994:18): [True: 29, False: 27]
  |  Branch (994:58): [True: 25, False: 4]
  ------------------
  995|     56|}
_ZNK8spvtools3val17ValidationState_t23IsUnsignedIntVectorTypeEj:
  997|     26|bool ValidationState_t::IsUnsignedIntVectorType(uint32_t id) const {
  998|     26|  const Instruction* inst = FindDef(id);
  999|     26|  if (!inst) {
  ------------------
  |  Branch (999:7): [True: 0, False: 26]
  ------------------
 1000|      0|    return false;
 1001|      0|  }
 1002|       |
 1003|     26|  if (inst->opcode() == spv::Op::OpTypeVector) {
  ------------------
  |  Branch (1003:7): [True: 13, False: 13]
  ------------------
 1004|     13|    return IsUnsignedIntScalarType(GetComponentType(id));
 1005|     13|  }
 1006|       |
 1007|     13|  return false;
 1008|     26|}
_ZNK8spvtools3val17ValidationState_t16IsBoolScalarTypeEj:
 1028|  19.2k|bool ValidationState_t::IsBoolScalarType(uint32_t id) const {
 1029|  19.2k|  const Instruction* inst = FindDef(id);
 1030|  19.2k|  return inst && inst->opcode() == spv::Op::OpTypeBool;
  ------------------
  |  Branch (1030:10): [True: 19.2k, False: 0]
  |  Branch (1030:18): [True: 19.2k, False: 31]
  ------------------
 1031|  19.2k|}
_ZNK8spvtools3val17ValidationState_t16IsBoolVectorTypeEj:
 1033|     23|bool ValidationState_t::IsBoolVectorType(uint32_t id) const {
 1034|     23|  const Instruction* inst = FindDef(id);
 1035|     23|  if (!inst) {
  ------------------
  |  Branch (1035:7): [True: 0, False: 23]
  ------------------
 1036|      0|    return false;
 1037|      0|  }
 1038|       |
 1039|     23|  if (inst->opcode() == spv::Op::OpTypeVector) {
  ------------------
  |  Branch (1039:7): [True: 8, False: 15]
  ------------------
 1040|      8|    return IsBoolScalarType(GetComponentType(id));
 1041|      8|  }
 1042|       |
 1043|     15|  return false;
 1044|     23|}
_ZNK8spvtools3val17ValidationState_t17IsFloatMatrixTypeEj:
 1063|      5|bool ValidationState_t::IsFloatMatrixType(uint32_t id) const {
 1064|      5|  const Instruction* inst = FindDef(id);
 1065|      5|  if (!inst) {
  ------------------
  |  Branch (1065:7): [True: 0, False: 5]
  ------------------
 1066|      0|    return false;
 1067|      0|  }
 1068|       |
 1069|      5|  if (inst->opcode() == spv::Op::OpTypeMatrix) {
  ------------------
  |  Branch (1069:7): [True: 2, False: 3]
  ------------------
 1070|      2|    return IsFloatScalarType(GetComponentType(id));
 1071|      2|  }
 1072|       |
 1073|      3|  return false;
 1074|      5|}
_ZNK8spvtools3val17ValidationState_t17GetMatrixTypeInfoEjPjS2_S2_S2_:
 1079|    191|                                          uint32_t* component_type) const {
 1080|    191|  if (!id) return false;
  ------------------
  |  Branch (1080:7): [True: 2, False: 189]
  ------------------
 1081|       |
 1082|    189|  const Instruction* mat_inst = FindDef(id);
 1083|    189|  assert(mat_inst);
 1084|    189|  if (mat_inst->opcode() != spv::Op::OpTypeMatrix) return false;
  ------------------
  |  Branch (1084:7): [True: 12, False: 177]
  ------------------
 1085|       |
 1086|    177|  const uint32_t vec_type = mat_inst->word(2);
 1087|    177|  const Instruction* vec_inst = FindDef(vec_type);
 1088|    177|  assert(vec_inst);
 1089|       |
 1090|    177|  if (vec_inst->opcode() != spv::Op::OpTypeVector) {
  ------------------
  |  Branch (1090:7): [True: 0, False: 177]
  ------------------
 1091|      0|    assert(0);
 1092|      0|    return false;
 1093|      0|  }
 1094|       |
 1095|    177|  *num_cols = mat_inst->word(3);
 1096|    177|  *num_rows = vec_inst->word(3);
 1097|    177|  *column_type = mat_inst->word(2);
 1098|    177|  *component_type = vec_inst->word(2);
 1099|       |
 1100|    177|  return true;
 1101|    177|}
_ZNK8spvtools3val17ValidationState_t20GetStructMemberTypesEjPNSt3__16vectorIjNS2_9allocatorIjEEEE:
 1104|     31|    uint32_t struct_type_id, std::vector<uint32_t>* member_types) const {
 1105|     31|  member_types->clear();
 1106|     31|  if (!struct_type_id) return false;
  ------------------
  |  Branch (1106:7): [True: 0, False: 31]
  ------------------
 1107|       |
 1108|     31|  const Instruction* inst = FindDef(struct_type_id);
 1109|     31|  assert(inst);
 1110|     31|  if (inst->opcode() != spv::Op::OpTypeStruct) return false;
  ------------------
  |  Branch (1110:7): [True: 12, False: 19]
  ------------------
 1111|       |
 1112|     19|  *member_types =
 1113|     19|      std::vector<uint32_t>(inst->words().cbegin() + 2, inst->words().cend());
 1114|       |
 1115|     19|  if (member_types->empty()) return false;
  ------------------
  |  Branch (1115:7): [True: 1, False: 18]
  ------------------
 1116|       |
 1117|     18|  return true;
 1118|     19|}
_ZNK8spvtools3val17ValidationState_t13IsPointerTypeEj:
 1120|  23.7k|bool ValidationState_t::IsPointerType(uint32_t id) const {
 1121|  23.7k|  const Instruction* inst = FindDef(id);
 1122|  23.7k|  return inst && inst->opcode() == spv::Op::OpTypePointer;
  ------------------
  |  Branch (1122:10): [True: 23.7k, False: 0]
  |  Branch (1122:18): [True: 163, False: 23.5k]
  ------------------
 1123|  23.7k|}
_ZNK8spvtools3val17ValidationState_t18GetPointerTypeInfoEjPjPN3spv12StorageClassE:
 1126|  50.7k|    uint32_t id, uint32_t* data_type, spv::StorageClass* storage_class) const {
 1127|  50.7k|  *storage_class = spv::StorageClass::Max;
 1128|  50.7k|  if (!id) return false;
  ------------------
  |  Branch (1128:7): [True: 2, False: 50.7k]
  ------------------
 1129|       |
 1130|  50.7k|  const Instruction* inst = FindDef(id);
 1131|  50.7k|  assert(inst);
 1132|  50.7k|  if (inst->opcode() != spv::Op::OpTypePointer) return false;
  ------------------
  |  Branch (1132:7): [True: 3, False: 50.7k]
  ------------------
 1133|       |
 1134|  50.7k|  *storage_class = spv::StorageClass(inst->word(2));
 1135|  50.7k|  *data_type = inst->word(3);
 1136|  50.7k|  return true;
 1137|  50.7k|}
_ZNK8spvtools3val17ValidationState_t23IsCooperativeMatrixTypeEj:
 1144|  3.15k|bool ValidationState_t::IsCooperativeMatrixType(uint32_t id) const {
 1145|  3.15k|  const Instruction* inst = FindDef(id);
 1146|  3.15k|  return inst && inst->opcode() == spv::Op::OpTypeCooperativeMatrixNV;
  ------------------
  |  Branch (1146:10): [True: 3.15k, False: 0]
  |  Branch (1146:18): [True: 0, False: 3.15k]
  ------------------
 1147|  3.15k|}
_ZNK8spvtools3val17ValidationState_t28IsFloatCooperativeMatrixTypeEj:
 1149|      5|bool ValidationState_t::IsFloatCooperativeMatrixType(uint32_t id) const {
 1150|      5|  if (!IsCooperativeMatrixType(id)) return false;
  ------------------
  |  Branch (1150:7): [True: 5, False: 0]
  ------------------
 1151|      0|  return IsFloatScalarType(FindDef(id)->word(2));
 1152|      5|}
_ZNK8spvtools3val17ValidationState_t26IsIntCooperativeMatrixTypeEj:
 1154|     16|bool ValidationState_t::IsIntCooperativeMatrixType(uint32_t id) const {
 1155|     16|  if (!IsCooperativeMatrixType(id)) return false;
  ------------------
  |  Branch (1155:7): [True: 16, False: 0]
  ------------------
 1156|      0|  return IsIntScalarType(FindDef(id)->word(2));
 1157|     16|}
_ZNK8spvtools3val17ValidationState_t34IsUnsignedIntCooperativeMatrixTypeEj:
 1159|     14|bool ValidationState_t::IsUnsignedIntCooperativeMatrixType(uint32_t id) const {
 1160|     14|  if (!IsCooperativeMatrixType(id)) return false;
  ------------------
  |  Branch (1160:7): [True: 14, False: 0]
  ------------------
 1161|      0|  return IsUnsignedIntScalarType(FindDef(id)->word(2));
 1162|     14|}
_ZNK8spvtools3val17ValidationState_t16GetOperandTypeIdEPKNS0_11InstructionEm:
 1231|  52.8k|                                             size_t operand_index) const {
 1232|  52.8k|  return GetTypeId(inst->GetOperandAs<uint32_t>(operand_index));
 1233|  52.8k|}
_ZNK8spvtools3val17ValidationState_t20GetConstantValUint64EjPm:
 1235|     35|bool ValidationState_t::GetConstantValUint64(uint32_t id, uint64_t* val) const {
 1236|     35|  const Instruction* inst = FindDef(id);
 1237|     35|  if (!inst) {
  ------------------
  |  Branch (1237:7): [True: 0, False: 35]
  ------------------
 1238|      0|    assert(0 && "Instruction not found");
 1239|      0|    return false;
 1240|      0|  }
 1241|       |
 1242|     35|  if (inst->opcode() != spv::Op::OpConstant &&
  ------------------
  |  Branch (1242:7): [True: 0, False: 35]
  ------------------
 1243|     35|      inst->opcode() != spv::Op::OpSpecConstant)
  ------------------
  |  Branch (1243:7): [True: 0, False: 0]
  ------------------
 1244|      0|    return false;
 1245|       |
 1246|     35|  if (!IsIntScalarType(inst->type_id())) return false;
  ------------------
  |  Branch (1246:7): [True: 0, False: 35]
  ------------------
 1247|       |
 1248|     35|  if (inst->words().size() == 4) {
  ------------------
  |  Branch (1248:7): [True: 35, False: 0]
  ------------------
 1249|     35|    *val = inst->word(3);
 1250|     35|  } else {
 1251|      0|    assert(inst->words().size() == 5);
 1252|      0|    *val = inst->word(3);
 1253|      0|    *val |= uint64_t(inst->word(4)) << 32;
 1254|      0|  }
 1255|      0|  return true;
 1256|     35|}
_ZNK8spvtools3val17ValidationState_t16EvalInt32IfConstEj:
 1259|  2.04k|    uint32_t id) const {
 1260|  2.04k|  const Instruction* const inst = FindDef(id);
 1261|  2.04k|  assert(inst);
 1262|      0|  const uint32_t type = inst->type_id();
 1263|       |
 1264|  2.04k|  if (type == 0 || !IsIntScalarType(type) || GetBitWidth(type) != 32) {
  ------------------
  |  Branch (1264:7): [True: 0, False: 2.04k]
  |  Branch (1264:20): [True: 3, False: 2.04k]
  |  Branch (1264:46): [True: 0, False: 2.04k]
  ------------------
 1265|      3|    return std::make_tuple(false, false, 0);
 1266|      3|  }
 1267|       |
 1268|       |  // Spec constant values cannot be evaluated so don't consider constant for
 1269|       |  // the purpose of this method.
 1270|  2.04k|  if (!spvOpcodeIsConstant(inst->opcode()) ||
  ------------------
  |  Branch (1270:7): [True: 0, False: 2.04k]
  ------------------
 1271|  2.04k|      spvOpcodeIsSpecConstant(inst->opcode())) {
  ------------------
  |  Branch (1271:7): [True: 103, False: 1.94k]
  ------------------
 1272|    103|    return std::make_tuple(true, false, 0);
 1273|    103|  }
 1274|       |
 1275|  1.94k|  if (inst->opcode() == spv::Op::OpConstantNull) {
  ------------------
  |  Branch (1275:7): [True: 4, False: 1.93k]
  ------------------
 1276|      4|    return std::make_tuple(true, true, 0);
 1277|      4|  }
 1278|       |
 1279|  1.93k|  assert(inst->words().size() == 4);
 1280|      0|  return std::make_tuple(true, true, inst->word(3));
 1281|  1.94k|}
_ZN8spvtools3val17ValidationState_t34ComputeFunctionToEntryPointMappingEv:
 1283|  2.41k|void ValidationState_t::ComputeFunctionToEntryPointMapping() {
 1284|  2.41k|  for (const uint32_t entry_point : entry_points()) {
  ------------------
  |  Branch (1284:35): [True: 1.49k, False: 2.41k]
  ------------------
 1285|  1.49k|    std::stack<uint32_t> call_stack;
 1286|  1.49k|    std::set<uint32_t> visited;
 1287|  1.49k|    call_stack.push(entry_point);
 1288|  3.17k|    while (!call_stack.empty()) {
  ------------------
  |  Branch (1288:12): [True: 1.68k, False: 1.49k]
  ------------------
 1289|  1.68k|      const uint32_t called_func_id = call_stack.top();
 1290|  1.68k|      call_stack.pop();
 1291|  1.68k|      if (!visited.insert(called_func_id).second) continue;
  ------------------
  |  Branch (1291:11): [True: 24, False: 1.66k]
  ------------------
 1292|       |
 1293|  1.66k|      function_to_entry_points_[called_func_id].push_back(entry_point);
 1294|       |
 1295|  1.66k|      const Function* called_func = function(called_func_id);
 1296|  1.66k|      if (called_func) {
  ------------------
  |  Branch (1296:11): [True: 1.66k, False: 0]
  ------------------
 1297|       |        // Other checks should error out on this invalid SPIR-V.
 1298|  1.66k|        for (const uint32_t new_call : called_func->function_call_targets()) {
  ------------------
  |  Branch (1298:38): [True: 191, False: 1.66k]
  ------------------
 1299|    191|          call_stack.push(new_call);
 1300|    191|        }
 1301|  1.66k|      }
 1302|  1.66k|    }
 1303|  1.49k|  }
 1304|  2.41k|}
_ZN8spvtools3val17ValidationState_t27ComputeRecursiveEntryPointsEv:
 1306|  2.41k|void ValidationState_t::ComputeRecursiveEntryPoints() {
 1307|  2.41k|  for (const Function& func : functions()) {
  ------------------
  |  Branch (1307:29): [True: 2.01k, False: 2.41k]
  ------------------
 1308|  2.01k|    std::stack<uint32_t> call_stack;
 1309|  2.01k|    std::set<uint32_t> visited;
 1310|       |
 1311|  2.01k|    for (const uint32_t new_call : func.function_call_targets()) {
  ------------------
  |  Branch (1311:34): [True: 231, False: 2.01k]
  ------------------
 1312|    231|      call_stack.push(new_call);
 1313|    231|    }
 1314|       |
 1315|  2.31k|    while (!call_stack.empty()) {
  ------------------
  |  Branch (1315:12): [True: 297, False: 2.01k]
  ------------------
 1316|    297|      const uint32_t called_func_id = call_stack.top();
 1317|    297|      call_stack.pop();
 1318|       |
 1319|    297|      if (!visited.insert(called_func_id).second) continue;
  ------------------
  |  Branch (1319:11): [True: 23, False: 274]
  ------------------
 1320|       |
 1321|    274|      if (called_func_id == func.id()) {
  ------------------
  |  Branch (1321:11): [True: 3, False: 271]
  ------------------
 1322|      3|        for (const uint32_t entry_point :
  ------------------
  |  Branch (1322:41): [True: 2, False: 3]
  ------------------
 1323|      3|             function_to_entry_points_[called_func_id])
 1324|      2|          recursive_entry_points_.insert(entry_point);
 1325|      3|        break;
 1326|      3|      }
 1327|       |
 1328|    271|      const Function* called_func = function(called_func_id);
 1329|    271|      if (called_func) {
  ------------------
  |  Branch (1329:11): [True: 271, False: 0]
  ------------------
 1330|       |        // Other checks should error out on this invalid SPIR-V.
 1331|    271|        for (const uint32_t new_call : called_func->function_call_targets()) {
  ------------------
  |  Branch (1331:38): [True: 66, False: 271]
  ------------------
 1332|     66|          call_stack.push(new_call);
 1333|     66|        }
 1334|    271|      }
 1335|    271|    }
 1336|  2.01k|  }
 1337|  2.41k|}
_ZNK8spvtools3val17ValidationState_t19FunctionEntryPointsEj:
 1340|    954|    uint32_t func) const {
 1341|    954|  auto iter = function_to_entry_points_.find(func);
 1342|    954|  if (iter == function_to_entry_points_.end()) {
  ------------------
  |  Branch (1342:7): [True: 287, False: 667]
  ------------------
 1343|    287|    return empty_ids_;
 1344|    667|  } else {
 1345|    667|    return iter->second;
 1346|    667|  }
 1347|    954|}
_ZNK8spvtools3val17ValidationState_t20EntryPointReferencesEj:
 1349|     12|std::set<uint32_t> ValidationState_t::EntryPointReferences(uint32_t id) const {
 1350|     12|  std::set<uint32_t> referenced_entry_points;
 1351|     12|  const auto inst = FindDef(id);
 1352|     12|  if (!inst) return referenced_entry_points;
  ------------------
  |  Branch (1352:7): [True: 0, False: 12]
  ------------------
 1353|       |
 1354|     12|  std::vector<const Instruction*> stack;
 1355|     12|  stack.push_back(inst);
 1356|     71|  while (!stack.empty()) {
  ------------------
  |  Branch (1356:10): [True: 59, False: 12]
  ------------------
 1357|     59|    const auto current_inst = stack.back();
 1358|     59|    stack.pop_back();
 1359|       |
 1360|     59|    if (const auto func = current_inst->function()) {
  ------------------
  |  Branch (1360:20): [True: 0, False: 59]
  ------------------
 1361|       |      // Instruction lives in a function, we can stop searching.
 1362|      0|      const auto function_entry_points = FunctionEntryPoints(func->id());
 1363|      0|      referenced_entry_points.insert(function_entry_points.begin(),
 1364|      0|                                     function_entry_points.end());
 1365|     59|    } else {
 1366|       |      // Instruction is in the global scope, keep searching its uses.
 1367|     59|      for (auto pair : current_inst->uses()) {
  ------------------
  |  Branch (1367:22): [True: 47, False: 59]
  ------------------
 1368|     47|        const auto next_inst = pair.first;
 1369|     47|        stack.push_back(next_inst);
 1370|     47|      }
 1371|     59|    }
 1372|     59|  }
 1373|       |
 1374|     12|  return referenced_entry_points;
 1375|     12|}
_ZNK8spvtools3val17ValidationState_t11DisassembleERKNS0_11InstructionE:
 1377|  4.45k|std::string ValidationState_t::Disassemble(const Instruction& inst) const {
 1378|  4.45k|  const spv_parsed_instruction_t& c_inst(inst.c_inst());
 1379|  4.45k|  return Disassemble(c_inst.words, c_inst.num_words);
 1380|  4.45k|}
_ZNK8spvtools3val17ValidationState_t11DisassembleEPKjt:
 1383|  4.45k|                                           uint16_t num_words) const {
 1384|  4.45k|  uint32_t disassembly_options = SPV_BINARY_TO_TEXT_OPTION_NO_HEADER |
 1385|  4.45k|                                 SPV_BINARY_TO_TEXT_OPTION_FRIENDLY_NAMES;
 1386|       |
 1387|  4.45k|  return spvInstructionBinaryToText(context()->target_env, words, num_words,
 1388|  4.45k|                                    words_, num_words_, disassembly_options);
 1389|  4.45k|}
_ZNK8spvtools3val17ValidationState_t12ContainsTypeEjRKNSt3__18functionIFbPKNS0_11InstructionEEEEb:
 1478|   402k|    bool traverse_all_types) const {
 1479|   402k|  const auto inst = FindDef(id);
 1480|   402k|  if (!inst) return false;
  ------------------
  |  Branch (1480:7): [True: 102k, False: 299k]
  ------------------
 1481|       |
 1482|   299k|  if (f(inst)) return true;
  ------------------
  |  Branch (1482:7): [True: 142, False: 299k]
  ------------------
 1483|       |
 1484|   299k|  switch (inst->opcode()) {
 1485|  3.83k|    case spv::Op::OpTypeArray:
  ------------------
  |  Branch (1485:5): [True: 3.83k, False: 295k]
  ------------------
 1486|  4.08k|    case spv::Op::OpTypeRuntimeArray:
  ------------------
  |  Branch (1486:5): [True: 253, False: 299k]
  ------------------
 1487|  35.6k|    case spv::Op::OpTypeVector:
  ------------------
  |  Branch (1487:5): [True: 31.5k, False: 268k]
  ------------------
 1488|  38.1k|    case spv::Op::OpTypeMatrix:
  ------------------
  |  Branch (1488:5): [True: 2.50k, False: 297k]
  ------------------
 1489|  38.8k|    case spv::Op::OpTypeImage:
  ------------------
  |  Branch (1489:5): [True: 691, False: 299k]
  ------------------
 1490|  39.3k|    case spv::Op::OpTypeSampledImage:
  ------------------
  |  Branch (1490:5): [True: 492, False: 299k]
  ------------------
 1491|  39.3k|    case spv::Op::OpTypeCooperativeMatrixNV:
  ------------------
  |  Branch (1491:5): [True: 0, False: 299k]
  ------------------
 1492|  39.3k|      return ContainsType(inst->GetOperandAs<uint32_t>(1u), f,
 1493|  39.3k|                          traverse_all_types);
 1494|  11.8k|    case spv::Op::OpTypePointer:
  ------------------
  |  Branch (1494:5): [True: 11.8k, False: 287k]
  ------------------
 1495|  11.8k|      if (IsForwardPointer(id)) return false;
  ------------------
  |  Branch (1495:11): [True: 0, False: 11.8k]
  ------------------
 1496|  11.8k|      if (traverse_all_types) {
  ------------------
  |  Branch (1496:11): [True: 11.8k, False: 0]
  ------------------
 1497|  11.8k|        return ContainsType(inst->GetOperandAs<uint32_t>(2u), f,
 1498|  11.8k|                            traverse_all_types);
 1499|  11.8k|      }
 1500|      0|      break;
 1501|      0|    case spv::Op::OpTypeFunction:
  ------------------
  |  Branch (1501:5): [True: 0, False: 299k]
  ------------------
 1502|  12.7k|    case spv::Op::OpTypeStruct:
  ------------------
  |  Branch (1502:5): [True: 12.7k, False: 287k]
  ------------------
 1503|  12.7k|      if (inst->opcode() == spv::Op::OpTypeFunction && !traverse_all_types) {
  ------------------
  |  Branch (1503:11): [True: 0, False: 12.7k]
  |  Branch (1503:56): [True: 0, False: 0]
  ------------------
 1504|      0|        return false;
 1505|      0|      }
 1506|  42.6k|      for (uint32_t i = 1; i < inst->operands().size(); ++i) {
  ------------------
  |  Branch (1506:28): [True: 29.8k, False: 12.7k]
  ------------------
 1507|  29.8k|        if (ContainsType(inst->GetOperandAs<uint32_t>(i), f,
  ------------------
  |  Branch (1507:13): [True: 0, False: 29.8k]
  ------------------
 1508|  29.8k|                         traverse_all_types)) {
 1509|      0|          return true;
 1510|      0|        }
 1511|  29.8k|      }
 1512|  12.7k|      break;
 1513|   235k|    default:
  ------------------
  |  Branch (1513:5): [True: 235k, False: 63.9k]
  ------------------
 1514|   235k|      break;
 1515|   299k|  }
 1516|       |
 1517|   248k|  return false;
 1518|   299k|}
_ZNK8spvtools3val17ValidationState_t27ContainsSizedIntOrFloatTypeEjN3spv2OpEj:
 1521|   304k|                                                    uint32_t width) const {
 1522|   304k|  if (type != spv::Op::OpTypeInt && type != spv::Op::OpTypeFloat) return false;
  ------------------
  |  Branch (1522:7): [True: 101k, False: 203k]
  |  Branch (1522:37): [True: 0, False: 101k]
  ------------------
 1523|       |
 1524|   304k|  const auto f = [type, width](const Instruction* inst) {
 1525|   304k|    if (inst->opcode() == type) {
 1526|   304k|      return inst->GetOperandAs<uint32_t>(1u) == width;
 1527|   304k|    }
 1528|   304k|    return false;
 1529|   304k|  };
 1530|   304k|  return ContainsType(id, f);
 1531|   304k|}
_ZNK8spvtools3val17ValidationState_t32ContainsLimitedUseIntOrFloatTypeEj:
 1533|  94.5k|bool ValidationState_t::ContainsLimitedUseIntOrFloatType(uint32_t id) const {
 1534|  94.5k|  if ((!HasCapability(spv::Capability::Int16) &&
  ------------------
  |  Branch (1534:8): [True: 94.4k, False: 42]
  ------------------
 1535|  94.5k|       ContainsSizedIntOrFloatType(id, spv::Op::OpTypeInt, 16)) ||
  ------------------
  |  Branch (1535:8): [True: 0, False: 94.4k]
  ------------------
 1536|  94.5k|      (!HasCapability(spv::Capability::Int8) &&
  ------------------
  |  Branch (1536:8): [True: 94.4k, False: 46]
  ------------------
 1537|  94.5k|       ContainsSizedIntOrFloatType(id, spv::Op::OpTypeInt, 8)) ||
  ------------------
  |  Branch (1537:8): [True: 0, False: 94.4k]
  ------------------
 1538|  94.5k|      (!HasCapability(spv::Capability::Float16) &&
  ------------------
  |  Branch (1538:8): [True: 94.5k, False: 33]
  ------------------
 1539|  94.5k|       ContainsSizedIntOrFloatType(id, spv::Op::OpTypeFloat, 16))) {
  ------------------
  |  Branch (1539:8): [True: 1, False: 94.4k]
  ------------------
 1540|      1|    return true;
 1541|      1|  }
 1542|  94.5k|  return false;
 1543|  94.5k|}
_ZNK8spvtools3val17ValidationState_t20ContainsRuntimeArrayEj:
 1545|  16.5k|bool ValidationState_t::ContainsRuntimeArray(uint32_t id) const {
 1546|  16.5k|  const auto f = [](const Instruction* inst) {
 1547|  16.5k|    return inst->opcode() == spv::Op::OpTypeRuntimeArray;
 1548|  16.5k|  };
 1549|  16.5k|  return ContainsType(id, f, /* traverse_all_types = */ false);
 1550|  16.5k|}
_ZNK8spvtools3val17ValidationState_t19IsValidStorageClassEN3spv12StorageClassE:
 1553|  12.6k|    spv::StorageClass storage_class) const {
 1554|  12.6k|  if (spvIsVulkanEnv(context()->target_env)) {
  ------------------
  |  Branch (1554:7): [True: 0, False: 12.6k]
  ------------------
 1555|      0|    switch (storage_class) {
 1556|      0|      case spv::StorageClass::UniformConstant:
  ------------------
  |  Branch (1556:7): [True: 0, False: 0]
  ------------------
 1557|      0|      case spv::StorageClass::Uniform:
  ------------------
  |  Branch (1557:7): [True: 0, False: 0]
  ------------------
 1558|      0|      case spv::StorageClass::StorageBuffer:
  ------------------
  |  Branch (1558:7): [True: 0, False: 0]
  ------------------
 1559|      0|      case spv::StorageClass::Input:
  ------------------
  |  Branch (1559:7): [True: 0, False: 0]
  ------------------
 1560|      0|      case spv::StorageClass::Output:
  ------------------
  |  Branch (1560:7): [True: 0, False: 0]
  ------------------
 1561|      0|      case spv::StorageClass::Image:
  ------------------
  |  Branch (1561:7): [True: 0, False: 0]
  ------------------
 1562|      0|      case spv::StorageClass::Workgroup:
  ------------------
  |  Branch (1562:7): [True: 0, False: 0]
  ------------------
 1563|      0|      case spv::StorageClass::Private:
  ------------------
  |  Branch (1563:7): [True: 0, False: 0]
  ------------------
 1564|      0|      case spv::StorageClass::Function:
  ------------------
  |  Branch (1564:7): [True: 0, False: 0]
  ------------------
 1565|      0|      case spv::StorageClass::PushConstant:
  ------------------
  |  Branch (1565:7): [True: 0, False: 0]
  ------------------
 1566|      0|      case spv::StorageClass::PhysicalStorageBuffer:
  ------------------
  |  Branch (1566:7): [True: 0, False: 0]
  ------------------
 1567|      0|      case spv::StorageClass::RayPayloadKHR:
  ------------------
  |  Branch (1567:7): [True: 0, False: 0]
  ------------------
 1568|      0|      case spv::StorageClass::IncomingRayPayloadKHR:
  ------------------
  |  Branch (1568:7): [True: 0, False: 0]
  ------------------
 1569|      0|      case spv::StorageClass::HitAttributeKHR:
  ------------------
  |  Branch (1569:7): [True: 0, False: 0]
  ------------------
 1570|      0|      case spv::StorageClass::CallableDataKHR:
  ------------------
  |  Branch (1570:7): [True: 0, False: 0]
  ------------------
 1571|      0|      case spv::StorageClass::IncomingCallableDataKHR:
  ------------------
  |  Branch (1571:7): [True: 0, False: 0]
  ------------------
 1572|      0|      case spv::StorageClass::ShaderRecordBufferKHR:
  ------------------
  |  Branch (1572:7): [True: 0, False: 0]
  ------------------
 1573|      0|      case spv::StorageClass::TaskPayloadWorkgroupEXT:
  ------------------
  |  Branch (1573:7): [True: 0, False: 0]
  ------------------
 1574|      0|      case spv::StorageClass::HitObjectAttributeNV:
  ------------------
  |  Branch (1574:7): [True: 0, False: 0]
  ------------------
 1575|      0|        return true;
 1576|      0|      default:
  ------------------
  |  Branch (1576:7): [True: 0, False: 0]
  ------------------
 1577|      0|        return false;
 1578|      0|    }
 1579|      0|  }
 1580|       |
 1581|  12.6k|  return true;
 1582|  12.6k|}
_ZNK8spvtools3val17ValidationState_t9VkErrorIDEjPKc:
 1588|     35|                                         const char* /*reference*/) const {
 1589|     35|  if (!spvIsVulkanEnv(context_->target_env)) {
  ------------------
  |  Branch (1589:7): [True: 35, False: 0]
  ------------------
 1590|     35|    return "";
 1591|     35|  }
 1592|       |
 1593|       |  // This large switch case is only searched when an error has occurred.
 1594|       |  // If an id is changed, the old case must be modified or removed. Each string
 1595|       |  // here is interpreted as being "implemented"
 1596|       |
 1597|       |  // Clang format adds spaces between hyphens
 1598|       |  // clang-format off
 1599|      0|  switch (id) {
 1600|      0|    case 4154:
  ------------------
  |  Branch (1600:5): [True: 0, False: 0]
  ------------------
 1601|      0|      return VUID_WRAP(VUID-BaryCoordKHR-BaryCoordKHR-04154);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1602|      0|    case 4155:
  ------------------
  |  Branch (1602:5): [True: 0, False: 0]
  ------------------
 1603|      0|      return VUID_WRAP(VUID-BaryCoordKHR-BaryCoordKHR-04155);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1604|      0|    case 4156:
  ------------------
  |  Branch (1604:5): [True: 0, False: 0]
  ------------------
 1605|      0|      return VUID_WRAP(VUID-BaryCoordKHR-BaryCoordKHR-04156);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1606|      0|    case 4160:
  ------------------
  |  Branch (1606:5): [True: 0, False: 0]
  ------------------
 1607|      0|      return VUID_WRAP(VUID-BaryCoordNoPerspKHR-BaryCoordNoPerspKHR-04160);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1608|      0|    case 4161:
  ------------------
  |  Branch (1608:5): [True: 0, False: 0]
  ------------------
 1609|      0|      return VUID_WRAP(VUID-BaryCoordNoPerspKHR-BaryCoordNoPerspKHR-04161);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1610|      0|    case 4162:
  ------------------
  |  Branch (1610:5): [True: 0, False: 0]
  ------------------
 1611|      0|      return VUID_WRAP(VUID-BaryCoordNoPerspKHR-BaryCoordNoPerspKHR-04162);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1612|      0|    case 4181:
  ------------------
  |  Branch (1612:5): [True: 0, False: 0]
  ------------------
 1613|      0|      return VUID_WRAP(VUID-BaseInstance-BaseInstance-04181);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1614|      0|    case 4182:
  ------------------
  |  Branch (1614:5): [True: 0, False: 0]
  ------------------
 1615|      0|      return VUID_WRAP(VUID-BaseInstance-BaseInstance-04182);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1616|      0|    case 4183:
  ------------------
  |  Branch (1616:5): [True: 0, False: 0]
  ------------------
 1617|      0|      return VUID_WRAP(VUID-BaseInstance-BaseInstance-04183);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1618|      0|    case 4184:
  ------------------
  |  Branch (1618:5): [True: 0, False: 0]
  ------------------
 1619|      0|      return VUID_WRAP(VUID-BaseVertex-BaseVertex-04184);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1620|      0|    case 4185:
  ------------------
  |  Branch (1620:5): [True: 0, False: 0]
  ------------------
 1621|      0|      return VUID_WRAP(VUID-BaseVertex-BaseVertex-04185);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1622|      0|    case 4186:
  ------------------
  |  Branch (1622:5): [True: 0, False: 0]
  ------------------
 1623|      0|      return VUID_WRAP(VUID-BaseVertex-BaseVertex-04186);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1624|      0|    case 4187:
  ------------------
  |  Branch (1624:5): [True: 0, False: 0]
  ------------------
 1625|      0|      return VUID_WRAP(VUID-ClipDistance-ClipDistance-04187);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1626|      0|    case 4188:
  ------------------
  |  Branch (1626:5): [True: 0, False: 0]
  ------------------
 1627|      0|      return VUID_WRAP(VUID-ClipDistance-ClipDistance-04188);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1628|      0|    case 4189:
  ------------------
  |  Branch (1628:5): [True: 0, False: 0]
  ------------------
 1629|      0|      return VUID_WRAP(VUID-ClipDistance-ClipDistance-04189);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1630|      0|    case 4190:
  ------------------
  |  Branch (1630:5): [True: 0, False: 0]
  ------------------
 1631|      0|      return VUID_WRAP(VUID-ClipDistance-ClipDistance-04190);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1632|      0|    case 4191:
  ------------------
  |  Branch (1632:5): [True: 0, False: 0]
  ------------------
 1633|      0|      return VUID_WRAP(VUID-ClipDistance-ClipDistance-04191);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1634|      0|    case 4196:
  ------------------
  |  Branch (1634:5): [True: 0, False: 0]
  ------------------
 1635|      0|      return VUID_WRAP(VUID-CullDistance-CullDistance-04196);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1636|      0|    case 4197:
  ------------------
  |  Branch (1636:5): [True: 0, False: 0]
  ------------------
 1637|      0|      return VUID_WRAP(VUID-CullDistance-CullDistance-04197);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1638|      0|    case 4198:
  ------------------
  |  Branch (1638:5): [True: 0, False: 0]
  ------------------
 1639|      0|      return VUID_WRAP(VUID-CullDistance-CullDistance-04198);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1640|      0|    case 4199:
  ------------------
  |  Branch (1640:5): [True: 0, False: 0]
  ------------------
 1641|      0|      return VUID_WRAP(VUID-CullDistance-CullDistance-04199);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1642|      0|    case 4200:
  ------------------
  |  Branch (1642:5): [True: 0, False: 0]
  ------------------
 1643|      0|      return VUID_WRAP(VUID-CullDistance-CullDistance-04200);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1644|      0|    case 6735:
  ------------------
  |  Branch (1644:5): [True: 0, False: 0]
  ------------------
 1645|      0|      return VUID_WRAP(VUID-CullMaskKHR-CullMaskKHR-06735); // Execution Model
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1646|      0|    case 6736:
  ------------------
  |  Branch (1646:5): [True: 0, False: 0]
  ------------------
 1647|      0|      return VUID_WRAP(VUID-CullMaskKHR-CullMaskKHR-06736); // input storage
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1648|      0|    case 6737:
  ------------------
  |  Branch (1648:5): [True: 0, False: 0]
  ------------------
 1649|      0|      return VUID_WRAP(VUID-CullMaskKHR-CullMaskKHR-06737); // 32 int scalar
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1650|      0|    case 4205:
  ------------------
  |  Branch (1650:5): [True: 0, False: 0]
  ------------------
 1651|      0|      return VUID_WRAP(VUID-DeviceIndex-DeviceIndex-04205);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1652|      0|    case 4206:
  ------------------
  |  Branch (1652:5): [True: 0, False: 0]
  ------------------
 1653|      0|      return VUID_WRAP(VUID-DeviceIndex-DeviceIndex-04206);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1654|      0|    case 4207:
  ------------------
  |  Branch (1654:5): [True: 0, False: 0]
  ------------------
 1655|      0|      return VUID_WRAP(VUID-DrawIndex-DrawIndex-04207);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1656|      0|    case 4208:
  ------------------
  |  Branch (1656:5): [True: 0, False: 0]
  ------------------
 1657|      0|      return VUID_WRAP(VUID-DrawIndex-DrawIndex-04208);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1658|      0|    case 4209:
  ------------------
  |  Branch (1658:5): [True: 0, False: 0]
  ------------------
 1659|      0|      return VUID_WRAP(VUID-DrawIndex-DrawIndex-04209);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1660|      0|    case 4210:
  ------------------
  |  Branch (1660:5): [True: 0, False: 0]
  ------------------
 1661|      0|      return VUID_WRAP(VUID-FragCoord-FragCoord-04210);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1662|      0|    case 4211:
  ------------------
  |  Branch (1662:5): [True: 0, False: 0]
  ------------------
 1663|      0|      return VUID_WRAP(VUID-FragCoord-FragCoord-04211);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1664|      0|    case 4212:
  ------------------
  |  Branch (1664:5): [True: 0, False: 0]
  ------------------
 1665|      0|      return VUID_WRAP(VUID-FragCoord-FragCoord-04212);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1666|      0|    case 4213:
  ------------------
  |  Branch (1666:5): [True: 0, False: 0]
  ------------------
 1667|      0|      return VUID_WRAP(VUID-FragDepth-FragDepth-04213);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1668|      0|    case 4214:
  ------------------
  |  Branch (1668:5): [True: 0, False: 0]
  ------------------
 1669|      0|      return VUID_WRAP(VUID-FragDepth-FragDepth-04214);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1670|      0|    case 4215:
  ------------------
  |  Branch (1670:5): [True: 0, False: 0]
  ------------------
 1671|      0|      return VUID_WRAP(VUID-FragDepth-FragDepth-04215);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1672|      0|    case 4216:
  ------------------
  |  Branch (1672:5): [True: 0, False: 0]
  ------------------
 1673|      0|      return VUID_WRAP(VUID-FragDepth-FragDepth-04216);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1674|      0|    case 4217:
  ------------------
  |  Branch (1674:5): [True: 0, False: 0]
  ------------------
 1675|      0|      return VUID_WRAP(VUID-FragInvocationCountEXT-FragInvocationCountEXT-04217);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1676|      0|    case 4218:
  ------------------
  |  Branch (1676:5): [True: 0, False: 0]
  ------------------
 1677|      0|      return VUID_WRAP(VUID-FragInvocationCountEXT-FragInvocationCountEXT-04218);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1678|      0|    case 4219:
  ------------------
  |  Branch (1678:5): [True: 0, False: 0]
  ------------------
 1679|      0|      return VUID_WRAP(VUID-FragInvocationCountEXT-FragInvocationCountEXT-04219);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1680|      0|    case 4220:
  ------------------
  |  Branch (1680:5): [True: 0, False: 0]
  ------------------
 1681|      0|      return VUID_WRAP(VUID-FragSizeEXT-FragSizeEXT-04220);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1682|      0|    case 4221:
  ------------------
  |  Branch (1682:5): [True: 0, False: 0]
  ------------------
 1683|      0|      return VUID_WRAP(VUID-FragSizeEXT-FragSizeEXT-04221);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1684|      0|    case 4222:
  ------------------
  |  Branch (1684:5): [True: 0, False: 0]
  ------------------
 1685|      0|      return VUID_WRAP(VUID-FragSizeEXT-FragSizeEXT-04222);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1686|      0|    case 4223:
  ------------------
  |  Branch (1686:5): [True: 0, False: 0]
  ------------------
 1687|      0|      return VUID_WRAP(VUID-FragStencilRefEXT-FragStencilRefEXT-04223);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1688|      0|    case 4224:
  ------------------
  |  Branch (1688:5): [True: 0, False: 0]
  ------------------
 1689|      0|      return VUID_WRAP(VUID-FragStencilRefEXT-FragStencilRefEXT-04224);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1690|      0|    case 4225:
  ------------------
  |  Branch (1690:5): [True: 0, False: 0]
  ------------------
 1691|      0|      return VUID_WRAP(VUID-FragStencilRefEXT-FragStencilRefEXT-04225);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1692|      0|    case 4229:
  ------------------
  |  Branch (1692:5): [True: 0, False: 0]
  ------------------
 1693|      0|      return VUID_WRAP(VUID-FrontFacing-FrontFacing-04229);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1694|      0|    case 4230:
  ------------------
  |  Branch (1694:5): [True: 0, False: 0]
  ------------------
 1695|      0|      return VUID_WRAP(VUID-FrontFacing-FrontFacing-04230);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1696|      0|    case 4231:
  ------------------
  |  Branch (1696:5): [True: 0, False: 0]
  ------------------
 1697|      0|      return VUID_WRAP(VUID-FrontFacing-FrontFacing-04231);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1698|      0|    case 4232:
  ------------------
  |  Branch (1698:5): [True: 0, False: 0]
  ------------------
 1699|      0|      return VUID_WRAP(VUID-FullyCoveredEXT-FullyCoveredEXT-04232);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1700|      0|    case 4233:
  ------------------
  |  Branch (1700:5): [True: 0, False: 0]
  ------------------
 1701|      0|      return VUID_WRAP(VUID-FullyCoveredEXT-FullyCoveredEXT-04233);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1702|      0|    case 4234:
  ------------------
  |  Branch (1702:5): [True: 0, False: 0]
  ------------------
 1703|      0|      return VUID_WRAP(VUID-FullyCoveredEXT-FullyCoveredEXT-04234);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1704|      0|    case 4236:
  ------------------
  |  Branch (1704:5): [True: 0, False: 0]
  ------------------
 1705|      0|      return VUID_WRAP(VUID-GlobalInvocationId-GlobalInvocationId-04236);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1706|      0|    case 4237:
  ------------------
  |  Branch (1706:5): [True: 0, False: 0]
  ------------------
 1707|      0|      return VUID_WRAP(VUID-GlobalInvocationId-GlobalInvocationId-04237);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1708|      0|    case 4238:
  ------------------
  |  Branch (1708:5): [True: 0, False: 0]
  ------------------
 1709|      0|      return VUID_WRAP(VUID-GlobalInvocationId-GlobalInvocationId-04238);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1710|      0|    case 4239:
  ------------------
  |  Branch (1710:5): [True: 0, False: 0]
  ------------------
 1711|      0|      return VUID_WRAP(VUID-HelperInvocation-HelperInvocation-04239);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1712|      0|    case 4240:
  ------------------
  |  Branch (1712:5): [True: 0, False: 0]
  ------------------
 1713|      0|      return VUID_WRAP(VUID-HelperInvocation-HelperInvocation-04240);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1714|      0|    case 4241:
  ------------------
  |  Branch (1714:5): [True: 0, False: 0]
  ------------------
 1715|      0|      return VUID_WRAP(VUID-HelperInvocation-HelperInvocation-04241);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1716|      0|    case 4242:
  ------------------
  |  Branch (1716:5): [True: 0, False: 0]
  ------------------
 1717|      0|      return VUID_WRAP(VUID-HitKindKHR-HitKindKHR-04242);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1718|      0|    case 4243:
  ------------------
  |  Branch (1718:5): [True: 0, False: 0]
  ------------------
 1719|      0|      return VUID_WRAP(VUID-HitKindKHR-HitKindKHR-04243);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1720|      0|    case 4244:
  ------------------
  |  Branch (1720:5): [True: 0, False: 0]
  ------------------
 1721|      0|      return VUID_WRAP(VUID-HitKindKHR-HitKindKHR-04244);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1722|      0|    case 4245:
  ------------------
  |  Branch (1722:5): [True: 0, False: 0]
  ------------------
 1723|      0|      return VUID_WRAP(VUID-HitTNV-HitTNV-04245);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1724|      0|    case 4246:
  ------------------
  |  Branch (1724:5): [True: 0, False: 0]
  ------------------
 1725|      0|      return VUID_WRAP(VUID-HitTNV-HitTNV-04246);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1726|      0|    case 4247:
  ------------------
  |  Branch (1726:5): [True: 0, False: 0]
  ------------------
 1727|      0|      return VUID_WRAP(VUID-HitTNV-HitTNV-04247);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1728|      0|    case 4248:
  ------------------
  |  Branch (1728:5): [True: 0, False: 0]
  ------------------
 1729|      0|      return VUID_WRAP(VUID-IncomingRayFlagsKHR-IncomingRayFlagsKHR-04248);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1730|      0|    case 4249:
  ------------------
  |  Branch (1730:5): [True: 0, False: 0]
  ------------------
 1731|      0|      return VUID_WRAP(VUID-IncomingRayFlagsKHR-IncomingRayFlagsKHR-04249);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1732|      0|    case 4250:
  ------------------
  |  Branch (1732:5): [True: 0, False: 0]
  ------------------
 1733|      0|      return VUID_WRAP(VUID-IncomingRayFlagsKHR-IncomingRayFlagsKHR-04250);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1734|      0|    case 4251:
  ------------------
  |  Branch (1734:5): [True: 0, False: 0]
  ------------------
 1735|      0|      return VUID_WRAP(VUID-InstanceCustomIndexKHR-InstanceCustomIndexKHR-04251);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1736|      0|    case 4252:
  ------------------
  |  Branch (1736:5): [True: 0, False: 0]
  ------------------
 1737|      0|      return VUID_WRAP(VUID-InstanceCustomIndexKHR-InstanceCustomIndexKHR-04252);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1738|      0|    case 4253:
  ------------------
  |  Branch (1738:5): [True: 0, False: 0]
  ------------------
 1739|      0|      return VUID_WRAP(VUID-InstanceCustomIndexKHR-InstanceCustomIndexKHR-04253);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1740|      0|    case 4254:
  ------------------
  |  Branch (1740:5): [True: 0, False: 0]
  ------------------
 1741|      0|      return VUID_WRAP(VUID-InstanceId-InstanceId-04254);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1742|      0|    case 4255:
  ------------------
  |  Branch (1742:5): [True: 0, False: 0]
  ------------------
 1743|      0|      return VUID_WRAP(VUID-InstanceId-InstanceId-04255);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1744|      0|    case 4256:
  ------------------
  |  Branch (1744:5): [True: 0, False: 0]
  ------------------
 1745|      0|      return VUID_WRAP(VUID-InstanceId-InstanceId-04256);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1746|      0|    case 4257:
  ------------------
  |  Branch (1746:5): [True: 0, False: 0]
  ------------------
 1747|      0|      return VUID_WRAP(VUID-InvocationId-InvocationId-04257);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1748|      0|    case 4258:
  ------------------
  |  Branch (1748:5): [True: 0, False: 0]
  ------------------
 1749|      0|      return VUID_WRAP(VUID-InvocationId-InvocationId-04258);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1750|      0|    case 4259:
  ------------------
  |  Branch (1750:5): [True: 0, False: 0]
  ------------------
 1751|      0|      return VUID_WRAP(VUID-InvocationId-InvocationId-04259);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1752|      0|    case 4263:
  ------------------
  |  Branch (1752:5): [True: 0, False: 0]
  ------------------
 1753|      0|      return VUID_WRAP(VUID-InstanceIndex-InstanceIndex-04263);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1754|      0|    case 4264:
  ------------------
  |  Branch (1754:5): [True: 0, False: 0]
  ------------------
 1755|      0|      return VUID_WRAP(VUID-InstanceIndex-InstanceIndex-04264);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1756|      0|    case 4265:
  ------------------
  |  Branch (1756:5): [True: 0, False: 0]
  ------------------
 1757|      0|      return VUID_WRAP(VUID-InstanceIndex-InstanceIndex-04265);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1758|      0|    case 4266:
  ------------------
  |  Branch (1758:5): [True: 0, False: 0]
  ------------------
 1759|      0|      return VUID_WRAP(VUID-LaunchIdKHR-LaunchIdKHR-04266);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1760|      0|    case 4267:
  ------------------
  |  Branch (1760:5): [True: 0, False: 0]
  ------------------
 1761|      0|      return VUID_WRAP(VUID-LaunchIdKHR-LaunchIdKHR-04267);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1762|      0|    case 4268:
  ------------------
  |  Branch (1762:5): [True: 0, False: 0]
  ------------------
 1763|      0|      return VUID_WRAP(VUID-LaunchIdKHR-LaunchIdKHR-04268);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1764|      0|    case 4269:
  ------------------
  |  Branch (1764:5): [True: 0, False: 0]
  ------------------
 1765|      0|      return VUID_WRAP(VUID-LaunchSizeKHR-LaunchSizeKHR-04269);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1766|      0|    case 4270:
  ------------------
  |  Branch (1766:5): [True: 0, False: 0]
  ------------------
 1767|      0|      return VUID_WRAP(VUID-LaunchSizeKHR-LaunchSizeKHR-04270);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1768|      0|    case 4271:
  ------------------
  |  Branch (1768:5): [True: 0, False: 0]
  ------------------
 1769|      0|      return VUID_WRAP(VUID-LaunchSizeKHR-LaunchSizeKHR-04271);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1770|      0|    case 4272:
  ------------------
  |  Branch (1770:5): [True: 0, False: 0]
  ------------------
 1771|      0|      return VUID_WRAP(VUID-Layer-Layer-04272);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1772|      0|    case 4273:
  ------------------
  |  Branch (1772:5): [True: 0, False: 0]
  ------------------
 1773|      0|      return VUID_WRAP(VUID-Layer-Layer-04273);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1774|      0|    case 4274:
  ------------------
  |  Branch (1774:5): [True: 0, False: 0]
  ------------------
 1775|      0|      return VUID_WRAP(VUID-Layer-Layer-04274);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1776|      0|    case 4275:
  ------------------
  |  Branch (1776:5): [True: 0, False: 0]
  ------------------
 1777|      0|      return VUID_WRAP(VUID-Layer-Layer-04275);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1778|      0|    case 4276:
  ------------------
  |  Branch (1778:5): [True: 0, False: 0]
  ------------------
 1779|      0|      return VUID_WRAP(VUID-Layer-Layer-04276);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1780|      0|    case 4281:
  ------------------
  |  Branch (1780:5): [True: 0, False: 0]
  ------------------
 1781|      0|      return VUID_WRAP(VUID-LocalInvocationId-LocalInvocationId-04281);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1782|      0|    case 4282:
  ------------------
  |  Branch (1782:5): [True: 0, False: 0]
  ------------------
 1783|      0|      return VUID_WRAP(VUID-LocalInvocationId-LocalInvocationId-04282);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1784|      0|    case 4283:
  ------------------
  |  Branch (1784:5): [True: 0, False: 0]
  ------------------
 1785|      0|      return VUID_WRAP(VUID-LocalInvocationId-LocalInvocationId-04283);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1786|      0|    case 4293:
  ------------------
  |  Branch (1786:5): [True: 0, False: 0]
  ------------------
 1787|      0|      return VUID_WRAP(VUID-NumSubgroups-NumSubgroups-04293);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1788|      0|    case 4294:
  ------------------
  |  Branch (1788:5): [True: 0, False: 0]
  ------------------
 1789|      0|      return VUID_WRAP(VUID-NumSubgroups-NumSubgroups-04294);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1790|      0|    case 4295:
  ------------------
  |  Branch (1790:5): [True: 0, False: 0]
  ------------------
 1791|      0|      return VUID_WRAP(VUID-NumSubgroups-NumSubgroups-04295);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1792|      0|    case 4296:
  ------------------
  |  Branch (1792:5): [True: 0, False: 0]
  ------------------
 1793|      0|      return VUID_WRAP(VUID-NumWorkgroups-NumWorkgroups-04296);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1794|      0|    case 4297:
  ------------------
  |  Branch (1794:5): [True: 0, False: 0]
  ------------------
 1795|      0|      return VUID_WRAP(VUID-NumWorkgroups-NumWorkgroups-04297);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1796|      0|    case 4298:
  ------------------
  |  Branch (1796:5): [True: 0, False: 0]
  ------------------
 1797|      0|      return VUID_WRAP(VUID-NumWorkgroups-NumWorkgroups-04298);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1798|      0|    case 4299:
  ------------------
  |  Branch (1798:5): [True: 0, False: 0]
  ------------------
 1799|      0|      return VUID_WRAP(VUID-ObjectRayDirectionKHR-ObjectRayDirectionKHR-04299);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1800|      0|    case 4300:
  ------------------
  |  Branch (1800:5): [True: 0, False: 0]
  ------------------
 1801|      0|      return VUID_WRAP(VUID-ObjectRayDirectionKHR-ObjectRayDirectionKHR-04300);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1802|      0|    case 4301:
  ------------------
  |  Branch (1802:5): [True: 0, False: 0]
  ------------------
 1803|      0|      return VUID_WRAP(VUID-ObjectRayDirectionKHR-ObjectRayDirectionKHR-04301);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1804|      0|    case 4302:
  ------------------
  |  Branch (1804:5): [True: 0, False: 0]
  ------------------
 1805|      0|      return VUID_WRAP(VUID-ObjectRayOriginKHR-ObjectRayOriginKHR-04302);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1806|      0|    case 4303:
  ------------------
  |  Branch (1806:5): [True: 0, False: 0]
  ------------------
 1807|      0|      return VUID_WRAP(VUID-ObjectRayOriginKHR-ObjectRayOriginKHR-04303);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1808|      0|    case 4304:
  ------------------
  |  Branch (1808:5): [True: 0, False: 0]
  ------------------
 1809|      0|      return VUID_WRAP(VUID-ObjectRayOriginKHR-ObjectRayOriginKHR-04304);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1810|      0|    case 4305:
  ------------------
  |  Branch (1810:5): [True: 0, False: 0]
  ------------------
 1811|      0|      return VUID_WRAP(VUID-ObjectToWorldKHR-ObjectToWorldKHR-04305);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1812|      0|    case 4306:
  ------------------
  |  Branch (1812:5): [True: 0, False: 0]
  ------------------
 1813|      0|      return VUID_WRAP(VUID-ObjectToWorldKHR-ObjectToWorldKHR-04306);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1814|      0|    case 4307:
  ------------------
  |  Branch (1814:5): [True: 0, False: 0]
  ------------------
 1815|      0|      return VUID_WRAP(VUID-ObjectToWorldKHR-ObjectToWorldKHR-04307);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1816|      0|    case 4308:
  ------------------
  |  Branch (1816:5): [True: 0, False: 0]
  ------------------
 1817|      0|      return VUID_WRAP(VUID-PatchVertices-PatchVertices-04308);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1818|      0|    case 4309:
  ------------------
  |  Branch (1818:5): [True: 0, False: 0]
  ------------------
 1819|      0|      return VUID_WRAP(VUID-PatchVertices-PatchVertices-04309);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1820|      0|    case 4310:
  ------------------
  |  Branch (1820:5): [True: 0, False: 0]
  ------------------
 1821|      0|      return VUID_WRAP(VUID-PatchVertices-PatchVertices-04310);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1822|      0|    case 4311:
  ------------------
  |  Branch (1822:5): [True: 0, False: 0]
  ------------------
 1823|      0|      return VUID_WRAP(VUID-PointCoord-PointCoord-04311);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1824|      0|    case 4312:
  ------------------
  |  Branch (1824:5): [True: 0, False: 0]
  ------------------
 1825|      0|      return VUID_WRAP(VUID-PointCoord-PointCoord-04312);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1826|      0|    case 4313:
  ------------------
  |  Branch (1826:5): [True: 0, False: 0]
  ------------------
 1827|      0|      return VUID_WRAP(VUID-PointCoord-PointCoord-04313);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1828|      0|    case 4314:
  ------------------
  |  Branch (1828:5): [True: 0, False: 0]
  ------------------
 1829|      0|      return VUID_WRAP(VUID-PointSize-PointSize-04314);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1830|      0|    case 4315:
  ------------------
  |  Branch (1830:5): [True: 0, False: 0]
  ------------------
 1831|      0|      return VUID_WRAP(VUID-PointSize-PointSize-04315);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1832|      0|    case 4316:
  ------------------
  |  Branch (1832:5): [True: 0, False: 0]
  ------------------
 1833|      0|      return VUID_WRAP(VUID-PointSize-PointSize-04316);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1834|      0|    case 4317:
  ------------------
  |  Branch (1834:5): [True: 0, False: 0]
  ------------------
 1835|      0|      return VUID_WRAP(VUID-PointSize-PointSize-04317);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1836|      0|    case 4318:
  ------------------
  |  Branch (1836:5): [True: 0, False: 0]
  ------------------
 1837|      0|      return VUID_WRAP(VUID-Position-Position-04318);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1838|      0|    case 4319:
  ------------------
  |  Branch (1838:5): [True: 0, False: 0]
  ------------------
 1839|      0|      return VUID_WRAP(VUID-Position-Position-04319);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1840|      0|    case 4320:
  ------------------
  |  Branch (1840:5): [True: 0, False: 0]
  ------------------
 1841|      0|      return VUID_WRAP(VUID-Position-Position-04320);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1842|      0|    case 4321:
  ------------------
  |  Branch (1842:5): [True: 0, False: 0]
  ------------------
 1843|      0|      return VUID_WRAP(VUID-Position-Position-04321);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1844|      0|    case 4330:
  ------------------
  |  Branch (1844:5): [True: 0, False: 0]
  ------------------
 1845|      0|      return VUID_WRAP(VUID-PrimitiveId-PrimitiveId-04330);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1846|      0|    case 4334:
  ------------------
  |  Branch (1846:5): [True: 0, False: 0]
  ------------------
 1847|      0|      return VUID_WRAP(VUID-PrimitiveId-PrimitiveId-04334);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1848|      0|    case 4337:
  ------------------
  |  Branch (1848:5): [True: 0, False: 0]
  ------------------
 1849|      0|      return VUID_WRAP(VUID-PrimitiveId-PrimitiveId-04337);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1850|      0|    case 4345:
  ------------------
  |  Branch (1850:5): [True: 0, False: 0]
  ------------------
 1851|      0|      return VUID_WRAP(VUID-RayGeometryIndexKHR-RayGeometryIndexKHR-04345);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1852|      0|    case 4346:
  ------------------
  |  Branch (1852:5): [True: 0, False: 0]
  ------------------
 1853|      0|      return VUID_WRAP(VUID-RayGeometryIndexKHR-RayGeometryIndexKHR-04346);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1854|      0|    case 4347:
  ------------------
  |  Branch (1854:5): [True: 0, False: 0]
  ------------------
 1855|      0|      return VUID_WRAP(VUID-RayGeometryIndexKHR-RayGeometryIndexKHR-04347);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1856|      0|    case 4348:
  ------------------
  |  Branch (1856:5): [True: 0, False: 0]
  ------------------
 1857|      0|      return VUID_WRAP(VUID-RayTmaxKHR-RayTmaxKHR-04348);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1858|      0|    case 4349:
  ------------------
  |  Branch (1858:5): [True: 0, False: 0]
  ------------------
 1859|      0|      return VUID_WRAP(VUID-RayTmaxKHR-RayTmaxKHR-04349);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1860|      0|    case 4350:
  ------------------
  |  Branch (1860:5): [True: 0, False: 0]
  ------------------
 1861|      0|      return VUID_WRAP(VUID-RayTmaxKHR-RayTmaxKHR-04350);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1862|      0|    case 4351:
  ------------------
  |  Branch (1862:5): [True: 0, False: 0]
  ------------------
 1863|      0|      return VUID_WRAP(VUID-RayTminKHR-RayTminKHR-04351);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1864|      0|    case 4352:
  ------------------
  |  Branch (1864:5): [True: 0, False: 0]
  ------------------
 1865|      0|      return VUID_WRAP(VUID-RayTminKHR-RayTminKHR-04352);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1866|      0|    case 4353:
  ------------------
  |  Branch (1866:5): [True: 0, False: 0]
  ------------------
 1867|      0|      return VUID_WRAP(VUID-RayTminKHR-RayTminKHR-04353);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1868|      0|    case 4354:
  ------------------
  |  Branch (1868:5): [True: 0, False: 0]
  ------------------
 1869|      0|      return VUID_WRAP(VUID-SampleId-SampleId-04354);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1870|      0|    case 4355:
  ------------------
  |  Branch (1870:5): [True: 0, False: 0]
  ------------------
 1871|      0|      return VUID_WRAP(VUID-SampleId-SampleId-04355);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1872|      0|    case 4356:
  ------------------
  |  Branch (1872:5): [True: 0, False: 0]
  ------------------
 1873|      0|      return VUID_WRAP(VUID-SampleId-SampleId-04356);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1874|      0|    case 4357:
  ------------------
  |  Branch (1874:5): [True: 0, False: 0]
  ------------------
 1875|      0|      return VUID_WRAP(VUID-SampleMask-SampleMask-04357);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1876|      0|    case 4358:
  ------------------
  |  Branch (1876:5): [True: 0, False: 0]
  ------------------
 1877|      0|      return VUID_WRAP(VUID-SampleMask-SampleMask-04358);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1878|      0|    case 4359:
  ------------------
  |  Branch (1878:5): [True: 0, False: 0]
  ------------------
 1879|      0|      return VUID_WRAP(VUID-SampleMask-SampleMask-04359);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1880|      0|    case 4360:
  ------------------
  |  Branch (1880:5): [True: 0, False: 0]
  ------------------
 1881|      0|      return VUID_WRAP(VUID-SamplePosition-SamplePosition-04360);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1882|      0|    case 4361:
  ------------------
  |  Branch (1882:5): [True: 0, False: 0]
  ------------------
 1883|      0|      return VUID_WRAP(VUID-SamplePosition-SamplePosition-04361);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1884|      0|    case 4362:
  ------------------
  |  Branch (1884:5): [True: 0, False: 0]
  ------------------
 1885|      0|      return VUID_WRAP(VUID-SamplePosition-SamplePosition-04362);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1886|      0|    case 4367:
  ------------------
  |  Branch (1886:5): [True: 0, False: 0]
  ------------------
 1887|      0|      return VUID_WRAP(VUID-SubgroupId-SubgroupId-04367);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1888|      0|    case 4368:
  ------------------
  |  Branch (1888:5): [True: 0, False: 0]
  ------------------
 1889|      0|      return VUID_WRAP(VUID-SubgroupId-SubgroupId-04368);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1890|      0|    case 4369:
  ------------------
  |  Branch (1890:5): [True: 0, False: 0]
  ------------------
 1891|      0|      return VUID_WRAP(VUID-SubgroupId-SubgroupId-04369);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1892|      0|    case 4370:
  ------------------
  |  Branch (1892:5): [True: 0, False: 0]
  ------------------
 1893|      0|      return VUID_WRAP(VUID-SubgroupEqMask-SubgroupEqMask-04370);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1894|      0|    case 4371:
  ------------------
  |  Branch (1894:5): [True: 0, False: 0]
  ------------------
 1895|      0|      return VUID_WRAP(VUID-SubgroupEqMask-SubgroupEqMask-04371);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1896|      0|    case 4372:
  ------------------
  |  Branch (1896:5): [True: 0, False: 0]
  ------------------
 1897|      0|      return VUID_WRAP(VUID-SubgroupGeMask-SubgroupGeMask-04372);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1898|      0|    case 4373:
  ------------------
  |  Branch (1898:5): [True: 0, False: 0]
  ------------------
 1899|      0|      return VUID_WRAP(VUID-SubgroupGeMask-SubgroupGeMask-04373);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1900|      0|    case 4374:
  ------------------
  |  Branch (1900:5): [True: 0, False: 0]
  ------------------
 1901|      0|      return VUID_WRAP(VUID-SubgroupGtMask-SubgroupGtMask-04374);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1902|      0|    case 4375:
  ------------------
  |  Branch (1902:5): [True: 0, False: 0]
  ------------------
 1903|      0|      return VUID_WRAP(VUID-SubgroupGtMask-SubgroupGtMask-04375);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1904|      0|    case 4376:
  ------------------
  |  Branch (1904:5): [True: 0, False: 0]
  ------------------
 1905|      0|      return VUID_WRAP(VUID-SubgroupLeMask-SubgroupLeMask-04376);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1906|      0|    case 4377:
  ------------------
  |  Branch (1906:5): [True: 0, False: 0]
  ------------------
 1907|      0|      return VUID_WRAP(VUID-SubgroupLeMask-SubgroupLeMask-04377);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1908|      0|    case 4378:
  ------------------
  |  Branch (1908:5): [True: 0, False: 0]
  ------------------
 1909|      0|      return VUID_WRAP(VUID-SubgroupLtMask-SubgroupLtMask-04378);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1910|      0|    case 4379:
  ------------------
  |  Branch (1910:5): [True: 0, False: 0]
  ------------------
 1911|      0|      return VUID_WRAP(VUID-SubgroupLtMask-SubgroupLtMask-04379);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1912|      0|    case 4380:
  ------------------
  |  Branch (1912:5): [True: 0, False: 0]
  ------------------
 1913|      0|      return VUID_WRAP(VUID-SubgroupLocalInvocationId-SubgroupLocalInvocationId-04380);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1914|      0|    case 4381:
  ------------------
  |  Branch (1914:5): [True: 0, False: 0]
  ------------------
 1915|      0|      return VUID_WRAP(VUID-SubgroupLocalInvocationId-SubgroupLocalInvocationId-04381);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1916|      0|    case 4382:
  ------------------
  |  Branch (1916:5): [True: 0, False: 0]
  ------------------
 1917|      0|      return VUID_WRAP(VUID-SubgroupSize-SubgroupSize-04382);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1918|      0|    case 4383:
  ------------------
  |  Branch (1918:5): [True: 0, False: 0]
  ------------------
 1919|      0|      return VUID_WRAP(VUID-SubgroupSize-SubgroupSize-04383);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1920|      0|    case 4387:
  ------------------
  |  Branch (1920:5): [True: 0, False: 0]
  ------------------
 1921|      0|      return VUID_WRAP(VUID-TessCoord-TessCoord-04387);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1922|      0|    case 4388:
  ------------------
  |  Branch (1922:5): [True: 0, False: 0]
  ------------------
 1923|      0|      return VUID_WRAP(VUID-TessCoord-TessCoord-04388);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1924|      0|    case 4389:
  ------------------
  |  Branch (1924:5): [True: 0, False: 0]
  ------------------
 1925|      0|      return VUID_WRAP(VUID-TessCoord-TessCoord-04389);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1926|      0|    case 4390:
  ------------------
  |  Branch (1926:5): [True: 0, False: 0]
  ------------------
 1927|      0|      return VUID_WRAP(VUID-TessLevelOuter-TessLevelOuter-04390);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1928|      0|    case 4391:
  ------------------
  |  Branch (1928:5): [True: 0, False: 0]
  ------------------
 1929|      0|      return VUID_WRAP(VUID-TessLevelOuter-TessLevelOuter-04391);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1930|      0|    case 4392:
  ------------------
  |  Branch (1930:5): [True: 0, False: 0]
  ------------------
 1931|      0|      return VUID_WRAP(VUID-TessLevelOuter-TessLevelOuter-04392);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1932|      0|    case 4393:
  ------------------
  |  Branch (1932:5): [True: 0, False: 0]
  ------------------
 1933|      0|      return VUID_WRAP(VUID-TessLevelOuter-TessLevelOuter-04393);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1934|      0|    case 4394:
  ------------------
  |  Branch (1934:5): [True: 0, False: 0]
  ------------------
 1935|      0|      return VUID_WRAP(VUID-TessLevelInner-TessLevelInner-04394);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1936|      0|    case 4395:
  ------------------
  |  Branch (1936:5): [True: 0, False: 0]
  ------------------
 1937|      0|      return VUID_WRAP(VUID-TessLevelInner-TessLevelInner-04395);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1938|      0|    case 4396:
  ------------------
  |  Branch (1938:5): [True: 0, False: 0]
  ------------------
 1939|      0|      return VUID_WRAP(VUID-TessLevelInner-TessLevelInner-04396);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1940|      0|    case 4397:
  ------------------
  |  Branch (1940:5): [True: 0, False: 0]
  ------------------
 1941|      0|      return VUID_WRAP(VUID-TessLevelInner-TessLevelInner-04397);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1942|      0|    case 4398:
  ------------------
  |  Branch (1942:5): [True: 0, False: 0]
  ------------------
 1943|      0|      return VUID_WRAP(VUID-VertexIndex-VertexIndex-04398);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1944|      0|    case 4399:
  ------------------
  |  Branch (1944:5): [True: 0, False: 0]
  ------------------
 1945|      0|      return VUID_WRAP(VUID-VertexIndex-VertexIndex-04399);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1946|      0|    case 4400:
  ------------------
  |  Branch (1946:5): [True: 0, False: 0]
  ------------------
 1947|      0|      return VUID_WRAP(VUID-VertexIndex-VertexIndex-04400);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1948|      0|    case 4401:
  ------------------
  |  Branch (1948:5): [True: 0, False: 0]
  ------------------
 1949|      0|      return VUID_WRAP(VUID-ViewIndex-ViewIndex-04401);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1950|      0|    case 4402:
  ------------------
  |  Branch (1950:5): [True: 0, False: 0]
  ------------------
 1951|      0|      return VUID_WRAP(VUID-ViewIndex-ViewIndex-04402);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1952|      0|    case 4403:
  ------------------
  |  Branch (1952:5): [True: 0, False: 0]
  ------------------
 1953|      0|      return VUID_WRAP(VUID-ViewIndex-ViewIndex-04403);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1954|      0|    case 4404:
  ------------------
  |  Branch (1954:5): [True: 0, False: 0]
  ------------------
 1955|      0|      return VUID_WRAP(VUID-ViewportIndex-ViewportIndex-04404);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1956|      0|    case 4405:
  ------------------
  |  Branch (1956:5): [True: 0, False: 0]
  ------------------
 1957|      0|      return VUID_WRAP(VUID-ViewportIndex-ViewportIndex-04405);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1958|      0|    case 4406:
  ------------------
  |  Branch (1958:5): [True: 0, False: 0]
  ------------------
 1959|      0|      return VUID_WRAP(VUID-ViewportIndex-ViewportIndex-04406);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1960|      0|    case 4407:
  ------------------
  |  Branch (1960:5): [True: 0, False: 0]
  ------------------
 1961|      0|      return VUID_WRAP(VUID-ViewportIndex-ViewportIndex-04407);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1962|      0|    case 4408:
  ------------------
  |  Branch (1962:5): [True: 0, False: 0]
  ------------------
 1963|      0|      return VUID_WRAP(VUID-ViewportIndex-ViewportIndex-04408);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1964|      0|    case 4422:
  ------------------
  |  Branch (1964:5): [True: 0, False: 0]
  ------------------
 1965|      0|      return VUID_WRAP(VUID-WorkgroupId-WorkgroupId-04422);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1966|      0|    case 4423:
  ------------------
  |  Branch (1966:5): [True: 0, False: 0]
  ------------------
 1967|      0|      return VUID_WRAP(VUID-WorkgroupId-WorkgroupId-04423);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1968|      0|    case 4424:
  ------------------
  |  Branch (1968:5): [True: 0, False: 0]
  ------------------
 1969|      0|      return VUID_WRAP(VUID-WorkgroupId-WorkgroupId-04424);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1970|      0|    case 4425:
  ------------------
  |  Branch (1970:5): [True: 0, False: 0]
  ------------------
 1971|      0|      return VUID_WRAP(VUID-WorkgroupSize-WorkgroupSize-04425);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1972|      0|    case 4426:
  ------------------
  |  Branch (1972:5): [True: 0, False: 0]
  ------------------
 1973|      0|      return VUID_WRAP(VUID-WorkgroupSize-WorkgroupSize-04426);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1974|      0|    case 4427:
  ------------------
  |  Branch (1974:5): [True: 0, False: 0]
  ------------------
 1975|      0|      return VUID_WRAP(VUID-WorkgroupSize-WorkgroupSize-04427);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1976|      0|    case 4428:
  ------------------
  |  Branch (1976:5): [True: 0, False: 0]
  ------------------
 1977|      0|      return VUID_WRAP(VUID-WorldRayDirectionKHR-WorldRayDirectionKHR-04428);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1978|      0|    case 4429:
  ------------------
  |  Branch (1978:5): [True: 0, False: 0]
  ------------------
 1979|      0|      return VUID_WRAP(VUID-WorldRayDirectionKHR-WorldRayDirectionKHR-04429);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1980|      0|    case 4430:
  ------------------
  |  Branch (1980:5): [True: 0, False: 0]
  ------------------
 1981|      0|      return VUID_WRAP(VUID-WorldRayDirectionKHR-WorldRayDirectionKHR-04430);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1982|      0|    case 4431:
  ------------------
  |  Branch (1982:5): [True: 0, False: 0]
  ------------------
 1983|      0|      return VUID_WRAP(VUID-WorldRayOriginKHR-WorldRayOriginKHR-04431);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1984|      0|    case 4432:
  ------------------
  |  Branch (1984:5): [True: 0, False: 0]
  ------------------
 1985|      0|      return VUID_WRAP(VUID-WorldRayOriginKHR-WorldRayOriginKHR-04432);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1986|      0|    case 4433:
  ------------------
  |  Branch (1986:5): [True: 0, False: 0]
  ------------------
 1987|      0|      return VUID_WRAP(VUID-WorldRayOriginKHR-WorldRayOriginKHR-04433);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1988|      0|    case 4434:
  ------------------
  |  Branch (1988:5): [True: 0, False: 0]
  ------------------
 1989|      0|      return VUID_WRAP(VUID-WorldToObjectKHR-WorldToObjectKHR-04434);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1990|      0|    case 4435:
  ------------------
  |  Branch (1990:5): [True: 0, False: 0]
  ------------------
 1991|      0|      return VUID_WRAP(VUID-WorldToObjectKHR-WorldToObjectKHR-04435);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1992|      0|    case 4436:
  ------------------
  |  Branch (1992:5): [True: 0, False: 0]
  ------------------
 1993|      0|      return VUID_WRAP(VUID-WorldToObjectKHR-WorldToObjectKHR-04436);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1994|      0|    case 4484:
  ------------------
  |  Branch (1994:5): [True: 0, False: 0]
  ------------------
 1995|      0|      return VUID_WRAP(VUID-PrimitiveShadingRateKHR-PrimitiveShadingRateKHR-04484);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1996|      0|    case 4485:
  ------------------
  |  Branch (1996:5): [True: 0, False: 0]
  ------------------
 1997|      0|      return VUID_WRAP(VUID-PrimitiveShadingRateKHR-PrimitiveShadingRateKHR-04485);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 1998|      0|    case 4486:
  ------------------
  |  Branch (1998:5): [True: 0, False: 0]
  ------------------
 1999|      0|      return VUID_WRAP(VUID-PrimitiveShadingRateKHR-PrimitiveShadingRateKHR-04486);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 2000|      0|    case 4490:
  ------------------
  |  Branch (2000:5): [True: 0, False: 0]
  ------------------
 2001|      0|      return VUID_WRAP(VUID-ShadingRateKHR-ShadingRateKHR-04490);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 2002|      0|    case 4491:
  ------------------
  |  Branch (2002:5): [True: 0, False: 0]
  ------------------
 2003|      0|      return VUID_WRAP(VUID-ShadingRateKHR-ShadingRateKHR-04491);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 2004|      0|    case 4492:
  ------------------
  |  Branch (2004:5): [True: 0, False: 0]
  ------------------
 2005|      0|      return VUID_WRAP(VUID-ShadingRateKHR-ShadingRateKHR-04492);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 2006|      0|    case 4633:
  ------------------
  |  Branch (2006:5): [True: 0, False: 0]
  ------------------
 2007|      0|      return VUID_WRAP(VUID-StandaloneSpirv-None-04633);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 2008|      0|    case 4634:
  ------------------
  |  Branch (2008:5): [True: 0, False: 0]
  ------------------
 2009|      0|      return VUID_WRAP(VUID-StandaloneSpirv-None-04634);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 2010|      0|    case 4635:
  ------------------
  |  Branch (2010:5): [True: 0, False: 0]
  ------------------
 2011|      0|      return VUID_WRAP(VUID-StandaloneSpirv-None-04635);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 2012|      0|    case 4636:
  ------------------
  |  Branch (2012:5): [True: 0, False: 0]
  ------------------
 2013|      0|      return VUID_WRAP(VUID-StandaloneSpirv-None-04636);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 2014|      0|    case 4637:
  ------------------
  |  Branch (2014:5): [True: 0, False: 0]
  ------------------
 2015|      0|      return VUID_WRAP(VUID-StandaloneSpirv-None-04637);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 2016|      0|    case 4638:
  ------------------
  |  Branch (2016:5): [True: 0, False: 0]
  ------------------
 2017|      0|      return VUID_WRAP(VUID-StandaloneSpirv-None-04638);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 2018|      0|    case 7321:
  ------------------
  |  Branch (2018:5): [True: 0, False: 0]
  ------------------
 2019|      0|      return VUID_WRAP(VUID-StandaloneSpirv-None-07321);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 2020|      0|    case 4640:
  ------------------
  |  Branch (2020:5): [True: 0, False: 0]
  ------------------
 2021|      0|      return VUID_WRAP(VUID-StandaloneSpirv-None-04640);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 2022|      0|    case 4641:
  ------------------
  |  Branch (2022:5): [True: 0, False: 0]
  ------------------
 2023|      0|      return VUID_WRAP(VUID-StandaloneSpirv-None-04641);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 2024|      0|    case 4642:
  ------------------
  |  Branch (2024:5): [True: 0, False: 0]
  ------------------
 2025|      0|      return VUID_WRAP(VUID-StandaloneSpirv-None-04642);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 2026|      0|    case 4643:
  ------------------
  |  Branch (2026:5): [True: 0, False: 0]
  ------------------
 2027|      0|      return VUID_WRAP(VUID-StandaloneSpirv-None-04643);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 2028|      0|    case 4644:
  ------------------
  |  Branch (2028:5): [True: 0, False: 0]
  ------------------
 2029|      0|      return VUID_WRAP(VUID-StandaloneSpirv-None-04644);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 2030|      0|    case 4645:
  ------------------
  |  Branch (2030:5): [True: 0, False: 0]
  ------------------
 2031|      0|      return VUID_WRAP(VUID-StandaloneSpirv-None-04645);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 2032|      0|    case 4651:
  ------------------
  |  Branch (2032:5): [True: 0, False: 0]
  ------------------
 2033|      0|      return VUID_WRAP(VUID-StandaloneSpirv-OpVariable-04651);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 2034|      0|    case 4652:
  ------------------
  |  Branch (2034:5): [True: 0, False: 0]
  ------------------
 2035|      0|      return VUID_WRAP(VUID-StandaloneSpirv-OpReadClockKHR-04652);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 2036|      0|    case 4653:
  ------------------
  |  Branch (2036:5): [True: 0, False: 0]
  ------------------
 2037|      0|      return VUID_WRAP(VUID-StandaloneSpirv-OriginLowerLeft-04653);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 2038|      0|    case 4654:
  ------------------
  |  Branch (2038:5): [True: 0, False: 0]
  ------------------
 2039|      0|      return VUID_WRAP(VUID-StandaloneSpirv-PixelCenterInteger-04654);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 2040|      0|    case 4655:
  ------------------
  |  Branch (2040:5): [True: 0, False: 0]
  ------------------
 2041|      0|      return VUID_WRAP(VUID-StandaloneSpirv-UniformConstant-04655);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 2042|      0|    case 4656:
  ------------------
  |  Branch (2042:5): [True: 0, False: 0]
  ------------------
 2043|      0|      return VUID_WRAP(VUID-StandaloneSpirv-OpTypeImage-04656);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 2044|      0|    case 4657:
  ------------------
  |  Branch (2044:5): [True: 0, False: 0]
  ------------------
 2045|      0|      return VUID_WRAP(VUID-StandaloneSpirv-OpTypeImage-04657);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 2046|      0|    case 4658:
  ------------------
  |  Branch (2046:5): [True: 0, False: 0]
  ------------------
 2047|      0|      return VUID_WRAP(VUID-StandaloneSpirv-OpImageTexelPointer-04658);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 2048|      0|    case 4659:
  ------------------
  |  Branch (2048:5): [True: 0, False: 0]
  ------------------
 2049|      0|      return VUID_WRAP(VUID-StandaloneSpirv-OpImageQuerySizeLod-04659);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 2050|      0|    case 4662:
  ------------------
  |  Branch (2050:5): [True: 0, False: 0]
  ------------------
 2051|      0|      return VUID_WRAP(VUID-StandaloneSpirv-Offset-04662);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 2052|      0|    case 4663:
  ------------------
  |  Branch (2052:5): [True: 0, False: 0]
  ------------------
 2053|      0|      return VUID_WRAP(VUID-StandaloneSpirv-Offset-04663);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 2054|      0|    case 4664:
  ------------------
  |  Branch (2054:5): [True: 0, False: 0]
  ------------------
 2055|      0|      return VUID_WRAP(VUID-StandaloneSpirv-OpImageGather-04664);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 2056|      0|    case 4667:
  ------------------
  |  Branch (2056:5): [True: 0, False: 0]
  ------------------
 2057|      0|      return VUID_WRAP(VUID-StandaloneSpirv-None-04667);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 2058|      0|    case 4669:
  ------------------
  |  Branch (2058:5): [True: 0, False: 0]
  ------------------
 2059|      0|      return VUID_WRAP(VUID-StandaloneSpirv-GLSLShared-04669);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 2060|      0|    case 4670:
  ------------------
  |  Branch (2060:5): [True: 0, False: 0]
  ------------------
 2061|      0|      return VUID_WRAP(VUID-StandaloneSpirv-Flat-04670);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 2062|      0|    case 4675:
  ------------------
  |  Branch (2062:5): [True: 0, False: 0]
  ------------------
 2063|      0|      return VUID_WRAP(VUID-StandaloneSpirv-FPRoundingMode-04675);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 2064|      0|    case 4677:
  ------------------
  |  Branch (2064:5): [True: 0, False: 0]
  ------------------
 2065|      0|      return VUID_WRAP(VUID-StandaloneSpirv-Invariant-04677);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 2066|      0|    case 4680:
  ------------------
  |  Branch (2066:5): [True: 0, False: 0]
  ------------------
 2067|      0|      return VUID_WRAP(VUID-StandaloneSpirv-OpTypeRuntimeArray-04680);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 2068|      0|    case 4682:
  ------------------
  |  Branch (2068:5): [True: 0, False: 0]
  ------------------
 2069|      0|      return VUID_WRAP(VUID-StandaloneSpirv-OpControlBarrier-04682);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 2070|      0|    case 6426:
  ------------------
  |  Branch (2070:5): [True: 0, False: 0]
  ------------------
 2071|      0|      return VUID_WRAP(VUID-StandaloneSpirv-LocalSize-06426); // formally 04683
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 2072|      0|    case 4685:
  ------------------
  |  Branch (2072:5): [True: 0, False: 0]
  ------------------
 2073|      0|      return VUID_WRAP(VUID-StandaloneSpirv-OpGroupNonUniformBallotBitCount-04685);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 2074|      0|    case 4686:
  ------------------
  |  Branch (2074:5): [True: 0, False: 0]
  ------------------
 2075|      0|      return VUID_WRAP(VUID-StandaloneSpirv-None-04686);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 2076|      0|    case 4698:
  ------------------
  |  Branch (2076:5): [True: 0, False: 0]
  ------------------
 2077|      0|      return VUID_WRAP(VUID-StandaloneSpirv-RayPayloadKHR-04698);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 2078|      0|    case 4699:
  ------------------
  |  Branch (2078:5): [True: 0, False: 0]
  ------------------
 2079|      0|      return VUID_WRAP(VUID-StandaloneSpirv-IncomingRayPayloadKHR-04699);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 2080|      0|    case 4701:
  ------------------
  |  Branch (2080:5): [True: 0, False: 0]
  ------------------
 2081|      0|      return VUID_WRAP(VUID-StandaloneSpirv-HitAttributeKHR-04701);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 2082|      0|    case 4703:
  ------------------
  |  Branch (2082:5): [True: 0, False: 0]
  ------------------
 2083|      0|      return VUID_WRAP(VUID-StandaloneSpirv-HitAttributeKHR-04703);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 2084|      0|    case 4704:
  ------------------
  |  Branch (2084:5): [True: 0, False: 0]
  ------------------
 2085|      0|      return VUID_WRAP(VUID-StandaloneSpirv-CallableDataKHR-04704);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 2086|      0|    case 4705:
  ------------------
  |  Branch (2086:5): [True: 0, False: 0]
  ------------------
 2087|      0|      return VUID_WRAP(VUID-StandaloneSpirv-IncomingCallableDataKHR-04705);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 2088|      0|    case 7119:
  ------------------
  |  Branch (2088:5): [True: 0, False: 0]
  ------------------
 2089|      0|      return VUID_WRAP(VUID-StandaloneSpirv-ShaderRecordBufferKHR-07119);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 2090|      0|    case 4708:
  ------------------
  |  Branch (2090:5): [True: 0, False: 0]
  ------------------
 2091|      0|      return VUID_WRAP(VUID-StandaloneSpirv-PhysicalStorageBuffer64-04708);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 2092|      0|    case 4710:
  ------------------
  |  Branch (2092:5): [True: 0, False: 0]
  ------------------
 2093|      0|      return VUID_WRAP(VUID-StandaloneSpirv-PhysicalStorageBuffer64-04710);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 2094|      0|    case 4711:
  ------------------
  |  Branch (2094:5): [True: 0, False: 0]
  ------------------
 2095|      0|      return VUID_WRAP(VUID-StandaloneSpirv-OpTypeForwardPointer-04711);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 2096|      0|    case 4730:
  ------------------
  |  Branch (2096:5): [True: 0, False: 0]
  ------------------
 2097|      0|      return VUID_WRAP(VUID-StandaloneSpirv-OpAtomicStore-04730);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 2098|      0|    case 4731:
  ------------------
  |  Branch (2098:5): [True: 0, False: 0]
  ------------------
 2099|      0|      return VUID_WRAP(VUID-StandaloneSpirv-OpAtomicLoad-04731);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 2100|      0|    case 4732:
  ------------------
  |  Branch (2100:5): [True: 0, False: 0]
  ------------------
 2101|      0|      return VUID_WRAP(VUID-StandaloneSpirv-OpMemoryBarrier-04732);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 2102|      0|    case 4733:
  ------------------
  |  Branch (2102:5): [True: 0, False: 0]
  ------------------
 2103|      0|      return VUID_WRAP(VUID-StandaloneSpirv-OpMemoryBarrier-04733);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 2104|      0|    case 4734:
  ------------------
  |  Branch (2104:5): [True: 0, False: 0]
  ------------------
 2105|      0|      return VUID_WRAP(VUID-StandaloneSpirv-OpVariable-04734);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 2106|      0|    case 4744:
  ------------------
  |  Branch (2106:5): [True: 0, False: 0]
  ------------------
 2107|      0|      return VUID_WRAP(VUID-StandaloneSpirv-Flat-04744);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 2108|      0|    case 4777:
  ------------------
  |  Branch (2108:5): [True: 0, False: 0]
  ------------------
 2109|      0|      return VUID_WRAP(VUID-StandaloneSpirv-OpImage-04777);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 2110|      0|    case 4780:
  ------------------
  |  Branch (2110:5): [True: 0, False: 0]
  ------------------
 2111|      0|      return VUID_WRAP(VUID-StandaloneSpirv-Result-04780);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 2112|      0|    case 4781:
  ------------------
  |  Branch (2112:5): [True: 0, False: 0]
  ------------------
 2113|      0|      return VUID_WRAP(VUID-StandaloneSpirv-Base-04781);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 2114|      0|    case 4915:
  ------------------
  |  Branch (2114:5): [True: 0, False: 0]
  ------------------
 2115|      0|      return VUID_WRAP(VUID-StandaloneSpirv-Location-04915);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 2116|      0|    case 4916:
  ------------------
  |  Branch (2116:5): [True: 0, False: 0]
  ------------------
 2117|      0|      return VUID_WRAP(VUID-StandaloneSpirv-Location-04916);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 2118|      0|    case 4917:
  ------------------
  |  Branch (2118:5): [True: 0, False: 0]
  ------------------
 2119|      0|      return VUID_WRAP(VUID-StandaloneSpirv-Location-04917);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 2120|      0|    case 4918:
  ------------------
  |  Branch (2120:5): [True: 0, False: 0]
  ------------------
 2121|      0|      return VUID_WRAP(VUID-StandaloneSpirv-Location-04918);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 2122|      0|    case 4919:
  ------------------
  |  Branch (2122:5): [True: 0, False: 0]
  ------------------
 2123|      0|      return VUID_WRAP(VUID-StandaloneSpirv-Location-04919);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 2124|      0|    case 4920:
  ------------------
  |  Branch (2124:5): [True: 0, False: 0]
  ------------------
 2125|      0|      return VUID_WRAP(VUID-StandaloneSpirv-Component-04920);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 2126|      0|    case 4921:
  ------------------
  |  Branch (2126:5): [True: 0, False: 0]
  ------------------
 2127|      0|      return VUID_WRAP(VUID-StandaloneSpirv-Component-04921);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 2128|      0|    case 4922:
  ------------------
  |  Branch (2128:5): [True: 0, False: 0]
  ------------------
 2129|      0|      return VUID_WRAP(VUID-StandaloneSpirv-Component-04922);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 2130|      0|    case 4923:
  ------------------
  |  Branch (2130:5): [True: 0, False: 0]
  ------------------
 2131|      0|      return VUID_WRAP(VUID-StandaloneSpirv-Component-04923);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 2132|      0|    case 4924:
  ------------------
  |  Branch (2132:5): [True: 0, False: 0]
  ------------------
 2133|      0|      return VUID_WRAP(VUID-StandaloneSpirv-Component-04924);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 2134|      0|    case 6201:
  ------------------
  |  Branch (2134:5): [True: 0, False: 0]
  ------------------
 2135|      0|      return VUID_WRAP(VUID-StandaloneSpirv-Flat-06201);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 2136|      0|    case 6202:
  ------------------
  |  Branch (2136:5): [True: 0, False: 0]
  ------------------
 2137|      0|      return VUID_WRAP(VUID-StandaloneSpirv-Flat-06202);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 2138|      0|    case 6214:
  ------------------
  |  Branch (2138:5): [True: 0, False: 0]
  ------------------
 2139|      0|      return VUID_WRAP(VUID-StandaloneSpirv-OpTypeImage-06214);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 2140|      0|    case 6491:
  ------------------
  |  Branch (2140:5): [True: 0, False: 0]
  ------------------
 2141|      0|      return VUID_WRAP(VUID-StandaloneSpirv-DescriptorSet-06491);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 2142|      0|    case 6671:
  ------------------
  |  Branch (2142:5): [True: 0, False: 0]
  ------------------
 2143|      0|      return VUID_WRAP(VUID-StandaloneSpirv-OpTypeSampledImage-06671);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 2144|      0|    case 6672:
  ------------------
  |  Branch (2144:5): [True: 0, False: 0]
  ------------------
 2145|      0|      return VUID_WRAP(VUID-StandaloneSpirv-Location-06672);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 2146|      0|    case 6674:
  ------------------
  |  Branch (2146:5): [True: 0, False: 0]
  ------------------
 2147|      0|      return VUID_WRAP(VUID-StandaloneSpirv-OpEntryPoint-06674);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 2148|      0|    case 6675:
  ------------------
  |  Branch (2148:5): [True: 0, False: 0]
  ------------------
 2149|      0|      return VUID_WRAP(VUID-StandaloneSpirv-PushConstant-06675);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 2150|      0|    case 6676:
  ------------------
  |  Branch (2150:5): [True: 0, False: 0]
  ------------------
 2151|      0|      return VUID_WRAP(VUID-StandaloneSpirv-Uniform-06676);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 2152|      0|    case 6677:
  ------------------
  |  Branch (2152:5): [True: 0, False: 0]
  ------------------
 2153|      0|      return VUID_WRAP(VUID-StandaloneSpirv-UniformConstant-06677);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 2154|      0|    case 6678:
  ------------------
  |  Branch (2154:5): [True: 0, False: 0]
  ------------------
 2155|      0|      return VUID_WRAP(VUID-StandaloneSpirv-InputAttachmentIndex-06678);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 2156|      0|    case 6777:
  ------------------
  |  Branch (2156:5): [True: 0, False: 0]
  ------------------
 2157|      0|      return VUID_WRAP(VUID-StandaloneSpirv-PerVertexKHR-06777);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 2158|      0|    case 6778:
  ------------------
  |  Branch (2158:5): [True: 0, False: 0]
  ------------------
 2159|      0|      return VUID_WRAP(VUID-StandaloneSpirv-Input-06778);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 2160|      0|    case 6807:
  ------------------
  |  Branch (2160:5): [True: 0, False: 0]
  ------------------
 2161|      0|      return VUID_WRAP(VUID-StandaloneSpirv-Uniform-06807);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 2162|      0|    case 6808:
  ------------------
  |  Branch (2162:5): [True: 0, False: 0]
  ------------------
 2163|      0|      return VUID_WRAP(VUID-StandaloneSpirv-PushConstant-06808);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 2164|      0|    case 6925:
  ------------------
  |  Branch (2164:5): [True: 0, False: 0]
  ------------------
 2165|      0|      return VUID_WRAP(VUID-StandaloneSpirv-Uniform-06925);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 2166|      0|    case 6997:
  ------------------
  |  Branch (2166:5): [True: 0, False: 0]
  ------------------
 2167|      0|      return VUID_WRAP(VUID-StandaloneSpirv-SubgroupVoteKHR-06997);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 2168|      0|    case 7102:
  ------------------
  |  Branch (2168:5): [True: 0, False: 0]
  ------------------
 2169|      0|      return VUID_WRAP(VUID-StandaloneSpirv-MeshEXT-07102);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 2170|      0|    case 7320:
  ------------------
  |  Branch (2170:5): [True: 0, False: 0]
  ------------------
 2171|      0|      return VUID_WRAP(VUID-StandaloneSpirv-ExecutionModel-07320);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 2172|      0|    case 7290:
  ------------------
  |  Branch (2172:5): [True: 0, False: 0]
  ------------------
 2173|      0|      return VUID_WRAP(VUID-StandaloneSpirv-Input-07290);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 2174|      0|    case 7650:
  ------------------
  |  Branch (2174:5): [True: 0, False: 0]
  ------------------
 2175|      0|      return VUID_WRAP(VUID-StandaloneSpirv-Base-07650);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 2176|      0|    case 7651:
  ------------------
  |  Branch (2176:5): [True: 0, False: 0]
  ------------------
 2177|      0|      return VUID_WRAP(VUID-StandaloneSpirv-Base-07651);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 2178|      0|    case 7652:
  ------------------
  |  Branch (2178:5): [True: 0, False: 0]
  ------------------
 2179|      0|      return VUID_WRAP(VUID-StandaloneSpirv-Base-07652);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 2180|      0|    case 7703:
  ------------------
  |  Branch (2180:5): [True: 0, False: 0]
  ------------------
 2181|      0|      return VUID_WRAP(VUID-StandaloneSpirv-Component-07703);
  ------------------
  |  | 1584|      0|#define VUID_WRAP(vuid) "[" #vuid "] "
  ------------------
 2182|      0|    default:
  ------------------
  |  Branch (2182:5): [True: 0, False: 0]
  ------------------
 2183|      0|      return "";  // unknown id
 2184|      0|  }
 2185|       |  // clang-format on
 2186|      0|}
validation_state.cpp:_ZN8spvtools3val12_GLOBAL__N_19setHeaderEPv16spv_endianness_tjjjjj:
  119|  8.11k|                       uint32_t) {
  120|  8.11k|  ValidationState_t& vstate =
  121|  8.11k|      *(reinterpret_cast<ValidationState_t*>(user_data));
  122|  8.11k|  vstate.setIdBound(id_bound);
  123|  8.11k|  vstate.setGenerator(generator);
  124|  8.11k|  vstate.setVersion(version);
  125|       |
  126|  8.11k|  return SPV_SUCCESS;
  127|  8.11k|}
validation_state.cpp:_ZN8spvtools3val12_GLOBAL__N_117CountInstructionsEPvPK24spv_parsed_instruction_t:
  107|   506k|                               const spv_parsed_instruction_t* inst) {
  108|   506k|  ValidationState_t& _ = *(reinterpret_cast<ValidationState_t*>(user_data));
  109|   506k|  if (spv::Op(inst->opcode) == spv::Op::OpFunction) {
  ------------------
  |  Branch (109:7): [True: 5.00k, False: 501k]
  ------------------
  110|  5.00k|    _.increment_total_functions();
  111|  5.00k|  }
  112|   506k|  _.increment_total_instructions();
  113|       |
  114|   506k|  return SPV_SUCCESS;
  115|   506k|}
validation_state.cpp:_ZN8spvtools3val12_GLOBAL__N_133UpdateFeaturesBasedOnSpirvVersionEPNS0_17ValidationState_t7FeatureEj:
  131|  8.24k|                                       uint32_t version) {
  132|  8.24k|  assert(features);
  133|  8.24k|  if (version >= SPV_SPIRV_VERSION_WORD(1, 4)) {
  ------------------
  |  |   26|  8.24k|  ((uint32_t(uint8_t(MAJOR)) << 16) | (uint32_t(uint8_t(MINOR)) << 8))
  ------------------
  |  Branch (133:7): [True: 18, False: 8.22k]
  ------------------
  134|     18|    features->select_between_composites = true;
  135|     18|    features->copy_memory_permits_two_memory_accesses = true;
  136|     18|    features->uconvert_spec_constant_op = true;
  137|     18|    features->nonwritable_var_in_function_or_private = true;
  138|     18|  }
  139|  8.24k|}
validation_state.cpp:_ZN8spvtools3val12_GLOBAL__N_124InstructionLayoutSectionENS0_19ModuleLayoutSectionEN3spv2OpE:
   34|   520k|    ModuleLayoutSection current_section, spv::Op op) {
   35|       |  // See Section 2.4
   36|   520k|  if (spvOpcodeGeneratesType(op) || spvOpcodeIsConstant(op))
  ------------------
  |  Branch (36:7): [True: 83.9k, False: 436k]
  |  Branch (36:37): [True: 19.5k, False: 417k]
  ------------------
   37|   103k|    return kLayoutTypes;
   38|       |
   39|   417k|  switch (op) {
   40|  7.02k|    case spv::Op::OpCapability:
  ------------------
  |  Branch (40:5): [True: 7.02k, False: 410k]
  ------------------
   41|  7.02k|      return kLayoutCapabilities;
   42|  3.44k|    case spv::Op::OpExtension:
  ------------------
  |  Branch (42:5): [True: 3.44k, False: 413k]
  ------------------
   43|  3.44k|      return kLayoutExtensions;
   44|  5.24k|    case spv::Op::OpExtInstImport:
  ------------------
  |  Branch (44:5): [True: 5.24k, False: 412k]
  ------------------
   45|  5.24k|      return kLayoutExtInstImport;
   46|  34.2k|    case spv::Op::OpMemoryModel:
  ------------------
  |  Branch (46:5): [True: 34.2k, False: 383k]
  ------------------
   47|  34.2k|      return kLayoutMemoryModel;
   48|  11.5k|    case spv::Op::OpEntryPoint:
  ------------------
  |  Branch (48:5): [True: 11.5k, False: 405k]
  ------------------
   49|  11.5k|      return kLayoutEntryPoint;
   50|  8.03k|    case spv::Op::OpExecutionMode:
  ------------------
  |  Branch (50:5): [True: 8.03k, False: 409k]
  ------------------
   51|  8.03k|    case spv::Op::OpExecutionModeId:
  ------------------
  |  Branch (51:5): [True: 0, False: 417k]
  ------------------
   52|  8.03k|      return kLayoutExecutionMode;
   53|     38|    case spv::Op::OpSourceContinued:
  ------------------
  |  Branch (53:5): [True: 38, False: 417k]
  ------------------
   54|  1.61k|    case spv::Op::OpSource:
  ------------------
  |  Branch (54:5): [True: 1.57k, False: 415k]
  ------------------
   55|  1.92k|    case spv::Op::OpSourceExtension:
  ------------------
  |  Branch (55:5): [True: 312, False: 417k]
  ------------------
   56|  2.05k|    case spv::Op::OpString:
  ------------------
  |  Branch (56:5): [True: 130, False: 417k]
  ------------------
   57|  2.05k|      return kLayoutDebug1;
   58|  3.64k|    case spv::Op::OpName:
  ------------------
  |  Branch (58:5): [True: 3.64k, False: 413k]
  ------------------
   59|  4.09k|    case spv::Op::OpMemberName:
  ------------------
  |  Branch (59:5): [True: 450, False: 416k]
  ------------------
   60|  4.09k|      return kLayoutDebug2;
   61|      0|    case spv::Op::OpModuleProcessed:
  ------------------
  |  Branch (61:5): [True: 0, False: 417k]
  ------------------
   62|      0|      return kLayoutDebug3;
   63|  23.8k|    case spv::Op::OpDecorate:
  ------------------
  |  Branch (63:5): [True: 23.8k, False: 393k]
  ------------------
   64|  26.4k|    case spv::Op::OpMemberDecorate:
  ------------------
  |  Branch (64:5): [True: 2.57k, False: 414k]
  ------------------
   65|  28.2k|    case spv::Op::OpGroupDecorate:
  ------------------
  |  Branch (65:5): [True: 1.85k, False: 415k]
  ------------------
   66|  28.8k|    case spv::Op::OpGroupMemberDecorate:
  ------------------
  |  Branch (66:5): [True: 553, False: 416k]
  ------------------
   67|  31.2k|    case spv::Op::OpDecorationGroup:
  ------------------
  |  Branch (67:5): [True: 2.42k, False: 414k]
  ------------------
   68|  31.2k|    case spv::Op::OpDecorateId:
  ------------------
  |  Branch (68:5): [True: 17, False: 417k]
  ------------------
   69|  31.3k|    case spv::Op::OpDecorateStringGOOGLE:
  ------------------
  |  Branch (69:5): [True: 46, False: 417k]
  ------------------
   70|  31.3k|    case spv::Op::OpMemberDecorateStringGOOGLE:
  ------------------
  |  Branch (70:5): [True: 7, False: 417k]
  ------------------
   71|  31.3k|      return kLayoutAnnotations;
   72|    949|    case spv::Op::OpTypeForwardPointer:
  ------------------
  |  Branch (72:5): [True: 949, False: 416k]
  ------------------
   73|    949|      return kLayoutTypes;
   74|  8.72k|    case spv::Op::OpVariable:
  ------------------
  |  Branch (74:5): [True: 8.72k, False: 408k]
  ------------------
   75|  8.72k|      if (current_section == kLayoutTypes) return kLayoutTypes;
  ------------------
  |  Branch (75:11): [True: 2.94k, False: 5.77k]
  ------------------
   76|  5.77k|      return kLayoutFunctionDefinitions;
   77|  3.43k|    case spv::Op::OpExtInst:
  ------------------
  |  Branch (77:5): [True: 3.43k, False: 413k]
  ------------------
   78|       |      // spv::Op::OpExtInst is only allowed in types section for certain
   79|       |      // extended instruction sets. This will be checked separately.
   80|  3.43k|      if (current_section == kLayoutTypes) return kLayoutTypes;
  ------------------
  |  Branch (80:11): [True: 5, False: 3.43k]
  ------------------
   81|  3.43k|      return kLayoutFunctionDefinitions;
   82|    323|    case spv::Op::OpLine:
  ------------------
  |  Branch (82:5): [True: 323, False: 416k]
  ------------------
   83|  13.7k|    case spv::Op::OpNoLine:
  ------------------
  |  Branch (83:5): [True: 13.4k, False: 403k]
  ------------------
   84|  14.2k|    case spv::Op::OpUndef:
  ------------------
  |  Branch (84:5): [True: 441, False: 416k]
  ------------------
   85|  14.2k|      if (current_section == kLayoutTypes) return kLayoutTypes;
  ------------------
  |  Branch (85:11): [True: 12.3k, False: 1.83k]
  ------------------
   86|  1.83k|      return kLayoutFunctionDefinitions;
   87|  15.4k|    case spv::Op::OpFunction:
  ------------------
  |  Branch (87:5): [True: 15.4k, False: 401k]
  ------------------
   88|  16.2k|    case spv::Op::OpFunctionParameter:
  ------------------
  |  Branch (88:5): [True: 813, False: 416k]
  ------------------
   89|  20.7k|    case spv::Op::OpFunctionEnd:
  ------------------
  |  Branch (89:5): [True: 4.54k, False: 412k]
  ------------------
   90|  20.7k|      if (current_section == kLayoutFunctionDeclarations)
  ------------------
  |  Branch (90:11): [True: 8.57k, False: 12.2k]
  ------------------
   91|  8.57k|        return kLayoutFunctionDeclarations;
   92|  12.2k|      return kLayoutFunctionDefinitions;
   93|      6|    case spv::Op::OpSamplerImageAddressingModeNV:
  ------------------
  |  Branch (93:5): [True: 6, False: 417k]
  ------------------
   94|      6|      return kLayoutSamplerImageAddressMode;
   95|   262k|    default:
  ------------------
  |  Branch (95:5): [True: 262k, False: 155k]
  ------------------
   96|   262k|      break;
   97|   417k|  }
   98|   262k|  return kLayoutFunctionDefinitions;
   99|   417k|}
validation_state.cpp:_ZN8spvtools3val12_GLOBAL__N_128IsInstructionInLayoutSectionENS0_19ModuleLayoutSectionEN3spv2OpE:
  101|   458k|bool IsInstructionInLayoutSection(ModuleLayoutSection layout, spv::Op op) {
  102|   458k|  return layout == InstructionLayoutSection(layout, op);
  103|   458k|}
validation_state.cpp:_ZZN8spvtools3val17ValidationState_tC1EPK13spv_context_tPK23spv_validator_options_tPKjmjENK3$_0clE19spv_message_level_tPKcRK14spv_position_tSD_:
  205|  1.19k|                                   const spv_position_t&, const char*) {};
validation_state.cpp:_ZZN8spvtools3val17ValidationState_t18RegisterCapabilityEN3spv10CapabilityEENK3$_1clES3_:
  369|  9.26k|        .ForEach([this](spv::Capability c) { RegisterCapability(c); });
validation_state.cpp:_ZZNK8spvtools3val17ValidationState_t27ContainsSizedIntOrFloatTypeEjN3spv2OpEjENK4$_12clEPKNS0_11InstructionE:
 1524|   280k|  const auto f = [type, width](const Instruction* inst) {
 1525|   280k|    if (inst->opcode() == type) {
  ------------------
  |  Branch (1525:9): [True: 114k, False: 166k]
  ------------------
 1526|   114k|      return inst->GetOperandAs<uint32_t>(1u) == width;
 1527|   114k|    }
 1528|   166k|    return false;
 1529|   280k|  };
validation_state.cpp:_ZZNK8spvtools3val17ValidationState_t20ContainsRuntimeArrayEjENK4$_13clEPKNS0_11InstructionE:
 1546|  19.1k|  const auto f = [](const Instruction* inst) {
 1547|  19.1k|    return inst->opcode() == spv::Op::OpTypeRuntimeArray;
 1548|  19.1k|  };

_ZNK8spvtools3val17ValidationState_t7optionsEv:
  120|  75.1k|  spv_const_validator_options options() const { return options_; }
_ZNK8spvtools3val17ValidationState_t20ordered_instructionsEv:
  471|  1.28M|  const std::vector<Instruction>& ordered_instructions() const {
  472|  1.28M|    return ordered_instructions_;
  473|  1.28M|  }
_ZN8spvtools3val17ValidationState_t18RegisterEntryPointEjN3spv14ExecutionModelEONS1_21EntryPointDescriptionE:
  222|  3.33k|                          EntryPointDescription&& desc) {
  223|  3.33k|    entry_points_.push_back(id);
  224|  3.33k|    entry_point_to_execution_models_[id].insert(execution_model);
  225|  3.33k|    entry_point_descriptions_[id].emplace_back(desc);
  226|  3.33k|  }
_ZN8spvtools3val17ValidationState_t21AddFunctionCallTargetEj:
  290|    700|  void AddFunctionCallTarget(const uint32_t id) {
  291|    700|    function_call_targets_.insert(id);
  292|    700|    current_function().AddFunctionCallTarget(id);
  293|    700|  }
_ZNK8spvtools3val17ValidationState_t26has_memory_model_specifiedEv:
  346|  10.5k|  bool has_memory_model_specified() const {
  347|  10.5k|    return addressing_model_ != spv::AddressingModel::Max &&
  ------------------
  |  Branch (347:12): [True: 4.94k, False: 5.57k]
  ------------------
  348|  10.5k|           memory_model_ != spv::MemoryModel::Max;
  ------------------
  |  Branch (348:12): [True: 4.94k, False: 0]
  ------------------
  349|  10.5k|  }
_ZNK8spvtools3val17ValidationState_t13HasCapabilityEN3spv10CapabilityE:
  319|   772k|  bool HasCapability(spv::Capability cap) const {
  320|   772k|    return module_capabilities_.Contains(cap);
  321|   772k|  }
_ZNK8spvtools3val17ValidationState_t12entry_pointsEv:
  229|  11.9k|  const std::vector<uint32_t>& entry_points() const { return entry_points_; }
_ZN8spvtools3val17ValidationState_t20IsFunctionCallTargetEj:
  296|  1.49k|  bool IsFunctionCallTarget(const uint32_t id) {
  297|  1.49k|    return (function_call_targets_.find(id) != function_call_targets_.end());
  298|  1.49k|  }
_ZNK8spvtools3val17ValidationState_t7contextEv:
  117|   206k|  spv_const_context context() const { return context_; }
_ZN8spvtools3val17ValidationState_t12setGeneratorEj:
  123|  8.11k|  void setGenerator(uint32_t gen) { generator_ = gen; }
_ZN8spvtools3val17ValidationState_t10setVersionEj:
  129|  8.11k|  void setVersion(uint32_t ver) { version_ = ver; }
_ZNK8spvtools3val17ValidationState_t7versionEv:
  132|   466k|  uint32_t version() const { return version_; }
_ZN8spvtools3val17ValidationState_t28increment_total_instructionsEv:
  171|   506k|  void increment_total_instructions() { total_instructions_++; }
_ZN8spvtools3val17ValidationState_t25increment_total_functionsEv:
  174|  5.00k|  void increment_total_functions() { total_functions_++; }
_ZN8spvtools3val17ValidationState_t34RegisterExecutionModeForEntryPointEjN3spv13ExecutionModeE:
  239|  4.17k|                                          spv::ExecutionMode execution_mode) {
  240|  4.17k|    entry_point_to_execution_modes_[entry_point].insert(execution_mode);
  241|  4.17k|  }
_ZN8spvtools3val17ValidationState_t24entry_point_descriptionsEj:
  245|  1.08k|      uint32_t entry_point) {
  246|  1.08k|    return entry_point_descriptions_.at(entry_point);
  247|  1.08k|  }
_ZNK8spvtools3val17ValidationState_t18GetExecutionModelsEj:
  252|  2.03k|      uint32_t entry_point) const {
  253|  2.03k|    const auto it = entry_point_to_execution_models_.find(entry_point);
  254|  2.03k|    if (it == entry_point_to_execution_models_.end()) {
  ------------------
  |  Branch (254:9): [True: 0, False: 2.03k]
  ------------------
  255|      0|      assert(0);
  256|      0|      return nullptr;
  257|      0|    }
  258|  2.03k|    return &it->second;
  259|  2.03k|  }
_ZNK8spvtools3val17ValidationState_t17GetExecutionModesEj:
  264|  1.83k|      uint32_t entry_point) const {
  265|  1.83k|    const auto it = entry_point_to_execution_modes_.find(entry_point);
  266|  1.83k|    if (it == entry_point_to_execution_modes_.end()) {
  ------------------
  |  Branch (266:9): [True: 455, False: 1.37k]
  ------------------
  267|    455|      return nullptr;
  268|    455|    }
  269|  1.37k|    return &it->second;
  270|  1.83k|  }
_ZNK8spvtools3val17ValidationState_t12HasExtensionENS_9ExtensionE:
  330|  23.7k|  bool HasExtension(Extension ext) const {
  331|  23.7k|    return module_extensions_.Contains(ext);
  332|  23.7k|  }
_ZNK8spvtools3val17ValidationState_t7grammarEv:
  379|  1.37M|  const AssemblyGrammar& grammar() const { return grammar_; }
_ZN8spvtools3val17ValidationState_t23RegisterDecorationForIdEjRKNS0_10DecorationE:
  392|  14.0k|  void RegisterDecorationForId(uint32_t id, const Decoration& dec) {
  393|  14.0k|    auto& dec_list = id_decorations_[id];
  394|  14.0k|    dec_list.insert(dec);
  395|  14.0k|  }
_ZN8spvtools3val17ValidationState_t14id_decorationsEj:
  421|  18.3k|  std::set<Decoration>& id_decorations(uint32_t id) {
  422|  18.3k|    return id_decorations_[id];
  423|  18.3k|  }
_ZN8spvtools3val17ValidationState_t21id_member_decorationsEjj:
  431|    467|                                             uint32_t member_index) {
  432|    467|    const auto& decorations = id_decorations_[id];
  433|       |
  434|       |    // The decorations are sorted by member_index, so this look up will give the
  435|       |    // exact range of decorations for this member index.
  436|    467|    Decoration min_decoration((spv::Decoration)0, {}, member_index);
  437|    467|    Decoration max_decoration(spv::Decoration::Max, {}, member_index);
  438|       |
  439|    467|    FieldDecorationsIter result;
  440|    467|    result.begin = decorations.lower_bound(min_decoration);
  441|    467|    result.end = decorations.upper_bound(max_decoration);
  442|       |
  443|    467|    return result;
  444|    467|  }
_ZNK8spvtools3val17ValidationState_t14id_decorationsEv:
  447|  1.36k|  const std::map<uint32_t, std::set<Decoration>>& id_decorations() const {
  448|  1.36k|    return id_decorations_;
  449|  1.36k|  }
_ZN8spvtools3val17ValidationState_t13HasDecorationEjN3spv10DecorationE:
  453|    650|  bool HasDecoration(uint32_t id, spv::Decoration dec) {
  454|    650|    const auto& decorations = id_decorations_.find(id);
  455|    650|    if (decorations == id_decorations_.end()) return false;
  ------------------
  |  Branch (455:9): [True: 55, False: 595]
  ------------------
  456|       |
  457|    595|    return std::any_of(
  458|    595|        decorations->second.begin(), decorations->second.end(),
  459|    595|        [dec](const Decoration& d) { return dec == d.dec_type(); });
  460|    650|  }
_ZNK8spvtools3val17ValidationState_t15all_definitionsEv:
  476|     19|  const std::unordered_map<uint32_t, Instruction*>& all_definitions() const {
  477|     19|    return all_definitions_;
  478|     19|  }
_ZN8spvtools3val17ValidationState_t11global_varsEv:
  493|  1.02k|  std::unordered_set<uint32_t>& global_vars() { return global_vars_; }
_ZN8spvtools3val17ValidationState_t15num_global_varsEv:
  499|  2.94k|  size_t num_global_vars() { return global_vars_.size(); }
_ZN8spvtools3val17ValidationState_t14num_local_varsEv:
  502|  5.77k|  size_t num_local_vars() { return local_vars_.size(); }
_ZN8spvtools3val17ValidationState_t22registerGlobalVariableEj:
  505|  2.94k|  void registerGlobalVariable(const uint32_t id) { global_vars_.insert(id); }
_ZN8spvtools3val17ValidationState_t21registerLocalVariableEj:
  508|  5.77k|  void registerLocalVariable(const uint32_t id) { local_vars_.insert(id); }
_ZN8spvtools3val17ValidationState_t24set_struct_nesting_depthEjj:
  523|  3.97k|  void set_struct_nesting_depth(uint32_t id, uint32_t depth) {
  524|  3.97k|    struct_nesting_depth_[id] = depth;
  525|  3.97k|  }
_ZN8spvtools3val17ValidationState_t20struct_nesting_depthEj:
  528|    301|  uint32_t struct_nesting_depth(uint32_t id) {
  529|    301|    return struct_nesting_depth_[id];
  530|    301|  }
_ZN8spvtools3val17ValidationState_t36SetHasNestedBlockOrBufferBlockStructEjb:
  534|  3.32k|  void SetHasNestedBlockOrBufferBlockStruct(uint32_t id, bool has) {
  535|  3.32k|    struct_has_nested_blockorbufferblock_struct_[id] = has;
  536|  3.32k|  }
_ZN8spvtools3val17ValidationState_t36GetHasNestedBlockOrBufferBlockStructEj:
  540|  3.58k|  bool GetHasNestedBlockOrBufferBlockStruct(uint32_t id) {
  541|  3.58k|    return struct_has_nested_blockorbufferblock_struct_[id];
  542|  3.58k|  }
_ZN8spvtools3val17ValidationState_t35RegisterStructTypeWithBuiltInMemberEj:
  545|     22|  void RegisterStructTypeWithBuiltInMember(uint32_t id) {
  546|     22|    builtin_structs_.insert(id);
  547|     22|  }
_ZNK8spvtools3val17ValidationState_t29IsStructTypeWithBuiltInMemberEj:
  550|    298|  bool IsStructTypeWithBuiltInMember(uint32_t id) const {
  551|    298|    return (builtin_structs_.find(id) != builtin_structs_.end());
  552|    298|  }
_ZNK8spvtools3val17ValidationState_t8featuresEv:
  555|   101k|  const Feature& features() const { return features_; }
_ZNK8spvtools3val17ValidationState_t23IsPointerToUniformBlockEj:
  661|     10|  bool IsPointerToUniformBlock(uint32_t type_id) const {
  662|     10|    return pointer_to_uniform_block_.find(type_id) !=
  663|     10|           pointer_to_uniform_block_.cend();
  664|     10|  }
_ZN8spvtools3val17ValidationState_t29RegisterPointerToUniformBlockEj:
  666|    124|  void RegisterPointerToUniformBlock(uint32_t type_id) {
  667|    124|    pointer_to_uniform_block_.insert(type_id);
  668|    124|  }
_ZN8spvtools3val17ValidationState_t29RegisterStructForUniformBlockEj:
  677|    124|  void RegisterStructForUniformBlock(uint32_t type_id) {
  678|    124|    struct_for_uniform_block_.insert(type_id);
  679|    124|  }
_ZNK8spvtools3val17ValidationState_t24IsPointerToStorageBufferEj:
  684|     10|  bool IsPointerToStorageBuffer(uint32_t type_id) const {
  685|     10|    return pointer_to_storage_buffer_.find(type_id) !=
  686|     10|           pointer_to_storage_buffer_.cend();
  687|     10|  }
_ZN8spvtools3val17ValidationState_t30RegisterPointerToStorageBufferEj:
  689|     51|  void RegisterPointerToStorageBuffer(uint32_t type_id) {
  690|     51|    pointer_to_storage_buffer_.insert(type_id);
  691|     51|  }
_ZN8spvtools3val17ValidationState_t30RegisterStructForStorageBufferEj:
  700|     51|  void RegisterStructForStorageBuffer(uint32_t type_id) {
  701|     51|    struct_for_storage_buffer_.insert(type_id);
  702|     51|  }
_ZNK8spvtools3val17ValidationState_t23IsPointerToStorageImageEj:
  706|     10|  bool IsPointerToStorageImage(uint32_t type_id) const {
  707|     10|    return pointer_to_storage_image_.find(type_id) !=
  708|     10|           pointer_to_storage_image_.cend();
  709|     10|  }
_ZN8spvtools3val17ValidationState_t29RegisterPointerToStorageImageEj:
  711|      8|  void RegisterPointerToStorageImage(uint32_t type_id) {
  712|      8|    pointer_to_storage_image_.insert(type_id);
  713|      8|  }
_ZN8spvtools3val17ValidationState_t19SpvDecorationStringEj:
  728|     79|  std::string SpvDecorationString(uint32_t decoration) {
  729|     79|    spv_operand_desc desc = nullptr;
  730|     79|    if (grammar_.lookupOperand(SPV_OPERAND_TYPE_DECORATION, decoration,
  ------------------
  |  Branch (730:9): [True: 0, False: 79]
  ------------------
  731|     79|                               &desc) != SPV_SUCCESS) {
  732|      0|      return std::string("Unknown");
  733|      0|    }
  734|     79|    return std::string(desc->name);
  735|     79|  }
_ZN8spvtools3val17ValidationState_t19SpvDecorationStringEN3spv10DecorationE:
  736|     79|  std::string SpvDecorationString(spv::Decoration decoration) {
  737|     79|    return SpvDecorationString(uint32_t(decoration));
  738|     79|  }
_ZN8spvtools3val17ValidationState_t24RegisterDecorationsForIdINSt3__121__tree_const_iteratorINS0_10DecorationEPNS3_11__tree_nodeIS5_PvEElEEEEvjT_SB_:
  399|  1.60k|  void RegisterDecorationsForId(uint32_t id, InputIt begin, InputIt end) {
  400|  1.60k|    std::set<Decoration>& cur_decs = id_decorations_[id];
  401|  1.60k|    cur_decs.insert(begin, end);
  402|  1.60k|  }
_ZN8spvtools3val17ValidationState_t34RegisterDecorationsForStructMemberINSt3__121__tree_const_iteratorINS0_10DecorationEPNS3_11__tree_nodeIS5_PvEElEEEEvjjT_SB_:
  409|    304|                                          InputIt end) {
  410|    304|    std::set<Decoration>& cur_decs = id_decorations_[struct_id];
  411|  1.83k|    for (InputIt iter = begin; iter != end; ++iter) {
  ------------------
  |  Branch (411:32): [True: 1.53k, False: 304]
  ------------------
  412|  1.53k|      Decoration dec = *iter;
  413|  1.53k|      dec.set_struct_member_index(member_index);
  414|  1.53k|      cur_decs.insert(dec);
  415|  1.53k|    }
  416|    304|  }
_ZZN8spvtools3val17ValidationState_t13HasDecorationEjN3spv10DecorationEENKUlRKNS0_10DecorationEE_clES6_:
  459|  1.32k|        [dec](const Decoration& d) { return dec == d.dec_type(); });

_ZN8spvtools7fuzzers15RandomGeneratorC2Em:
   84|  8.24k|RandomGenerator::RandomGenerator(uint64_t seed) : engine_(seed) {}
_ZN8spvtools7fuzzers15RandomGeneratorC2EPKhm:
   86|  8.24k|RandomGenerator::RandomGenerator(const uint8_t* data, size_t size) {
   87|  8.24k|  RandomGenerator(RandomGenerator::CalculateSeed(data, size));
   88|  8.24k|}
_ZN8spvtools7fuzzers15RandomGenerator12GetTargetEnvEv:
   90|  8.24k|spv_target_env RandomGenerator::GetTargetEnv() {
   91|  8.24k|  spv_target_env result;
   92|       |
   93|       |  // Need to check that the generated value isn't for a deprecated target env.
   94|  8.24k|  do {
   95|  8.24k|    result = static_cast<spv_target_env>(
   96|  8.24k|        RandomUInt(&engine_, 0u, static_cast<unsigned int>(SPV_ENV_MAX)));
   97|  8.24k|  } while (!spvIsValidEnv(result));
  ------------------
  |  Branch (97:12): [True: 0, False: 8.24k]
  ------------------
   98|       |
   99|  8.24k|  return result;
  100|  8.24k|}
_ZN8spvtools7fuzzers15RandomGenerator13CalculateSeedEPKhm:
  111|  8.24k|uint64_t RandomGenerator::CalculateSeed(const uint8_t* data, size_t size) {
  112|  8.24k|  assert(data != nullptr && "|data| must be !nullptr");
  113|       |
  114|       |  // Number of bytes we want to skip at the start of data for the hash.
  115|       |  // Fewer bytes may be skipped when `size` is small.
  116|       |  // Has lower precedence than kHashDesiredMinBytes.
  117|      0|  static const int64_t kHashDesiredLeadingSkipBytes = 5;
  118|       |  // Minimum number of bytes we want to use in the hash.
  119|       |  // Used for short buffers.
  120|  8.24k|  static const int64_t kHashDesiredMinBytes = 4;
  121|       |  // Maximum number of bytes we want to use in the hash.
  122|  8.24k|  static const int64_t kHashDesiredMaxBytes = 32;
  123|  8.24k|  int64_t size_i64 = static_cast<int64_t>(size);
  124|  8.24k|  int64_t hash_begin_i64 =
  125|  8.24k|      std::min(kHashDesiredLeadingSkipBytes,
  126|  8.24k|               std::max<int64_t>(size_i64 - kHashDesiredMinBytes, 0));
  127|  8.24k|  int64_t hash_end_i64 =
  128|  8.24k|      std::min(hash_begin_i64 + kHashDesiredMaxBytes, size_i64);
  129|  8.24k|  size_t hash_begin = static_cast<size_t>(hash_begin_i64);
  130|  8.24k|  size_t hash_size = static_cast<size_t>(hash_end_i64) - hash_begin;
  131|  8.24k|  return HashBuffer(data + hash_begin, hash_size);
  132|  8.24k|}
random_generator.cpp:_ZN8spvtools7fuzzers12_GLOBAL__N_110HashBufferEPKhm:
   72|  8.24k|size_t HashBuffer(const uint8_t* data, const size_t size) {
   73|  8.24k|  size_t hash =
   74|  8.24k|      static_cast<size_t>(0xCA8945571519E991);  // seed with an arbitrary prime
   75|  8.24k|  HashCombine(&hash, size);
   76|   264k|  for (size_t i = 0; i < size; i++) {
  ------------------
  |  Branch (76:22): [True: 256k, False: 8.24k]
  ------------------
   77|   256k|    HashCombine(&hash, data[i]);
   78|   256k|  }
   79|  8.24k|  return hash;
   80|  8.24k|}
random_generator.cpp:_ZN8spvtools7fuzzers12_GLOBAL__N_111HashCombineImEEvPmRKT_:
   63|  8.24k|void HashCombine(size_t* hash, const T& value) {
   64|  8.24k|  constexpr size_t offset = HashCombineOffset<sizeof(size_t)>::value();
   65|  8.24k|  *hash ^= std::hash<T>()(value) + offset + (*hash << 6) + (*hash >> 2);
   66|  8.24k|}
random_generator.cpp:_ZN8spvtools7fuzzers12_GLOBAL__N_111HashCombineIhEEvPmRKT_:
   63|   256k|void HashCombine(size_t* hash, const T& value) {
   64|   256k|  constexpr size_t offset = HashCombineOffset<sizeof(size_t)>::value();
   65|   256k|  *hash ^= std::hash<T>()(value) + offset + (*hash << 6) + (*hash >> 2);
   66|   256k|}
random_generator.cpp:_ZN8spvtools7fuzzers12_GLOBAL__N_110RandomUIntIjEET_PNSt3__123mersenne_twister_engineImLm64ELm312ELm156ELm31ELm13043109905998158313ELm29ELm6148914691236517205ELm17ELm8202884508482404352ELm37ELm18444473444759240704ELm43ELm6364136223846793005EEES3_S3_:
   32|  8.24k|I RandomUInt(std::mt19937_64* engine, I lower, I upper) {
   33|  8.24k|  assert(lower < upper && "|lower| must be stictly less than |upper|");
   34|      0|  return std::uniform_int_distribution<I>(lower, upper - 1)(*engine);
   35|  8.24k|}

_ZN8spvtools7fuzzers15RandomGeneratorD2Ev:
   38|  16.4k|  ~RandomGenerator() {}

LLVMFuzzerTestOneInput:
   21|  8.24k|extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
   22|  8.24k|  if (size < 1) {
  ------------------
  |  Branch (22:7): [True: 0, False: 8.24k]
  ------------------
   23|      0|    return 0;
   24|      0|  }
   25|       |
   26|  8.24k|  spvtools::fuzzers::RandomGenerator random_gen(data, size);
   27|  8.24k|  spvtools::SpirvTools tools(random_gen.GetTargetEnv());
   28|  8.24k|  tools.SetMessageConsumer([](spv_message_level_t, const char*,
   29|  8.24k|                              const spv_position_t&, const char*) {});
   30|       |
   31|  8.24k|  std::vector<uint32_t> input;
   32|  8.24k|  input.resize(size >> 2);
   33|       |
   34|  8.24k|  size_t count = 0;
   35|  5.23M|  for (size_t i = 0; (i + 3) < size; i += 4) {
  ------------------
  |  Branch (35:22): [True: 5.23M, False: 8.24k]
  ------------------
   36|  5.23M|    input[count++] = data[i] | (data[i + 1] << 8) | (data[i + 2] << 16) |
   37|  5.23M|                     (data[i + 3]) << 24;
   38|  5.23M|  }
   39|       |
   40|  8.24k|  tools.Validate(input);
   41|  8.24k|  return 0;
   42|  8.24k|}
spvtools_val_fuzzer.cpp:_ZZ22LLVMFuzzerTestOneInputENK3$_0clE19spv_message_level_tPKcRK14spv_position_tS2_:
   29|  9.48k|                              const spv_position_t&, const char*) {});

