@@ -150,26 +150,80 @@ static void EnumerateTwoInterestingConstantFPRanges(Fn TestFn,
150
150
151
151
template <typename Fn>
152
152
static void EnumerateValuesInConstantFPRange (const ConstantFPRange &CR,
153
- Fn TestFn) {
153
+ Fn TestFn, bool IgnoreNaNPayload ) {
154
154
const fltSemantics &Sem = CR.getSemantics ();
155
- unsigned Bits = APFloat::semanticsSizeInBits (Sem);
156
- assert (Bits < 32 && " Too many bits" );
157
- for (unsigned I = 0 , E = (1U << Bits) - 1 ; I != E; ++I) {
158
- APFloat V (Sem, APInt (Bits, I));
159
- if (CR.contains (V))
160
- TestFn (V);
155
+ if (IgnoreNaNPayload) {
156
+ if (CR.containsSNaN ()) {
157
+ TestFn (APFloat::getSNaN (Sem, false ));
158
+ TestFn (APFloat::getSNaN (Sem, true ));
159
+ }
160
+ if (CR.containsQNaN ()) {
161
+ TestFn (APFloat::getQNaN (Sem, false ));
162
+ TestFn (APFloat::getQNaN (Sem, true ));
163
+ }
164
+ if (CR.isNaNOnly ())
165
+ return ;
166
+ APFloat Lower = CR.getLower ();
167
+ const APFloat &Upper = CR.getUpper ();
168
+ auto Next = [&](APFloat &V) {
169
+ if (V.bitwiseIsEqual (Upper))
170
+ return false ;
171
+ strictNext (V);
172
+ return true ;
173
+ };
174
+ do
175
+ TestFn (Lower);
176
+ while (Next (Lower));
177
+ } else {
178
+ unsigned Bits = APFloat::semanticsSizeInBits (Sem);
179
+ assert (Bits < 32 && " Too many bits" );
180
+ for (unsigned I = 0 , E = (1U << Bits) - 1 ; I != E; ++I) {
181
+ APFloat V (Sem, APInt (Bits, I));
182
+ if (CR.contains (V))
183
+ TestFn (V);
184
+ }
161
185
}
162
186
}
163
187
164
188
template <typename Fn>
165
- static bool AnyOfValueInConstantFPRange (const ConstantFPRange &CR, Fn TestFn) {
189
+ static bool AnyOfValueInConstantFPRange (const ConstantFPRange &CR, Fn TestFn,
190
+ bool IgnoreNaNPayload) {
166
191
const fltSemantics &Sem = CR.getSemantics ();
167
- unsigned Bits = APFloat::semanticsSizeInBits (Sem);
168
- assert (Bits < 32 && " Too many bits" );
169
- for (unsigned I = 0 , E = (1U << Bits) - 1 ; I != E; ++I) {
170
- APFloat V (Sem, APInt (Bits, I));
171
- if (CR.contains (V) && TestFn (V))
192
+ if (IgnoreNaNPayload) {
193
+ if (CR.containsSNaN ()) {
194
+ if (TestFn (APFloat::getSNaN (Sem, false )))
195
+ return true ;
196
+ if (TestFn (APFloat::getSNaN (Sem, true )))
197
+ return true ;
198
+ }
199
+ if (CR.containsQNaN ()) {
200
+ if (TestFn (APFloat::getQNaN (Sem, false )))
201
+ return true ;
202
+ if (TestFn (APFloat::getQNaN (Sem, true )))
203
+ return true ;
204
+ }
205
+ if (CR.isNaNOnly ())
206
+ return false ;
207
+ APFloat Lower = CR.getLower ();
208
+ const APFloat &Upper = CR.getUpper ();
209
+ auto Next = [&](APFloat &V) {
210
+ if (V.bitwiseIsEqual (Upper))
211
+ return false ;
212
+ strictNext (V);
172
213
return true ;
214
+ };
215
+ do {
216
+ if (TestFn (Lower))
217
+ return true ;
218
+ } while (Next (Lower));
219
+ } else {
220
+ unsigned Bits = APFloat::semanticsSizeInBits (Sem);
221
+ assert (Bits < 32 && " Too many bits" );
222
+ for (unsigned I = 0 , E = (1U << Bits) - 1 ; I != E; ++I) {
223
+ APFloat V (Sem, APInt (Bits, I));
224
+ if (CR.contains (V) && TestFn (V))
225
+ return true ;
226
+ }
173
227
}
174
228
return false ;
175
229
}
@@ -385,13 +439,16 @@ TEST_F(ConstantFPRangeTest, FPClassify) {
385
439
[](const ConstantFPRange &CR) {
386
440
unsigned Mask = fcNone;
387
441
bool HasPos = false , HasNeg = false ;
388
- EnumerateValuesInConstantFPRange (CR, [&](const APFloat &V) {
389
- Mask |= V.classify ();
390
- if (V.isNegative ())
391
- HasNeg = true ;
392
- else
393
- HasPos = true ;
394
- });
442
+ EnumerateValuesInConstantFPRange (
443
+ CR,
444
+ [&](const APFloat &V) {
445
+ Mask |= V.classify ();
446
+ if (V.isNegative ())
447
+ HasNeg = true ;
448
+ else
449
+ HasPos = true ;
450
+ },
451
+ /* IgnoreNaNPayload=*/ true );
395
452
396
453
std::optional<bool > SignBit = std::nullopt;
397
454
if (HasPos != HasNeg)
@@ -453,11 +510,15 @@ TEST_F(ConstantFPRangeTest, makeAllowedFCmpRegion) {
453
510
EnumerateValuesInConstantFPRange (
454
511
ConstantFPRange::getFull (CR.getSemantics ()),
455
512
[&](const APFloat &V) {
456
- if (AnyOfValueInConstantFPRange (CR, [&](const APFloat &U) {
457
- return FCmpInst::compare (V, U, Pred);
458
- }))
513
+ if (AnyOfValueInConstantFPRange (
514
+ CR,
515
+ [&](const APFloat &U) {
516
+ return FCmpInst::compare (V, U, Pred);
517
+ },
518
+ /* IgnoreNaNPayload=*/ true ))
459
519
Optimal = Optimal.unionWith (ConstantFPRange (V));
460
- });
520
+ },
521
+ /* IgnoreNaNPayload=*/ true );
461
522
462
523
EXPECT_TRUE (Res.contains (Optimal))
463
524
<< " Wrong result for makeAllowedFCmpRegion(" << Pred << " , " << CR
0 commit comments