From 91fc4e09499c24e9184853e9a53a953bdea8a356 Mon Sep 17 00:00:00 2001 From: Aditya Nandakumar Date: Fri, 9 Mar 2018 17:31:51 +0000 Subject: [PATCH] [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 --- .../llvm/CodeGen/GlobalISel/MIPatternMatch.h | 13 ++++++++ .../llvm/CodeGen/GlobalISel/MachineIRBuilder.h | 6 ++++ llvm/include/llvm/CodeGen/GlobalISel/Utils.h | 3 ++ llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp | 8 +++++ llvm/lib/CodeGen/GlobalISel/Utils.cpp | 14 +++++++++ .../CodeGen/GlobalISel/PatternMatchTest.cpp | 36 ++++++++++++++++++++++ 6 files changed, 80 insertions(+) diff --git a/llvm/include/llvm/CodeGen/GlobalISel/MIPatternMatch.h b/llvm/include/llvm/CodeGen/GlobalISel/MIPatternMatch.h index 2f31cab..336eba7 100644 --- a/llvm/include/llvm/CodeGen/GlobalISel/MIPatternMatch.h +++ b/llvm/include/llvm/CodeGen/GlobalISel/MIPatternMatch.h @@ -142,6 +142,16 @@ template <> struct bind_helper { } }; +template <> struct bind_helper { + static bool bind(const MachineRegisterInfo &MRI, const ConstantFP *&F, + unsigned Reg) { + F = getConstantFPVRegVal(Reg, MRI); + if (F) + return true; + return false; + } +}; + template struct bind_ty { Class &VR; @@ -156,6 +166,9 @@ inline bind_ty m_Reg(unsigned &R) { return R; } inline bind_ty m_MInstr(MachineInstr *&MI) { return MI; } inline bind_ty m_Type(LLT &Ty) { return Ty; } +// Helper for matching G_FCONSTANT +inline bind_ty m_GFCst(const ConstantFP *&C) { return C; } + // General helper for all the binary generic MI such as G_ADD/G_SUB etc template diff --git a/llvm/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h b/llvm/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h index 8a5d027..47d072c3 100644 --- a/llvm/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h +++ b/llvm/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h @@ -572,6 +572,12 @@ public: } MachineInstrBuilder buildFConstant(unsigned Res, const ConstantFP &Val); + template + 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. diff --git a/llvm/include/llvm/CodeGen/GlobalISel/Utils.h b/llvm/include/llvm/CodeGen/GlobalISel/Utils.h index 36cf652..837035f 100644 --- a/llvm/include/llvm/CodeGen/GlobalISel/Utils.h +++ b/llvm/include/llvm/CodeGen/GlobalISel/Utils.h @@ -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 diff --git a/llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp b/llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp index 475bb82..a6c285a 100644 --- a/llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp +++ b/llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp @@ -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"); diff --git a/llvm/lib/CodeGen/GlobalISel/Utils.cpp b/llvm/lib/CodeGen/GlobalISel/Utils.cpp index b34414b..f39b387 100644 --- a/llvm/lib/CodeGen/GlobalISel/Utils.cpp +++ b/llvm/lib/CodeGen/GlobalISel/Utils.cpp @@ -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; +} diff --git a/llvm/unittests/CodeGen/GlobalISel/PatternMatchTest.cpp b/llvm/unittests/CodeGen/GlobalISel/PatternMatchTest.cpp index 0816084..d402d0b 100644 --- a/llvm/unittests/CodeGen/GlobalISel/PatternMatchTest.cpp +++ b/llvm/unittests/CodeGen/GlobalISel/PatternMatchTest.cpp @@ -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) { -- 2.7.4