• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //===- llvm/Support/KnownBits.h - Stores known zeros/ones -------*- 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 // 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 
19 namespace llvm {
20 
21 // Struct for tracking the known zeros and ones of a value.
22 struct KnownBits {
23   APInt Zero;
24   APInt One;
25 
26 private:
27   // Internal constructor for creating a KnownBits from two APInts.
KnownBitsKnownBits28   KnownBits(APInt Zero, APInt One)
29       : Zero(std::move(Zero)), One(std::move(One)) {}
30 
31 public:
32   // Default construct Zero and One.
KnownBitsKnownBits33   KnownBits() {}
34 
35   /// Create a known bits object of BitWidth bits initialized to unknown.
KnownBitsKnownBits36   KnownBits(unsigned BitWidth) : Zero(BitWidth, 0), One(BitWidth, 0) {}
37 
38   /// Get the bit width of this value.
getBitWidthKnownBits39   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.
hasConflictKnownBits46   bool hasConflict() const { return Zero.intersects(One); }
47 
48   /// Returns true if we know the value of all bits.
isConstantKnownBits49   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.
getConstantKnownBits56   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.
isUnknownKnownBits62   bool isUnknown() const { return Zero.isNullValue() && One.isNullValue(); }
63 
64   /// Resets the known state of all bits.
resetAllKnownBits65   void resetAll() {
66     Zero.clearAllBits();
67     One.clearAllBits();
68   }
69 
70   /// Returns true if value is all zero.
isZeroKnownBits71   bool isZero() const {
72     assert(!hasConflict() && "KnownBits conflict!");
73     return Zero.isAllOnesValue();
74   }
75 
76   /// Returns true if value is all one bits.
isAllOnesKnownBits77   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.
setAllZeroKnownBits83   void setAllZero() {
84     Zero.setAllBits();
85     One.clearAllBits();
86   }
87 
88   /// Make all bits known to be one and discard any previous information.
setAllOnesKnownBits89   void setAllOnes() {
90     Zero.clearAllBits();
91     One.setAllBits();
92   }
93 
94   /// Returns true if this value is known to be negative.
isNegativeKnownBits95   bool isNegative() const { return One.isSignBitSet(); }
96 
97   /// Returns true if this value is known to be non-negative.
isNonNegativeKnownBits98   bool isNonNegative() const { return Zero.isSignBitSet(); }
99 
100   /// Returns true if this value is known to be non-zero.
isNonZeroKnownBits101   bool isNonZero() const { return !One.isNullValue(); }
102 
103   /// Returns true if this value is known to be positive.
isStrictlyPositiveKnownBits104   bool isStrictlyPositive() const { return Zero.isSignBitSet() && !One.isNullValue(); }
105 
106   /// Make this value negative.
makeNegativeKnownBits107   void makeNegative() {
108     One.setSignBit();
109   }
110 
111   /// Make this value non-negative.
makeNonNegativeKnownBits112   void makeNonNegative() {
113     Zero.setSignBit();
114   }
115 
116   /// Return the minimal value possible given these KnownBits.
getMinValueKnownBits117   APInt getMinValue() const {
118     // Assume that all bits that aren't known-ones are zeros.
119     return One;
120   }
121 
122   /// Return the maximal value possible given these KnownBits.
getMaxValueKnownBits123   APInt getMaxValue() const {
124     // Assume that all bits that aren't known-zeros are ones.
125     return ~Zero;
126   }
127 
128   /// Return known bits for a truncation of the value we're tracking.
truncKnownBits129   KnownBits trunc(unsigned BitWidth) const {
130     return KnownBits(Zero.trunc(BitWidth), One.trunc(BitWidth));
131   }
132 
133   /// Return known bits for an "any" extension of the value we're tracking,
134   /// where we don't know anything about the extended bits.
anyextKnownBits135   KnownBits anyext(unsigned BitWidth) const {
136     return KnownBits(Zero.zext(BitWidth), One.zext(BitWidth));
137   }
138 
139   /// Return known bits for a zero extension of the value we're tracking.
zextKnownBits140   KnownBits zext(unsigned BitWidth) const {
141     unsigned OldBitWidth = getBitWidth();
142     APInt NewZero = Zero.zext(BitWidth);
143     NewZero.setBitsFrom(OldBitWidth);
144     return KnownBits(NewZero, One.zext(BitWidth));
145   }
146 
147   /// Return known bits for a sign extension of the value we're tracking.
sextKnownBits148   KnownBits sext(unsigned BitWidth) const {
149     return KnownBits(Zero.sext(BitWidth), One.sext(BitWidth));
150   }
151 
152   /// Return known bits for an "any" extension or truncation of the value we're
153   /// tracking.
anyextOrTruncKnownBits154   KnownBits anyextOrTrunc(unsigned BitWidth) const {
155     if (BitWidth > getBitWidth())
156       return anyext(BitWidth);
157     if (BitWidth < getBitWidth())
158       return trunc(BitWidth);
159     return *this;
160   }
161 
162   /// Return known bits for a zero extension or truncation of the value we're
163   /// tracking.
zextOrTruncKnownBits164   KnownBits zextOrTrunc(unsigned BitWidth) const {
165     if (BitWidth > getBitWidth())
166       return zext(BitWidth);
167     if (BitWidth < getBitWidth())
168       return trunc(BitWidth);
169     return *this;
170   }
171 
172   /// Return known bits for a sign extension or truncation of the value we're
173   /// tracking.
sextOrTruncKnownBits174   KnownBits sextOrTrunc(unsigned BitWidth) const {
175     if (BitWidth > getBitWidth())
176       return sext(BitWidth);
177     if (BitWidth < getBitWidth())
178       return trunc(BitWidth);
179     return *this;
180   }
181 
182   /// Return known bits for a in-register sign extension of the value we're
183   /// tracking.
184   KnownBits sextInReg(unsigned SrcBitWidth) const;
185 
186   /// Return a KnownBits with the extracted bits
187   /// [bitPosition,bitPosition+numBits).
extractBitsKnownBits188   KnownBits extractBits(unsigned NumBits, unsigned BitPosition) const {
189     return KnownBits(Zero.extractBits(NumBits, BitPosition),
190                      One.extractBits(NumBits, BitPosition));
191   }
192 
193   /// Return KnownBits based on this, but updated given that the underlying
194   /// value is known to be greater than or equal to Val.
195   KnownBits makeGE(const APInt &Val) const;
196 
197   /// Returns the minimum number of trailing zero bits.
countMinTrailingZerosKnownBits198   unsigned countMinTrailingZeros() const {
199     return Zero.countTrailingOnes();
200   }
201 
202   /// Returns the minimum number of trailing one bits.
countMinTrailingOnesKnownBits203   unsigned countMinTrailingOnes() const {
204     return One.countTrailingOnes();
205   }
206 
207   /// Returns the minimum number of leading zero bits.
countMinLeadingZerosKnownBits208   unsigned countMinLeadingZeros() const {
209     return Zero.countLeadingOnes();
210   }
211 
212   /// Returns the minimum number of leading one bits.
countMinLeadingOnesKnownBits213   unsigned countMinLeadingOnes() const {
214     return One.countLeadingOnes();
215   }
216 
217   /// Returns the number of times the sign bit is replicated into the other
218   /// bits.
countMinSignBitsKnownBits219   unsigned countMinSignBits() const {
220     if (isNonNegative())
221       return countMinLeadingZeros();
222     if (isNegative())
223       return countMinLeadingOnes();
224     return 0;
225   }
226 
227   /// Returns the maximum number of trailing zero bits possible.
countMaxTrailingZerosKnownBits228   unsigned countMaxTrailingZeros() const {
229     return One.countTrailingZeros();
230   }
231 
232   /// Returns the maximum number of trailing one bits possible.
countMaxTrailingOnesKnownBits233   unsigned countMaxTrailingOnes() const {
234     return Zero.countTrailingZeros();
235   }
236 
237   /// Returns the maximum number of leading zero bits possible.
countMaxLeadingZerosKnownBits238   unsigned countMaxLeadingZeros() const {
239     return One.countLeadingZeros();
240   }
241 
242   /// Returns the maximum number of leading one bits possible.
countMaxLeadingOnesKnownBits243   unsigned countMaxLeadingOnes() const {
244     return Zero.countLeadingZeros();
245   }
246 
247   /// Returns the number of bits known to be one.
countMinPopulationKnownBits248   unsigned countMinPopulation() const {
249     return One.countPopulation();
250   }
251 
252   /// Returns the maximum number of bits that could be one.
countMaxPopulationKnownBits253   unsigned countMaxPopulation() const {
254     return getBitWidth() - Zero.countPopulation();
255   }
256 
257   /// Create known bits from a known constant.
makeConstantKnownBits258   static KnownBits makeConstant(const APInt &C) {
259     return KnownBits(~C, C);
260   }
261 
262   /// Compute known bits common to LHS and RHS.
commonBitsKnownBits263   static KnownBits commonBits(const KnownBits &LHS, const KnownBits &RHS) {
264     return KnownBits(LHS.Zero & RHS.Zero, LHS.One & RHS.One);
265   }
266 
267   /// Compute known bits resulting from adding LHS, RHS and a 1-bit Carry.
268   static KnownBits computeForAddCarry(
269       const KnownBits &LHS, const KnownBits &RHS, const KnownBits &Carry);
270 
271   /// Compute known bits resulting from adding LHS and RHS.
272   static KnownBits computeForAddSub(bool Add, bool NSW, const KnownBits &LHS,
273                                     KnownBits RHS);
274 
275   /// Compute known bits resulting from multiplying LHS and RHS.
276   static KnownBits computeForMul(const KnownBits &LHS, const KnownBits &RHS);
277 
278   /// Compute known bits for udiv(LHS, RHS).
279   static KnownBits udiv(const KnownBits &LHS, const KnownBits &RHS);
280 
281   /// Compute known bits for urem(LHS, RHS).
282   static KnownBits urem(const KnownBits &LHS, const KnownBits &RHS);
283 
284   /// Compute known bits for srem(LHS, RHS).
285   static KnownBits srem(const KnownBits &LHS, const KnownBits &RHS);
286 
287   /// Compute known bits for umax(LHS, RHS).
288   static KnownBits umax(const KnownBits &LHS, const KnownBits &RHS);
289 
290   /// Compute known bits for umin(LHS, RHS).
291   static KnownBits umin(const KnownBits &LHS, const KnownBits &RHS);
292 
293   /// Compute known bits for smax(LHS, RHS).
294   static KnownBits smax(const KnownBits &LHS, const KnownBits &RHS);
295 
296   /// Compute known bits for smin(LHS, RHS).
297   static KnownBits smin(const KnownBits &LHS, const KnownBits &RHS);
298 
299   /// Compute known bits for shl(LHS, RHS).
300   /// NOTE: RHS (shift amount) bitwidth doesn't need to be the same as LHS.
301   static KnownBits shl(const KnownBits &LHS, const KnownBits &RHS);
302 
303   /// Compute known bits for lshr(LHS, RHS).
304   /// NOTE: RHS (shift amount) bitwidth doesn't need to be the same as LHS.
305   static KnownBits lshr(const KnownBits &LHS, const KnownBits &RHS);
306 
307   /// Compute known bits for ashr(LHS, RHS).
308   /// NOTE: RHS (shift amount) bitwidth doesn't need to be the same as LHS.
309   static KnownBits ashr(const KnownBits &LHS, const KnownBits &RHS);
310 
311   /// Insert the bits from a smaller known bits starting at bitPosition.
insertBitsKnownBits312   void insertBits(const KnownBits &SubBits, unsigned BitPosition) {
313     Zero.insertBits(SubBits.Zero, BitPosition);
314     One.insertBits(SubBits.One, BitPosition);
315   }
316 
317   /// Return a subset of the known bits from [bitPosition,bitPosition+numBits).
extractBitsKnownBits318   KnownBits extractBits(unsigned NumBits, unsigned BitPosition) {
319     return KnownBits(Zero.extractBits(NumBits, BitPosition),
320                      One.extractBits(NumBits, BitPosition));
321   }
322 
323   /// Update known bits based on ANDing with RHS.
324   KnownBits &operator&=(const KnownBits &RHS);
325 
326   /// Update known bits based on ORing with RHS.
327   KnownBits &operator|=(const KnownBits &RHS);
328 
329   /// Update known bits based on XORing with RHS.
330   KnownBits &operator^=(const KnownBits &RHS);
331 
332   /// Compute known bits for the absolute value.
333   KnownBits abs(bool IntMinIsPoison = false) const;
334 
byteSwapKnownBits335   KnownBits byteSwap() {
336     return KnownBits(Zero.byteSwap(), One.byteSwap());
337   }
338 
reverseBitsKnownBits339   KnownBits reverseBits() {
340     return KnownBits(Zero.reverseBits(), One.reverseBits());
341   }
342 };
343 
344 inline KnownBits operator&(KnownBits LHS, const KnownBits &RHS) {
345   LHS &= RHS;
346   return LHS;
347 }
348 
349 inline KnownBits operator&(const KnownBits &LHS, KnownBits &&RHS) {
350   RHS &= LHS;
351   return std::move(RHS);
352 }
353 
354 inline KnownBits operator|(KnownBits LHS, const KnownBits &RHS) {
355   LHS |= RHS;
356   return LHS;
357 }
358 
359 inline KnownBits operator|(const KnownBits &LHS, KnownBits &&RHS) {
360   RHS |= LHS;
361   return std::move(RHS);
362 }
363 
364 inline KnownBits operator^(KnownBits LHS, const KnownBits &RHS) {
365   LHS ^= RHS;
366   return LHS;
367 }
368 
369 inline KnownBits operator^(const KnownBits &LHS, KnownBits &&RHS) {
370   RHS ^= LHS;
371   return std::move(RHS);
372 }
373 
374 } // end namespace llvm
375 
376 #endif
377