@@ -34,6 +34,7 @@ class DominatorTree;
34
34
class GEPOperator ;
35
35
class WithOverflowInst ;
36
36
struct KnownBits ;
37
+ struct KnownFPClass ;
37
38
class Loop ;
38
39
class LoopInfo ;
39
40
class MDNode ;
@@ -255,244 +256,6 @@ std::tuple<Value *, FPClassTest, FPClassTest>
255
256
fcmpImpliesClass (CmpInst::Predicate Pred, const Function &F, Value *LHS,
256
257
const APFloat &RHS, bool LookThroughSrc = true );
257
258
258
- struct KnownFPClass {
259
- // / Floating-point classes the value could be one of.
260
- FPClassTest KnownFPClasses = fcAllFlags;
261
-
262
- // / std::nullopt if the sign bit is unknown, true if the sign bit is
263
- // / definitely set or false if the sign bit is definitely unset.
264
- std::optional<bool > SignBit;
265
-
266
- bool operator ==(KnownFPClass Other) const {
267
- return KnownFPClasses == Other.KnownFPClasses && SignBit == Other.SignBit ;
268
- }
269
-
270
- // / Return true if it's known this can never be one of the mask entries.
271
- bool isKnownNever (FPClassTest Mask) const {
272
- return (KnownFPClasses & Mask) == fcNone;
273
- }
274
-
275
- bool isKnownAlways (FPClassTest Mask) const { return isKnownNever (~Mask); }
276
-
277
- bool isUnknown () const {
278
- return KnownFPClasses == fcAllFlags && !SignBit;
279
- }
280
-
281
- // / Return true if it's known this can never be a nan.
282
- bool isKnownNeverNaN () const {
283
- return isKnownNever (fcNan);
284
- }
285
-
286
- // / Return true if it's known this must always be a nan.
287
- bool isKnownAlwaysNaN () const { return isKnownAlways (fcNan); }
288
-
289
- // / Return true if it's known this can never be an infinity.
290
- bool isKnownNeverInfinity () const {
291
- return isKnownNever (fcInf);
292
- }
293
-
294
- // / Return true if it's known this can never be +infinity.
295
- bool isKnownNeverPosInfinity () const {
296
- return isKnownNever (fcPosInf);
297
- }
298
-
299
- // / Return true if it's known this can never be -infinity.
300
- bool isKnownNeverNegInfinity () const {
301
- return isKnownNever (fcNegInf);
302
- }
303
-
304
- // / Return true if it's known this can never be a subnormal
305
- bool isKnownNeverSubnormal () const {
306
- return isKnownNever (fcSubnormal);
307
- }
308
-
309
- // / Return true if it's known this can never be a positive subnormal
310
- bool isKnownNeverPosSubnormal () const {
311
- return isKnownNever (fcPosSubnormal);
312
- }
313
-
314
- // / Return true if it's known this can never be a negative subnormal
315
- bool isKnownNeverNegSubnormal () const {
316
- return isKnownNever (fcNegSubnormal);
317
- }
318
-
319
- // / Return true if it's known this can never be a zero. This means a literal
320
- // / [+-]0, and does not include denormal inputs implicitly treated as [+-]0.
321
- bool isKnownNeverZero () const {
322
- return isKnownNever (fcZero);
323
- }
324
-
325
- // / Return true if it's known this can never be a literal positive zero.
326
- bool isKnownNeverPosZero () const {
327
- return isKnownNever (fcPosZero);
328
- }
329
-
330
- // / Return true if it's known this can never be a negative zero. This means a
331
- // / literal -0 and does not include denormal inputs implicitly treated as -0.
332
- bool isKnownNeverNegZero () const {
333
- return isKnownNever (fcNegZero);
334
- }
335
-
336
- // / Return true if it's know this can never be interpreted as a zero. This
337
- // / extends isKnownNeverZero to cover the case where the assumed
338
- // / floating-point mode for the function interprets denormals as zero.
339
- bool isKnownNeverLogicalZero (const Function &F, Type *Ty) const ;
340
-
341
- // / Return true if it's know this can never be interpreted as a negative zero.
342
- bool isKnownNeverLogicalNegZero (const Function &F, Type *Ty) const ;
343
-
344
- // / Return true if it's know this can never be interpreted as a positive zero.
345
- bool isKnownNeverLogicalPosZero (const Function &F, Type *Ty) const ;
346
-
347
- static constexpr FPClassTest OrderedLessThanZeroMask =
348
- fcNegSubnormal | fcNegNormal | fcNegInf;
349
- static constexpr FPClassTest OrderedGreaterThanZeroMask =
350
- fcPosSubnormal | fcPosNormal | fcPosInf;
351
-
352
- // / Return true if we can prove that the analyzed floating-point value is
353
- // / either NaN or never less than -0.0.
354
- // /
355
- // / NaN --> true
356
- // / +0 --> true
357
- // / -0 --> true
358
- // / x > +0 --> true
359
- // / x < -0 --> false
360
- bool cannotBeOrderedLessThanZero () const {
361
- return isKnownNever (OrderedLessThanZeroMask);
362
- }
363
-
364
- // / Return true if we can prove that the analyzed floating-point value is
365
- // / either NaN or never greater than -0.0.
366
- // / NaN --> true
367
- // / +0 --> true
368
- // / -0 --> true
369
- // / x > +0 --> false
370
- // / x < -0 --> true
371
- bool cannotBeOrderedGreaterThanZero () const {
372
- return isKnownNever (OrderedGreaterThanZeroMask);
373
- }
374
-
375
- KnownFPClass &operator |=(const KnownFPClass &RHS) {
376
- KnownFPClasses = KnownFPClasses | RHS.KnownFPClasses ;
377
-
378
- if (SignBit != RHS.SignBit )
379
- SignBit = std::nullopt;
380
- return *this ;
381
- }
382
-
383
- void knownNot (FPClassTest RuleOut) {
384
- KnownFPClasses = KnownFPClasses & ~RuleOut;
385
- if (isKnownNever (fcNan) && !SignBit) {
386
- if (isKnownNever (fcNegative))
387
- SignBit = false ;
388
- else if (isKnownNever (fcPositive))
389
- SignBit = true ;
390
- }
391
- }
392
-
393
- void fneg () {
394
- KnownFPClasses = llvm::fneg (KnownFPClasses);
395
- if (SignBit)
396
- SignBit = !*SignBit;
397
- }
398
-
399
- void fabs () {
400
- if (KnownFPClasses & fcNegZero)
401
- KnownFPClasses |= fcPosZero;
402
-
403
- if (KnownFPClasses & fcNegInf)
404
- KnownFPClasses |= fcPosInf;
405
-
406
- if (KnownFPClasses & fcNegSubnormal)
407
- KnownFPClasses |= fcPosSubnormal;
408
-
409
- if (KnownFPClasses & fcNegNormal)
410
- KnownFPClasses |= fcPosNormal;
411
-
412
- signBitMustBeZero ();
413
- }
414
-
415
- // / Return true if the sign bit must be 0, ignoring the sign of nans.
416
- bool signBitIsZeroOrNaN () const {
417
- return isKnownNever (fcNegative);
418
- }
419
-
420
- // / Assume the sign bit is zero.
421
- void signBitMustBeZero () {
422
- KnownFPClasses &= (fcPositive | fcNan);
423
- SignBit = false ;
424
- }
425
-
426
- // / Assume the sign bit is one.
427
- void signBitMustBeOne () {
428
- KnownFPClasses &= (fcNegative | fcNan);
429
- SignBit = true ;
430
- }
431
-
432
- void copysign (const KnownFPClass &Sign) {
433
- // Don't know anything about the sign of the source. Expand the possible set
434
- // to its opposite sign pair.
435
- if (KnownFPClasses & fcZero)
436
- KnownFPClasses |= fcZero;
437
- if (KnownFPClasses & fcSubnormal)
438
- KnownFPClasses |= fcSubnormal;
439
- if (KnownFPClasses & fcNormal)
440
- KnownFPClasses |= fcNormal;
441
- if (KnownFPClasses & fcInf)
442
- KnownFPClasses |= fcInf;
443
-
444
- // Sign bit is exactly preserved even for nans.
445
- SignBit = Sign.SignBit ;
446
-
447
- // Clear sign bits based on the input sign mask.
448
- if (Sign.isKnownNever (fcPositive | fcNan) || (SignBit && *SignBit))
449
- KnownFPClasses &= (fcNegative | fcNan);
450
- if (Sign.isKnownNever (fcNegative | fcNan) || (SignBit && !*SignBit))
451
- KnownFPClasses &= (fcPositive | fcNan);
452
- }
453
-
454
- // Propagate knowledge that a non-NaN source implies the result can also not
455
- // be a NaN. For unconstrained operations, signaling nans are not guaranteed
456
- // to be quieted but cannot be introduced.
457
- void propagateNaN (const KnownFPClass &Src, bool PreserveSign = false ) {
458
- if (Src.isKnownNever (fcNan)) {
459
- knownNot (fcNan);
460
- if (PreserveSign)
461
- SignBit = Src.SignBit ;
462
- } else if (Src.isKnownNever (fcSNan))
463
- knownNot (fcSNan);
464
- }
465
-
466
- // / Propagate knowledge from a source value that could be a denormal or
467
- // / zero. We have to be conservative since output flushing is not guaranteed,
468
- // / so known-never-zero may not hold.
469
- // /
470
- // / This assumes a copy-like operation and will replace any currently known
471
- // / information.
472
- void propagateDenormal (const KnownFPClass &Src, const Function &F, Type *Ty);
473
-
474
- // / Report known classes if \p Src is evaluated through a potentially
475
- // / canonicalizing operation. We can assume signaling nans will not be
476
- // / introduced, but cannot assume a denormal will be flushed under FTZ/DAZ.
477
- // /
478
- // / This assumes a copy-like operation and will replace any currently known
479
- // / information.
480
- void propagateCanonicalizingSrc (const KnownFPClass &Src, const Function &F,
481
- Type *Ty);
482
-
483
- void resetAll () { *this = KnownFPClass (); }
484
- };
485
-
486
- inline KnownFPClass operator |(KnownFPClass LHS, const KnownFPClass &RHS) {
487
- LHS |= RHS;
488
- return LHS;
489
- }
490
-
491
- inline KnownFPClass operator |(const KnownFPClass &LHS, KnownFPClass &&RHS) {
492
- RHS |= LHS;
493
- return std::move (RHS);
494
- }
495
-
496
259
// / Determine which floating-point classes are valid for \p V, and return them
497
260
// / in KnownFPClass bit sets.
498
261
// /
@@ -510,56 +273,30 @@ KnownFPClass computeKnownFPClass(const Value *V, const APInt &DemandedElts,
510
273
KnownFPClass computeKnownFPClass (const Value *V, FPClassTest InterestedClasses,
511
274
unsigned Depth, const SimplifyQuery &SQ);
512
275
513
- inline KnownFPClass computeKnownFPClass (
514
- const Value *V, const DataLayout &DL,
515
- FPClassTest InterestedClasses = fcAllFlags, unsigned Depth = 0 ,
516
- const TargetLibraryInfo *TLI = nullptr , AssumptionCache *AC = nullptr ,
517
- const Instruction *CxtI = nullptr , const DominatorTree *DT = nullptr ,
518
- bool UseInstrInfo = true ) {
519
- return computeKnownFPClass (
520
- V, InterestedClasses, Depth,
521
- SimplifyQuery (DL, TLI, DT, AC, CxtI, UseInstrInfo));
522
- }
276
+ KnownFPClass computeKnownFPClass (const Value *V, const DataLayout &DL,
277
+ FPClassTest InterestedClasses = fcAllFlags,
278
+ unsigned Depth = 0 ,
279
+ const TargetLibraryInfo *TLI = nullptr ,
280
+ AssumptionCache *AC = nullptr ,
281
+ const Instruction *CxtI = nullptr ,
282
+ const DominatorTree *DT = nullptr ,
283
+ bool UseInstrInfo = true );
523
284
524
285
// / Wrapper to account for known fast math flags at the use instruction.
525
- inline KnownFPClass
526
- computeKnownFPClass (const Value *V, const APInt &DemandedElts,
527
- FastMathFlags FMF, FPClassTest InterestedClasses,
528
- unsigned Depth, const SimplifyQuery &SQ) {
529
- if (FMF.noNaNs ())
530
- InterestedClasses &= ~fcNan;
531
- if (FMF.noInfs ())
532
- InterestedClasses &= ~fcInf;
533
-
534
- KnownFPClass Result =
535
- computeKnownFPClass (V, DemandedElts, InterestedClasses, Depth, SQ);
536
-
537
- if (FMF.noNaNs ())
538
- Result.KnownFPClasses &= ~fcNan;
539
- if (FMF.noInfs ())
540
- Result.KnownFPClasses &= ~fcInf;
541
- return Result;
542
- }
286
+ KnownFPClass computeKnownFPClass (const Value *V, const APInt &DemandedElts,
287
+ FastMathFlags FMF,
288
+ FPClassTest InterestedClasses, unsigned Depth,
289
+ const SimplifyQuery &SQ);
543
290
544
- inline KnownFPClass computeKnownFPClass (const Value *V, FastMathFlags FMF,
545
- FPClassTest InterestedClasses,
546
- unsigned Depth,
547
- const SimplifyQuery &SQ) {
548
- auto *FVTy = dyn_cast<FixedVectorType>(V->getType ());
549
- APInt DemandedElts =
550
- FVTy ? APInt::getAllOnes (FVTy->getNumElements ()) : APInt (1 , 1 );
551
- return computeKnownFPClass (V, DemandedElts, FMF, InterestedClasses, Depth,
552
- SQ);
553
- }
291
+ KnownFPClass computeKnownFPClass (const Value *V, FastMathFlags FMF,
292
+ FPClassTest InterestedClasses, unsigned Depth,
293
+ const SimplifyQuery &SQ);
554
294
555
295
// / Return true if we can prove that the specified FP value is never equal to
556
296
// / -0.0. Users should use caution when considering PreserveSign
557
297
// / denormal-fp-math.
558
- inline bool cannotBeNegativeZero (const Value *V, unsigned Depth,
559
- const SimplifyQuery &SQ) {
560
- KnownFPClass Known = computeKnownFPClass (V, fcNegZero, Depth, SQ);
561
- return Known.isKnownNeverNegZero ();
562
- }
298
+ bool cannotBeNegativeZero (const Value *V, unsigned Depth,
299
+ const SimplifyQuery &SQ);
563
300
564
301
// / Return true if we can prove that the specified FP value is either NaN or
565
302
// / never less than -0.0.
@@ -569,46 +306,29 @@ inline bool cannotBeNegativeZero(const Value *V, unsigned Depth,
569
306
// / -0 --> true
570
307
// / x > +0 --> true
571
308
// / x < -0 --> false
572
- inline bool cannotBeOrderedLessThanZero (const Value *V, unsigned Depth,
573
- const SimplifyQuery &SQ) {
574
- KnownFPClass Known =
575
- computeKnownFPClass (V, KnownFPClass::OrderedLessThanZeroMask, Depth, SQ);
576
- return Known.cannotBeOrderedLessThanZero ();
577
- }
309
+ bool cannotBeOrderedLessThanZero (const Value *V, unsigned Depth,
310
+ const SimplifyQuery &SQ);
578
311
579
312
// / Return true if the floating-point scalar value is not an infinity or if
580
313
// / the floating-point vector value has no infinities. Return false if a value
581
314
// / could ever be infinity.
582
- inline bool isKnownNeverInfinity (const Value *V, unsigned Depth,
583
- const SimplifyQuery &SQ) {
584
- KnownFPClass Known = computeKnownFPClass (V, fcInf, Depth, SQ);
585
- return Known.isKnownNeverInfinity ();
586
- }
315
+ bool isKnownNeverInfinity (const Value *V, unsigned Depth,
316
+ const SimplifyQuery &SQ);
587
317
588
318
// / Return true if the floating-point value can never contain a NaN or infinity.
589
- inline bool isKnownNeverInfOrNaN (const Value *V, unsigned Depth,
590
- const SimplifyQuery &SQ) {
591
- KnownFPClass Known = computeKnownFPClass (V, fcInf | fcNan, Depth, SQ);
592
- return Known.isKnownNeverNaN () && Known.isKnownNeverInfinity ();
593
- }
319
+ bool isKnownNeverInfOrNaN (const Value *V, unsigned Depth,
320
+ const SimplifyQuery &SQ);
594
321
595
322
// / Return true if the floating-point scalar value is not a NaN or if the
596
323
// / floating-point vector value has no NaN elements. Return false if a value
597
324
// / could ever be NaN.
598
- inline bool isKnownNeverNaN (const Value *V, unsigned Depth,
599
- const SimplifyQuery &SQ) {
600
- KnownFPClass Known = computeKnownFPClass (V, fcNan, Depth, SQ);
601
- return Known.isKnownNeverNaN ();
602
- }
325
+ bool isKnownNeverNaN (const Value *V, unsigned Depth, const SimplifyQuery &SQ);
603
326
604
327
// / Return false if we can prove that the specified FP value's sign bit is 0.
605
328
// / Return true if we can prove that the specified FP value's sign bit is 1.
606
329
// / Otherwise return std::nullopt.
607
- inline std::optional<bool > computeKnownFPSignBit (const Value *V, unsigned Depth,
608
- const SimplifyQuery &SQ) {
609
- KnownFPClass Known = computeKnownFPClass (V, fcAllFlags, Depth, SQ);
610
- return Known.SignBit ;
611
- }
330
+ std::optional<bool > computeKnownFPSignBit (const Value *V, unsigned Depth,
331
+ const SimplifyQuery &SQ);
612
332
613
333
// / If the specified value can be set by repeating the same byte in memory,
614
334
// / return the i8 value that it is represented with. This is true for all i8
0 commit comments