1 //===-- CmpInstAnalysis.h - Utils to help fold compare insts ----*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // This file holds routines to help analyse compare instructions 10 // and fold them into constants or other compare instructions 11 // 12 //===----------------------------------------------------------------------===// 13 14 #ifndef LLVM_ANALYSIS_CMPINSTANALYSIS_H 15 #define LLVM_ANALYSIS_CMPINSTANALYSIS_H 16 17 #include "llvm/IR/InstrTypes.h" 18 19 namespace llvm { 20 class Type; 21 class Value; 22 23 /// Encode a icmp predicate into a three bit mask. These bits are carefully 24 /// arranged to allow folding of expressions such as: 25 /// 26 /// (A < B) | (A > B) --> (A != B) 27 /// 28 /// Note that this is only valid if the first and second predicates have the 29 /// same sign. It is illegal to do: (A u< B) | (A s> B) 30 /// 31 /// Three bits are used to represent the condition, as follows: 32 /// 0 A > B 33 /// 1 A == B 34 /// 2 A < B 35 /// 36 /// <=> Value Definition 37 /// 000 0 Always false 38 /// 001 1 A > B 39 /// 010 2 A == B 40 /// 011 3 A >= B 41 /// 100 4 A < B 42 /// 101 5 A != B 43 /// 110 6 A <= B 44 /// 111 7 Always true 45 /// 46 unsigned getICmpCode(CmpInst::Predicate Pred); 47 48 /// This is the complement of getICmpCode. It turns a predicate code into 49 /// either a constant true or false or the predicate for a new ICmp. 50 /// The sign is passed in to determine which kind of predicate to use in the 51 /// new ICmp instruction. 52 /// Non-NULL return value will be a true or false constant. 53 /// NULL return means a new ICmp is needed. The predicate is output in Pred. 54 Constant *getPredForICmpCode(unsigned Code, bool Sign, Type *OpTy, 55 CmpInst::Predicate &Pred); 56 57 /// Return true if both predicates match sign or if at least one of them is an 58 /// equality comparison (which is signless). 59 bool predicatesFoldable(CmpInst::Predicate P1, CmpInst::Predicate P2); 60 61 /// Similar to getICmpCode but for FCmpInst. This encodes a fcmp predicate 62 /// into a four bit mask. getFCmpCode(CmpInst::Predicate CC)63 inline unsigned getFCmpCode(CmpInst::Predicate CC) { 64 assert(CmpInst::FCMP_FALSE <= CC && CC <= CmpInst::FCMP_TRUE && 65 "Unexpected FCmp predicate!"); 66 // Take advantage of the bit pattern of CmpInst::Predicate here. 67 // U L G E 68 static_assert(CmpInst::FCMP_FALSE == 0); // 0 0 0 0 69 static_assert(CmpInst::FCMP_OEQ == 1); // 0 0 0 1 70 static_assert(CmpInst::FCMP_OGT == 2); // 0 0 1 0 71 static_assert(CmpInst::FCMP_OGE == 3); // 0 0 1 1 72 static_assert(CmpInst::FCMP_OLT == 4); // 0 1 0 0 73 static_assert(CmpInst::FCMP_OLE == 5); // 0 1 0 1 74 static_assert(CmpInst::FCMP_ONE == 6); // 0 1 1 0 75 static_assert(CmpInst::FCMP_ORD == 7); // 0 1 1 1 76 static_assert(CmpInst::FCMP_UNO == 8); // 1 0 0 0 77 static_assert(CmpInst::FCMP_UEQ == 9); // 1 0 0 1 78 static_assert(CmpInst::FCMP_UGT == 10); // 1 0 1 0 79 static_assert(CmpInst::FCMP_UGE == 11); // 1 0 1 1 80 static_assert(CmpInst::FCMP_ULT == 12); // 1 1 0 0 81 static_assert(CmpInst::FCMP_ULE == 13); // 1 1 0 1 82 static_assert(CmpInst::FCMP_UNE == 14); // 1 1 1 0 83 static_assert(CmpInst::FCMP_TRUE == 15); // 1 1 1 1 84 return CC; 85 } 86 87 /// This is the complement of getFCmpCode. It turns a predicate code into 88 /// either a constant true or false or the predicate for a new FCmp. 89 /// Non-NULL return value will be a true or false constant. 90 /// NULL return means a new ICmp is needed. The predicate is output in Pred. 91 Constant *getPredForFCmpCode(unsigned Code, Type *OpTy, 92 CmpInst::Predicate &Pred); 93 94 /// Decompose an icmp into the form ((X & Mask) pred 0) if possible. The 95 /// returned predicate is either == or !=. Returns false if decomposition 96 /// fails. 97 bool decomposeBitTestICmp(Value *LHS, Value *RHS, CmpInst::Predicate &Pred, 98 Value *&X, APInt &Mask, 99 bool LookThroughTrunc = true); 100 101 } // end namespace llvm 102 103 #endif 104