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(Predicate: Pred, LHS: getConstant(), |
28 | RHS: Other.getConstant(), DL); |
29 | |
30 | if (ICmpInst::isEquality(P: 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, Other: OtherCR)) |
48 | return ConstantInt::getTrue(Ty); |
49 | if (CR.icmp(Pred: CmpInst::getInversePredicate(pred: Pred), Other: 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(UndefAllowed: true).getLower() << ", " |
69 | << Val.getConstantRange(UndefAllowed: 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 | |