11
11
// ===----------------------------------------------------------------------===//
12
12
13
13
#include " llvm/ADT/ArrayRef.h"
14
+ #include " llvm/ADT/StringRef.h"
15
+ #include " llvm/ADT/Twine.h"
14
16
#include " llvm/Support/KnownBits.h"
15
17
#include " KnownBitsTest.h"
16
18
#include " gtest/gtest.h"
@@ -25,7 +27,8 @@ using BinaryBitsFn =
25
27
using BinaryIntFn =
26
28
llvm::function_ref<std::optional<APInt>(const APInt &, const APInt &)>;
27
29
28
- static testing::AssertionResult checkResult (const KnownBits &Exact,
30
+ static testing::AssertionResult checkResult (Twine Name,
31
+ const KnownBits &Exact,
29
32
const KnownBits &Computed,
30
33
ArrayRef<KnownBits> Inputs,
31
34
bool CheckOptimality) {
@@ -41,14 +44,15 @@ static testing::AssertionResult checkResult(const KnownBits &Exact,
41
44
}
42
45
43
46
testing::AssertionResult Result = testing::AssertionFailure ();
47
+ Result << Name << " : " ;
44
48
Result << " Inputs = " ;
45
49
for (const KnownBits &Input : Inputs)
46
50
Result << Input << " , " ;
47
51
Result << " Computed = " << Computed << " , Exact = " << Exact;
48
52
return Result;
49
53
}
50
54
51
- static void testUnaryOpExhaustive (UnaryBitsFn BitsFn, UnaryIntFn IntFn,
55
+ static void testUnaryOpExhaustive (StringRef Name, UnaryBitsFn BitsFn, UnaryIntFn IntFn,
52
56
bool CheckOptimality = true ) {
53
57
for (unsigned Bits : {1 , 4 }) {
54
58
ForeachKnownBits (Bits, [&](const KnownBits &Known) {
@@ -65,12 +69,12 @@ static void testUnaryOpExhaustive(UnaryBitsFn BitsFn, UnaryIntFn IntFn,
65
69
});
66
70
67
71
EXPECT_TRUE (!Computed.hasConflict ());
68
- EXPECT_TRUE (checkResult (Exact, Computed, Known, CheckOptimality));
72
+ EXPECT_TRUE (checkResult (Name, Exact, Computed, Known, CheckOptimality));
69
73
});
70
74
}
71
75
}
72
76
73
- static void testBinaryOpExhaustive (BinaryBitsFn BitsFn, BinaryIntFn IntFn,
77
+ static void testBinaryOpExhaustive (StringRef Name, BinaryBitsFn BitsFn, BinaryIntFn IntFn,
74
78
bool CheckOptimality = true ,
75
79
bool RefinePoisonToZero = false ) {
76
80
for (unsigned Bits : {1 , 4 }) {
@@ -92,7 +96,7 @@ static void testBinaryOpExhaustive(BinaryBitsFn BitsFn, BinaryIntFn IntFn,
92
96
93
97
EXPECT_TRUE (!Computed.hasConflict ());
94
98
EXPECT_TRUE (
95
- checkResult (Exact, Computed, {Known1, Known2}, CheckOptimality));
99
+ checkResult (Name, Exact, Computed, {Known1, Known2}, CheckOptimality));
96
100
// In some cases we choose to return zero if the result is always
97
101
// poison.
98
102
if (RefinePoisonToZero && Exact.hasConflict ()) {
@@ -137,6 +141,7 @@ TEST(KnownBitsTest, AddCarryExhaustive) {
137
141
}
138
142
139
143
static void TestAddSubExhaustive (bool IsAdd) {
144
+ Twine Name = IsAdd ? " add" : " sub" ;
140
145
unsigned Bits = 4 ;
141
146
ForeachKnownBits (Bits, [&](const KnownBits &Known1) {
142
147
ForeachKnownBits (Bits, [&](const KnownBits &Known2) {
@@ -186,22 +191,22 @@ static void TestAddSubExhaustive(bool IsAdd) {
186
191
187
192
KnownBits KnownComputed = KnownBits::computeForAddSub (
188
193
IsAdd, /* NSW=*/ false , /* NUW=*/ false , Known1, Known2);
189
- EXPECT_TRUE (checkResult (Known, KnownComputed, {Known1, Known2},
194
+ EXPECT_TRUE (checkResult (Name, Known, KnownComputed, {Known1, Known2},
190
195
/* CheckOptimality=*/ true ));
191
196
192
197
KnownBits KnownNSWComputed = KnownBits::computeForAddSub (
193
198
IsAdd, /* NSW=*/ true , /* NUW=*/ false , Known1, Known2);
194
- EXPECT_TRUE (checkResult (KnownNSW, KnownNSWComputed, {Known1, Known2},
199
+ EXPECT_TRUE (checkResult (Name + " nsw " , KnownNSW, KnownNSWComputed, {Known1, Known2},
195
200
/* CheckOptimality=*/ true ));
196
201
197
202
KnownBits KnownNUWComputed = KnownBits::computeForAddSub (
198
203
IsAdd, /* NSW=*/ false , /* NUW=*/ true , Known1, Known2);
199
- EXPECT_TRUE (checkResult (KnownNUW, KnownNUWComputed, {Known1, Known2},
204
+ EXPECT_TRUE (checkResult (Name + " nuw " , KnownNUW, KnownNUWComputed, {Known1, Known2},
200
205
/* CheckOptimality=*/ true ));
201
206
202
207
KnownBits KnownNSWAndNUWComputed = KnownBits::computeForAddSub (
203
208
IsAdd, /* NSW=*/ true , /* NUW=*/ true , Known1, Known2);
204
- EXPECT_TRUE (checkResult (KnownNSWAndNUW, KnownNSWAndNUWComputed,
209
+ EXPECT_TRUE (checkResult (Name + " nsw nuw " , KnownNSWAndNUW, KnownNSWAndNUWComputed,
205
210
{Known1, Known2}, /* CheckOptimality=*/ true ));
206
211
});
207
212
});
@@ -266,28 +271,28 @@ TEST(KnownBitsTest, SignBitUnknown) {
266
271
}
267
272
268
273
TEST (KnownBitsTest, BinaryExhaustive) {
269
- testBinaryOpExhaustive (
274
+ testBinaryOpExhaustive (" and " ,
270
275
[](const KnownBits &Known1, const KnownBits &Known2) {
271
276
return Known1 & Known2;
272
277
},
273
278
[](const APInt &N1, const APInt &N2) { return N1 & N2; });
274
- testBinaryOpExhaustive (
279
+ testBinaryOpExhaustive (" or " ,
275
280
[](const KnownBits &Known1, const KnownBits &Known2) {
276
281
return Known1 | Known2;
277
282
},
278
283
[](const APInt &N1, const APInt &N2) { return N1 | N2; });
279
- testBinaryOpExhaustive (
284
+ testBinaryOpExhaustive (" xor " ,
280
285
[](const KnownBits &Known1, const KnownBits &Known2) {
281
286
return Known1 ^ Known2;
282
287
},
283
288
[](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);
290
- testBinaryOpExhaustive (
289
+ testBinaryOpExhaustive (" umax " , KnownBits::umax, APIntOps::umax);
290
+ testBinaryOpExhaustive (" umin " , KnownBits::umin, APIntOps::umin);
291
+ testBinaryOpExhaustive (" smax " , KnownBits::smax, APIntOps::smax);
292
+ testBinaryOpExhaustive (" smin " , KnownBits::smin, APIntOps::smin);
293
+ testBinaryOpExhaustive (" abdu " , KnownBits::abdu, APIntOps::abdu);
294
+ testBinaryOpExhaustive (" abds " , KnownBits::abds, APIntOps::abds);
295
+ testBinaryOpExhaustive (" udiv " ,
291
296
[](const KnownBits &Known1, const KnownBits &Known2) {
292
297
return KnownBits::udiv (Known1, Known2);
293
298
},
@@ -297,7 +302,7 @@ TEST(KnownBitsTest, BinaryExhaustive) {
297
302
return N1.udiv (N2);
298
303
},
299
304
/* CheckOptimality=*/ false );
300
- testBinaryOpExhaustive (
305
+ testBinaryOpExhaustive (" udiv exact " ,
301
306
[](const KnownBits &Known1, const KnownBits &Known2) {
302
307
return KnownBits::udiv (Known1, Known2, /* Exact*/ true );
303
308
},
@@ -307,7 +312,7 @@ TEST(KnownBitsTest, BinaryExhaustive) {
307
312
return N1.udiv (N2);
308
313
},
309
314
/* CheckOptimality=*/ false );
310
- testBinaryOpExhaustive (
315
+ testBinaryOpExhaustive (" sdiv " ,
311
316
[](const KnownBits &Known1, const KnownBits &Known2) {
312
317
return KnownBits::sdiv (Known1, Known2);
313
318
},
@@ -317,7 +322,7 @@ TEST(KnownBitsTest, BinaryExhaustive) {
317
322
return N1.sdiv (N2);
318
323
},
319
324
/* CheckOptimality=*/ false );
320
- testBinaryOpExhaustive (
325
+ testBinaryOpExhaustive (" sdiv exact " ,
321
326
[](const KnownBits &Known1, const KnownBits &Known2) {
322
327
return KnownBits::sdiv (Known1, Known2, /* Exact*/ true );
323
328
},
@@ -328,47 +333,47 @@ TEST(KnownBitsTest, BinaryExhaustive) {
328
333
return N1.sdiv (N2);
329
334
},
330
335
/* CheckOptimality=*/ false );
331
- testBinaryOpExhaustive (
336
+ testBinaryOpExhaustive (" urem " ,
332
337
KnownBits::urem,
333
338
[](const APInt &N1, const APInt &N2) -> std::optional<APInt> {
334
339
if (N2.isZero ())
335
340
return std::nullopt;
336
341
return N1.urem (N2);
337
342
},
338
343
/* CheckOptimality=*/ false );
339
- testBinaryOpExhaustive (
344
+ testBinaryOpExhaustive (" srem " ,
340
345
KnownBits::srem,
341
346
[](const APInt &N1, const APInt &N2) -> std::optional<APInt> {
342
347
if (N2.isZero ())
343
348
return std::nullopt;
344
349
return N1.srem (N2);
345
350
},
346
351
/* CheckOptimality=*/ false );
347
- testBinaryOpExhaustive (
352
+ testBinaryOpExhaustive (" sadd_sat " ,
348
353
KnownBits::sadd_sat,
349
354
[](const APInt &N1, const APInt &N2) -> std::optional<APInt> {
350
355
return N1.sadd_sat (N2);
351
356
},
352
357
/* CheckOptimality=*/ false );
353
- testBinaryOpExhaustive (
358
+ testBinaryOpExhaustive (" uadd_sat " ,
354
359
KnownBits::uadd_sat,
355
360
[](const APInt &N1, const APInt &N2) -> std::optional<APInt> {
356
361
return N1.uadd_sat (N2);
357
362
},
358
363
/* CheckOptimality=*/ false );
359
- testBinaryOpExhaustive (
364
+ testBinaryOpExhaustive (" ssub_sat " ,
360
365
KnownBits::ssub_sat,
361
366
[](const APInt &N1, const APInt &N2) -> std::optional<APInt> {
362
367
return N1.ssub_sat (N2);
363
368
},
364
369
/* CheckOptimality=*/ false );
365
- testBinaryOpExhaustive (
370
+ testBinaryOpExhaustive (" usub_sat " ,
366
371
KnownBits::usub_sat,
367
372
[](const APInt &N1, const APInt &N2) -> std::optional<APInt> {
368
373
return N1.usub_sat (N2);
369
374
},
370
375
/* CheckOptimality=*/ false );
371
- testBinaryOpExhaustive (
376
+ testBinaryOpExhaustive (" shl " ,
372
377
[](const KnownBits &Known1, const KnownBits &Known2) {
373
378
return KnownBits::shl (Known1, Known2);
374
379
},
@@ -378,7 +383,7 @@ TEST(KnownBitsTest, BinaryExhaustive) {
378
383
return N1.shl (N2);
379
384
},
380
385
/* CheckOptimality=*/ true , /* RefinePoisonToZero */ true );
381
- testBinaryOpExhaustive (
386
+ testBinaryOpExhaustive (" ushl_ov " ,
382
387
[](const KnownBits &Known1, const KnownBits &Known2) {
383
388
return KnownBits::shl (Known1, Known2, /* NUW */ true );
384
389
},
@@ -390,7 +395,7 @@ TEST(KnownBitsTest, BinaryExhaustive) {
390
395
return Res;
391
396
},
392
397
/* CheckOptimality=*/ true , /* RefinePoisonToZero */ true );
393
- testBinaryOpExhaustive (
398
+ testBinaryOpExhaustive (" shl nsw " ,
394
399
[](const KnownBits &Known1, const KnownBits &Known2) {
395
400
return KnownBits::shl (Known1, Known2, /* NUW */ false , /* NSW */ true );
396
401
},
@@ -402,7 +407,7 @@ TEST(KnownBitsTest, BinaryExhaustive) {
402
407
return Res;
403
408
},
404
409
/* CheckOptimality=*/ true , /* RefinePoisonToZero */ true );
405
- testBinaryOpExhaustive (
410
+ testBinaryOpExhaustive (" shl nuw " ,
406
411
[](const KnownBits &Known1, const KnownBits &Known2) {
407
412
return KnownBits::shl (Known1, Known2, /* NUW */ true , /* NSW */ true );
408
413
},
@@ -416,7 +421,7 @@ TEST(KnownBitsTest, BinaryExhaustive) {
416
421
},
417
422
/* CheckOptimality=*/ true , /* RefinePoisonToZero */ true );
418
423
419
- testBinaryOpExhaustive (
424
+ testBinaryOpExhaustive (" lshr " ,
420
425
[](const KnownBits &Known1, const KnownBits &Known2) {
421
426
return KnownBits::lshr (Known1, Known2);
422
427
},
@@ -426,7 +431,7 @@ TEST(KnownBitsTest, BinaryExhaustive) {
426
431
return N1.lshr (N2);
427
432
},
428
433
/* CheckOptimality=*/ true , /* RefinePoisonToZero */ true );
429
- testBinaryOpExhaustive (
434
+ testBinaryOpExhaustive (" lshr exact " ,
430
435
[](const KnownBits &Known1, const KnownBits &Known2) {
431
436
return KnownBits::lshr (Known1, Known2, /* ShAmtNonZero=*/ false ,
432
437
/* Exact=*/ true );
@@ -439,7 +444,7 @@ TEST(KnownBitsTest, BinaryExhaustive) {
439
444
return N1.lshr (N2);
440
445
},
441
446
/* CheckOptimality=*/ true , /* RefinePoisonToZero */ true );
442
- testBinaryOpExhaustive (
447
+ testBinaryOpExhaustive (" ashr " ,
443
448
[](const KnownBits &Known1, const KnownBits &Known2) {
444
449
return KnownBits::ashr (Known1, Known2);
445
450
},
@@ -449,7 +454,7 @@ TEST(KnownBitsTest, BinaryExhaustive) {
449
454
return N1.ashr (N2);
450
455
},
451
456
/* CheckOptimality=*/ true , /* RefinePoisonToZero */ true );
452
- testBinaryOpExhaustive (
457
+ testBinaryOpExhaustive (" ashr exact " ,
453
458
[](const KnownBits &Known1, const KnownBits &Known2) {
454
459
return KnownBits::ashr (Known1, Known2, /* ShAmtNonZero=*/ false ,
455
460
/* Exact=*/ true );
@@ -462,39 +467,39 @@ TEST(KnownBitsTest, BinaryExhaustive) {
462
467
return N1.ashr (N2);
463
468
},
464
469
/* CheckOptimality=*/ true , /* RefinePoisonToZero */ true );
465
- testBinaryOpExhaustive (
470
+ testBinaryOpExhaustive (" mul " ,
466
471
[](const KnownBits &Known1, const KnownBits &Known2) {
467
472
return KnownBits::mul (Known1, Known2);
468
473
},
469
474
[](const APInt &N1, const APInt &N2) { return N1 * N2; },
470
475
/* CheckOptimality=*/ false );
471
- testBinaryOpExhaustive (
476
+ testBinaryOpExhaustive (" mulhs " ,
472
477
KnownBits::mulhs,
473
478
[](const APInt &N1, const APInt &N2) { return APIntOps::mulhs (N1, N2); },
474
479
/* CheckOptimality=*/ false );
475
- testBinaryOpExhaustive (
480
+ testBinaryOpExhaustive (" mulhu " ,
476
481
KnownBits::mulhu,
477
482
[](const APInt &N1, const APInt &N2) { return APIntOps::mulhu (N1, N2); },
478
483
/* CheckOptimality=*/ false );
479
484
}
480
485
481
486
TEST (KnownBitsTest, UnaryExhaustive) {
482
- testUnaryOpExhaustive ([](const KnownBits &Known) { return Known.abs (); },
487
+ testUnaryOpExhaustive (" abs " , [](const KnownBits &Known) { return Known.abs (); },
483
488
[](const APInt &N) { return N.abs (); });
484
489
485
- testUnaryOpExhaustive ([](const KnownBits &Known) { return Known.abs (true ); },
490
+ testUnaryOpExhaustive (" abs(true) " , [](const KnownBits &Known) { return Known.abs (true ); },
486
491
[](const APInt &N) -> std::optional<APInt> {
487
492
if (N.isMinSignedValue ())
488
493
return std::nullopt;
489
494
return N.abs ();
490
495
});
491
496
492
- testUnaryOpExhaustive ([](const KnownBits &Known) { return Known.blsi (); },
497
+ testUnaryOpExhaustive (" blsi " , [](const KnownBits &Known) { return Known.blsi (); },
493
498
[](const APInt &N) { return N & -N; });
494
- testUnaryOpExhaustive ([](const KnownBits &Known) { return Known.blsmsk (); },
499
+ testUnaryOpExhaustive (" blsmsk " , [](const KnownBits &Known) { return Known.blsmsk (); },
495
500
[](const APInt &N) { return N ^ (N - 1 ); });
496
501
497
- testUnaryOpExhaustive (
502
+ testUnaryOpExhaustive (" mul self " ,
498
503
[](const KnownBits &Known) {
499
504
return KnownBits::mul (Known, Known, /* SelfMultiply*/ true );
500
505
},
0 commit comments