@@ -84,13 +84,36 @@ static void strictNext(APFloat &V) {
84
84
}
85
85
86
86
template <typename Fn>
87
- static void EnumerateConstantFPRangesImpl (Fn TestFn, bool MayBeQNaN ,
88
- bool MayBeSNaN) {
87
+ static void EnumerateConstantFPRangesImpl (Fn TestFn, bool Exhaustive ,
88
+ bool MayBeQNaN, bool MayBeSNaN) {
89
89
const fltSemantics &Sem = APFloat::Float8E4M3 ();
90
90
APFloat PosInf = APFloat::getInf (Sem, /* Negative=*/ false );
91
91
APFloat NegInf = APFloat::getInf (Sem, /* Negative=*/ true );
92
92
TestFn (ConstantFPRange (PosInf, NegInf, MayBeQNaN, MayBeSNaN));
93
93
94
+ if (!Exhaustive) {
95
+ SmallVector<APFloat, 36 > Values;
96
+ Values.push_back (APFloat::getInf (Sem, /* Negative=*/ true ));
97
+ Values.push_back (APFloat::getLargest (Sem, /* Negative=*/ true ));
98
+ unsigned BitWidth = APFloat::semanticsSizeInBits (Sem);
99
+ unsigned Exponents = APFloat::semanticsMaxExponent (Sem) -
100
+ APFloat::semanticsMinExponent (Sem) + 3 ;
101
+ unsigned MantissaBits = APFloat::semanticsPrecision (Sem) - 1 ;
102
+ // Add -2^(max exponent), -2^(max exponent-1), ..., -2^(min exponent)
103
+ for (unsigned M = Exponents - 2 ; M != 0 ; --M)
104
+ Values.push_back (
105
+ APFloat (Sem, APInt (BitWidth, (M + Exponents) << MantissaBits)));
106
+ Values.push_back (APFloat::getSmallest (Sem, /* Negative=*/ true ));
107
+ Values.push_back (APFloat::getZero (Sem, /* Negative=*/ true ));
108
+ size_t E = Values.size ();
109
+ for (size_t I = 1 ; I <= E; ++I)
110
+ Values.push_back (-Values[E - I]);
111
+ for (size_t I = 0 ; I != Values.size (); ++I)
112
+ for (size_t J = I; J != Values.size (); ++J)
113
+ TestFn (ConstantFPRange (Values[I], Values[J], MayBeQNaN, MayBeSNaN));
114
+ return ;
115
+ }
116
+
94
117
auto Next = [&](APFloat &V) {
95
118
if (V.isPosInfinity ())
96
119
return false ;
@@ -107,22 +130,27 @@ static void EnumerateConstantFPRangesImpl(Fn TestFn, bool MayBeQNaN,
107
130
} while (Next (Lower));
108
131
}
109
132
110
- template <typename Fn> static void EnumerateConstantFPRanges (Fn TestFn) {
111
- EnumerateConstantFPRangesImpl (TestFn, /* MayBeQNaN=*/ false ,
133
+ template <typename Fn>
134
+ static void EnumerateConstantFPRanges (Fn TestFn, bool Exhaustive) {
135
+ EnumerateConstantFPRangesImpl (TestFn, Exhaustive, /* MayBeQNaN=*/ false ,
112
136
/* MayBeSNaN=*/ false );
113
- EnumerateConstantFPRangesImpl (TestFn, /* MayBeQNaN=*/ false ,
137
+ EnumerateConstantFPRangesImpl (TestFn, Exhaustive, /* MayBeQNaN=*/ false ,
114
138
/* MayBeSNaN=*/ true );
115
- EnumerateConstantFPRangesImpl (TestFn, /* MayBeQNaN=*/ true ,
139
+ EnumerateConstantFPRangesImpl (TestFn, Exhaustive, /* MayBeQNaN=*/ true ,
116
140
/* MayBeSNaN=*/ false );
117
- EnumerateConstantFPRangesImpl (TestFn, /* MayBeQNaN=*/ true , /* MayBeSNaN=*/ true );
141
+ EnumerateConstantFPRangesImpl (TestFn, Exhaustive, /* MayBeQNaN=*/ true ,
142
+ /* MayBeSNaN=*/ true );
118
143
}
119
144
120
145
template <typename Fn>
121
- static void EnumerateTwoInterestingConstantFPRanges (Fn TestFn) {
122
- EnumerateConstantFPRanges ([&](const ConstantFPRange &CR1) {
123
- EnumerateConstantFPRanges (
124
- [&](const ConstantFPRange &CR2) { TestFn (CR1, CR2); });
125
- });
146
+ static void EnumerateTwoInterestingConstantFPRanges (Fn TestFn,
147
+ bool Exhaustive) {
148
+ EnumerateConstantFPRanges (
149
+ [&](const ConstantFPRange &CR1) {
150
+ EnumerateConstantFPRanges (
151
+ [&](const ConstantFPRange &CR2) { TestFn (CR1, CR2); }, Exhaustive);
152
+ },
153
+ Exhaustive);
126
154
}
127
155
128
156
template <typename Fn>
@@ -248,11 +276,21 @@ TEST_F(ConstantFPRangeTest, SingleElement) {
248
276
EXPECT_FALSE (Zero.isSingleElement ());
249
277
}
250
278
251
- TEST_F (ConstantFPRangeTest, Enumerate ) {
279
+ TEST_F (ConstantFPRangeTest, ExhaustivelyEnumerate ) {
252
280
constexpr unsigned NNaNValues = (1 << 8 ) - 2 * ((1 << 3 ) - 1 );
253
281
constexpr unsigned Expected = 4 * ((NNaNValues + 1 ) * NNaNValues / 2 + 1 );
254
282
unsigned Count = 0 ;
255
- EnumerateConstantFPRanges ([&](const ConstantFPRange &) { ++Count; });
283
+ EnumerateConstantFPRanges ([&](const ConstantFPRange &) { ++Count; },
284
+ /* Exhaustive=*/ true );
285
+ EXPECT_EQ (Expected, Count);
286
+ }
287
+
288
+ TEST_F (ConstantFPRangeTest, Enumerate) {
289
+ constexpr unsigned NNaNValues = 2 * ((1 << 4 ) - 2 + 4 );
290
+ constexpr unsigned Expected = 4 * ((NNaNValues + 1 ) * NNaNValues / 2 + 1 );
291
+ unsigned Count = 0 ;
292
+ EnumerateConstantFPRanges ([&](const ConstantFPRange &) { ++Count; },
293
+ /* Exhaustive=*/ false );
256
294
EXPECT_EQ (Expected, Count);
257
295
}
258
296
@@ -334,24 +372,26 @@ TEST_F(ConstantFPRangeTest, FPClassify) {
334
372
EXPECT_EQ (SomePos.toKnownFPClass ().SignBit , false );
335
373
EXPECT_EQ (SomeNeg.toKnownFPClass ().SignBit , true );
336
374
337
- EnumerateConstantFPRanges ([](const ConstantFPRange &CR) {
338
- unsigned Mask = fcNone;
339
- bool HasPos = false , HasNeg = false ;
340
- EnumerateValuesInConstantFPRange (CR, [&](const APFloat &V) {
341
- Mask |= V.classify ();
342
- if (V.isNegative ())
343
- HasNeg = true ;
344
- else
345
- HasPos = true ;
346
- });
347
-
348
- std::optional<bool > SignBit = std::nullopt;
349
- if (HasPos != HasNeg)
350
- SignBit = HasNeg;
351
-
352
- EXPECT_EQ (SignBit, CR.getSignBit ()) << CR;
353
- EXPECT_EQ (Mask, CR.classify ()) << CR;
354
- });
375
+ EnumerateConstantFPRanges (
376
+ [](const ConstantFPRange &CR) {
377
+ unsigned Mask = fcNone;
378
+ bool HasPos = false , HasNeg = false ;
379
+ EnumerateValuesInConstantFPRange (CR, [&](const APFloat &V) {
380
+ Mask |= V.classify ();
381
+ if (V.isNegative ())
382
+ HasNeg = true ;
383
+ else
384
+ HasPos = true ;
385
+ });
386
+
387
+ std::optional<bool > SignBit = std::nullopt;
388
+ if (HasPos != HasNeg)
389
+ SignBit = HasNeg;
390
+
391
+ EXPECT_EQ (SignBit, CR.getSignBit ()) << CR;
392
+ EXPECT_EQ (Mask, CR.classify ()) << CR;
393
+ },
394
+ /* Exhaustive=*/ true );
355
395
}
356
396
357
397
TEST_F (ConstantFPRangeTest, Print) {
0 commit comments