@@ -34,6 +34,7 @@ class DominatorTree;
3434class GEPOperator ;
3535class WithOverflowInst ;
3636struct KnownBits ;
37+ struct KnownFPClass ;
3738class Loop ;
3839class LoopInfo ;
3940class MDNode ;
@@ -255,244 +256,6 @@ std::tuple<Value *, FPClassTest, FPClassTest>
255256fcmpImpliesClass (CmpInst::Predicate Pred, const Function &F, Value *LHS,
256257 const APFloat &RHS, bool LookThroughSrc = true );
257258
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-
496259// / Determine which floating-point classes are valid for \p V, and return them
497260// / in KnownFPClass bit sets.
498261// /
@@ -510,56 +273,30 @@ KnownFPClass computeKnownFPClass(const Value *V, const APInt &DemandedElts,
510273KnownFPClass computeKnownFPClass (const Value *V, FPClassTest InterestedClasses,
511274 unsigned Depth, const SimplifyQuery &SQ);
512275
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 );
523284
524285// / 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);
543290
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);
554294
555295// / Return true if we can prove that the specified FP value is never equal to
556296// / -0.0. Users should use caution when considering PreserveSign
557297// / 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);
563300
564301// / Return true if we can prove that the specified FP value is either NaN or
565302// / never less than -0.0.
@@ -569,46 +306,29 @@ inline bool cannotBeNegativeZero(const Value *V, unsigned Depth,
569306// / -0 --> true
570307// / x > +0 --> true
571308// / 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);
578311
579312// / Return true if the floating-point scalar value is not an infinity or if
580313// / the floating-point vector value has no infinities. Return false if a value
581314// / 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);
587317
588318// / 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);
594321
595322// / Return true if the floating-point scalar value is not a NaN or if the
596323// / floating-point vector value has no NaN elements. Return false if a value
597324// / 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);
603326
604327// / Return false if we can prove that the specified FP value's sign bit is 0.
605328// / Return true if we can prove that the specified FP value's sign bit is 1.
606329// / 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);
612332
613333// / If the specified value can be set by repeating the same byte in memory,
614334// / return the i8 value that it is represented with. This is true for all i8
0 commit comments