LLVM  7.0.0svn
LegalizerHelper.cpp
Go to the documentation of this file.
1 //===-- llvm/CodeGen/GlobalISel/LegalizerHelper.cpp -----------------------===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 /// \file This file implements the LegalizerHelper class to legalize
11 /// individual instructions and the LegalizeMachineIR wrapper pass for the
12 /// primary legalization.
13 //
14 //===----------------------------------------------------------------------===//
15 
22 #include "llvm/Support/Debug.h"
24 
25 
26 #define DEBUG_TYPE "legalizer"
27 
28 using namespace llvm;
29 using namespace LegalizeActions;
30 
32  : MRI(MF.getRegInfo()), LI(*MF.getSubtarget().getLegalizerInfo()) {
33  MIRBuilder.setMF(MF);
34 }
35 
38  LLVM_DEBUG(dbgs() << "Legalizing: "; MI.print(dbgs()));
39 
40  auto Step = LI.getAction(MI, MRI);
41  switch (Step.Action) {
42  case Legal:
43  LLVM_DEBUG(dbgs() << ".. Already legal\n");
44  return AlreadyLegal;
45  case Libcall:
46  LLVM_DEBUG(dbgs() << ".. Convert to libcall\n");
47  return libcall(MI);
48  case NarrowScalar:
49  LLVM_DEBUG(dbgs() << ".. Narrow scalar\n");
50  return narrowScalar(MI, Step.TypeIdx, Step.NewType);
51  case WidenScalar:
52  LLVM_DEBUG(dbgs() << ".. Widen scalar\n");
53  return widenScalar(MI, Step.TypeIdx, Step.NewType);
54  case Lower:
55  LLVM_DEBUG(dbgs() << ".. Lower\n");
56  return lower(MI, Step.TypeIdx, Step.NewType);
57  case FewerElements:
58  LLVM_DEBUG(dbgs() << ".. Reduce number of elements\n");
59  return fewerElementsVector(MI, Step.TypeIdx, Step.NewType);
60  case Custom:
61  LLVM_DEBUG(dbgs() << ".. Custom legalization\n");
62  return LI.legalizeCustom(MI, MRI, MIRBuilder) ? Legalized
64  default:
65  LLVM_DEBUG(dbgs() << ".. Unable to legalize\n");
66  return UnableToLegalize;
67  }
68 }
69 
70 void LegalizerHelper::extractParts(unsigned Reg, LLT Ty, int NumParts,
72  for (int i = 0; i < NumParts; ++i)
74  MIRBuilder.buildUnmerge(VRegs, Reg);
75 }
76 
77 static RTLIB::Libcall getRTLibDesc(unsigned Opcode, unsigned Size) {
78  switch (Opcode) {
79  case TargetOpcode::G_SDIV:
80  assert(Size == 32 && "Unsupported size");
81  return RTLIB::SDIV_I32;
82  case TargetOpcode::G_UDIV:
83  assert(Size == 32 && "Unsupported size");
84  return RTLIB::UDIV_I32;
85  case TargetOpcode::G_SREM:
86  assert(Size == 32 && "Unsupported size");
87  return RTLIB::SREM_I32;
88  case TargetOpcode::G_UREM:
89  assert(Size == 32 && "Unsupported size");
90  return RTLIB::UREM_I32;
91  case TargetOpcode::G_FADD:
92  assert((Size == 32 || Size == 64) && "Unsupported size");
93  return Size == 64 ? RTLIB::ADD_F64 : RTLIB::ADD_F32;
94  case TargetOpcode::G_FSUB:
95  assert((Size == 32 || Size == 64) && "Unsupported size");
96  return Size == 64 ? RTLIB::SUB_F64 : RTLIB::SUB_F32;
97  case TargetOpcode::G_FMUL:
98  assert((Size == 32 || Size == 64) && "Unsupported size");
99  return Size == 64 ? RTLIB::MUL_F64 : RTLIB::MUL_F32;
100  case TargetOpcode::G_FDIV:
101  assert((Size == 32 || Size == 64) && "Unsupported size");
102  return Size == 64 ? RTLIB::DIV_F64 : RTLIB::DIV_F32;
103  case TargetOpcode::G_FREM:
104  return Size == 64 ? RTLIB::REM_F64 : RTLIB::REM_F32;
105  case TargetOpcode::G_FPOW:
106  return Size == 64 ? RTLIB::POW_F64 : RTLIB::POW_F32;
107  case TargetOpcode::G_FMA:
108  assert((Size == 32 || Size == 64) && "Unsupported size");
109  return Size == 64 ? RTLIB::FMA_F64 : RTLIB::FMA_F32;
110  }
111  llvm_unreachable("Unknown libcall function");
112 }
113 
116  const CallLowering::ArgInfo &Result,
118  auto &CLI = *MIRBuilder.getMF().getSubtarget().getCallLowering();
119  auto &TLI = *MIRBuilder.getMF().getSubtarget().getTargetLowering();
120  const char *Name = TLI.getLibcallName(Libcall);
121 
122  MIRBuilder.getMF().getFrameInfo().setHasCalls(true);
123  if (!CLI.lowerCall(MIRBuilder, TLI.getLibcallCallingConv(Libcall),
124  MachineOperand::CreateES(Name), Result, Args))
126 
128 }
129 
130 // Useful for libcalls where all operands have the same type.
133  Type *OpType) {
134  auto Libcall = getRTLibDesc(MI.getOpcode(), Size);
135 
137  for (unsigned i = 1; i < MI.getNumOperands(); i++)
138  Args.push_back({MI.getOperand(i).getReg(), OpType});
139  return createLibcall(MIRBuilder, Libcall, {MI.getOperand(0).getReg(), OpType},
140  Args);
141 }
142 
143 static RTLIB::Libcall getConvRTLibDesc(unsigned Opcode, Type *ToType,
144  Type *FromType) {
145  auto ToMVT = MVT::getVT(ToType);
146  auto FromMVT = MVT::getVT(FromType);
147 
148  switch (Opcode) {
149  case TargetOpcode::G_FPEXT:
150  return RTLIB::getFPEXT(FromMVT, ToMVT);
151  case TargetOpcode::G_FPTRUNC:
152  return RTLIB::getFPROUND(FromMVT, ToMVT);
153  case TargetOpcode::G_FPTOSI:
154  return RTLIB::getFPTOSINT(FromMVT, ToMVT);
155  case TargetOpcode::G_FPTOUI:
156  return RTLIB::getFPTOUINT(FromMVT, ToMVT);
157  case TargetOpcode::G_SITOFP:
158  return RTLIB::getSINTTOFP(FromMVT, ToMVT);
159  case TargetOpcode::G_UITOFP:
160  return RTLIB::getUINTTOFP(FromMVT, ToMVT);
161  }
162  llvm_unreachable("Unsupported libcall function");
163 }
164 
167  Type *FromType) {
169  return createLibcall(MIRBuilder, Libcall, {MI.getOperand(0).getReg(), ToType},
170  {{MI.getOperand(1).getReg(), FromType}});
171 }
172 
175  LLT LLTy = MRI.getType(MI.getOperand(0).getReg());
176  unsigned Size = LLTy.getSizeInBits();
177  auto &Ctx = MIRBuilder.getMF().getFunction().getContext();
178 
179  MIRBuilder.setInstr(MI);
180 
181  switch (MI.getOpcode()) {
182  default:
183  return UnableToLegalize;
184  case TargetOpcode::G_SDIV:
185  case TargetOpcode::G_UDIV:
186  case TargetOpcode::G_SREM:
187  case TargetOpcode::G_UREM: {
188  Type *HLTy = Type::getInt32Ty(Ctx);
189  auto Status = simpleLibcall(MI, MIRBuilder, Size, HLTy);
190  if (Status != Legalized)
191  return Status;
192  break;
193  }
194  case TargetOpcode::G_FADD:
195  case TargetOpcode::G_FSUB:
196  case TargetOpcode::G_FMUL:
197  case TargetOpcode::G_FDIV:
198  case TargetOpcode::G_FMA:
199  case TargetOpcode::G_FPOW:
200  case TargetOpcode::G_FREM: {
201  Type *HLTy = Size == 64 ? Type::getDoubleTy(Ctx) : Type::getFloatTy(Ctx);
202  auto Status = simpleLibcall(MI, MIRBuilder, Size, HLTy);
203  if (Status != Legalized)
204  return Status;
205  break;
206  }
207  case TargetOpcode::G_FPEXT: {
208  // FIXME: Support other floating point types (half, fp128 etc)
209  unsigned FromSize = MRI.getType(MI.getOperand(1).getReg()).getSizeInBits();
210  unsigned ToSize = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits();
211  if (ToSize != 64 || FromSize != 32)
212  return UnableToLegalize;
215  if (Status != Legalized)
216  return Status;
217  break;
218  }
219  case TargetOpcode::G_FPTRUNC: {
220  // FIXME: Support other floating point types (half, fp128 etc)
221  unsigned FromSize = MRI.getType(MI.getOperand(1).getReg()).getSizeInBits();
222  unsigned ToSize = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits();
223  if (ToSize != 32 || FromSize != 64)
224  return UnableToLegalize;
227  if (Status != Legalized)
228  return Status;
229  break;
230  }
231  case TargetOpcode::G_FPTOSI:
232  case TargetOpcode::G_FPTOUI: {
233  // FIXME: Support other types
234  unsigned FromSize = MRI.getType(MI.getOperand(1).getReg()).getSizeInBits();
235  unsigned ToSize = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits();
236  if (ToSize != 32 || (FromSize != 32 && FromSize != 64))
237  return UnableToLegalize;
239  MI, MIRBuilder, Type::getInt32Ty(Ctx),
240  FromSize == 64 ? Type::getDoubleTy(Ctx) : Type::getFloatTy(Ctx));
241  if (Status != Legalized)
242  return Status;
243  break;
244  }
245  case TargetOpcode::G_SITOFP:
246  case TargetOpcode::G_UITOFP: {
247  // FIXME: Support other types
248  unsigned FromSize = MRI.getType(MI.getOperand(1).getReg()).getSizeInBits();
249  unsigned ToSize = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits();
250  if (FromSize != 32 || (ToSize != 32 && ToSize != 64))
251  return UnableToLegalize;
253  MI, MIRBuilder,
254  ToSize == 64 ? Type::getDoubleTy(Ctx) : Type::getFloatTy(Ctx),
255  Type::getInt32Ty(Ctx));
256  if (Status != Legalized)
257  return Status;
258  break;
259  }
260  }
261 
262  MI.eraseFromParent();
263  return Legalized;
264 }
265 
267  unsigned TypeIdx,
268  LLT NarrowTy) {
269  // FIXME: Don't know how to handle secondary types yet.
270  if (TypeIdx != 0 && MI.getOpcode() != TargetOpcode::G_EXTRACT)
271  return UnableToLegalize;
272 
273  MIRBuilder.setInstr(MI);
274 
275  uint64_t SizeOp0 = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits();
276  uint64_t NarrowSize = NarrowTy.getSizeInBits();
277 
278  switch (MI.getOpcode()) {
279  default:
280  return UnableToLegalize;
281  case TargetOpcode::G_IMPLICIT_DEF: {
282  // FIXME: add support for when SizeOp0 isn't an exact multiple of
283  // NarrowSize.
284  if (SizeOp0 % NarrowSize != 0)
285  return UnableToLegalize;
286  int NumParts = SizeOp0 / NarrowSize;
287 
288  SmallVector<unsigned, 2> DstRegs;
289  for (int i = 0; i < NumParts; ++i)
290  DstRegs.push_back(
291  MIRBuilder.buildUndef(NarrowTy)->getOperand(0).getReg());
292  MIRBuilder.buildMerge(MI.getOperand(0).getReg(), DstRegs);
293  MI.eraseFromParent();
294  return Legalized;
295  }
296  case TargetOpcode::G_ADD: {
297  // FIXME: add support for when SizeOp0 isn't an exact multiple of
298  // NarrowSize.
299  if (SizeOp0 % NarrowSize != 0)
300  return UnableToLegalize;
301  // Expand in terms of carry-setting/consuming G_ADDE instructions.
302  int NumParts = SizeOp0 / NarrowTy.getSizeInBits();
303 
304  SmallVector<unsigned, 2> Src1Regs, Src2Regs, DstRegs;
305  extractParts(MI.getOperand(1).getReg(), NarrowTy, NumParts, Src1Regs);
306  extractParts(MI.getOperand(2).getReg(), NarrowTy, NumParts, Src2Regs);
307 
308  unsigned CarryIn = MRI.createGenericVirtualRegister(LLT::scalar(1));
309  MIRBuilder.buildConstant(CarryIn, 0);
310 
311  for (int i = 0; i < NumParts; ++i) {
312  unsigned DstReg = MRI.createGenericVirtualRegister(NarrowTy);
313  unsigned CarryOut = MRI.createGenericVirtualRegister(LLT::scalar(1));
314 
315  MIRBuilder.buildUAdde(DstReg, CarryOut, Src1Regs[i],
316  Src2Regs[i], CarryIn);
317 
318  DstRegs.push_back(DstReg);
319  CarryIn = CarryOut;
320  }
321  unsigned DstReg = MI.getOperand(0).getReg();
322  MIRBuilder.buildMerge(DstReg, DstRegs);
323  MI.eraseFromParent();
324  return Legalized;
325  }
326  case TargetOpcode::G_EXTRACT: {
327  if (TypeIdx != 1)
328  return UnableToLegalize;
329 
330  int64_t SizeOp1 = MRI.getType(MI.getOperand(1).getReg()).getSizeInBits();
331  // FIXME: add support for when SizeOp1 isn't an exact multiple of
332  // NarrowSize.
333  if (SizeOp1 % NarrowSize != 0)
334  return UnableToLegalize;
335  int NumParts = SizeOp1 / NarrowSize;
336 
337  SmallVector<unsigned, 2> SrcRegs, DstRegs;
338  SmallVector<uint64_t, 2> Indexes;
339  extractParts(MI.getOperand(1).getReg(), NarrowTy, NumParts, SrcRegs);
340 
341  unsigned OpReg = MI.getOperand(0).getReg();
342  uint64_t OpStart = MI.getOperand(2).getImm();
343  uint64_t OpSize = MRI.getType(OpReg).getSizeInBits();
344  for (int i = 0; i < NumParts; ++i) {
345  unsigned SrcStart = i * NarrowSize;
346 
347  if (SrcStart + NarrowSize <= OpStart || SrcStart >= OpStart + OpSize) {
348  // No part of the extract uses this subregister, ignore it.
349  continue;
350  } else if (SrcStart == OpStart && NarrowTy == MRI.getType(OpReg)) {
351  // The entire subregister is extracted, forward the value.
352  DstRegs.push_back(SrcRegs[i]);
353  continue;
354  }
355 
356  // OpSegStart is where this destination segment would start in OpReg if it
357  // extended infinitely in both directions.
358  int64_t ExtractOffset;
359  uint64_t SegSize;
360  if (OpStart < SrcStart) {
361  ExtractOffset = 0;
362  SegSize = std::min(NarrowSize, OpStart + OpSize - SrcStart);
363  } else {
364  ExtractOffset = OpStart - SrcStart;
365  SegSize = std::min(SrcStart + NarrowSize - OpStart, OpSize);
366  }
367 
368  unsigned SegReg = SrcRegs[i];
369  if (ExtractOffset != 0 || SegSize != NarrowSize) {
370  // A genuine extract is needed.
371  SegReg = MRI.createGenericVirtualRegister(LLT::scalar(SegSize));
372  MIRBuilder.buildExtract(SegReg, SrcRegs[i], ExtractOffset);
373  }
374 
375  DstRegs.push_back(SegReg);
376  }
377 
378  MIRBuilder.buildMerge(MI.getOperand(0).getReg(), DstRegs);
379  MI.eraseFromParent();
380  return Legalized;
381  }
382  case TargetOpcode::G_INSERT: {
383  // FIXME: add support for when SizeOp0 isn't an exact multiple of
384  // NarrowSize.
385  if (SizeOp0 % NarrowSize != 0)
386  return UnableToLegalize;
387 
388  int NumParts = SizeOp0 / NarrowSize;
389 
390  SmallVector<unsigned, 2> SrcRegs, DstRegs;
391  SmallVector<uint64_t, 2> Indexes;
392  extractParts(MI.getOperand(1).getReg(), NarrowTy, NumParts, SrcRegs);
393 
394  unsigned OpReg = MI.getOperand(2).getReg();
395  uint64_t OpStart = MI.getOperand(3).getImm();
396  uint64_t OpSize = MRI.getType(OpReg).getSizeInBits();
397  for (int i = 0; i < NumParts; ++i) {
398  unsigned DstStart = i * NarrowSize;
399 
400  if (DstStart + NarrowSize <= OpStart || DstStart >= OpStart + OpSize) {
401  // No part of the insert affects this subregister, forward the original.
402  DstRegs.push_back(SrcRegs[i]);
403  continue;
404  } else if (DstStart == OpStart && NarrowTy == MRI.getType(OpReg)) {
405  // The entire subregister is defined by this insert, forward the new
406  // value.
407  DstRegs.push_back(OpReg);
408  continue;
409  }
410 
411  // OpSegStart is where this destination segment would start in OpReg if it
412  // extended infinitely in both directions.
413  int64_t ExtractOffset, InsertOffset;
414  uint64_t SegSize;
415  if (OpStart < DstStart) {
416  InsertOffset = 0;
417  ExtractOffset = DstStart - OpStart;
418  SegSize = std::min(NarrowSize, OpStart + OpSize - DstStart);
419  } else {
420  InsertOffset = OpStart - DstStart;
421  ExtractOffset = 0;
422  SegSize =
423  std::min(NarrowSize - InsertOffset, OpStart + OpSize - DstStart);
424  }
425 
426  unsigned SegReg = OpReg;
427  if (ExtractOffset != 0 || SegSize != OpSize) {
428  // A genuine extract is needed.
429  SegReg = MRI.createGenericVirtualRegister(LLT::scalar(SegSize));
430  MIRBuilder.buildExtract(SegReg, OpReg, ExtractOffset);
431  }
432 
433  unsigned DstReg = MRI.createGenericVirtualRegister(NarrowTy);
434  MIRBuilder.buildInsert(DstReg, SrcRegs[i], SegReg, InsertOffset);
435  DstRegs.push_back(DstReg);
436  }
437 
438  assert(DstRegs.size() == (unsigned)NumParts && "not all parts covered");
439  MIRBuilder.buildMerge(MI.getOperand(0).getReg(), DstRegs);
440  MI.eraseFromParent();
441  return Legalized;
442  }
443  case TargetOpcode::G_LOAD: {
444  // FIXME: add support for when SizeOp0 isn't an exact multiple of
445  // NarrowSize.
446  if (SizeOp0 % NarrowSize != 0)
447  return UnableToLegalize;
448 
449  const auto &MMO = **MI.memoperands_begin();
450  // This implementation doesn't work for atomics. Give up instead of doing
451  // something invalid.
452  if (MMO.getOrdering() != AtomicOrdering::NotAtomic ||
453  MMO.getFailureOrdering() != AtomicOrdering::NotAtomic)
454  return UnableToLegalize;
455 
456  int NumParts = SizeOp0 / NarrowSize;
457  LLT OffsetTy = LLT::scalar(
458  MRI.getType(MI.getOperand(1).getReg()).getScalarSizeInBits());
459 
460  SmallVector<unsigned, 2> DstRegs;
461  for (int i = 0; i < NumParts; ++i) {
462  unsigned DstReg = MRI.createGenericVirtualRegister(NarrowTy);
463  unsigned SrcReg = 0;
464  unsigned Adjustment = i * NarrowSize / 8;
465 
467  MMO.getPointerInfo().getWithOffset(Adjustment), MMO.getFlags(),
468  NarrowSize / 8, i == 0 ? MMO.getAlignment() : NarrowSize / 8,
469  MMO.getAAInfo(), MMO.getRanges(), MMO.getSyncScopeID(),
470  MMO.getOrdering(), MMO.getFailureOrdering());
471 
472  MIRBuilder.materializeGEP(SrcReg, MI.getOperand(1).getReg(), OffsetTy,
473  Adjustment);
474 
475  MIRBuilder.buildLoad(DstReg, SrcReg, *SplitMMO);
476 
477  DstRegs.push_back(DstReg);
478  }
479  unsigned DstReg = MI.getOperand(0).getReg();
480  MIRBuilder.buildMerge(DstReg, DstRegs);
481  MI.eraseFromParent();
482  return Legalized;
483  }
484  case TargetOpcode::G_STORE: {
485  // FIXME: add support for when SizeOp0 isn't an exact multiple of
486  // NarrowSize.
487  if (SizeOp0 % NarrowSize != 0)
488  return UnableToLegalize;
489 
490  const auto &MMO = **MI.memoperands_begin();
491  // This implementation doesn't work for atomics. Give up instead of doing
492  // something invalid.
493  if (MMO.getOrdering() != AtomicOrdering::NotAtomic ||
494  MMO.getFailureOrdering() != AtomicOrdering::NotAtomic)
495  return UnableToLegalize;
496 
497  int NumParts = SizeOp0 / NarrowSize;
498  LLT OffsetTy = LLT::scalar(
499  MRI.getType(MI.getOperand(1).getReg()).getScalarSizeInBits());
500 
501  SmallVector<unsigned, 2> SrcRegs;
502  extractParts(MI.getOperand(0).getReg(), NarrowTy, NumParts, SrcRegs);
503 
504  for (int i = 0; i < NumParts; ++i) {
505  unsigned DstReg = 0;
506  unsigned Adjustment = i * NarrowSize / 8;
507 
509  MMO.getPointerInfo().getWithOffset(Adjustment), MMO.getFlags(),
510  NarrowSize / 8, i == 0 ? MMO.getAlignment() : NarrowSize / 8,
511  MMO.getAAInfo(), MMO.getRanges(), MMO.getSyncScopeID(),
512  MMO.getOrdering(), MMO.getFailureOrdering());
513 
514  MIRBuilder.materializeGEP(DstReg, MI.getOperand(1).getReg(), OffsetTy,
515  Adjustment);
516 
517  MIRBuilder.buildStore(SrcRegs[i], DstReg, *SplitMMO);
518  }
519  MI.eraseFromParent();
520  return Legalized;
521  }
522  case TargetOpcode::G_CONSTANT: {
523  // FIXME: add support for when SizeOp0 isn't an exact multiple of
524  // NarrowSize.
525  if (SizeOp0 % NarrowSize != 0)
526  return UnableToLegalize;
527  int NumParts = SizeOp0 / NarrowSize;
528  const APInt &Cst = MI.getOperand(1).getCImm()->getValue();
530 
531  SmallVector<unsigned, 2> DstRegs;
532  for (int i = 0; i < NumParts; ++i) {
533  unsigned DstReg = MRI.createGenericVirtualRegister(NarrowTy);
534  ConstantInt *CI =
535  ConstantInt::get(Ctx, Cst.lshr(NarrowSize * i).trunc(NarrowSize));
536  MIRBuilder.buildConstant(DstReg, *CI);
537  DstRegs.push_back(DstReg);
538  }
539  unsigned DstReg = MI.getOperand(0).getReg();
540  MIRBuilder.buildMerge(DstReg, DstRegs);
541  MI.eraseFromParent();
542  return Legalized;
543  }
544  case TargetOpcode::G_OR: {
545  // Legalize bitwise operation:
546  // A = BinOp<Ty> B, C
547  // into:
548  // B1, ..., BN = G_UNMERGE_VALUES B
549  // C1, ..., CN = G_UNMERGE_VALUES C
550  // A1 = BinOp<Ty/N> B1, C2
551  // ...
552  // AN = BinOp<Ty/N> BN, CN
553  // A = G_MERGE_VALUES A1, ..., AN
554 
555  // FIXME: add support for when SizeOp0 isn't an exact multiple of
556  // NarrowSize.
557  if (SizeOp0 % NarrowSize != 0)
558  return UnableToLegalize;
559  int NumParts = SizeOp0 / NarrowSize;
560 
561  // List the registers where the destination will be scattered.
562  SmallVector<unsigned, 2> DstRegs;
563  // List the registers where the first argument will be split.
564  SmallVector<unsigned, 2> SrcsReg1;
565  // List the registers where the second argument will be split.
566  SmallVector<unsigned, 2> SrcsReg2;
567  // Create all the temporary registers.
568  for (int i = 0; i < NumParts; ++i) {
569  unsigned DstReg = MRI.createGenericVirtualRegister(NarrowTy);
570  unsigned SrcReg1 = MRI.createGenericVirtualRegister(NarrowTy);
571  unsigned SrcReg2 = MRI.createGenericVirtualRegister(NarrowTy);
572 
573  DstRegs.push_back(DstReg);
574  SrcsReg1.push_back(SrcReg1);
575  SrcsReg2.push_back(SrcReg2);
576  }
577  // Explode the big arguments into smaller chunks.
578  MIRBuilder.buildUnmerge(SrcsReg1, MI.getOperand(1).getReg());
579  MIRBuilder.buildUnmerge(SrcsReg2, MI.getOperand(2).getReg());
580 
581  // Do the operation on each small part.
582  for (int i = 0; i < NumParts; ++i)
583  MIRBuilder.buildOr(DstRegs[i], SrcsReg1[i], SrcsReg2[i]);
584 
585  // Gather the destination registers into the final destination.
586  unsigned DstReg = MI.getOperand(0).getReg();
587  MIRBuilder.buildMerge(DstReg, DstRegs);
588  MI.eraseFromParent();
589  return Legalized;
590  }
591  }
592 }
593 
594 void LegalizerHelper::widenScalarSrc(MachineInstr &MI, LLT WideTy,
595  unsigned OpIdx, unsigned ExtOpcode) {
596  MachineOperand &MO = MI.getOperand(OpIdx);
597  auto ExtB = MIRBuilder.buildInstr(ExtOpcode, WideTy, MO.getReg());
598  MO.setReg(ExtB->getOperand(0).getReg());
599 }
600 
601 void LegalizerHelper::widenScalarDst(MachineInstr &MI, LLT WideTy,
602  unsigned OpIdx, unsigned TruncOpcode) {
603  MachineOperand &MO = MI.getOperand(OpIdx);
604  unsigned DstExt = MRI.createGenericVirtualRegister(WideTy);
606  MIRBuilder.buildInstr(TruncOpcode, MO.getReg(), DstExt);
607  MO.setReg(DstExt);
608 }
609 
611 LegalizerHelper::widenScalar(MachineInstr &MI, unsigned TypeIdx, LLT WideTy) {
612  MIRBuilder.setInstr(MI);
613 
614  switch (MI.getOpcode()) {
615  default:
616  return UnableToLegalize;
617 
618  case TargetOpcode::G_ADD:
619  case TargetOpcode::G_AND:
620  case TargetOpcode::G_MUL:
621  case TargetOpcode::G_OR:
622  case TargetOpcode::G_XOR:
623  case TargetOpcode::G_SUB:
624  // Perform operation at larger width (any extension is fine here, high bits
625  // don't affect the result) and then truncate the result back to the
626  // original type.
627  widenScalarSrc(MI, WideTy, 1, TargetOpcode::G_ANYEXT);
628  widenScalarSrc(MI, WideTy, 2, TargetOpcode::G_ANYEXT);
629  widenScalarDst(MI, WideTy);
631  return Legalized;
632 
633  case TargetOpcode::G_SHL:
634  widenScalarSrc(MI, WideTy, 1, TargetOpcode::G_ANYEXT);
635  // The "number of bits to shift" operand must preserve its value as an
636  // unsigned integer:
637  widenScalarSrc(MI, WideTy, 2, TargetOpcode::G_ZEXT);
638  widenScalarDst(MI, WideTy);
640  return Legalized;
641 
642  case TargetOpcode::G_SDIV:
643  case TargetOpcode::G_SREM:
644  widenScalarSrc(MI, WideTy, 1, TargetOpcode::G_SEXT);
645  widenScalarSrc(MI, WideTy, 2, TargetOpcode::G_SEXT);
646  widenScalarDst(MI, WideTy);
648  return Legalized;
649 
650  case TargetOpcode::G_ASHR:
651  widenScalarSrc(MI, WideTy, 1, TargetOpcode::G_SEXT);
652  // The "number of bits to shift" operand must preserve its value as an
653  // unsigned integer:
654  widenScalarSrc(MI, WideTy, 2, TargetOpcode::G_ZEXT);
655  widenScalarDst(MI, WideTy);
657  return Legalized;
658 
659  case TargetOpcode::G_UDIV:
660  case TargetOpcode::G_UREM:
661  case TargetOpcode::G_LSHR:
662  widenScalarSrc(MI, WideTy, 1, TargetOpcode::G_ZEXT);
663  widenScalarSrc(MI, WideTy, 2, TargetOpcode::G_ZEXT);
664  widenScalarDst(MI, WideTy);
666  return Legalized;
667 
668  case TargetOpcode::G_SELECT:
669  if (TypeIdx != 0)
670  return UnableToLegalize;
671  // Perform operation at larger width (any extension is fine here, high bits
672  // don't affect the result) and then truncate the result back to the
673  // original type.
674  widenScalarSrc(MI, WideTy, 2, TargetOpcode::G_ANYEXT);
675  widenScalarSrc(MI, WideTy, 3, TargetOpcode::G_ANYEXT);
676  widenScalarDst(MI, WideTy);
678  return Legalized;
679 
680  case TargetOpcode::G_FPTOSI:
681  case TargetOpcode::G_FPTOUI:
682  if (TypeIdx != 0)
683  return UnableToLegalize;
684  widenScalarDst(MI, WideTy);
686  return Legalized;
687 
688  case TargetOpcode::G_SITOFP:
689  if (TypeIdx != 1)
690  return UnableToLegalize;
691  widenScalarSrc(MI, WideTy, 1, TargetOpcode::G_SEXT);
693  return Legalized;
694 
695  case TargetOpcode::G_UITOFP:
696  if (TypeIdx != 1)
697  return UnableToLegalize;
698  widenScalarSrc(MI, WideTy, 1, TargetOpcode::G_ZEXT);
700  return Legalized;
701 
702  case TargetOpcode::G_INSERT:
703  if (TypeIdx != 0)
704  return UnableToLegalize;
705  widenScalarSrc(MI, WideTy, 1, TargetOpcode::G_ANYEXT);
706  widenScalarDst(MI, WideTy);
708  return Legalized;
709 
710  case TargetOpcode::G_LOAD:
711  // For some types like i24, we might try to widen to i32. To properly handle
712  // this we should be using a dedicated extending load, until then avoid
713  // trying to legalize.
714  if (alignTo(MRI.getType(MI.getOperand(0).getReg()).getSizeInBits(), 8) !=
715  WideTy.getSizeInBits())
716  return UnableToLegalize;
718  case TargetOpcode::G_SEXTLOAD:
719  case TargetOpcode::G_ZEXTLOAD:
720  widenScalarDst(MI, WideTy);
722  return Legalized;
723 
724  case TargetOpcode::G_STORE: {
725  if (MRI.getType(MI.getOperand(0).getReg()) != LLT::scalar(1) ||
726  WideTy != LLT::scalar(8))
727  return UnableToLegalize;
728 
729  widenScalarSrc(MI, WideTy, 0, TargetOpcode::G_ZEXT);
731  return Legalized;
732  }
733  case TargetOpcode::G_CONSTANT: {
734  MachineOperand &SrcMO = MI.getOperand(1);
736  const APInt &Val = SrcMO.getCImm()->getValue().sext(WideTy.getSizeInBits());
737  SrcMO.setCImm(ConstantInt::get(Ctx, Val));
738 
739  widenScalarDst(MI, WideTy);
741  return Legalized;
742  }
743  case TargetOpcode::G_FCONSTANT: {
744  MachineOperand &SrcMO = MI.getOperand(1);
746  APFloat Val = SrcMO.getFPImm()->getValueAPF();
747  bool LosesInfo;
748  switch (WideTy.getSizeInBits()) {
749  case 32:
751  break;
752  case 64:
754  break;
755  default:
756  llvm_unreachable("Unhandled fp widen type");
757  }
758  SrcMO.setFPImm(ConstantFP::get(Ctx, Val));
759 
760  widenScalarDst(MI, WideTy, 0, TargetOpcode::G_FPTRUNC);
762  return Legalized;
763  }
764  case TargetOpcode::G_BRCOND:
765  widenScalarSrc(MI, WideTy, 0, TargetOpcode::G_ANYEXT);
767  return Legalized;
768 
769  case TargetOpcode::G_FCMP:
770  if (TypeIdx == 0)
771  widenScalarDst(MI, WideTy);
772  else {
773  widenScalarSrc(MI, WideTy, 2, TargetOpcode::G_FPEXT);
774  widenScalarSrc(MI, WideTy, 3, TargetOpcode::G_FPEXT);
775  }
777  return Legalized;
778 
779  case TargetOpcode::G_ICMP:
780  if (TypeIdx == 0)
781  widenScalarDst(MI, WideTy);
782  else {
783  unsigned ExtOpcode = CmpInst::isSigned(static_cast<CmpInst::Predicate>(
784  MI.getOperand(1).getPredicate()))
785  ? TargetOpcode::G_SEXT
786  : TargetOpcode::G_ZEXT;
787  widenScalarSrc(MI, WideTy, 2, ExtOpcode);
788  widenScalarSrc(MI, WideTy, 3, ExtOpcode);
789  }
791  return Legalized;
792 
793  case TargetOpcode::G_GEP:
794  assert(TypeIdx == 1 && "unable to legalize pointer of GEP");
795  widenScalarSrc(MI, WideTy, 2, TargetOpcode::G_SEXT);
797  return Legalized;
798 
799  case TargetOpcode::G_PHI: {
800  assert(TypeIdx == 0 && "Expecting only Idx 0");
801 
802  for (unsigned I = 1; I < MI.getNumOperands(); I += 2) {
803  MachineBasicBlock &OpMBB = *MI.getOperand(I + 1).getMBB();
804  MIRBuilder.setInsertPt(OpMBB, OpMBB.getFirstTerminator());
805  widenScalarSrc(MI, WideTy, I, TargetOpcode::G_ANYEXT);
806  }
807 
808  MachineBasicBlock &MBB = *MI.getParent();
809  MIRBuilder.setInsertPt(MBB, --MBB.getFirstNonPHI());
810  widenScalarDst(MI, WideTy);
812  return Legalized;
813  }
814  }
815 }
816 
818 LegalizerHelper::lower(MachineInstr &MI, unsigned TypeIdx, LLT Ty) {
819  using namespace TargetOpcode;
820  MIRBuilder.setInstr(MI);
821 
822  switch(MI.getOpcode()) {
823  default:
824  return UnableToLegalize;
825  case TargetOpcode::G_SREM:
826  case TargetOpcode::G_UREM: {
827  unsigned QuotReg = MRI.createGenericVirtualRegister(Ty);
828  MIRBuilder.buildInstr(MI.getOpcode() == G_SREM ? G_SDIV : G_UDIV)
829  .addDef(QuotReg)
830  .addUse(MI.getOperand(1).getReg())
831  .addUse(MI.getOperand(2).getReg());
832 
833  unsigned ProdReg = MRI.createGenericVirtualRegister(Ty);
834  MIRBuilder.buildMul(ProdReg, QuotReg, MI.getOperand(2).getReg());
836  ProdReg);
837  MI.eraseFromParent();
838  return Legalized;
839  }
840  case TargetOpcode::G_SMULO:
841  case TargetOpcode::G_UMULO: {
842  // Generate G_UMULH/G_SMULH to check for overflow and a normal G_MUL for the
843  // result.
844  unsigned Res = MI.getOperand(0).getReg();
845  unsigned Overflow = MI.getOperand(1).getReg();
846  unsigned LHS = MI.getOperand(2).getReg();
847  unsigned RHS = MI.getOperand(3).getReg();
848 
849  MIRBuilder.buildMul(Res, LHS, RHS);
850 
851  unsigned Opcode = MI.getOpcode() == TargetOpcode::G_SMULO
852  ? TargetOpcode::G_SMULH
853  : TargetOpcode::G_UMULH;
854 
855  unsigned HiPart = MRI.createGenericVirtualRegister(Ty);
856  MIRBuilder.buildInstr(Opcode)
857  .addDef(HiPart)
858  .addUse(LHS)
859  .addUse(RHS);
860 
861  unsigned Zero = MRI.createGenericVirtualRegister(Ty);
862  MIRBuilder.buildConstant(Zero, 0);
863 
864  // For *signed* multiply, overflow is detected by checking:
865  // (hi != (lo >> bitwidth-1))
866  if (Opcode == TargetOpcode::G_SMULH) {
867  unsigned Shifted = MRI.createGenericVirtualRegister(Ty);
868  unsigned ShiftAmt = MRI.createGenericVirtualRegister(Ty);
869  MIRBuilder.buildConstant(ShiftAmt, Ty.getSizeInBits() - 1);
870  MIRBuilder.buildInstr(TargetOpcode::G_ASHR)
871  .addDef(Shifted)
872  .addUse(Res)
873  .addUse(ShiftAmt);
874  MIRBuilder.buildICmp(CmpInst::ICMP_NE, Overflow, HiPart, Shifted);
875  } else {
876  MIRBuilder.buildICmp(CmpInst::ICMP_NE, Overflow, HiPart, Zero);
877  }
878  MI.eraseFromParent();
879  return Legalized;
880  }
881  case TargetOpcode::G_FNEG: {
882  // TODO: Handle vector types once we are able to
883  // represent them.
884  if (Ty.isVector())
885  return UnableToLegalize;
886  unsigned Res = MI.getOperand(0).getReg();
887  Type *ZeroTy;
889  switch (Ty.getSizeInBits()) {
890  case 16:
891  ZeroTy = Type::getHalfTy(Ctx);
892  break;
893  case 32:
894  ZeroTy = Type::getFloatTy(Ctx);
895  break;
896  case 64:
897  ZeroTy = Type::getDoubleTy(Ctx);
898  break;
899  case 128:
900  ZeroTy = Type::getFP128Ty(Ctx);
901  break;
902  default:
903  llvm_unreachable("unexpected floating-point type");
904  }
905  ConstantFP &ZeroForNegation =
906  *cast<ConstantFP>(ConstantFP::getZeroValueForNegation(ZeroTy));
907  auto Zero = MIRBuilder.buildFConstant(Ty, ZeroForNegation);
908  MIRBuilder.buildInstr(TargetOpcode::G_FSUB)
909  .addDef(Res)
910  .addUse(Zero->getOperand(0).getReg())
911  .addUse(MI.getOperand(1).getReg());
912  MI.eraseFromParent();
913  return Legalized;
914  }
915  case TargetOpcode::G_FSUB: {
916  // Lower (G_FSUB LHS, RHS) to (G_FADD LHS, (G_FNEG RHS)).
917  // First, check if G_FNEG is marked as Lower. If so, we may
918  // end up with an infinite loop as G_FSUB is used to legalize G_FNEG.
919  if (LI.getAction({G_FNEG, {Ty}}).Action == Lower)
920  return UnableToLegalize;
921  unsigned Res = MI.getOperand(0).getReg();
922  unsigned LHS = MI.getOperand(1).getReg();
923  unsigned RHS = MI.getOperand(2).getReg();
924  unsigned Neg = MRI.createGenericVirtualRegister(Ty);
925  MIRBuilder.buildInstr(TargetOpcode::G_FNEG).addDef(Neg).addUse(RHS);
926  MIRBuilder.buildInstr(TargetOpcode::G_FADD)
927  .addDef(Res)
928  .addUse(LHS)
929  .addUse(Neg);
930  MI.eraseFromParent();
931  return Legalized;
932  }
933  case TargetOpcode::G_ATOMIC_CMPXCHG_WITH_SUCCESS: {
934  unsigned OldValRes = MI.getOperand(0).getReg();
935  unsigned SuccessRes = MI.getOperand(1).getReg();
936  unsigned Addr = MI.getOperand(2).getReg();
937  unsigned CmpVal = MI.getOperand(3).getReg();
938  unsigned NewVal = MI.getOperand(4).getReg();
939  MIRBuilder.buildAtomicCmpXchg(OldValRes, Addr, CmpVal, NewVal,
940  **MI.memoperands_begin());
941  MIRBuilder.buildICmp(CmpInst::ICMP_EQ, SuccessRes, OldValRes, CmpVal);
942  MI.eraseFromParent();
943  return Legalized;
944  }
945  case TargetOpcode::G_LOAD:
946  case TargetOpcode::G_SEXTLOAD:
947  case TargetOpcode::G_ZEXTLOAD: {
948  // Lower to a memory-width G_LOAD and a G_SEXT/G_ZEXT/G_ANYEXT
949  unsigned DstReg = MI.getOperand(0).getReg();
950  unsigned PtrReg = MI.getOperand(1).getReg();
951  LLT DstTy = MRI.getType(DstReg);
952  auto &MMO = **MI.memoperands_begin();
953 
954  if (DstTy.getSizeInBits() == MMO.getSize() /* in bytes */ * 8) {
955  // In the case of G_LOAD, this was a non-extending load already and we're
956  // about to lower to the same instruction.
957  if (MI.getOpcode() == TargetOpcode::G_LOAD)
958  return UnableToLegalize;
959  MIRBuilder.buildLoad(DstReg, PtrReg, MMO);
960  MI.eraseFromParent();
961  return Legalized;
962  }
963 
964  if (DstTy.isScalar()) {
965  unsigned TmpReg = MRI.createGenericVirtualRegister(
966  LLT::scalar(MMO.getSize() /* in bytes */ * 8));
967  MIRBuilder.buildLoad(TmpReg, PtrReg, MMO);
968  switch (MI.getOpcode()) {
969  default:
970  llvm_unreachable("Unexpected opcode");
971  case TargetOpcode::G_LOAD:
972  MIRBuilder.buildAnyExt(DstReg, TmpReg);
973  break;
974  case TargetOpcode::G_SEXTLOAD:
975  MIRBuilder.buildSExt(DstReg, TmpReg);
976  break;
977  case TargetOpcode::G_ZEXTLOAD:
978  MIRBuilder.buildZExt(DstReg, TmpReg);
979  break;
980  }
981  MI.eraseFromParent();
982  return Legalized;
983  }
984 
985  return UnableToLegalize;
986  }
987  }
988 }
989 
992  LLT NarrowTy) {
993  // FIXME: Don't know how to handle secondary types yet.
994  if (TypeIdx != 0)
995  return UnableToLegalize;
996  switch (MI.getOpcode()) {
997  default:
998  return UnableToLegalize;
999  case TargetOpcode::G_ADD: {
1000  unsigned NarrowSize = NarrowTy.getSizeInBits();
1001  unsigned DstReg = MI.getOperand(0).getReg();
1002  unsigned Size = MRI.getType(DstReg).getSizeInBits();
1003  int NumParts = Size / NarrowSize;
1004  // FIXME: Don't know how to handle the situation where the small vectors
1005  // aren't all the same size yet.
1006  if (Size % NarrowSize != 0)
1007  return UnableToLegalize;
1008 
1009  MIRBuilder.setInstr(MI);
1010 
1011  SmallVector<unsigned, 2> Src1Regs, Src2Regs, DstRegs;
1012  extractParts(MI.getOperand(1).getReg(), NarrowTy, NumParts, Src1Regs);
1013  extractParts(MI.getOperand(2).getReg(), NarrowTy, NumParts, Src2Regs);
1014 
1015  for (int i = 0; i < NumParts; ++i) {
1016  unsigned DstReg = MRI.createGenericVirtualRegister(NarrowTy);
1017  MIRBuilder.buildAdd(DstReg, Src1Regs[i], Src2Regs[i]);
1018  DstRegs.push_back(DstReg);
1019  }
1020 
1021  MIRBuilder.buildMerge(DstReg, DstRegs);
1022  MI.eraseFromParent();
1023  return Legalized;
1024  }
1025  }
1026 }
static LegalizerHelper::LegalizeResult simpleLibcall(MachineInstr &MI, MachineIRBuilder &MIRBuilder, unsigned Size, Type *OpType)
MachineInstrBuilder buildOr(unsigned Dst, unsigned Src0, unsigned Src1)
Build and insert Res = G_OR Op0, Op1.
void push_back(const T &Elt)
Definition: SmallVector.h:213
MachineIRBuilder MIRBuilder
Expose MIRBuilder so clients can set their own RecordInsertInstruction functions. ...
static Type * getDoubleTy(LLVMContext &C)
Definition: Type.cpp:165
APInt sext(unsigned width) const
Sign extend to a new width.
Definition: APInt.cpp:840
MachineBasicBlock * getMBB() const
Compute iterated dominance frontiers using a linear time algorithm.
Definition: AllocatorList.h:24
LLVM_ATTRIBUTE_ALWAYS_INLINE size_type size() const
Definition: SmallVector.h:137
The operation should be implemented in terms of a wider scalar base-type.
Definition: LegalizerInfo.h:57
void setFPImm(const ConstantFP *CFP)
MachineInstrBuilder buildStore(unsigned Val, unsigned Addr, MachineMemOperand &MMO)
Build and insert G_STORE Val, Addr, MMO.
bool isScalar() const
MachineInstrBuilder buildFConstant(DstType &&Res, const ConstantFP &Val)
Build and insert Res = G_FCONSTANT Val.
iterator getFirstTerminator()
Returns an iterator to the first terminator instruction of this basic block.
MachineInstrBuilder buildUndef(DstType &&Res)
Build and insert Res = IMPLICIT_DEF.
unsigned getReg() const
getReg - Returns the register number.
MachineInstrBuilder buildSExt(DstType &&Res, ArgType &&Arg)
Build and insert Res = G_SEXT Op.
MachineInstrBuilder buildUnmerge(ArrayRef< unsigned > Res, unsigned Op)
Build and insert Res0, ...
unsigned Reg
The (vector) operation should be implemented by splitting it into sub-vectors where the operation is ...
Definition: LegalizerInfo.h:62
Libcall
RTLIB::Libcall enum - This enum defines all of the runtime library calls the backend can emit...
virtual const TargetLowering * getTargetLowering() const
LLT getType(unsigned Reg) const
Get the low-level type of Reg or LLT{} if Reg is not a generic (target independent) virtual register...
static const MCPhysReg VRegs[32]
APInt trunc(unsigned width) const
Truncate to new width.
Definition: APInt.cpp:817
MachineInstrBuilder buildAnyExt(unsigned Res, unsigned Op)
Build and insert Res = G_ANYEXT Op0.
uint64_t alignTo(uint64_t Value, uint64_t Align, uint64_t Skew=0)
Returns the next integer (mod 2**64) that is greater than or equal to Value and is a multiple of Alig...
Definition: MathExtras.h:677
Libcall getFPROUND(EVT OpVT, EVT RetVT)
getFPROUND - Return the FPROUND_*_* value for the given types, or UNKNOWN_LIBCALL if there is none...
MachineInstrBuilder buildAtomicCmpXchg(unsigned OldValRes, unsigned Addr, unsigned CmpVal, unsigned NewVal, MachineMemOperand &MMO)
Build and insert OldValRes = G_ATOMIC_CMPXCHG Addr, CmpVal, NewVal, MMO.
Libcall getUINTTOFP(EVT OpVT, EVT RetVT)
getUINTTOFP - Return the UINTTOFP_*_* value for the given types, or UNKNOWN_LIBCALL if there is none...
LegalizerHelper(MachineFunction &MF)
The operation should be synthesized from multiple instructions acting on a narrower scalar base-type...
Definition: LegalizerInfo.h:52
bool isVector() const
LegalizeActionStep getAction(const LegalityQuery &Query) const
Determine what action should be taken to legalize the described instruction.
void recordInsertion(MachineInstr *InsertedInstr) const
A description of a memory reference used in the backend.
bool isSigned() const
Definition: InstrTypes.h:1054
LegalizeResult widenScalar(MachineInstr &MI, unsigned TypeIdx, LLT WideTy)
Legalize an instruction by performing the operation on a wider scalar type (for example a 16-bit addi...
static Type * getFloatTy(LLVMContext &C)
Definition: Type.cpp:164
const ConstantFP * getFPImm() const
unsigned getNumOperands() const
Access to explicit operands of the instruction.
Definition: MachineInstr.h:314
void setMF(MachineFunction &)
const MachineInstrBuilder & addUse(unsigned RegNo, unsigned Flags=0, unsigned SubReg=0) const
Add a virtual register use operand.
void eraseFromParent()
Unlink &#39;this&#39; from the containing basic block and delete it.
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
Definition: MachineInstr.h:311
MachineMemOperand * getMachineMemOperand(MachinePointerInfo PtrInfo, MachineMemOperand::Flags f, uint64_t s, unsigned base_alignment, const AAMDNodes &AAInfo=AAMDNodes(), const MDNode *Ranges=nullptr, SyncScope::ID SSID=SyncScope::System, AtomicOrdering Ordering=AtomicOrdering::NotAtomic, AtomicOrdering FailureOrdering=AtomicOrdering::NotAtomic)
getMachineMemOperand - Allocate a new MachineMemOperand.
LegalizerHelper::LegalizeResult createLibcall(MachineIRBuilder &MIRBuilder, RTLIB::Libcall Libcall, const CallLowering::ArgInfo &Result, ArrayRef< CallLowering::ArgInfo > Args)
Helper function that creates the given libcall.
opStatus convert(const fltSemantics &ToSemantics, roundingMode RM, bool *losesInfo)
Definition: APFloat.cpp:4444
MachineInstrBuilder buildSub(unsigned Dst, unsigned Src0, unsigned Src1)
Build and insert Res = G_SUB Op0, Op1.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory)...
Definition: APInt.h:33
const APInt & getValue() const
Return the constant as an APInt value reference.
Definition: Constants.h:138
static const fltSemantics & IEEEdouble() LLVM_READNONE
Definition: APFloat.cpp:123
static LLT scalar(unsigned SizeInBits)
Get a low-level scalar or aggregate "bag of bits".
MachineInstrBuilder buildZExt(DstType &&Res, ArgType &&Arg)
Build and insert Res = G_ZEXT Op.
unsigned const MachineRegisterInfo * MRI
LegalizeResult legalizeInstrStep(MachineInstr &MI)
Replace MI by a sequence of legal instructions that can implement the same operation.
The instances of the Type class are immutable: once they are created, they are never changed...
Definition: Type.h:46
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
This is an important class for using LLVM in a threaded context.
Definition: LLVMContext.h:69
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
ConstantFP - Floating Point Values [float, double].
Definition: Constants.h:264
Libcall getFPTOSINT(EVT OpVT, EVT RetVT)
getFPTOSINT - Return the FPTOSINT_*_* value for the given types, or UNKNOWN_LIBCALL if there is none...
MachineInstrBuilder buildUAdde(unsigned Res, unsigned CarryOut, unsigned Op0, unsigned Op1, unsigned CarryIn)
Build and insert Res, CarryOut = G_UADDE Op0, Op1, CarryIn.
MachineInstrBuilder buildExtract(unsigned Res, unsigned Src, uint64_t Index)
Build and insert `Res0, ...
virtual const CallLowering * getCallLowering() const
void setInstr(MachineInstr &MI)
Set the insertion point to before MI.
static MVT getVT(Type *Ty, bool HandleUnknown=false)
Return the value type corresponding to the specified type.
Definition: ValueTypes.cpp:281
void print(raw_ostream &OS, bool IsStandalone=true, bool SkipOpers=false, bool SkipDebugLoc=false, bool AddNewLine=true, const TargetInstrInfo *TII=nullptr) const
Print this MI to OS.
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function. ...
Definition: Function.cpp:193
Some kind of error has occurred and we could not legalize this instruction.
Instruction was already legal and no change was made to the MachineFunction.
MachineBasicBlock::iterator getInsertPt()
Current insertion point for new instructions.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
APInt lshr(unsigned shiftAmt) const
Logical right-shift function.
Definition: APInt.h:964
static Type * getFP128Ty(LLVMContext &C)
Definition: Type.cpp:169
const APFloat & getValueAPF() const
Definition: Constants.h:299
Libcall getFPEXT(EVT OpVT, EVT RetVT)
getFPEXT - Return the FPEXT_*_* value for the given types, or UNKNOWN_LIBCALL if there is none...
unsigned createGenericVirtualRegister(LLT Ty, StringRef Name="")
Create and return a new generic virtual register with low-level type Ty.
static Type * getHalfTy(LLVMContext &C)
Definition: Type.cpp:163
static const fltSemantics & IEEEsingle() LLVM_READNONE
Definition: APFloat.cpp:120
void setInsertPt(MachineBasicBlock &MBB, MachineBasicBlock::iterator II)
Set the insertion point before the specified position.
This is the shared class of boolean and integer constants.
Definition: Constants.h:84
LegalizeResult libcall(MachineInstr &MI)
Legalize an instruction by emiting a runtime library call instead.
mmo_iterator memoperands_begin() const
Access to memory operands of the instruction.
Definition: MachineInstr.h:416
static RTLIB::Libcall getRTLibDesc(unsigned Opcode, unsigned Size)
MachineOperand class - Representation of each machine instruction operand.
This is a &#39;vector&#39; (really, a variable-sized array), optimized for the case when the array is small...
Definition: SmallVector.h:861
unsigned getSizeInBits() const
Returns the total size of the type. Must only be called on sized types.
The target wants to do something special with this combination of operand and type.
Definition: LegalizerInfo.h:81
LegalizeResult lower(MachineInstr &MI, unsigned TypeIdx, LLT Ty)
Legalize an instruction by splitting it into simpler parts, hopefully understood by the target...
static Constant * get(Type *Ty, uint64_t V, bool isSigned=false)
If Ty is a vector type, return a Constant with a splat of the given value.
Definition: Constants.cpp:611
static Constant * get(Type *Ty, double V)
This returns a ConstantFP, or a vector containing a splat of a ConstantFP, for the specified value in...
Definition: Constants.cpp:674
LegalizeResult fewerElementsVector(MachineInstr &MI, unsigned TypeIdx, LLT NarrowTy)
Legalize a vector instruction by splitting into multiple components, each acting on the same scalar t...
int64_t getImm() const
MachineInstrBuilder buildAdd(unsigned Dst, unsigned Src0, unsigned Src1)
Build and insert Res = G_ADD Op0, Op1.
const Function & getFunction() const
Return the LLVM function that this machine code represents.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:133
Class for arbitrary precision integers.
Definition: APInt.h:69
static RTLIB::Libcall getConvRTLibDesc(unsigned Opcode, Type *ToType, Type *FromType)
static MachineOperand CreateES(const char *SymName, unsigned char TargetFlags=0)
static LegalizerHelper::LegalizeResult conversionLibcall(MachineInstr &MI, MachineIRBuilder &MIRBuilder, Type *ToType, Type *FromType)
MachineInstrBuilder buildConstant(unsigned Res, const ConstantInt &Val)
Build and insert Res = G_CONSTANT Val.
const MachineBasicBlock * getParent() const
Definition: MachineInstr.h:156
MachineInstrBuilder buildMerge(unsigned Res, ArrayRef< unsigned > Ops)
Build and insert Res = G_MERGE_VALUES Op0, ...
virtual bool legalizeCustom(MachineInstr &MI, MachineRegisterInfo &MRI, MachineIRBuilder &MIRBuilder) const
Representation of each machine instruction.
Definition: MachineInstr.h:60
Instruction has been legalized and the MachineFunction changed.
Libcall getFPTOUINT(EVT OpVT, EVT RetVT)
getFPTOUINT - Return the FPTOUINT_*_* value for the given types, or UNKNOWN_LIBCALL if there is none...
static IntegerType * getInt32Ty(LLVMContext &C)
Definition: Type.cpp:176
void setReg(unsigned Reg)
Change the register this operand corresponds to.
#define I(x, y, z)
Definition: MD5.cpp:58
MachineInstrBuilder buildLoad(unsigned Res, unsigned Addr, MachineMemOperand &MMO)
Build and insert Res = G_LOAD Addr, MMO.
static Constant * getZeroValueForNegation(Type *Ty)
Floating point negation must be implemented with f(x) = -0.0 - x.
Definition: Constants.cpp:738
MachineFunction & getMF()
Getter for the function we currently build.
void setCImm(const ConstantInt *CI)
iterator getFirstNonPHI()
Returns a pointer to the first instruction in this block that is not a PHINode instruction.
Optional< MachineInstrBuilder > materializeGEP(unsigned &Res, unsigned Op0, const LLT &ValueTy, uint64_t Value)
Materialize and insert Res = G_GEP Op0, (G_CONSTANT Value)
Libcall getSINTTOFP(EVT OpVT, EVT RetVT)
getSINTTOFP - Return the SINTTOFP_*_* value for the given types, or UNKNOWN_LIBCALL if there is none...
LegalizeResult narrowScalar(MachineInstr &MI, unsigned TypeIdx, LLT NarrowTy)
Legalize an instruction by reducing the width of the underlying scalar type.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
unsigned getSizeInBits(unsigned Reg, const MachineRegisterInfo &MRI, const TargetRegisterInfo &TRI) const
Get the size in bits of Reg.
constexpr char Size[]
Key for Kernel::Arg::Metadata::mSize.
This file describes how to lower LLVM calls to machine code calls.
#define LLVM_FALLTHROUGH
LLVM_FALLTHROUGH - Mark fallthrough cases in switch statements.
Definition: Compiler.h:235
MachineBasicBlock & getMBB()
Getter for the basic block we currently build.
MachineInstrBuilder buildInstr(unsigned Opc, DstTy &&Ty, UseArgsTy &&... Args)
DAG like Generic method for building arbitrary instructions as above.
IRTranslator LLVM IR MI
MachineInstrBuilder buildMul(unsigned Dst, unsigned Src0, unsigned Src1)
Build and insert Res = G_MUL Op0, Op1.
const MachineInstrBuilder & addDef(unsigned RegNo, unsigned Flags=0, unsigned SubReg=0) const
Add a virtual register definition operand.
MachineInstrBuilder buildInsert(unsigned Res, unsigned Src, unsigned Op, unsigned Index)
#define LLVM_DEBUG(X)
Definition: Debug.h:119
const MachineOperand & getOperand(unsigned i) const
Definition: MachineInstr.h:316
const ConstantInt * getCImm() const
The operation is expected to be selectable directly by the target, and no transformation is necessary...
Definition: LegalizerInfo.h:47
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
MachineInstrBuilder buildICmp(CmpInst::Predicate Pred, unsigned Res, unsigned Op0, unsigned Op1)
Build and insert a Res = G_ICMP Pred, Op0, Op1.
This file describes how to lower LLVM code to machine code.
unsigned getPredicate() const