Skip to content
Merged
Changes from all 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
41 changes: 24 additions & 17 deletions llvm/unittests/Support/KnownBitsTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,8 @@ static void testUnaryOpExhaustive(StringRef Name, UnaryBitsFn BitsFn,

static void testBinaryOpExhaustive(StringRef Name, BinaryBitsFn BitsFn,
BinaryIntFn IntFn,
bool CheckOptimality = true) {
bool CheckOptimality = true,
bool RefinePoisonToZero = false) {
for (unsigned Bits : {1, 4}) {
ForeachKnownBits(Bits, [&](const KnownBits &Known1) {
ForeachKnownBits(Bits, [&](const KnownBits &Known2) {
Expand All @@ -99,6 +100,12 @@ static void testBinaryOpExhaustive(StringRef Name, BinaryBitsFn BitsFn,
EXPECT_TRUE(checkResult(Name, Exact, Computed, {Known1, Known2},
CheckOptimality));
}
// In some cases we choose to return zero if the result is always
// poison.
if (RefinePoisonToZero && Exact.hasConflict() &&
!Known1.hasConflict() && !Known2.hasConflict()) {
EXPECT_TRUE(Computed.isZero());
}
});
});
}
Expand Down Expand Up @@ -313,7 +320,7 @@ TEST(KnownBitsTest, BinaryExhaustive) {
testBinaryOpExhaustive(
"udiv exact",
[](const KnownBits &Known1, const KnownBits &Known2) {
return KnownBits::udiv(Known1, Known2, /*Exact*/ true);
return KnownBits::udiv(Known1, Known2, /*Exact=*/true);
},
[](const APInt &N1, const APInt &N2) -> std::optional<APInt> {
if (N2.isZero() || !N1.urem(N2).isZero())
Expand All @@ -335,7 +342,7 @@ TEST(KnownBitsTest, BinaryExhaustive) {
testBinaryOpExhaustive(
"sdiv exact",
[](const KnownBits &Known1, const KnownBits &Known2) {
return KnownBits::sdiv(Known1, Known2, /*Exact*/ true);
return KnownBits::sdiv(Known1, Known2, /*Exact=*/true);
},
[](const APInt &N1, const APInt &N2) -> std::optional<APInt> {
if (N2.isZero() || (N1.isMinSignedValue() && N2.isAllOnes()) ||
Expand Down Expand Up @@ -394,11 +401,11 @@ TEST(KnownBitsTest, BinaryExhaustive) {
return std::nullopt;
return N1.shl(N2);
},
/*CheckOptimality=*/true);
/*CheckOptimality=*/true, /*RefinePoisonToZero=*/true);
testBinaryOpExhaustive(
"ushl_ov",
[](const KnownBits &Known1, const KnownBits &Known2) {
return KnownBits::shl(Known1, Known2, /* NUW */ true);
return KnownBits::shl(Known1, Known2, /*NUW=*/true);
},
[](const APInt &N1, const APInt &N2) -> std::optional<APInt> {
bool Overflow;
Expand All @@ -407,11 +414,11 @@ TEST(KnownBitsTest, BinaryExhaustive) {
return std::nullopt;
return Res;
},
/*CheckOptimality=*/true);
/*CheckOptimality=*/true, /*RefinePoisonToZero=*/true);
testBinaryOpExhaustive(
"shl nsw",
[](const KnownBits &Known1, const KnownBits &Known2) {
return KnownBits::shl(Known1, Known2, /* NUW */ false, /* NSW */ true);
return KnownBits::shl(Known1, Known2, /*NUW=*/false, /*NSW=*/true);
},
[](const APInt &N1, const APInt &N2) -> std::optional<APInt> {
bool Overflow;
Expand All @@ -420,11 +427,11 @@ TEST(KnownBitsTest, BinaryExhaustive) {
return std::nullopt;
return Res;
},
/*CheckOptimality=*/true);
/*CheckOptimality=*/true, /*RefinePoisonToZero=*/true);
testBinaryOpExhaustive(
"shl nuw",
[](const KnownBits &Known1, const KnownBits &Known2) {
return KnownBits::shl(Known1, Known2, /* NUW */ true, /* NSW */ true);
return KnownBits::shl(Known1, Known2, /*NUW=*/true, /*NSW=*/true);
},
[](const APInt &N1, const APInt &N2) -> std::optional<APInt> {
bool OverflowUnsigned, OverflowSigned;
Expand All @@ -434,7 +441,7 @@ TEST(KnownBitsTest, BinaryExhaustive) {
return std::nullopt;
return Res;
},
/*CheckOptimality=*/true);
/*CheckOptimality=*/true, /*RefinePoisonToZero=*/true);

testBinaryOpExhaustive(
"lshr",
Expand All @@ -446,7 +453,7 @@ TEST(KnownBitsTest, BinaryExhaustive) {
return std::nullopt;
return N1.lshr(N2);
},
/*CheckOptimality=*/true);
/*CheckOptimality=*/true, /*RefinePoisonToZero=*/true);
testBinaryOpExhaustive(
"lshr exact",
[](const KnownBits &Known1, const KnownBits &Known2) {
Expand All @@ -460,7 +467,7 @@ TEST(KnownBitsTest, BinaryExhaustive) {
return std::nullopt;
return N1.lshr(N2);
},
/*CheckOptimality=*/true);
/*CheckOptimality=*/true, /*RefinePoisonToZero=*/true);
testBinaryOpExhaustive(
"ashr",
[](const KnownBits &Known1, const KnownBits &Known2) {
Expand All @@ -471,7 +478,7 @@ TEST(KnownBitsTest, BinaryExhaustive) {
return std::nullopt;
return N1.ashr(N2);
},
/*CheckOptimality=*/true);
/*CheckOptimality=*/true, /*RefinePoisonToZero=*/true);
testBinaryOpExhaustive(
"ashr exact",
[](const KnownBits &Known1, const KnownBits &Known2) {
Expand All @@ -485,7 +492,7 @@ TEST(KnownBitsTest, BinaryExhaustive) {
return std::nullopt;
return N1.ashr(N2);
},
/*CheckOptimality=*/true);
/*CheckOptimality=*/true, /*RefinePoisonToZero=*/true);
testBinaryOpExhaustive(
"mul",
[](const KnownBits &Known1, const KnownBits &Known2) {
Expand Down Expand Up @@ -538,7 +545,7 @@ TEST(KnownBitsTest, UnaryExhaustive) {
testUnaryOpExhaustive(
"mul self",
[](const KnownBits &Known) {
return KnownBits::mul(Known, Known, /*SelfMultiply*/ true);
return KnownBits::mul(Known, Known, /*SelfMultiply=*/true);
},
[](const APInt &N) { return N * N; }, /*CheckOptimality=*/false);
}
Expand Down Expand Up @@ -709,8 +716,8 @@ TEST(KnownBitsTest, SExtOrTrunc) {
const unsigned NarrowerSize = 4;
const unsigned BaseSize = 6;
const unsigned WiderSize = 8;
APInt NegativeFitsNarrower(BaseSize, -4, /*isSigned*/ true);
APInt NegativeDoesntFitNarrower(BaseSize, -28, /*isSigned*/ true);
APInt NegativeFitsNarrower(BaseSize, -4, /*isSigned=*/true);
APInt NegativeDoesntFitNarrower(BaseSize, -28, /*isSigned=*/true);
APInt PositiveFitsNarrower(BaseSize, 14);
APInt PositiveDoesntFitNarrower(BaseSize, 36);
auto InitKnownBits = [&](KnownBits &Res, const APInt &Input) {
Expand Down