blob: 07fd94e29a1fb6f4670359621bbee9c3557ee6ee [file] [log] [blame]
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001//===- llvm/Support/KnownBits.h - Stores known zeros/ones -------*- C++ -*-===//
2//
Andrew Walbran16937d02019-10-22 13:54:20 +01003// 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
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01006//
7//===----------------------------------------------------------------------===//
8//
9// This file contains a class for representing known zeros and ones used by
10// computeKnownBits.
11//
12//===----------------------------------------------------------------------===//
13
14#ifndef LLVM_SUPPORT_KNOWNBITS_H
15#define LLVM_SUPPORT_KNOWNBITS_H
16
17#include "llvm/ADT/APInt.h"
18
19namespace llvm {
20
21// Struct for tracking the known zeros and ones of a value.
22struct KnownBits {
23 APInt Zero;
24 APInt One;
25
26private:
27 // Internal constructor for creating a KnownBits from two APInts.
28 KnownBits(APInt Zero, APInt One)
29 : Zero(std::move(Zero)), One(std::move(One)) {}
30
31public:
32 // Default construct Zero and One.
33 KnownBits() {}
34
35 /// Create a known bits object of BitWidth bits initialized to unknown.
36 KnownBits(unsigned BitWidth) : Zero(BitWidth, 0), One(BitWidth, 0) {}
37
38 /// Get the bit width of this value.
39 unsigned getBitWidth() const {
40 assert(Zero.getBitWidth() == One.getBitWidth() &&
41 "Zero and One should have the same width!");
42 return Zero.getBitWidth();
43 }
44
45 /// Returns true if there is conflicting information.
46 bool hasConflict() const { return Zero.intersects(One); }
47
48 /// Returns true if we know the value of all bits.
49 bool isConstant() const {
50 assert(!hasConflict() && "KnownBits conflict!");
51 return Zero.countPopulation() + One.countPopulation() == getBitWidth();
52 }
53
54 /// Returns the value when all bits have a known value. This just returns One
55 /// with a protective assertion.
56 const APInt &getConstant() const {
57 assert(isConstant() && "Can only get value when all bits are known");
58 return One;
59 }
60
61 /// Returns true if we don't know any bits.
62 bool isUnknown() const { return Zero.isNullValue() && One.isNullValue(); }
63
64 /// Resets the known state of all bits.
65 void resetAll() {
66 Zero.clearAllBits();
67 One.clearAllBits();
68 }
69
70 /// Returns true if value is all zero.
71 bool isZero() const {
72 assert(!hasConflict() && "KnownBits conflict!");
73 return Zero.isAllOnesValue();
74 }
75
76 /// Returns true if value is all one bits.
77 bool isAllOnes() const {
78 assert(!hasConflict() && "KnownBits conflict!");
79 return One.isAllOnesValue();
80 }
81
82 /// Make all bits known to be zero and discard any previous information.
83 void setAllZero() {
84 Zero.setAllBits();
85 One.clearAllBits();
86 }
87
88 /// Make all bits known to be one and discard any previous information.
89 void setAllOnes() {
90 Zero.clearAllBits();
91 One.setAllBits();
92 }
93
94 /// Returns true if this value is known to be negative.
95 bool isNegative() const { return One.isSignBitSet(); }
96
97 /// Returns true if this value is known to be non-negative.
98 bool isNonNegative() const { return Zero.isSignBitSet(); }
99
100 /// Make this value negative.
101 void makeNegative() {
102 One.setSignBit();
103 }
104
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100105 /// Make this value non-negative.
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100106 void makeNonNegative() {
107 Zero.setSignBit();
108 }
109
110 /// Truncate the underlying known Zero and One bits. This is equivalent
111 /// to truncating the value we're tracking.
Andrew Walbran3d2c1972020-04-07 12:24:26 +0100112 KnownBits trunc(unsigned BitWidth) const {
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100113 return KnownBits(Zero.trunc(BitWidth), One.trunc(BitWidth));
114 }
115
Andrew Walbran3d2c1972020-04-07 12:24:26 +0100116 /// Extends the underlying known Zero and One bits.
117 /// By setting ExtendedBitsAreKnownZero=true this will be equivalent to
118 /// zero extending the value we're tracking.
119 /// With ExtendedBitsAreKnownZero=false the extended bits are set to unknown.
120 KnownBits zext(unsigned BitWidth, bool ExtendedBitsAreKnownZero) const {
121 unsigned OldBitWidth = getBitWidth();
122 APInt NewZero = Zero.zext(BitWidth);
123 if (ExtendedBitsAreKnownZero)
124 NewZero.setBitsFrom(OldBitWidth);
125 return KnownBits(NewZero, One.zext(BitWidth));
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100126 }
127
128 /// Sign extends the underlying known Zero and One bits. This is equivalent
129 /// to sign extending the value we're tracking.
Andrew Walbran3d2c1972020-04-07 12:24:26 +0100130 KnownBits sext(unsigned BitWidth) const {
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100131 return KnownBits(Zero.sext(BitWidth), One.sext(BitWidth));
132 }
133
Andrew Walbran3d2c1972020-04-07 12:24:26 +0100134 /// Extends or truncates the underlying known Zero and One bits. When
135 /// extending the extended bits can either be set as known zero (if
136 /// ExtendedBitsAreKnownZero=true) or as unknown (if
137 /// ExtendedBitsAreKnownZero=false).
138 KnownBits zextOrTrunc(unsigned BitWidth,
139 bool ExtendedBitsAreKnownZero) const {
140 if (BitWidth > getBitWidth())
141 return zext(BitWidth, ExtendedBitsAreKnownZero);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100142 return KnownBits(Zero.zextOrTrunc(BitWidth), One.zextOrTrunc(BitWidth));
143 }
144
145 /// Returns the minimum number of trailing zero bits.
146 unsigned countMinTrailingZeros() const {
147 return Zero.countTrailingOnes();
148 }
149
150 /// Returns the minimum number of trailing one bits.
151 unsigned countMinTrailingOnes() const {
152 return One.countTrailingOnes();
153 }
154
155 /// Returns the minimum number of leading zero bits.
156 unsigned countMinLeadingZeros() const {
157 return Zero.countLeadingOnes();
158 }
159
160 /// Returns the minimum number of leading one bits.
161 unsigned countMinLeadingOnes() const {
162 return One.countLeadingOnes();
163 }
164
165 /// Returns the number of times the sign bit is replicated into the other
166 /// bits.
167 unsigned countMinSignBits() const {
168 if (isNonNegative())
169 return countMinLeadingZeros();
170 if (isNegative())
171 return countMinLeadingOnes();
172 return 0;
173 }
174
175 /// Returns the maximum number of trailing zero bits possible.
176 unsigned countMaxTrailingZeros() const {
177 return One.countTrailingZeros();
178 }
179
180 /// Returns the maximum number of trailing one bits possible.
181 unsigned countMaxTrailingOnes() const {
182 return Zero.countTrailingZeros();
183 }
184
185 /// Returns the maximum number of leading zero bits possible.
186 unsigned countMaxLeadingZeros() const {
187 return One.countLeadingZeros();
188 }
189
190 /// Returns the maximum number of leading one bits possible.
191 unsigned countMaxLeadingOnes() const {
192 return Zero.countLeadingZeros();
193 }
194
195 /// Returns the number of bits known to be one.
196 unsigned countMinPopulation() const {
197 return One.countPopulation();
198 }
199
200 /// Returns the maximum number of bits that could be one.
201 unsigned countMaxPopulation() const {
202 return getBitWidth() - Zero.countPopulation();
203 }
204
Andrew Walbran3d2c1972020-04-07 12:24:26 +0100205 /// Compute known bits resulting from adding LHS, RHS and a 1-bit Carry.
206 static KnownBits computeForAddCarry(
207 const KnownBits &LHS, const KnownBits &RHS, const KnownBits &Carry);
208
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100209 /// Compute known bits resulting from adding LHS and RHS.
210 static KnownBits computeForAddSub(bool Add, bool NSW, const KnownBits &LHS,
211 KnownBits RHS);
212};
213
214} // end namespace llvm
215
216#endif