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