| 32 | } |
| 33 | |
| 34 | bool TransformationReplaceIrrelevantId::IsApplicable( |
| 35 | opt::IRContext* ir_context, |
| 36 | const TransformationContext& transformation_context) const { |
| 37 | auto id_of_interest = message_.id_use_descriptor().id_of_interest(); |
| 38 | |
| 39 | // The id must be irrelevant. |
| 40 | if (!transformation_context.GetFactManager()->IdIsIrrelevant( |
| 41 | id_of_interest)) { |
| 42 | return false; |
| 43 | } |
| 44 | |
| 45 | // Find the instruction containing the id use, which must exist. |
| 46 | auto use_instruction = |
| 47 | FindInstructionContainingUse(message_.id_use_descriptor(), ir_context); |
| 48 | if (!use_instruction) { |
| 49 | return false; |
| 50 | } |
| 51 | |
| 52 | // Check that the replacement id exists and retrieve its definition. |
| 53 | auto replacement_id_def = |
| 54 | ir_context->get_def_use_mgr()->GetDef(message_.replacement_id()); |
| 55 | if (!replacement_id_def) { |
| 56 | return false; |
| 57 | } |
| 58 | |
| 59 | // The type of the id of interest and of the replacement id must be the same. |
| 60 | uint32_t type_id_of_interest = |
| 61 | ir_context->get_def_use_mgr()->GetDef(id_of_interest)->type_id(); |
| 62 | uint32_t type_replacement_id = replacement_id_def->type_id(); |
| 63 | if (type_id_of_interest != type_replacement_id) { |
| 64 | return false; |
| 65 | } |
| 66 | |
| 67 | // The replacement id must not be the result of an OpFunction instruction. |
| 68 | if (replacement_id_def->opcode() == spv::Op::OpFunction) { |
| 69 | return false; |
| 70 | } |
| 71 | |
| 72 | // Consistency check: an irrelevant id cannot be a pointer. |
| 73 | assert( |
| 74 | !ir_context->get_type_mgr()->GetType(type_id_of_interest)->AsPointer() && |
| 75 | "An irrelevant id cannot be a pointer"); |
| 76 | |
| 77 | uint32_t use_in_operand_index = |
| 78 | message_.id_use_descriptor().in_operand_index(); |
| 79 | |
| 80 | // The id use must be replaceable with any other id of the same type. |
| 81 | if (!fuzzerutil::IdUseCanBeReplaced(ir_context, transformation_context, |
| 82 | use_instruction, use_in_operand_index)) { |
| 83 | return false; |
| 84 | } |
| 85 | |
| 86 | if (AttemptsToReplaceVariableInitializerWithNonConstant( |
| 87 | *use_instruction, *replacement_id_def)) { |
| 88 | return false; |
| 89 | } |
| 90 | |
| 91 | // The id must be available to use at the use point. |
nothing calls this directly
no test coverage detected