Skip to content

Commit f0cbdd3

Browse files
authored
[KnownBitsTest] Print name of function when exhaustive tests fail (#89588)
When exhaustive unary/binary tests fail, print the name of the function being tested as well as the values of the inputs and outputs. Example of a simulated failure in testing "udiv exact": unittests/Support/KnownBitsTest.cpp:99: Failure Value of: checkResult(Name, Exact, Computed, {Known1, Known2}, CheckOptimality) Actual: false (udiv exact: Inputs = ???1, ????, Computed = ???1, Exact = 0???) Expected: true
1 parent c93f029 commit f0cbdd3

File tree

1 file changed

+68
-38
lines changed

1 file changed

+68
-38
lines changed

llvm/unittests/Support/KnownBitsTest.cpp

Lines changed: 68 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,11 @@
1010
//
1111
//===----------------------------------------------------------------------===//
1212

13-
#include "llvm/ADT/ArrayRef.h"
1413
#include "llvm/Support/KnownBits.h"
1514
#include "KnownBitsTest.h"
15+
#include "llvm/ADT/ArrayRef.h"
16+
#include "llvm/ADT/StringRef.h"
17+
#include "llvm/ADT/Twine.h"
1618
#include "gtest/gtest.h"
1719

1820
using namespace llvm;
@@ -25,7 +27,7 @@ using BinaryBitsFn =
2527
using BinaryIntFn =
2628
llvm::function_ref<std::optional<APInt>(const APInt &, const APInt &)>;
2729

28-
static testing::AssertionResult checkResult(const KnownBits &Exact,
30+
static testing::AssertionResult checkResult(Twine Name, const KnownBits &Exact,
2931
const KnownBits &Computed,
3032
ArrayRef<KnownBits> Inputs,
3133
bool CheckOptimality) {
@@ -41,14 +43,16 @@ static testing::AssertionResult checkResult(const KnownBits &Exact,
4143
}
4244

4345
testing::AssertionResult Result = testing::AssertionFailure();
46+
Result << Name << ": ";
4447
Result << "Inputs = ";
4548
for (const KnownBits &Input : Inputs)
4649
Result << Input << ", ";
4750
Result << "Computed = " << Computed << ", Exact = " << Exact;
4851
return Result;
4952
}
5053

51-
static void testUnaryOpExhaustive(UnaryBitsFn BitsFn, UnaryIntFn IntFn,
54+
static void testUnaryOpExhaustive(StringRef Name, UnaryBitsFn BitsFn,
55+
UnaryIntFn IntFn,
5256
bool CheckOptimality = true) {
5357
for (unsigned Bits : {1, 4}) {
5458
ForeachKnownBits(Bits, [&](const KnownBits &Known) {
@@ -65,12 +69,13 @@ static void testUnaryOpExhaustive(UnaryBitsFn BitsFn, UnaryIntFn IntFn,
6569
});
6670

6771
EXPECT_TRUE(!Computed.hasConflict());
68-
EXPECT_TRUE(checkResult(Exact, Computed, Known, CheckOptimality));
72+
EXPECT_TRUE(checkResult(Name, Exact, Computed, Known, CheckOptimality));
6973
});
7074
}
7175
}
7276

73-
static void testBinaryOpExhaustive(BinaryBitsFn BitsFn, BinaryIntFn IntFn,
77+
static void testBinaryOpExhaustive(StringRef Name, BinaryBitsFn BitsFn,
78+
BinaryIntFn IntFn,
7479
bool CheckOptimality = true,
7580
bool RefinePoisonToZero = false) {
7681
for (unsigned Bits : {1, 4}) {
@@ -91,8 +96,8 @@ static void testBinaryOpExhaustive(BinaryBitsFn BitsFn, BinaryIntFn IntFn,
9196
});
9297

9398
EXPECT_TRUE(!Computed.hasConflict());
94-
EXPECT_TRUE(
95-
checkResult(Exact, Computed, {Known1, Known2}, CheckOptimality));
99+
EXPECT_TRUE(checkResult(Name, Exact, Computed, {Known1, Known2},
100+
CheckOptimality));
96101
// In some cases we choose to return zero if the result is always
97102
// poison.
98103
if (RefinePoisonToZero && Exact.hasConflict()) {
@@ -137,6 +142,7 @@ TEST(KnownBitsTest, AddCarryExhaustive) {
137142
}
138143

139144
static void TestAddSubExhaustive(bool IsAdd) {
145+
Twine Name = IsAdd ? "add" : "sub";
140146
unsigned Bits = 4;
141147
ForeachKnownBits(Bits, [&](const KnownBits &Known1) {
142148
ForeachKnownBits(Bits, [&](const KnownBits &Known2) {
@@ -186,23 +192,26 @@ static void TestAddSubExhaustive(bool IsAdd) {
186192

187193
KnownBits KnownComputed = KnownBits::computeForAddSub(
188194
IsAdd, /*NSW=*/false, /*NUW=*/false, Known1, Known2);
189-
EXPECT_TRUE(checkResult(Known, KnownComputed, {Known1, Known2},
195+
EXPECT_TRUE(checkResult(Name, Known, KnownComputed, {Known1, Known2},
190196
/*CheckOptimality=*/true));
191197

192198
KnownBits KnownNSWComputed = KnownBits::computeForAddSub(
193199
IsAdd, /*NSW=*/true, /*NUW=*/false, Known1, Known2);
194-
EXPECT_TRUE(checkResult(KnownNSW, KnownNSWComputed, {Known1, Known2},
200+
EXPECT_TRUE(checkResult(Name + " nsw", KnownNSW, KnownNSWComputed,
201+
{Known1, Known2},
195202
/*CheckOptimality=*/true));
196203

197204
KnownBits KnownNUWComputed = KnownBits::computeForAddSub(
198205
IsAdd, /*NSW=*/false, /*NUW=*/true, Known1, Known2);
199-
EXPECT_TRUE(checkResult(KnownNUW, KnownNUWComputed, {Known1, Known2},
206+
EXPECT_TRUE(checkResult(Name + " nuw", KnownNUW, KnownNUWComputed,
207+
{Known1, Known2},
200208
/*CheckOptimality=*/true));
201209

202210
KnownBits KnownNSWAndNUWComputed = KnownBits::computeForAddSub(
203211
IsAdd, /*NSW=*/true, /*NUW=*/true, Known1, Known2);
204-
EXPECT_TRUE(checkResult(KnownNSWAndNUW, KnownNSWAndNUWComputed,
205-
{Known1, Known2}, /*CheckOptimality=*/true));
212+
EXPECT_TRUE(checkResult(Name + " nsw nuw", KnownNSWAndNUW,
213+
KnownNSWAndNUWComputed, {Known1, Known2},
214+
/*CheckOptimality=*/true));
206215
});
207216
});
208217
}
@@ -267,27 +276,31 @@ TEST(KnownBitsTest, SignBitUnknown) {
267276

268277
TEST(KnownBitsTest, BinaryExhaustive) {
269278
testBinaryOpExhaustive(
279+
"and",
270280
[](const KnownBits &Known1, const KnownBits &Known2) {
271281
return Known1 & Known2;
272282
},
273283
[](const APInt &N1, const APInt &N2) { return N1 & N2; });
274284
testBinaryOpExhaustive(
285+
"or",
275286
[](const KnownBits &Known1, const KnownBits &Known2) {
276287
return Known1 | Known2;
277288
},
278289
[](const APInt &N1, const APInt &N2) { return N1 | N2; });
279290
testBinaryOpExhaustive(
291+
"xor",
280292
[](const KnownBits &Known1, const KnownBits &Known2) {
281293
return Known1 ^ Known2;
282294
},
283295
[](const APInt &N1, const APInt &N2) { return N1 ^ N2; });
284-
testBinaryOpExhaustive(KnownBits::umax, APIntOps::umax);
285-
testBinaryOpExhaustive(KnownBits::umin, APIntOps::umin);
286-
testBinaryOpExhaustive(KnownBits::smax, APIntOps::smax);
287-
testBinaryOpExhaustive(KnownBits::smin, APIntOps::smin);
288-
testBinaryOpExhaustive(KnownBits::abdu, APIntOps::abdu);
289-
testBinaryOpExhaustive(KnownBits::abds, APIntOps::abds);
296+
testBinaryOpExhaustive("umax", KnownBits::umax, APIntOps::umax);
297+
testBinaryOpExhaustive("umin", KnownBits::umin, APIntOps::umin);
298+
testBinaryOpExhaustive("smax", KnownBits::smax, APIntOps::smax);
299+
testBinaryOpExhaustive("smin", KnownBits::smin, APIntOps::smin);
300+
testBinaryOpExhaustive("abdu", KnownBits::abdu, APIntOps::abdu);
301+
testBinaryOpExhaustive("abds", KnownBits::abds, APIntOps::abds);
290302
testBinaryOpExhaustive(
303+
"udiv",
291304
[](const KnownBits &Known1, const KnownBits &Known2) {
292305
return KnownBits::udiv(Known1, Known2);
293306
},
@@ -298,6 +311,7 @@ TEST(KnownBitsTest, BinaryExhaustive) {
298311
},
299312
/*CheckOptimality=*/false);
300313
testBinaryOpExhaustive(
314+
"udiv exact",
301315
[](const KnownBits &Known1, const KnownBits &Known2) {
302316
return KnownBits::udiv(Known1, Known2, /*Exact*/ true);
303317
},
@@ -308,6 +322,7 @@ TEST(KnownBitsTest, BinaryExhaustive) {
308322
},
309323
/*CheckOptimality=*/false);
310324
testBinaryOpExhaustive(
325+
"sdiv",
311326
[](const KnownBits &Known1, const KnownBits &Known2) {
312327
return KnownBits::sdiv(Known1, Known2);
313328
},
@@ -318,6 +333,7 @@ TEST(KnownBitsTest, BinaryExhaustive) {
318333
},
319334
/*CheckOptimality=*/false);
320335
testBinaryOpExhaustive(
336+
"sdiv exact",
321337
[](const KnownBits &Known1, const KnownBits &Known2) {
322338
return KnownBits::sdiv(Known1, Known2, /*Exact*/ true);
323339
},
@@ -329,46 +345,47 @@ TEST(KnownBitsTest, BinaryExhaustive) {
329345
},
330346
/*CheckOptimality=*/false);
331347
testBinaryOpExhaustive(
332-
KnownBits::urem,
348+
"urem", KnownBits::urem,
333349
[](const APInt &N1, const APInt &N2) -> std::optional<APInt> {
334350
if (N2.isZero())
335351
return std::nullopt;
336352
return N1.urem(N2);
337353
},
338354
/*CheckOptimality=*/false);
339355
testBinaryOpExhaustive(
340-
KnownBits::srem,
356+
"srem", KnownBits::srem,
341357
[](const APInt &N1, const APInt &N2) -> std::optional<APInt> {
342358
if (N2.isZero())
343359
return std::nullopt;
344360
return N1.srem(N2);
345361
},
346362
/*CheckOptimality=*/false);
347363
testBinaryOpExhaustive(
348-
KnownBits::sadd_sat,
364+
"sadd_sat", KnownBits::sadd_sat,
349365
[](const APInt &N1, const APInt &N2) -> std::optional<APInt> {
350366
return N1.sadd_sat(N2);
351367
},
352368
/*CheckOptimality=*/false);
353369
testBinaryOpExhaustive(
354-
KnownBits::uadd_sat,
370+
"uadd_sat", KnownBits::uadd_sat,
355371
[](const APInt &N1, const APInt &N2) -> std::optional<APInt> {
356372
return N1.uadd_sat(N2);
357373
},
358374
/*CheckOptimality=*/false);
359375
testBinaryOpExhaustive(
360-
KnownBits::ssub_sat,
376+
"ssub_sat", KnownBits::ssub_sat,
361377
[](const APInt &N1, const APInt &N2) -> std::optional<APInt> {
362378
return N1.ssub_sat(N2);
363379
},
364380
/*CheckOptimality=*/false);
365381
testBinaryOpExhaustive(
366-
KnownBits::usub_sat,
382+
"usub_sat", KnownBits::usub_sat,
367383
[](const APInt &N1, const APInt &N2) -> std::optional<APInt> {
368384
return N1.usub_sat(N2);
369385
},
370386
/*CheckOptimality=*/false);
371387
testBinaryOpExhaustive(
388+
"shl",
372389
[](const KnownBits &Known1, const KnownBits &Known2) {
373390
return KnownBits::shl(Known1, Known2);
374391
},
@@ -379,6 +396,7 @@ TEST(KnownBitsTest, BinaryExhaustive) {
379396
},
380397
/*CheckOptimality=*/true, /* RefinePoisonToZero */ true);
381398
testBinaryOpExhaustive(
399+
"ushl_ov",
382400
[](const KnownBits &Known1, const KnownBits &Known2) {
383401
return KnownBits::shl(Known1, Known2, /* NUW */ true);
384402
},
@@ -391,6 +409,7 @@ TEST(KnownBitsTest, BinaryExhaustive) {
391409
},
392410
/*CheckOptimality=*/true, /* RefinePoisonToZero */ true);
393411
testBinaryOpExhaustive(
412+
"shl nsw",
394413
[](const KnownBits &Known1, const KnownBits &Known2) {
395414
return KnownBits::shl(Known1, Known2, /* NUW */ false, /* NSW */ true);
396415
},
@@ -403,6 +422,7 @@ TEST(KnownBitsTest, BinaryExhaustive) {
403422
},
404423
/*CheckOptimality=*/true, /* RefinePoisonToZero */ true);
405424
testBinaryOpExhaustive(
425+
"shl nuw",
406426
[](const KnownBits &Known1, const KnownBits &Known2) {
407427
return KnownBits::shl(Known1, Known2, /* NUW */ true, /* NSW */ true);
408428
},
@@ -417,6 +437,7 @@ TEST(KnownBitsTest, BinaryExhaustive) {
417437
/*CheckOptimality=*/true, /* RefinePoisonToZero */ true);
418438

419439
testBinaryOpExhaustive(
440+
"lshr",
420441
[](const KnownBits &Known1, const KnownBits &Known2) {
421442
return KnownBits::lshr(Known1, Known2);
422443
},
@@ -427,6 +448,7 @@ TEST(KnownBitsTest, BinaryExhaustive) {
427448
},
428449
/*CheckOptimality=*/true, /* RefinePoisonToZero */ true);
429450
testBinaryOpExhaustive(
451+
"lshr exact",
430452
[](const KnownBits &Known1, const KnownBits &Known2) {
431453
return KnownBits::lshr(Known1, Known2, /*ShAmtNonZero=*/false,
432454
/*Exact=*/true);
@@ -440,6 +462,7 @@ TEST(KnownBitsTest, BinaryExhaustive) {
440462
},
441463
/*CheckOptimality=*/true, /* RefinePoisonToZero */ true);
442464
testBinaryOpExhaustive(
465+
"ashr",
443466
[](const KnownBits &Known1, const KnownBits &Known2) {
444467
return KnownBits::ashr(Known1, Known2);
445468
},
@@ -450,6 +473,7 @@ TEST(KnownBitsTest, BinaryExhaustive) {
450473
},
451474
/*CheckOptimality=*/true, /* RefinePoisonToZero */ true);
452475
testBinaryOpExhaustive(
476+
"ashr exact",
453477
[](const KnownBits &Known1, const KnownBits &Known2) {
454478
return KnownBits::ashr(Known1, Known2, /*ShAmtNonZero=*/false,
455479
/*Exact=*/true);
@@ -463,38 +487,44 @@ TEST(KnownBitsTest, BinaryExhaustive) {
463487
},
464488
/*CheckOptimality=*/true, /* RefinePoisonToZero */ true);
465489
testBinaryOpExhaustive(
490+
"mul",
466491
[](const KnownBits &Known1, const KnownBits &Known2) {
467492
return KnownBits::mul(Known1, Known2);
468493
},
469494
[](const APInt &N1, const APInt &N2) { return N1 * N2; },
470495
/*CheckOptimality=*/false);
471496
testBinaryOpExhaustive(
472-
KnownBits::mulhs,
497+
"mulhs", KnownBits::mulhs,
473498
[](const APInt &N1, const APInt &N2) { return APIntOps::mulhs(N1, N2); },
474499
/*CheckOptimality=*/false);
475500
testBinaryOpExhaustive(
476-
KnownBits::mulhu,
501+
"mulhu", KnownBits::mulhu,
477502
[](const APInt &N1, const APInt &N2) { return APIntOps::mulhu(N1, N2); },
478503
/*CheckOptimality=*/false);
479504
}
480505

481506
TEST(KnownBitsTest, UnaryExhaustive) {
482-
testUnaryOpExhaustive([](const KnownBits &Known) { return Known.abs(); },
483-
[](const APInt &N) { return N.abs(); });
507+
testUnaryOpExhaustive(
508+
"abs", [](const KnownBits &Known) { return Known.abs(); },
509+
[](const APInt &N) { return N.abs(); });
484510

485-
testUnaryOpExhaustive([](const KnownBits &Known) { return Known.abs(true); },
486-
[](const APInt &N) -> std::optional<APInt> {
487-
if (N.isMinSignedValue())
488-
return std::nullopt;
489-
return N.abs();
490-
});
511+
testUnaryOpExhaustive(
512+
"abs(true)", [](const KnownBits &Known) { return Known.abs(true); },
513+
[](const APInt &N) -> std::optional<APInt> {
514+
if (N.isMinSignedValue())
515+
return std::nullopt;
516+
return N.abs();
517+
});
491518

492-
testUnaryOpExhaustive([](const KnownBits &Known) { return Known.blsi(); },
493-
[](const APInt &N) { return N & -N; });
494-
testUnaryOpExhaustive([](const KnownBits &Known) { return Known.blsmsk(); },
495-
[](const APInt &N) { return N ^ (N - 1); });
519+
testUnaryOpExhaustive(
520+
"blsi", [](const KnownBits &Known) { return Known.blsi(); },
521+
[](const APInt &N) { return N & -N; });
522+
testUnaryOpExhaustive(
523+
"blsmsk", [](const KnownBits &Known) { return Known.blsmsk(); },
524+
[](const APInt &N) { return N ^ (N - 1); });
496525

497526
testUnaryOpExhaustive(
527+
"mul self",
498528
[](const KnownBits &Known) {
499529
return KnownBits::mul(Known, Known, /*SelfMultiply*/ true);
500530
},

0 commit comments

Comments
 (0)