1 //===- ValueLattice.cpp - Value constraint analysis -------------*- 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 #include "llvm/Analysis/ValueLattice.h" 10 #include "llvm/Analysis/ConstantFolding.h" 11 12 namespace llvm { 13 Constant * 14 ValueLatticeElement::getCompare(CmpInst::Predicate Pred, Type *Ty, 15 const ValueLatticeElement &Other, 16 const DataLayout &DL) const { 17 // Not yet resolved. 18 if (isUnknown() || Other.isUnknown()) 19 return nullptr; 20 21 // TODO: Can be made more precise, but always returning undef would be 22 // incorrect. 23 if (isUndef() || Other.isUndef()) 24 return nullptr; 25 26 if (isConstant() && Other.isConstant()) 27 return ConstantFoldCompareInstOperands(Pred, getConstant(), 28 Other.getConstant(), DL); 29 30 if (ICmpInst::isEquality(Pred)) { 31 // not(C) != C => true, not(C) == C => false. 32 if ((isNotConstant() && Other.isConstant() && 33 getNotConstant() == Other.getConstant()) || 34 (isConstant() && Other.isNotConstant() && 35 getConstant() == Other.getNotConstant())) 36 return Pred == ICmpInst::ICMP_NE ? ConstantInt::getTrue(Ty) 37 : ConstantInt::getFalse(Ty); 38 } 39 40 // Integer constants are represented as ConstantRanges with single 41 // elements. 42 if (!isConstantRange() || !Other.isConstantRange()) 43 return nullptr; 44 45 const auto &CR = getConstantRange(); 46 const auto &OtherCR = Other.getConstantRange(); 47 if (CR.icmp(Pred, OtherCR)) 48 return ConstantInt::getTrue(Ty); 49 if (CR.icmp(CmpInst::getInversePredicate(Pred), OtherCR)) 50 return ConstantInt::getFalse(Ty); 51 52 return nullptr; 53 } 54 55 raw_ostream &operator<<(raw_ostream &OS, const ValueLatticeElement &Val) { 56 if (Val.isUnknown()) 57 return OS << "unknown"; 58 if (Val.isUndef()) 59 return OS << "undef"; 60 if (Val.isOverdefined()) 61 return OS << "overdefined"; 62 63 if (Val.isNotConstant()) 64 return OS << "notconstant<" << *Val.getNotConstant() << ">"; 65 66 if (Val.isConstantRangeIncludingUndef()) 67 return OS << "constantrange incl. undef <" 68 << Val.getConstantRange(true).getLower() << ", " 69 << Val.getConstantRange(true).getUpper() << ">"; 70 71 if (Val.isConstantRange()) 72 return OS << "constantrange<" << Val.getConstantRange().getLower() << ", " 73 << Val.getConstantRange().getUpper() << ">"; 74 return OS << "constant<" << *Val.getConstant() << ">"; 75 } 76 } // end namespace llvm 77