transformation_add_spec_constant_op.cpp 3.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. // Copyright (c) 2020 Vasyl Teliman
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. #include "source/fuzz/transformation_add_spec_constant_op.h"
  15. #include <utility>
  16. #include "source/fuzz/fuzzer_util.h"
  17. namespace spvtools {
  18. namespace fuzz {
  19. TransformationAddSpecConstantOp::TransformationAddSpecConstantOp(
  20. spvtools::fuzz::protobufs::TransformationAddSpecConstantOp message)
  21. : message_(std::move(message)) {}
  22. TransformationAddSpecConstantOp::TransformationAddSpecConstantOp(
  23. uint32_t fresh_id, uint32_t type_id, spv::Op opcode,
  24. const opt::Instruction::OperandList& operands) {
  25. message_.set_fresh_id(fresh_id);
  26. message_.set_type_id(type_id);
  27. message_.set_opcode(uint32_t(opcode));
  28. for (const auto& operand : operands) {
  29. auto* op = message_.add_operand();
  30. op->set_operand_type(operand.type);
  31. for (auto word : operand.words) {
  32. op->add_operand_data(word);
  33. }
  34. }
  35. }
  36. bool TransformationAddSpecConstantOp::IsApplicable(
  37. opt::IRContext* ir_context,
  38. const TransformationContext& transformation_context) const {
  39. auto clone = fuzzerutil::CloneIRContext(ir_context);
  40. ApplyImpl(clone.get());
  41. return fuzzerutil::IsValid(clone.get(),
  42. transformation_context.GetValidatorOptions(),
  43. fuzzerutil::kSilentMessageConsumer);
  44. }
  45. void TransformationAddSpecConstantOp::Apply(
  46. opt::IRContext* ir_context, TransformationContext* /*unused*/) const {
  47. ApplyImpl(ir_context);
  48. ir_context->InvalidateAnalysesExceptFor(
  49. opt::IRContext::Analysis::kAnalysisNone);
  50. }
  51. void TransformationAddSpecConstantOp::ApplyImpl(
  52. opt::IRContext* ir_context) const {
  53. opt::Instruction::OperandList operands = {
  54. {SPV_OPERAND_TYPE_SPEC_CONSTANT_OP_NUMBER, {message_.opcode()}}};
  55. for (const auto& operand : message_.operand()) {
  56. std::vector<uint32_t> words(operand.operand_data().begin(),
  57. operand.operand_data().end());
  58. operands.push_back({static_cast<spv_operand_type_t>(operand.operand_type()),
  59. std::move(words)});
  60. }
  61. ir_context->AddGlobalValue(MakeUnique<opt::Instruction>(
  62. ir_context, spv::Op::OpSpecConstantOp, message_.type_id(),
  63. message_.fresh_id(), std::move(operands)));
  64. fuzzerutil::UpdateModuleIdBound(ir_context, message_.fresh_id());
  65. }
  66. protobufs::Transformation TransformationAddSpecConstantOp::ToMessage() const {
  67. protobufs::Transformation result;
  68. *result.mutable_add_spec_constant_op() = message_;
  69. return result;
  70. }
  71. std::unordered_set<uint32_t> TransformationAddSpecConstantOp::GetFreshIds()
  72. const {
  73. return {message_.fresh_id()};
  74. }
  75. } // namespace fuzz
  76. } // namespace spvtools