14
14
#ifndef LLVM_CODEGEN_GLOBALISEL_GISELVALUETRACKING_H
15
15
#define LLVM_CODEGEN_GLOBALISEL_GISELVALUETRACKING_H
16
16
17
+ #include " llvm/ADT/APFloat.h"
17
18
#include " llvm/ADT/DenseMap.h"
18
19
#include " llvm/CodeGen/GlobalISel/GISelChangeObserver.h"
19
20
#include " llvm/CodeGen/MachineFunctionPass.h"
20
21
#include " llvm/CodeGen/Register.h"
22
+ #include " llvm/IR/InstrTypes.h"
21
23
#include " llvm/IR/PassManager.h"
22
24
#include " llvm/InitializePasses.h"
23
25
#include " llvm/Support/KnownBits.h"
26
+ #include " llvm/Support/KnownFPClass.h"
24
27
25
28
namespace llvm {
26
29
@@ -35,13 +38,72 @@ class GISelValueTracking : public GISelChangeObserver {
35
38
unsigned MaxDepth;
36
39
// / Cache maintained during a computeKnownBits request.
37
40
SmallDenseMap<Register, KnownBits, 16 > ComputeKnownBitsCache;
41
+ SmallDenseMap<Register, KnownFPClass, 16 > ComputeKnownFPClassCache;
38
42
39
43
void computeKnownBitsMin (Register Src0, Register Src1, KnownBits &Known,
40
44
const APInt &DemandedElts, unsigned Depth = 0 );
41
45
42
46
unsigned computeNumSignBitsMin (Register Src0, Register Src1,
43
47
const APInt &DemandedElts, unsigned Depth = 0 );
44
48
49
+ // / Returns a pair of values, which if passed to llvm.is.fpclass, returns the
50
+ // / same result as an fcmp with the given operands.
51
+ // /
52
+ // / If \p LookThroughSrc is true, consider the input value when computing the
53
+ // / mask.
54
+ // /
55
+ // / If \p LookThroughSrc is false, ignore the source value (i.e. the first
56
+ // / pair element will always be LHS.
57
+ std::pair<Register, FPClassTest> fcmpToClassTest (CmpInst::Predicate Pred,
58
+ const MachineFunction &MF,
59
+ Register LHS, Value *RHS,
60
+ bool LookThroughSrc = true );
61
+ std::pair<Register, FPClassTest> fcmpToClassTest (CmpInst::Predicate Pred,
62
+ const MachineFunction &MF,
63
+ Register LHS,
64
+ const APFloat *ConstRHS,
65
+ bool LookThroughSrc = true );
66
+
67
+ // / Compute the possible floating-point classes that \p LHS could be based on
68
+ // / fcmp \Pred \p LHS, \p RHS.
69
+ // /
70
+ // / \returns { TestedValue, ClassesIfTrue, ClassesIfFalse }
71
+ // /
72
+ // / If the compare returns an exact class test, ClassesIfTrue ==
73
+ // / ~ClassesIfFalse
74
+ // /
75
+ // / This is a less exact version of fcmpToClassTest (e.g. fcmpToClassTest will
76
+ // / only succeed for a test of x > 0 implies positive, but not x > 1).
77
+ // /
78
+ // / If \p LookThroughSrc is true, consider the input value when computing the
79
+ // / mask. This may look through sign bit operations.
80
+ // /
81
+ // / If \p LookThroughSrc is false, ignore the source value (i.e. the first
82
+ // / pair element will always be LHS.
83
+ // /
84
+ std::tuple<Register, FPClassTest, FPClassTest>
85
+ fcmpImpliesClass (CmpInst::Predicate Pred, const MachineFunction &MF,
86
+ Register LHS, Register RHS, bool LookThroughSrc = true );
87
+ std::tuple<Register, FPClassTest, FPClassTest>
88
+ fcmpImpliesClass (CmpInst::Predicate Pred, const MachineFunction &MF,
89
+ Register LHS, FPClassTest RHS, bool LookThroughSrc = true );
90
+ std::tuple<Register, FPClassTest, FPClassTest>
91
+ fcmpImpliesClass (CmpInst::Predicate Pred, const MachineFunction &MF,
92
+ Register LHS, const APFloat &RHS,
93
+ bool LookThroughSrc = true );
94
+
95
+ void computeKnownFPClass (Register R, KnownFPClass &Known,
96
+ FPClassTest InterestedClasses, unsigned Depth);
97
+
98
+ void computeKnownFPClassForFPTrunc (const MachineInstr &MI,
99
+ const APInt &DemandedElts,
100
+ FPClassTest InterestedClasses,
101
+ KnownFPClass &Known, unsigned Depth);
102
+
103
+ void computeKnownFPClass (Register R, const APInt &DemandedElts,
104
+ FPClassTest InterestedClasses, KnownFPClass &Known,
105
+ unsigned Depth);
106
+
45
107
public:
46
108
GISelValueTracking (MachineFunction &MF, unsigned MaxDepth = 6 );
47
109
virtual ~GISelValueTracking () = default ;
@@ -87,6 +149,34 @@ class GISelValueTracking : public GISelChangeObserver {
87
149
// / \return The known alignment for the pointer-like value \p R.
88
150
Align computeKnownAlignment (Register R, unsigned Depth = 0 );
89
151
152
+ // / Determine which floating-point classes are valid for \p V, and return them
153
+ // / in KnownFPClass bit sets.
154
+ // /
155
+ // / This function is defined on values with floating-point type, values
156
+ // / vectors of floating-point type, and arrays of floating-point type.
157
+
158
+ // / \p InterestedClasses is a compile time optimization hint for which
159
+ // / floating point classes should be queried. Queries not specified in \p
160
+ // / InterestedClasses should be reliable if they are determined during the
161
+ // / query.
162
+ KnownFPClass computeKnownFPClass (Register R, const APInt &DemandedElts,
163
+ FPClassTest InterestedClasses,
164
+ unsigned Depth);
165
+
166
+ KnownFPClass computeKnownFPClass (Register R,
167
+ FPClassTest InterestedClasses = fcAllFlags,
168
+ unsigned Depth = 0 );
169
+
170
+ // / Wrapper to account for known fast math flags at the use instruction.
171
+ KnownFPClass computeKnownFPClass (Register R, const APInt &DemandedElts,
172
+ uint32_t Flags,
173
+ FPClassTest InterestedClasses,
174
+ unsigned Depth);
175
+
176
+ KnownFPClass computeKnownFPClass (Register R, uint32_t Flags,
177
+ FPClassTest InterestedClasses,
178
+ unsigned Depth);
179
+
90
180
// Observer API. No-op for non-caching implementation.
91
181
void erasingInstr (MachineInstr &MI) override {}
92
182
void createdInstr (MachineInstr &MI) override {}
0 commit comments