@@ -108,11 +108,109 @@ ConstantFPRange ConstantFPRange::getNonNaN(const fltSemantics &Sem) {
108
108
/* MayBeQNaN=*/ false , /* MayBeSNaN=*/ false );
109
109
}
110
110
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
+
111
158
ConstantFPRange
112
159
ConstantFPRange::makeAllowedFCmpRegion (FCmpInst::Predicate Pred,
113
160
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
+ }
116
214
}
117
215
118
216
ConstantFPRange
0 commit comments