retdec
symbolic_tree_match.h
Go to the documentation of this file.
1 
12 #ifndef RETDEC_BIN2LLVMIR_UTILS_SYMBOLIC_TREE_MATCH_H
13 #define RETDEC_BIN2LLVMIR_UTILS_SYMBOLIC_TREE_MATCH_H
14 
16 
17 namespace retdec {
18 namespace bin2llvmir {
19 namespace st_match {
20 
21 //
22 //==============================================================================
23 // Main matching function.
24 //==============================================================================
25 //
26 
27 template <typename Pattern>
28 bool match(SymbolicTree& st, const Pattern& p)
29 {
30  return const_cast<Pattern&>(p).match(st);
31 }
32 
33 //
34 //==============================================================================
35 // Matching combinators.
36 //==============================================================================
37 //
38 
39 template<typename LTy, typename RTy> struct match_combine_or
40 {
41  LTy L;
42  RTy R;
43 
44  match_combine_or(const LTy &Left, const RTy &Right) :
45  L(Left), R(Right)
46  {
47  }
48 
50  {
51  if (L.match(V))
52  return true;
53  if (R.match(V))
54  return true;
55  return false;
56  }
57 };
58 
59 template<typename LTy, typename RTy> struct match_combine_and
60 {
61  LTy L;
62  RTy R;
63 
64  match_combine_and(const LTy &Left, const RTy &Right) :
65  L(Left), R(Right)
66  {
67  }
68 
70  {
71  if (L.match(V))
72  if (R.match(V))
73  return true;
74  return false;
75  }
76 };
77 
79 template<typename LTy, typename RTy>
80 inline match_combine_or<LTy, RTy> m_CombineOr(const LTy &L, const RTy &R)
81 {
82  return match_combine_or<LTy, RTy>(L, R);
83 }
84 
86 template<typename LTy, typename RTy>
87 inline match_combine_and<LTy, RTy> m_CombineAnd(const LTy &L, const RTy &R)
88 {
89  return match_combine_and<LTy, RTy>(L, R);
90 }
91 
92 //
93 //==============================================================================
94 // Any Binary matcher.
95 //==============================================================================
96 //
97 
98 template <typename LHS_t, typename RHS_t, bool Commutable = false>
100 {
101  LHS_t L;
102  RHS_t R;
103  llvm::BinaryOperator** insn = nullptr;
104 
105  AnyBinaryOp_match(const LHS_t &LHS, const RHS_t &RHS, llvm::BinaryOperator** i) :
106  L(LHS),
107  R(RHS),
108  insn(i)
109  {
110  }
111 
112  bool match(SymbolicTree& st)
113  {
114  if (!st.isBinary())
115  {
116  return false;
117  }
118 
119  if (auto* I = llvm::dyn_cast<llvm::BinaryOperator>(st.value))
120  {
121  if ((L.match(st.ops[0]) && R.match(st.ops[1]))
122  || (Commutable && L.match(st.ops[1]) && R.match(st.ops[0])))
123  {
124  if (insn)
125  {
126  *insn = I;
127  }
128  return true;
129  }
130  }
131 
132  return false;
133  }
134 };
135 
136 template <typename LHS, typename RHS>
138  const LHS &L,
139  const RHS &R,
140  llvm::BinaryOperator** insn = nullptr)
141 {
142  return AnyBinaryOp_match<LHS, RHS>(L, R, insn);
143 }
144 
145 template <typename LHS, typename RHS>
147  const LHS &L,
148  const RHS &R,
149  llvm::BinaryOperator** insn = nullptr)
150 {
151  return AnyBinaryOp_match<LHS, RHS, true>(L, R, insn);
152 }
153 
154 //
155 //==============================================================================
156 // Binary matcher.
157 //==============================================================================
158 //
159 
160 template <typename LHS_t, typename RHS_t, unsigned Opcode, bool Commutable = false>
162 {
163  LHS_t L;
164  RHS_t R;
165  llvm::BinaryOperator** insn = nullptr;
166 
167  BinaryOp_match(const LHS_t &LHS, const RHS_t &RHS, llvm::BinaryOperator** i = nullptr) :
168  L(LHS),
169  R(RHS),
170  insn(i)
171  {
172  }
173 
174  bool match(SymbolicTree& st)
175  {
176  if (!st.isBinary())
177  {
178  return false;
179  }
180 
181  if (st.value->getValueID() == llvm::Value::InstructionVal + Opcode)
182  {
183  if ((L.match(st.ops[0]) && R.match(st.ops[1]))
184  || (Commutable && L.match(st.ops[1]) && R.match(st.ops[0])))
185  {
186  if (insn)
187  {
188  *insn = llvm::cast<llvm::BinaryOperator>(st.value);
189  }
190  return true;
191  }
192  }
193  if (auto* ce = llvm::dyn_cast<llvm::ConstantExpr>(st.value))
194  {
195  return ce->getOpcode() == Opcode &&
196  ((L.match(st.ops[0]) && R.match(st.ops[1]))
197  || (Commutable && L.match(st.ops[1]) && R.match(st.ops[0])));
198  }
199 
200  return false;
201  }
202 };
203 
204 //
205 //==============================================================================
206 // Binary matchers - non-commutative.
207 //==============================================================================
208 //
209 
210 template <typename LHS, typename RHS>
212  const LHS &L,
213  const RHS &R,
214  llvm::BinaryOperator** add = nullptr)
215 {
217 }
218 
219 template <typename LHS, typename RHS>
221  const LHS &L,
222  const RHS &R,
223  llvm::BinaryOperator** fadd = nullptr)
224 {
226 }
227 
228 template <typename LHS, typename RHS>
230  const LHS &L,
231  const RHS &R,
232  llvm::BinaryOperator** sub = nullptr)
233 {
235 }
236 
237 template <typename LHS, typename RHS>
239  const LHS &L,
240  const RHS &R,
241  llvm::BinaryOperator** fsub = nullptr)
242 {
244 }
245 
246 template <typename LHS, typename RHS>
248  const LHS &L,
249  const RHS &R,
250  llvm::BinaryOperator** mul = nullptr)
251 {
253 }
254 
255 template <typename LHS, typename RHS>
257  const LHS &L,
258  const RHS &R,
259  llvm::BinaryOperator** fmul = nullptr)
260 {
262 }
263 
264 template <typename LHS, typename RHS>
266  const LHS &L,
267  const RHS &R,
268  llvm::BinaryOperator** udiv = nullptr)
269 {
271 }
272 
273 template <typename LHS, typename RHS>
275  const LHS &L,
276  const RHS &R,
277  llvm::BinaryOperator** sdiv = nullptr)
278 {
280 }
281 
282 template <typename LHS, typename RHS>
284  const LHS &L,
285  const RHS &R,
286  llvm::BinaryOperator** fdiv = nullptr)
287 {
289 }
290 
291 template <typename LHS, typename RHS>
293  const LHS &L,
294  const RHS &R,
295  llvm::BinaryOperator** urem = nullptr)
296 {
298 }
299 
300 template <typename LHS, typename RHS>
302  const LHS &L,
303  const RHS &R,
304  llvm::BinaryOperator** srem = nullptr)
305 {
307 }
308 
309 template <typename LHS, typename RHS>
311  const LHS &L,
312  const RHS &R,
313  llvm::BinaryOperator** frem = nullptr)
314 {
316 }
317 
318 template <typename LHS, typename RHS>
320  const LHS &L,
321  const RHS &R,
322  llvm::BinaryOperator** andi = nullptr)
323 {
325 }
326 
327 template <typename LHS, typename RHS>
329  const LHS &L,
330  const RHS &R,
331  llvm::BinaryOperator** ori = nullptr)
332 {
334 }
335 
336 template <typename LHS, typename RHS>
338  const LHS &L,
339  const RHS &R,
340  llvm::BinaryOperator** xori = nullptr)
341 {
343 }
344 
345 template <typename LHS, typename RHS>
347  const LHS &L,
348  const RHS &R,
349  llvm::BinaryOperator** shl = nullptr)
350 {
352 }
353 
354 template <typename LHS, typename RHS>
356  const LHS &L,
357  const RHS &R,
358  llvm::BinaryOperator** lshr = nullptr)
359 {
361 }
362 
363 template <typename LHS, typename RHS>
365  const LHS &L,
366  const RHS &R,
367  llvm::BinaryOperator** ashr = nullptr)
368 {
370 }
371 
372 //
373 //==============================================================================
374 // Binary matchers - commutative.
375 //==============================================================================
376 //
377 
378 template <typename LHS, typename RHS>
380  const LHS &L,
381  const RHS &R,
382  llvm::BinaryOperator** add = nullptr)
383 {
385 }
386 
387 template <typename LHS, typename RHS>
389  const LHS &L,
390  const RHS &R,
391  llvm::BinaryOperator** mul = nullptr)
392 {
394 }
395 
396 template <typename LHS, typename RHS>
398  const LHS &L,
399  const RHS &R,
400  llvm::BinaryOperator** andi = nullptr)
401 {
403 }
404 
405 template <typename LHS, typename RHS>
407  const LHS &L,
408  const RHS &R,
409  llvm::BinaryOperator** ori = nullptr)
410 {
412 }
413 
414 template <typename LHS, typename RHS>
416  const LHS &L,
417  const RHS &R,
418  llvm::BinaryOperator** xori = nullptr)
419 {
421 }
422 
423 //
424 //==============================================================================
425 // Unary matchers.
426 //==============================================================================
427 //
428 
429 template<typename LHS_t> struct not_match
430 {
431  LHS_t L;
432 
433  not_match(const LHS_t& LHS) :
434  L(LHS)
435  {
436  }
437 
438  bool match(SymbolicTree& st)
439  {
440  if (!st.isBinary())
441  {
442  return false;
443  }
444 
445  if (auto *O = llvm::dyn_cast<llvm::Operator>(st.value))
446  {
447  if (O->getOpcode() == llvm::Instruction::Xor)
448  {
449  if (isAllOnes(st.ops[1].value))
450  return L.match(st.ops[0]);
451  if (isAllOnes(st.ops[0].value))
452  return L.match(st.ops[1]);
453  }
454  }
455  return false;
456  }
457 
458 private:
459  bool isAllOnes(llvm::Value *V)
460  {
461  return llvm::isa<llvm::Constant>(V)
462  && llvm::cast<llvm::Constant>(V)->isAllOnesValue();
463  }
464 };
465 
466 template<typename LHS> inline not_match<LHS> m_Not(const LHS &L)
467 {
468  return L;
469 }
470 
471 template<typename LHS_t> struct neg_match
472 {
473  LHS_t L;
474 
475  neg_match(const LHS_t &LHS) :
476  L(LHS)
477  {
478  }
479 
480  bool match(SymbolicTree& st)
481  {
482  if (!st.isBinary())
483  {
484  return false;
485  }
486 
487  if (auto *O = llvm::dyn_cast<llvm::Operator>(st.value))
488  {
489  if (O->getOpcode() == llvm::Instruction::Sub)
490  {
491  return matchIfNeg(st.ops[0], st.ops[1]);
492  }
493  }
494  return false;
495  }
496 
497 private:
499  {
500  return ((llvm::isa <llvm::ConstantInt>(LHS.value)
501  && llvm::cast<llvm::ConstantInt>(LHS.value)->isZero())
502  || llvm::isa<llvm::ConstantAggregateZero>(LHS)) && L.match(RHS);
503  }
504 };
505 
507 template<typename LHS> inline neg_match<LHS> m_Neg(const LHS &L)
508 {
509  return L;
510 }
511 
512 //
513 //==============================================================================
514 // CmpInst matchers - matching Predicate.
515 //==============================================================================
516 //
517 
518 template<
519  typename LHS_t,
520  typename RHS_t,
521  typename Class,
522  typename PredicateTy,
523  bool Commutable = false>
525 {
526  PredicateTy& Predicate;
527  LHS_t L;
528  RHS_t R;
529  Class** cmp = nullptr;
530 
532  PredicateTy &Pred,
533  const LHS_t &LHS,
534  const RHS_t &RHS,
535  Class** i = nullptr)
536  :
537  Predicate(Pred),
538  L(LHS),
539  R(RHS),
540  cmp(i)
541  {
542  }
543 
544  bool match(SymbolicTree& st)
545  {
546  if (!st.isBinary())
547  {
548  return false;
549  }
550 
551  auto *I = llvm::dyn_cast<Class>(st.value);
552  if (I == nullptr)
553  {
554  return false;
555  }
556 
557  if ((L.match(st.ops[0]) && R.match(st.ops[1]))
558  || (Commutable && L.match(st.ops[1]) && R.match(st.ops[0])))
559  {
560  if (cmp)
561  {
562  *cmp = I;
563  }
564  Predicate = I->getPredicate();
565  return true;
566  }
567 
568  return false;
569  }
570 };
571 
572 template<typename LHS, typename RHS>
574  llvm::CmpInst::Predicate &Pred,
575  const LHS &L,
576  const RHS &R,
577  llvm::CmpInst** cmp = nullptr)
578 {
580 }
581 
582 template<typename LHS, typename RHS>
584  llvm::ICmpInst::Predicate &Pred,
585  const LHS &L,
586  const RHS &R,
587  llvm::ICmpInst** icmp = nullptr)
588 {
590 }
591 
592 template<typename LHS, typename RHS>
594  llvm::ICmpInst::Predicate &Pred,
595  const LHS &L,
596  const RHS &R,
597  llvm::ICmpInst** icmp = nullptr)
598 {
600 }
601 
602 template<typename LHS, typename RHS>
604  llvm::FCmpInst::Predicate &Pred,
605  const LHS &L,
606  const RHS &R,
607  llvm::FCmpInst** fcmp = nullptr)
608 {
610 }
611 
612 //
613 //==============================================================================
614 // CmpInst matchers - checking Predicate.
615 //==============================================================================
616 //
617 
618 template<
619  typename LHS_t,
620  typename RHS_t,
621  typename Class,
622  typename PredicateTy,
623  bool Commutable = false>
625 {
626  PredicateTy Predicate;
627  LHS_t L;
628  RHS_t R;
629  Class** cmp = nullptr;
630 
632  PredicateTy Pred,
633  const LHS_t &LHS,
634  const RHS_t &RHS,
635  Class** i = nullptr)
636  :
637  Predicate(Pred),
638  L(LHS),
639  R(RHS),
640  cmp(i)
641  {
642  }
643 
644  bool match(SymbolicTree& st)
645  {
646  if (!st.isBinary())
647  {
648  return false;
649  }
650 
651  auto *I = llvm::dyn_cast<Class>(st.value);
652  if (I == nullptr)
653  {
654  return false;
655  }
656  if (I->getPredicate() != Predicate)
657  {
658  return false;
659  }
660 
661  if ((L.match(st.ops[0]) && R.match(st.ops[1]))
662  || (Commutable && L.match(st.ops[1]) && R.match(st.ops[0])))
663  {
664  if (cmp)
665  {
666  *cmp = I;
667  }
668  return true;
669  }
670 
671  return false;
672  }
673 };
674 
675 template<typename LHS, typename RHS>
677  llvm::CmpInst::Predicate Pred,
678  const LHS &L,
679  const RHS &R,
680  llvm::CmpInst** cmp = nullptr)
681 {
683 }
684 
685 template<typename LHS, typename RHS>
687  llvm::ICmpInst::Predicate Pred,
688  const LHS &L,
689  const RHS &R,
690  llvm::ICmpInst** icmp = nullptr)
691 {
693 }
694 
695 template<typename LHS, typename RHS>
697  llvm::ICmpInst::Predicate Pred,
698  const LHS &L,
699  const RHS &R,
700  llvm::ICmpInst** icmp = nullptr)
701 {
703 }
704 
705 template<typename LHS, typename RHS>
707  llvm::FCmpInst::Predicate Pred,
708  const LHS &L,
709  const RHS &R,
710  llvm::FCmpInst** fcmp = nullptr)
711 {
713 }
714 
715 //
716 //==============================================================================
717 // LoadInst matchers.
718 //==============================================================================
719 //
720 
721 template<typename Op_t> struct LoadClass_match
722 {
723  Op_t Op;
724  llvm::LoadInst** load = nullptr;
725 
726  LoadClass_match(const Op_t &OpMatch, llvm::LoadInst** l = nullptr) :
727  Op(OpMatch),
728  load(l)
729  {
730  }
731 
732  bool match(SymbolicTree& st)
733  {
734  if (!st.isUnary())
735  {
736  return false;
737  }
738 
739  if (auto *LI = llvm::dyn_cast<llvm::LoadInst>(st.value))
740  {
741  if (Op.match(st.ops[0]))
742  {
743  if (load)
744  {
745  *load = LI;
746  }
747  return true;
748  }
749  }
750  return false;
751  }
752 };
753 
754 template<typename OpTy> inline LoadClass_match<OpTy> m_Load(
755  const OpTy &Op,
756  llvm::LoadInst** l = nullptr)
757 {
758  return LoadClass_match<OpTy>(Op, l);
759 }
760 
761 //
762 //==============================================================================
763 // Capturing (binding) matchers.
764 //==============================================================================
765 //
766 
767 template <typename Class>
768 struct bind_ty
769 {
771 
772  bind_ty(Class*& v) :
773  VR(v)
774  {
775  }
776 
777  bool match(SymbolicTree& st)
778  {
779  if (auto* CV = llvm::dyn_cast<Class>(st.value))
780  {
781  VR = CV;
782  return true;
783  }
784  return false;
785  }
786 };
787 
788 inline bind_ty<llvm::Value> m_Value(llvm::Value*& V)
789 {
790  return V;
791 }
792 
793 inline bind_ty<const llvm::Value> m_Value(const llvm::Value*& V)
794 {
795  return V;
796 }
797 
798 inline bind_ty<llvm::BinaryOperator> m_BinOp(llvm::BinaryOperator*& I)
799 {
800  return I;
801 }
802 
803 inline bind_ty<llvm::ConstantInt> m_ConstantInt(llvm::ConstantInt*& CI)
804 {
805  return CI;
806 }
807 
808 inline bind_ty<llvm::Constant> m_Constant(llvm::Constant*& C)
809 {
810  return C;
811 }
812 
813 inline bind_ty<llvm::ConstantFP> m_ConstantFP(llvm::ConstantFP*& C)
814 {
815  return C;
816 }
817 
818 inline bind_ty<llvm::GlobalVariable> m_GlobalVariable(llvm::GlobalVariable*& G)
819 {
820  return G;
821 }
822 
823 inline bind_ty<llvm::Instruction> m_Instruction(llvm::Instruction*& I)
824 {
825  return I;
826 }
827 
828 template<typename Class>
830 {
831  return I;
832 }
833 
834 //
835 //==============================================================================
836 // Non-capturing (ignoring) matchers.
837 //==============================================================================
838 //
839 
840 template<typename Class>
842 {
843  bool match(SymbolicTree& st)
844  {
845  return llvm::isa<Class>(st.value);
846  }
847 };
848 
850 {
851  return class_match<llvm::Value>();
852 }
853 
855 {
857 }
858 
860 {
862 }
863 
865 {
867 }
868 
870 {
872 }
873 
875 {
877 }
878 
880 {
882 }
883 
884 template<typename Class>
885 inline class_match<Class> m_Instruction()
886 {
887  return class_match<Class>();
888 }
889 
890 //
891 //==============================================================================
892 // APInt matchers.
893 //==============================================================================
894 //
895 
897 {
898  const llvm::APInt *&Res;
899 
900  apint_match(const llvm::APInt *&R) :
901  Res(R)
902  {
903  }
904 
905  bool match(SymbolicTree& st)
906  {
907  if (auto* CI = llvm::dyn_cast<llvm::ConstantInt>(st.value))
908  {
909  Res = &CI->getValue();
910  return true;
911  }
912  return false;
913  }
914 };
915 
918 inline apint_match m_APInt(const llvm::APInt*& Res)
919 {
920  return Res;
921 }
922 
923 //
924 //==============================================================================
925 // APFloat matchers.
926 //==============================================================================
927 //
928 
930 {
931  const llvm::APFloat*& Res;
932  apfloat_match(const llvm::APFloat*& R) :
933  Res(R)
934  {
935  }
936 
937  bool match(SymbolicTree& st)
938  {
939  if (auto *CI = llvm::dyn_cast<llvm::ConstantFP>(st.value))
940  {
941  Res = &CI->getValueAPF();
942  return true;
943  }
944  return false;
945  }
946 };
947 
950 inline apfloat_match m_APFloat(const llvm::APFloat*& Res)
951 {
952  return Res;
953 }
954 
955 //
956 //==============================================================================
957 // Constant int matchers.
958 //==============================================================================
959 //
960 
961 template<int64_t Val> struct constantint_match
962 {
963  bool match(SymbolicTree& st)
964  {
965  if (const auto* CI = llvm::dyn_cast<llvm::ConstantInt>(st.value))
966  {
967  const llvm::APInt& CIV = CI->getValue();
968  if (Val >= 0)
969  return CIV == static_cast<uint64_t>(Val);
970  // If Val is negative, and CI is shorter than it, truncate to the
971  // right number of bits. If it is larger, then we have to sign
972  // extend. Just compare their negated values.
973  return -CIV == -Val;
974  }
975  return false;
976  }
977 };
978 
980 template<int64_t Val> inline constantint_match<Val> m_ConstantInt()
981 {
982  return constantint_match<Val>();
983 }
984 
985 //
986 //==============================================================================
987 // Zero matchers.
988 //==============================================================================
989 //
990 
992 {
993  bool match(SymbolicTree& st)
994  {
995  if (const auto* C = llvm::dyn_cast<llvm::Constant>(st.value))
996  {
997  return C->isNullValue();
998  }
999  return false;
1000  }
1001 };
1002 
1006 {
1007  return match_zero();
1008 }
1009 
1011 {
1012  llvm::ConstantInt*& CI;
1013 
1014  match_not_zero(llvm::ConstantInt*& ci) :
1015  CI(ci)
1016  {
1017  }
1018 
1020  {
1021  if (auto* C = llvm::dyn_cast<llvm::ConstantInt>(st.value))
1022  {
1023  if (!C->isNullValue())
1024  {
1025  CI = C;
1026  return true;
1027  }
1028  }
1029  return false;
1030  }
1031 };
1032 
1035 {
1036  llvm::ConstantInt* CI;
1037  return match_not_zero(CI);
1038 }
1039 
1041 inline match_not_zero m_not_Zero(llvm::ConstantInt*& CI)
1042 {
1043  return match_not_zero(CI);
1044 }
1045 
1047 {
1049  {
1050  if (const auto *C = llvm::dyn_cast<llvm::Constant>(st.value))
1051  {
1052  return C->isNegativeZeroValue();
1053  }
1054  return false;
1055  }
1056 };
1057 
1063 {
1064  return match_neg_zero();
1065 }
1066 
1068 {
1070  {
1071  if (const auto *C = llvm::dyn_cast<llvm::Constant>(st.value))
1072  {
1073  return C->isZeroValue();
1074  }
1075  return false;
1076  }
1077 };
1078 
1083 {
1084  return match_any_zero();
1085 }
1086 
1087 //
1088 //==============================================================================
1089 // One matchers.
1090 //==============================================================================
1091 //
1092 
1094 {
1096  {
1097  if (const auto* C = llvm::dyn_cast<llvm::Constant>(st.value))
1098  {
1099  return C->isOneValue();
1100  }
1101  return false;
1102  }
1103 };
1104 
1106 {
1107  return match_one();
1108 }
1109 
1110 //
1111 //==============================================================================
1112 // Specific value matchers.
1113 //==============================================================================
1114 //
1115 
1117 {
1118  const llvm::Value* Val;
1119 
1120  specificval_ty(const llvm::Value* V) :
1121  Val(V)
1122  {
1123  }
1124 
1126  {
1127  return st.value == Val;
1128  }
1129 };
1130 
1132 inline specificval_ty m_Specific(const llvm::Value* V)
1133 {
1134  return V;
1135 }
1136 
1137 //
1138 //==============================================================================
1139 // Bind int matchers.
1140 //==============================================================================
1141 //
1142 
1144 {
1145  uint64_t& VR;
1146 
1147  bind_const_intval_ty(uint64_t &V) :
1148  VR(V)
1149  {
1150  }
1151 
1153  {
1154  if (const auto* CV = llvm::dyn_cast<llvm::ConstantInt>(st.value))
1155  {
1156  if (CV->getValue().ule(UINT64_MAX))
1157  {
1158  VR = CV->getZExtValue();
1159  return true;
1160  }
1161  }
1162  return false;
1163  }
1164 };
1165 
1169 {
1170  return V;
1171 }
1172 
1173 //
1174 //==============================================================================
1175 // Specific int matchers.
1176 //==============================================================================
1177 //
1178 
1181 {
1182  uint64_t Val;
1183 
1184  specific_intval(uint64_t V) :
1185  Val(V)
1186  {
1187  }
1188 
1190  {
1191  const auto *CI = llvm::dyn_cast<llvm::ConstantInt>(st.value);
1192  return CI && CI->getValue() == Val;
1193  }
1194 };
1195 
1196 inline specific_intval m_SpecificInt(uint64_t V)
1197 {
1198  return specific_intval(V);
1199 }
1200 
1201 //
1202 //==============================================================================
1203 // Specific FP matchers.
1204 //==============================================================================
1205 //
1206 
1209 {
1210  double Val;
1211 
1212  specific_fpval(double V) :
1213  Val(V)
1214  {
1215  }
1216 
1217  template<typename ITy> bool match(ITy *V)
1218  {
1219  if (const auto *CFP = llvm::dyn_cast<llvm::ConstantFP>(V))
1220  return CFP->isExactlyValue(Val);
1221  return false;
1222  }
1223 };
1224 
1226 {
1227  return specific_fpval(V);
1228 }
1229 
1232 {
1233  return m_SpecificFP(1.0);
1234 }
1235 
1236 } // namespace st_match
1237 } // namespace bin2llvmir
1238 } // namespace retdec
1239 
1240 #endif
Definition: hierarchy.h:24
Definition: symbolic_tree.h:43
bool isUnary() const
Definition: symbolic_tree.cpp:676
std::vector< SymbolicTree > ops
Definition: symbolic_tree.h:133
llvm::Value * value
Definition: symbolic_tree.h:131
bool isBinary() const
Definition: symbolic_tree.cpp:681
The frontend-end part of the decompiler.
BinaryOp_match< LHS, RHS, llvm::Instruction::FDiv > m_FDiv(const LHS &L, const RHS &R, llvm::BinaryOperator **fdiv=nullptr)
Definition: symbolic_tree_match.h:283
specific_fpval m_FPOne()
Match a float 1.0.
Definition: symbolic_tree_match.h:1231
BinaryOp_match< LHS, RHS, llvm::Instruction::FRem > m_FRem(const LHS &L, const RHS &R, llvm::BinaryOperator **frem=nullptr)
Definition: symbolic_tree_match.h:310
CmpClass_match< LHS, RHS, llvm::CmpInst, llvm::CmpInst::Predicate > m_Cmp(llvm::CmpInst::Predicate &Pred, const LHS &L, const RHS &R, llvm::CmpInst **cmp=nullptr)
Definition: symbolic_tree_match.h:573
BinaryOp_match< LHS, RHS, llvm::Instruction::Sub > m_Sub(const LHS &L, const RHS &R, llvm::BinaryOperator **sub=nullptr)
Definition: symbolic_tree_match.h:229
BinaryOp_match< LHS, RHS, llvm::Instruction::AShr > m_AShr(const LHS &L, const RHS &R, llvm::BinaryOperator **ashr=nullptr)
Definition: symbolic_tree_match.h:364
BinaryOp_match< LHS, RHS, llvm::Instruction::FSub > m_FSub(const LHS &L, const RHS &R, llvm::BinaryOperator **fsub=nullptr)
Definition: symbolic_tree_match.h:238
specific_fpval m_SpecificFP(double V)
Definition: symbolic_tree_match.h:1225
AnyBinaryOp_match< LHS, RHS, true > m_c_BinOp(const LHS &L, const RHS &R, llvm::BinaryOperator **insn=nullptr)
Definition: symbolic_tree_match.h:146
bind_ty< llvm::ConstantInt > m_ConstantInt(llvm::ConstantInt *&CI)
Definition: symbolic_tree_match.h:803
AnyBinaryOp_match< LHS, RHS > m_BinOp(const LHS &L, const RHS &R, llvm::BinaryOperator **insn=nullptr)
Definition: symbolic_tree_match.h:137
BinaryOp_match< LHS, RHS, llvm::Instruction::FMul > m_FMul(const LHS &L, const RHS &R, llvm::BinaryOperator **fmul=nullptr)
Definition: symbolic_tree_match.h:256
specific_intval m_SpecificInt(uint64_t V)
Definition: symbolic_tree_match.h:1196
BinaryOp_match< LHS, RHS, llvm::Instruction::Xor > m_Xor(const LHS &L, const RHS &R, llvm::BinaryOperator **xori=nullptr)
Definition: symbolic_tree_match.h:337
BinaryOp_match< LHS, RHS, llvm::Instruction::Mul > m_Mul(const LHS &L, const RHS &R, llvm::BinaryOperator **mul=nullptr)
Definition: symbolic_tree_match.h:247
CmpClass_match< LHS, RHS, llvm::FCmpInst, llvm::FCmpInst::Predicate > m_FCmp(llvm::FCmpInst::Predicate &Pred, const LHS &L, const RHS &R, llvm::FCmpInst **fcmp=nullptr)
Definition: symbolic_tree_match.h:603
match_combine_or< LTy, RTy > m_CombineOr(const LTy &L, const RTy &R)
Combine two pattern matchers matching L || R.
Definition: symbolic_tree_match.h:80
BinaryOp_match< LHS, RHS, llvm::Instruction::And > m_And(const LHS &L, const RHS &R, llvm::BinaryOperator **andi=nullptr)
Definition: symbolic_tree_match.h:319
match_not_zero m_not_Zero()
Match an arbitrary non-zero constant integer.
Definition: symbolic_tree_match.h:1034
match_one m_One()
Definition: symbolic_tree_match.h:1105
BinaryOp_match< LHS, RHS, llvm::Instruction::Add, true > m_c_Add(const LHS &L, const RHS &R, llvm::BinaryOperator **add=nullptr)
Definition: symbolic_tree_match.h:379
BinaryOp_match< LHS, RHS, llvm::Instruction::FAdd > m_FAdd(const LHS &L, const RHS &R, llvm::BinaryOperator **fadd=nullptr)
Definition: symbolic_tree_match.h:220
not_match< LHS > m_Not(const LHS &L)
Definition: symbolic_tree_match.h:466
BinaryOp_match< LHS, RHS, llvm::Instruction::Shl > m_Shl(const LHS &L, const RHS &R, llvm::BinaryOperator **shl=nullptr)
Definition: symbolic_tree_match.h:346
class_match< llvm::UndefValue > m_Undef()
Definition: symbolic_tree_match.h:869
match_neg_zero m_NegZero()
Match an arbitrary zero/null constant. This includes zero_initializer for vectors and ConstantPointer...
Definition: symbolic_tree_match.h:1062
bind_ty< llvm::Constant > m_Constant(llvm::Constant *&C)
Definition: symbolic_tree_match.h:808
BinaryOp_match< LHS, RHS, llvm::Instruction::Add > m_Add(const LHS &L, const RHS &R, llvm::BinaryOperator **add=nullptr)
Definition: symbolic_tree_match.h:211
bool match(SymbolicTree &st, const Pattern &p)
Definition: symbolic_tree_match.h:28
bind_ty< llvm::Value > m_Value(llvm::Value *&V)
Definition: symbolic_tree_match.h:788
BinaryOp_match< LHS, RHS, llvm::Instruction::URem > m_URem(const LHS &L, const RHS &R, llvm::BinaryOperator **urem=nullptr)
Definition: symbolic_tree_match.h:292
bind_ty< llvm::Instruction > m_Instruction(llvm::Instruction *&I)
Definition: symbolic_tree_match.h:823
BinaryOp_match< LHS, RHS, llvm::Instruction::SRem > m_SRem(const LHS &L, const RHS &R, llvm::BinaryOperator **srem=nullptr)
Definition: symbolic_tree_match.h:301
BinaryOp_match< LHS, RHS, llvm::Instruction::And, true > m_c_And(const LHS &L, const RHS &R, llvm::BinaryOperator **andi=nullptr)
Definition: symbolic_tree_match.h:397
BinaryOp_match< LHS, RHS, llvm::Instruction::LShr > m_LShr(const LHS &L, const RHS &R, llvm::BinaryOperator **lshr=nullptr)
Definition: symbolic_tree_match.h:355
BinaryOp_match< LHS, RHS, llvm::Instruction::SDiv > m_SDiv(const LHS &L, const RHS &R, llvm::BinaryOperator **sdiv=nullptr)
Definition: symbolic_tree_match.h:274
BinaryOp_match< LHS, RHS, llvm::Instruction::Xor, true > m_c_Xor(const LHS &L, const RHS &R, llvm::BinaryOperator **xori=nullptr)
Definition: symbolic_tree_match.h:415
BinaryOp_match< LHS, RHS, llvm::Instruction::Or > m_Or(const LHS &L, const RHS &R, llvm::BinaryOperator **ori=nullptr)
Definition: symbolic_tree_match.h:328
apfloat_match m_APFloat(const llvm::APFloat *&Res)
Match a ConstantFP, binding the specified pointer to the contained APFloat.
Definition: symbolic_tree_match.h:950
apint_match m_APInt(const llvm::APInt *&Res)
Match a ConstantInt, binding the specified pointer to the contained APInt.
Definition: symbolic_tree_match.h:918
bind_ty< llvm::GlobalVariable > m_GlobalVariable(llvm::GlobalVariable *&G)
Definition: symbolic_tree_match.h:818
neg_match< LHS > m_Neg(const LHS &L)
Match an integer negate.
Definition: symbolic_tree_match.h:507
match_any_zero m_AnyZero()
Match an arbitrary zero/null constant. This includes zero_initializer for vectors and ConstantPointer...
Definition: symbolic_tree_match.h:1082
match_zero m_Zero()
Match an arbitrary zero/null constant. This includes zero_initializer for vectors and ConstantPointer...
Definition: symbolic_tree_match.h:1005
bind_ty< llvm::ConstantFP > m_ConstantFP(llvm::ConstantFP *&C)
Definition: symbolic_tree_match.h:813
match_combine_and< LTy, RTy > m_CombineAnd(const LTy &L, const RTy &R)
Combine two pattern matchers matching L && R.
Definition: symbolic_tree_match.h:87
CmpClass_match< LHS, RHS, llvm::ICmpInst, llvm::ICmpInst::Predicate > m_ICmp(llvm::ICmpInst::Predicate &Pred, const LHS &L, const RHS &R, llvm::ICmpInst **icmp=nullptr)
Definition: symbolic_tree_match.h:583
CmpClass_match< LHS, RHS, llvm::ICmpInst, llvm::ICmpInst::Predicate, true > m_c_ICmp(llvm::ICmpInst::Predicate &Pred, const LHS &L, const RHS &R, llvm::ICmpInst **icmp=nullptr)
Definition: symbolic_tree_match.h:593
BinaryOp_match< LHS, RHS, llvm::Instruction::UDiv > m_UDiv(const LHS &L, const RHS &R, llvm::BinaryOperator **udiv=nullptr)
Definition: symbolic_tree_match.h:265
specificval_ty m_Specific(const llvm::Value *V)
Match if we have a specific specified value.
Definition: symbolic_tree_match.h:1132
LoadClass_match< OpTy > m_Load(const OpTy &Op, llvm::LoadInst **l=nullptr)
Definition: symbolic_tree_match.h:754
BinaryOp_match< LHS, RHS, llvm::Instruction::Mul, true > m_c_Mul(const LHS &L, const RHS &R, llvm::BinaryOperator **mul=nullptr)
Definition: symbolic_tree_match.h:388
BinaryOp_match< LHS, RHS, llvm::Instruction::Or, true > m_c_Or(const LHS &L, const RHS &R, llvm::BinaryOperator **ori=nullptr)
Definition: symbolic_tree_match.h:406
union retdec::pdbparser::_CV CV
Definition: archive_wrapper.h:19
Definition: symbolic_tree_match.h:100
LHS_t L
Definition: symbolic_tree_match.h:101
bool match(SymbolicTree &st)
Definition: symbolic_tree_match.h:112
llvm::BinaryOperator ** insn
Definition: symbolic_tree_match.h:103
RHS_t R
Definition: symbolic_tree_match.h:102
AnyBinaryOp_match(const LHS_t &LHS, const RHS_t &RHS, llvm::BinaryOperator **i)
Definition: symbolic_tree_match.h:105
Definition: symbolic_tree_match.h:162
BinaryOp_match(const LHS_t &LHS, const RHS_t &RHS, llvm::BinaryOperator **i=nullptr)
Definition: symbolic_tree_match.h:167
bool match(SymbolicTree &st)
Definition: symbolic_tree_match.h:174
RHS_t R
Definition: symbolic_tree_match.h:164
LHS_t L
Definition: symbolic_tree_match.h:163
llvm::BinaryOperator ** insn
Definition: symbolic_tree_match.h:165
Definition: symbolic_tree_match.h:525
RHS_t R
Definition: symbolic_tree_match.h:528
Class ** cmp
Definition: symbolic_tree_match.h:529
bool match(SymbolicTree &st)
Definition: symbolic_tree_match.h:544
CmpClass_match(PredicateTy &Pred, const LHS_t &LHS, const RHS_t &RHS, Class **i=nullptr)
Definition: symbolic_tree_match.h:531
LHS_t L
Definition: symbolic_tree_match.h:527
PredicateTy & Predicate
Definition: symbolic_tree_match.h:526
Definition: symbolic_tree_match.h:625
bool match(SymbolicTree &st)
Definition: symbolic_tree_match.h:644
RHS_t R
Definition: symbolic_tree_match.h:628
PredicateTy Predicate
Definition: symbolic_tree_match.h:626
Class ** cmp
Definition: symbolic_tree_match.h:629
CmpClass_pred_match(PredicateTy Pred, const LHS_t &LHS, const RHS_t &RHS, Class **i=nullptr)
Definition: symbolic_tree_match.h:631
LHS_t L
Definition: symbolic_tree_match.h:627
Definition: symbolic_tree_match.h:722
llvm::LoadInst ** load
Definition: symbolic_tree_match.h:724
LoadClass_match(const Op_t &OpMatch, llvm::LoadInst **l=nullptr)
Definition: symbolic_tree_match.h:726
Op_t Op
Definition: symbolic_tree_match.h:723
bool match(SymbolicTree &st)
Definition: symbolic_tree_match.h:732
Definition: symbolic_tree_match.h:930
const llvm::APFloat *& Res
Definition: symbolic_tree_match.h:931
bool match(SymbolicTree &st)
Definition: symbolic_tree_match.h:937
apfloat_match(const llvm::APFloat *&R)
Definition: symbolic_tree_match.h:932
Definition: symbolic_tree_match.h:897
const llvm::APInt *& Res
Definition: symbolic_tree_match.h:898
apint_match(const llvm::APInt *&R)
Definition: symbolic_tree_match.h:900
bool match(SymbolicTree &st)
Definition: symbolic_tree_match.h:905
Definition: symbolic_tree_match.h:1144
uint64_t & VR
Definition: symbolic_tree_match.h:1145
bind_const_intval_ty(uint64_t &V)
Definition: symbolic_tree_match.h:1147
bool match(SymbolicTree &st)
Definition: symbolic_tree_match.h:1152
Definition: symbolic_tree_match.h:769
Class *& VR
Definition: symbolic_tree_match.h:770
bind_ty(Class *&v)
Definition: symbolic_tree_match.h:772
bool match(SymbolicTree &st)
Definition: symbolic_tree_match.h:777
Definition: symbolic_tree_match.h:842
bool match(SymbolicTree &st)
Definition: symbolic_tree_match.h:843
Definition: symbolic_tree_match.h:962
bool match(SymbolicTree &st)
Definition: symbolic_tree_match.h:963
Definition: symbolic_tree_match.h:1068
bool match(SymbolicTree &st)
Definition: symbolic_tree_match.h:1069
Definition: symbolic_tree_match.h:60
RTy R
Definition: symbolic_tree_match.h:62
bool match(SymbolicTree &V)
Definition: symbolic_tree_match.h:69
match_combine_and(const LTy &Left, const RTy &Right)
Definition: symbolic_tree_match.h:64
LTy L
Definition: symbolic_tree_match.h:61
Definition: symbolic_tree_match.h:40
match_combine_or(const LTy &Left, const RTy &Right)
Definition: symbolic_tree_match.h:44
LTy L
Definition: symbolic_tree_match.h:41
bool match(SymbolicTree &V)
Definition: symbolic_tree_match.h:49
RTy R
Definition: symbolic_tree_match.h:42
Definition: symbolic_tree_match.h:1047
bool match(SymbolicTree &st)
Definition: symbolic_tree_match.h:1048
Definition: symbolic_tree_match.h:1011
bool match(SymbolicTree &st)
Definition: symbolic_tree_match.h:1019
match_not_zero(llvm::ConstantInt *&ci)
Definition: symbolic_tree_match.h:1014
llvm::ConstantInt *& CI
Definition: symbolic_tree_match.h:1012
Definition: symbolic_tree_match.h:1094
bool match(SymbolicTree &st)
Definition: symbolic_tree_match.h:1095
Definition: symbolic_tree_match.h:992
bool match(SymbolicTree &st)
Definition: symbolic_tree_match.h:993
Definition: symbolic_tree_match.h:472
LHS_t L
Definition: symbolic_tree_match.h:473
bool match(SymbolicTree &st)
Definition: symbolic_tree_match.h:480
bool matchIfNeg(SymbolicTree &LHS, SymbolicTree &RHS)
Definition: symbolic_tree_match.h:498
neg_match(const LHS_t &LHS)
Definition: symbolic_tree_match.h:475
Definition: symbolic_tree_match.h:430
bool match(SymbolicTree &st)
Definition: symbolic_tree_match.h:438
not_match(const LHS_t &LHS)
Definition: symbolic_tree_match.h:433
LHS_t L
Definition: symbolic_tree_match.h:431
bool isAllOnes(llvm::Value *V)
Definition: symbolic_tree_match.h:459
Match a specified floating point value.
Definition: symbolic_tree_match.h:1209
specific_fpval(double V)
Definition: symbolic_tree_match.h:1212
bool match(ITy *V)
Definition: symbolic_tree_match.h:1217
double Val
Definition: symbolic_tree_match.h:1210
Match a specified integer value.
Definition: symbolic_tree_match.h:1181
specific_intval(uint64_t V)
Definition: symbolic_tree_match.h:1184
uint64_t Val
Definition: symbolic_tree_match.h:1182
bool match(SymbolicTree &st)
Definition: symbolic_tree_match.h:1189
Definition: symbolic_tree_match.h:1117
bool match(SymbolicTree &st)
Definition: symbolic_tree_match.h:1125
specificval_ty(const llvm::Value *V)
Definition: symbolic_tree_match.h:1120
const llvm::Value * Val
Definition: symbolic_tree_match.h:1118
Construction of symbolic tree from the given node.