Skip to content

Commit f0687d6

Browse files
committed
[GlobalISel] Add computeFPClass to GlobaISelValueTracking
1 parent 2f97695 commit f0687d6

File tree

9 files changed

+1960
-374
lines changed

9 files changed

+1960
-374
lines changed

llvm/include/llvm/ADT/FloatingPointModeUtils.h

Lines changed: 434 additions & 0 deletions
Large diffs are not rendered by default.

llvm/include/llvm/CodeGen/GlobalISel/GISelValueTracking.h

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,15 @@
1414
#ifndef LLVM_CODEGEN_GLOBALISEL_GISELVALUETRACKING_H
1515
#define LLVM_CODEGEN_GLOBALISEL_GISELVALUETRACKING_H
1616

17+
#include "llvm/ADT/APFloat.h"
1718
#include "llvm/ADT/DenseMap.h"
1819
#include "llvm/CodeGen/GlobalISel/GISelChangeObserver.h"
1920
#include "llvm/CodeGen/MachineFunctionPass.h"
2021
#include "llvm/CodeGen/Register.h"
22+
#include "llvm/IR/InstrTypes.h"
2123
#include "llvm/InitializePasses.h"
2224
#include "llvm/Support/KnownBits.h"
25+
#include "llvm/Support/KnownFPClass.h"
2326

2427
namespace llvm {
2528

@@ -34,13 +37,72 @@ class GISelValueTracking : public GISelChangeObserver {
3437
unsigned MaxDepth;
3538
/// Cache maintained during a computeKnownBits request.
3639
SmallDenseMap<Register, KnownBits, 16> ComputeKnownBitsCache;
40+
SmallDenseMap<Register, KnownFPClass, 16> ComputeKnownFPClassCache;
3741

3842
void computeKnownBitsMin(Register Src0, Register Src1, KnownBits &Known,
3943
const APInt &DemandedElts, unsigned Depth = 0);
4044

4145
unsigned computeNumSignBitsMin(Register Src0, Register Src1,
4246
const APInt &DemandedElts, unsigned Depth = 0);
4347

48+
/// Returns a pair of values, which if passed to llvm.is.fpclass, returns the
49+
/// same result as an fcmp with the given operands.
50+
///
51+
/// If \p LookThroughSrc is true, consider the input value when computing the
52+
/// mask.
53+
///
54+
/// If \p LookThroughSrc is false, ignore the source value (i.e. the first
55+
/// pair element will always be LHS.
56+
std::pair<Register, FPClassTest> fcmpToClassTest(CmpInst::Predicate Pred,
57+
const MachineFunction &MF,
58+
Register LHS, Value *RHS,
59+
bool LookThroughSrc = true);
60+
std::pair<Register, FPClassTest> fcmpToClassTest(CmpInst::Predicate Pred,
61+
const MachineFunction &MF,
62+
Register LHS,
63+
const APFloat *ConstRHS,
64+
bool LookThroughSrc = true);
65+
66+
/// Compute the possible floating-point classes that \p LHS could be based on
67+
/// fcmp \Pred \p LHS, \p RHS.
68+
///
69+
/// \returns { TestedValue, ClassesIfTrue, ClassesIfFalse }
70+
///
71+
/// If the compare returns an exact class test, ClassesIfTrue ==
72+
/// ~ClassesIfFalse
73+
///
74+
/// This is a less exact version of fcmpToClassTest (e.g. fcmpToClassTest will
75+
/// only succeed for a test of x > 0 implies positive, but not x > 1).
76+
///
77+
/// If \p LookThroughSrc is true, consider the input value when computing the
78+
/// mask. This may look through sign bit operations.
79+
///
80+
/// If \p LookThroughSrc is false, ignore the source value (i.e. the first
81+
/// pair element will always be LHS.
82+
///
83+
std::tuple<Register, FPClassTest, FPClassTest>
84+
fcmpImpliesClass(CmpInst::Predicate Pred, const MachineFunction &MF,
85+
Register LHS, Register RHS, bool LookThroughSrc = true);
86+
std::tuple<Register, FPClassTest, FPClassTest>
87+
fcmpImpliesClass(CmpInst::Predicate Pred, const MachineFunction &MF,
88+
Register LHS, FPClassTest RHS, bool LookThroughSrc = true);
89+
std::tuple<Register, FPClassTest, FPClassTest>
90+
fcmpImpliesClass(CmpInst::Predicate Pred, const MachineFunction &MF,
91+
Register LHS, const APFloat &RHS,
92+
bool LookThroughSrc = true);
93+
94+
void computeKnownFPClass(Register R, KnownFPClass &Known,
95+
FPClassTest InterestedClasses, unsigned Depth);
96+
97+
void computeKnownFPClassForFPTrunc(const MachineInstr &MI,
98+
const APInt &DemandedElts,
99+
FPClassTest InterestedClasses,
100+
KnownFPClass &Known, unsigned Depth);
101+
102+
void computeKnownFPClass(Register R, const APInt &DemandedElts,
103+
FPClassTest InterestedClasses, KnownFPClass &Known,
104+
unsigned Depth);
105+
44106
public:
45107
GISelValueTracking(MachineFunction &MF, unsigned MaxDepth = 6);
46108
virtual ~GISelValueTracking() = default;
@@ -86,6 +148,34 @@ class GISelValueTracking : public GISelChangeObserver {
86148
/// \return The known alignment for the pointer-like value \p R.
87149
Align computeKnownAlignment(Register R, unsigned Depth = 0);
88150

151+
/// Determine which floating-point classes are valid for \p V, and return them
152+
/// in KnownFPClass bit sets.
153+
///
154+
/// This function is defined on values with floating-point type, values
155+
/// vectors of floating-point type, and arrays of floating-point type.
156+
157+
/// \p InterestedClasses is a compile time optimization hint for which
158+
/// floating point classes should be queried. Queries not specified in \p
159+
/// InterestedClasses should be reliable if they are determined during the
160+
/// query.
161+
KnownFPClass computeKnownFPClass(Register R, const APInt &DemandedElts,
162+
FPClassTest InterestedClasses,
163+
unsigned Depth);
164+
165+
KnownFPClass computeKnownFPClass(Register R,
166+
FPClassTest InterestedClasses = fcAllFlags,
167+
unsigned Depth = 0);
168+
169+
/// Wrapper to account for known fast math flags at the use instruction.
170+
KnownFPClass computeKnownFPClass(Register R, const APInt &DemandedElts,
171+
uint32_t Flags,
172+
FPClassTest InterestedClasses,
173+
unsigned Depth);
174+
175+
KnownFPClass computeKnownFPClass(Register R, uint32_t Flags,
176+
FPClassTest InterestedClasses,
177+
unsigned Depth);
178+
89179
// Observer API. No-op for non-caching implementation.
90180
void erasingInstr(MachineInstr &MI) override {}
91181
void createdInstr(MachineInstr &MI) override {}

0 commit comments

Comments
 (0)