1 //===- llvm/Support/KnownBits.h - Stores known zeros/ones -------*- C++ -*-===//
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
7 //===----------------------------------------------------------------------===//
9 // This file contains a class for representing known zeros and ones used by
12 //===----------------------------------------------------------------------===//
14 #ifndef LLVM_SUPPORT_KNOWNBITS_H
15 #define LLVM_SUPPORT_KNOWNBITS_H
17 #include "llvm/ADT/APInt.h"
21 // Struct for tracking the known zeros and ones of a value.
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
)) {}
32 // Default construct Zero and One.
35 /// Create a known bits object of BitWidth bits initialized to unknown.
36 KnownBits(unsigned BitWidth
) : Zero(BitWidth
, 0), One(BitWidth
, 0) {}
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();
45 /// Returns true if there is conflicting information.
46 bool hasConflict() const { return Zero
.intersects(One
); }
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();
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");
61 /// Returns true if we don't know any bits.
62 bool isUnknown() const { return Zero
.isNullValue() && One
.isNullValue(); }
64 /// Resets the known state of all bits.
70 /// Returns true if value is all zero.
72 assert(!hasConflict() && "KnownBits conflict!");
73 return Zero
.isAllOnesValue();
76 /// Returns true if value is all one bits.
77 bool isAllOnes() const {
78 assert(!hasConflict() && "KnownBits conflict!");
79 return One
.isAllOnesValue();
82 /// Make all bits known to be zero and discard any previous information.
88 /// Make all bits known to be one and discard any previous information.
94 /// Returns true if this value is known to be negative.
95 bool isNegative() const { return One
.isSignBitSet(); }
97 /// Returns true if this value is known to be non-negative.
98 bool isNonNegative() const { return Zero
.isSignBitSet(); }
100 /// Make this value negative.
101 void makeNegative() {
105 /// Make this value non-negative.
106 void makeNonNegative() {
110 /// Truncate the underlying known Zero and One bits. This is equivalent
111 /// to truncating the value we're tracking.
112 KnownBits
trunc(unsigned BitWidth
) {
113 return KnownBits(Zero
.trunc(BitWidth
), One
.trunc(BitWidth
));
116 /// Zero extends the underlying known Zero and One bits. This is equivalent
117 /// to zero extending the value we're tracking.
118 KnownBits
zext(unsigned BitWidth
) {
119 return KnownBits(Zero
.zext(BitWidth
), One
.zext(BitWidth
));
122 /// Sign extends the underlying known Zero and One bits. This is equivalent
123 /// to sign extending the value we're tracking.
124 KnownBits
sext(unsigned BitWidth
) {
125 return KnownBits(Zero
.sext(BitWidth
), One
.sext(BitWidth
));
128 /// Zero extends or truncates the underlying known Zero and One bits. This is
129 /// equivalent to zero extending or truncating the value we're tracking.
130 KnownBits
zextOrTrunc(unsigned BitWidth
) {
131 return KnownBits(Zero
.zextOrTrunc(BitWidth
), One
.zextOrTrunc(BitWidth
));
134 /// Returns the minimum number of trailing zero bits.
135 unsigned countMinTrailingZeros() const {
136 return Zero
.countTrailingOnes();
139 /// Returns the minimum number of trailing one bits.
140 unsigned countMinTrailingOnes() const {
141 return One
.countTrailingOnes();
144 /// Returns the minimum number of leading zero bits.
145 unsigned countMinLeadingZeros() const {
146 return Zero
.countLeadingOnes();
149 /// Returns the minimum number of leading one bits.
150 unsigned countMinLeadingOnes() const {
151 return One
.countLeadingOnes();
154 /// Returns the number of times the sign bit is replicated into the other
156 unsigned countMinSignBits() const {
158 return countMinLeadingZeros();
160 return countMinLeadingOnes();
164 /// Returns the maximum number of trailing zero bits possible.
165 unsigned countMaxTrailingZeros() const {
166 return One
.countTrailingZeros();
169 /// Returns the maximum number of trailing one bits possible.
170 unsigned countMaxTrailingOnes() const {
171 return Zero
.countTrailingZeros();
174 /// Returns the maximum number of leading zero bits possible.
175 unsigned countMaxLeadingZeros() const {
176 return One
.countLeadingZeros();
179 /// Returns the maximum number of leading one bits possible.
180 unsigned countMaxLeadingOnes() const {
181 return Zero
.countLeadingZeros();
184 /// Returns the number of bits known to be one.
185 unsigned countMinPopulation() const {
186 return One
.countPopulation();
189 /// Returns the maximum number of bits that could be one.
190 unsigned countMaxPopulation() const {
191 return getBitWidth() - Zero
.countPopulation();
194 /// Compute known bits resulting from adding LHS and RHS.
195 static KnownBits
computeForAddSub(bool Add
, bool NSW
, const KnownBits
&LHS
,
199 } // end namespace llvm