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 bool llvm::decomposeBitTestICmp(Value *LHS, Value *RHS, 65 CmpInst::Predicate &Pred, 66 Value *&X, APInt &Mask, bool LookThruTrunc) { 67 using namespace PatternMatch; 68 69 const APInt *C; 70 if (!match(RHS, m_APInt(C))) 71 return false; 72 73 switch (Pred) { 74 default: 75 return false; 76 case ICmpInst::ICMP_SLT: 77 // X < 0 is equivalent to (X & SignMask) != 0. 78 if (!C->isZero()) 79 return false; 80 Mask = APInt::getSignMask(C->getBitWidth()); 81 Pred = ICmpInst::ICMP_NE; 82 break; 83 case ICmpInst::ICMP_SLE: 84 // X <= -1 is equivalent to (X & SignMask) != 0. 85 if (!C->isAllOnes()) 86 return false; 87 Mask = APInt::getSignMask(C->getBitWidth()); 88 Pred = ICmpInst::ICMP_NE; 89 break; 90 case ICmpInst::ICMP_SGT: 91 // X > -1 is equivalent to (X & SignMask) == 0. 92 if (!C->isAllOnes()) 93 return false; 94 Mask = APInt::getSignMask(C->getBitWidth()); 95 Pred = ICmpInst::ICMP_EQ; 96 break; 97 case ICmpInst::ICMP_SGE: 98 // X >= 0 is equivalent to (X & SignMask) == 0. 99 if (!C->isZero()) 100 return false; 101 Mask = APInt::getSignMask(C->getBitWidth()); 102 Pred = ICmpInst::ICMP_EQ; 103 break; 104 case ICmpInst::ICMP_ULT: 105 // X <u 2^n is equivalent to (X & ~(2^n-1)) == 0. 106 if (!C->isPowerOf2()) 107 return false; 108 Mask = -*C; 109 Pred = ICmpInst::ICMP_EQ; 110 break; 111 case ICmpInst::ICMP_ULE: 112 // X <=u 2^n-1 is equivalent to (X & ~(2^n-1)) == 0. 113 if (!(*C + 1).isPowerOf2()) 114 return false; 115 Mask = ~*C; 116 Pred = ICmpInst::ICMP_EQ; 117 break; 118 case ICmpInst::ICMP_UGT: 119 // X >u 2^n-1 is equivalent to (X & ~(2^n-1)) != 0. 120 if (!(*C + 1).isPowerOf2()) 121 return false; 122 Mask = ~*C; 123 Pred = ICmpInst::ICMP_NE; 124 break; 125 case ICmpInst::ICMP_UGE: 126 // X >=u 2^n is equivalent to (X & ~(2^n-1)) != 0. 127 if (!C->isPowerOf2()) 128 return false; 129 Mask = -*C; 130 Pred = ICmpInst::ICMP_NE; 131 break; 132 } 133 134 if (LookThruTrunc && match(LHS, m_Trunc(m_Value(X)))) { 135 Mask = Mask.zext(X->getType()->getScalarSizeInBits()); 136 } else { 137 X = LHS; 138 } 139 140 return true; 141 } 142