forked from OSchip/llvm-project
[GISel]: Add helpers for easy building G_FCONSTANT along with matchers
Added helpers to build G_FCONSTANT, along with matching ConstantFP and unit tests for the same. Sample usage. auto MIB = Builder.buildFConstant(s32, 0.5); // Build IEEESingle For Matching the above const ConstantFP* Tmp; mi_match(DstReg, MRI, m_GFCst(Tmp)); https://reviews.llvm.org/D44128 reviewed by: volkan llvm-svn: 327152
This commit is contained in:
parent
2e55ee77e2
commit
91fc4e0949
|
@ -142,6 +142,16 @@ template <> struct bind_helper<LLT> {
|
|||
}
|
||||
};
|
||||
|
||||
template <> struct bind_helper<const ConstantFP *> {
|
||||
static bool bind(const MachineRegisterInfo &MRI, const ConstantFP *&F,
|
||||
unsigned Reg) {
|
||||
F = getConstantFPVRegVal(Reg, MRI);
|
||||
if (F)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Class> struct bind_ty {
|
||||
Class &VR;
|
||||
|
||||
|
@ -156,6 +166,9 @@ inline bind_ty<unsigned> m_Reg(unsigned &R) { return R; }
|
|||
inline bind_ty<MachineInstr *> m_MInstr(MachineInstr *&MI) { return MI; }
|
||||
inline bind_ty<LLT> m_Type(LLT &Ty) { return Ty; }
|
||||
|
||||
// Helper for matching G_FCONSTANT
|
||||
inline bind_ty<const ConstantFP *> m_GFCst(const ConstantFP *&C) { return C; }
|
||||
|
||||
// General helper for all the binary generic MI such as G_ADD/G_SUB etc
|
||||
template <typename LHS_P, typename RHS_P, unsigned Opcode,
|
||||
bool Commutable = false>
|
||||
|
|
|
@ -572,6 +572,12 @@ public:
|
|||
}
|
||||
MachineInstrBuilder buildFConstant(unsigned Res, const ConstantFP &Val);
|
||||
|
||||
template <typename DstType>
|
||||
MachineInstrBuilder buildFConstant(DstType &&Res, double Val) {
|
||||
return buildFConstant(getDestFromArg(Res), Val);
|
||||
}
|
||||
MachineInstrBuilder buildFConstant(unsigned Res, double Val);
|
||||
|
||||
/// Build and insert \p Res = COPY Op
|
||||
///
|
||||
/// Register-to-register COPY sets \p Res to \p Op.
|
||||
|
|
|
@ -33,6 +33,7 @@ class TargetRegisterInfo;
|
|||
class TargetRegisterClass;
|
||||
class Twine;
|
||||
class ConstantFP;
|
||||
class APFloat;
|
||||
|
||||
/// Try to constrain Reg to the specified register class. If this fails,
|
||||
/// create a new virtual register in the correct class and insert a COPY before
|
||||
|
@ -99,5 +100,7 @@ const ConstantFP* getConstantFPVRegVal(unsigned VReg,
|
|||
MachineInstr *getOpcodeDef(unsigned Opcode, unsigned Reg,
|
||||
const MachineRegisterInfo &MRI);
|
||||
|
||||
/// Returns an APFloat from Val converted to the appropriate size.
|
||||
APFloat getAPFloatFromSize(double Val, unsigned Size);
|
||||
} // End namespace llvm.
|
||||
#endif
|
||||
|
|
|
@ -284,6 +284,14 @@ MachineInstrBuilder MachineIRBuilder::buildFConstant(unsigned Res,
|
|||
return buildInstr(TargetOpcode::G_FCONSTANT).addDef(Res).addFPImm(&Val);
|
||||
}
|
||||
|
||||
MachineInstrBuilder MachineIRBuilder::buildFConstant(unsigned Res, double Val) {
|
||||
LLT DstTy = MRI->getType(Res);
|
||||
auto &Ctx = MF->getFunction().getContext();
|
||||
auto *CFP =
|
||||
ConstantFP::get(Ctx, getAPFloatFromSize(Val, DstTy.getSizeInBits()));
|
||||
return buildFConstant(Res, *CFP);
|
||||
}
|
||||
|
||||
MachineInstrBuilder MachineIRBuilder::buildBrCond(unsigned Tst,
|
||||
MachineBasicBlock &Dest) {
|
||||
assert(MRI->getType(Tst).isScalar() && "invalid operand type");
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "llvm/CodeGen/GlobalISel/Utils.h"
|
||||
#include "llvm/ADT/APFloat.h"
|
||||
#include "llvm/ADT/Twine.h"
|
||||
#include "llvm/CodeGen/GlobalISel/RegisterBankInfo.h"
|
||||
#include "llvm/CodeGen/MachineInstr.h"
|
||||
|
@ -212,3 +213,16 @@ llvm::MachineInstr *llvm::getOpcodeDef(unsigned Opcode, unsigned Reg,
|
|||
}
|
||||
return DefMI->getOpcode() == Opcode ? DefMI : nullptr;
|
||||
}
|
||||
|
||||
APFloat llvm::getAPFloatFromSize(double Val, unsigned Size) {
|
||||
if (Size == 32)
|
||||
return APFloat(float(Val));
|
||||
if (Size == 64)
|
||||
return APFloat(Val);
|
||||
if (Size != 16)
|
||||
llvm_unreachable("Unsupported FPConstant size");
|
||||
bool Ignored;
|
||||
APFloat APF(Val);
|
||||
APF.convert(APFloat::IEEEhalf(), APFloat::rmNearestTiesToEven, &Ignored);
|
||||
return APF;
|
||||
}
|
||||
|
|
|
@ -257,6 +257,42 @@ TEST(PatternMatchInstr, MatchFPUnaryOp) {
|
|||
match = mi_match(MIBFabs->getOperand(0).getReg(), MRI, m_GFabs(m_Reg(Src)));
|
||||
ASSERT_TRUE(match);
|
||||
ASSERT_EQ(Src, Copy0s32->getOperand(0).getReg());
|
||||
|
||||
// Build and match FConstant.
|
||||
auto MIBFCst = B.buildFConstant(s32, .5);
|
||||
const ConstantFP *TmpFP{};
|
||||
match = mi_match(MIBFCst->getOperand(0).getReg(), MRI, m_GFCst(TmpFP));
|
||||
ASSERT_TRUE(match);
|
||||
ASSERT_TRUE(TmpFP);
|
||||
APFloat APF((float).5);
|
||||
auto *CFP = ConstantFP::get(Context, APF);
|
||||
ASSERT_EQ(CFP, TmpFP);
|
||||
|
||||
// Build double float.
|
||||
LLT s64 = LLT::scalar(64);
|
||||
auto MIBFCst64 = B.buildFConstant(s64, .5);
|
||||
const ConstantFP *TmpFP64{};
|
||||
match = mi_match(MIBFCst64->getOperand(0).getReg(), MRI, m_GFCst(TmpFP64));
|
||||
ASSERT_TRUE(match);
|
||||
ASSERT_TRUE(TmpFP64);
|
||||
APFloat APF64(.5);
|
||||
auto CFP64 = ConstantFP::get(Context, APF64);
|
||||
ASSERT_EQ(CFP64, TmpFP64);
|
||||
ASSERT_NE(TmpFP64, TmpFP);
|
||||
|
||||
// Build half float.
|
||||
LLT s16 = LLT::scalar(16);
|
||||
auto MIBFCst16 = B.buildFConstant(s16, .5);
|
||||
const ConstantFP *TmpFP16{};
|
||||
match = mi_match(MIBFCst16->getOperand(0).getReg(), MRI, m_GFCst(TmpFP16));
|
||||
ASSERT_TRUE(match);
|
||||
ASSERT_TRUE(TmpFP16);
|
||||
bool Ignored;
|
||||
APFloat APF16(.5);
|
||||
APF16.convert(APFloat::IEEEhalf(), APFloat::rmNearestTiesToEven, &Ignored);
|
||||
auto CFP16 = ConstantFP::get(Context, APF16);
|
||||
ASSERT_EQ(TmpFP16, CFP16);
|
||||
ASSERT_NE(TmpFP16, TmpFP);
|
||||
}
|
||||
|
||||
TEST(PatternMatchInstr, MatchExtendsTrunc) {
|
||||
|
|
Loading…
Reference in New Issue