1 //===- CmpInstAnalysis.cpp - Utils to help fold compares ---------------===// 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 #include "llvm/Analysis/CmpInstAnalysis.h" 15 #include "llvm/IR/Constants.h" 16 #include "llvm/IR/Instructions.h" 17 #include "llvm/IR/PatternMatch.h" 18 19 using namespace llvm; 20 21 unsigned llvm::getICmpCode(CmpInst::Predicate Pred) { 22 switch (Pred) { 23 // False -> 0 24 case ICmpInst::ICMP_UGT: return 1; // 001 25 case ICmpInst::ICMP_SGT: return 1; // 001 26 case ICmpInst::ICMP_EQ: return 2; // 010 27 case ICmpInst::ICMP_UGE: return 3; // 011 28 case ICmpInst::ICMP_SGE: return 3; // 011 29 case ICmpInst::ICMP_ULT: return 4; // 100 30 case ICmpInst::ICMP_SLT: return 4; // 100 31 case ICmpInst::ICMP_NE: return 5; // 101 32 case ICmpInst::ICMP_ULE: return 6; // 110 33 case ICmpInst::ICMP_SLE: return 6; // 110 34 // True -> 7 35 default: 36 llvm_unreachable("Invalid ICmp predicate!"); 37 } 38 } 39 40 Constant *llvm::getPredForICmpCode(unsigned Code, bool Sign, Type *OpTy, 41 CmpInst::Predicate &Pred) { 42 switch (Code) { 43 default: llvm_unreachable("Illegal ICmp code!"); 44 case 0: // False. 45 return ConstantInt::get(CmpInst::makeCmpResultType(OpTy), 0); 46 case 1: Pred = Sign ? ICmpInst::ICMP_SGT : ICmpInst::ICMP_UGT; break; 47 case 2: Pred = ICmpInst::ICMP_EQ; break; 48 case 3: Pred = Sign ? ICmpInst::ICMP_SGE : ICmpInst::ICMP_UGE; break; 49 case 4: Pred = Sign ? ICmpInst::ICMP_SLT : ICmpInst::ICMP_ULT; break; 50 case 5: Pred = ICmpInst::ICMP_NE; break; 51 case 6: Pred = Sign ? ICmpInst::ICMP_SLE : ICmpInst::ICMP_ULE; break; 52 case 7: // True. 53 return ConstantInt::get(CmpInst::makeCmpResultType(OpTy), 1); 54 } 55 return nullptr; 56 } 57 58 bool llvm::predicatesFoldable(ICmpInst::Predicate P1, ICmpInst::Predicate P2) { 59 return (CmpInst::isSigned(P1) == CmpInst::isSigned(P2)) || 60 (CmpInst::isSigned(P1) && ICmpInst::isEquality(P2)) || 61 (CmpInst::isSigned(P2) && ICmpInst::isEquality(P1)); 62 } 63 64 Constant *llvm::getPredForFCmpCode(unsigned Code, Type *OpTy, 65 CmpInst::Predicate &Pred) { 66 Pred = static_cast<FCmpInst::Predicate>(Code); 67 assert(FCmpInst::FCMP_FALSE <= Pred && Pred <= FCmpInst::FCMP_TRUE && 68 "Unexpected FCmp predicate!"); 69 if (Pred == FCmpInst::FCMP_FALSE) 70 return ConstantInt::get(CmpInst::makeCmpResultType(OpTy), 0); 71 if (Pred == FCmpInst::FCMP_TRUE) 72 return ConstantInt::get(CmpInst::makeCmpResultType(OpTy), 1); 73 return nullptr; 74 } 75 76 bool llvm::decomposeBitTestICmp(Value *LHS, Value *RHS, 77 CmpInst::Predicate &Pred, 78 Value *&X, APInt &Mask, bool LookThruTrunc) { 79 using namespace PatternMatch; 80 81 const APInt *C; 82 if (!match(RHS, m_APIntAllowUndef(C))) 83 return false; 84 85 switch (Pred) { 86 default: 87 return false; 88 case ICmpInst::ICMP_SLT: 89 // X < 0 is equivalent to (X & SignMask) != 0. 90 if (!C->isZero()) 91 return false; 92 Mask = APInt::getSignMask(C->getBitWidth()); 93 Pred = ICmpInst::ICMP_NE; 94 break; 95 case ICmpInst::ICMP_SLE: 96 // X <= -1 is equivalent to (X & SignMask) != 0. 97 if (!C->isAllOnes()) 98 return false; 99 Mask = APInt::getSignMask(C->getBitWidth()); 100 Pred = ICmpInst::ICMP_NE; 101 break; 102 case ICmpInst::ICMP_SGT: 103 // X > -1 is equivalent to (X & SignMask) == 0. 104 if (!C->isAllOnes()) 105 return false; 106 Mask = APInt::getSignMask(C->getBitWidth()); 107 Pred = ICmpInst::ICMP_EQ; 108 break; 109 case ICmpInst::ICMP_SGE: 110 // X >= 0 is equivalent to (X & SignMask) == 0. 111 if (!C->isZero()) 112 return false; 113 Mask = APInt::getSignMask(C->getBitWidth()); 114 Pred = ICmpInst::ICMP_EQ; 115 break; 116 case ICmpInst::ICMP_ULT: 117 // X <u 2^n is equivalent to (X & ~(2^n-1)) == 0. 118 if (!C->isPowerOf2()) 119 return false; 120 Mask = -*C; 121 Pred = ICmpInst::ICMP_EQ; 122 break; 123 case ICmpInst::ICMP_ULE: 124 // X <=u 2^n-1 is equivalent to (X & ~(2^n-1)) == 0. 125 if (!(*C + 1).isPowerOf2()) 126 return false; 127 Mask = ~*C; 128 Pred = ICmpInst::ICMP_EQ; 129 break; 130 case ICmpInst::ICMP_UGT: 131 // X >u 2^n-1 is equivalent to (X & ~(2^n-1)) != 0. 132 if (!(*C + 1).isPowerOf2()) 133 return false; 134 Mask = ~*C; 135 Pred = ICmpInst::ICMP_NE; 136 break; 137 case ICmpInst::ICMP_UGE: 138 // X >=u 2^n is equivalent to (X & ~(2^n-1)) != 0. 139 if (!C->isPowerOf2()) 140 return false; 141 Mask = -*C; 142 Pred = ICmpInst::ICMP_NE; 143 break; 144 } 145 146 if (LookThruTrunc && match(LHS, m_Trunc(m_Value(X)))) { 147 Mask = Mask.zext(X->getType()->getScalarSizeInBits()); 148 } else { 149 X = LHS; 150 } 151 152 return true; 153 } 154