llvm.org GIT mirror llvm / bf0554f
[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 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@327152 91177308-0d34-0410-b5e6-96231b3b80d8 Aditya Nandakumar 2 years ago
6 changed file(s) with 80 addition(s) and 0 deletion(s). Raw diff Collapse all Expand all
141141 }
142142 };
143143
144 template <> struct bind_helper {
145 static bool bind(const MachineRegisterInfo &MRI, const ConstantFP *&F,
146 unsigned Reg) {
147 F = getConstantFPVRegVal(Reg, MRI);
148 if (F)
149 return true;
150 return false;
151 }
152 };
153
144154 template struct bind_ty {
145155 Class &VR;
146156
154164 inline bind_ty m_Reg(unsigned &R) { return R; }
155165 inline bind_ty m_MInstr(MachineInstr *&MI) { return MI; }
156166 inline bind_ty m_Type(LLT &Ty) { return Ty; }
167
168 // Helper for matching G_FCONSTANT
169 inline bind_ty m_GFCst(const ConstantFP *&C) { return C; }
157170
158171 // General helper for all the binary generic MI such as G_ADD/G_SUB etc
159172 template
571571 }
572572 MachineInstrBuilder buildFConstant(unsigned Res, const ConstantFP &Val);
573573
574 template
575 MachineInstrBuilder buildFConstant(DstType &&Res, double Val) {
576 return buildFConstant(getDestFromArg(Res), Val);
577 }
578 MachineInstrBuilder buildFConstant(unsigned Res, double Val);
579
574580 /// Build and insert \p Res = COPY Op
575581 ///
576582 /// Register-to-register COPY sets \p Res to \p Op.
3232 class TargetRegisterClass;
3333 class Twine;
3434 class ConstantFP;
35 class APFloat;
3536
3637 /// Try to constrain Reg to the specified register class. If this fails,
3738 /// create a new virtual register in the correct class and insert a COPY before
9899 MachineInstr *getOpcodeDef(unsigned Opcode, unsigned Reg,
99100 const MachineRegisterInfo &MRI);
100101
102 /// Returns an APFloat from Val converted to the appropriate size.
103 APFloat getAPFloatFromSize(double Val, unsigned Size);
101104 } // End namespace llvm.
102105 #endif
283283 return buildInstr(TargetOpcode::G_FCONSTANT).addDef(Res).addFPImm(&Val);
284284 }
285285
286 MachineInstrBuilder MachineIRBuilder::buildFConstant(unsigned Res, double Val) {
287 LLT DstTy = MRI->getType(Res);
288 auto &Ctx = MF->getFunction().getContext();
289 auto *CFP =
290 ConstantFP::get(Ctx, getAPFloatFromSize(Val, DstTy.getSizeInBits()));
291 return buildFConstant(Res, *CFP);
292 }
293
286294 MachineInstrBuilder MachineIRBuilder::buildBrCond(unsigned Tst,
287295 MachineBasicBlock &Dest) {
288296 assert(MRI->getType(Tst).isScalar() && "invalid operand type");
1010 //===----------------------------------------------------------------------===//
1111
1212 #include "llvm/CodeGen/GlobalISel/Utils.h"
13 #include "llvm/ADT/APFloat.h"
1314 #include "llvm/ADT/Twine.h"
1415 #include "llvm/CodeGen/GlobalISel/RegisterBankInfo.h"
1516 #include "llvm/CodeGen/MachineInstr.h"
211212 }
212213 return DefMI->getOpcode() == Opcode ? DefMI : nullptr;
213214 }
215
216 APFloat llvm::getAPFloatFromSize(double Val, unsigned Size) {
217 if (Size == 32)
218 return APFloat(float(Val));
219 if (Size == 64)
220 return APFloat(Val);
221 if (Size != 16)
222 llvm_unreachable("Unsupported FPConstant size");
223 bool Ignored;
224 APFloat APF(Val);
225 APF.convert(APFloat::IEEEhalf(), APFloat::rmNearestTiesToEven, &Ignored);
226 return APF;
227 }
256256 match = mi_match(MIBFabs->getOperand(0).getReg(), MRI, m_GFabs(m_Reg(Src)));
257257 ASSERT_TRUE(match);
258258 ASSERT_EQ(Src, Copy0s32->getOperand(0).getReg());
259
260 // Build and match FConstant.
261 auto MIBFCst = B.buildFConstant(s32, .5);
262 const ConstantFP *TmpFP{};
263 match = mi_match(MIBFCst->getOperand(0).getReg(), MRI, m_GFCst(TmpFP));
264 ASSERT_TRUE(match);
265 ASSERT_TRUE(TmpFP);
266 APFloat APF((float).5);
267 auto *CFP = ConstantFP::get(Context, APF);
268 ASSERT_EQ(CFP, TmpFP);
269
270 // Build double float.
271 LLT s64 = LLT::scalar(64);
272 auto MIBFCst64 = B.buildFConstant(s64, .5);
273 const ConstantFP *TmpFP64{};
274 match = mi_match(MIBFCst64->getOperand(0).getReg(), MRI, m_GFCst(TmpFP64));
275 ASSERT_TRUE(match);
276 ASSERT_TRUE(TmpFP64);
277 APFloat APF64(.5);
278 auto CFP64 = ConstantFP::get(Context, APF64);
279 ASSERT_EQ(CFP64, TmpFP64);
280 ASSERT_NE(TmpFP64, TmpFP);
281
282 // Build half float.
283 LLT s16 = LLT::scalar(16);
284 auto MIBFCst16 = B.buildFConstant(s16, .5);
285 const ConstantFP *TmpFP16{};
286 match = mi_match(MIBFCst16->getOperand(0).getReg(), MRI, m_GFCst(TmpFP16));
287 ASSERT_TRUE(match);
288 ASSERT_TRUE(TmpFP16);
289 bool Ignored;
290 APFloat APF16(.5);
291 APF16.convert(APFloat::IEEEhalf(), APFloat::rmNearestTiesToEven, &Ignored);
292 auto CFP16 = ConstantFP::get(Context, APF16);
293 ASSERT_EQ(TmpFP16, CFP16);
294 ASSERT_NE(TmpFP16, TmpFP);
259295 }
260296
261297 TEST(PatternMatchInstr, MatchExtendsTrunc) {