1b498a23fSCraig Topper //===-- KnownBits.cpp - Stores known zeros/ones ---------------------------===//
2b498a23fSCraig Topper //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6b498a23fSCraig Topper //
7b498a23fSCraig Topper //===----------------------------------------------------------------------===//
8b498a23fSCraig Topper //
9b498a23fSCraig Topper // This file contains a class for representing known zeros and ones used by
10b498a23fSCraig Topper // computeKnownBits.
11b498a23fSCraig Topper //
12b498a23fSCraig Topper //===----------------------------------------------------------------------===//
13b498a23fSCraig Topper
14b498a23fSCraig Topper #include "llvm/Support/KnownBits.h"
15115a42adSPhilip Reames #include "llvm/Support/Debug.h"
16115a42adSPhilip Reames #include "llvm/Support/raw_ostream.h"
17eb812efaSJoerg Sonnenberger #include <cassert>
18b498a23fSCraig Topper
19b498a23fSCraig Topper using namespace llvm;
20b498a23fSCraig Topper
computeForAddCarry(const KnownBits & LHS,const KnownBits & RHS,bool CarryZero,bool CarryOne)217671fc71SNikita Popov static KnownBits computeForAddCarry(
227671fc71SNikita Popov const KnownBits &LHS, const KnownBits &RHS,
237671fc71SNikita Popov bool CarryZero, bool CarryOne) {
247671fc71SNikita Popov assert(!(CarryZero && CarryOne) &&
257671fc71SNikita Popov "Carry can't be zero and one at the same time");
26b498a23fSCraig Topper
279a20c79dSRoman Lebedev APInt PossibleSumZero = LHS.getMaxValue() + RHS.getMaxValue() + !CarryZero;
289a20c79dSRoman Lebedev APInt PossibleSumOne = LHS.getMinValue() + RHS.getMinValue() + CarryOne;
29b498a23fSCraig Topper
30b498a23fSCraig Topper // Compute known bits of the carry.
31b498a23fSCraig Topper APInt CarryKnownZero = ~(PossibleSumZero ^ LHS.Zero ^ RHS.Zero);
32b498a23fSCraig Topper APInt CarryKnownOne = PossibleSumOne ^ LHS.One ^ RHS.One;
33b498a23fSCraig Topper
34b498a23fSCraig Topper // Compute set of known bits (where all three relevant bits are known).
35b498a23fSCraig Topper APInt LHSKnownUnion = LHS.Zero | LHS.One;
36b498a23fSCraig Topper APInt RHSKnownUnion = RHS.Zero | RHS.One;
37b498a23fSCraig Topper APInt CarryKnownUnion = std::move(CarryKnownZero) | CarryKnownOne;
38b498a23fSCraig Topper APInt Known = std::move(LHSKnownUnion) & RHSKnownUnion & CarryKnownUnion;
39b498a23fSCraig Topper
40b498a23fSCraig Topper assert((PossibleSumZero & Known) == (PossibleSumOne & Known) &&
41b498a23fSCraig Topper "known bits of sum differ");
42b498a23fSCraig Topper
43b498a23fSCraig Topper // Compute known bits of the result.
44b498a23fSCraig Topper KnownBits KnownOut;
45b498a23fSCraig Topper KnownOut.Zero = ~std::move(PossibleSumZero) & Known;
46b498a23fSCraig Topper KnownOut.One = std::move(PossibleSumOne) & Known;
477671fc71SNikita Popov return KnownOut;
487671fc71SNikita Popov }
497671fc71SNikita Popov
computeForAddCarry(const KnownBits & LHS,const KnownBits & RHS,const KnownBits & Carry)507671fc71SNikita Popov KnownBits KnownBits::computeForAddCarry(
517671fc71SNikita Popov const KnownBits &LHS, const KnownBits &RHS, const KnownBits &Carry) {
527671fc71SNikita Popov assert(Carry.getBitWidth() == 1 && "Carry must be 1-bit");
537671fc71SNikita Popov return ::computeForAddCarry(
547671fc71SNikita Popov LHS, RHS, Carry.Zero.getBoolValue(), Carry.One.getBoolValue());
557671fc71SNikita Popov }
567671fc71SNikita Popov
computeForAddSub(bool Add,bool NSW,const KnownBits & LHS,KnownBits RHS)577671fc71SNikita Popov KnownBits KnownBits::computeForAddSub(bool Add, bool NSW,
587671fc71SNikita Popov const KnownBits &LHS, KnownBits RHS) {
597671fc71SNikita Popov KnownBits KnownOut;
607671fc71SNikita Popov if (Add) {
617671fc71SNikita Popov // Sum = LHS + RHS + 0
627671fc71SNikita Popov KnownOut = ::computeForAddCarry(
637671fc71SNikita Popov LHS, RHS, /*CarryZero*/true, /*CarryOne*/false);
647671fc71SNikita Popov } else {
657671fc71SNikita Popov // Sum = LHS + ~RHS + 1
667671fc71SNikita Popov std::swap(RHS.Zero, RHS.One);
677671fc71SNikita Popov KnownOut = ::computeForAddCarry(
687671fc71SNikita Popov LHS, RHS, /*CarryZero*/false, /*CarryOne*/true);
697671fc71SNikita Popov }
70b498a23fSCraig Topper
71b498a23fSCraig Topper // Are we still trying to solve for the sign bit?
727671fc71SNikita Popov if (!KnownOut.isNegative() && !KnownOut.isNonNegative()) {
73b498a23fSCraig Topper if (NSW) {
74b498a23fSCraig Topper // Adding two non-negative numbers, or subtracting a negative number from
75b498a23fSCraig Topper // a non-negative one, can't wrap into negative.
76b498a23fSCraig Topper if (LHS.isNonNegative() && RHS.isNonNegative())
77b498a23fSCraig Topper KnownOut.makeNonNegative();
78b498a23fSCraig Topper // Adding two negative numbers, or subtracting a non-negative number from
79b498a23fSCraig Topper // a negative one, can't wrap into non-negative.
80b498a23fSCraig Topper else if (LHS.isNegative() && RHS.isNegative())
81b498a23fSCraig Topper KnownOut.makeNegative();
82b498a23fSCraig Topper }
83b498a23fSCraig Topper }
84b498a23fSCraig Topper
85b498a23fSCraig Topper return KnownOut;
86b498a23fSCraig Topper }
87c63aed89SJay Foad
sextInReg(unsigned SrcBitWidth) const889cf4f493SSimon Pilgrim KnownBits KnownBits::sextInReg(unsigned SrcBitWidth) const {
899cf4f493SSimon Pilgrim unsigned BitWidth = getBitWidth();
900b46f19aSSimon Pilgrim assert(0 < SrcBitWidth && SrcBitWidth <= BitWidth &&
910b46f19aSSimon Pilgrim "Illegal sext-in-register");
920b46f19aSSimon Pilgrim
930b46f19aSSimon Pilgrim if (SrcBitWidth == BitWidth)
940b46f19aSSimon Pilgrim return *this;
959cf4f493SSimon Pilgrim
96c0939fddSSimon Pilgrim unsigned ExtBits = BitWidth - SrcBitWidth;
979cf4f493SSimon Pilgrim KnownBits Result;
98c0939fddSSimon Pilgrim Result.One = One << ExtBits;
99c0939fddSSimon Pilgrim Result.Zero = Zero << ExtBits;
100c0939fddSSimon Pilgrim Result.One.ashrInPlace(ExtBits);
101c0939fddSSimon Pilgrim Result.Zero.ashrInPlace(ExtBits);
1029cf4f493SSimon Pilgrim return Result;
1039cf4f493SSimon Pilgrim }
1049cf4f493SSimon Pilgrim
makeGE(const APInt & Val) const1055350e1b5SJay Foad KnownBits KnownBits::makeGE(const APInt &Val) const {
1065350e1b5SJay Foad // Count the number of leading bit positions where our underlying value is
1075350e1b5SJay Foad // known to be less than or equal to Val.
1085350e1b5SJay Foad unsigned N = (Zero | Val).countLeadingOnes();
1095350e1b5SJay Foad
1105350e1b5SJay Foad // For each of those bit positions, if Val has a 1 in that bit then our
1115350e1b5SJay Foad // underlying value must also have a 1.
1125350e1b5SJay Foad APInt MaskedVal(Val);
1135350e1b5SJay Foad MaskedVal.clearLowBits(getBitWidth() - N);
1145350e1b5SJay Foad return KnownBits(Zero, One | MaskedVal);
1155350e1b5SJay Foad }
1165350e1b5SJay Foad
umax(const KnownBits & LHS,const KnownBits & RHS)1175350e1b5SJay Foad KnownBits KnownBits::umax(const KnownBits &LHS, const KnownBits &RHS) {
1185350e1b5SJay Foad // If we can prove that LHS >= RHS then use LHS as the result. Likewise for
1195350e1b5SJay Foad // RHS. Ideally our caller would already have spotted these cases and
1205350e1b5SJay Foad // optimized away the umax operation, but we handle them here for
1215350e1b5SJay Foad // completeness.
1225350e1b5SJay Foad if (LHS.getMinValue().uge(RHS.getMaxValue()))
1235350e1b5SJay Foad return LHS;
1245350e1b5SJay Foad if (RHS.getMinValue().uge(LHS.getMaxValue()))
1255350e1b5SJay Foad return RHS;
1265350e1b5SJay Foad
1275350e1b5SJay Foad // If the result of the umax is LHS then it must be greater than or equal to
1285350e1b5SJay Foad // the minimum possible value of RHS. Likewise for RHS. Any known bits that
1295350e1b5SJay Foad // are common to these two values are also known in the result.
1305350e1b5SJay Foad KnownBits L = LHS.makeGE(RHS.getMinValue());
1315350e1b5SJay Foad KnownBits R = RHS.makeGE(LHS.getMinValue());
1321a62ca65SSimon Pilgrim return KnownBits::commonBits(L, R);
1335350e1b5SJay Foad }
1345350e1b5SJay Foad
umin(const KnownBits & LHS,const KnownBits & RHS)1355350e1b5SJay Foad KnownBits KnownBits::umin(const KnownBits &LHS, const KnownBits &RHS) {
1365350e1b5SJay Foad // Flip the range of values: [0, 0xFFFFFFFF] <-> [0xFFFFFFFF, 0]
137ddab4cd8SNikita Popov auto Flip = [](const KnownBits &Val) { return KnownBits(Val.One, Val.Zero); };
1385350e1b5SJay Foad return Flip(umax(Flip(LHS), Flip(RHS)));
1395350e1b5SJay Foad }
1405350e1b5SJay Foad
smax(const KnownBits & LHS,const KnownBits & RHS)1415350e1b5SJay Foad KnownBits KnownBits::smax(const KnownBits &LHS, const KnownBits &RHS) {
1425350e1b5SJay Foad // Flip the range of values: [-0x80000000, 0x7FFFFFFF] <-> [0, 0xFFFFFFFF]
143ddab4cd8SNikita Popov auto Flip = [](const KnownBits &Val) {
1445350e1b5SJay Foad unsigned SignBitPosition = Val.getBitWidth() - 1;
1455350e1b5SJay Foad APInt Zero = Val.Zero;
1465350e1b5SJay Foad APInt One = Val.One;
1475350e1b5SJay Foad Zero.setBitVal(SignBitPosition, Val.One[SignBitPosition]);
1485350e1b5SJay Foad One.setBitVal(SignBitPosition, Val.Zero[SignBitPosition]);
1495350e1b5SJay Foad return KnownBits(Zero, One);
1505350e1b5SJay Foad };
1515350e1b5SJay Foad return Flip(umax(Flip(LHS), Flip(RHS)));
1525350e1b5SJay Foad }
1535350e1b5SJay Foad
smin(const KnownBits & LHS,const KnownBits & RHS)1545350e1b5SJay Foad KnownBits KnownBits::smin(const KnownBits &LHS, const KnownBits &RHS) {
1555350e1b5SJay Foad // Flip the range of values: [-0x80000000, 0x7FFFFFFF] <-> [0xFFFFFFFF, 0]
156ddab4cd8SNikita Popov auto Flip = [](const KnownBits &Val) {
1575350e1b5SJay Foad unsigned SignBitPosition = Val.getBitWidth() - 1;
1585350e1b5SJay Foad APInt Zero = Val.One;
1595350e1b5SJay Foad APInt One = Val.Zero;
1605350e1b5SJay Foad Zero.setBitVal(SignBitPosition, Val.Zero[SignBitPosition]);
1615350e1b5SJay Foad One.setBitVal(SignBitPosition, Val.One[SignBitPosition]);
1625350e1b5SJay Foad return KnownBits(Zero, One);
1635350e1b5SJay Foad };
1645350e1b5SJay Foad return Flip(umax(Flip(LHS), Flip(RHS)));
1655350e1b5SJay Foad }
1665350e1b5SJay Foad
shl(const KnownBits & LHS,const KnownBits & RHS)167cab21d4fSSimon Pilgrim KnownBits KnownBits::shl(const KnownBits &LHS, const KnownBits &RHS) {
168cab21d4fSSimon Pilgrim unsigned BitWidth = LHS.getBitWidth();
169cab21d4fSSimon Pilgrim KnownBits Known(BitWidth);
170cab21d4fSSimon Pilgrim
171cab21d4fSSimon Pilgrim // If the shift amount is a valid constant then transform LHS directly.
172cab21d4fSSimon Pilgrim if (RHS.isConstant() && RHS.getConstant().ult(BitWidth)) {
173cab21d4fSSimon Pilgrim unsigned Shift = RHS.getConstant().getZExtValue();
174cab21d4fSSimon Pilgrim Known = LHS;
175cab21d4fSSimon Pilgrim Known.Zero <<= Shift;
176cab21d4fSSimon Pilgrim Known.One <<= Shift;
177cab21d4fSSimon Pilgrim // Low bits are known zero.
178cab21d4fSSimon Pilgrim Known.Zero.setLowBits(Shift);
179cab21d4fSSimon Pilgrim return Known;
180cab21d4fSSimon Pilgrim }
181cab21d4fSSimon Pilgrim
182cab21d4fSSimon Pilgrim // No matter the shift amount, the trailing zeros will stay zero.
18327e9f0f9SSimon Pilgrim unsigned MinTrailingZeros = LHS.countMinTrailingZeros();
18427e9f0f9SSimon Pilgrim
18527e9f0f9SSimon Pilgrim // Minimum shift amount low bits are known zero.
186bb20cf2fSSimon Pilgrim APInt MinShiftAmount = RHS.getMinValue();
187bb20cf2fSSimon Pilgrim if (MinShiftAmount.ult(BitWidth)) {
188bb20cf2fSSimon Pilgrim MinTrailingZeros += MinShiftAmount.getZExtValue();
18927e9f0f9SSimon Pilgrim MinTrailingZeros = std::min(MinTrailingZeros, BitWidth);
19027e9f0f9SSimon Pilgrim }
19127e9f0f9SSimon Pilgrim
192c2d18d70SSimon Pilgrim // If the maximum shift is in range, then find the common bits from all
193c2d18d70SSimon Pilgrim // possible shifts.
194c2d18d70SSimon Pilgrim APInt MaxShiftAmount = RHS.getMaxValue();
195c2d18d70SSimon Pilgrim if (MaxShiftAmount.ult(BitWidth) && !LHS.isUnknown()) {
196c2d18d70SSimon Pilgrim uint64_t ShiftAmtZeroMask = (~RHS.Zero).getZExtValue();
197c2d18d70SSimon Pilgrim uint64_t ShiftAmtOneMask = RHS.One.getZExtValue();
198c2d18d70SSimon Pilgrim assert(MinShiftAmount.ult(MaxShiftAmount) && "Illegal shift range");
199c2d18d70SSimon Pilgrim Known.Zero.setAllBits();
200c2d18d70SSimon Pilgrim Known.One.setAllBits();
201c2d18d70SSimon Pilgrim for (uint64_t ShiftAmt = MinShiftAmount.getZExtValue(),
202c2d18d70SSimon Pilgrim MaxShiftAmt = MaxShiftAmount.getZExtValue();
203c2d18d70SSimon Pilgrim ShiftAmt <= MaxShiftAmt; ++ShiftAmt) {
204c2d18d70SSimon Pilgrim // Skip if the shift amount is impossible.
205c2d18d70SSimon Pilgrim if ((ShiftAmtZeroMask & ShiftAmt) != ShiftAmt ||
206c2d18d70SSimon Pilgrim (ShiftAmtOneMask | ShiftAmt) != ShiftAmt)
207c2d18d70SSimon Pilgrim continue;
208c2d18d70SSimon Pilgrim KnownBits SpecificShift;
209c2d18d70SSimon Pilgrim SpecificShift.Zero = LHS.Zero << ShiftAmt;
210c2d18d70SSimon Pilgrim SpecificShift.One = LHS.One << ShiftAmt;
211c2d18d70SSimon Pilgrim Known = KnownBits::commonBits(Known, SpecificShift);
212c2d18d70SSimon Pilgrim if (Known.isUnknown())
213c2d18d70SSimon Pilgrim break;
214c2d18d70SSimon Pilgrim }
215c2d18d70SSimon Pilgrim }
216c2d18d70SSimon Pilgrim
21727e9f0f9SSimon Pilgrim Known.Zero.setLowBits(MinTrailingZeros);
218cab21d4fSSimon Pilgrim return Known;
219cab21d4fSSimon Pilgrim }
220cab21d4fSSimon Pilgrim
lshr(const KnownBits & LHS,const KnownBits & RHS)221cb798f04SSimon Pilgrim KnownBits KnownBits::lshr(const KnownBits &LHS, const KnownBits &RHS) {
222cb798f04SSimon Pilgrim unsigned BitWidth = LHS.getBitWidth();
223cb798f04SSimon Pilgrim KnownBits Known(BitWidth);
224cb798f04SSimon Pilgrim
225cb798f04SSimon Pilgrim if (RHS.isConstant() && RHS.getConstant().ult(BitWidth)) {
226cb798f04SSimon Pilgrim unsigned Shift = RHS.getConstant().getZExtValue();
227cb798f04SSimon Pilgrim Known = LHS;
228cb798f04SSimon Pilgrim Known.Zero.lshrInPlace(Shift);
229cb798f04SSimon Pilgrim Known.One.lshrInPlace(Shift);
230cb798f04SSimon Pilgrim // High bits are known zero.
231cb798f04SSimon Pilgrim Known.Zero.setHighBits(Shift);
232cb798f04SSimon Pilgrim return Known;
233cb798f04SSimon Pilgrim }
234cb798f04SSimon Pilgrim
235cb798f04SSimon Pilgrim // No matter the shift amount, the leading zeros will stay zero.
23627e9f0f9SSimon Pilgrim unsigned MinLeadingZeros = LHS.countMinLeadingZeros();
23727e9f0f9SSimon Pilgrim
23827e9f0f9SSimon Pilgrim // Minimum shift amount high bits are known zero.
239bb20cf2fSSimon Pilgrim APInt MinShiftAmount = RHS.getMinValue();
240bb20cf2fSSimon Pilgrim if (MinShiftAmount.ult(BitWidth)) {
241bb20cf2fSSimon Pilgrim MinLeadingZeros += MinShiftAmount.getZExtValue();
24227e9f0f9SSimon Pilgrim MinLeadingZeros = std::min(MinLeadingZeros, BitWidth);
24327e9f0f9SSimon Pilgrim }
24427e9f0f9SSimon Pilgrim
245c2d18d70SSimon Pilgrim // If the maximum shift is in range, then find the common bits from all
246c2d18d70SSimon Pilgrim // possible shifts.
247c2d18d70SSimon Pilgrim APInt MaxShiftAmount = RHS.getMaxValue();
248c2d18d70SSimon Pilgrim if (MaxShiftAmount.ult(BitWidth) && !LHS.isUnknown()) {
249c2d18d70SSimon Pilgrim uint64_t ShiftAmtZeroMask = (~RHS.Zero).getZExtValue();
250c2d18d70SSimon Pilgrim uint64_t ShiftAmtOneMask = RHS.One.getZExtValue();
251c2d18d70SSimon Pilgrim assert(MinShiftAmount.ult(MaxShiftAmount) && "Illegal shift range");
252c2d18d70SSimon Pilgrim Known.Zero.setAllBits();
253c2d18d70SSimon Pilgrim Known.One.setAllBits();
254c2d18d70SSimon Pilgrim for (uint64_t ShiftAmt = MinShiftAmount.getZExtValue(),
255c2d18d70SSimon Pilgrim MaxShiftAmt = MaxShiftAmount.getZExtValue();
256c2d18d70SSimon Pilgrim ShiftAmt <= MaxShiftAmt; ++ShiftAmt) {
257c2d18d70SSimon Pilgrim // Skip if the shift amount is impossible.
258c2d18d70SSimon Pilgrim if ((ShiftAmtZeroMask & ShiftAmt) != ShiftAmt ||
259c2d18d70SSimon Pilgrim (ShiftAmtOneMask | ShiftAmt) != ShiftAmt)
260c2d18d70SSimon Pilgrim continue;
261c2d18d70SSimon Pilgrim KnownBits SpecificShift = LHS;
262c2d18d70SSimon Pilgrim SpecificShift.Zero.lshrInPlace(ShiftAmt);
263c2d18d70SSimon Pilgrim SpecificShift.One.lshrInPlace(ShiftAmt);
264c2d18d70SSimon Pilgrim Known = KnownBits::commonBits(Known, SpecificShift);
265c2d18d70SSimon Pilgrim if (Known.isUnknown())
266c2d18d70SSimon Pilgrim break;
267c2d18d70SSimon Pilgrim }
268c2d18d70SSimon Pilgrim }
269c2d18d70SSimon Pilgrim
27027e9f0f9SSimon Pilgrim Known.Zero.setHighBits(MinLeadingZeros);
271cb798f04SSimon Pilgrim return Known;
272cb798f04SSimon Pilgrim }
273cb798f04SSimon Pilgrim
ashr(const KnownBits & LHS,const KnownBits & RHS)274e9b88c75SSimon Pilgrim KnownBits KnownBits::ashr(const KnownBits &LHS, const KnownBits &RHS) {
275e9b88c75SSimon Pilgrim unsigned BitWidth = LHS.getBitWidth();
276e9b88c75SSimon Pilgrim KnownBits Known(BitWidth);
277e9b88c75SSimon Pilgrim
278e9b88c75SSimon Pilgrim if (RHS.isConstant() && RHS.getConstant().ult(BitWidth)) {
279e9b88c75SSimon Pilgrim unsigned Shift = RHS.getConstant().getZExtValue();
280e9b88c75SSimon Pilgrim Known = LHS;
281e9b88c75SSimon Pilgrim Known.Zero.ashrInPlace(Shift);
282e9b88c75SSimon Pilgrim Known.One.ashrInPlace(Shift);
283e9b88c75SSimon Pilgrim return Known;
284e9b88c75SSimon Pilgrim }
285e9b88c75SSimon Pilgrim
28627e9f0f9SSimon Pilgrim // No matter the shift amount, the leading sign bits will stay.
28727e9f0f9SSimon Pilgrim unsigned MinLeadingZeros = LHS.countMinLeadingZeros();
28827e9f0f9SSimon Pilgrim unsigned MinLeadingOnes = LHS.countMinLeadingOnes();
28927e9f0f9SSimon Pilgrim
29027e9f0f9SSimon Pilgrim // Minimum shift amount high bits are known sign bits.
291bb20cf2fSSimon Pilgrim APInt MinShiftAmount = RHS.getMinValue();
292bb20cf2fSSimon Pilgrim if (MinShiftAmount.ult(BitWidth)) {
29327e9f0f9SSimon Pilgrim if (MinLeadingZeros) {
294bb20cf2fSSimon Pilgrim MinLeadingZeros += MinShiftAmount.getZExtValue();
29527e9f0f9SSimon Pilgrim MinLeadingZeros = std::min(MinLeadingZeros, BitWidth);
29627e9f0f9SSimon Pilgrim }
29727e9f0f9SSimon Pilgrim if (MinLeadingOnes) {
298bb20cf2fSSimon Pilgrim MinLeadingOnes += MinShiftAmount.getZExtValue();
29927e9f0f9SSimon Pilgrim MinLeadingOnes = std::min(MinLeadingOnes, BitWidth);
30027e9f0f9SSimon Pilgrim }
30127e9f0f9SSimon Pilgrim }
30227e9f0f9SSimon Pilgrim
303c2d18d70SSimon Pilgrim // If the maximum shift is in range, then find the common bits from all
304c2d18d70SSimon Pilgrim // possible shifts.
305c2d18d70SSimon Pilgrim APInt MaxShiftAmount = RHS.getMaxValue();
306c2d18d70SSimon Pilgrim if (MaxShiftAmount.ult(BitWidth) && !LHS.isUnknown()) {
307c2d18d70SSimon Pilgrim uint64_t ShiftAmtZeroMask = (~RHS.Zero).getZExtValue();
308c2d18d70SSimon Pilgrim uint64_t ShiftAmtOneMask = RHS.One.getZExtValue();
309c2d18d70SSimon Pilgrim assert(MinShiftAmount.ult(MaxShiftAmount) && "Illegal shift range");
310c2d18d70SSimon Pilgrim Known.Zero.setAllBits();
311c2d18d70SSimon Pilgrim Known.One.setAllBits();
312c2d18d70SSimon Pilgrim for (uint64_t ShiftAmt = MinShiftAmount.getZExtValue(),
313c2d18d70SSimon Pilgrim MaxShiftAmt = MaxShiftAmount.getZExtValue();
314c2d18d70SSimon Pilgrim ShiftAmt <= MaxShiftAmt; ++ShiftAmt) {
315c2d18d70SSimon Pilgrim // Skip if the shift amount is impossible.
316c2d18d70SSimon Pilgrim if ((ShiftAmtZeroMask & ShiftAmt) != ShiftAmt ||
317c2d18d70SSimon Pilgrim (ShiftAmtOneMask | ShiftAmt) != ShiftAmt)
318c2d18d70SSimon Pilgrim continue;
319c2d18d70SSimon Pilgrim KnownBits SpecificShift = LHS;
320c2d18d70SSimon Pilgrim SpecificShift.Zero.ashrInPlace(ShiftAmt);
321c2d18d70SSimon Pilgrim SpecificShift.One.ashrInPlace(ShiftAmt);
322c2d18d70SSimon Pilgrim Known = KnownBits::commonBits(Known, SpecificShift);
323c2d18d70SSimon Pilgrim if (Known.isUnknown())
324c2d18d70SSimon Pilgrim break;
325c2d18d70SSimon Pilgrim }
326c2d18d70SSimon Pilgrim }
327c2d18d70SSimon Pilgrim
32827e9f0f9SSimon Pilgrim Known.Zero.setHighBits(MinLeadingZeros);
32927e9f0f9SSimon Pilgrim Known.One.setHighBits(MinLeadingOnes);
330e9b88c75SSimon Pilgrim return Known;
331e9b88c75SSimon Pilgrim }
332e9b88c75SSimon Pilgrim
eq(const KnownBits & LHS,const KnownBits & RHS)33323b41986SSimon Pilgrim Optional<bool> KnownBits::eq(const KnownBits &LHS, const KnownBits &RHS) {
33423b41986SSimon Pilgrim if (LHS.isConstant() && RHS.isConstant())
33523b41986SSimon Pilgrim return Optional<bool>(LHS.getConstant() == RHS.getConstant());
33623b41986SSimon Pilgrim if (LHS.One.intersects(RHS.Zero) || RHS.One.intersects(LHS.Zero))
33723b41986SSimon Pilgrim return Optional<bool>(false);
33823b41986SSimon Pilgrim return None;
33923b41986SSimon Pilgrim }
34023b41986SSimon Pilgrim
ne(const KnownBits & LHS,const KnownBits & RHS)34123b41986SSimon Pilgrim Optional<bool> KnownBits::ne(const KnownBits &LHS, const KnownBits &RHS) {
34223b41986SSimon Pilgrim if (Optional<bool> KnownEQ = eq(LHS, RHS))
343*7a47ee51SKazu Hirata return Optional<bool>(!*KnownEQ);
34423b41986SSimon Pilgrim return None;
34523b41986SSimon Pilgrim }
34623b41986SSimon Pilgrim
ugt(const KnownBits & LHS,const KnownBits & RHS)34723b41986SSimon Pilgrim Optional<bool> KnownBits::ugt(const KnownBits &LHS, const KnownBits &RHS) {
34823b41986SSimon Pilgrim // LHS >u RHS -> false if umax(LHS) <= umax(RHS)
34923b41986SSimon Pilgrim if (LHS.getMaxValue().ule(RHS.getMinValue()))
35023b41986SSimon Pilgrim return Optional<bool>(false);
35123b41986SSimon Pilgrim // LHS >u RHS -> true if umin(LHS) > umax(RHS)
35223b41986SSimon Pilgrim if (LHS.getMinValue().ugt(RHS.getMaxValue()))
35323b41986SSimon Pilgrim return Optional<bool>(true);
35423b41986SSimon Pilgrim return None;
35523b41986SSimon Pilgrim }
35623b41986SSimon Pilgrim
uge(const KnownBits & LHS,const KnownBits & RHS)35723b41986SSimon Pilgrim Optional<bool> KnownBits::uge(const KnownBits &LHS, const KnownBits &RHS) {
35823b41986SSimon Pilgrim if (Optional<bool> IsUGT = ugt(RHS, LHS))
359*7a47ee51SKazu Hirata return Optional<bool>(!*IsUGT);
36023b41986SSimon Pilgrim return None;
36123b41986SSimon Pilgrim }
36223b41986SSimon Pilgrim
ult(const KnownBits & LHS,const KnownBits & RHS)36323b41986SSimon Pilgrim Optional<bool> KnownBits::ult(const KnownBits &LHS, const KnownBits &RHS) {
36423b41986SSimon Pilgrim return ugt(RHS, LHS);
36523b41986SSimon Pilgrim }
36623b41986SSimon Pilgrim
ule(const KnownBits & LHS,const KnownBits & RHS)36723b41986SSimon Pilgrim Optional<bool> KnownBits::ule(const KnownBits &LHS, const KnownBits &RHS) {
36823b41986SSimon Pilgrim return uge(RHS, LHS);
36923b41986SSimon Pilgrim }
37023b41986SSimon Pilgrim
sgt(const KnownBits & LHS,const KnownBits & RHS)37123b41986SSimon Pilgrim Optional<bool> KnownBits::sgt(const KnownBits &LHS, const KnownBits &RHS) {
37223b41986SSimon Pilgrim // LHS >s RHS -> false if smax(LHS) <= smax(RHS)
37323b41986SSimon Pilgrim if (LHS.getSignedMaxValue().sle(RHS.getSignedMinValue()))
37423b41986SSimon Pilgrim return Optional<bool>(false);
37523b41986SSimon Pilgrim // LHS >s RHS -> true if smin(LHS) > smax(RHS)
37623b41986SSimon Pilgrim if (LHS.getSignedMinValue().sgt(RHS.getSignedMaxValue()))
37723b41986SSimon Pilgrim return Optional<bool>(true);
37823b41986SSimon Pilgrim return None;
37923b41986SSimon Pilgrim }
38023b41986SSimon Pilgrim
sge(const KnownBits & LHS,const KnownBits & RHS)38123b41986SSimon Pilgrim Optional<bool> KnownBits::sge(const KnownBits &LHS, const KnownBits &RHS) {
38223b41986SSimon Pilgrim if (Optional<bool> KnownSGT = sgt(RHS, LHS))
383*7a47ee51SKazu Hirata return Optional<bool>(!*KnownSGT);
38423b41986SSimon Pilgrim return None;
38523b41986SSimon Pilgrim }
38623b41986SSimon Pilgrim
slt(const KnownBits & LHS,const KnownBits & RHS)38723b41986SSimon Pilgrim Optional<bool> KnownBits::slt(const KnownBits &LHS, const KnownBits &RHS) {
38823b41986SSimon Pilgrim return sgt(RHS, LHS);
38923b41986SSimon Pilgrim }
39023b41986SSimon Pilgrim
sle(const KnownBits & LHS,const KnownBits & RHS)39123b41986SSimon Pilgrim Optional<bool> KnownBits::sle(const KnownBits &LHS, const KnownBits &RHS) {
39223b41986SSimon Pilgrim return sge(RHS, LHS);
39323b41986SSimon Pilgrim }
39423b41986SSimon Pilgrim
abs(bool IntMinIsPoison) const3959a85643cSNikita Popov KnownBits KnownBits::abs(bool IntMinIsPoison) const {
396d816499fSSimon Pilgrim // If the source's MSB is zero then we know the rest of the bits already.
397d816499fSSimon Pilgrim if (isNonNegative())
398d816499fSSimon Pilgrim return *this;
399d816499fSSimon Pilgrim
4009a85643cSNikita Popov // Absolute value preserves trailing zero count.
401d816499fSSimon Pilgrim KnownBits KnownAbs(getBitWidth());
4029a85643cSNikita Popov KnownAbs.Zero.setLowBits(countMinTrailingZeros());
403d816499fSSimon Pilgrim
4049a85643cSNikita Popov // We only know that the absolute values's MSB will be zero if INT_MIN is
4059a85643cSNikita Popov // poison, or there is a set bit that isn't the sign bit (otherwise it could
4069a85643cSNikita Popov // be INT_MIN).
407a9bceb2bSJay Foad if (IntMinIsPoison || (!One.isZero() && !One.isMinSignedValue()))
408d816499fSSimon Pilgrim KnownAbs.Zero.setSignBit();
409d816499fSSimon Pilgrim
4109a85643cSNikita Popov // FIXME: Handle known negative input?
4119a85643cSNikita Popov // FIXME: Calculate the negated Known bits and combine them?
412d816499fSSimon Pilgrim return KnownAbs;
413d816499fSSimon Pilgrim }
414d816499fSSimon Pilgrim
mul(const KnownBits & LHS,const KnownBits & RHS,bool NoUndefSelfMultiply)4150a07ae6eSSimon Pilgrim KnownBits KnownBits::mul(const KnownBits &LHS, const KnownBits &RHS,
41694453952SSimon Pilgrim bool NoUndefSelfMultiply) {
4179431f8adSQuentin Colombet unsigned BitWidth = LHS.getBitWidth();
418ddbb5873SSimon Pilgrim assert(BitWidth == RHS.getBitWidth() && !LHS.hasConflict() &&
419ddbb5873SSimon Pilgrim !RHS.hasConflict() && "Operand mismatch");
420a694546fSNikita Popov assert((!NoUndefSelfMultiply || LHS == RHS) &&
4210a07ae6eSSimon Pilgrim "Self multiplication knownbits mismatch");
4229431f8adSQuentin Colombet
423892c7316SSanjay Patel // Compute the high known-0 bits by multiplying the unsigned max of each side.
424892c7316SSanjay Patel // Conservatively, M active bits * N active bits results in M + N bits in the
425892c7316SSanjay Patel // result. But if we know a value is a power-of-2 for example, then this
426892c7316SSanjay Patel // computes one more leading zero.
427e9179a6aSSanjay Patel // TODO: This could be generalized to number of sign bits (negative numbers).
428892c7316SSanjay Patel APInt UMaxLHS = LHS.getMaxValue();
429892c7316SSanjay Patel APInt UMaxRHS = RHS.getMaxValue();
430e9179a6aSSanjay Patel
431892c7316SSanjay Patel // For leading zeros in the result to be valid, the unsigned max product must
432892c7316SSanjay Patel // fit in the bitwidth (it must not overflow).
433892c7316SSanjay Patel bool HasOverflow;
434892c7316SSanjay Patel APInt UMaxResult = UMaxLHS.umul_ov(UMaxRHS, HasOverflow);
435892c7316SSanjay Patel unsigned LeadZ = HasOverflow ? 0 : UMaxResult.countLeadingZeros();
4369431f8adSQuentin Colombet
4379431f8adSQuentin Colombet // The result of the bottom bits of an integer multiply can be
4389431f8adSQuentin Colombet // inferred by looking at the bottom bits of both operands and
4399431f8adSQuentin Colombet // multiplying them together.
4409431f8adSQuentin Colombet // We can infer at least the minimum number of known trailing bits
4419431f8adSQuentin Colombet // of both operands. Depending on number of trailing zeros, we can
4429431f8adSQuentin Colombet // infer more bits, because (a*b) <=> ((a/m) * (b/n)) * (m*n) assuming
4439431f8adSQuentin Colombet // a and b are divisible by m and n respectively.
4449431f8adSQuentin Colombet // We then calculate how many of those bits are inferrable and set
4459431f8adSQuentin Colombet // the output. For example, the i8 mul:
4469431f8adSQuentin Colombet // a = XXXX1100 (12)
4479431f8adSQuentin Colombet // b = XXXX1110 (14)
4489431f8adSQuentin Colombet // We know the bottom 3 bits are zero since the first can be divided by
4499431f8adSQuentin Colombet // 4 and the second by 2, thus having ((12/4) * (14/2)) * (2*4).
4509431f8adSQuentin Colombet // Applying the multiplication to the trimmed arguments gets:
4519431f8adSQuentin Colombet // XX11 (3)
4529431f8adSQuentin Colombet // X111 (7)
4539431f8adSQuentin Colombet // -------
4549431f8adSQuentin Colombet // XX11
4559431f8adSQuentin Colombet // XX11
4569431f8adSQuentin Colombet // XX11
4579431f8adSQuentin Colombet // XX11
4589431f8adSQuentin Colombet // -------
4599431f8adSQuentin Colombet // XXXXX01
4609431f8adSQuentin Colombet // Which allows us to infer the 2 LSBs. Since we're multiplying the result
4619431f8adSQuentin Colombet // by 8, the bottom 3 bits will be 0, so we can infer a total of 5 bits.
4629431f8adSQuentin Colombet // The proof for this can be described as:
4639431f8adSQuentin Colombet // Pre: (C1 >= 0) && (C1 < (1 << C5)) && (C2 >= 0) && (C2 < (1 << C6)) &&
4649431f8adSQuentin Colombet // (C7 == (1 << (umin(countTrailingZeros(C1), C5) +
4659431f8adSQuentin Colombet // umin(countTrailingZeros(C2), C6) +
4669431f8adSQuentin Colombet // umin(C5 - umin(countTrailingZeros(C1), C5),
4679431f8adSQuentin Colombet // C6 - umin(countTrailingZeros(C2), C6)))) - 1)
4689431f8adSQuentin Colombet // %aa = shl i8 %a, C5
4699431f8adSQuentin Colombet // %bb = shl i8 %b, C6
4709431f8adSQuentin Colombet // %aaa = or i8 %aa, C1
4719431f8adSQuentin Colombet // %bbb = or i8 %bb, C2
4729431f8adSQuentin Colombet // %mul = mul i8 %aaa, %bbb
4739431f8adSQuentin Colombet // %mask = and i8 %mul, C7
4749431f8adSQuentin Colombet // =>
4759431f8adSQuentin Colombet // %mask = i8 ((C1*C2)&C7)
4769431f8adSQuentin Colombet // Where C5, C6 describe the known bits of %a, %b
4779431f8adSQuentin Colombet // C1, C2 describe the known bottom bits of %a, %b.
4789431f8adSQuentin Colombet // C7 describes the mask of the known bits of the result.
479ecbd0413SSimon Pilgrim const APInt &Bottom0 = LHS.One;
480ecbd0413SSimon Pilgrim const APInt &Bottom1 = RHS.One;
4819431f8adSQuentin Colombet
4829431f8adSQuentin Colombet // How many times we'd be able to divide each argument by 2 (shr by 1).
4839431f8adSQuentin Colombet // This gives us the number of trailing zeros on the multiplication result.
4849431f8adSQuentin Colombet unsigned TrailBitsKnown0 = (LHS.Zero | LHS.One).countTrailingOnes();
4859431f8adSQuentin Colombet unsigned TrailBitsKnown1 = (RHS.Zero | RHS.One).countTrailingOnes();
4869431f8adSQuentin Colombet unsigned TrailZero0 = LHS.countMinTrailingZeros();
4879431f8adSQuentin Colombet unsigned TrailZero1 = RHS.countMinTrailingZeros();
4889431f8adSQuentin Colombet unsigned TrailZ = TrailZero0 + TrailZero1;
4899431f8adSQuentin Colombet
4909431f8adSQuentin Colombet // Figure out the fewest known-bits operand.
4919431f8adSQuentin Colombet unsigned SmallestOperand =
4929431f8adSQuentin Colombet std::min(TrailBitsKnown0 - TrailZero0, TrailBitsKnown1 - TrailZero1);
4939431f8adSQuentin Colombet unsigned ResultBitsKnown = std::min(SmallestOperand + TrailZ, BitWidth);
4949431f8adSQuentin Colombet
4959431f8adSQuentin Colombet APInt BottomKnown =
4969431f8adSQuentin Colombet Bottom0.getLoBits(TrailBitsKnown0) * Bottom1.getLoBits(TrailBitsKnown1);
4979431f8adSQuentin Colombet
4989431f8adSQuentin Colombet KnownBits Res(BitWidth);
4999431f8adSQuentin Colombet Res.Zero.setHighBits(LeadZ);
5009431f8adSQuentin Colombet Res.Zero |= (~BottomKnown).getLoBits(ResultBitsKnown);
5019431f8adSQuentin Colombet Res.One = BottomKnown.getLoBits(ResultBitsKnown);
5020a07ae6eSSimon Pilgrim
5030a07ae6eSSimon Pilgrim // If we're self-multiplying then bit[1] is guaranteed to be zero.
50494453952SSimon Pilgrim if (NoUndefSelfMultiply && BitWidth > 1) {
5050a07ae6eSSimon Pilgrim assert(Res.One[1] == 0 &&
5060a07ae6eSSimon Pilgrim "Self-multiplication failed Quadratic Reciprocity!");
5070a07ae6eSSimon Pilgrim Res.Zero.setBit(1);
5080a07ae6eSSimon Pilgrim }
5090a07ae6eSSimon Pilgrim
5109431f8adSQuentin Colombet return Res;
5119431f8adSQuentin Colombet }
5129431f8adSQuentin Colombet
mulhs(const KnownBits & LHS,const KnownBits & RHS)513a9689721SSimon Pilgrim KnownBits KnownBits::mulhs(const KnownBits &LHS, const KnownBits &RHS) {
514a9689721SSimon Pilgrim unsigned BitWidth = LHS.getBitWidth();
515a9689721SSimon Pilgrim assert(BitWidth == RHS.getBitWidth() && !LHS.hasConflict() &&
516a9689721SSimon Pilgrim !RHS.hasConflict() && "Operand mismatch");
517a9689721SSimon Pilgrim KnownBits WideLHS = LHS.sext(2 * BitWidth);
518a9689721SSimon Pilgrim KnownBits WideRHS = RHS.sext(2 * BitWidth);
519ddbb5873SSimon Pilgrim return mul(WideLHS, WideRHS).extractBits(BitWidth, BitWidth);
520a9689721SSimon Pilgrim }
521a9689721SSimon Pilgrim
mulhu(const KnownBits & LHS,const KnownBits & RHS)522a9689721SSimon Pilgrim KnownBits KnownBits::mulhu(const KnownBits &LHS, const KnownBits &RHS) {
523a9689721SSimon Pilgrim unsigned BitWidth = LHS.getBitWidth();
524a9689721SSimon Pilgrim assert(BitWidth == RHS.getBitWidth() && !LHS.hasConflict() &&
525a9689721SSimon Pilgrim !RHS.hasConflict() && "Operand mismatch");
526a9689721SSimon Pilgrim KnownBits WideLHS = LHS.zext(2 * BitWidth);
527a9689721SSimon Pilgrim KnownBits WideRHS = RHS.zext(2 * BitWidth);
528ddbb5873SSimon Pilgrim return mul(WideLHS, WideRHS).extractBits(BitWidth, BitWidth);
529a9689721SSimon Pilgrim }
530a9689721SSimon Pilgrim
udiv(const KnownBits & LHS,const KnownBits & RHS)53132bee18bSSimon Pilgrim KnownBits KnownBits::udiv(const KnownBits &LHS, const KnownBits &RHS) {
53232bee18bSSimon Pilgrim unsigned BitWidth = LHS.getBitWidth();
53332bee18bSSimon Pilgrim assert(!LHS.hasConflict() && !RHS.hasConflict());
53432bee18bSSimon Pilgrim KnownBits Known(BitWidth);
53532bee18bSSimon Pilgrim
53632bee18bSSimon Pilgrim // For the purposes of computing leading zeros we can conservatively
53732bee18bSSimon Pilgrim // treat a udiv as a logical right shift by the power of 2 known to
53832bee18bSSimon Pilgrim // be less than the denominator.
53932bee18bSSimon Pilgrim unsigned LeadZ = LHS.countMinLeadingZeros();
54032bee18bSSimon Pilgrim unsigned RHSMaxLeadingZeros = RHS.countMaxLeadingZeros();
54132bee18bSSimon Pilgrim
54232bee18bSSimon Pilgrim if (RHSMaxLeadingZeros != BitWidth)
54332bee18bSSimon Pilgrim LeadZ = std::min(BitWidth, LeadZ + BitWidth - RHSMaxLeadingZeros - 1);
54432bee18bSSimon Pilgrim
54532bee18bSSimon Pilgrim Known.Zero.setHighBits(LeadZ);
54632bee18bSSimon Pilgrim return Known;
54732bee18bSSimon Pilgrim }
54832bee18bSSimon Pilgrim
urem(const KnownBits & LHS,const KnownBits & RHS)549e237d56bSSimon Pilgrim KnownBits KnownBits::urem(const KnownBits &LHS, const KnownBits &RHS) {
550e237d56bSSimon Pilgrim unsigned BitWidth = LHS.getBitWidth();
551e237d56bSSimon Pilgrim assert(!LHS.hasConflict() && !RHS.hasConflict());
552e237d56bSSimon Pilgrim KnownBits Known(BitWidth);
553e237d56bSSimon Pilgrim
554e237d56bSSimon Pilgrim if (RHS.isConstant() && RHS.getConstant().isPowerOf2()) {
555e237d56bSSimon Pilgrim // The upper bits are all zero, the lower ones are unchanged.
556e237d56bSSimon Pilgrim APInt LowBits = RHS.getConstant() - 1;
557e237d56bSSimon Pilgrim Known.Zero = LHS.Zero | ~LowBits;
558e237d56bSSimon Pilgrim Known.One = LHS.One & LowBits;
559e237d56bSSimon Pilgrim return Known;
560e237d56bSSimon Pilgrim }
561e237d56bSSimon Pilgrim
562e237d56bSSimon Pilgrim // Since the result is less than or equal to either operand, any leading
563e237d56bSSimon Pilgrim // zero bits in either operand must also exist in the result.
564e237d56bSSimon Pilgrim uint32_t Leaders =
565e237d56bSSimon Pilgrim std::max(LHS.countMinLeadingZeros(), RHS.countMinLeadingZeros());
566e237d56bSSimon Pilgrim Known.Zero.setHighBits(Leaders);
567e237d56bSSimon Pilgrim return Known;
568e237d56bSSimon Pilgrim }
569e237d56bSSimon Pilgrim
srem(const KnownBits & LHS,const KnownBits & RHS)5706729b6deSSimon Pilgrim KnownBits KnownBits::srem(const KnownBits &LHS, const KnownBits &RHS) {
5716729b6deSSimon Pilgrim unsigned BitWidth = LHS.getBitWidth();
5726729b6deSSimon Pilgrim assert(!LHS.hasConflict() && !RHS.hasConflict());
5736729b6deSSimon Pilgrim KnownBits Known(BitWidth);
5746729b6deSSimon Pilgrim
5756729b6deSSimon Pilgrim if (RHS.isConstant() && RHS.getConstant().isPowerOf2()) {
5766729b6deSSimon Pilgrim // The low bits of the first operand are unchanged by the srem.
5776729b6deSSimon Pilgrim APInt LowBits = RHS.getConstant() - 1;
5786729b6deSSimon Pilgrim Known.Zero = LHS.Zero & LowBits;
5796729b6deSSimon Pilgrim Known.One = LHS.One & LowBits;
5806729b6deSSimon Pilgrim
5816729b6deSSimon Pilgrim // If the first operand is non-negative or has all low bits zero, then
5826729b6deSSimon Pilgrim // the upper bits are all zero.
5836729b6deSSimon Pilgrim if (LHS.isNonNegative() || LowBits.isSubsetOf(LHS.Zero))
5846729b6deSSimon Pilgrim Known.Zero |= ~LowBits;
5856729b6deSSimon Pilgrim
5866729b6deSSimon Pilgrim // If the first operand is negative and not all low bits are zero, then
5876729b6deSSimon Pilgrim // the upper bits are all one.
5886729b6deSSimon Pilgrim if (LHS.isNegative() && LowBits.intersects(LHS.One))
5896729b6deSSimon Pilgrim Known.One |= ~LowBits;
5906729b6deSSimon Pilgrim return Known;
5916729b6deSSimon Pilgrim }
5926729b6deSSimon Pilgrim
5936729b6deSSimon Pilgrim // The sign bit is the LHS's sign bit, except when the result of the
594183bbad1SCraig Topper // remainder is zero. The magnitude of the result should be less than or
595183bbad1SCraig Topper // equal to the magnitude of the LHS. Therefore any leading zeros that exist
596183bbad1SCraig Topper // in the left hand side must also exist in the result.
597183bbad1SCraig Topper Known.Zero.setHighBits(LHS.countMinLeadingZeros());
5986729b6deSSimon Pilgrim return Known;
5996729b6deSSimon Pilgrim }
6006729b6deSSimon Pilgrim
operator &=(const KnownBits & RHS)601c63aed89SJay Foad KnownBits &KnownBits::operator&=(const KnownBits &RHS) {
602c63aed89SJay Foad // Result bit is 0 if either operand bit is 0.
603c63aed89SJay Foad Zero |= RHS.Zero;
604c63aed89SJay Foad // Result bit is 1 if both operand bits are 1.
605c63aed89SJay Foad One &= RHS.One;
606c63aed89SJay Foad return *this;
607c63aed89SJay Foad }
608c63aed89SJay Foad
operator |=(const KnownBits & RHS)609c63aed89SJay Foad KnownBits &KnownBits::operator|=(const KnownBits &RHS) {
610c63aed89SJay Foad // Result bit is 0 if both operand bits are 0.
611c63aed89SJay Foad Zero &= RHS.Zero;
612c63aed89SJay Foad // Result bit is 1 if either operand bit is 1.
613c63aed89SJay Foad One |= RHS.One;
614c63aed89SJay Foad return *this;
615c63aed89SJay Foad }
616c63aed89SJay Foad
operator ^=(const KnownBits & RHS)617c63aed89SJay Foad KnownBits &KnownBits::operator^=(const KnownBits &RHS) {
618c63aed89SJay Foad // Result bit is 0 if both operand bits are 0 or both are 1.
619c63aed89SJay Foad APInt Z = (Zero & RHS.Zero) | (One & RHS.One);
620c63aed89SJay Foad // Result bit is 1 if one operand bit is 0 and the other is 1.
621c63aed89SJay Foad One = (Zero & RHS.One) | (One & RHS.Zero);
622c63aed89SJay Foad Zero = std::move(Z);
623c63aed89SJay Foad return *this;
624c63aed89SJay Foad }
625115a42adSPhilip Reames
print(raw_ostream & OS) const626115a42adSPhilip Reames void KnownBits::print(raw_ostream &OS) const {
627115a42adSPhilip Reames OS << "{Zero=" << Zero << ", One=" << One << "}";
628115a42adSPhilip Reames }
dump() const629115a42adSPhilip Reames void KnownBits::dump() const {
630115a42adSPhilip Reames print(dbgs());
631115a42adSPhilip Reames dbgs() << "\n";
632115a42adSPhilip Reames }
633