xref: /freebsd/contrib/llvm-project/llvm/lib/Analysis/ValueLattice.cpp (revision bdd1243df58e60e85101c09001d9812a789b6bc4)
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 *
getCompare(CmpInst::Predicate Pred,Type * Ty,const ValueLatticeElement & Other,const DataLayout & DL) const14 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 
operator <<(raw_ostream & OS,const ValueLatticeElement & Val)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