Path: blob/main/contrib/llvm-project/llvm/lib/Analysis/CmpInstAnalysis.cpp
35234 views
//===- CmpInstAnalysis.cpp - Utils to help fold compares ---------------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7//8// This file holds routines to help analyse compare instructions9// and fold them into constants or other compare instructions10//11//===----------------------------------------------------------------------===//1213#include "llvm/Analysis/CmpInstAnalysis.h"14#include "llvm/IR/Constants.h"15#include "llvm/IR/Instructions.h"16#include "llvm/IR/PatternMatch.h"1718using namespace llvm;1920unsigned llvm::getICmpCode(CmpInst::Predicate Pred) {21switch (Pred) {22// False -> 023case ICmpInst::ICMP_UGT: return 1; // 00124case ICmpInst::ICMP_SGT: return 1; // 00125case ICmpInst::ICMP_EQ: return 2; // 01026case ICmpInst::ICMP_UGE: return 3; // 01127case ICmpInst::ICMP_SGE: return 3; // 01128case ICmpInst::ICMP_ULT: return 4; // 10029case ICmpInst::ICMP_SLT: return 4; // 10030case ICmpInst::ICMP_NE: return 5; // 10131case ICmpInst::ICMP_ULE: return 6; // 11032case ICmpInst::ICMP_SLE: return 6; // 11033// True -> 734default:35llvm_unreachable("Invalid ICmp predicate!");36}37}3839Constant *llvm::getPredForICmpCode(unsigned Code, bool Sign, Type *OpTy,40CmpInst::Predicate &Pred) {41switch (Code) {42default: llvm_unreachable("Illegal ICmp code!");43case 0: // False.44return ConstantInt::get(CmpInst::makeCmpResultType(OpTy), 0);45case 1: Pred = Sign ? ICmpInst::ICMP_SGT : ICmpInst::ICMP_UGT; break;46case 2: Pred = ICmpInst::ICMP_EQ; break;47case 3: Pred = Sign ? ICmpInst::ICMP_SGE : ICmpInst::ICMP_UGE; break;48case 4: Pred = Sign ? ICmpInst::ICMP_SLT : ICmpInst::ICMP_ULT; break;49case 5: Pred = ICmpInst::ICMP_NE; break;50case 6: Pred = Sign ? ICmpInst::ICMP_SLE : ICmpInst::ICMP_ULE; break;51case 7: // True.52return ConstantInt::get(CmpInst::makeCmpResultType(OpTy), 1);53}54return nullptr;55}5657bool llvm::predicatesFoldable(ICmpInst::Predicate P1, ICmpInst::Predicate P2) {58return (CmpInst::isSigned(P1) == CmpInst::isSigned(P2)) ||59(CmpInst::isSigned(P1) && ICmpInst::isEquality(P2)) ||60(CmpInst::isSigned(P2) && ICmpInst::isEquality(P1));61}6263Constant *llvm::getPredForFCmpCode(unsigned Code, Type *OpTy,64CmpInst::Predicate &Pred) {65Pred = static_cast<FCmpInst::Predicate>(Code);66assert(FCmpInst::FCMP_FALSE <= Pred && Pred <= FCmpInst::FCMP_TRUE &&67"Unexpected FCmp predicate!");68if (Pred == FCmpInst::FCMP_FALSE)69return ConstantInt::get(CmpInst::makeCmpResultType(OpTy), 0);70if (Pred == FCmpInst::FCMP_TRUE)71return ConstantInt::get(CmpInst::makeCmpResultType(OpTy), 1);72return nullptr;73}7475bool llvm::decomposeBitTestICmp(Value *LHS, Value *RHS,76CmpInst::Predicate &Pred,77Value *&X, APInt &Mask, bool LookThruTrunc) {78using namespace PatternMatch;7980const APInt *C;81if (!match(RHS, m_APIntAllowPoison(C)))82return false;8384switch (Pred) {85default:86return false;87case ICmpInst::ICMP_SLT:88// X < 0 is equivalent to (X & SignMask) != 0.89if (!C->isZero())90return false;91Mask = APInt::getSignMask(C->getBitWidth());92Pred = ICmpInst::ICMP_NE;93break;94case ICmpInst::ICMP_SLE:95// X <= -1 is equivalent to (X & SignMask) != 0.96if (!C->isAllOnes())97return false;98Mask = APInt::getSignMask(C->getBitWidth());99Pred = ICmpInst::ICMP_NE;100break;101case ICmpInst::ICMP_SGT:102// X > -1 is equivalent to (X & SignMask) == 0.103if (!C->isAllOnes())104return false;105Mask = APInt::getSignMask(C->getBitWidth());106Pred = ICmpInst::ICMP_EQ;107break;108case ICmpInst::ICMP_SGE:109// X >= 0 is equivalent to (X & SignMask) == 0.110if (!C->isZero())111return false;112Mask = APInt::getSignMask(C->getBitWidth());113Pred = ICmpInst::ICMP_EQ;114break;115case ICmpInst::ICMP_ULT:116// X <u 2^n is equivalent to (X & ~(2^n-1)) == 0.117if (!C->isPowerOf2())118return false;119Mask = -*C;120Pred = ICmpInst::ICMP_EQ;121break;122case ICmpInst::ICMP_ULE:123// X <=u 2^n-1 is equivalent to (X & ~(2^n-1)) == 0.124if (!(*C + 1).isPowerOf2())125return false;126Mask = ~*C;127Pred = ICmpInst::ICMP_EQ;128break;129case ICmpInst::ICMP_UGT:130// X >u 2^n-1 is equivalent to (X & ~(2^n-1)) != 0.131if (!(*C + 1).isPowerOf2())132return false;133Mask = ~*C;134Pred = ICmpInst::ICMP_NE;135break;136case ICmpInst::ICMP_UGE:137// X >=u 2^n is equivalent to (X & ~(2^n-1)) != 0.138if (!C->isPowerOf2())139return false;140Mask = -*C;141Pred = ICmpInst::ICMP_NE;142break;143}144145if (LookThruTrunc && match(LHS, m_Trunc(m_Value(X)))) {146Mask = Mask.zext(X->getType()->getScalarSizeInBits());147} else {148X = LHS;149}150151return true;152}153154155