LLVM: include/llvm/IR/GenericFloatingPointPredicateUtils.h Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15#ifndef LLVM_ADT_GENERICFLOATINGPOINTPREDICATEUTILS_H
16#define LLVM_ADT_GENERICFLOATINGPOINTPREDICATEUTILS_H
17
22#include
23
24namespace llvm {
25
27 using ValueRefT = typename ContextT::ValueRefT;
28 using FunctionT = typename ContextT::FunctionT;
29
30 constexpr static ValueRefT Invalid = {};
31
32private:
34 ValueRefT Val);
35
36 LLVM_ABI static bool lookThroughFAbs(const FunctionT &F, ValueRefT LHS,
37 ValueRefT &Src);
38
39 LLVM_ABI static std::optional matchConstantFloat(const FunctionT &F,
40 ValueRefT Val);
41
42
43
44 static std::tuple<ValueRefT, FPClassTest, FPClassTest>
46 return {V, M, ~M};
47 }
48
49public:
50
51
52 static std::pair<ValueRefT, FPClassTest>
54 ValueRefT RHS, bool LookThroughSrc) {
55 std::optional ConstRHS = matchConstantFloat(F, RHS);
56 if (!ConstRHS)
58
60 }
61
62 static std::pair<ValueRefT, FPClassTest>
64 const APFloat &ConstRHS, bool LookThroughSrc) {
65
66 auto [Src, ClassIfTrue, ClassIfFalse] =
68
69 if (Src && ClassIfTrue == ~ClassIfFalse)
70 return {Src, ClassIfTrue};
71
73 }
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92 static std::tuple<ValueRefT, FPClassTest, FPClassTest>
94 FPClassTest RHSClass, bool LookThroughSrc) {
96 ValueRefT Src = LHS;
97
100
102 return exactClass(Src, fcNone);
103
105
106 const bool IsNegativeRHS = (RHSClass & fcNegative) == RHSClass;
107 const bool IsPositiveRHS = (RHSClass & fcPositive) == RHSClass;
108 const bool IsNaN = (RHSClass & ~fcNan) == fcNone;
109
110 if (IsNaN) {
111
112
114 }
115
116
118 return exactClass(Src, ~fcNan);
119
120
122 return exactClass(Src, fcNan);
123
124 const bool IsFabs = LookThroughSrc && lookThroughFAbs(F, LHS, Src);
125 if (IsFabs)
127
128 const bool IsZero = (OrigClass & fcZero) == OrigClass;
129 if (IsZero) {
131
132
133
137
138 auto ExactClass = [IsFabs, Src](FPClassTest Mask) {
139 if (IsFabs)
141 return exactClass(Src, Mask);
142 };
143
144 switch (Pred) {
146 return exactClass(Src, fcZero);
150 return exactClass(Src, ~fcZero);
152 return exactClass(Src, ~fcNan & ~fcZero);
154
155
156 return exactClass(Src, ~fcNan);
158 return exactClass(Src, fcNan);
175 default:
177 }
178 }
179
180 const bool IsDenormalRHS = (OrigClass & fcSubnormal) == OrigClass;
181
182 const bool IsInf = (OrigClass & fcInf) == OrigClass;
183 if (IsInf) {
185
186 switch (Pred) {
189
190
191
192
193
194
195
196
197
198
199
200 if (IsNegativeRHS) {
202 if (IsFabs)
204 } else {
206 if (IsFabs)
208 }
209 break;
210 }
213
214
215
216
217
218
219
220
221
222
223 if (IsNegativeRHS) {
225 if (IsFabs)
227 } else {
229 if (IsFabs)
231 }
232
233 break;
234 }
237 if (IsNegativeRHS) {
238
239
240
241
243 break;
244 }
245
246
247
248
249
251 if (!IsFabs)
253 break;
254 }
257 if (IsNegativeRHS) {
258
259
260
261
263 break;
264 }
265
266
267
268
269
271 if (IsFabs)
273 break;
274 }
277 if (IsNegativeRHS) {
278
279
280
281
283 break;
284 }
285
286
288 break;
289 }
292 if (IsNegativeRHS) {
294 break;
295 }
296
297
298
299
300
302 break;
303 }
304 default:
306 }
307
308
310 Mask = ~Mask;
311
312 return exactClass(Src, Mask);
313 }
314
317
320 return {Src, Class, ~fcNan};
321 }
322
325
328
333 "should have been recognized as an exact class test");
334
335 if (IsNegativeRHS) {
336
337 if (IsFabs) {
338
339
340
341
342 switch (Pred) {
355 default:
356 break;
357 }
358
360 }
361
364
365 if (IsDenormalRHS)
367 else
369
370 switch (Pred) {
373 return {Src, ClassesGE, ~ClassesGE | RHSClass};
376 return {Src, ClassesGE | fcNan, ~(ClassesGE | fcNan) | RHSClass};
379 return {Src, ClassesLE, ~ClassesLE | RHSClass};
382 return {Src, ClassesLE | fcNan, ~(ClassesLE | fcNan) | RHSClass};
383 default:
384 break;
385 }
386 } else if (IsPositiveRHS) {
389 if (IsDenormalRHS)
391 else
393
394 if (IsFabs) {
397 }
398
399 switch (Pred) {
402 return {Src, ClassesGE, ~ClassesGE | RHSClass};
405 return {Src, ClassesGE | fcNan, ~(ClassesGE | fcNan) | RHSClass};
408 return {Src, ClassesLE, ~ClassesLE | RHSClass};
411 return {Src, ClassesLE | fcNan, ~(ClassesLE | fcNan) | RHSClass};
412 default:
413 break;
414 }
415 }
416
418 }
419
420 static std::tuple<ValueRefT, FPClassTest, FPClassTest>
422 const APFloat &ConstRHS, bool LookThroughSrc) {
423
424
426 ValueRefT Src = LHS;
427 const bool IsFabs = LookThroughSrc && lookThroughFAbs(F, LHS, Src);
428
430
431 switch (Pred) {
434
435
436
437
438
440 if (!IsFabs)
442
443 break;
444 }
447
448
449
450
452 if (IsFabs)
454 break;
455 }
456 default:
458 LookThroughSrc);
459 }
460
461
463 Mask = ~Mask;
464
465 return exactClass(Src, Mask);
466 }
467
469 }
470
471 static std::tuple<ValueRefT, FPClassTest, FPClassTest>
473 ValueRefT RHS, bool LookThroughSrc) {
474 std::optional ConstRHS = matchConstantFloat(F, RHS);
475 if (!ConstRHS)
477
478
480 }
481};
482
483}
484
485#endif
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
This file declares a class to represent arbitrary precision floating point values and provide a varie...
Utilities for dealing with flags related to floating point properties and mode controls.
static cl::opt< RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode > Mode("regalloc-enable-advisor", cl::Hidden, cl::init(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Default), cl::desc("Enable regalloc advisor mode"), cl::values(clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Default, "default", "Default"), clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Release, "release", "precompiled"), clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Development, "development", "for training")))
LLVM_ABI FPClassTest classify() const
Return the FPClassTest which will return true for the value.
bool isSmallestNormalized() const
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
@ FCMP_OEQ
0 0 0 1 True if ordered and equal
@ FCMP_TRUE
1 1 1 1 Always true (always folded)
@ FCMP_OLT
0 1 0 0 True if ordered and less than
@ FCMP_ULE
1 1 0 1 True if unordered, less than, or equal
@ FCMP_OGT
0 0 1 0 True if ordered and greater than
@ FCMP_OGE
0 0 1 1 True if ordered and greater than or equal
@ FCMP_ULT
1 1 0 0 True if unordered or less than
@ FCMP_ONE
0 1 1 0 True if ordered and operands are unequal
@ FCMP_UEQ
1 0 0 1 True if unordered or equal
@ FCMP_UGT
1 0 1 0 True if unordered or greater than
@ FCMP_OLE
0 1 0 1 True if ordered and less than or equal
@ FCMP_ORD
0 1 1 1 True if ordered (no nans)
@ FCMP_UNE
1 1 1 0 True if unordered or not equal
@ FCMP_UGE
1 0 1 1 True if unordered, greater than, or equal
@ FCMP_FALSE
0 0 0 0 Always false (always folded)
@ FCMP_UNO
1 0 0 0 True if unordered: isnan(X) | isnan(Y)
static LLVM_ABI bool isUnordered(Predicate predicate)
Determine if the predicate is an unordered operation.
static LLVM_ABI bool isOrdered(Predicate predicate)
Determine if the predicate is an ordered operation.
static std::tuple< ValueRefT, FPClassTest, FPClassTest > fcmpImpliesClass(CmpInst::Predicate Pred, const FunctionT &F, ValueRefT LHS, const APFloat &ConstRHS, bool LookThroughSrc)
Definition GenericFloatingPointPredicateUtils.h:421
static std::pair< ValueRefT, FPClassTest > fcmpToClassTest(FCmpInst::Predicate Pred, const FunctionT &F, ValueRefT LHS, const APFloat &ConstRHS, bool LookThroughSrc)
Definition GenericFloatingPointPredicateUtils.h:63
static std::tuple< ValueRefT, FPClassTest, FPClassTest > fcmpImpliesClass(CmpInst::Predicate Pred, const FunctionT &F, ValueRefT LHS, FPClassTest RHSClass, bool LookThroughSrc)
Compute the possible floating-point classes that LHS could be based on fcmp \Pred LHS,...
Definition GenericFloatingPointPredicateUtils.h:93
static std::pair< ValueRefT, FPClassTest > fcmpToClassTest(FCmpInst::Predicate Pred, const FunctionT &F, ValueRefT LHS, ValueRefT RHS, bool LookThroughSrc)
Returns a pair of values, which if passed to llvm.is.fpclass, returns the same result as an fcmp with...
Definition GenericFloatingPointPredicateUtils.h:53
static std::tuple< ValueRefT, FPClassTest, FPClassTest > fcmpImpliesClass(CmpInst::Predicate Pred, const FunctionT &F, ValueRefT LHS, ValueRefT RHS, bool LookThroughSrc)
Definition GenericFloatingPointPredicateUtils.h:472
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
This is an optimization pass for GlobalISel generic memory operations.
FPClassTest
Floating-point class tests, supported by 'is_fpclass' intrinsic.
LLVM_ABI FPClassTest inverse_fabs(FPClassTest Mask)
Return the test mask which returns true after fabs is applied to the value.
Represent subnormal handling kind for floating point instruction inputs and outputs.
@ IEEE
IEEE-754 denormal numbers preserved.