10b57cec5SDimitry Andric //===-- KnownBits.cpp - Stores known zeros/ones ---------------------------===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric // 90b57cec5SDimitry Andric // This file contains a class for representing known zeros and ones used by 100b57cec5SDimitry Andric // computeKnownBits. 110b57cec5SDimitry Andric // 120b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 130b57cec5SDimitry Andric 140b57cec5SDimitry Andric #include "llvm/Support/KnownBits.h" 15fe6060f1SDimitry Andric #include "llvm/Support/Debug.h" 16fe6060f1SDimitry Andric #include "llvm/Support/raw_ostream.h" 175ffd83dbSDimitry Andric #include <cassert> 180b57cec5SDimitry Andric 190b57cec5SDimitry Andric using namespace llvm; 200b57cec5SDimitry Andric 21*0fca6ea1SDimitry Andric static KnownBits computeForAddCarry(const KnownBits &LHS, const KnownBits &RHS, 220b57cec5SDimitry Andric bool CarryZero, bool CarryOne) { 230b57cec5SDimitry Andric 24480093f4SDimitry Andric APInt PossibleSumZero = LHS.getMaxValue() + RHS.getMaxValue() + !CarryZero; 25480093f4SDimitry Andric APInt PossibleSumOne = LHS.getMinValue() + RHS.getMinValue() + CarryOne; 260b57cec5SDimitry Andric 270b57cec5SDimitry Andric // Compute known bits of the carry. 280b57cec5SDimitry Andric APInt CarryKnownZero = ~(PossibleSumZero ^ LHS.Zero ^ RHS.Zero); 290b57cec5SDimitry Andric APInt CarryKnownOne = PossibleSumOne ^ LHS.One ^ RHS.One; 300b57cec5SDimitry Andric 310b57cec5SDimitry Andric // Compute set of known bits (where all three relevant bits are known). 320b57cec5SDimitry Andric APInt LHSKnownUnion = LHS.Zero | LHS.One; 330b57cec5SDimitry Andric APInt RHSKnownUnion = RHS.Zero | RHS.One; 340b57cec5SDimitry Andric APInt CarryKnownUnion = std::move(CarryKnownZero) | CarryKnownOne; 350b57cec5SDimitry Andric APInt Known = std::move(LHSKnownUnion) & RHSKnownUnion & CarryKnownUnion; 360b57cec5SDimitry Andric 370b57cec5SDimitry Andric // Compute known bits of the result. 380b57cec5SDimitry Andric KnownBits KnownOut; 390b57cec5SDimitry Andric KnownOut.Zero = ~std::move(PossibleSumZero) & Known; 400b57cec5SDimitry Andric KnownOut.One = std::move(PossibleSumOne) & Known; 410b57cec5SDimitry Andric return KnownOut; 420b57cec5SDimitry Andric } 430b57cec5SDimitry Andric 440b57cec5SDimitry Andric KnownBits KnownBits::computeForAddCarry( 450b57cec5SDimitry Andric const KnownBits &LHS, const KnownBits &RHS, const KnownBits &Carry) { 460b57cec5SDimitry Andric assert(Carry.getBitWidth() == 1 && "Carry must be 1-bit"); 470b57cec5SDimitry Andric return ::computeForAddCarry( 480b57cec5SDimitry Andric LHS, RHS, Carry.Zero.getBoolValue(), Carry.One.getBoolValue()); 490b57cec5SDimitry Andric } 500b57cec5SDimitry Andric 51*0fca6ea1SDimitry Andric KnownBits KnownBits::computeForAddSub(bool Add, bool NSW, bool NUW, 52*0fca6ea1SDimitry Andric const KnownBits &LHS, 53*0fca6ea1SDimitry Andric const KnownBits &RHS) { 54*0fca6ea1SDimitry Andric unsigned BitWidth = LHS.getBitWidth(); 55*0fca6ea1SDimitry Andric KnownBits KnownOut(BitWidth); 56*0fca6ea1SDimitry Andric // This can be a relatively expensive helper, so optimistically save some 57*0fca6ea1SDimitry Andric // work. 58*0fca6ea1SDimitry Andric if (LHS.isUnknown() && RHS.isUnknown()) 59*0fca6ea1SDimitry Andric return KnownOut; 60*0fca6ea1SDimitry Andric 61*0fca6ea1SDimitry Andric if (!LHS.isUnknown() && !RHS.isUnknown()) { 620b57cec5SDimitry Andric if (Add) { 630b57cec5SDimitry Andric // Sum = LHS + RHS + 0 64*0fca6ea1SDimitry Andric KnownOut = ::computeForAddCarry(LHS, RHS, /*CarryZero=*/true, 65*0fca6ea1SDimitry Andric /*CarryOne=*/false); 660b57cec5SDimitry Andric } else { 670b57cec5SDimitry Andric // Sum = LHS + ~RHS + 1 68*0fca6ea1SDimitry Andric KnownBits NotRHS = RHS; 69*0fca6ea1SDimitry Andric std::swap(NotRHS.Zero, NotRHS.One); 70*0fca6ea1SDimitry Andric KnownOut = ::computeForAddCarry(LHS, NotRHS, /*CarryZero=*/false, 71*0fca6ea1SDimitry Andric /*CarryOne=*/true); 72*0fca6ea1SDimitry Andric } 730b57cec5SDimitry Andric } 740b57cec5SDimitry Andric 75*0fca6ea1SDimitry Andric // Handle add/sub given nsw and/or nuw. 76*0fca6ea1SDimitry Andric if (NUW) { 77*0fca6ea1SDimitry Andric if (Add) { 78*0fca6ea1SDimitry Andric // (add nuw X, Y) 79*0fca6ea1SDimitry Andric APInt MinVal = LHS.getMinValue().uadd_sat(RHS.getMinValue()); 80*0fca6ea1SDimitry Andric // None of the adds can end up overflowing, so min consecutive highbits 81*0fca6ea1SDimitry Andric // in minimum possible of X + Y must all remain set. 820b57cec5SDimitry Andric if (NSW) { 83*0fca6ea1SDimitry Andric unsigned NumBits = MinVal.trunc(BitWidth - 1).countl_one(); 84*0fca6ea1SDimitry Andric // If we have NSW as well, we also know we can't overflow the signbit so 85*0fca6ea1SDimitry Andric // can start counting from 1 bit back. 86*0fca6ea1SDimitry Andric KnownOut.One.setBits(BitWidth - 1 - NumBits, BitWidth - 1); 87*0fca6ea1SDimitry Andric } 88*0fca6ea1SDimitry Andric KnownOut.One.setHighBits(MinVal.countl_one()); 89*0fca6ea1SDimitry Andric } else { 90*0fca6ea1SDimitry Andric // (sub nuw X, Y) 91*0fca6ea1SDimitry Andric APInt MaxVal = LHS.getMaxValue().usub_sat(RHS.getMinValue()); 92*0fca6ea1SDimitry Andric // None of the subs can overflow at any point, so any common high bits 93*0fca6ea1SDimitry Andric // will subtract away and result in zeros. 94*0fca6ea1SDimitry Andric if (NSW) { 95*0fca6ea1SDimitry Andric // If we have NSW as well, we also know we can't overflow the signbit so 96*0fca6ea1SDimitry Andric // can start counting from 1 bit back. 97*0fca6ea1SDimitry Andric unsigned NumBits = MaxVal.trunc(BitWidth - 1).countl_zero(); 98*0fca6ea1SDimitry Andric KnownOut.Zero.setBits(BitWidth - 1 - NumBits, BitWidth - 1); 99*0fca6ea1SDimitry Andric } 100*0fca6ea1SDimitry Andric KnownOut.Zero.setHighBits(MaxVal.countl_zero()); 1010b57cec5SDimitry Andric } 1020b57cec5SDimitry Andric } 1030b57cec5SDimitry Andric 104*0fca6ea1SDimitry Andric if (NSW) { 105*0fca6ea1SDimitry Andric APInt MinVal; 106*0fca6ea1SDimitry Andric APInt MaxVal; 107*0fca6ea1SDimitry Andric if (Add) { 108*0fca6ea1SDimitry Andric // (add nsw X, Y) 109*0fca6ea1SDimitry Andric MinVal = LHS.getSignedMinValue().sadd_sat(RHS.getSignedMinValue()); 110*0fca6ea1SDimitry Andric MaxVal = LHS.getSignedMaxValue().sadd_sat(RHS.getSignedMaxValue()); 111*0fca6ea1SDimitry Andric } else { 112*0fca6ea1SDimitry Andric // (sub nsw X, Y) 113*0fca6ea1SDimitry Andric MinVal = LHS.getSignedMinValue().ssub_sat(RHS.getSignedMaxValue()); 114*0fca6ea1SDimitry Andric MaxVal = LHS.getSignedMaxValue().ssub_sat(RHS.getSignedMinValue()); 115*0fca6ea1SDimitry Andric } 116*0fca6ea1SDimitry Andric if (MinVal.isNonNegative()) { 117*0fca6ea1SDimitry Andric // If min is non-negative, result will always be non-neg (can't overflow 118*0fca6ea1SDimitry Andric // around). 119*0fca6ea1SDimitry Andric unsigned NumBits = MinVal.trunc(BitWidth - 1).countl_one(); 120*0fca6ea1SDimitry Andric KnownOut.One.setBits(BitWidth - 1 - NumBits, BitWidth - 1); 121*0fca6ea1SDimitry Andric KnownOut.Zero.setSignBit(); 122*0fca6ea1SDimitry Andric } 123*0fca6ea1SDimitry Andric if (MaxVal.isNegative()) { 124*0fca6ea1SDimitry Andric // If max is negative, result will always be neg (can't overflow around). 125*0fca6ea1SDimitry Andric unsigned NumBits = MaxVal.trunc(BitWidth - 1).countl_zero(); 126*0fca6ea1SDimitry Andric KnownOut.Zero.setBits(BitWidth - 1 - NumBits, BitWidth - 1); 127*0fca6ea1SDimitry Andric KnownOut.One.setSignBit(); 128*0fca6ea1SDimitry Andric } 129*0fca6ea1SDimitry Andric } 130*0fca6ea1SDimitry Andric 131*0fca6ea1SDimitry Andric // Just return 0 if the nsw/nuw is violated and we have poison. 132*0fca6ea1SDimitry Andric if (KnownOut.hasConflict()) 133*0fca6ea1SDimitry Andric KnownOut.setAllZero(); 1340b57cec5SDimitry Andric return KnownOut; 1350b57cec5SDimitry Andric } 1365ffd83dbSDimitry Andric 1375f757f3fSDimitry Andric KnownBits KnownBits::computeForSubBorrow(const KnownBits &LHS, KnownBits RHS, 1385f757f3fSDimitry Andric const KnownBits &Borrow) { 1395f757f3fSDimitry Andric assert(Borrow.getBitWidth() == 1 && "Borrow must be 1-bit"); 1405f757f3fSDimitry Andric 1415f757f3fSDimitry Andric // LHS - RHS = LHS + ~RHS + 1 1425f757f3fSDimitry Andric // Carry 1 - Borrow in ::computeForAddCarry 1435f757f3fSDimitry Andric std::swap(RHS.Zero, RHS.One); 1445f757f3fSDimitry Andric return ::computeForAddCarry(LHS, RHS, 1455f757f3fSDimitry Andric /*CarryZero=*/Borrow.One.getBoolValue(), 1465f757f3fSDimitry Andric /*CarryOne=*/Borrow.Zero.getBoolValue()); 1475f757f3fSDimitry Andric } 1485f757f3fSDimitry Andric 149e8d8bef9SDimitry Andric KnownBits KnownBits::sextInReg(unsigned SrcBitWidth) const { 150e8d8bef9SDimitry Andric unsigned BitWidth = getBitWidth(); 151e8d8bef9SDimitry Andric assert(0 < SrcBitWidth && SrcBitWidth <= BitWidth && 152e8d8bef9SDimitry Andric "Illegal sext-in-register"); 153e8d8bef9SDimitry Andric 154e8d8bef9SDimitry Andric if (SrcBitWidth == BitWidth) 155e8d8bef9SDimitry Andric return *this; 156e8d8bef9SDimitry Andric 157e8d8bef9SDimitry Andric unsigned ExtBits = BitWidth - SrcBitWidth; 158e8d8bef9SDimitry Andric KnownBits Result; 159e8d8bef9SDimitry Andric Result.One = One << ExtBits; 160e8d8bef9SDimitry Andric Result.Zero = Zero << ExtBits; 161e8d8bef9SDimitry Andric Result.One.ashrInPlace(ExtBits); 162e8d8bef9SDimitry Andric Result.Zero.ashrInPlace(ExtBits); 163e8d8bef9SDimitry Andric return Result; 164e8d8bef9SDimitry Andric } 165e8d8bef9SDimitry Andric 166e8d8bef9SDimitry Andric KnownBits KnownBits::makeGE(const APInt &Val) const { 167e8d8bef9SDimitry Andric // Count the number of leading bit positions where our underlying value is 168e8d8bef9SDimitry Andric // known to be less than or equal to Val. 16906c3fb27SDimitry Andric unsigned N = (Zero | Val).countl_one(); 170e8d8bef9SDimitry Andric 171e8d8bef9SDimitry Andric // For each of those bit positions, if Val has a 1 in that bit then our 172e8d8bef9SDimitry Andric // underlying value must also have a 1. 173e8d8bef9SDimitry Andric APInt MaskedVal(Val); 174e8d8bef9SDimitry Andric MaskedVal.clearLowBits(getBitWidth() - N); 175e8d8bef9SDimitry Andric return KnownBits(Zero, One | MaskedVal); 176e8d8bef9SDimitry Andric } 177e8d8bef9SDimitry Andric 178e8d8bef9SDimitry Andric KnownBits KnownBits::umax(const KnownBits &LHS, const KnownBits &RHS) { 179e8d8bef9SDimitry Andric // If we can prove that LHS >= RHS then use LHS as the result. Likewise for 180e8d8bef9SDimitry Andric // RHS. Ideally our caller would already have spotted these cases and 181e8d8bef9SDimitry Andric // optimized away the umax operation, but we handle them here for 182e8d8bef9SDimitry Andric // completeness. 183e8d8bef9SDimitry Andric if (LHS.getMinValue().uge(RHS.getMaxValue())) 184e8d8bef9SDimitry Andric return LHS; 185e8d8bef9SDimitry Andric if (RHS.getMinValue().uge(LHS.getMaxValue())) 186e8d8bef9SDimitry Andric return RHS; 187e8d8bef9SDimitry Andric 188e8d8bef9SDimitry Andric // If the result of the umax is LHS then it must be greater than or equal to 189e8d8bef9SDimitry Andric // the minimum possible value of RHS. Likewise for RHS. Any known bits that 190e8d8bef9SDimitry Andric // are common to these two values are also known in the result. 191e8d8bef9SDimitry Andric KnownBits L = LHS.makeGE(RHS.getMinValue()); 192e8d8bef9SDimitry Andric KnownBits R = RHS.makeGE(LHS.getMinValue()); 19306c3fb27SDimitry Andric return L.intersectWith(R); 194e8d8bef9SDimitry Andric } 195e8d8bef9SDimitry Andric 196e8d8bef9SDimitry Andric KnownBits KnownBits::umin(const KnownBits &LHS, const KnownBits &RHS) { 197e8d8bef9SDimitry Andric // Flip the range of values: [0, 0xFFFFFFFF] <-> [0xFFFFFFFF, 0] 198e8d8bef9SDimitry Andric auto Flip = [](const KnownBits &Val) { return KnownBits(Val.One, Val.Zero); }; 199e8d8bef9SDimitry Andric return Flip(umax(Flip(LHS), Flip(RHS))); 200e8d8bef9SDimitry Andric } 201e8d8bef9SDimitry Andric 202e8d8bef9SDimitry Andric KnownBits KnownBits::smax(const KnownBits &LHS, const KnownBits &RHS) { 203e8d8bef9SDimitry Andric // Flip the range of values: [-0x80000000, 0x7FFFFFFF] <-> [0, 0xFFFFFFFF] 204e8d8bef9SDimitry Andric auto Flip = [](const KnownBits &Val) { 205e8d8bef9SDimitry Andric unsigned SignBitPosition = Val.getBitWidth() - 1; 206e8d8bef9SDimitry Andric APInt Zero = Val.Zero; 207e8d8bef9SDimitry Andric APInt One = Val.One; 208e8d8bef9SDimitry Andric Zero.setBitVal(SignBitPosition, Val.One[SignBitPosition]); 209e8d8bef9SDimitry Andric One.setBitVal(SignBitPosition, Val.Zero[SignBitPosition]); 210e8d8bef9SDimitry Andric return KnownBits(Zero, One); 211e8d8bef9SDimitry Andric }; 212e8d8bef9SDimitry Andric return Flip(umax(Flip(LHS), Flip(RHS))); 213e8d8bef9SDimitry Andric } 214e8d8bef9SDimitry Andric 215e8d8bef9SDimitry Andric KnownBits KnownBits::smin(const KnownBits &LHS, const KnownBits &RHS) { 216e8d8bef9SDimitry Andric // Flip the range of values: [-0x80000000, 0x7FFFFFFF] <-> [0xFFFFFFFF, 0] 217e8d8bef9SDimitry Andric auto Flip = [](const KnownBits &Val) { 218e8d8bef9SDimitry Andric unsigned SignBitPosition = Val.getBitWidth() - 1; 219e8d8bef9SDimitry Andric APInt Zero = Val.One; 220e8d8bef9SDimitry Andric APInt One = Val.Zero; 221e8d8bef9SDimitry Andric Zero.setBitVal(SignBitPosition, Val.Zero[SignBitPosition]); 222e8d8bef9SDimitry Andric One.setBitVal(SignBitPosition, Val.One[SignBitPosition]); 223e8d8bef9SDimitry Andric return KnownBits(Zero, One); 224e8d8bef9SDimitry Andric }; 225e8d8bef9SDimitry Andric return Flip(umax(Flip(LHS), Flip(RHS))); 226e8d8bef9SDimitry Andric } 227e8d8bef9SDimitry Andric 228*0fca6ea1SDimitry Andric KnownBits KnownBits::abdu(const KnownBits &LHS, const KnownBits &RHS) { 229*0fca6ea1SDimitry Andric // If we know which argument is larger, return (sub LHS, RHS) or 230*0fca6ea1SDimitry Andric // (sub RHS, LHS) directly. 231*0fca6ea1SDimitry Andric if (LHS.getMinValue().uge(RHS.getMaxValue())) 232*0fca6ea1SDimitry Andric return computeForAddSub(/*Add=*/false, /*NSW=*/false, /*NUW=*/false, LHS, 233*0fca6ea1SDimitry Andric RHS); 234*0fca6ea1SDimitry Andric if (RHS.getMinValue().uge(LHS.getMaxValue())) 235*0fca6ea1SDimitry Andric return computeForAddSub(/*Add=*/false, /*NSW=*/false, /*NUW=*/false, RHS, 236*0fca6ea1SDimitry Andric LHS); 237*0fca6ea1SDimitry Andric 238*0fca6ea1SDimitry Andric // By construction, the subtraction in abdu never has unsigned overflow. 239*0fca6ea1SDimitry Andric // Find the common bits between (sub nuw LHS, RHS) and (sub nuw RHS, LHS). 240*0fca6ea1SDimitry Andric KnownBits Diff0 = 241*0fca6ea1SDimitry Andric computeForAddSub(/*Add=*/false, /*NSW=*/false, /*NUW=*/true, LHS, RHS); 242*0fca6ea1SDimitry Andric KnownBits Diff1 = 243*0fca6ea1SDimitry Andric computeForAddSub(/*Add=*/false, /*NSW=*/false, /*NUW=*/true, RHS, LHS); 244*0fca6ea1SDimitry Andric return Diff0.intersectWith(Diff1); 245*0fca6ea1SDimitry Andric } 246*0fca6ea1SDimitry Andric 247*0fca6ea1SDimitry Andric KnownBits KnownBits::abds(KnownBits LHS, KnownBits RHS) { 248*0fca6ea1SDimitry Andric // If we know which argument is larger, return (sub LHS, RHS) or 249*0fca6ea1SDimitry Andric // (sub RHS, LHS) directly. 250*0fca6ea1SDimitry Andric if (LHS.getSignedMinValue().sge(RHS.getSignedMaxValue())) 251*0fca6ea1SDimitry Andric return computeForAddSub(/*Add=*/false, /*NSW=*/false, /*NUW=*/false, LHS, 252*0fca6ea1SDimitry Andric RHS); 253*0fca6ea1SDimitry Andric if (RHS.getSignedMinValue().sge(LHS.getSignedMaxValue())) 254*0fca6ea1SDimitry Andric return computeForAddSub(/*Add=*/false, /*NSW=*/false, /*NUW=*/false, RHS, 255*0fca6ea1SDimitry Andric LHS); 256*0fca6ea1SDimitry Andric 257*0fca6ea1SDimitry Andric // Shift both arguments from the signed range to the unsigned range, e.g. from 258*0fca6ea1SDimitry Andric // [-0x80, 0x7F] to [0, 0xFF]. This allows us to use "sub nuw" below just like 259*0fca6ea1SDimitry Andric // abdu does. 260*0fca6ea1SDimitry Andric // Note that we can't just use "sub nsw" instead because abds has signed 261*0fca6ea1SDimitry Andric // inputs but an unsigned result, which makes the overflow conditions 262*0fca6ea1SDimitry Andric // different. 263*0fca6ea1SDimitry Andric unsigned SignBitPosition = LHS.getBitWidth() - 1; 264*0fca6ea1SDimitry Andric for (auto Arg : {&LHS, &RHS}) { 265*0fca6ea1SDimitry Andric bool Tmp = Arg->Zero[SignBitPosition]; 266*0fca6ea1SDimitry Andric Arg->Zero.setBitVal(SignBitPosition, Arg->One[SignBitPosition]); 267*0fca6ea1SDimitry Andric Arg->One.setBitVal(SignBitPosition, Tmp); 268*0fca6ea1SDimitry Andric } 269*0fca6ea1SDimitry Andric 270*0fca6ea1SDimitry Andric // Find the common bits between (sub nuw LHS, RHS) and (sub nuw RHS, LHS). 271*0fca6ea1SDimitry Andric KnownBits Diff0 = 272*0fca6ea1SDimitry Andric computeForAddSub(/*Add=*/false, /*NSW=*/false, /*NUW=*/true, LHS, RHS); 273*0fca6ea1SDimitry Andric KnownBits Diff1 = 274*0fca6ea1SDimitry Andric computeForAddSub(/*Add=*/false, /*NSW=*/false, /*NUW=*/true, RHS, LHS); 275*0fca6ea1SDimitry Andric return Diff0.intersectWith(Diff1); 276*0fca6ea1SDimitry Andric } 277*0fca6ea1SDimitry Andric 27806c3fb27SDimitry Andric static unsigned getMaxShiftAmount(const APInt &MaxValue, unsigned BitWidth) { 27906c3fb27SDimitry Andric if (isPowerOf2_32(BitWidth)) 28006c3fb27SDimitry Andric return MaxValue.extractBitsAsZExtValue(Log2_32(BitWidth), 0); 28106c3fb27SDimitry Andric // This is only an approximate upper bound. 28206c3fb27SDimitry Andric return MaxValue.getLimitedValue(BitWidth - 1); 28306c3fb27SDimitry Andric } 284e8d8bef9SDimitry Andric 28506c3fb27SDimitry Andric KnownBits KnownBits::shl(const KnownBits &LHS, const KnownBits &RHS, bool NUW, 28606c3fb27SDimitry Andric bool NSW, bool ShAmtNonZero) { 28706c3fb27SDimitry Andric unsigned BitWidth = LHS.getBitWidth(); 28806c3fb27SDimitry Andric auto ShiftByConst = [&](const KnownBits &LHS, unsigned ShiftAmt) { 28906c3fb27SDimitry Andric KnownBits Known; 29006c3fb27SDimitry Andric bool ShiftedOutZero, ShiftedOutOne; 29106c3fb27SDimitry Andric Known.Zero = LHS.Zero.ushl_ov(ShiftAmt, ShiftedOutZero); 29206c3fb27SDimitry Andric Known.Zero.setLowBits(ShiftAmt); 29306c3fb27SDimitry Andric Known.One = LHS.One.ushl_ov(ShiftAmt, ShiftedOutOne); 29406c3fb27SDimitry Andric 29506c3fb27SDimitry Andric // All cases returning poison have been handled by MaxShiftAmount already. 29606c3fb27SDimitry Andric if (NSW) { 29706c3fb27SDimitry Andric if (NUW && ShiftAmt != 0) 29806c3fb27SDimitry Andric // NUW means we can assume anything shifted out was a zero. 29906c3fb27SDimitry Andric ShiftedOutZero = true; 30006c3fb27SDimitry Andric 30106c3fb27SDimitry Andric if (ShiftedOutZero) 30206c3fb27SDimitry Andric Known.makeNonNegative(); 30306c3fb27SDimitry Andric else if (ShiftedOutOne) 30406c3fb27SDimitry Andric Known.makeNegative(); 30506c3fb27SDimitry Andric } 30606c3fb27SDimitry Andric return Known; 30706c3fb27SDimitry Andric }; 30806c3fb27SDimitry Andric 30906c3fb27SDimitry Andric // Fast path for a common case when LHS is completely unknown. 31006c3fb27SDimitry Andric KnownBits Known(BitWidth); 31106c3fb27SDimitry Andric unsigned MinShiftAmount = RHS.getMinValue().getLimitedValue(BitWidth); 31206c3fb27SDimitry Andric if (MinShiftAmount == 0 && ShAmtNonZero) 31306c3fb27SDimitry Andric MinShiftAmount = 1; 31406c3fb27SDimitry Andric if (LHS.isUnknown()) { 31506c3fb27SDimitry Andric Known.Zero.setLowBits(MinShiftAmount); 31606c3fb27SDimitry Andric if (NUW && NSW && MinShiftAmount != 0) 31706c3fb27SDimitry Andric Known.makeNonNegative(); 318e8d8bef9SDimitry Andric return Known; 319e8d8bef9SDimitry Andric } 320e8d8bef9SDimitry Andric 32106c3fb27SDimitry Andric // Determine maximum shift amount, taking NUW/NSW flags into account. 32206c3fb27SDimitry Andric APInt MaxValue = RHS.getMaxValue(); 32306c3fb27SDimitry Andric unsigned MaxShiftAmount = getMaxShiftAmount(MaxValue, BitWidth); 32406c3fb27SDimitry Andric if (NUW && NSW) 32506c3fb27SDimitry Andric MaxShiftAmount = std::min(MaxShiftAmount, LHS.countMaxLeadingZeros() - 1); 32606c3fb27SDimitry Andric if (NUW) 32706c3fb27SDimitry Andric MaxShiftAmount = std::min(MaxShiftAmount, LHS.countMaxLeadingZeros()); 32806c3fb27SDimitry Andric if (NSW) 32906c3fb27SDimitry Andric MaxShiftAmount = std::min( 33006c3fb27SDimitry Andric MaxShiftAmount, 33106c3fb27SDimitry Andric std::max(LHS.countMaxLeadingZeros(), LHS.countMaxLeadingOnes()) - 1); 332e8d8bef9SDimitry Andric 33306c3fb27SDimitry Andric // Fast path for common case where the shift amount is unknown. 33406c3fb27SDimitry Andric if (MinShiftAmount == 0 && MaxShiftAmount == BitWidth - 1 && 33506c3fb27SDimitry Andric isPowerOf2_32(BitWidth)) { 33606c3fb27SDimitry Andric Known.Zero.setLowBits(LHS.countMinTrailingZeros()); 33706c3fb27SDimitry Andric if (LHS.isAllOnes()) 33806c3fb27SDimitry Andric Known.One.setSignBit(); 33906c3fb27SDimitry Andric if (NSW) { 34006c3fb27SDimitry Andric if (LHS.isNonNegative()) 34106c3fb27SDimitry Andric Known.makeNonNegative(); 34206c3fb27SDimitry Andric if (LHS.isNegative()) 34306c3fb27SDimitry Andric Known.makeNegative(); 34406c3fb27SDimitry Andric } 34506c3fb27SDimitry Andric return Known; 346e8d8bef9SDimitry Andric } 347e8d8bef9SDimitry Andric 34806c3fb27SDimitry Andric // Find the common bits from all possible shifts. 34906c3fb27SDimitry Andric unsigned ShiftAmtZeroMask = RHS.Zero.zextOrTrunc(32).getZExtValue(); 35006c3fb27SDimitry Andric unsigned ShiftAmtOneMask = RHS.One.zextOrTrunc(32).getZExtValue(); 351fe6060f1SDimitry Andric Known.Zero.setAllBits(); 352fe6060f1SDimitry Andric Known.One.setAllBits(); 35306c3fb27SDimitry Andric for (unsigned ShiftAmt = MinShiftAmount; ShiftAmt <= MaxShiftAmount; 35406c3fb27SDimitry Andric ++ShiftAmt) { 355fe6060f1SDimitry Andric // Skip if the shift amount is impossible. 35606c3fb27SDimitry Andric if ((ShiftAmtZeroMask & ShiftAmt) != 0 || 357fe6060f1SDimitry Andric (ShiftAmtOneMask | ShiftAmt) != ShiftAmt) 358fe6060f1SDimitry Andric continue; 35906c3fb27SDimitry Andric Known = Known.intersectWith(ShiftByConst(LHS, ShiftAmt)); 360fe6060f1SDimitry Andric if (Known.isUnknown()) 361fe6060f1SDimitry Andric break; 362fe6060f1SDimitry Andric } 363fe6060f1SDimitry Andric 36406c3fb27SDimitry Andric // All shift amounts may result in poison. 36506c3fb27SDimitry Andric if (Known.hasConflict()) 36606c3fb27SDimitry Andric Known.setAllZero(); 367e8d8bef9SDimitry Andric return Known; 368e8d8bef9SDimitry Andric } 369e8d8bef9SDimitry Andric 37006c3fb27SDimitry Andric KnownBits KnownBits::lshr(const KnownBits &LHS, const KnownBits &RHS, 371*0fca6ea1SDimitry Andric bool ShAmtNonZero, bool Exact) { 372e8d8bef9SDimitry Andric unsigned BitWidth = LHS.getBitWidth(); 37306c3fb27SDimitry Andric auto ShiftByConst = [&](const KnownBits &LHS, unsigned ShiftAmt) { 37406c3fb27SDimitry Andric KnownBits Known = LHS; 37506c3fb27SDimitry Andric Known.Zero.lshrInPlace(ShiftAmt); 37606c3fb27SDimitry Andric Known.One.lshrInPlace(ShiftAmt); 377e8d8bef9SDimitry Andric // High bits are known zero. 37806c3fb27SDimitry Andric Known.Zero.setHighBits(ShiftAmt); 379e8d8bef9SDimitry Andric return Known; 38006c3fb27SDimitry Andric }; 381e8d8bef9SDimitry Andric 38206c3fb27SDimitry Andric // Fast path for a common case when LHS is completely unknown. 383e8d8bef9SDimitry Andric KnownBits Known(BitWidth); 38406c3fb27SDimitry Andric unsigned MinShiftAmount = RHS.getMinValue().getLimitedValue(BitWidth); 38506c3fb27SDimitry Andric if (MinShiftAmount == 0 && ShAmtNonZero) 38606c3fb27SDimitry Andric MinShiftAmount = 1; 38706c3fb27SDimitry Andric if (LHS.isUnknown()) { 38806c3fb27SDimitry Andric Known.Zero.setHighBits(MinShiftAmount); 389e8d8bef9SDimitry Andric return Known; 390e8d8bef9SDimitry Andric } 391e8d8bef9SDimitry Andric 39206c3fb27SDimitry Andric // Find the common bits from all possible shifts. 39306c3fb27SDimitry Andric APInt MaxValue = RHS.getMaxValue(); 39406c3fb27SDimitry Andric unsigned MaxShiftAmount = getMaxShiftAmount(MaxValue, BitWidth); 395*0fca6ea1SDimitry Andric 396*0fca6ea1SDimitry Andric // If exact, bound MaxShiftAmount to first known 1 in LHS. 397*0fca6ea1SDimitry Andric if (Exact) { 398*0fca6ea1SDimitry Andric unsigned FirstOne = LHS.countMaxTrailingZeros(); 399*0fca6ea1SDimitry Andric if (FirstOne < MinShiftAmount) { 400*0fca6ea1SDimitry Andric // Always poison. Return zero because we don't like returning conflict. 401*0fca6ea1SDimitry Andric Known.setAllZero(); 402*0fca6ea1SDimitry Andric return Known; 403*0fca6ea1SDimitry Andric } 404*0fca6ea1SDimitry Andric MaxShiftAmount = std::min(MaxShiftAmount, FirstOne); 405*0fca6ea1SDimitry Andric } 406*0fca6ea1SDimitry Andric 40706c3fb27SDimitry Andric unsigned ShiftAmtZeroMask = RHS.Zero.zextOrTrunc(32).getZExtValue(); 40806c3fb27SDimitry Andric unsigned ShiftAmtOneMask = RHS.One.zextOrTrunc(32).getZExtValue(); 409fe6060f1SDimitry Andric Known.Zero.setAllBits(); 410fe6060f1SDimitry Andric Known.One.setAllBits(); 41106c3fb27SDimitry Andric for (unsigned ShiftAmt = MinShiftAmount; ShiftAmt <= MaxShiftAmount; 41206c3fb27SDimitry Andric ++ShiftAmt) { 413fe6060f1SDimitry Andric // Skip if the shift amount is impossible. 41406c3fb27SDimitry Andric if ((ShiftAmtZeroMask & ShiftAmt) != 0 || 415fe6060f1SDimitry Andric (ShiftAmtOneMask | ShiftAmt) != ShiftAmt) 416fe6060f1SDimitry Andric continue; 41706c3fb27SDimitry Andric Known = Known.intersectWith(ShiftByConst(LHS, ShiftAmt)); 418fe6060f1SDimitry Andric if (Known.isUnknown()) 419fe6060f1SDimitry Andric break; 420fe6060f1SDimitry Andric } 42106c3fb27SDimitry Andric 42206c3fb27SDimitry Andric // All shift amounts may result in poison. 42306c3fb27SDimitry Andric if (Known.hasConflict()) 42406c3fb27SDimitry Andric Known.setAllZero(); 42506c3fb27SDimitry Andric return Known; 426fe6060f1SDimitry Andric } 427fe6060f1SDimitry Andric 42806c3fb27SDimitry Andric KnownBits KnownBits::ashr(const KnownBits &LHS, const KnownBits &RHS, 429*0fca6ea1SDimitry Andric bool ShAmtNonZero, bool Exact) { 43006c3fb27SDimitry Andric unsigned BitWidth = LHS.getBitWidth(); 43106c3fb27SDimitry Andric auto ShiftByConst = [&](const KnownBits &LHS, unsigned ShiftAmt) { 43206c3fb27SDimitry Andric KnownBits Known = LHS; 43306c3fb27SDimitry Andric Known.Zero.ashrInPlace(ShiftAmt); 43406c3fb27SDimitry Andric Known.One.ashrInPlace(ShiftAmt); 43506c3fb27SDimitry Andric return Known; 43606c3fb27SDimitry Andric }; 43706c3fb27SDimitry Andric 43806c3fb27SDimitry Andric // Fast path for a common case when LHS is completely unknown. 43906c3fb27SDimitry Andric KnownBits Known(BitWidth); 44006c3fb27SDimitry Andric unsigned MinShiftAmount = RHS.getMinValue().getLimitedValue(BitWidth); 44106c3fb27SDimitry Andric if (MinShiftAmount == 0 && ShAmtNonZero) 44206c3fb27SDimitry Andric MinShiftAmount = 1; 44306c3fb27SDimitry Andric if (LHS.isUnknown()) { 44406c3fb27SDimitry Andric if (MinShiftAmount == BitWidth) { 44506c3fb27SDimitry Andric // Always poison. Return zero because we don't like returning conflict. 44606c3fb27SDimitry Andric Known.setAllZero(); 44706c3fb27SDimitry Andric return Known; 44806c3fb27SDimitry Andric } 44906c3fb27SDimitry Andric return Known; 45006c3fb27SDimitry Andric } 45106c3fb27SDimitry Andric 45206c3fb27SDimitry Andric // Find the common bits from all possible shifts. 45306c3fb27SDimitry Andric APInt MaxValue = RHS.getMaxValue(); 45406c3fb27SDimitry Andric unsigned MaxShiftAmount = getMaxShiftAmount(MaxValue, BitWidth); 455*0fca6ea1SDimitry Andric 456*0fca6ea1SDimitry Andric // If exact, bound MaxShiftAmount to first known 1 in LHS. 457*0fca6ea1SDimitry Andric if (Exact) { 458*0fca6ea1SDimitry Andric unsigned FirstOne = LHS.countMaxTrailingZeros(); 459*0fca6ea1SDimitry Andric if (FirstOne < MinShiftAmount) { 460*0fca6ea1SDimitry Andric // Always poison. Return zero because we don't like returning conflict. 461*0fca6ea1SDimitry Andric Known.setAllZero(); 462*0fca6ea1SDimitry Andric return Known; 463*0fca6ea1SDimitry Andric } 464*0fca6ea1SDimitry Andric MaxShiftAmount = std::min(MaxShiftAmount, FirstOne); 465*0fca6ea1SDimitry Andric } 466*0fca6ea1SDimitry Andric 46706c3fb27SDimitry Andric unsigned ShiftAmtZeroMask = RHS.Zero.zextOrTrunc(32).getZExtValue(); 46806c3fb27SDimitry Andric unsigned ShiftAmtOneMask = RHS.One.zextOrTrunc(32).getZExtValue(); 46906c3fb27SDimitry Andric Known.Zero.setAllBits(); 47006c3fb27SDimitry Andric Known.One.setAllBits(); 47106c3fb27SDimitry Andric for (unsigned ShiftAmt = MinShiftAmount; ShiftAmt <= MaxShiftAmount; 47206c3fb27SDimitry Andric ++ShiftAmt) { 47306c3fb27SDimitry Andric // Skip if the shift amount is impossible. 47406c3fb27SDimitry Andric if ((ShiftAmtZeroMask & ShiftAmt) != 0 || 47506c3fb27SDimitry Andric (ShiftAmtOneMask | ShiftAmt) != ShiftAmt) 47606c3fb27SDimitry Andric continue; 47706c3fb27SDimitry Andric Known = Known.intersectWith(ShiftByConst(LHS, ShiftAmt)); 47806c3fb27SDimitry Andric if (Known.isUnknown()) 47906c3fb27SDimitry Andric break; 48006c3fb27SDimitry Andric } 48106c3fb27SDimitry Andric 48206c3fb27SDimitry Andric // All shift amounts may result in poison. 48306c3fb27SDimitry Andric if (Known.hasConflict()) 48406c3fb27SDimitry Andric Known.setAllZero(); 485e8d8bef9SDimitry Andric return Known; 486e8d8bef9SDimitry Andric } 487e8d8bef9SDimitry Andric 488bdd1243dSDimitry Andric std::optional<bool> KnownBits::eq(const KnownBits &LHS, const KnownBits &RHS) { 489e8d8bef9SDimitry Andric if (LHS.isConstant() && RHS.isConstant()) 490bdd1243dSDimitry Andric return std::optional<bool>(LHS.getConstant() == RHS.getConstant()); 491e8d8bef9SDimitry Andric if (LHS.One.intersects(RHS.Zero) || RHS.One.intersects(LHS.Zero)) 492bdd1243dSDimitry Andric return std::optional<bool>(false); 493bdd1243dSDimitry Andric return std::nullopt; 494e8d8bef9SDimitry Andric } 495e8d8bef9SDimitry Andric 496bdd1243dSDimitry Andric std::optional<bool> KnownBits::ne(const KnownBits &LHS, const KnownBits &RHS) { 497bdd1243dSDimitry Andric if (std::optional<bool> KnownEQ = eq(LHS, RHS)) 498bdd1243dSDimitry Andric return std::optional<bool>(!*KnownEQ); 499bdd1243dSDimitry Andric return std::nullopt; 500e8d8bef9SDimitry Andric } 501e8d8bef9SDimitry Andric 502bdd1243dSDimitry Andric std::optional<bool> KnownBits::ugt(const KnownBits &LHS, const KnownBits &RHS) { 503e8d8bef9SDimitry Andric // LHS >u RHS -> false if umax(LHS) <= umax(RHS) 504e8d8bef9SDimitry Andric if (LHS.getMaxValue().ule(RHS.getMinValue())) 505bdd1243dSDimitry Andric return std::optional<bool>(false); 506e8d8bef9SDimitry Andric // LHS >u RHS -> true if umin(LHS) > umax(RHS) 507e8d8bef9SDimitry Andric if (LHS.getMinValue().ugt(RHS.getMaxValue())) 508bdd1243dSDimitry Andric return std::optional<bool>(true); 509bdd1243dSDimitry Andric return std::nullopt; 510e8d8bef9SDimitry Andric } 511e8d8bef9SDimitry Andric 512bdd1243dSDimitry Andric std::optional<bool> KnownBits::uge(const KnownBits &LHS, const KnownBits &RHS) { 513bdd1243dSDimitry Andric if (std::optional<bool> IsUGT = ugt(RHS, LHS)) 514bdd1243dSDimitry Andric return std::optional<bool>(!*IsUGT); 515bdd1243dSDimitry Andric return std::nullopt; 516e8d8bef9SDimitry Andric } 517e8d8bef9SDimitry Andric 518bdd1243dSDimitry Andric std::optional<bool> KnownBits::ult(const KnownBits &LHS, const KnownBits &RHS) { 519e8d8bef9SDimitry Andric return ugt(RHS, LHS); 520e8d8bef9SDimitry Andric } 521e8d8bef9SDimitry Andric 522bdd1243dSDimitry Andric std::optional<bool> KnownBits::ule(const KnownBits &LHS, const KnownBits &RHS) { 523e8d8bef9SDimitry Andric return uge(RHS, LHS); 524e8d8bef9SDimitry Andric } 525e8d8bef9SDimitry Andric 526bdd1243dSDimitry Andric std::optional<bool> KnownBits::sgt(const KnownBits &LHS, const KnownBits &RHS) { 527e8d8bef9SDimitry Andric // LHS >s RHS -> false if smax(LHS) <= smax(RHS) 528e8d8bef9SDimitry Andric if (LHS.getSignedMaxValue().sle(RHS.getSignedMinValue())) 529bdd1243dSDimitry Andric return std::optional<bool>(false); 530e8d8bef9SDimitry Andric // LHS >s RHS -> true if smin(LHS) > smax(RHS) 531e8d8bef9SDimitry Andric if (LHS.getSignedMinValue().sgt(RHS.getSignedMaxValue())) 532bdd1243dSDimitry Andric return std::optional<bool>(true); 533bdd1243dSDimitry Andric return std::nullopt; 534e8d8bef9SDimitry Andric } 535e8d8bef9SDimitry Andric 536bdd1243dSDimitry Andric std::optional<bool> KnownBits::sge(const KnownBits &LHS, const KnownBits &RHS) { 537bdd1243dSDimitry Andric if (std::optional<bool> KnownSGT = sgt(RHS, LHS)) 538bdd1243dSDimitry Andric return std::optional<bool>(!*KnownSGT); 539bdd1243dSDimitry Andric return std::nullopt; 540e8d8bef9SDimitry Andric } 541e8d8bef9SDimitry Andric 542bdd1243dSDimitry Andric std::optional<bool> KnownBits::slt(const KnownBits &LHS, const KnownBits &RHS) { 543e8d8bef9SDimitry Andric return sgt(RHS, LHS); 544e8d8bef9SDimitry Andric } 545e8d8bef9SDimitry Andric 546bdd1243dSDimitry Andric std::optional<bool> KnownBits::sle(const KnownBits &LHS, const KnownBits &RHS) { 547e8d8bef9SDimitry Andric return sge(RHS, LHS); 548e8d8bef9SDimitry Andric } 549e8d8bef9SDimitry Andric 550e8d8bef9SDimitry Andric KnownBits KnownBits::abs(bool IntMinIsPoison) const { 551e8d8bef9SDimitry Andric // If the source's MSB is zero then we know the rest of the bits already. 552e8d8bef9SDimitry Andric if (isNonNegative()) 553e8d8bef9SDimitry Andric return *this; 554e8d8bef9SDimitry Andric 555e8d8bef9SDimitry Andric // Absolute value preserves trailing zero count. 556e8d8bef9SDimitry Andric KnownBits KnownAbs(getBitWidth()); 55706c3fb27SDimitry Andric 55806c3fb27SDimitry Andric // If the input is negative, then abs(x) == -x. 55906c3fb27SDimitry Andric if (isNegative()) { 56006c3fb27SDimitry Andric KnownBits Tmp = *this; 56106c3fb27SDimitry Andric // Special case for IntMinIsPoison. We know the sign bit is set and we know 56206c3fb27SDimitry Andric // all the rest of the bits except one to be zero. Since we have 56306c3fb27SDimitry Andric // IntMinIsPoison, that final bit MUST be a one, as otherwise the input is 56406c3fb27SDimitry Andric // INT_MIN. 56506c3fb27SDimitry Andric if (IntMinIsPoison && (Zero.popcount() + 2) == getBitWidth()) 56606c3fb27SDimitry Andric Tmp.One.setBit(countMinTrailingZeros()); 56706c3fb27SDimitry Andric 56806c3fb27SDimitry Andric KnownAbs = computeForAddSub( 569*0fca6ea1SDimitry Andric /*Add*/ false, IntMinIsPoison, /*NUW=*/false, 57006c3fb27SDimitry Andric KnownBits::makeConstant(APInt(getBitWidth(), 0)), Tmp); 57106c3fb27SDimitry Andric 57206c3fb27SDimitry Andric // One more special case for IntMinIsPoison. If we don't know any ones other 57306c3fb27SDimitry Andric // than the signbit, we know for certain that all the unknowns can't be 57406c3fb27SDimitry Andric // zero. So if we know high zero bits, but have unknown low bits, we know 57506c3fb27SDimitry Andric // for certain those high-zero bits will end up as one. This is because, 57606c3fb27SDimitry Andric // the low bits can't be all zeros, so the +1 in (~x + 1) cannot carry up 57706c3fb27SDimitry Andric // to the high bits. If we know a known INT_MIN input skip this. The result 57806c3fb27SDimitry Andric // is poison anyways. 57906c3fb27SDimitry Andric if (IntMinIsPoison && Tmp.countMinPopulation() == 1 && 58006c3fb27SDimitry Andric Tmp.countMaxPopulation() != 1) { 58106c3fb27SDimitry Andric Tmp.One.clearSignBit(); 58206c3fb27SDimitry Andric Tmp.Zero.setSignBit(); 58306c3fb27SDimitry Andric KnownAbs.One.setBits(getBitWidth() - Tmp.countMinLeadingZeros(), 58406c3fb27SDimitry Andric getBitWidth() - 1); 58506c3fb27SDimitry Andric } 58606c3fb27SDimitry Andric 58706c3fb27SDimitry Andric } else { 58806c3fb27SDimitry Andric unsigned MaxTZ = countMaxTrailingZeros(); 58906c3fb27SDimitry Andric unsigned MinTZ = countMinTrailingZeros(); 59006c3fb27SDimitry Andric 59106c3fb27SDimitry Andric KnownAbs.Zero.setLowBits(MinTZ); 59206c3fb27SDimitry Andric // If we know the lowest set 1, then preserve it. 59306c3fb27SDimitry Andric if (MaxTZ == MinTZ && MaxTZ < getBitWidth()) 59406c3fb27SDimitry Andric KnownAbs.One.setBit(MaxTZ); 595e8d8bef9SDimitry Andric 596e8d8bef9SDimitry Andric // We only know that the absolute values's MSB will be zero if INT_MIN is 597e8d8bef9SDimitry Andric // poison, or there is a set bit that isn't the sign bit (otherwise it could 598e8d8bef9SDimitry Andric // be INT_MIN). 59906c3fb27SDimitry Andric if (IntMinIsPoison || (!One.isZero() && !One.isMinSignedValue())) { 60006c3fb27SDimitry Andric KnownAbs.One.clearSignBit(); 601e8d8bef9SDimitry Andric KnownAbs.Zero.setSignBit(); 60206c3fb27SDimitry Andric } 60306c3fb27SDimitry Andric } 604e8d8bef9SDimitry Andric 605e8d8bef9SDimitry Andric return KnownAbs; 606e8d8bef9SDimitry Andric } 607e8d8bef9SDimitry Andric 60806c3fb27SDimitry Andric static KnownBits computeForSatAddSub(bool Add, bool Signed, 60906c3fb27SDimitry Andric const KnownBits &LHS, 61006c3fb27SDimitry Andric const KnownBits &RHS) { 61106c3fb27SDimitry Andric // We don't see NSW even for sadd/ssub as we want to check if the result has 61206c3fb27SDimitry Andric // signed overflow. 613*0fca6ea1SDimitry Andric KnownBits Res = 614*0fca6ea1SDimitry Andric KnownBits::computeForAddSub(Add, /*NSW=*/false, /*NUW=*/false, LHS, RHS); 61506c3fb27SDimitry Andric unsigned BitWidth = Res.getBitWidth(); 61606c3fb27SDimitry Andric auto SignBitKnown = [&](const KnownBits &K) { 61706c3fb27SDimitry Andric return K.Zero[BitWidth - 1] || K.One[BitWidth - 1]; 61806c3fb27SDimitry Andric }; 61906c3fb27SDimitry Andric std::optional<bool> Overflow; 62006c3fb27SDimitry Andric 62106c3fb27SDimitry Andric if (Signed) { 62206c3fb27SDimitry Andric // If we can actually detect overflow do so. Otherwise leave Overflow as 62306c3fb27SDimitry Andric // nullopt (we assume it may have happened). 62406c3fb27SDimitry Andric if (SignBitKnown(LHS) && SignBitKnown(RHS) && SignBitKnown(Res)) { 62506c3fb27SDimitry Andric if (Add) { 62606c3fb27SDimitry Andric // sadd.sat 62706c3fb27SDimitry Andric Overflow = (LHS.isNonNegative() == RHS.isNonNegative() && 62806c3fb27SDimitry Andric Res.isNonNegative() != LHS.isNonNegative()); 62906c3fb27SDimitry Andric } else { 63006c3fb27SDimitry Andric // ssub.sat 63106c3fb27SDimitry Andric Overflow = (LHS.isNonNegative() != RHS.isNonNegative() && 63206c3fb27SDimitry Andric Res.isNonNegative() != LHS.isNonNegative()); 63306c3fb27SDimitry Andric } 63406c3fb27SDimitry Andric } 63506c3fb27SDimitry Andric } else if (Add) { 63606c3fb27SDimitry Andric // uadd.sat 63706c3fb27SDimitry Andric bool Of; 63806c3fb27SDimitry Andric (void)LHS.getMaxValue().uadd_ov(RHS.getMaxValue(), Of); 63906c3fb27SDimitry Andric if (!Of) { 64006c3fb27SDimitry Andric Overflow = false; 64106c3fb27SDimitry Andric } else { 64206c3fb27SDimitry Andric (void)LHS.getMinValue().uadd_ov(RHS.getMinValue(), Of); 64306c3fb27SDimitry Andric if (Of) 64406c3fb27SDimitry Andric Overflow = true; 64506c3fb27SDimitry Andric } 64606c3fb27SDimitry Andric } else { 64706c3fb27SDimitry Andric // usub.sat 64806c3fb27SDimitry Andric bool Of; 64906c3fb27SDimitry Andric (void)LHS.getMinValue().usub_ov(RHS.getMaxValue(), Of); 65006c3fb27SDimitry Andric if (!Of) { 65106c3fb27SDimitry Andric Overflow = false; 65206c3fb27SDimitry Andric } else { 65306c3fb27SDimitry Andric (void)LHS.getMaxValue().usub_ov(RHS.getMinValue(), Of); 65406c3fb27SDimitry Andric if (Of) 65506c3fb27SDimitry Andric Overflow = true; 65606c3fb27SDimitry Andric } 65706c3fb27SDimitry Andric } 65806c3fb27SDimitry Andric 65906c3fb27SDimitry Andric if (Signed) { 66006c3fb27SDimitry Andric if (Add) { 66106c3fb27SDimitry Andric if (LHS.isNonNegative() && RHS.isNonNegative()) { 66206c3fb27SDimitry Andric // Pos + Pos -> Pos 66306c3fb27SDimitry Andric Res.One.clearSignBit(); 66406c3fb27SDimitry Andric Res.Zero.setSignBit(); 66506c3fb27SDimitry Andric } 66606c3fb27SDimitry Andric if (LHS.isNegative() && RHS.isNegative()) { 66706c3fb27SDimitry Andric // Neg + Neg -> Neg 66806c3fb27SDimitry Andric Res.One.setSignBit(); 66906c3fb27SDimitry Andric Res.Zero.clearSignBit(); 67006c3fb27SDimitry Andric } 67106c3fb27SDimitry Andric } else { 67206c3fb27SDimitry Andric if (LHS.isNegative() && RHS.isNonNegative()) { 67306c3fb27SDimitry Andric // Neg - Pos -> Neg 67406c3fb27SDimitry Andric Res.One.setSignBit(); 67506c3fb27SDimitry Andric Res.Zero.clearSignBit(); 67606c3fb27SDimitry Andric } else if (LHS.isNonNegative() && RHS.isNegative()) { 67706c3fb27SDimitry Andric // Pos - Neg -> Pos 67806c3fb27SDimitry Andric Res.One.clearSignBit(); 67906c3fb27SDimitry Andric Res.Zero.setSignBit(); 68006c3fb27SDimitry Andric } 68106c3fb27SDimitry Andric } 68206c3fb27SDimitry Andric } else { 68306c3fb27SDimitry Andric // Add: Leading ones of either operand are preserved. 68406c3fb27SDimitry Andric // Sub: Leading zeros of LHS and leading ones of RHS are preserved 68506c3fb27SDimitry Andric // as leading zeros in the result. 68606c3fb27SDimitry Andric unsigned LeadingKnown; 68706c3fb27SDimitry Andric if (Add) 68806c3fb27SDimitry Andric LeadingKnown = 68906c3fb27SDimitry Andric std::max(LHS.countMinLeadingOnes(), RHS.countMinLeadingOnes()); 69006c3fb27SDimitry Andric else 69106c3fb27SDimitry Andric LeadingKnown = 69206c3fb27SDimitry Andric std::max(LHS.countMinLeadingZeros(), RHS.countMinLeadingOnes()); 69306c3fb27SDimitry Andric 69406c3fb27SDimitry Andric // We select between the operation result and all-ones/zero 69506c3fb27SDimitry Andric // respectively, so we can preserve known ones/zeros. 69606c3fb27SDimitry Andric APInt Mask = APInt::getHighBitsSet(BitWidth, LeadingKnown); 69706c3fb27SDimitry Andric if (Add) { 69806c3fb27SDimitry Andric Res.One |= Mask; 69906c3fb27SDimitry Andric Res.Zero &= ~Mask; 70006c3fb27SDimitry Andric } else { 70106c3fb27SDimitry Andric Res.Zero |= Mask; 70206c3fb27SDimitry Andric Res.One &= ~Mask; 70306c3fb27SDimitry Andric } 70406c3fb27SDimitry Andric } 70506c3fb27SDimitry Andric 70606c3fb27SDimitry Andric if (Overflow) { 70706c3fb27SDimitry Andric // We know whether or not we overflowed. 70806c3fb27SDimitry Andric if (!(*Overflow)) { 70906c3fb27SDimitry Andric // No overflow. 71006c3fb27SDimitry Andric return Res; 71106c3fb27SDimitry Andric } 71206c3fb27SDimitry Andric 71306c3fb27SDimitry Andric // We overflowed 71406c3fb27SDimitry Andric APInt C; 71506c3fb27SDimitry Andric if (Signed) { 71606c3fb27SDimitry Andric // sadd.sat / ssub.sat 71706c3fb27SDimitry Andric assert(SignBitKnown(LHS) && 71806c3fb27SDimitry Andric "We somehow know overflow without knowing input sign"); 71906c3fb27SDimitry Andric C = LHS.isNegative() ? APInt::getSignedMinValue(BitWidth) 72006c3fb27SDimitry Andric : APInt::getSignedMaxValue(BitWidth); 72106c3fb27SDimitry Andric } else if (Add) { 72206c3fb27SDimitry Andric // uadd.sat 72306c3fb27SDimitry Andric C = APInt::getMaxValue(BitWidth); 72406c3fb27SDimitry Andric } else { 72506c3fb27SDimitry Andric // uadd.sat 72606c3fb27SDimitry Andric C = APInt::getMinValue(BitWidth); 72706c3fb27SDimitry Andric } 72806c3fb27SDimitry Andric 72906c3fb27SDimitry Andric Res.One = C; 73006c3fb27SDimitry Andric Res.Zero = ~C; 73106c3fb27SDimitry Andric return Res; 73206c3fb27SDimitry Andric } 73306c3fb27SDimitry Andric 73406c3fb27SDimitry Andric // We don't know if we overflowed. 73506c3fb27SDimitry Andric if (Signed) { 73606c3fb27SDimitry Andric // sadd.sat/ssub.sat 73706c3fb27SDimitry Andric // We can keep our information about the sign bits. 73806c3fb27SDimitry Andric Res.Zero.clearLowBits(BitWidth - 1); 73906c3fb27SDimitry Andric Res.One.clearLowBits(BitWidth - 1); 74006c3fb27SDimitry Andric } else if (Add) { 74106c3fb27SDimitry Andric // uadd.sat 74206c3fb27SDimitry Andric // We need to clear all the known zeros as we can only use the leading ones. 74306c3fb27SDimitry Andric Res.Zero.clearAllBits(); 74406c3fb27SDimitry Andric } else { 74506c3fb27SDimitry Andric // usub.sat 74606c3fb27SDimitry Andric // We need to clear all the known ones as we can only use the leading zero. 74706c3fb27SDimitry Andric Res.One.clearAllBits(); 74806c3fb27SDimitry Andric } 74906c3fb27SDimitry Andric 75006c3fb27SDimitry Andric return Res; 75106c3fb27SDimitry Andric } 75206c3fb27SDimitry Andric 75306c3fb27SDimitry Andric KnownBits KnownBits::sadd_sat(const KnownBits &LHS, const KnownBits &RHS) { 75406c3fb27SDimitry Andric return computeForSatAddSub(/*Add*/ true, /*Signed*/ true, LHS, RHS); 75506c3fb27SDimitry Andric } 75606c3fb27SDimitry Andric KnownBits KnownBits::ssub_sat(const KnownBits &LHS, const KnownBits &RHS) { 75706c3fb27SDimitry Andric return computeForSatAddSub(/*Add*/ false, /*Signed*/ true, LHS, RHS); 75806c3fb27SDimitry Andric } 75906c3fb27SDimitry Andric KnownBits KnownBits::uadd_sat(const KnownBits &LHS, const KnownBits &RHS) { 76006c3fb27SDimitry Andric return computeForSatAddSub(/*Add*/ true, /*Signed*/ false, LHS, RHS); 76106c3fb27SDimitry Andric } 76206c3fb27SDimitry Andric KnownBits KnownBits::usub_sat(const KnownBits &LHS, const KnownBits &RHS) { 76306c3fb27SDimitry Andric return computeForSatAddSub(/*Add*/ false, /*Signed*/ false, LHS, RHS); 76406c3fb27SDimitry Andric } 76506c3fb27SDimitry Andric 766*0fca6ea1SDimitry Andric static KnownBits avgCompute(KnownBits LHS, KnownBits RHS, bool IsCeil, 767*0fca6ea1SDimitry Andric bool IsSigned) { 768*0fca6ea1SDimitry Andric unsigned BitWidth = LHS.getBitWidth(); 769*0fca6ea1SDimitry Andric LHS = IsSigned ? LHS.sext(BitWidth + 1) : LHS.zext(BitWidth + 1); 770*0fca6ea1SDimitry Andric RHS = IsSigned ? RHS.sext(BitWidth + 1) : RHS.zext(BitWidth + 1); 771*0fca6ea1SDimitry Andric LHS = 772*0fca6ea1SDimitry Andric computeForAddCarry(LHS, RHS, /*CarryZero*/ !IsCeil, /*CarryOne*/ IsCeil); 773*0fca6ea1SDimitry Andric LHS = LHS.extractBits(BitWidth, 1); 774*0fca6ea1SDimitry Andric return LHS; 775*0fca6ea1SDimitry Andric } 776*0fca6ea1SDimitry Andric 777*0fca6ea1SDimitry Andric KnownBits KnownBits::avgFloorS(const KnownBits &LHS, const KnownBits &RHS) { 778*0fca6ea1SDimitry Andric return avgCompute(LHS, RHS, /* IsCeil */ false, 779*0fca6ea1SDimitry Andric /* IsSigned */ true); 780*0fca6ea1SDimitry Andric } 781*0fca6ea1SDimitry Andric 782*0fca6ea1SDimitry Andric KnownBits KnownBits::avgFloorU(const KnownBits &LHS, const KnownBits &RHS) { 783*0fca6ea1SDimitry Andric return avgCompute(LHS, RHS, /* IsCeil */ false, 784*0fca6ea1SDimitry Andric /* IsSigned */ false); 785*0fca6ea1SDimitry Andric } 786*0fca6ea1SDimitry Andric 787*0fca6ea1SDimitry Andric KnownBits KnownBits::avgCeilS(const KnownBits &LHS, const KnownBits &RHS) { 788*0fca6ea1SDimitry Andric return avgCompute(LHS, RHS, /* IsCeil */ true, 789*0fca6ea1SDimitry Andric /* IsSigned */ true); 790*0fca6ea1SDimitry Andric } 791*0fca6ea1SDimitry Andric 792*0fca6ea1SDimitry Andric KnownBits KnownBits::avgCeilU(const KnownBits &LHS, const KnownBits &RHS) { 793*0fca6ea1SDimitry Andric return avgCompute(LHS, RHS, /* IsCeil */ true, 794*0fca6ea1SDimitry Andric /* IsSigned */ false); 795*0fca6ea1SDimitry Andric } 796*0fca6ea1SDimitry Andric 797349cc55cSDimitry Andric KnownBits KnownBits::mul(const KnownBits &LHS, const KnownBits &RHS, 79881ad6265SDimitry Andric bool NoUndefSelfMultiply) { 799e8d8bef9SDimitry Andric unsigned BitWidth = LHS.getBitWidth(); 800*0fca6ea1SDimitry Andric assert(BitWidth == RHS.getBitWidth() && "Operand mismatch"); 80181ad6265SDimitry Andric assert((!NoUndefSelfMultiply || LHS == RHS) && 802349cc55cSDimitry Andric "Self multiplication knownbits mismatch"); 803e8d8bef9SDimitry Andric 8040eae32dcSDimitry Andric // Compute the high known-0 bits by multiplying the unsigned max of each side. 8050eae32dcSDimitry Andric // Conservatively, M active bits * N active bits results in M + N bits in the 8060eae32dcSDimitry Andric // result. But if we know a value is a power-of-2 for example, then this 8070eae32dcSDimitry Andric // computes one more leading zero. 8080eae32dcSDimitry Andric // TODO: This could be generalized to number of sign bits (negative numbers). 8090eae32dcSDimitry Andric APInt UMaxLHS = LHS.getMaxValue(); 8100eae32dcSDimitry Andric APInt UMaxRHS = RHS.getMaxValue(); 8110eae32dcSDimitry Andric 8120eae32dcSDimitry Andric // For leading zeros in the result to be valid, the unsigned max product must 8130eae32dcSDimitry Andric // fit in the bitwidth (it must not overflow). 8140eae32dcSDimitry Andric bool HasOverflow; 8150eae32dcSDimitry Andric APInt UMaxResult = UMaxLHS.umul_ov(UMaxRHS, HasOverflow); 81606c3fb27SDimitry Andric unsigned LeadZ = HasOverflow ? 0 : UMaxResult.countl_zero(); 817e8d8bef9SDimitry Andric 818e8d8bef9SDimitry Andric // The result of the bottom bits of an integer multiply can be 819e8d8bef9SDimitry Andric // inferred by looking at the bottom bits of both operands and 820e8d8bef9SDimitry Andric // multiplying them together. 821e8d8bef9SDimitry Andric // We can infer at least the minimum number of known trailing bits 822e8d8bef9SDimitry Andric // of both operands. Depending on number of trailing zeros, we can 823e8d8bef9SDimitry Andric // infer more bits, because (a*b) <=> ((a/m) * (b/n)) * (m*n) assuming 824e8d8bef9SDimitry Andric // a and b are divisible by m and n respectively. 825e8d8bef9SDimitry Andric // We then calculate how many of those bits are inferrable and set 826e8d8bef9SDimitry Andric // the output. For example, the i8 mul: 827e8d8bef9SDimitry Andric // a = XXXX1100 (12) 828e8d8bef9SDimitry Andric // b = XXXX1110 (14) 829e8d8bef9SDimitry Andric // We know the bottom 3 bits are zero since the first can be divided by 830e8d8bef9SDimitry Andric // 4 and the second by 2, thus having ((12/4) * (14/2)) * (2*4). 831e8d8bef9SDimitry Andric // Applying the multiplication to the trimmed arguments gets: 832e8d8bef9SDimitry Andric // XX11 (3) 833e8d8bef9SDimitry Andric // X111 (7) 834e8d8bef9SDimitry Andric // ------- 835e8d8bef9SDimitry Andric // XX11 836e8d8bef9SDimitry Andric // XX11 837e8d8bef9SDimitry Andric // XX11 838e8d8bef9SDimitry Andric // XX11 839e8d8bef9SDimitry Andric // ------- 840e8d8bef9SDimitry Andric // XXXXX01 841e8d8bef9SDimitry Andric // Which allows us to infer the 2 LSBs. Since we're multiplying the result 842e8d8bef9SDimitry Andric // by 8, the bottom 3 bits will be 0, so we can infer a total of 5 bits. 843e8d8bef9SDimitry Andric // The proof for this can be described as: 844e8d8bef9SDimitry Andric // Pre: (C1 >= 0) && (C1 < (1 << C5)) && (C2 >= 0) && (C2 < (1 << C6)) && 845e8d8bef9SDimitry Andric // (C7 == (1 << (umin(countTrailingZeros(C1), C5) + 846e8d8bef9SDimitry Andric // umin(countTrailingZeros(C2), C6) + 847e8d8bef9SDimitry Andric // umin(C5 - umin(countTrailingZeros(C1), C5), 848e8d8bef9SDimitry Andric // C6 - umin(countTrailingZeros(C2), C6)))) - 1) 849e8d8bef9SDimitry Andric // %aa = shl i8 %a, C5 850e8d8bef9SDimitry Andric // %bb = shl i8 %b, C6 851e8d8bef9SDimitry Andric // %aaa = or i8 %aa, C1 852e8d8bef9SDimitry Andric // %bbb = or i8 %bb, C2 853e8d8bef9SDimitry Andric // %mul = mul i8 %aaa, %bbb 854e8d8bef9SDimitry Andric // %mask = and i8 %mul, C7 855e8d8bef9SDimitry Andric // => 856e8d8bef9SDimitry Andric // %mask = i8 ((C1*C2)&C7) 857e8d8bef9SDimitry Andric // Where C5, C6 describe the known bits of %a, %b 858e8d8bef9SDimitry Andric // C1, C2 describe the known bottom bits of %a, %b. 859e8d8bef9SDimitry Andric // C7 describes the mask of the known bits of the result. 860e8d8bef9SDimitry Andric const APInt &Bottom0 = LHS.One; 861e8d8bef9SDimitry Andric const APInt &Bottom1 = RHS.One; 862e8d8bef9SDimitry Andric 863e8d8bef9SDimitry Andric // How many times we'd be able to divide each argument by 2 (shr by 1). 864e8d8bef9SDimitry Andric // This gives us the number of trailing zeros on the multiplication result. 86506c3fb27SDimitry Andric unsigned TrailBitsKnown0 = (LHS.Zero | LHS.One).countr_one(); 86606c3fb27SDimitry Andric unsigned TrailBitsKnown1 = (RHS.Zero | RHS.One).countr_one(); 867e8d8bef9SDimitry Andric unsigned TrailZero0 = LHS.countMinTrailingZeros(); 868e8d8bef9SDimitry Andric unsigned TrailZero1 = RHS.countMinTrailingZeros(); 869e8d8bef9SDimitry Andric unsigned TrailZ = TrailZero0 + TrailZero1; 870e8d8bef9SDimitry Andric 871e8d8bef9SDimitry Andric // Figure out the fewest known-bits operand. 872e8d8bef9SDimitry Andric unsigned SmallestOperand = 873e8d8bef9SDimitry Andric std::min(TrailBitsKnown0 - TrailZero0, TrailBitsKnown1 - TrailZero1); 874e8d8bef9SDimitry Andric unsigned ResultBitsKnown = std::min(SmallestOperand + TrailZ, BitWidth); 875e8d8bef9SDimitry Andric 876e8d8bef9SDimitry Andric APInt BottomKnown = 877e8d8bef9SDimitry Andric Bottom0.getLoBits(TrailBitsKnown0) * Bottom1.getLoBits(TrailBitsKnown1); 878e8d8bef9SDimitry Andric 879e8d8bef9SDimitry Andric KnownBits Res(BitWidth); 880e8d8bef9SDimitry Andric Res.Zero.setHighBits(LeadZ); 881e8d8bef9SDimitry Andric Res.Zero |= (~BottomKnown).getLoBits(ResultBitsKnown); 882e8d8bef9SDimitry Andric Res.One = BottomKnown.getLoBits(ResultBitsKnown); 883349cc55cSDimitry Andric 884349cc55cSDimitry Andric // If we're self-multiplying then bit[1] is guaranteed to be zero. 88581ad6265SDimitry Andric if (NoUndefSelfMultiply && BitWidth > 1) { 886349cc55cSDimitry Andric assert(Res.One[1] == 0 && 887349cc55cSDimitry Andric "Self-multiplication failed Quadratic Reciprocity!"); 888349cc55cSDimitry Andric Res.Zero.setBit(1); 889349cc55cSDimitry Andric } 890349cc55cSDimitry Andric 891e8d8bef9SDimitry Andric return Res; 892e8d8bef9SDimitry Andric } 893e8d8bef9SDimitry Andric 894fe6060f1SDimitry Andric KnownBits KnownBits::mulhs(const KnownBits &LHS, const KnownBits &RHS) { 895fe6060f1SDimitry Andric unsigned BitWidth = LHS.getBitWidth(); 896*0fca6ea1SDimitry Andric assert(BitWidth == RHS.getBitWidth() && "Operand mismatch"); 897fe6060f1SDimitry Andric KnownBits WideLHS = LHS.sext(2 * BitWidth); 898fe6060f1SDimitry Andric KnownBits WideRHS = RHS.sext(2 * BitWidth); 899fe6060f1SDimitry Andric return mul(WideLHS, WideRHS).extractBits(BitWidth, BitWidth); 900fe6060f1SDimitry Andric } 901fe6060f1SDimitry Andric 902fe6060f1SDimitry Andric KnownBits KnownBits::mulhu(const KnownBits &LHS, const KnownBits &RHS) { 903fe6060f1SDimitry Andric unsigned BitWidth = LHS.getBitWidth(); 904*0fca6ea1SDimitry Andric assert(BitWidth == RHS.getBitWidth() && "Operand mismatch"); 905fe6060f1SDimitry Andric KnownBits WideLHS = LHS.zext(2 * BitWidth); 906fe6060f1SDimitry Andric KnownBits WideRHS = RHS.zext(2 * BitWidth); 907fe6060f1SDimitry Andric return mul(WideLHS, WideRHS).extractBits(BitWidth, BitWidth); 908fe6060f1SDimitry Andric } 909fe6060f1SDimitry Andric 91006c3fb27SDimitry Andric static KnownBits divComputeLowBit(KnownBits Known, const KnownBits &LHS, 91106c3fb27SDimitry Andric const KnownBits &RHS, bool Exact) { 912e8d8bef9SDimitry Andric 91306c3fb27SDimitry Andric if (!Exact) 91406c3fb27SDimitry Andric return Known; 915e8d8bef9SDimitry Andric 91606c3fb27SDimitry Andric // If LHS is Odd, the result is Odd no matter what. 91706c3fb27SDimitry Andric // Odd / Odd -> Odd 91806c3fb27SDimitry Andric // Odd / Even -> Impossible (because its exact division) 91906c3fb27SDimitry Andric if (LHS.One[0]) 92006c3fb27SDimitry Andric Known.One.setBit(0); 921e8d8bef9SDimitry Andric 92206c3fb27SDimitry Andric int MinTZ = 92306c3fb27SDimitry Andric (int)LHS.countMinTrailingZeros() - (int)RHS.countMaxTrailingZeros(); 92406c3fb27SDimitry Andric int MaxTZ = 92506c3fb27SDimitry Andric (int)LHS.countMaxTrailingZeros() - (int)RHS.countMinTrailingZeros(); 92606c3fb27SDimitry Andric if (MinTZ >= 0) { 92706c3fb27SDimitry Andric // Result has at least MinTZ trailing zeros. 92806c3fb27SDimitry Andric Known.Zero.setLowBits(MinTZ); 92906c3fb27SDimitry Andric if (MinTZ == MaxTZ) { 93006c3fb27SDimitry Andric // Result has exactly MinTZ trailing zeros. 93106c3fb27SDimitry Andric Known.One.setBit(MinTZ); 93206c3fb27SDimitry Andric } 93306c3fb27SDimitry Andric } else if (MaxTZ < 0) { 93406c3fb27SDimitry Andric // Poison Result 93506c3fb27SDimitry Andric Known.setAllZero(); 93606c3fb27SDimitry Andric } 93706c3fb27SDimitry Andric 93806c3fb27SDimitry Andric // In the KnownBits exhaustive tests, we have poison inputs for exact values 93906c3fb27SDimitry Andric // a LOT. If we have a conflict, just return all zeros. 94006c3fb27SDimitry Andric if (Known.hasConflict()) 94106c3fb27SDimitry Andric Known.setAllZero(); 94206c3fb27SDimitry Andric 943e8d8bef9SDimitry Andric return Known; 944e8d8bef9SDimitry Andric } 945e8d8bef9SDimitry Andric 94606c3fb27SDimitry Andric KnownBits KnownBits::sdiv(const KnownBits &LHS, const KnownBits &RHS, 94706c3fb27SDimitry Andric bool Exact) { 94806c3fb27SDimitry Andric // Equivalent of `udiv`. We must have caught this before it was folded. 94906c3fb27SDimitry Andric if (LHS.isNonNegative() && RHS.isNonNegative()) 95006c3fb27SDimitry Andric return udiv(LHS, RHS, Exact); 95106c3fb27SDimitry Andric 95206c3fb27SDimitry Andric unsigned BitWidth = LHS.getBitWidth(); 95306c3fb27SDimitry Andric KnownBits Known(BitWidth); 95406c3fb27SDimitry Andric 95506c3fb27SDimitry Andric if (LHS.isZero() || RHS.isZero()) { 95606c3fb27SDimitry Andric // Result is either known Zero or UB. Return Zero either way. 95706c3fb27SDimitry Andric // Checking this earlier saves us a lot of special cases later on. 95806c3fb27SDimitry Andric Known.setAllZero(); 95906c3fb27SDimitry Andric return Known; 96006c3fb27SDimitry Andric } 96106c3fb27SDimitry Andric 96206c3fb27SDimitry Andric std::optional<APInt> Res; 96306c3fb27SDimitry Andric if (LHS.isNegative() && RHS.isNegative()) { 96406c3fb27SDimitry Andric // Result non-negative. 96506c3fb27SDimitry Andric APInt Denom = RHS.getSignedMaxValue(); 96606c3fb27SDimitry Andric APInt Num = LHS.getSignedMinValue(); 96706c3fb27SDimitry Andric // INT_MIN/-1 would be a poison result (impossible). Estimate the division 96806c3fb27SDimitry Andric // as signed max (we will only set sign bit in the result). 96906c3fb27SDimitry Andric Res = (Num.isMinSignedValue() && Denom.isAllOnes()) 97006c3fb27SDimitry Andric ? APInt::getSignedMaxValue(BitWidth) 97106c3fb27SDimitry Andric : Num.sdiv(Denom); 97206c3fb27SDimitry Andric } else if (LHS.isNegative() && RHS.isNonNegative()) { 97306c3fb27SDimitry Andric // Result is negative if Exact OR -LHS u>= RHS. 97406c3fb27SDimitry Andric if (Exact || (-LHS.getSignedMaxValue()).uge(RHS.getSignedMaxValue())) { 97506c3fb27SDimitry Andric APInt Denom = RHS.getSignedMinValue(); 97606c3fb27SDimitry Andric APInt Num = LHS.getSignedMinValue(); 97706c3fb27SDimitry Andric Res = Denom.isZero() ? Num : Num.sdiv(Denom); 97806c3fb27SDimitry Andric } 97906c3fb27SDimitry Andric } else if (LHS.isStrictlyPositive() && RHS.isNegative()) { 98006c3fb27SDimitry Andric // Result is negative if Exact OR LHS u>= -RHS. 98106c3fb27SDimitry Andric if (Exact || LHS.getSignedMinValue().uge(-RHS.getSignedMinValue())) { 98206c3fb27SDimitry Andric APInt Denom = RHS.getSignedMaxValue(); 98306c3fb27SDimitry Andric APInt Num = LHS.getSignedMaxValue(); 98406c3fb27SDimitry Andric Res = Num.sdiv(Denom); 98506c3fb27SDimitry Andric } 98606c3fb27SDimitry Andric } 98706c3fb27SDimitry Andric 98806c3fb27SDimitry Andric if (Res) { 98906c3fb27SDimitry Andric if (Res->isNonNegative()) { 99006c3fb27SDimitry Andric unsigned LeadZ = Res->countLeadingZeros(); 99106c3fb27SDimitry Andric Known.Zero.setHighBits(LeadZ); 99206c3fb27SDimitry Andric } else { 99306c3fb27SDimitry Andric unsigned LeadO = Res->countLeadingOnes(); 99406c3fb27SDimitry Andric Known.One.setHighBits(LeadO); 99506c3fb27SDimitry Andric } 99606c3fb27SDimitry Andric } 99706c3fb27SDimitry Andric 99806c3fb27SDimitry Andric Known = divComputeLowBit(Known, LHS, RHS, Exact); 99906c3fb27SDimitry Andric return Known; 100006c3fb27SDimitry Andric } 100106c3fb27SDimitry Andric 100206c3fb27SDimitry Andric KnownBits KnownBits::udiv(const KnownBits &LHS, const KnownBits &RHS, 100306c3fb27SDimitry Andric bool Exact) { 1004e8d8bef9SDimitry Andric unsigned BitWidth = LHS.getBitWidth(); 1005e8d8bef9SDimitry Andric KnownBits Known(BitWidth); 1006e8d8bef9SDimitry Andric 100706c3fb27SDimitry Andric if (LHS.isZero() || RHS.isZero()) { 100806c3fb27SDimitry Andric // Result is either known Zero or UB. Return Zero either way. 100906c3fb27SDimitry Andric // Checking this earlier saves us a lot of special cases later on. 101006c3fb27SDimitry Andric Known.setAllZero(); 101106c3fb27SDimitry Andric return Known; 101206c3fb27SDimitry Andric } 101306c3fb27SDimitry Andric 101406c3fb27SDimitry Andric // We can figure out the minimum number of upper zero bits by doing 101506c3fb27SDimitry Andric // MaxNumerator / MinDenominator. If the Numerator gets smaller or Denominator 101606c3fb27SDimitry Andric // gets larger, the number of upper zero bits increases. 101706c3fb27SDimitry Andric APInt MinDenom = RHS.getMinValue(); 101806c3fb27SDimitry Andric APInt MaxNum = LHS.getMaxValue(); 101906c3fb27SDimitry Andric APInt MaxRes = MinDenom.isZero() ? MaxNum : MaxNum.udiv(MinDenom); 102006c3fb27SDimitry Andric 102106c3fb27SDimitry Andric unsigned LeadZ = MaxRes.countLeadingZeros(); 102206c3fb27SDimitry Andric 102306c3fb27SDimitry Andric Known.Zero.setHighBits(LeadZ); 102406c3fb27SDimitry Andric Known = divComputeLowBit(Known, LHS, RHS, Exact); 102506c3fb27SDimitry Andric 102606c3fb27SDimitry Andric return Known; 102706c3fb27SDimitry Andric } 102806c3fb27SDimitry Andric 102906c3fb27SDimitry Andric KnownBits KnownBits::remGetLowBits(const KnownBits &LHS, const KnownBits &RHS) { 103006c3fb27SDimitry Andric unsigned BitWidth = LHS.getBitWidth(); 103106c3fb27SDimitry Andric if (!RHS.isZero() && RHS.Zero[0]) { 103206c3fb27SDimitry Andric // rem X, Y where Y[0:N] is zero will preserve X[0:N] in the result. 103306c3fb27SDimitry Andric unsigned RHSZeros = RHS.countMinTrailingZeros(); 103406c3fb27SDimitry Andric APInt Mask = APInt::getLowBitsSet(BitWidth, RHSZeros); 103506c3fb27SDimitry Andric APInt OnesMask = LHS.One & Mask; 103606c3fb27SDimitry Andric APInt ZerosMask = LHS.Zero & Mask; 103706c3fb27SDimitry Andric return KnownBits(ZerosMask, OnesMask); 103806c3fb27SDimitry Andric } 103906c3fb27SDimitry Andric return KnownBits(BitWidth); 104006c3fb27SDimitry Andric } 104106c3fb27SDimitry Andric 104206c3fb27SDimitry Andric KnownBits KnownBits::urem(const KnownBits &LHS, const KnownBits &RHS) { 104306c3fb27SDimitry Andric KnownBits Known = remGetLowBits(LHS, RHS); 1044e8d8bef9SDimitry Andric if (RHS.isConstant() && RHS.getConstant().isPowerOf2()) { 104506c3fb27SDimitry Andric // NB: Low bits set in `remGetLowBits`. 104606c3fb27SDimitry Andric APInt HighBits = ~(RHS.getConstant() - 1); 104706c3fb27SDimitry Andric Known.Zero |= HighBits; 1048e8d8bef9SDimitry Andric return Known; 1049e8d8bef9SDimitry Andric } 1050e8d8bef9SDimitry Andric 1051e8d8bef9SDimitry Andric // Since the result is less than or equal to either operand, any leading 1052e8d8bef9SDimitry Andric // zero bits in either operand must also exist in the result. 1053e8d8bef9SDimitry Andric uint32_t Leaders = 1054e8d8bef9SDimitry Andric std::max(LHS.countMinLeadingZeros(), RHS.countMinLeadingZeros()); 1055e8d8bef9SDimitry Andric Known.Zero.setHighBits(Leaders); 1056e8d8bef9SDimitry Andric return Known; 1057e8d8bef9SDimitry Andric } 1058e8d8bef9SDimitry Andric 1059e8d8bef9SDimitry Andric KnownBits KnownBits::srem(const KnownBits &LHS, const KnownBits &RHS) { 106006c3fb27SDimitry Andric KnownBits Known = remGetLowBits(LHS, RHS); 1061e8d8bef9SDimitry Andric if (RHS.isConstant() && RHS.getConstant().isPowerOf2()) { 106206c3fb27SDimitry Andric // NB: Low bits are set in `remGetLowBits`. 1063e8d8bef9SDimitry Andric APInt LowBits = RHS.getConstant() - 1; 1064e8d8bef9SDimitry Andric // If the first operand is non-negative or has all low bits zero, then 1065e8d8bef9SDimitry Andric // the upper bits are all zero. 1066e8d8bef9SDimitry Andric if (LHS.isNonNegative() || LowBits.isSubsetOf(LHS.Zero)) 1067e8d8bef9SDimitry Andric Known.Zero |= ~LowBits; 1068e8d8bef9SDimitry Andric 1069e8d8bef9SDimitry Andric // If the first operand is negative and not all low bits are zero, then 1070e8d8bef9SDimitry Andric // the upper bits are all one. 1071e8d8bef9SDimitry Andric if (LHS.isNegative() && LowBits.intersects(LHS.One)) 1072e8d8bef9SDimitry Andric Known.One |= ~LowBits; 1073e8d8bef9SDimitry Andric return Known; 1074e8d8bef9SDimitry Andric } 1075e8d8bef9SDimitry Andric 1076e8d8bef9SDimitry Andric // The sign bit is the LHS's sign bit, except when the result of the 1077fe6060f1SDimitry Andric // remainder is zero. The magnitude of the result should be less than or 1078fe6060f1SDimitry Andric // equal to the magnitude of the LHS. Therefore any leading zeros that exist 1079fe6060f1SDimitry Andric // in the left hand side must also exist in the result. 1080fe6060f1SDimitry Andric Known.Zero.setHighBits(LHS.countMinLeadingZeros()); 1081e8d8bef9SDimitry Andric return Known; 1082e8d8bef9SDimitry Andric } 1083e8d8bef9SDimitry Andric 10845ffd83dbSDimitry Andric KnownBits &KnownBits::operator&=(const KnownBits &RHS) { 10855ffd83dbSDimitry Andric // Result bit is 0 if either operand bit is 0. 10865ffd83dbSDimitry Andric Zero |= RHS.Zero; 10875ffd83dbSDimitry Andric // Result bit is 1 if both operand bits are 1. 10885ffd83dbSDimitry Andric One &= RHS.One; 10895ffd83dbSDimitry Andric return *this; 10905ffd83dbSDimitry Andric } 10915ffd83dbSDimitry Andric 10925ffd83dbSDimitry Andric KnownBits &KnownBits::operator|=(const KnownBits &RHS) { 10935ffd83dbSDimitry Andric // Result bit is 0 if both operand bits are 0. 10945ffd83dbSDimitry Andric Zero &= RHS.Zero; 10955ffd83dbSDimitry Andric // Result bit is 1 if either operand bit is 1. 10965ffd83dbSDimitry Andric One |= RHS.One; 10975ffd83dbSDimitry Andric return *this; 10985ffd83dbSDimitry Andric } 10995ffd83dbSDimitry Andric 11005ffd83dbSDimitry Andric KnownBits &KnownBits::operator^=(const KnownBits &RHS) { 11015ffd83dbSDimitry Andric // Result bit is 0 if both operand bits are 0 or both are 1. 11025ffd83dbSDimitry Andric APInt Z = (Zero & RHS.Zero) | (One & RHS.One); 11035ffd83dbSDimitry Andric // Result bit is 1 if one operand bit is 0 and the other is 1. 11045ffd83dbSDimitry Andric One = (Zero & RHS.One) | (One & RHS.Zero); 11055ffd83dbSDimitry Andric Zero = std::move(Z); 11065ffd83dbSDimitry Andric return *this; 11075ffd83dbSDimitry Andric } 1108fe6060f1SDimitry Andric 110906c3fb27SDimitry Andric KnownBits KnownBits::blsi() const { 111006c3fb27SDimitry Andric unsigned BitWidth = getBitWidth(); 111106c3fb27SDimitry Andric KnownBits Known(Zero, APInt(BitWidth, 0)); 111206c3fb27SDimitry Andric unsigned Max = countMaxTrailingZeros(); 111306c3fb27SDimitry Andric Known.Zero.setBitsFrom(std::min(Max + 1, BitWidth)); 111406c3fb27SDimitry Andric unsigned Min = countMinTrailingZeros(); 111506c3fb27SDimitry Andric if (Max == Min && Max < BitWidth) 111606c3fb27SDimitry Andric Known.One.setBit(Max); 111706c3fb27SDimitry Andric return Known; 111806c3fb27SDimitry Andric } 111906c3fb27SDimitry Andric 112006c3fb27SDimitry Andric KnownBits KnownBits::blsmsk() const { 112106c3fb27SDimitry Andric unsigned BitWidth = getBitWidth(); 112206c3fb27SDimitry Andric KnownBits Known(BitWidth); 112306c3fb27SDimitry Andric unsigned Max = countMaxTrailingZeros(); 112406c3fb27SDimitry Andric Known.Zero.setBitsFrom(std::min(Max + 1, BitWidth)); 112506c3fb27SDimitry Andric unsigned Min = countMinTrailingZeros(); 112606c3fb27SDimitry Andric Known.One.setLowBits(std::min(Min + 1, BitWidth)); 112706c3fb27SDimitry Andric return Known; 112806c3fb27SDimitry Andric } 112906c3fb27SDimitry Andric 1130fe6060f1SDimitry Andric void KnownBits::print(raw_ostream &OS) const { 113106c3fb27SDimitry Andric unsigned BitWidth = getBitWidth(); 113206c3fb27SDimitry Andric for (unsigned I = 0; I < BitWidth; ++I) { 113306c3fb27SDimitry Andric unsigned N = BitWidth - I - 1; 113406c3fb27SDimitry Andric if (Zero[N] && One[N]) 113506c3fb27SDimitry Andric OS << "!"; 113606c3fb27SDimitry Andric else if (Zero[N]) 113706c3fb27SDimitry Andric OS << "0"; 113806c3fb27SDimitry Andric else if (One[N]) 113906c3fb27SDimitry Andric OS << "1"; 114006c3fb27SDimitry Andric else 114106c3fb27SDimitry Andric OS << "?"; 114206c3fb27SDimitry Andric } 1143fe6060f1SDimitry Andric } 1144fe6060f1SDimitry Andric void KnownBits::dump() const { 1145fe6060f1SDimitry Andric print(dbgs()); 1146fe6060f1SDimitry Andric dbgs() << "\n"; 1147fe6060f1SDimitry Andric } 1148