Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions llvm/include/llvm/Support/KnownBits.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@ struct KnownBits {
KnownBits(APInt Zero, APInt One)
: Zero(std::move(Zero)), One(std::move(One)) {}

// Flip the range of values: [-0x80000000, 0x7FFFFFFF] <-> [0, 0xFFFFFFFF]
static KnownBits flipSignBit(const KnownBits &Val);

public:
// Default construct Zero and One.
KnownBits() = default;
Expand Down
39 changes: 17 additions & 22 deletions llvm/lib/Support/KnownBits.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,15 @@

using namespace llvm;

KnownBits KnownBits::flipSignBit(const KnownBits &Val) {
unsigned SignBitPosition = Val.getBitWidth() - 1;
APInt Zero = Val.Zero;
APInt One = Val.One;
Zero.setBitVal(SignBitPosition, Val.One[SignBitPosition]);
One.setBitVal(SignBitPosition, Val.Zero[SignBitPosition]);
return KnownBits(Zero, One);
}

static KnownBits computeForAddCarry(const KnownBits &LHS, const KnownBits &RHS,
bool CarryZero, bool CarryOne) {

Expand Down Expand Up @@ -200,16 +209,7 @@ KnownBits KnownBits::umin(const KnownBits &LHS, const KnownBits &RHS) {
}

KnownBits KnownBits::smax(const KnownBits &LHS, const KnownBits &RHS) {
// Flip the range of values: [-0x80000000, 0x7FFFFFFF] <-> [0, 0xFFFFFFFF]
auto Flip = [](const KnownBits &Val) {
unsigned SignBitPosition = Val.getBitWidth() - 1;
APInt Zero = Val.Zero;
APInt One = Val.One;
Zero.setBitVal(SignBitPosition, Val.One[SignBitPosition]);
One.setBitVal(SignBitPosition, Val.Zero[SignBitPosition]);
return KnownBits(Zero, One);
};
return Flip(umax(Flip(LHS), Flip(RHS)));
return flipSignBit(umax(flipSignBit(LHS), flipSignBit(RHS)));
}

KnownBits KnownBits::smin(const KnownBits &LHS, const KnownBits &RHS) {
Expand Down Expand Up @@ -763,35 +763,30 @@ KnownBits KnownBits::usub_sat(const KnownBits &LHS, const KnownBits &RHS) {
return computeForSatAddSub(/*Add*/ false, /*Signed*/ false, LHS, RHS);
}

static KnownBits avgCompute(KnownBits LHS, KnownBits RHS, bool IsCeil,
bool IsSigned) {
static KnownBits avgComputeU(KnownBits LHS, KnownBits RHS, bool IsCeil) {
unsigned BitWidth = LHS.getBitWidth();
LHS = IsSigned ? LHS.sext(BitWidth + 1) : LHS.zext(BitWidth + 1);
RHS = IsSigned ? RHS.sext(BitWidth + 1) : RHS.zext(BitWidth + 1);
LHS = LHS.zext(BitWidth + 1);
RHS = RHS.zext(BitWidth + 1);
LHS =
computeForAddCarry(LHS, RHS, /*CarryZero*/ !IsCeil, /*CarryOne*/ IsCeil);
LHS = LHS.extractBits(BitWidth, 1);
return LHS;
}

KnownBits KnownBits::avgFloorS(const KnownBits &LHS, const KnownBits &RHS) {
return avgCompute(LHS, RHS, /* IsCeil */ false,
/* IsSigned */ true);
return flipSignBit(avgFloorU(flipSignBit(LHS), flipSignBit(RHS)));
}

KnownBits KnownBits::avgFloorU(const KnownBits &LHS, const KnownBits &RHS) {
return avgCompute(LHS, RHS, /* IsCeil */ false,
/* IsSigned */ false);
return avgComputeU(LHS, RHS, /* IsCeil */ false);
}

KnownBits KnownBits::avgCeilS(const KnownBits &LHS, const KnownBits &RHS) {
return avgCompute(LHS, RHS, /* IsCeil */ true,
/* IsSigned */ true);
return flipSignBit(avgCeilU(flipSignBit(LHS), flipSignBit(RHS)));
}

KnownBits KnownBits::avgCeilU(const KnownBits &LHS, const KnownBits &RHS) {
return avgCompute(LHS, RHS, /* IsCeil */ true,
/* IsSigned */ false);
return avgComputeU(LHS, RHS, /* IsCeil */ true);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit, /*IsCeil=*/ for the comments.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

}

KnownBits KnownBits::mul(const KnownBits &LHS, const KnownBits &RHS,
Expand Down
7 changes: 3 additions & 4 deletions llvm/unittests/Support/KnownBitsTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -521,16 +521,15 @@ TEST(KnownBitsTest, BinaryExhaustive) {
[](const APInt &N1, const APInt &N2) { return APIntOps::mulhu(N1, N2); },
/*CheckOptimality=*/false);

testBinaryOpExhaustive("avgFloorS", KnownBits::avgFloorS, APIntOps::avgFloorS,
/*CheckOptimality=*/false);
testBinaryOpExhaustive("avgFloorS", KnownBits::avgFloorS,
APIntOps::avgFloorS);

testBinaryOpExhaustive("avgFloorU", KnownBits::avgFloorU,
APIntOps::avgFloorU);

testBinaryOpExhaustive("avgCeilU", KnownBits::avgCeilU, APIntOps::avgCeilU);

testBinaryOpExhaustive("avgCeilS", KnownBits::avgCeilS, APIntOps::avgCeilS,
/*CheckOptimality=*/false);
testBinaryOpExhaustive("avgCeilS", KnownBits::avgCeilS, APIntOps::avgCeilS);
}

TEST(KnownBitsTest, UnaryExhaustive) {
Expand Down
Loading