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 
15 #ifndef SOURCE_FUZZ_TRANSFORMATION_INVERT_COMPARISON_OPERATOR_H_
16 #define SOURCE_FUZZ_TRANSFORMATION_INVERT_COMPARISON_OPERATOR_H_
17 
18 #include "source/fuzz/protobufs/spirvfuzz_protobufs.h"
19 #include "source/fuzz/transformation.h"
20 #include "source/fuzz/transformation_context.h"
21 #include "source/opt/ir_context.h"
22 
23 namespace spvtools {
24 namespace fuzz {
25 
26 class TransformationInvertComparisonOperator : public Transformation {
27  public:
28   explicit TransformationInvertComparisonOperator(
29       protobufs::TransformationInvertComparisonOperator message);
30 
31   TransformationInvertComparisonOperator(uint32_t operator_id,
32                                          uint32_t fresh_id);
33 
34   // - |operator_id| should be a result id of some instruction for which
35   //   IsInversionSupported returns true.
36   // - |fresh_id| must be a fresh id.
37   bool IsApplicable(
38       opt::IRContext* ir_context,
39       const TransformationContext& transformation_context) const override;
40 
41   // Inverts the opcode of the instruction with result id |operator_id| (e.g >=
42   // becomes <) and inserts OpLogicalNot instruction after |operator_id|. Also,
43   // changes the result id of OpLogicalNot to |operator_id| and the result id of
44   // the inverted operator to |fresh_id|.
45   void Apply(opt::IRContext* ir_context,
46              TransformationContext* transformation_context) const override;
47 
48   std::unordered_set<uint32_t> GetFreshIds() const override;
49 
50   protobufs::Transformation ToMessage() const override;
51 
52   // Returns true if |opcode| is supported by this transformation.
53   static bool IsInversionSupported(SpvOp opcode);
54 
55  private:
56   // Returns an inverted |opcode| (e.g. < becomes >=, == becomes != etc.)
57   static SpvOp InvertOpcode(SpvOp opcode);
58 
59   protobufs::TransformationInvertComparisonOperator message_;
60 };
61 
62 }  // namespace fuzz
63 }  // namespace spvtools
64 
65 #endif  // SOURCE_FUZZ_TRANSFORMATION_INVERT_COMPARISON_OPERATOR_H_
66