@@ -108,11 +108,109 @@ ConstantFPRange ConstantFPRange::getNonNaN(const fltSemantics &Sem) {
108108 /* MayBeQNaN=*/ false , /* MayBeSNaN=*/ false );
109109}
110110
111+ // / Return [-inf, V) or [-inf, V]
112+ static ConstantFPRange makeLessThan (APFloat V, FCmpInst::Predicate Pred) {
113+ const fltSemantics &Sem = V.getSemantics ();
114+ if (!(Pred & FCmpInst::FCMP_OEQ)) {
115+ if (V.isNegInfinity ())
116+ return ConstantFPRange::getEmpty (Sem);
117+ V.next (/* nextDown=*/ true );
118+ }
119+ return ConstantFPRange::getNonNaN (APFloat::getInf (Sem, /* Negative=*/ true ),
120+ std::move (V));
121+ }
122+
123+ // / Return (V, +inf] or [V, +inf]
124+ static ConstantFPRange makeGreaterThan (APFloat V, FCmpInst::Predicate Pred) {
125+ const fltSemantics &Sem = V.getSemantics ();
126+ if (!(Pred & FCmpInst::FCMP_OEQ)) {
127+ if (V.isPosInfinity ())
128+ return ConstantFPRange::getEmpty (Sem);
129+ V.next (/* nextDown=*/ false );
130+ }
131+ return ConstantFPRange::getNonNaN (std::move (V),
132+ APFloat::getInf (Sem, /* Negative=*/ false ));
133+ }
134+
135+ // / Make sure that +0/-0 are both included in the range.
136+ static ConstantFPRange extendZeroIfEqual (const ConstantFPRange &CR,
137+ FCmpInst::Predicate Pred) {
138+ if (!(Pred & FCmpInst::FCMP_OEQ))
139+ return CR;
140+
141+ APFloat Lower = CR.getLower ();
142+ APFloat Upper = CR.getUpper ();
143+ if (Lower.isPosZero ())
144+ Lower = APFloat::getZero (Lower.getSemantics (), /* Negative=*/ true );
145+ if (Upper.isNegZero ())
146+ Upper = APFloat::getZero (Upper.getSemantics (), /* Negative=*/ false );
147+ return ConstantFPRange (std::move (Lower), std::move (Upper), CR.containsQNaN (),
148+ CR.containsSNaN ());
149+ }
150+
151+ static ConstantFPRange setNaNField (const ConstantFPRange &CR,
152+ FCmpInst::Predicate Pred) {
153+ bool ContainsNaN = FCmpInst::isUnordered (Pred);
154+ return ConstantFPRange (CR.getLower (), CR.getUpper (),
155+ /* MayBeQNaN=*/ ContainsNaN, /* MayBeSNaN=*/ ContainsNaN);
156+ }
157+
111158ConstantFPRange
112159ConstantFPRange::makeAllowedFCmpRegion (FCmpInst::Predicate Pred,
113160 const ConstantFPRange &Other) {
114- // TODO
115- return getFull (Other.getSemantics ());
161+ if (Other.isEmptySet ())
162+ return Other;
163+ if (Other.containsNaN () && FCmpInst::isUnordered (Pred))
164+ return getFull (Other.getSemantics ());
165+ if (Other.isNaNOnly () && FCmpInst::isOrdered (Pred))
166+ return getEmpty (Other.getSemantics ());
167+
168+ switch (Pred) {
169+ case FCmpInst::FCMP_TRUE:
170+ return getFull (Other.getSemantics ());
171+ case FCmpInst::FCMP_FALSE:
172+ return getEmpty (Other.getSemantics ());
173+ case FCmpInst::FCMP_ORD:
174+ return getNonNaN (Other.getSemantics ());
175+ case FCmpInst::FCMP_UNO:
176+ return getNaNOnly (Other.getSemantics (), /* MayBeQNaN=*/ true ,
177+ /* MayBeSNaN=*/ true );
178+ case FCmpInst::FCMP_OEQ:
179+ case FCmpInst::FCMP_UEQ:
180+ return setNaNField (extendZeroIfEqual (Other, Pred), Pred);
181+ case FCmpInst::FCMP_ONE:
182+ case FCmpInst::FCMP_UNE:
183+ if (const APFloat *SingleElement =
184+ Other.getSingleElement (/* ExcludesNaN=*/ true )) {
185+ const fltSemantics &Sem = SingleElement->getSemantics ();
186+ if (SingleElement->isPosInfinity ())
187+ return setNaNField (
188+ getNonNaN (APFloat::getInf (Sem, /* Negative=*/ true ),
189+ APFloat::getLargest (Sem, /* Negative=*/ false )),
190+ Pred);
191+ if (SingleElement->isNegInfinity ())
192+ return setNaNField (
193+ getNonNaN (APFloat::getLargest (Sem, /* Negative=*/ true ),
194+ APFloat::getInf (Sem, /* Negative=*/ false )),
195+ Pred);
196+ }
197+ return Pred == FCmpInst::FCMP_ONE ? getNonNaN (Other.getSemantics ())
198+ : getFull (Other.getSemantics ());
199+ case FCmpInst::FCMP_OLT:
200+ case FCmpInst::FCMP_OLE:
201+ case FCmpInst::FCMP_ULT:
202+ case FCmpInst::FCMP_ULE:
203+ return setNaNField (
204+ extendZeroIfEqual (makeLessThan (Other.getUpper (), Pred), Pred), Pred);
205+ case FCmpInst::FCMP_OGT:
206+ case FCmpInst::FCMP_OGE:
207+ case FCmpInst::FCMP_UGT:
208+ case FCmpInst::FCMP_UGE:
209+ return setNaNField (
210+ extendZeroIfEqual (makeGreaterThan (Other.getLower (), Pred), Pred), Pred);
211+ default :
212+ llvm_unreachable (" Unexpected predicate" );
213+ }
116214}
117215
118216ConstantFPRange
0 commit comments