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  DEBUG(dbgs() << "Legalizing: "; MI.print(dbgs()));
39 
40  auto Step = LI.getAction(MI, MRI);
41  switch (Step.Action) {
42  case Legal:
43  DEBUG(dbgs() << ".. Already legal\n");
44  return AlreadyLegal;
45  case Libcall:
46  DEBUG(dbgs() << ".. Convert to libcall\n");
47  return libcall(MI);
48  case NarrowScalar:
49  DEBUG(dbgs() << ".. Narrow scalar\n");
50  return narrowScalar(MI, Step.TypeIdx, Step.NewType);
51  case WidenScalar:
52  DEBUG(dbgs() << ".. Widen scalar\n");
53  return widenScalar(MI, Step.TypeIdx, Step.NewType);
54  case Lower:
55  DEBUG(dbgs() << ".. Lower\n");
56  return lower(MI, Step.TypeIdx, Step.NewType);
57  case FewerElements:
58  DEBUG(dbgs() << ".. Reduce number of elements\n");
59  return fewerElementsVector(MI, Step.TypeIdx, Step.NewType);
60  case Custom:
61  DEBUG(dbgs() << ".. Custom legalization\n");
62  return LI.legalizeCustom(MI, MRI, MIRBuilder) ? Legalized
64  default:
65  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  int64_t SizeOp0 = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits();
276  int64_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  int64_t OpStart = MI.getOperand(2).getImm();
343  int64_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, SegSize;
359  if (OpStart < SrcStart) {
360  ExtractOffset = 0;
361  SegSize = std::min(NarrowSize, OpStart + OpSize - SrcStart);
362  } else {
363  ExtractOffset = OpStart - SrcStart;
364  SegSize = std::min(SrcStart + NarrowSize - OpStart, OpSize);
365  }
366 
367  unsigned SegReg = SrcRegs[i];
368  if (ExtractOffset != 0 || SegSize != NarrowSize) {
369  // A genuine extract is needed.
370  SegReg = MRI.createGenericVirtualRegister(LLT::scalar(SegSize));
371  MIRBuilder.buildExtract(SegReg, SrcRegs[i], ExtractOffset);
372  }
373 
374  DstRegs.push_back(SegReg);
375  }
376 
377  MIRBuilder.buildMerge(MI.getOperand(0).getReg(), DstRegs);
378  MI.eraseFromParent();
379  return Legalized;
380  }
381  case TargetOpcode::G_INSERT: {
382  // FIXME: add support for when SizeOp0 isn't an exact multiple of
383  // NarrowSize.
384  if (SizeOp0 % NarrowSize != 0)
385  return UnableToLegalize;
386 
387  int NumParts = SizeOp0 / NarrowSize;
388 
389  SmallVector<unsigned, 2> SrcRegs, DstRegs;
390  SmallVector<uint64_t, 2> Indexes;
391  extractParts(MI.getOperand(1).getReg(), NarrowTy, NumParts, SrcRegs);
392 
393  unsigned OpReg = MI.getOperand(2).getReg();
394  int64_t OpStart = MI.getOperand(3).getImm();
395  int64_t OpSize = MRI.getType(OpReg).getSizeInBits();
396  for (int i = 0; i < NumParts; ++i) {
397  unsigned DstStart = i * NarrowSize;
398 
399  if (DstStart + NarrowSize <= OpStart || DstStart >= OpStart + OpSize) {
400  // No part of the insert affects this subregister, forward the original.
401  DstRegs.push_back(SrcRegs[i]);
402  continue;
403  } else if (DstStart == OpStart && NarrowTy == MRI.getType(OpReg)) {
404  // The entire subregister is defined by this insert, forward the new
405  // value.
406  DstRegs.push_back(OpReg);
407  continue;
408  }
409 
410  // OpSegStart is where this destination segment would start in OpReg if it
411  // extended infinitely in both directions.
412  int64_t ExtractOffset, InsertOffset, SegSize;
413  if (OpStart < DstStart) {
414  InsertOffset = 0;
415  ExtractOffset = DstStart - OpStart;
416  SegSize = std::min(NarrowSize, OpStart + OpSize - DstStart);
417  } else {
418  InsertOffset = OpStart - DstStart;
419  ExtractOffset = 0;
420  SegSize =
421  std::min(NarrowSize - InsertOffset, OpStart + OpSize - DstStart);
422  }
423 
424  unsigned SegReg = OpReg;
425  if (ExtractOffset != 0 || SegSize != OpSize) {
426  // A genuine extract is needed.
427  SegReg = MRI.createGenericVirtualRegister(LLT::scalar(SegSize));
428  MIRBuilder.buildExtract(SegReg, OpReg, ExtractOffset);
429  }
430 
431  unsigned DstReg = MRI.createGenericVirtualRegister(NarrowTy);
432  MIRBuilder.buildInsert(DstReg, SrcRegs[i], SegReg, InsertOffset);
433  DstRegs.push_back(DstReg);
434  }
435 
436  assert(DstRegs.size() == (unsigned)NumParts && "not all parts covered");
437  MIRBuilder.buildMerge(MI.getOperand(0).getReg(), DstRegs);
438  MI.eraseFromParent();
439  return Legalized;
440  }
441  case TargetOpcode::G_LOAD: {
442  // FIXME: add support for when SizeOp0 isn't an exact multiple of
443  // NarrowSize.
444  if (SizeOp0 % NarrowSize != 0)
445  return UnableToLegalize;
446  int NumParts = SizeOp0 / NarrowSize;
447  LLT OffsetTy = LLT::scalar(
448  MRI.getType(MI.getOperand(1).getReg()).getScalarSizeInBits());
449 
450  SmallVector<unsigned, 2> DstRegs;
451  for (int i = 0; i < NumParts; ++i) {
452  unsigned DstReg = MRI.createGenericVirtualRegister(NarrowTy);
453  unsigned SrcReg = 0;
454  unsigned Adjustment = i * NarrowSize / 8;
455 
456  MIRBuilder.materializeGEP(SrcReg, MI.getOperand(1).getReg(), OffsetTy,
457  Adjustment);
458 
459  // TODO: This is conservatively correct, but we probably want to split the
460  // memory operands in the future.
461  MIRBuilder.buildLoad(DstReg, SrcReg, **MI.memoperands_begin());
462 
463  DstRegs.push_back(DstReg);
464  }
465  unsigned DstReg = MI.getOperand(0).getReg();
466  MIRBuilder.buildMerge(DstReg, DstRegs);
467  MI.eraseFromParent();
468  return Legalized;
469  }
470  case TargetOpcode::G_STORE: {
471  // FIXME: add support for when SizeOp0 isn't an exact multiple of
472  // NarrowSize.
473  if (SizeOp0 % NarrowSize != 0)
474  return UnableToLegalize;
475  int NumParts = SizeOp0 / NarrowSize;
476  LLT OffsetTy = LLT::scalar(
477  MRI.getType(MI.getOperand(1).getReg()).getScalarSizeInBits());
478 
479  SmallVector<unsigned, 2> SrcRegs;
480  extractParts(MI.getOperand(0).getReg(), NarrowTy, NumParts, SrcRegs);
481 
482  for (int i = 0; i < NumParts; ++i) {
483  unsigned DstReg = 0;
484  unsigned Adjustment = i * NarrowSize / 8;
485 
486  MIRBuilder.materializeGEP(DstReg, MI.getOperand(1).getReg(), OffsetTy,
487  Adjustment);
488 
489  // TODO: This is conservatively correct, but we probably want to split the
490  // memory operands in the future.
491  MIRBuilder.buildStore(SrcRegs[i], DstReg, **MI.memoperands_begin());
492  }
493  MI.eraseFromParent();
494  return Legalized;
495  }
496  case TargetOpcode::G_CONSTANT: {
497  // FIXME: add support for when SizeOp0 isn't an exact multiple of
498  // NarrowSize.
499  if (SizeOp0 % NarrowSize != 0)
500  return UnableToLegalize;
501  int NumParts = SizeOp0 / NarrowSize;
502  const APInt &Cst = MI.getOperand(1).getCImm()->getValue();
504 
505  SmallVector<unsigned, 2> DstRegs;
506  for (int i = 0; i < NumParts; ++i) {
507  unsigned DstReg = MRI.createGenericVirtualRegister(NarrowTy);
508  ConstantInt *CI =
509  ConstantInt::get(Ctx, Cst.lshr(NarrowSize * i).trunc(NarrowSize));
510  MIRBuilder.buildConstant(DstReg, *CI);
511  DstRegs.push_back(DstReg);
512  }
513  unsigned DstReg = MI.getOperand(0).getReg();
514  MIRBuilder.buildMerge(DstReg, DstRegs);
515  MI.eraseFromParent();
516  return Legalized;
517  }
518  case TargetOpcode::G_OR: {
519  // Legalize bitwise operation:
520  // A = BinOp<Ty> B, C
521  // into:
522  // B1, ..., BN = G_UNMERGE_VALUES B
523  // C1, ..., CN = G_UNMERGE_VALUES C
524  // A1 = BinOp<Ty/N> B1, C2
525  // ...
526  // AN = BinOp<Ty/N> BN, CN
527  // A = G_MERGE_VALUES A1, ..., AN
528 
529  // FIXME: add support for when SizeOp0 isn't an exact multiple of
530  // NarrowSize.
531  if (SizeOp0 % NarrowSize != 0)
532  return UnableToLegalize;
533  int NumParts = SizeOp0 / NarrowSize;
534 
535  // List the registers where the destination will be scattered.
536  SmallVector<unsigned, 2> DstRegs;
537  // List the registers where the first argument will be split.
538  SmallVector<unsigned, 2> SrcsReg1;
539  // List the registers where the second argument will be split.
540  SmallVector<unsigned, 2> SrcsReg2;
541  // Create all the temporary registers.
542  for (int i = 0; i < NumParts; ++i) {
543  unsigned DstReg = MRI.createGenericVirtualRegister(NarrowTy);
544  unsigned SrcReg1 = MRI.createGenericVirtualRegister(NarrowTy);
545  unsigned SrcReg2 = MRI.createGenericVirtualRegister(NarrowTy);
546 
547  DstRegs.push_back(DstReg);
548  SrcsReg1.push_back(SrcReg1);
549  SrcsReg2.push_back(SrcReg2);
550  }
551  // Explode the big arguments into smaller chunks.
552  MIRBuilder.buildUnmerge(SrcsReg1, MI.getOperand(1).getReg());
553  MIRBuilder.buildUnmerge(SrcsReg2, MI.getOperand(2).getReg());
554 
555  // Do the operation on each small part.
556  for (int i = 0; i < NumParts; ++i)
557  MIRBuilder.buildOr(DstRegs[i], SrcsReg1[i], SrcsReg2[i]);
558 
559  // Gather the destination registers into the final destination.
560  unsigned DstReg = MI.getOperand(0).getReg();
561  MIRBuilder.buildMerge(DstReg, DstRegs);
562  MI.eraseFromParent();
563  return Legalized;
564  }
565  }
566 }
567 
569 LegalizerHelper::widenScalar(MachineInstr &MI, unsigned TypeIdx, LLT WideTy) {
570  MIRBuilder.setInstr(MI);
571 
572  switch (MI.getOpcode()) {
573  default:
574  return UnableToLegalize;
575  case TargetOpcode::G_ADD:
576  case TargetOpcode::G_AND:
577  case TargetOpcode::G_MUL:
578  case TargetOpcode::G_OR:
579  case TargetOpcode::G_XOR:
580  case TargetOpcode::G_SUB:
581  case TargetOpcode::G_SHL: {
582  // Perform operation at larger width (any extension is fine here, high bits
583  // don't affect the result) and then truncate the result back to the
584  // original type.
585  unsigned Src1Ext = MRI.createGenericVirtualRegister(WideTy);
586  unsigned Src2Ext = MRI.createGenericVirtualRegister(WideTy);
587  MIRBuilder.buildAnyExt(Src1Ext, MI.getOperand(1).getReg());
588  MIRBuilder.buildAnyExt(Src2Ext, MI.getOperand(2).getReg());
589 
590  unsigned DstExt = MRI.createGenericVirtualRegister(WideTy);
592  .addDef(DstExt)
593  .addUse(Src1Ext)
594  .addUse(Src2Ext);
595 
596  MIRBuilder.buildTrunc(MI.getOperand(0).getReg(), DstExt);
597  MI.eraseFromParent();
598  return Legalized;
599  }
600  case TargetOpcode::G_SDIV:
601  case TargetOpcode::G_UDIV:
602  case TargetOpcode::G_SREM:
603  case TargetOpcode::G_UREM:
604  case TargetOpcode::G_ASHR:
605  case TargetOpcode::G_LSHR: {
606  unsigned ExtOp = MI.getOpcode() == TargetOpcode::G_SDIV ||
607  MI.getOpcode() == TargetOpcode::G_SREM ||
608  MI.getOpcode() == TargetOpcode::G_ASHR
609  ? TargetOpcode::G_SEXT
610  : TargetOpcode::G_ZEXT;
611 
612  unsigned LHSExt = MRI.createGenericVirtualRegister(WideTy);
613  MIRBuilder.buildInstr(ExtOp).addDef(LHSExt).addUse(
614  MI.getOperand(1).getReg());
615 
616  unsigned RHSExt = MRI.createGenericVirtualRegister(WideTy);
617  MIRBuilder.buildInstr(ExtOp).addDef(RHSExt).addUse(
618  MI.getOperand(2).getReg());
619 
620  unsigned ResExt = MRI.createGenericVirtualRegister(WideTy);
622  .addDef(ResExt)
623  .addUse(LHSExt)
624  .addUse(RHSExt);
625 
626  MIRBuilder.buildTrunc(MI.getOperand(0).getReg(), ResExt);
627  MI.eraseFromParent();
628  return Legalized;
629  }
630  case TargetOpcode::G_SELECT: {
631  if (TypeIdx != 0)
632  return UnableToLegalize;
633 
634  // Perform operation at larger width (any extension is fine here, high bits
635  // don't affect the result) and then truncate the result back to the
636  // original type.
637  unsigned Src1Ext = MRI.createGenericVirtualRegister(WideTy);
638  unsigned Src2Ext = MRI.createGenericVirtualRegister(WideTy);
639  MIRBuilder.buildAnyExt(Src1Ext, MI.getOperand(2).getReg());
640  MIRBuilder.buildAnyExt(Src2Ext, MI.getOperand(3).getReg());
641 
642  unsigned DstExt = MRI.createGenericVirtualRegister(WideTy);
643  MIRBuilder.buildInstr(TargetOpcode::G_SELECT)
644  .addDef(DstExt)
645  .addReg(MI.getOperand(1).getReg())
646  .addUse(Src1Ext)
647  .addUse(Src2Ext);
648 
649  MIRBuilder.buildTrunc(MI.getOperand(0).getReg(), DstExt);
650  MI.eraseFromParent();
651  return Legalized;
652  }
653  case TargetOpcode::G_FPTOSI:
654  case TargetOpcode::G_FPTOUI: {
655  if (TypeIdx != 0)
656  return UnableToLegalize;
657 
658  unsigned DstExt = MRI.createGenericVirtualRegister(WideTy);
660  .addDef(DstExt)
661  .addUse(MI.getOperand(1).getReg());
662 
663  MIRBuilder.buildTrunc(MI.getOperand(0).getReg(), DstExt);
664  MI.eraseFromParent();
665  return Legalized;
666  }
667  case TargetOpcode::G_SITOFP:
668  case TargetOpcode::G_UITOFP: {
669  if (TypeIdx != 1)
670  return UnableToLegalize;
671 
672  unsigned Src = MI.getOperand(1).getReg();
673  unsigned SrcExt = MRI.createGenericVirtualRegister(WideTy);
674 
675  if (MI.getOpcode() == TargetOpcode::G_SITOFP) {
676  MIRBuilder.buildSExt(SrcExt, Src);
677  } else {
678  assert(MI.getOpcode() == TargetOpcode::G_UITOFP && "Unexpected conv op");
679  MIRBuilder.buildZExt(SrcExt, Src);
680  }
681 
683  .addDef(MI.getOperand(0).getReg())
684  .addUse(SrcExt);
685 
686  MI.eraseFromParent();
687  return Legalized;
688  }
689  case TargetOpcode::G_INSERT: {
690  if (TypeIdx != 0)
691  return UnableToLegalize;
692 
693  unsigned Src = MI.getOperand(1).getReg();
694  unsigned SrcExt = MRI.createGenericVirtualRegister(WideTy);
695  MIRBuilder.buildAnyExt(SrcExt, Src);
696 
697  unsigned DstExt = MRI.createGenericVirtualRegister(WideTy);
698  auto MIB = MIRBuilder.buildInsert(DstExt, SrcExt, MI.getOperand(2).getReg(),
699  MI.getOperand(3).getImm());
700  for (unsigned OpNum = 4; OpNum < MI.getNumOperands(); OpNum += 2) {
701  MIB.addReg(MI.getOperand(OpNum).getReg());
702  MIB.addImm(MI.getOperand(OpNum + 1).getImm());
703  }
704 
705  MIRBuilder.buildTrunc(MI.getOperand(0).getReg(), DstExt);
706  MI.eraseFromParent();
707  return Legalized;
708  }
709  case TargetOpcode::G_LOAD: {
710  // For some types like i24, we might try to widen to i32. To properly handle
711  // this we should be using a dedicated extending load, until then avoid
712  // trying to legalize.
713  if (alignTo(MRI.getType(MI.getOperand(0).getReg()).getSizeInBits(), 8) !=
714  WideTy.getSizeInBits())
715  return UnableToLegalize;
716 
717  unsigned DstExt = MRI.createGenericVirtualRegister(WideTy);
718  MIRBuilder.buildLoad(DstExt, MI.getOperand(1).getReg(),
719  **MI.memoperands_begin());
720  MIRBuilder.buildTrunc(MI.getOperand(0).getReg(), DstExt);
721  MI.eraseFromParent();
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  auto &TLI = *MIRBuilder.getMF().getSubtarget().getTargetLowering();
730  auto Content = TLI.getBooleanContents(false, false);
731 
732  unsigned ExtOp = TargetOpcode::G_ANYEXT;
734  ExtOp = TargetOpcode::G_ZEXT;
736  ExtOp = TargetOpcode::G_SEXT;
737  else
738  ExtOp = TargetOpcode::G_ANYEXT;
739 
740  unsigned SrcExt = MRI.createGenericVirtualRegister(WideTy);
741  MIRBuilder.buildInstr(ExtOp).addDef(SrcExt).addUse(
742  MI.getOperand(0).getReg());
743  MIRBuilder.buildStore(SrcExt, MI.getOperand(1).getReg(),
744  **MI.memoperands_begin());
745  MI.eraseFromParent();
746  return Legalized;
747  }
748  case TargetOpcode::G_CONSTANT: {
749  unsigned DstExt = MRI.createGenericVirtualRegister(WideTy);
750  MIRBuilder.buildConstant(DstExt, *MI.getOperand(1).getCImm());
751  MIRBuilder.buildTrunc(MI.getOperand(0).getReg(), DstExt);
752  MI.eraseFromParent();
753  return Legalized;
754  }
755  case TargetOpcode::G_FCONSTANT: {
756  const ConstantFP *CFP = MI.getOperand(1).getFPImm();
757  APFloat Val = CFP->getValueAPF();
759  auto LLT2Sem = [](LLT Ty) {
760  switch (Ty.getSizeInBits()) {
761  case 32:
762  return &APFloat::IEEEsingle();
763  break;
764  case 64:
765  return &APFloat::IEEEdouble();
766  break;
767  default:
768  llvm_unreachable("Unhandled fp widen type");
769  }
770  };
771  bool LosesInfo;
772  Val.convert(*LLT2Sem(WideTy), APFloat::rmTowardZero, &LosesInfo);
773  auto Cst = MIRBuilder.buildFConstant(WideTy, *ConstantFP::get(Ctx, Val));
775  MI.eraseFromParent();
776  return Legalized;
777  }
778  case TargetOpcode::G_BRCOND: {
779  unsigned TstExt = MRI.createGenericVirtualRegister(WideTy);
780  MIRBuilder.buildAnyExt(TstExt, MI.getOperand(0).getReg());
781  MIRBuilder.buildBrCond(TstExt, *MI.getOperand(1).getMBB());
782  MI.eraseFromParent();
783  return Legalized;
784  }
785  case TargetOpcode::G_FCMP: {
786  unsigned Op0Ext, Op1Ext, DstReg;
787  unsigned Cmp1 = MI.getOperand(2).getReg();
788  unsigned Cmp2 = MI.getOperand(3).getReg();
789  if (TypeIdx == 0) {
790  Op0Ext = Cmp1;
791  Op1Ext = Cmp2;
792  DstReg = MRI.createGenericVirtualRegister(WideTy);
793  } else {
794  Op0Ext = MRI.createGenericVirtualRegister(WideTy);
795  Op1Ext = MRI.createGenericVirtualRegister(WideTy);
796  DstReg = MI.getOperand(0).getReg();
797  MIRBuilder.buildInstr(TargetOpcode::G_FPEXT, Op0Ext, Cmp1);
798  MIRBuilder.buildInstr(TargetOpcode::G_FPEXT, Op1Ext, Cmp2);
799  }
801  static_cast<CmpInst::Predicate>(MI.getOperand(1).getPredicate()),
802  DstReg, Op0Ext, Op1Ext);
803  if (TypeIdx == 0)
804  MIRBuilder.buildInstr(TargetOpcode::G_TRUNC, MI.getOperand(0).getReg(),
805  DstReg);
806  MI.eraseFromParent();
807  return Legalized;
808  }
809  case TargetOpcode::G_ICMP: {
810  bool IsSigned = CmpInst::isSigned(
811  static_cast<CmpInst::Predicate>(MI.getOperand(1).getPredicate()));
812  unsigned Cmp1 = MI.getOperand(2).getReg();
813  unsigned Cmp2 = MI.getOperand(3).getReg();
814  unsigned Op0Ext, Op1Ext, DstReg;
815  if (TypeIdx == 0) {
816  Op0Ext = Cmp1;
817  Op1Ext = Cmp2;
818  DstReg = MRI.createGenericVirtualRegister(WideTy);
819  } else {
820  Op0Ext = MRI.createGenericVirtualRegister(WideTy);
821  Op1Ext = MRI.createGenericVirtualRegister(WideTy);
822  DstReg = MI.getOperand(0).getReg();
823  if (IsSigned) {
824  MIRBuilder.buildSExt(Op0Ext, Cmp1);
825  MIRBuilder.buildSExt(Op1Ext, Cmp2);
826  } else {
827  MIRBuilder.buildZExt(Op0Ext, Cmp1);
828  MIRBuilder.buildZExt(Op1Ext, Cmp2);
829  }
830  }
832  static_cast<CmpInst::Predicate>(MI.getOperand(1).getPredicate()),
833  DstReg, Op0Ext, Op1Ext);
834  if (TypeIdx == 0)
835  MIRBuilder.buildInstr(TargetOpcode::G_TRUNC, MI.getOperand(0).getReg(),
836  DstReg);
837  MI.eraseFromParent();
838  return Legalized;
839  }
840  case TargetOpcode::G_GEP: {
841  assert(TypeIdx == 1 && "unable to legalize pointer of GEP");
842  unsigned OffsetExt = MRI.createGenericVirtualRegister(WideTy);
843  MIRBuilder.buildSExt(OffsetExt, MI.getOperand(2).getReg());
844  MI.getOperand(2).setReg(OffsetExt);
845  return Legalized;
846  }
847  case TargetOpcode::G_PHI: {
848  assert(TypeIdx == 0 && "Expecting only Idx 0");
849  auto getExtendedReg = [&](unsigned Reg, MachineBasicBlock &MBB) {
850  auto FirstTermIt = MBB.getFirstTerminator();
851  MIRBuilder.setInsertPt(MBB, FirstTermIt);
852  MachineInstr *DefMI = MRI.getVRegDef(Reg);
854  if (DefMI->getOpcode() == TargetOpcode::G_TRUNC)
855  MIB = MIRBuilder.buildAnyExtOrTrunc(WideTy,
856  DefMI->getOperand(1).getReg());
857  else
858  MIB = MIRBuilder.buildAnyExt(WideTy, Reg);
859  return MIB->getOperand(0).getReg();
860  };
861  auto MIB = MIRBuilder.buildInstr(TargetOpcode::G_PHI, WideTy);
862  for (auto OpIt = MI.operands_begin() + 1, OpE = MI.operands_end();
863  OpIt != OpE;) {
864  unsigned Reg = OpIt++->getReg();
865  MachineBasicBlock *OpMBB = OpIt++->getMBB();
866  MIB.addReg(getExtendedReg(Reg, *OpMBB));
867  MIB.addMBB(OpMBB);
868  }
869  auto *MBB = MI.getParent();
870  MIRBuilder.setInsertPt(*MBB, MBB->getFirstNonPHI());
872  MIB->getOperand(0).getReg());
873  MI.eraseFromParent();
874  return Legalized;
875  }
876  }
877 }
878 
880 LegalizerHelper::lower(MachineInstr &MI, unsigned TypeIdx, LLT Ty) {
881  using namespace TargetOpcode;
882  MIRBuilder.setInstr(MI);
883 
884  switch(MI.getOpcode()) {
885  default:
886  return UnableToLegalize;
887  case TargetOpcode::G_SREM:
888  case TargetOpcode::G_UREM: {
889  unsigned QuotReg = MRI.createGenericVirtualRegister(Ty);
890  MIRBuilder.buildInstr(MI.getOpcode() == G_SREM ? G_SDIV : G_UDIV)
891  .addDef(QuotReg)
892  .addUse(MI.getOperand(1).getReg())
893  .addUse(MI.getOperand(2).getReg());
894 
895  unsigned ProdReg = MRI.createGenericVirtualRegister(Ty);
896  MIRBuilder.buildMul(ProdReg, QuotReg, MI.getOperand(2).getReg());
898  ProdReg);
899  MI.eraseFromParent();
900  return Legalized;
901  }
902  case TargetOpcode::G_SMULO:
903  case TargetOpcode::G_UMULO: {
904  // Generate G_UMULH/G_SMULH to check for overflow and a normal G_MUL for the
905  // result.
906  unsigned Res = MI.getOperand(0).getReg();
907  unsigned Overflow = MI.getOperand(1).getReg();
908  unsigned LHS = MI.getOperand(2).getReg();
909  unsigned RHS = MI.getOperand(3).getReg();
910 
911  MIRBuilder.buildMul(Res, LHS, RHS);
912 
913  unsigned Opcode = MI.getOpcode() == TargetOpcode::G_SMULO
914  ? TargetOpcode::G_SMULH
915  : TargetOpcode::G_UMULH;
916 
917  unsigned HiPart = MRI.createGenericVirtualRegister(Ty);
918  MIRBuilder.buildInstr(Opcode)
919  .addDef(HiPart)
920  .addUse(LHS)
921  .addUse(RHS);
922 
923  unsigned Zero = MRI.createGenericVirtualRegister(Ty);
924  MIRBuilder.buildConstant(Zero, 0);
925 
926  // For *signed* multiply, overflow is detected by checking:
927  // (hi != (lo >> bitwidth-1))
928  if (Opcode == TargetOpcode::G_SMULH) {
929  unsigned Shifted = MRI.createGenericVirtualRegister(Ty);
930  unsigned ShiftAmt = MRI.createGenericVirtualRegister(Ty);
931  MIRBuilder.buildConstant(ShiftAmt, Ty.getSizeInBits() - 1);
932  MIRBuilder.buildInstr(TargetOpcode::G_ASHR)
933  .addDef(Shifted)
934  .addUse(Res)
935  .addUse(ShiftAmt);
936  MIRBuilder.buildICmp(CmpInst::ICMP_NE, Overflow, HiPart, Shifted);
937  } else {
938  MIRBuilder.buildICmp(CmpInst::ICMP_NE, Overflow, HiPart, Zero);
939  }
940  MI.eraseFromParent();
941  return Legalized;
942  }
943  case TargetOpcode::G_FNEG: {
944  // TODO: Handle vector types once we are able to
945  // represent them.
946  if (Ty.isVector())
947  return UnableToLegalize;
948  unsigned Res = MI.getOperand(0).getReg();
949  Type *ZeroTy;
951  switch (Ty.getSizeInBits()) {
952  case 16:
953  ZeroTy = Type::getHalfTy(Ctx);
954  break;
955  case 32:
956  ZeroTy = Type::getFloatTy(Ctx);
957  break;
958  case 64:
959  ZeroTy = Type::getDoubleTy(Ctx);
960  break;
961  case 128:
962  ZeroTy = Type::getFP128Ty(Ctx);
963  break;
964  default:
965  llvm_unreachable("unexpected floating-point type");
966  }
967  ConstantFP &ZeroForNegation =
968  *cast<ConstantFP>(ConstantFP::getZeroValueForNegation(ZeroTy));
969  auto Zero = MIRBuilder.buildFConstant(Ty, ZeroForNegation);
970  MIRBuilder.buildInstr(TargetOpcode::G_FSUB)
971  .addDef(Res)
972  .addUse(Zero->getOperand(0).getReg())
973  .addUse(MI.getOperand(1).getReg());
974  MI.eraseFromParent();
975  return Legalized;
976  }
977  case TargetOpcode::G_FSUB: {
978  // Lower (G_FSUB LHS, RHS) to (G_FADD LHS, (G_FNEG RHS)).
979  // First, check if G_FNEG is marked as Lower. If so, we may
980  // end up with an infinite loop as G_FSUB is used to legalize G_FNEG.
981  if (LI.getAction({G_FNEG, {Ty}}).Action == Lower)
982  return UnableToLegalize;
983  unsigned Res = MI.getOperand(0).getReg();
984  unsigned LHS = MI.getOperand(1).getReg();
985  unsigned RHS = MI.getOperand(2).getReg();
986  unsigned Neg = MRI.createGenericVirtualRegister(Ty);
987  MIRBuilder.buildInstr(TargetOpcode::G_FNEG).addDef(Neg).addUse(RHS);
988  MIRBuilder.buildInstr(TargetOpcode::G_FADD)
989  .addDef(Res)
990  .addUse(LHS)
991  .addUse(Neg);
992  MI.eraseFromParent();
993  return Legalized;
994  }
995  case TargetOpcode::G_ATOMIC_CMPXCHG_WITH_SUCCESS: {
996  unsigned OldValRes = MI.getOperand(0).getReg();
997  unsigned SuccessRes = MI.getOperand(1).getReg();
998  unsigned Addr = MI.getOperand(2).getReg();
999  unsigned CmpVal = MI.getOperand(3).getReg();
1000  unsigned NewVal = MI.getOperand(4).getReg();
1001  MIRBuilder.buildAtomicCmpXchg(OldValRes, Addr, CmpVal, NewVal,
1002  **MI.memoperands_begin());
1003  MIRBuilder.buildICmp(CmpInst::ICMP_EQ, SuccessRes, OldValRes, CmpVal);
1004  MI.eraseFromParent();
1005  return Legalized;
1006  }
1007  }
1008 }
1009 
1012  LLT NarrowTy) {
1013  // FIXME: Don't know how to handle secondary types yet.
1014  if (TypeIdx != 0)
1015  return UnableToLegalize;
1016  switch (MI.getOpcode()) {
1017  default:
1018  return UnableToLegalize;
1019  case TargetOpcode::G_ADD: {
1020  unsigned NarrowSize = NarrowTy.getSizeInBits();
1021  unsigned DstReg = MI.getOperand(0).getReg();
1022  unsigned Size = MRI.getType(DstReg).getSizeInBits();
1023  int NumParts = Size / NarrowSize;
1024  // FIXME: Don't know how to handle the situation where the small vectors
1025  // aren't all the same size yet.
1026  if (Size % NarrowSize != 0)
1027  return UnableToLegalize;
1028 
1029  MIRBuilder.setInstr(MI);
1030 
1031  SmallVector<unsigned, 2> Src1Regs, Src2Regs, DstRegs;
1032  extractParts(MI.getOperand(1).getReg(), NarrowTy, NumParts, Src1Regs);
1033  extractParts(MI.getOperand(2).getReg(), NarrowTy, NumParts, Src2Regs);
1034 
1035  for (int i = 0; i < NumParts; ++i) {
1036  unsigned DstReg = MRI.createGenericVirtualRegister(NarrowTy);
1037  MIRBuilder.buildAdd(DstReg, Src1Regs[i], Src2Regs[i]);
1038  DstRegs.push_back(DstReg);
1039  }
1040 
1041  MIRBuilder.buildMerge(DstReg, DstRegs);
1042  MI.eraseFromParent();
1043  return Legalized;
1044  }
1045  }
1046 }
static LegalizerHelper::LegalizeResult simpleLibcall(MachineInstr &MI, MachineIRBuilder &MIRBuilder, unsigned Size, Type *OpType)
void push_back(const T &Elt)
Definition: SmallVector.h:212
MachineIRBuilder MIRBuilder
Expose MIRBuilder so clients can set their own RecordInsertInstruction functions. ...
mop_iterator operands_end()
Definition: MachineInstr.h:330
static Type * getDoubleTy(LLVMContext &C)
Definition: Type.cpp:165
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:136
The operation should be implemented in terms of a wider scalar base-type.
Definition: LegalizerInfo.h:52
unsigned getReg() const
getReg - Returns the register number.
The (vector) operation should be implemented by splitting it into sub-vectors where the operation is ...
Definition: LegalizerInfo.h:57
Libcall
RTLIB::Libcall enum - This enum defines all of the runtime library calls the backend can emit...
virtual const TargetLowering * getTargetLowering() const
static const MCPhysReg VRegs[32]
APInt trunc(unsigned width) const
Truncate to new width.
Definition: APInt.cpp:819
MachineInstrBuilder buildTrunc(unsigned Res, unsigned Op)
Build and insert Res = G_TRUNC Op.
MachineInstrBuilder buildAnyExtOrTrunc(DstTy &&Dst, UseArgTy &&Use)
Res = COPY Op depending on the differing sizes of Res and Op.
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
MachineInstrBuilder buildAnyExt(unsigned Res, unsigned Op)
Build and insert Res = G_ANYEXT Op0.
BooleanContent getBooleanContents(bool isVec, bool isFloat) const
For targets without i1 registers, this gives the nature of the high-bits of boolean values held in ty...
unsigned createGenericVirtualRegister(LLT Ty)
Create and return a new generic virtual register with low-level type Ty.
MachineInstrBuilder buildExtract(unsigned Res, unsigned Src, uint64_t Index)
Build and insert `Res0, ...
MachineInstrBuilder buildFCmp(CmpInst::Predicate Pred, unsigned Res, unsigned Op0, unsigned Op1)
Build and insert a Res = G_FCMP PredOp0, Op1.
Libcall getFPROUND(EVT OpVT, EVT RetVT)
getFPROUND - Return the FPROUND_*_* value for the given types, or UNKNOWN_LIBCALL if there is none...
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:47
MachineInstrBuilder buildStore(unsigned Val, unsigned Addr, MachineMemOperand &MMO)
Build and insert G_STORE Val, Addr, MMO.
bool isVector() const
LegalizeActionStep getAction(const LegalityQuery &Query) const
Determine what action should be taken to legalize the described instruction.
bool isSigned() const
Determine if this instruction is using a signed comparison.
Definition: InstrTypes.h:1022
void setInsertPt(MachineBasicBlock &MBB, MachineBasicBlock::iterator II)
Set the insertion point before the specified position.
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:296
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.
MachineInstrBuilder buildFPTrunc(DstType &&Res, SrcType &&Src)
Build and insert Res = G_FPTRUNC Op.
Reg
All possible values of the reg field in the ModR/M byte.
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
Definition: MachineInstr.h:293
LegalizerHelper::LegalizeResult createLibcall(MachineIRBuilder &MIRBuilder, RTLIB::Libcall Libcall, const CallLowering::ArgInfo &Result, ArrayRef< CallLowering::ArgInfo > Args)
Helper function that creates the given libcall.
MachineInstr * getVRegDef(unsigned Reg) const
getVRegDef - Return the machine instr that defines the specified virtual register or null if none is ...
opStatus convert(const fltSemantics &ToSemantics, roundingMode RM, bool *losesInfo)
Definition: APFloat.cpp:4441
MachineFunction & getMF()
Getter for the function we currently build.
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
MachineInstrBuilder buildOr(DstTy &&Dst, UseArgsTy &&... UseArgs)
Build and insert Res = G_OR Op0, Op1.
static const fltSemantics & IEEEdouble() LLVM_READNONE
Definition: APFloat.cpp:122
static LLT scalar(unsigned SizeInBits)
Get a low-level scalar or aggregate "bag of bits".
MachineInstrBuilder buildMul(DstTy &&Ty, UseArgsTy &&... UseArgs)
Build and insert Res = G_MUL Op0, Op1.
MachineInstrBuilder buildSExt(DstType &&Res, ArgType &&Arg)
Build and insert Res = G_SEXT 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
MachineInstrBuilder buildInstr(unsigned Opcode)
Build and insert <empty> = Opcode <empty>.
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
ConstantFP - Floating Point Values [float, double].
Definition: Constants.h:264
Helper class to build MachineInstr.
Libcall getFPTOSINT(EVT OpVT, EVT RetVT)
getFPTOSINT - Return the FPTOSINT_*_* value for the given types, or UNKNOWN_LIBCALL if there is none...
MachineInstrBuilder buildICmp(CmpInst::Predicate Pred, unsigned Res, unsigned Op0, unsigned Op1)
Build and insert a Res = G_ICMP Pred, Op0, Op1.
MachineInstrBuilder buildUndef(DstType &&Res)
Build and insert Res = IMPLICIT_DEF.
void setInstr(MachineInstr &MI)
Set the insertion point to before MI.
MachineInstrBuilder buildInsert(unsigned Res, unsigned Src, unsigned Op, unsigned Index)
virtual const CallLowering * getCallLowering() const
static MVT getVT(Type *Ty, bool HandleUnknown=false)
Return the value type corresponding to the specified type.
Definition: ValueTypes.cpp:284
void setMF(MachineFunction &)
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function. ...
Definition: Function.cpp:194
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.
MachineInstrBuilder buildUAdde(unsigned Res, unsigned CarryOut, unsigned Op0, unsigned Op1, unsigned CarryIn)
Build and insert Res, CarryOut = G_UADDE Op0, Op1, CarryIn.
#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:959
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...
static Type * getHalfTy(LLVMContext &C)
Definition: Type.cpp:163
static const fltSemantics & IEEEsingle() LLVM_READNONE
Definition: APFloat.cpp:119
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:392
static RTLIB::Libcall getRTLibDesc(unsigned Opcode, unsigned Size)
This is a &#39;vector&#39; (really, a variable-sized array), optimized for the case when the array is small...
Definition: SmallVector.h:862
MachineInstrBuilder MachineInstrBuilder & DefMI
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:76
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:585
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:648
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
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:132
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)
const MachineBasicBlock * getParent() const
Definition: MachineInstr.h:142
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...
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
static IntegerType * getInt32Ty(LLVMContext &C)
Definition: Type.cpp:176
MachineInstrBuilder buildAdd(unsigned Res, unsigned Op0, unsigned Op1)
Build and insert Res = G_ADD Op0, Op1.
MachineInstrBuilder buildConstant(unsigned Res, const ConstantInt &Val)
Build and insert Res = G_CONSTANT Val.
void setReg(unsigned Reg)
Change the register this operand corresponds to.
static Constant * getZeroValueForNegation(Type *Ty)
Floating point negation must be implemented with f(x) = -0.0 - x.
Definition: Constants.cpp:712
LLT getType(unsigned VReg) const
Get the low-level type of VReg or LLT{} if VReg is not a generic (target independent) virtual registe...
MachineInstrBuilder buildFConstant(DstType &&Res, const ConstantFP &Val)
Build and insert Res = G_FCONSTANT Val.
const MachineInstrBuilder & addReg(unsigned RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
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...
MachineInstrBuilder buildUnmerge(ArrayRef< unsigned > Res, unsigned Op)
Build and insert Res0, ...
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())
mop_iterator operands_begin()
Definition: MachineInstr.h:329
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.
MachineInstrBuilder buildLoad(unsigned Res, unsigned Addr, MachineMemOperand &MMO)
Build and insert Res = G_LOAD Addr, MMO.
#define DEBUG(X)
Definition: Debug.h:118
MachineInstrBuilder buildAtomicCmpXchg(unsigned OldValRes, unsigned Addr, unsigned CmpVal, unsigned NewVal, MachineMemOperand &MMO)
Build and insert OldValRes = G_ATOMIC_CMPXCHG Addr, CmpVal, NewVal, MMO.
IRTranslator LLVM IR MI
const MachineInstrBuilder & addDef(unsigned RegNo, unsigned Flags=0, unsigned SubReg=0) const
Add a virtual register definition operand.
void print(raw_ostream &OS, bool IsStandalone=true, bool SkipOpers=false, bool SkipDebugLoc=false, const TargetInstrInfo *TII=nullptr) const
Print this MI to OS.
const MachineOperand & getOperand(unsigned i) const
Definition: MachineInstr.h:298
MachineInstrBuilder buildMerge(unsigned Res, ArrayRef< unsigned > Ops)
Build and insert Res = G_MERGE_VALUES Op0, ...
const ConstantInt * getCImm() const
The operation is expected to be selectable directly by the target, and no transformation is necessary...
Definition: LegalizerInfo.h:42
MachineInstrBuilder buildZExt(DstType &&Res, ArgType &&Arg)
Build and insert Res = G_ZEXT Op.
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
This file describes how to lower LLVM code to machine code.
MachineInstrBuilder buildSub(DstTy &&Ty, UseArgsTy &&... UseArgs)
Build and insert Res = G_SUB Op0, Op1.
unsigned getPredicate() const
MachineInstrBuilder buildBrCond(unsigned Tst, MachineBasicBlock &BB)
Build and insert G_BRCOND Tst, Dest.